diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-10-10 11:47:16 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-10-10 11:47:16 -0700 | 
| commit | 9e208aa06c2109b45eec6be049a8e47034748c20 (patch) | |
| tree | 6f7a07ee2cc3c5558b7b39ef310f115a72825db6 | |
| parent | fb20da6af705597cefcf05fc99e48d5c066dbdff (diff) | |
| parent | aeea4b75f045294e1c026acc380466daa43afc65 (diff) | |
Merge tag 'xfs-5.4-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Darrick Wong:
 "A couple of small code cleanups and bug fixes for rounding errors,
  metadata logging errors, and an extra layer of safeguards against
  leaking memory contents.
   - Fix a rounding error in the fallocate code
   - Minor code cleanups
   - Make sure to zero memory buffers before formatting metadata blocks
   - Fix a few places where we forgot to log an inode metadata update
   - Remove broken error handling that tried to clean up after a failure
     but still got it wrong"
* tag 'xfs-5.4-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: move local to extent inode logging into bmap helper
  xfs: remove broken error handling on failed attr sf to leaf change
  xfs: log the inode on directory sf to block format change
  xfs: assure zeroed memory buffers for certain kmem allocations
  xfs: removed unused error variable from xchk_refcountbt_rec
  xfs: remove unused flags arg from xfs_get_aghdr_buf()
  xfs: Fix tail rounding in xfs_alloc_file_space()
