Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04ca2c17 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* 'for-linus' of git://oss.sgi.com/xfs/xfs:
  [XFS] XFS: Check for valid transaction headers in recovery
  [XFS] handle memory allocation failures during log initialisation
  [XFS] Account for allocated blocks when expanding directories
  [XFS] Wait for all I/O on truncate to zero file size
  [XFS] Fix use-after-free with log and quotas
parents ad1164b7 220ca310
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1566,11 +1566,14 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
	int nmap, error, w, count, c, got, i, mapi;
	xfs_trans_t *tp;
	xfs_mount_t *mp;
	xfs_drfsbno_t	nblks;

	dp = args->dp;
	mp = dp->i_mount;
	w = args->whichfork;
	tp = args->trans;
	nblks = dp->i_d.di_nblocks;

	/*
	 * For new directories adjust the file offset and block count.
	 */
@@ -1647,6 +1650,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
	}
	if (mapp != &map)
		kmem_free(mapp);
	/* account for newly allocated blocks in reserved blocks total */
	args->total -= dp->i_d.di_nblocks - nblks;
	*new_blkno = (xfs_dablk_t)bno;
	return 0;
}
+6 −0
Original line number Diff line number Diff line
@@ -525,11 +525,13 @@ xfs_dir2_grow_inode(
	xfs_mount_t	*mp;
	int		nmap;		/* number of bmap entries */
	xfs_trans_t	*tp;
	xfs_drfsbno_t	nblks;

	xfs_dir2_trace_args_s("grow_inode", args, space);
	dp = args->dp;
	tp = args->trans;
	mp = dp->i_mount;
	nblks = dp->i_d.di_nblocks;
	/*
	 * Set lowest possible block in the space requested.
	 */
@@ -622,7 +624,11 @@ xfs_dir2_grow_inode(
	 */
	if (mapp != &map)
		kmem_free(mapp);

	/* account for newly allocated blocks in reserved blocks total */
	args->total -= dp->i_d.di_nblocks - nblks;
	*dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno);

	/*
	 * Update file's size if this is the data space and it grew.
	 */
+1 −1
Original line number Diff line number Diff line
@@ -1414,7 +1414,7 @@ xfs_itruncate_start(
	mp = ip->i_mount;

	/* wait for the completion of any pending DIOs */
	if (new_size < ip->i_size)
	if (new_size == 0 || new_size < ip->i_size)
		vn_iowait(ip);

	/*
+36 −3
Original line number Diff line number Diff line
@@ -563,6 +563,11 @@ xfs_log_mount(
	}

	mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
	if (!mp->m_log) {
		cmn_err(CE_WARN, "XFS: Log allocation failed: No memory!");
		error = ENOMEM;
		goto out;
	}

	/*
	 * Initialize the AIL now we have a log.
@@ -601,6 +606,7 @@ xfs_log_mount(
	return 0;
error:
	xfs_log_unmount_dealloc(mp);
out:
	return error;
}	/* xfs_log_mount */

@@ -1217,7 +1223,9 @@ xlog_alloc_log(xfs_mount_t *mp,
	int			i;
	int			iclogsize;

	log = (xlog_t *)kmem_zalloc(sizeof(xlog_t), KM_SLEEP);
	log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
	if (!log)
		return NULL;

	log->l_mp	   = mp;
	log->l_targ	   = log_target;
@@ -1249,6 +1257,8 @@ xlog_alloc_log(xfs_mount_t *mp,
	xlog_get_iclog_buffer_size(mp, log);

	bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
	if (!bp)
		goto out_free_log;
	XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
	XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
	XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
@@ -1275,13 +1285,17 @@ xlog_alloc_log(xfs_mount_t *mp,
	iclogsize = log->l_iclog_size;
	ASSERT(log->l_iclog_size >= 4096);
	for (i=0; i < log->l_iclog_bufs; i++) {
		*iclogp = (xlog_in_core_t *)
			  kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
		*iclogp = kmem_zalloc(sizeof(xlog_in_core_t), KM_MAYFAIL);
		if (!*iclogp)
			goto out_free_iclog;

		iclog = *iclogp;
		iclog->ic_prev = prev_iclog;
		prev_iclog = iclog;

		bp = xfs_buf_get_noaddr(log->l_iclog_size, mp->m_logdev_targp);
		if (!bp)
			goto out_free_iclog;
		if (!XFS_BUF_CPSEMA(bp))
			ASSERT(0);
		XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
@@ -1323,6 +1337,25 @@ xlog_alloc_log(xfs_mount_t *mp,
	log->l_iclog->ic_prev = prev_iclog;	/* re-write 1st prev ptr */

	return log;

out_free_iclog:
	for (iclog = log->l_iclog; iclog; iclog = prev_iclog) {
		prev_iclog = iclog->ic_next;
		if (iclog->ic_bp) {
			sv_destroy(&iclog->ic_force_wait);
			sv_destroy(&iclog->ic_write_wait);
			xfs_buf_free(iclog->ic_bp);
			xlog_trace_iclog_dealloc(iclog);
		}
		kmem_free(iclog);
	}
	spinlock_destroy(&log->l_icloglock);
	spinlock_destroy(&log->l_grant_lock);
	xlog_trace_loggrant_dealloc(log);
	xfs_buf_free(log->l_xbuf);
out_free_log:
	kmem_free(log);
	return NULL;
}	/* xlog_alloc_log */


+7 −1
Original line number Diff line number Diff line
@@ -1419,7 +1419,13 @@ xlog_recover_add_to_trans(
		return 0;
	item = trans->r_itemq;
	if (item == NULL) {
		ASSERT(*(uint *)dp == XFS_TRANS_HEADER_MAGIC);
		/* we need to catch log corruptions here */
		if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) {
			xlog_warn("XFS: xlog_recover_add_to_trans: "
				  "bad header magic number");
			ASSERT(0);
			return XFS_ERROR(EIO);
		}
		if (len == sizeof(xfs_trans_header_t))
			xlog_recover_add_item(&trans->r_itemq);
		memcpy(&trans->r_theader, dp, len); /* d, s, l */
Loading