diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_defer.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_defer.c | 40 | 
1 files changed, 19 insertions, 21 deletions
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 087fea02c389..c3e5bffda4f5 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -1,21 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+  /*   * Copyright (C) 2016 Oracle.  All Rights Reserved. - *   * Author: Darrick J. Wong <darrick.wong@oracle.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.   */  #include "xfs.h"  #include "xfs_fs.h" @@ -220,7 +206,7 @@ xfs_defer_trans_abort(  {  	struct xfs_defer_pending	*dfp; -	trace_xfs_defer_trans_abort(tp->t_mountp, dop); +	trace_xfs_defer_trans_abort(tp->t_mountp, dop, _RET_IP_);  	/* Abort intent items that don't have a done item. */  	list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { @@ -253,7 +239,7 @@ xfs_defer_trans_roll(  	for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++)  		xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); -	trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); +	trace_xfs_defer_trans_roll((*tp)->t_mountp, dop, _RET_IP_);  	/* Roll the transaction. */  	error = xfs_trans_roll(tp); @@ -352,10 +338,21 @@ xfs_defer_finish(  	void				*state;  	int				error = 0;  	void				(*cleanup_fn)(struct xfs_trans *, void *, int); +	struct xfs_defer_ops		*orig_dop;  	ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); -	trace_xfs_defer_finish((*tp)->t_mountp, dop); +	trace_xfs_defer_finish((*tp)->t_mountp, dop, _RET_IP_); + +	/* +	 * Attach dfops to the transaction during deferred ops processing. This +	 * explicitly causes calls into the allocator to defer AGFL block frees. +	 * Note that this code can go away once all dfops users attach to the +	 * associated tp. +	 */ +	ASSERT(!(*tp)->t_agfl_dfops || ((*tp)->t_agfl_dfops == dop)); +	orig_dop = (*tp)->t_agfl_dfops; +	(*tp)->t_agfl_dfops = dop;  	/* Until we run out of pending work to finish... */  	while (xfs_defer_has_unfinished_work(dop)) { @@ -428,10 +425,11 @@ xfs_defer_finish(  	}  out: +	(*tp)->t_agfl_dfops = orig_dop;  	if (error)  		trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error);  	else -		trace_xfs_defer_finish_done((*tp)->t_mountp, dop); +		trace_xfs_defer_finish_done((*tp)->t_mountp, dop, _RET_IP_);  	return error;  } @@ -447,7 +445,7 @@ xfs_defer_cancel(  	struct list_head		*pwi;  	struct list_head		*n; -	trace_xfs_defer_cancel(NULL, dop); +	trace_xfs_defer_cancel(NULL, dop, _RET_IP_);  	/*  	 * Free the pending items.  Caller should already have arranged @@ -532,5 +530,5 @@ xfs_defer_init(  	*fbp = NULLFSBLOCK;  	INIT_LIST_HEAD(&dop->dop_intake);  	INIT_LIST_HEAD(&dop->dop_pending); -	trace_xfs_defer_init(NULL, dop); +	trace_xfs_defer_init(NULL, dop, _RET_IP_);  }  | 