| -rw-r--r-- | fs/xfs/libxfs/xfs_ag.c | 5 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.c | 21 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 6 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.h | 3 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2_block.c | 2 | ||||
| -rw-r--r-- | fs/xfs/scrub/refcount.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_util.c | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf.c | 12 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_recover.c | 2 | 
10 files changed, 29 insertions, 31 deletions
| diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 5de296b34ab1..14fbdf22b7e7 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -28,12 +28,11 @@ xfs_get_aghdr_buf(  	struct xfs_mount	*mp,  	xfs_daddr_t		blkno,  	size_t			numblks, -	int			flags,  	const struct xfs_buf_ops *ops)  {  	struct xfs_buf		*bp; -	bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags); +	bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0);  	if (!bp)  		return NULL; @@ -345,7 +344,7 @@ xfs_ag_init_hdr(  {  	struct xfs_buf		*bp; -	bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, 0, ops); +	bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, ops);  	if (!bp)  		return -ENOMEM; diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b9f019603d0b..f0089e862216 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -826,32 +826,17 @@ xfs_attr_shortform_to_leaf(  	sf = (xfs_attr_shortform_t *)tmpbuffer;  	xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); -	xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK); +	xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);  	bp = NULL;  	error = xfs_da_grow_inode(args, &blkno); -	if (error) { -		/* -		 * If we hit an IO error middle of the transaction inside -		 * grow_inode(), we may have inconsistent data. Bail out. -		 */ -		if (error == -EIO) -			goto out; -		xfs_idata_realloc(dp, size, XFS_ATTR_FORK);	/* try to put */ -		memcpy(ifp->if_u1.if_data, tmpbuffer, size);	/* it back */ +	if (error)  		goto out; -	}  	ASSERT(blkno == 0);  	error = xfs_attr3_leaf_create(args, blkno, &bp); -	if (error) { -		/* xfs_attr3_leaf_create may not have instantiated a block */ -		if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0)) -			goto out; -		xfs_idata_realloc(dp, size, XFS_ATTR_FORK);	/* try to put */ -		memcpy(ifp->if_u1.if_data, tmpbuffer, size);	/* it back */ +	if (error)  		goto out; -	}  	memset((char *)&nargs, 0, sizeof(nargs));  	nargs.dp = dp; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4edc25a2ba80..02469d59c787 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -792,6 +792,7 @@ out_root_realloc:   */  void  xfs_bmap_local_to_extents_empty( +	struct xfs_trans	*tp,  	struct xfs_inode	*ip,  	int			whichfork)  { @@ -808,6 +809,7 @@ xfs_bmap_local_to_extents_empty(  	ifp->if_u1.if_root = NULL;  	ifp->if_height = 0;  	XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); +	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  } @@ -840,7 +842,7 @@ xfs_bmap_local_to_extents(  	ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);  	if (!ifp->if_bytes) { -		xfs_bmap_local_to_extents_empty(ip, whichfork); +		xfs_bmap_local_to_extents_empty(tp, ip, whichfork);  		flags = XFS_ILOG_CORE;  		goto done;  	} @@ -887,7 +889,7 @@ xfs_bmap_local_to_extents(  	/* account for the change in fork size */  	xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); -	xfs_bmap_local_to_extents_empty(ip, whichfork); +	xfs_bmap_local_to_extents_empty(tp, ip, whichfork);  	flags |= XFS_ILOG_CORE;  	ifp->if_u1.if_root = NULL; diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 5bb446d80542..e2798c6f3a5f 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -182,7 +182,8 @@ void	xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,  		xfs_filblks_t len);  int	xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);  int	xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version); -void	xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); +void	xfs_bmap_local_to_extents_empty(struct xfs_trans *tp, +		struct xfs_inode *ip, int whichfork);  void	__xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,  		xfs_filblks_t len, const struct xfs_owner_info *oinfo,  		bool skip_discard); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9595ced393dc..49e4bc39e7bb 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1096,7 +1096,7 @@ xfs_dir2_sf_to_block(  	memcpy(sfp, oldsfp, ifp->if_bytes);  	xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK); -	xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK); +	xfs_bmap_local_to_extents_empty(tp, dp, XFS_DATA_FORK);  	dp->i_d.di_size = 0;  	/* diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index 93b3793bc5b3..0cab11a5d390 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -341,7 +341,6 @@ xchk_refcountbt_rec(  	xfs_extlen_t		len;  	xfs_nlink_t		refcount;  	bool			has_cowflag; -	int			error = 0;  	bno = be32_to_cpu(rec->refc.rc_startblock);  	len = be32_to_cpu(rec->refc.rc_blockcount); @@ -366,7 +365,7 @@ xchk_refcountbt_rec(  	xchk_refcountbt_xref(bs->sc, bno, len, refcount); -	return error; +	return 0;  }  /* Make sure we have as many refc blocks as the rmap says. */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 0910cb75b65d..4f443703065e 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -864,6 +864,7 @@ xfs_alloc_file_space(  	xfs_filblks_t		allocatesize_fsb;  	xfs_extlen_t		extsz, temp;  	xfs_fileoff_t		startoffset_fsb; +	xfs_fileoff_t		endoffset_fsb;  	int			nimaps;  	int			quota_flag;  	int			rt; @@ -891,7 +892,8 @@ xfs_alloc_file_space(  	imapp = &imaps[0];  	nimaps = 1;  	startoffset_fsb	= XFS_B_TO_FSBT(mp, offset); -	allocatesize_fsb = XFS_B_TO_FSB(mp, count); +	endoffset_fsb = XFS_B_TO_FSB(mp, offset + count); +	allocatesize_fsb = endoffset_fsb - startoffset_fsb;  	/*  	 * Allocate file space until done or until there is an error diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 21c243622a79..0abba171aa89 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -345,6 +345,15 @@ xfs_buf_allocate_memory(  	unsigned short		page_count, i;  	xfs_off_t		start, end;  	int			error; +	xfs_km_flags_t		kmflag_mask = 0; + +	/* +	 * assure zeroed buffer for non-read cases. +	 */ +	if (!(flags & XBF_READ)) { +		kmflag_mask |= KM_ZERO; +		gfp_mask |= __GFP_ZERO; +	}  	/*  	 * for buffers that are contained within a single page, just allocate @@ -354,7 +363,8 @@ xfs_buf_allocate_memory(  	size = BBTOB(bp->b_length);  	if (size < PAGE_SIZE) {  		int align_mask = xfs_buftarg_dma_alignment(bp->b_target); -		bp->b_addr = kmem_alloc_io(size, align_mask, KM_NOFS); +		bp->b_addr = kmem_alloc_io(size, align_mask, +					   KM_NOFS | kmflag_mask);  		if (!bp->b_addr) {  			/* low memory - use alloc_page loop instead */  			goto use_alloc_page; diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a2beee9f74da..641d07f30a27 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1443,7 +1443,7 @@ xlog_alloc_log(  		prev_iclog = iclog;  		iclog->ic_data = kmem_alloc_io(log->l_iclog_size, align_mask, -						KM_MAYFAIL); +						KM_MAYFAIL | KM_ZERO);  		if (!iclog->ic_data)  			goto out_free_iclog;  #ifdef DEBUG diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 508319039dce..c1a514ffff55 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -127,7 +127,7 @@ xlog_alloc_buffer(  	if (nbblks > 1 && log->l_sectBBsize > 1)  		nbblks += log->l_sectBBsize;  	nbblks = round_up(nbblks, log->l_sectBBsize); -	return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL); +	return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL | KM_ZERO);  }  /* | 
