diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_alloc.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 289 | 
1 files changed, 186 insertions, 103 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index c20fe99405d8..3069194527dd 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1536,7 +1536,8 @@ xfs_alloc_ag_vextent_lastblock(   */  STATIC int  xfs_alloc_ag_vextent_near( -	struct xfs_alloc_arg	*args) +	struct xfs_alloc_arg	*args, +	uint32_t		alloc_flags)  {  	struct xfs_alloc_cur	acur = {};  	int			error;		/* error code */ @@ -1555,6 +1556,8 @@ xfs_alloc_ag_vextent_near(  	if (args->agbno > args->max_agbno)  		args->agbno = args->max_agbno; +	/* Retry once quickly if we find busy extents before blocking. */ +	alloc_flags |= XFS_ALLOC_FLAG_TRYFLUSH;  restart:  	len = 0; @@ -1610,9 +1613,20 @@ restart:  	 */  	if (!acur.len) {  		if (acur.busy) { +			/* +			 * Our only valid extents must have been busy. Flush and +			 * retry the allocation again. If we get an -EAGAIN +			 * error, we're being told that a deadlock was avoided +			 * and the current transaction needs committing before +			 * the allocation can be retried. +			 */  			trace_xfs_alloc_near_busy(args); -			xfs_extent_busy_flush(args->mp, args->pag, -					      acur.busy_gen); +			error = xfs_extent_busy_flush(args->tp, args->pag, +					acur.busy_gen, alloc_flags); +			if (error) +				goto out; + +			alloc_flags &= ~XFS_ALLOC_FLAG_TRYFLUSH;  			goto restart;  		}  		trace_xfs_alloc_size_neither(args); @@ -1635,22 +1649,25 @@ out:   * and of the form k * prod + mod unless there's nothing that large.   * Return the starting a.g. block, or NULLAGBLOCK if we can't do it.   */ -STATIC int				/* error */ +static int  xfs_alloc_ag_vextent_size( -	xfs_alloc_arg_t	*args)		/* allocation argument structure */ +	struct xfs_alloc_arg	*args, +	uint32_t		alloc_flags)  { -	struct xfs_agf	*agf = args->agbp->b_addr; -	struct xfs_btree_cur *bno_cur;	/* cursor for bno btree */ -	struct xfs_btree_cur *cnt_cur;	/* cursor for cnt btree */ -	int		error;		/* error result */ -	xfs_agblock_t	fbno;		/* start of found freespace */ -	xfs_extlen_t	flen;		/* length of found freespace */ -	int		i;		/* temp status variable */ -	xfs_agblock_t	rbno;		/* returned block number */ -	xfs_extlen_t	rlen;		/* length of returned extent */ -	bool		busy; -	unsigned	busy_gen; +	struct xfs_agf		*agf = args->agbp->b_addr; +	struct xfs_btree_cur	*bno_cur; +	struct xfs_btree_cur	*cnt_cur; +	xfs_agblock_t		fbno;		/* start of found freespace */ +	xfs_extlen_t		flen;		/* length of found freespace */ +	xfs_agblock_t		rbno;		/* returned block number */ +	xfs_extlen_t		rlen;		/* length of returned extent */ +	bool			busy; +	unsigned		busy_gen; +	int			error; +	int			i; +	/* Retry once quickly if we find busy extents before blocking. */ +	alloc_flags |= XFS_ALLOC_FLAG_TRYFLUSH;  restart:  	/*  	 * Allocate and initialize a cursor for the by-size btree. @@ -1708,19 +1725,25 @@ restart:  			error = xfs_btree_increment(cnt_cur, 0, &i);  			if (error)  				goto error0; -			if (i == 0) { -				/* -				 * Our only valid extents must have been busy. -				 * Make it unbusy by forcing the log out and -				 * retrying. -				 */ -				xfs_btree_del_cursor(cnt_cur, -						     XFS_BTREE_NOERROR); -				trace_xfs_alloc_size_busy(args); -				xfs_extent_busy_flush(args->mp, -							args->pag, busy_gen); -				goto restart; -			} +			if (i) +				continue; + +			/* +			 * Our only valid extents must have been busy. Flush and +			 * retry the allocation again. If we get an -EAGAIN +			 * error, we're being told that a deadlock was avoided +			 * and the current transaction needs committing before +			 * the allocation can be retried. +			 */ +			trace_xfs_alloc_size_busy(args); +			error = xfs_extent_busy_flush(args->tp, args->pag, +					busy_gen, alloc_flags); +			if (error) +				goto error0; + +			alloc_flags &= ~XFS_ALLOC_FLAG_TRYFLUSH; +			xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); +			goto restart;  		}  	} @@ -1800,9 +1823,21 @@ restart:  	args->len = rlen;  	if (rlen < args->minlen) {  		if (busy) { -			xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); +			/* +			 * Our only valid extents must have been busy. Flush and +			 * retry the allocation again. If we get an -EAGAIN +			 * error, we're being told that a deadlock was avoided +			 * and the current transaction needs committing before +			 * the allocation can be retried. +			 */  			trace_xfs_alloc_size_busy(args); -			xfs_extent_busy_flush(args->mp, args->pag, busy_gen); +			error = xfs_extent_busy_flush(args->tp, args->pag, +					busy_gen, alloc_flags); +			if (error) +				goto error0; + +			alloc_flags &= ~XFS_ALLOC_FLAG_TRYFLUSH; +			xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);  			goto restart;  		}  		goto out_nominleft; @@ -2435,23 +2470,25 @@ static int  xfs_defer_agfl_block(  	struct xfs_trans		*tp,  	xfs_agnumber_t			agno, -	xfs_fsblock_t			agbno, +	xfs_agblock_t			agbno,  	struct xfs_owner_info		*oinfo)  {  	struct xfs_mount		*mp = tp->t_mountp;  	struct xfs_extent_free_item	*xefi; +	xfs_fsblock_t			fsbno = XFS_AGB_TO_FSB(mp, agno, agbno);  	ASSERT(xfs_extfree_item_cache != NULL);  	ASSERT(oinfo != NULL); +	if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, fsbno))) +		return -EFSCORRUPTED; +  	xefi = kmem_cache_zalloc(xfs_extfree_item_cache,  			       GFP_KERNEL | __GFP_NOFAIL); -	xefi->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno); +	xefi->xefi_startblock = fsbno;  	xefi->xefi_blockcount = 1;  	xefi->xefi_owner = oinfo->oi_owner; - -	if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, xefi->xefi_startblock))) -		return -EFSCORRUPTED; +	xefi->xefi_agresv = XFS_AG_RESV_AGFL;  	trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1); @@ -2470,6 +2507,7 @@ __xfs_free_extent_later(  	xfs_fsblock_t			bno,  	xfs_filblks_t			len,  	const struct xfs_owner_info	*oinfo, +	enum xfs_ag_resv_type		type,  	bool				skip_discard)  {  	struct xfs_extent_free_item	*xefi; @@ -2490,6 +2528,7 @@ __xfs_free_extent_later(  	ASSERT(agbno + len <= mp->m_sb.sb_agblocks);  #endif  	ASSERT(xfs_extfree_item_cache != NULL); +	ASSERT(type != XFS_AG_RESV_AGFL);  	if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbext(mp, bno, len)))  		return -EFSCORRUPTED; @@ -2498,6 +2537,7 @@ __xfs_free_extent_later(  			       GFP_KERNEL | __GFP_NOFAIL);  	xefi->xefi_startblock = bno;  	xefi->xefi_blockcount = (xfs_extlen_t)len; +	xefi->xefi_agresv = type;  	if (skip_discard)  		xefi->xefi_flags |= XFS_EFI_SKIP_DISCARD;  	if (oinfo) { @@ -2568,7 +2608,7 @@ out:  int			/* error */  xfs_alloc_fix_freelist(  	struct xfs_alloc_arg	*args,	/* allocation argument structure */ -	int			flags)	/* XFS_ALLOC_FLAG_... */ +	uint32_t		alloc_flags)  {  	struct xfs_mount	*mp = args->mp;  	struct xfs_perag	*pag = args->pag; @@ -2584,7 +2624,7 @@ xfs_alloc_fix_freelist(  	ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);  	if (!xfs_perag_initialised_agf(pag)) { -		error = xfs_alloc_read_agf(pag, tp, flags, &agbp); +		error = xfs_alloc_read_agf(pag, tp, alloc_flags, &agbp);  		if (error) {  			/* Couldn't lock the AGF so skip this AG. */  			if (error == -EAGAIN) @@ -2600,13 +2640,13 @@ xfs_alloc_fix_freelist(  	 */  	if (xfs_perag_prefers_metadata(pag) &&  	    (args->datatype & XFS_ALLOC_USERDATA) && -	    (flags & XFS_ALLOC_FLAG_TRYLOCK)) { -		ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); +	    (alloc_flags & XFS_ALLOC_FLAG_TRYLOCK)) { +		ASSERT(!(alloc_flags & XFS_ALLOC_FLAG_FREEING));  		goto out_agbp_relse;  	}  	need = xfs_alloc_min_freelist(mp, pag); -	if (!xfs_alloc_space_available(args, need, flags | +	if (!xfs_alloc_space_available(args, need, alloc_flags |  			XFS_ALLOC_FLAG_CHECK))  		goto out_agbp_relse; @@ -2615,7 +2655,7 @@ xfs_alloc_fix_freelist(  	 * Can fail if we're not blocking on locks, and it's held.  	 */  	if (!agbp) { -		error = xfs_alloc_read_agf(pag, tp, flags, &agbp); +		error = xfs_alloc_read_agf(pag, tp, alloc_flags, &agbp);  		if (error) {  			/* Couldn't lock the AGF so skip this AG. */  			if (error == -EAGAIN) @@ -2630,7 +2670,7 @@ xfs_alloc_fix_freelist(  	/* If there isn't enough total space or single-extent, reject it. */  	need = xfs_alloc_min_freelist(mp, pag); -	if (!xfs_alloc_space_available(args, need, flags)) +	if (!xfs_alloc_space_available(args, need, alloc_flags))  		goto out_agbp_relse;  #ifdef DEBUG @@ -2668,11 +2708,12 @@ xfs_alloc_fix_freelist(  	 */  	memset(&targs, 0, sizeof(targs));  	/* struct copy below */ -	if (flags & XFS_ALLOC_FLAG_NORMAP) +	if (alloc_flags & XFS_ALLOC_FLAG_NORMAP)  		targs.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;  	else  		targs.oinfo = XFS_RMAP_OINFO_AG; -	while (!(flags & XFS_ALLOC_FLAG_NOSHRINK) && pag->pagf_flcount > need) { +	while (!(alloc_flags & XFS_ALLOC_FLAG_NOSHRINK) && +			pag->pagf_flcount > need) {  		error = xfs_alloc_get_freelist(pag, tp, agbp, &bno, 0);  		if (error)  			goto out_agbp_relse; @@ -2700,7 +2741,7 @@ xfs_alloc_fix_freelist(  		targs.resv = XFS_AG_RESV_AGFL;  		/* Allocate as many blocks as possible at once. */ -		error = xfs_alloc_ag_vextent_size(&targs); +		error = xfs_alloc_ag_vextent_size(&targs, alloc_flags);  		if (error)  			goto out_agflbp_relse; @@ -2710,7 +2751,7 @@ xfs_alloc_fix_freelist(  		 * on a completely full ag.  		 */  		if (targs.agbno == NULLAGBLOCK) { -			if (flags & XFS_ALLOC_FLAG_FREEING) +			if (alloc_flags & XFS_ALLOC_FLAG_FREEING)  				break;  			goto out_agflbp_relse;  		} @@ -2916,6 +2957,47 @@ xfs_alloc_put_freelist(  }  /* + * Check that this AGF/AGI header's sequence number and length matches the AG + * number and size in fsblocks. + */ +xfs_failaddr_t +xfs_validate_ag_length( +	struct xfs_buf		*bp, +	uint32_t		seqno, +	uint32_t		length) +{ +	struct xfs_mount	*mp = bp->b_mount; +	/* +	 * During growfs operations, the perag is not fully initialised, +	 * so we can't use it for any useful checking. growfs ensures we can't +	 * use it by using uncached buffers that don't have the perag attached +	 * so we can detect and avoid this problem. +	 */ +	if (bp->b_pag && seqno != bp->b_pag->pag_agno) +		return __this_address; + +	/* +	 * Only the last AG in the filesystem is allowed to be shorter +	 * than the AG size recorded in the superblock. +	 */ +	if (length != mp->m_sb.sb_agblocks) { +		/* +		 * During growfs, the new last AG can get here before we +		 * have updated the superblock. Give it a pass on the seqno +		 * check. +		 */ +		if (bp->b_pag && seqno != mp->m_sb.sb_agcount - 1) +			return __this_address; +		if (length < XFS_MIN_AG_BLOCKS) +			return __this_address; +		if (length > mp->m_sb.sb_agblocks) +			return __this_address; +	} + +	return NULL; +} + +/*   * Verify the AGF is consistent.   *   * We do not verify the AGFL indexes in the AGF are fully consistent here @@ -2934,6 +3016,9 @@ xfs_agf_verify(  {  	struct xfs_mount	*mp = bp->b_mount;  	struct xfs_agf		*agf = bp->b_addr; +	xfs_failaddr_t		fa; +	uint32_t		agf_seqno = be32_to_cpu(agf->agf_seqno); +	uint32_t		agf_length = be32_to_cpu(agf->agf_length);  	if (xfs_has_crc(mp)) {  		if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) @@ -2945,18 +3030,26 @@ xfs_agf_verify(  	if (!xfs_verify_magic(bp, agf->agf_magicnum))  		return __this_address; -	if (!(XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && -	      be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && -	      be32_to_cpu(agf->agf_flfirst) < xfs_agfl_size(mp) && -	      be32_to_cpu(agf->agf_fllast) < xfs_agfl_size(mp) && -	      be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp))) +	if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)))  		return __this_address; -	if (be32_to_cpu(agf->agf_length) > mp->m_sb.sb_dblocks) +	/* +	 * Both agf_seqno and agf_length need to validated before anything else +	 * block number related in the AGF or AGFL can be checked. +	 */ +	fa = xfs_validate_ag_length(bp, agf_seqno, agf_length); +	if (fa) +		return fa; + +	if (be32_to_cpu(agf->agf_flfirst) >= xfs_agfl_size(mp)) +		return __this_address; +	if (be32_to_cpu(agf->agf_fllast) >= xfs_agfl_size(mp)) +		return __this_address; +	if (be32_to_cpu(agf->agf_flcount) > xfs_agfl_size(mp))  		return __this_address;  	if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) || -	    be32_to_cpu(agf->agf_freeblks) > be32_to_cpu(agf->agf_length)) +	    be32_to_cpu(agf->agf_freeblks) > agf_length)  		return __this_address;  	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || @@ -2967,38 +3060,28 @@ xfs_agf_verify(  						mp->m_alloc_maxlevels)  		return __this_address; -	if (xfs_has_rmapbt(mp) && -	    (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 || -	     be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > -						mp->m_rmap_maxlevels)) -		return __this_address; - -	if (xfs_has_rmapbt(mp) && -	    be32_to_cpu(agf->agf_rmap_blocks) > be32_to_cpu(agf->agf_length)) +	if (xfs_has_lazysbcount(mp) && +	    be32_to_cpu(agf->agf_btreeblks) > agf_length)  		return __this_address; -	/* -	 * during growfs operations, the perag is not fully initialised, -	 * so we can't use it for any useful checking. growfs ensures we can't -	 * use it by using uncached buffers that don't have the perag attached -	 * so we can detect and avoid this problem. -	 */ -	if (bp->b_pag && be32_to_cpu(agf->agf_seqno) != bp->b_pag->pag_agno) -		return __this_address; +	if (xfs_has_rmapbt(mp)) { +		if (be32_to_cpu(agf->agf_rmap_blocks) > agf_length) +			return __this_address; -	if (xfs_has_lazysbcount(mp) && -	    be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length)) -		return __this_address; +		if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 || +		    be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > +							mp->m_rmap_maxlevels) +			return __this_address; +	} -	if (xfs_has_reflink(mp) && -	    be32_to_cpu(agf->agf_refcount_blocks) > -	    be32_to_cpu(agf->agf_length)) -		return __this_address; +	if (xfs_has_reflink(mp)) { +		if (be32_to_cpu(agf->agf_refcount_blocks) > agf_length) +			return __this_address; -	if (xfs_has_reflink(mp) && -	    (be32_to_cpu(agf->agf_refcount_level) < 1 || -	     be32_to_cpu(agf->agf_refcount_level) > mp->m_refc_maxlevels)) -		return __this_address; +		if (be32_to_cpu(agf->agf_refcount_level) < 1 || +		    be32_to_cpu(agf->agf_refcount_level) > mp->m_refc_maxlevels) +			return __this_address; +	}  	return NULL;  } @@ -3226,7 +3309,7 @@ xfs_alloc_vextent_check_args(  static int  xfs_alloc_vextent_prepare_ag(  	struct xfs_alloc_arg	*args, -	uint32_t		flags) +	uint32_t		alloc_flags)  {  	bool			need_pag = !args->pag;  	int			error; @@ -3235,7 +3318,7 @@ xfs_alloc_vextent_prepare_ag(  		args->pag = xfs_perag_get(args->mp, args->agno);  	args->agbp = NULL; -	error = xfs_alloc_fix_freelist(args, flags); +	error = xfs_alloc_fix_freelist(args, alloc_flags);  	if (error) {  		trace_xfs_alloc_vextent_nofix(args);  		if (need_pag) @@ -3357,6 +3440,7 @@ xfs_alloc_vextent_this_ag(  {  	struct xfs_mount	*mp = args->mp;  	xfs_agnumber_t		minimum_agno; +	uint32_t		alloc_flags = 0;  	int			error;  	ASSERT(args->pag != NULL); @@ -3375,9 +3459,9 @@ xfs_alloc_vextent_this_ag(  		return error;  	} -	error = xfs_alloc_vextent_prepare_ag(args, 0); +	error = xfs_alloc_vextent_prepare_ag(args, alloc_flags);  	if (!error && args->agbp) -		error = xfs_alloc_ag_vextent_size(args); +		error = xfs_alloc_ag_vextent_size(args, alloc_flags);  	return xfs_alloc_vextent_finish(args, minimum_agno, error, false);  } @@ -3406,20 +3490,20 @@ xfs_alloc_vextent_iterate_ags(  	xfs_agnumber_t		minimum_agno,  	xfs_agnumber_t		start_agno,  	xfs_agblock_t		target_agbno, -	uint32_t		flags) +	uint32_t		alloc_flags)  {  	struct xfs_mount	*mp = args->mp;  	xfs_agnumber_t		restart_agno = minimum_agno;  	xfs_agnumber_t		agno;  	int			error = 0; -	if (flags & XFS_ALLOC_FLAG_TRYLOCK) +	if (alloc_flags & XFS_ALLOC_FLAG_TRYLOCK)  		restart_agno = 0;  restart:  	for_each_perag_wrap_range(mp, start_agno, restart_agno,  			mp->m_sb.sb_agcount, agno, args->pag) {  		args->agno = agno; -		error = xfs_alloc_vextent_prepare_ag(args, flags); +		error = xfs_alloc_vextent_prepare_ag(args, alloc_flags);  		if (error)  			break;  		if (!args->agbp) { @@ -3433,10 +3517,10 @@ restart:  		 */  		if (args->agno == start_agno && target_agbno) {  			args->agbno = target_agbno; -			error = xfs_alloc_ag_vextent_near(args); +			error = xfs_alloc_ag_vextent_near(args, alloc_flags);  		} else {  			args->agbno = 0; -			error = xfs_alloc_ag_vextent_size(args); +			error = xfs_alloc_ag_vextent_size(args, alloc_flags);  		}  		break;  	} @@ -3453,8 +3537,8 @@ restart:  	 * constraining flags by the caller, drop them and retry the allocation  	 * without any constraints being set.  	 */ -	if (flags) { -		flags = 0; +	if (alloc_flags & XFS_ALLOC_FLAG_TRYLOCK) { +		alloc_flags &= ~XFS_ALLOC_FLAG_TRYLOCK;  		restart_agno = minimum_agno;  		goto restart;  	} @@ -3482,6 +3566,7 @@ xfs_alloc_vextent_start_ag(  	xfs_agnumber_t		start_agno;  	xfs_agnumber_t		rotorstep = xfs_rotorstep;  	bool			bump_rotor = false; +	uint32_t		alloc_flags = XFS_ALLOC_FLAG_TRYLOCK;  	int			error;  	ASSERT(args->pag == NULL); @@ -3508,7 +3593,7 @@ xfs_alloc_vextent_start_ag(  	start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target));  	error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, -			XFS_FSB_TO_AGBNO(mp, target), XFS_ALLOC_FLAG_TRYLOCK); +			XFS_FSB_TO_AGBNO(mp, target), alloc_flags);  	if (bump_rotor) {  		if (args->agno == start_agno) @@ -3535,6 +3620,7 @@ xfs_alloc_vextent_first_ag(  	struct xfs_mount	*mp = args->mp;  	xfs_agnumber_t		minimum_agno;  	xfs_agnumber_t		start_agno; +	uint32_t		alloc_flags = XFS_ALLOC_FLAG_TRYLOCK;  	int			error;  	ASSERT(args->pag == NULL); @@ -3553,7 +3639,7 @@ xfs_alloc_vextent_first_ag(  	start_agno = max(minimum_agno, XFS_FSB_TO_AGNO(mp, target));  	error = xfs_alloc_vextent_iterate_ags(args, minimum_agno, start_agno, -			XFS_FSB_TO_AGBNO(mp, target), 0); +			XFS_FSB_TO_AGBNO(mp, target), alloc_flags);  	return xfs_alloc_vextent_finish(args, minimum_agno, error, true);  } @@ -3606,6 +3692,7 @@ xfs_alloc_vextent_near_bno(  	struct xfs_mount	*mp = args->mp;  	xfs_agnumber_t		minimum_agno;  	bool			needs_perag = args->pag == NULL; +	uint32_t		alloc_flags = 0;  	int			error;  	if (!needs_perag) @@ -3626,9 +3713,9 @@ xfs_alloc_vextent_near_bno(  	if (needs_perag)  		args->pag = xfs_perag_grab(mp, args->agno); -	error = xfs_alloc_vextent_prepare_ag(args, 0); +	error = xfs_alloc_vextent_prepare_ag(args, alloc_flags);  	if (!error && args->agbp) -		error = xfs_alloc_ag_vextent_near(args); +		error = xfs_alloc_ag_vextent_near(args, alloc_flags);  	return xfs_alloc_vextent_finish(args, minimum_agno, error, needs_perag);  } @@ -3756,15 +3843,11 @@ xfs_alloc_query_range(  	xfs_alloc_query_range_fn		fn,  	void					*priv)  { -	union xfs_btree_irec			low_brec; -	union xfs_btree_irec			high_brec; -	struct xfs_alloc_query_range_info	query; +	union xfs_btree_irec			low_brec = { .a = *low_rec }; +	union xfs_btree_irec			high_brec = { .a = *high_rec }; +	struct xfs_alloc_query_range_info	query = { .priv = priv, .fn = fn };  	ASSERT(cur->bc_btnum == XFS_BTNUM_BNO); -	low_brec.a = *low_rec; -	high_brec.a = *high_rec; -	query.priv = priv; -	query.fn = fn;  	return xfs_btree_query_range(cur, &low_brec, &high_brec,  			xfs_alloc_query_range_helper, &query);  }  |