xfs: condense dfops and automatic relogging
cover xfs: condense dfops and automatic relogging
Hi all,
Here is the (actual) final dfops cleanup series. ;P This essentially pares down xfs_defer_ops to a single list_head for queued deferred ops and folds said list into the transaction, eliminating the need for the xfs_defer_ops structure.
To facilitate this, the low free space mode flag is converted into a transaction flag and carried across tx rolls to preserve current behavior. The pending list is converted to an on-stack list with the help of a change to cancel pending ops on xfs_defer_finish() failure. The joined inode/buffer lists are also converted to on-stack lists once said items are automatically relogged across dfops transaction rolls via item hold/lock state.
The only real behavior change here should be patch 6 which adds the missing xfs_defer_ijoin() calls that would, in absence of patch 6, be implied by the automatic inode relogging patch. In other words, these are the inodes that patch 8 would start to relog that weren't relogged before. Technically patch 6 is unnecessary, but I had already identified these sites as part of the initial investigation and so figured it would be more clear to add them explicitly.
This survives xfstests and a weekend long fsstress run so far. I have some fsx testing in progress now.
Thoughts, reviews, flames appreciated.
Brian
Brian Foster (15):
xfs: refactor internal dfops initialization
xfs: use transaction for intent recovery instead of raw dfops
xfs: remove unused __xfs_defer_cancel() internal helper
xfs: pass transaction to dfops reset/move helpers
xfs: replace dop_low with transaction flag
xfs: add missing defer ijoins for held inodes
xfs: automatic dfops buffer relogging
xfs: automatic dfops inode relogging
xfs: drop dop param from xfs_defer_op_type ->finish_item() callback
xfs: clean out superfluous dfops dop params/vars
xfs: cancel dfops on xfs_defer_finish() error
xfs: replace xfs_defer_ops ->dop_pending with on-stack list
xfs: pass transaction to xfs_defer_add()
xfs: always defer agfl block frees
xfs: fold dfops into the transaction
fs/xfs/libxfs/xfs_alloc.c | 18 +-- fs/xfs/libxfs/xfs_attr.c | 26 +-- fs/xfs/libxfs/xfs_attr_remote.c | 6 +- fs/xfs/libxfs/xfs_bmap.c | 93 +++++------ fs/xfs/libxfs/xfs_bmap.h | 25 ++- fs/xfs/libxfs/xfs_bmap_btree.c | 6 +- fs/xfs/libxfs/xfs_btree.h | 1 - fs/xfs/libxfs/xfs_da_btree.h | 1 - fs/xfs/libxfs/xfs_defer.c | 273 ++++++++++++++------------------ fs/xfs/libxfs/xfs_defer.h | 28 +--- fs/xfs/libxfs/xfs_dir2.c | 2 - fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/libxfs/xfs_ialloc.c | 25 +-- fs/xfs/libxfs/xfs_refcount.c | 76 ++++----- fs/xfs/libxfs/xfs_refcount.h | 25 ++- fs/xfs/libxfs/xfs_rmap.c | 53 +++---- fs/xfs/libxfs/xfs_rmap.h | 22 ++- fs/xfs/libxfs/xfs_shared.h | 12 ++ fs/xfs/xfs_bmap_item.c | 20 ++- fs/xfs/xfs_bmap_item.h | 3 +- fs/xfs/xfs_bmap_util.c | 18 +-- fs/xfs/xfs_dquot.c | 3 +- fs/xfs/xfs_filestream.c | 3 +- fs/xfs/xfs_inode.c | 3 +- fs/xfs/xfs_inode.h | 1 - fs/xfs/xfs_log_recover.c | 42 +++-- fs/xfs/xfs_refcount_item.c | 30 ++-- fs/xfs/xfs_refcount_item.h | 3 +- fs/xfs/xfs_reflink.c | 33 ++-- fs/xfs/xfs_symlink.c | 1 - fs/xfs/xfs_trace.h | 40 ++--- fs/xfs/xfs_trans.c | 32 +--- fs/xfs/xfs_trans.h | 28 +--- fs/xfs/xfs_trans_bmap.c | 6 +- fs/xfs/xfs_trans_extfree.c | 2 - fs/xfs/xfs_trans_refcount.c | 6 +- fs/xfs/xfs_trans_rmap.c | 1 - 37 files changed, 394 insertions(+), 574 deletions(-)
Signature · 1 line
2.17.1
PATCH 1/15 xfs: refactor internal dfops initialization
The current transaction allocation code conditionally initializes the ->t_dfops indirection pointer. Transaction commit/cancel check the validity of the pointer to determine whether to finish/cancel the internal dfops.
This disallows the ability to use the internal dfops list as a temporary container (via xfs_trans_alloc_empty()). Refactor transaction allocation to always initialize ->t_dfops and check permanent reservation state on transaction commit/cancel.
--- fs/xfs/xfs_trans.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
fs/xfs/xfs_trans.c +3 -9
@@ -281,13 +281,7 @@ xfs_trans_alloc(INIT_LIST_HEAD (&tp->t_items);INIT_LIST_HEAD (&tp->t_busy); tp->t_firstblock =NULLFSBLOCK ; -/* -* We only roll transactions with permanent log reservation. Don't init -* ->t_dfops to skip attempts to finish or cancel an empty dfops with a -* non-permanent res. -*/ -if (resp->tr_logflags &XFS_TRANS_PERM_LOG_RES ) -xfs_defer_init (tp, &tp->t_dfops_internal); +xfs_defer_init (tp, &tp->t_dfops_internal); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error) {
@@ -932,7 +926,7 @@ __xfs_trans_commit(trace_xfs_trans_commit (tp, _RET_IP_);/* finish deferred items on final commit */ -if (!regrant && tp->t_dfops) { +if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) { error =xfs_defer_finish_noroll (&tp);if (error) {xfs_defer_cancel (tp);
@@ -1029,7 +1023,7 @@ xfs_trans_cancel(trace_xfs_trans_cancel (tp, _RET_IP_); -if (tp->t_dfops) +if (tp->t_flags &XFS_TRANS_PERM_LOG_RES )xfs_defer_cancel (tp);/*
Signature · 1 line
2.17.1
Re: [PATCH 01/15] xfs: refactor internal dfops initialization
Quoted 35 lines · Brian Foster
The current transaction allocation code conditionally initializes the ->t_dfops indirection pointer. Transaction commit/cancel check the validity of the pointer to determine whether to finish/cancel the internal dfops.
This disallows the ability to use the internal dfops list as a temporary container (via
xfs_trans_alloc_empty()). Refactor transaction allocation to always initialize ->t_dfops and check permanent reservation state on transaction commit/cancel.Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_trans.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)fs/xfs/xfs_trans.c +1
-7@@ -281,13 +281,7 @@ xfs_trans_alloc(INIT_LIST_HEAD (&tp->t_items);INIT_LIST_HEAD (&tp->t_busy); tp->t_firstblock =NULLFSBLOCK ; -/* -* We only roll transactions with permanent log reservation. Don't init -* ->t_dfops to skip attempts to finish or cancel an empty dfops with a -* non-permanent res. -*/ -if (resp->tr_logflags &XFS_TRANS_PERM_LOG_RES ) -xfs_defer_init (tp, &tp->t_dfops_internal); +xfs_defer_init (tp, &tp->t_dfops_internal); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error) {
fs/xfs/xfs_trans.c __xfs_trans_commit( · line 929
Quoted 5 lines
fs/xfs/xfs_trans.c +1
-1@@ -932,7 +926,7 @@ __xfs_trans_commit(trace_xfs_trans_commit (tp, _RET_IP_);/* finish deferred items on final commit */ -if (!regrant && tp->t_dfops) { +if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) {
The usage model of deferred ops is that one has to create a transaction with a permanent reservation, and only then start attaching deferred ops to the dfops inside the transaction. It's a programming error if a caller tries to finish deferred ops using a non-permanent transaction, and prior to this patch t_dfops would be NULL and we'd blow up immediately in xfs_defer_add(..., tp->t_dfops, ...);
However, now that we initialize t_dfops unconditionally, won't this cause the above programming mistake to leak silently any incorrectly queued defer ops?
--D
Quoted 19 lines
fs/xfs/xfs_trans.c +1
-1error =xfs_defer_finish_noroll (&tp);if (error) {xfs_defer_cancel (tp);@@ -1029,7 +1023,7 @@ xfs_trans_cancel(trace_xfs_trans_cancel (tp, _RET_IP_); -if (tp->t_dfops) +if (tp->t_flags &XFS_TRANS_PERM_LOG_RES )xfs_defer_cancel (tp);/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Christoph Hellwig
Reviewed-byRe: [PATCH 01/15] xfs: refactor internal dfops initialization
Quoted 13 lines · Darrick J. Wong
fs/xfs/xfs_trans.c __xfs_trans_commit( · line 929
Quoted 5 lines
fs/xfs/xfs_trans.c +1
-1trace_xfs_trans_commit (tp, _RET_IP_);/* finish deferred items on final commit */ -if (!regrant && tp->t_dfops) { +if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) {The usage model of deferred ops is that one has to create a transaction with a permanent reservation, and only then start attaching deferred ops to the dfops inside the transaction. It's a programming error if a caller tries to finish deferred ops using a non-permanent transaction, and prior to this patch
t_dfopswould be NULL and we'd blow up immediately inxfs_defer_add(..., tp->t_dfops, ...);
Quoted 3 lines
However, now that we initialize
t_dfopsunconditionally, won't this cause the above programming mistake to leak silently any incorrectly queued defer ops?
I guess we'll just need an assert for a perment reservation in xfs_defer_add, although that'll have to wait for the patch that actually passes a transaction to it.
Except for that this patch looks fine to me:
Re: [PATCH 01/15] xfs: refactor internal dfops initialization
In reply to Darrick J. WongQuoted 49 lines · Darrick J. Wong
Quoted 35 lines · Brian Foster
The current transaction allocation code conditionally initializes the ->t_dfops indirection pointer. Transaction commit/cancel check the validity of the pointer to determine whether to finish/cancel the internal dfops.
This disallows the ability to use the internal dfops list as a temporary container (via
xfs_trans_alloc_empty()). Refactor transaction allocation to always initialize ->t_dfops and check permanent reservation state on transaction commit/cancel.Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_trans.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)fs/xfs/xfs_trans.c +1
-7@@ -281,13 +281,7 @@ xfs_trans_alloc(INIT_LIST_HEAD (&tp->t_items);INIT_LIST_HEAD (&tp->t_busy); tp->t_firstblock =NULLFSBLOCK ; -/* -* We only roll transactions with permanent log reservation. Don't init -* ->t_dfops to skip attempts to finish or cancel an empty dfops with a -* non-permanent res. -*/ -if (resp->tr_logflags &XFS_TRANS_PERM_LOG_RES ) -xfs_defer_init (tp, &tp->t_dfops_internal); +xfs_defer_init (tp, &tp->t_dfops_internal); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error) {fs/xfs/xfs_trans.c __xfs_trans_commit( · line 929
Quoted 5 lines
fs/xfs/xfs_trans.c +1
-1@@ -932,7 +926,7 @@ __xfs_trans_commit(trace_xfs_trans_commit (tp, _RET_IP_);/* finish deferred items on final commit */ -if (!regrant && tp->t_dfops) { +if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) {The usage model of deferred ops is that one has to create a transaction with a permanent reservation, and only then start attaching deferred ops to the dfops inside the transaction. It's a programming error if a caller tries to finish deferred ops using a non-permanent transaction, and prior to this patch
t_dfopswould be NULL and we'd blow up immediately inxfs_defer_add(..., tp->t_dfops, ...);
Quoted 4 lines
However, now that we initialize
t_dfopsunconditionally, won't this cause the above programming mistake to leak silently any incorrectly queued defer ops?
Yeah, I'm not sure the previous behavior was really appropriate in that regard either. I'll add the xfs_defer_add() assert suggested by Christoph. We could also add a WARN_ON_ONCE() or something in the commit path to make sure we never see a !perm transaction with dfops, if you think that's useful..?
Brian
Quoted 25 lines
--D
Quoted 19 lines
fs/xfs/xfs_trans.c +1
-1error =xfs_defer_finish_noroll (&tp);if (error) {xfs_defer_cancel (tp);@@ -1029,7 +1023,7 @@ xfs_trans_cancel(trace_xfs_trans_cancel (tp, _RET_IP_); -if (tp->t_dfops) +if (tp->t_flags &XFS_TRANS_PERM_LOG_RES )xfs_defer_cancel (tp);/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/15] xfs: refactor internal dfops initialization
Quoted 55 lines · Brian Foster
Quoted 49 lines · Darrick J. Wong
Quoted 35 lines · Brian Foster
The current transaction allocation code conditionally initializes the ->t_dfops indirection pointer. Transaction commit/cancel check the validity of the pointer to determine whether to finish/cancel the internal dfops.
This disallows the ability to use the internal dfops list as a temporary container (via
xfs_trans_alloc_empty()). Refactor transaction allocation to always initialize ->t_dfops and check permanent reservation state on transaction commit/cancel.Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_trans.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)fs/xfs/xfs_trans.c +1
-7@@ -281,13 +281,7 @@ xfs_trans_alloc(INIT_LIST_HEAD (&tp->t_items);INIT_LIST_HEAD (&tp->t_busy); tp->t_firstblock =NULLFSBLOCK ; -/* -* We only roll transactions with permanent log reservation. Don't init -* ->t_dfops to skip attempts to finish or cancel an empty dfops with a -* non-permanent res. -*/ -if (resp->tr_logflags &XFS_TRANS_PERM_LOG_RES ) -xfs_defer_init (tp, &tp->t_dfops_internal); +xfs_defer_init (tp, &tp->t_dfops_internal); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error) {fs/xfs/xfs_trans.c __xfs_trans_commit( · line 929
Quoted 5 lines
fs/xfs/xfs_trans.c +1
-1@@ -932,7 +926,7 @@ __xfs_trans_commit(trace_xfs_trans_commit (tp, _RET_IP_);/* finish deferred items on final commit */ -if (!regrant && tp->t_dfops) { +if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) {The usage model of deferred ops is that one has to create a transaction with a permanent reservation, and only then start attaching deferred ops to the dfops inside the transaction. It's a programming error if a caller tries to finish deferred ops using a non-permanent transaction, and prior to this patch
t_dfopswould be NULL and we'd blow up immediately inxfs_defer_add(..., tp->t_dfops, ...);Quoted 4 lines
However, now that we initialize
t_dfopsunconditionally, won't this cause the above programming mistake to leak silently any incorrectly queued defer ops?
Quoted 5 lines
Yeah, I'm not sure the previous behavior was really appropriate in that regard either. I'll add the
xfs_defer_add()assert suggested by Christoph. We could also add aWARN_ON_ONCE()or something in the commit path to make sure we never see a !perm transaction with dfops, if you think that's useful..?
Yes -- some sort of warning that will help us catch programming mistakes even if !DEBUG. :)
--D
Quoted 31 lines
Brian
Quoted 17 lines
--D
Quoted 15 lines
fs/xfs/xfs_trans.c +1
-1error =xfs_defer_finish_noroll (&tp);if (error) {xfs_defer_cancel (tp);@@ -1029,7 +1023,7 @@ xfs_trans_cancel(trace_xfs_trans_cancel (tp, _RET_IP_); -if (tp->t_dfops) +if (tp->t_flags &XFS_TRANS_PERM_LOG_RES )xfs_defer_cancel (tp);/* Signature · 1 line
2.17.1Quoted 8 lines
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/15 xfs: use transaction for intent recovery instead of raw dfops
In reply to Brian FosterLog intent recovery is the last user of an external (on-stack) dfops. The pattern exists because the dfops is used to collect additional deferred operations queued during the whole recovery sequence. The dfops is finished with a new transaction after intent recovery completes.
We already have a mechanism to create an empty, container-like transaction to support the scrub infrastructure. We can reuse that mechanism here to drop the final user of external dfops. This facilitates folding dfops state (i.e., dop_low) into the transaction, the elimination of now unused external dfops support and also eliminates the only caller of __xfs_defer_cancel().
Replace the on-stack dfops with an empty transaction and pass it around to the various helpers that queue and finish deferred operations during intent recovery.
--- fs/xfs/xfs_bmap_item.c | 12 +++++------ fs/xfs/xfs_bmap_item.h | 3 +-- fs/xfs/xfs_log_recover.c | 42 ++++++++++++++++++-------------------- fs/xfs/xfs_refcount_item.c | 12 +++++------ fs/xfs/xfs_refcount_item.h | 3 +-- 5 files changed, 34 insertions(+), 38 deletions(-)
fs/xfs/xfs_bmap_item.c +6 -6
@@ -375,9 +375,8 @@ xfs_bud_init(*/ int xfs_bui_recover ( -struct xfs_mount *mp, -struct xfs_bui_log_item *buip, -struct xfs_defer_ops *dfops) +struct xfs_trans *itp, +struct xfs_bui_log_item *buip) {int error =0 ;unsigned int bui_type;
@@ -393,6 +392,7 @@ xfs_bui_recover(struct xfs_trans *tp;struct xfs_inode *ip =NULL ;struct xfs_bmbt_irec irec; +struct xfs_mount *mp = itp->t_mountp;ASSERT (!test_bit (XFS_BUI_RECOVERED , &buip->bui_flags));
@@ -446,7 +446,7 @@ xfs_bui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops); budp =xfs_trans_get_bud (tp, buip);/* Grab the inode. */
@@ -494,7 +494,7 @@ xfs_bui_recover( }set_bit (XFS_BUI_RECOVERED , &buip->bui_flags); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );xfs_irele (ip);
@@ -502,7 +502,7 @@ xfs_bui_recover(return error; err_inode: -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops);xfs_trans_cancel (tp);if (ip) {xfs_iunlock (ip,XFS_ILOCK_EXCL );
fs/xfs/xfs_bmap_item.h +1 -2
@@ -79,7 +79,6 @@ struct xfs_bud_log_item *xfs_bud_init(struct xfs_mount *, struct xfs_bui_log_item *);void xfs_bui_item_free (struct xfs_bui_log_item *);void xfs_bui_release (struct xfs_bui_log_item *); -int xfs_bui_recover (struct xfs_mount *mp,struct xfs_bui_log_item *buip, -struct xfs_defer_ops *dfops); +int xfs_bui_recover (struct xfs_trans *itp,struct xfs_bui_log_item *buip);#endif /* __XFS_BMAP_ITEM_H__ */
fs/xfs/xfs_log_recover.c +20 -22
114 lines not on this page · raw message
fs/xfs/xfs_refcount_item.c +6 -6
@@ -380,9 +380,8 @@ xfs_cud_init(*/ int xfs_cui_recover ( -struct xfs_mount *mp, -struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops) +struct xfs_trans *itp, +struct xfs_cui_log_item *cuip) {int i;int error =0 ;
@@ -398,6 +397,7 @@ xfs_cui_recover(xfs_extlen_t new_len;struct xfs_bmbt_irec irec;bool requeue_only = false; +struct xfs_mount *mp = itp->t_mountp;ASSERT (!test_bit (XFS_CUI_RECOVERED , &cuip->cui_flags));
@@ -457,7 +457,7 @@ xfs_cui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops); cudp =xfs_trans_get_cud (tp, cuip);for (i =0 ; i < cuip->cui_format.cui_nextents; i++) {
@@ -522,13 +522,13 @@ xfs_cui_recover(xfs_refcount_finish_one_cleanup (tp, rcur, error);set_bit (XFS_CUI_RECOVERED , &cuip->cui_flags); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops); error =xfs_trans_commit (tp);return error; abort_error:xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops);xfs_trans_cancel (tp);return error; }
fs/xfs/xfs_refcount_item.h +1 -2
@@ -82,7 +82,6 @@ struct xfs_cud_log_item *xfs_cud_init(struct xfs_mount *, struct xfs_cui_log_item *);void xfs_cui_item_free (struct xfs_cui_log_item *);void xfs_cui_release (struct xfs_cui_log_item *); -int xfs_cui_recover (struct xfs_mount *mp,struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops); +int xfs_cui_recover (struct xfs_trans *itp,struct xfs_cui_log_item *cuip);#endif /* __XFS_REFCOUNT_ITEM_H__ */
Signature · 1 line
2.17.1
Re: [PATCH 02/15] xfs: use transaction for intent recovery instead of raw dfops
Quoted 31 lines · Brian Foster
Log intent recovery is the last user of an external (on-stack) dfops. The pattern exists because the dfops is used to collect additional deferred operations queued during the whole recovery sequence. The dfops is finished with a new transaction after intent recovery completes.
We already have a mechanism to create an empty, container-like transaction to support the scrub infrastructure. We can reuse that mechanism here to drop the final user of external dfops. This facilitates folding dfops state (i.e.,
dop_low) into the transaction, the elimination of now unused external dfops support and also eliminates the only caller of__xfs_defer_cancel().Replace the on-stack dfops with an empty transaction and pass it around to the various helpers that queue and finish deferred operations during intent recovery.
Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_bmap_item.c | 12 +++++------ fs/xfs/xfs_bmap_item.h | 3 +-- fs/xfs/xfs_log_recover.c | 42 ++++++++++++++++++-------------------- fs/xfs/xfs_refcount_item.c | 12 +++++------ fs/xfs/xfs_refcount_item.h | 3 +-- 5 files changed, 34 insertions(+), 38 deletions(-)fs/xfs/xfs_bmap_item.c +0
-0
fs/xfs/xfs_bmap_item.c xfs_bud_init( · line 378
Quoted 7 lines
fs/xfs/xfs_bmap_item.c +1
-3@@ -375,9 +375,8 @@ xfs_bud_init(*/ int xfs_bui_recover( -struct xfs_mount *mp, -struct xfs_bui_log_item *buip, -struct xfs_defer_ops *dfops) + struct xfs_trans *itp,
"itp"?
Oh, the intent-holder transaction...
Quoted 57 lines
fs/xfs/xfs_bmap_item.c +5
-3+ struct xfs_bui_log_item *buip) {int error =0 ;unsigned int bui_type;@@ -393,6 +392,7 @@ xfs_bui_recover(struct xfs_trans *tp;struct xfs_inode *ip =NULL ;struct xfs_bmbt_irec irec; +struct xfs_mount *mp = itp->t_mountp;ASSERT (!test_bit (XFS_BUI_RECOVERED , &buip->bui_flags));@@ -446,7 +446,7 @@ xfs_bui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops); budp =xfs_trans_get_bud (tp, buip);/* Grab the inode. */ @@ -494,7 +494,7 @@ xfs_bui_recover( }set_bit (XFS_BUI_RECOVERED , &buip->bui_flags); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );xfs_irele (ip);@@ -502,7 +502,7 @@ xfs_bui_recover(return error; err_inode: -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops);xfs_trans_cancel (tp);if (ip) {xfs_iunlock (ip,XFS_ILOCK_EXCL );fs/xfs/xfs_bmap_item.h +1
-2@@ -79,7 +79,6 @@ struct xfs_bud_log_item *xfs_bud_init(struct xfs_mount *, struct xfs_bui_log_item *);void xfs_bui_item_free (struct xfs_bui_log_item *);void xfs_bui_release (struct xfs_bui_log_item *); -int xfs_bui_recover (struct xfs_mount *mp,struct xfs_bui_log_item *buip, -struct xfs_defer_ops *dfops); +int xfs_bui_recover (struct xfs_trans *itp,struct xfs_bui_log_item *buip);#endif /* __XFS_BMAP_ITEM_H__ */ fs/xfs/xfs_log_recover.c +0
-0
fs/xfs/xfs_log_recover.c xlog_recover_cancel_rui( · line 4736
Quoted 5 lines
fs/xfs/xfs_log_recover.c +1
-1@@ -4733,10 +4733,9 @@ xlog_recover_cancel_rui(/* Recover the CUI if necessary. */ STATIC int xlog_recover_process_cui( - struct xfs_mount *mp, + struct xfs_trans *tp,
This parameter is the intent-placeholder transaction, right? Shouldn't it be "itp"?
Quoted 65 lines
fs/xfs/xfs_log_recover.c +9
-11struct xfs_ail *ailp, - struct xfs_log_item *lip, - struct xfs_defer_ops *dfops) + struct xfs_log_item *lip) { struct xfs_cui_log_item *cuip;int error;@@ -4749,7 +4748,7 @@ xlog_recover_process_cui(return 0 ;spin_unlock (&ailp->ail_lock); - error =xfs_cui_recover (mp, cuip, dfops); + error =xfs_cui_recover (tp, cuip);spin_lock (&ailp->ail_lock);return error;@@ -4774,10 +4773,9 @@ xlog_recover_cancel_cui(/* Recover the BUI if necessary. */ STATIC intxlog_recover_process_bui ( -struct xfs_mount *mp, +struct xfs_trans *tp,struct xfs_ail *ailp, -struct xfs_log_item *lip, -struct xfs_defer_ops *dfops) +struct xfs_log_item *lip) {struct xfs_bui_log_item *buip;int error;@@ -4790,7 +4788,7 @@ xlog_recover_process_bui(return 0 ;spin_unlock (&ailp->ail_lock); - error =xfs_bui_recover (mp, buip, dfops); + error =xfs_bui_recover (tp, buip);spin_lock (&ailp->ail_lock);return error;@@ -4829,9 +4827,9 @@ static inline bool xlog_item_is_intent(struct xfs_log_item *lip)/* Take all the collected deferred ops and finish them in order. */ static int xlog_finish_defer_ops ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops) +struct xfs_trans *itp) { +struct xfs_mount *mp = itp->t_mountp;struct xfs_trans *tp;int64_t freeblks;uint resblks;@@ -4855,7 +4853,7 @@ xlog_finish_defer_ops(if (error)return error;/* transfer all collected dfops to this transaction */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops);return xfs_trans_commit (tp); }@@ -4880,22 +4878,25 @@ STATIC intxlog_recover_process_intents ( struct xlog *log) { -struct xfs_defer_ops dfops; +struct xfs_trans *tp;
fs/xfs/xfs_log_recover.c STATIC int · line 4890
Quoted 10 lines
fs/xfs/xfs_log_recover.c +2
-1struct xfs_ail_cursor cur;struct xfs_log_item *lip;struct xfs_ail *ailp; -int error =0 ; +int error;#if defined(DEBUG ) || defined(XFS_WARN )xfs_lsn_t last_lsn;#endif + error =xfs_trans_alloc_empty (log->l_mp, &tp);
Here's where we allocate the intent-placeholder transaction, so why isn't this named "itp" as well?
I think I have a handle on what this patch does, though the variable naming itp/tp is a little confusing.
--D
Quoted 111 lines
fs/xfs/xfs_log_recover.c +8
-9+if (error) +return error; + ailp = log->l_ailp;spin_lock (&ailp->ail_lock); lip =xfs_trans_ail_cursor_first (ailp, &cur,0 );#if defined(DEBUG ) || defined(XFS_WARN ) last_lsn =xlog_assign_lsn (log->l_curr_cycle, log->l_curr_block);#endif -xfs_defer_init (NULL , &dfops);while (lip !=NULL ) {/* * We're done when we see something other than an intent. @@ -4930,12 +4931,10 @@ xlog_recover_process_intents( error =xlog_recover_process_rui (log->l_mp, ailp, lip);break ;case XFS_LI_CUI : - error =xlog_recover_process_cui (log->l_mp, ailp, lip, - &dfops); + error =xlog_recover_process_cui (tp, ailp, lip);break ;case XFS_LI_BUI : - error =xlog_recover_process_bui (log->l_mp, ailp, lip, - &dfops); + error =xlog_recover_process_bui (tp, ailp, lip);break ; }if (error)@@ -4945,10 +4944,9 @@ xlog_recover_process_intents( out:xfs_trans_ail_cursor_done (&cur);spin_unlock (&ailp->ail_lock); -if (error) -__xfs_defer_cancel (&dfops); -else - error =xlog_finish_defer_ops (log->l_mp, &dfops); +if (!error) + error =xlog_finish_defer_ops (tp); +xfs_trans_cancel (tp);return error; }fs/xfs/xfs_refcount_item.c +6
-6@@ -380,9 +380,8 @@ xfs_cud_init(*/ int xfs_cui_recover ( -struct xfs_mount *mp, -struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops) +struct xfs_trans *itp, +struct xfs_cui_log_item *cuip) {int i;int error =0 ;@@ -398,6 +397,7 @@ xfs_cui_recover(xfs_extlen_t new_len;struct xfs_bmbt_irec irec;bool requeue_only = false; +struct xfs_mount *mp = itp->t_mountp;ASSERT (!test_bit (XFS_CUI_RECOVERED , &cuip->cui_flags));@@ -457,7 +457,7 @@ xfs_cui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops); cudp =xfs_trans_get_cud (tp, cuip);for (i =0 ; i < cuip->cui_format.cui_nextents; i++) {@@ -522,13 +522,13 @@ xfs_cui_recover(xfs_refcount_finish_one_cleanup (tp, rcur, error);set_bit (XFS_CUI_RECOVERED , &cuip->cui_flags); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops); error =xfs_trans_commit (tp);return error; abort_error:xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops);xfs_trans_cancel (tp);return error; }fs/xfs/xfs_refcount_item.h +1
-2@@ -82,7 +82,6 @@ struct xfs_cud_log_item *xfs_cud_init(struct xfs_mount *, struct xfs_cui_log_item *);void xfs_cui_item_free (struct xfs_cui_log_item *);void xfs_cui_release (struct xfs_cui_log_item *); -int xfs_cui_recover (struct xfs_mount *mp,struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops); +int xfs_cui_recover (struct xfs_trans *itp,struct xfs_cui_log_item *cuip);#endif /* __XFS_REFCOUNT_ITEM_H__ */ Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/15] xfs: use transaction for intent recovery instead of raw dfops
Quoted 8 lines · Darrick J. Wong
fs/xfs/xfs_bmap_item.c xfs_bud_init( · line 378
Quoted 4 lines
fs/xfs/xfs_bmap_item.c +1
-3-struct xfs_mount *mp, - struct xfs_bui_log_item *buip, - struct xfs_defer_ops *dfops) + struct xfs_trans *itp,"itp"?
Oh, the intent-holder transaction...
Maybe we should just call it parent_tp which would be a little less confusing?
Re: [PATCH 02/15] xfs: use transaction for intent recovery instead of raw dfops
In reply to Darrick J. WongQuoted 42 lines · Darrick J. Wong
Quoted 31 lines · Brian Foster
Log intent recovery is the last user of an external (on-stack) dfops. The pattern exists because the dfops is used to collect additional deferred operations queued during the whole recovery sequence. The dfops is finished with a new transaction after intent recovery completes.
We already have a mechanism to create an empty, container-like transaction to support the scrub infrastructure. We can reuse that mechanism here to drop the final user of external dfops. This facilitates folding dfops state (i.e.,
dop_low) into the transaction, the elimination of now unused external dfops support and also eliminates the only caller of__xfs_defer_cancel().Replace the on-stack dfops with an empty transaction and pass it around to the various helpers that queue and finish deferred operations during intent recovery.
Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_bmap_item.c | 12 +++++------ fs/xfs/xfs_bmap_item.h | 3 +-- fs/xfs/xfs_log_recover.c | 42 ++++++++++++++++++-------------------- fs/xfs/xfs_refcount_item.c | 12 +++++------ fs/xfs/xfs_refcount_item.h | 3 +-- 5 files changed, 34 insertions(+), 38 deletions(-)fs/xfs/xfs_bmap_item.c +0
-0fs/xfs/xfs_bmap_item.c xfs_bud_init( · line 378
Quoted 7 lines
fs/xfs/xfs_bmap_item.c +1
-3@@ -375,9 +375,8 @@ xfs_bud_init(*/ int xfs_bui_recover( -struct xfs_mount *mp, -struct xfs_bui_log_item *buip, -struct xfs_defer_ops *dfops) + struct xfs_trans *itp,"itp"?
Quoted 2 lines
Oh, the intent-holder transaction...
Yeah..
Quoted 4 lines
Quoted 4 lines
fs/xfs/xfs_bmap_item.c +1
-0+ struct xfs_bui_log_item *buip) {int error =0 ;unsigned int bui_type;
...
Quoted 4 lines
Quoted 4 lines
fs/xfs/xfs_log_recover.c +0
-0
...
Quoted 15 lines
Quoted 15 lines
fs/xfs/xfs_log_recover.c +2
-2@@ -4880,22 +4878,25 @@ STATIC intxlog_recover_process_intents ( struct xlog *log) { -struct xfs_defer_ops dfops; +struct xfs_trans *tp;struct xfs_ail_cursor cur;struct xfs_log_item *lip;struct xfs_ail *ailp; -int error =0 ; +int error;#if defined(DEBUG ) || defined(XFS_WARN )xfs_lsn_t last_lsn;#endif
Quoted 5 lines
fs/xfs/xfs_log_recover.c STATIC int · line 4890
Quoted 1 line
fs/xfs/xfs_log_recover.c +1
-0+ error =xfs_trans_alloc_empty (log->l_mp, &tp);Here's where we allocate the intent-placeholder transaction, so why isn't this named "itp" as well?
I only used itp where tp conflicted with a local transaction (the contexts where we have to transfer state back and forth between two transactions).
Quoted 3 lines
I think I have a handle on what this patch does, though the variable naming itp/tp is a little confusing.
I have no real preference on the naming. I can call it parent_tp as Christoph suggests and use that up and down the chain rather than only in the contexts where both transactions exist if you think that is more clear..?
Brian
Quoted 117 lines
--D
Quoted 111 lines
fs/xfs/xfs_log_recover.c +8
-9+if (error) +return error; + ailp = log->l_ailp;spin_lock (&ailp->ail_lock); lip =xfs_trans_ail_cursor_first (ailp, &cur,0 );#if defined(DEBUG ) || defined(XFS_WARN ) last_lsn =xlog_assign_lsn (log->l_curr_cycle, log->l_curr_block);#endif -xfs_defer_init (NULL , &dfops);while (lip !=NULL ) {/* * We're done when we see something other than an intent. @@ -4930,12 +4931,10 @@ xlog_recover_process_intents( error =xlog_recover_process_rui (log->l_mp, ailp, lip);break ;case XFS_LI_CUI : - error =xlog_recover_process_cui (log->l_mp, ailp, lip, - &dfops); + error =xlog_recover_process_cui (tp, ailp, lip);break ;case XFS_LI_BUI : - error =xlog_recover_process_bui (log->l_mp, ailp, lip, - &dfops); + error =xlog_recover_process_bui (tp, ailp, lip);break ; }if (error)@@ -4945,10 +4944,9 @@ xlog_recover_process_intents( out:xfs_trans_ail_cursor_done (&cur);spin_unlock (&ailp->ail_lock); -if (error) -__xfs_defer_cancel (&dfops); -else - error =xlog_finish_defer_ops (log->l_mp, &dfops); +if (!error) + error =xlog_finish_defer_ops (tp); +xfs_trans_cancel (tp);return error; }fs/xfs/xfs_refcount_item.c +6
-6@@ -380,9 +380,8 @@ xfs_cud_init(*/ int xfs_cui_recover ( -struct xfs_mount *mp, -struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops) +struct xfs_trans *itp, +struct xfs_cui_log_item *cuip) {int i;int error =0 ;@@ -398,6 +397,7 @@ xfs_cui_recover(xfs_extlen_t new_len;struct xfs_bmbt_irec irec;bool requeue_only = false; +struct xfs_mount *mp = itp->t_mountp;ASSERT (!test_bit (XFS_CUI_RECOVERED , &cuip->cui_flags));@@ -457,7 +457,7 @@ xfs_cui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops); cudp =xfs_trans_get_cud (tp, cuip);for (i =0 ; i < cuip->cui_format.cui_nextents; i++) {@@ -522,13 +522,13 @@ xfs_cui_recover(xfs_refcount_finish_one_cleanup (tp, rcur, error);set_bit (XFS_CUI_RECOVERED , &cuip->cui_flags); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops); error =xfs_trans_commit (tp);return error; abort_error:xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops);xfs_trans_cancel (tp);return error; }fs/xfs/xfs_refcount_item.h +1
-2@@ -82,7 +82,6 @@ struct xfs_cud_log_item *xfs_cud_init(struct xfs_mount *, struct xfs_cui_log_item *);void xfs_cui_item_free (struct xfs_cui_log_item *);void xfs_cui_release (struct xfs_cui_log_item *); -int xfs_cui_recover (struct xfs_mount *mp,struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops); +int xfs_cui_recover (struct xfs_trans *itp,struct xfs_cui_log_item *cuip);#endif /* __XFS_REFCOUNT_ITEM_H__ */ Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/15] xfs: use transaction for intent recovery instead of raw dfops
Quoted 83 lines · Brian Foster
Quoted 42 lines · Darrick J. Wong
Quoted 31 lines · Brian Foster
Log intent recovery is the last user of an external (on-stack) dfops. The pattern exists because the dfops is used to collect additional deferred operations queued during the whole recovery sequence. The dfops is finished with a new transaction after intent recovery completes.
We already have a mechanism to create an empty, container-like transaction to support the scrub infrastructure. We can reuse that mechanism here to drop the final user of external dfops. This facilitates folding dfops state (i.e.,
dop_low) into the transaction, the elimination of now unused external dfops support and also eliminates the only caller of__xfs_defer_cancel().Replace the on-stack dfops with an empty transaction and pass it around to the various helpers that queue and finish deferred operations during intent recovery.
Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_bmap_item.c | 12 +++++------ fs/xfs/xfs_bmap_item.h | 3 +-- fs/xfs/xfs_log_recover.c | 42 ++++++++++++++++++-------------------- fs/xfs/xfs_refcount_item.c | 12 +++++------ fs/xfs/xfs_refcount_item.h | 3 +-- 5 files changed, 34 insertions(+), 38 deletions(-)fs/xfs/xfs_bmap_item.c +0
-0fs/xfs/xfs_bmap_item.c xfs_bud_init( · line 378
Quoted 7 lines
fs/xfs/xfs_bmap_item.c +1
-3@@ -375,9 +375,8 @@ xfs_bud_init(*/ int xfs_bui_recover( -struct xfs_mount *mp, -struct xfs_bui_log_item *buip, -struct xfs_defer_ops *dfops) + struct xfs_trans *itp,"itp"?
Quoted 2 lines
Oh, the intent-holder transaction...
Yeah..
Quoted 4 lines
Quoted 4 lines
fs/xfs/xfs_bmap_item.c +1
-0+ struct xfs_bui_log_item *buip) {int error =0 ;unsigned int bui_type;...
Quoted 4 lines
Quoted 4 lines
fs/xfs/xfs_log_recover.c +0
-0...
Quoted 15 lines
Quoted 15 lines
fs/xfs/xfs_log_recover.c +2
-2@@ -4880,22 +4878,25 @@ STATIC intxlog_recover_process_intents ( struct xlog *log) { -struct xfs_defer_ops dfops; +struct xfs_trans *tp;struct xfs_ail_cursor cur;struct xfs_log_item *lip;struct xfs_ail *ailp; -int error =0 ; +int error;#if defined(DEBUG ) || defined(XFS_WARN )xfs_lsn_t last_lsn;#endif Quoted 5 lines
fs/xfs/xfs_log_recover.c STATIC int · line 4890
Quoted 1 line
fs/xfs/xfs_log_recover.c +1
-0+ error =xfs_trans_alloc_empty (log->l_mp, &tp);Here's where we allocate the intent-placeholder transaction, so why isn't this named "itp" as well?
I only used itp where tp conflicted with a local transaction (the contexts where we have to transfer state back and forth between two transactions).
Quoted 8 lines
Quoted 3 lines
I think I have a handle on what this patch does, though the variable naming itp/tp is a little confusing.
I have no real preference on the naming. I can call it
parent_tpas Christoph suggests and use that up and down the chain rather than only in the contexts where both transactions exist if you think that is more clear..?
Yes, please. The 'parent_tp' transaction is really just a holder for a dfops list that will eventually get finished with a non-empty transaction, so we should make it as clear as possible in the source code that the parent_tp is not for logging real work. :)
--D
Quoted 123 lines
Brian
Quoted 109 lines
--D
Quoted 107 lines
fs/xfs/xfs_log_recover.c +8
-9+if (error) +return error; + ailp = log->l_ailp;spin_lock (&ailp->ail_lock); lip =xfs_trans_ail_cursor_first (ailp, &cur,0 );#if defined(DEBUG ) || defined(XFS_WARN ) last_lsn =xlog_assign_lsn (log->l_curr_cycle, log->l_curr_block);#endif -xfs_defer_init (NULL , &dfops);while (lip !=NULL ) {/* * We're done when we see something other than an intent. @@ -4930,12 +4931,10 @@ xlog_recover_process_intents( error =xlog_recover_process_rui (log->l_mp, ailp, lip);break ;case XFS_LI_CUI : - error =xlog_recover_process_cui (log->l_mp, ailp, lip, - &dfops); + error =xlog_recover_process_cui (tp, ailp, lip);break ;case XFS_LI_BUI : - error =xlog_recover_process_bui (log->l_mp, ailp, lip, - &dfops); + error =xlog_recover_process_bui (tp, ailp, lip);break ; }if (error)@@ -4945,10 +4944,9 @@ xlog_recover_process_intents( out:xfs_trans_ail_cursor_done (&cur);spin_unlock (&ailp->ail_lock); -if (error) -__xfs_defer_cancel (&dfops); -else - error =xlog_finish_defer_ops (log->l_mp, &dfops); +if (!error) + error =xlog_finish_defer_ops (tp); +xfs_trans_cancel (tp);return error; }fs/xfs/xfs_refcount_item.c +6
-6@@ -380,9 +380,8 @@ xfs_cud_init(*/ int xfs_cui_recover ( -struct xfs_mount *mp, -struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops) +struct xfs_trans *itp, +struct xfs_cui_log_item *cuip) {int i;int error =0 ;@@ -398,6 +397,7 @@ xfs_cui_recover(xfs_extlen_t new_len;struct xfs_bmbt_irec irec;bool requeue_only = false; +struct xfs_mount *mp = itp->t_mountp;ASSERT (!test_bit (XFS_CUI_RECOVERED , &cuip->cui_flags));@@ -457,7 +457,7 @@ xfs_cui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, dfops); +xfs_defer_move (tp->t_dfops, itp->t_dfops); cudp =xfs_trans_get_cud (tp, cuip);for (i =0 ; i < cuip->cui_format.cui_nextents; i++) {@@ -522,13 +522,13 @@ xfs_cui_recover(xfs_refcount_finish_one_cleanup (tp, rcur, error);set_bit (XFS_CUI_RECOVERED , &cuip->cui_flags); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops); error =xfs_trans_commit (tp);return error; abort_error:xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (dfops, tp->t_dfops); +xfs_defer_move (itp->t_dfops, tp->t_dfops);xfs_trans_cancel (tp);return error; }fs/xfs/xfs_refcount_item.h +1
-2@@ -82,7 +82,6 @@ struct xfs_cud_log_item *xfs_cud_init(struct xfs_mount *, struct xfs_cui_log_item *);void xfs_cui_item_free (struct xfs_cui_log_item *);void xfs_cui_release (struct xfs_cui_log_item *); -int xfs_cui_recover (struct xfs_mount *mp,struct xfs_cui_log_item *cuip, -struct xfs_defer_ops *dfops); +int xfs_cui_recover (struct xfs_trans *itp,struct xfs_cui_log_item *cuip);#endif /* __XFS_REFCOUNT_ITEM_H__ */ Signature · 1 line
2.17.1Quoted 8 lines
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/15] xfs: use transaction for intent recovery instead of raw dfops
In reply to Brian Fosterfs/xfs/xfs_log_recover.c STATIC int · line 4893
Quoted 5 lines
fs/xfs/xfs_log_recover.c +4
-0+ error =xfs_trans_alloc_empty (log->l_mp, &tp); +if (error) +return error; +
I think we need a big comment explaining the use of this transaction here. Except for that and any naming issues:
PATCH 3/15 xfs: remove unused __xfs_defer_cancel() internal helper
In reply to Brian FosterWith no more external dfops users, there is no need for an xfs_defer_ops cancel wrapper.
--- fs/xfs/libxfs/xfs_defer.c | 5 +++-- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_trans.c | 7 ------- fs/xfs/xfs_trans.h | 3 --- 4 files changed, 4 insertions(+), 13 deletions(-)
fs/xfs/libxfs/xfs_defer.c +3 -2
@@ -465,9 +465,10 @@ xfs_defer_finish(* Free up any items left in the list. */ void -__xfs_defer_cancel ( -struct xfs_defer_ops *dop) +xfs_defer_cancel ( +struct xfs_trans *tp) { +struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;struct xfs_defer_pending *pli;struct list_head *pwi;
fs/xfs/libxfs/xfs_defer.h +1 -1
@@ -50,7 +50,7 @@ void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h);int xfs_defer_finish_noroll (struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp); -void __xfs_defer_cancel (struct xfs_defer_ops *dop); +void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip);
fs/xfs/xfs_trans.c +0 -7
@@ -1105,10 +1105,3 @@ xfs_trans_roll( tres.tr_logflags =XFS_TRANS_PERM_LOG_RES ;return xfs_trans_reserve (*tpp, &tres,0 ,0 ); } - -void -xfs_defer_cancel ( -struct xfs_trans *tp) -{ -__xfs_defer_cancel (tp->t_dfops); -}
fs/xfs/xfs_trans.h +0 -3
@@ -214,9 +214,6 @@ xfs_trans_read_buf( flags, bpp, ops); } -/* cancel dfops associated with a transaction */ -void xfs_defer_cancel (struct xfs_trans *); -struct xfs_buf *xfs_trans_getsb (xfs_trans_t *,struct xfs_mount *,int );void xfs_trans_brelse (xfs_trans_t *,struct xfs_buf *);
Signature · 1 line
2.17.1
Re: [PATCH 03/15] xfs: remove unused __xfs_defer_cancel() internal helper
Quoted 4 lines · Brian Foster
With no more external dfops users, there is no need for an
xfs_defer_opscancel wrapper.Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 73 lines
--- fs/xfs/libxfs/xfs_defer.c | 5 +++-- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_trans.c | 7 ------- fs/xfs/xfs_trans.h | 3 --- 4 files changed, 4 insertions(+), 13 deletions(-)fs/xfs/libxfs/xfs_defer.c +3
-2@@ -465,9 +465,10 @@ xfs_defer_finish(* Free up any items left in the list. */ void -__xfs_defer_cancel ( -struct xfs_defer_ops *dop) +xfs_defer_cancel ( +struct xfs_trans *tp) { +struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;struct xfs_defer_pending *pli;struct list_head *pwi;fs/xfs/libxfs/xfs_defer.h +1
-1@@ -50,7 +50,7 @@ void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h);int xfs_defer_finish_noroll (struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp); -void __xfs_defer_cancel (struct xfs_defer_ops *dop); +void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip);fs/xfs/xfs_trans.c +0
-7@@ -1105,10 +1105,3 @@ xfs_trans_roll( tres.tr_logflags =XFS_TRANS_PERM_LOG_RES ;return xfs_trans_reserve (*tpp, &tres,0 ,0 ); } - -void -xfs_defer_cancel ( -struct xfs_trans *tp) -{ -__xfs_defer_cancel (tp->t_dfops); -}fs/xfs/xfs_trans.h +0
-3@@ -214,9 +214,6 @@ xfs_trans_read_buf( flags, bpp, ops); } -/* cancel dfops associated with a transaction */ -void xfs_defer_cancel (struct xfs_trans *); -struct xfs_buf *xfs_trans_getsb (xfs_trans_t *,struct xfs_mount *,int );void xfs_trans_brelse (xfs_trans_t *,struct xfs_buf *);Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 03/15] xfs: remove unused __xfs_defer_cancel() internal helper
In reply to Brian FosterQuoted 4 lines · Brian Foster
With no more external dfops users, there is no need for an
xfs_defer_opscancel wrapper.Signed-off-by Brian Foster <[email protected]>
Looks good,
PATCH 4/15 xfs: pass transaction to dfops reset/move helpers
In reply to Brian FosterAll callers pass ->t_dfops of the associated transactions. Refactor the helpers to receive the transactions and facilitate further cleanups between xfs_defer_ops and xfs_trans.
--- fs/xfs/libxfs/xfs_defer.c | 15 ++++++++++----- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_bmap_item.c | 6 +++--- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_refcount_item.c | 6 +++--- fs/xfs/xfs_trans.c | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-)
fs/xfs/libxfs/xfs_defer.c +10 -5
@@ -324,9 +324,12 @@ xfs_defer_bjoin(*/ static void xfs_defer_reset ( -struct xfs_defer_ops *dop) +struct xfs_trans *tp) { +struct xfs_defer_ops *dop = tp->t_dfops; +ASSERT (!xfs_defer_has_unfinished_work (dop)); + dop->dop_low = false;memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes));memset (dop->dop_bufs,0 ,sizeof (dop->dop_bufs));
@@ -457,7 +460,7 @@ xfs_defer_finish(if (error)return error; } -xfs_defer_reset ((*tp)->t_dfops); +xfs_defer_reset (*tp);return 0 ; }
@@ -575,9 +578,11 @@ xfs_defer_init(*/ void xfs_defer_move ( -struct xfs_defer_ops *dst, -struct xfs_defer_ops *src) +struct xfs_trans *dtp, +struct xfs_trans *stp) { +struct xfs_defer_ops *dst = dtp->t_dfops; +struct xfs_defer_ops *src = stp->t_dfops;ASSERT (dst != src);list_splice_init (&src->dop_intake, &dst->dop_intake);
@@ -587,5 +592,5 @@ xfs_defer_move(memcpy (dst->dop_bufs, src->dop_bufs,sizeof (dst->dop_bufs)); dst->dop_low = src->dop_low; -xfs_defer_reset (src); +xfs_defer_reset (stp); }
fs/xfs/libxfs/xfs_defer.h +1 -1
@@ -55,7 +55,7 @@ void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip);int xfs_defer_bjoin (struct xfs_defer_ops *dop,struct xfs_buf *bp); -void xfs_defer_move (struct xfs_defer_ops *dst,struct xfs_defer_ops *src); +void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ struct xfs_defer_op_type {
fs/xfs/xfs_bmap_item.c +3 -3
@@ -446,7 +446,7 @@ xfs_bui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, itp->t_dfops); +xfs_defer_move (tp, itp); budp =xfs_trans_get_bud (tp, buip);/* Grab the inode. */
@@ -494,7 +494,7 @@ xfs_bui_recover( }set_bit (XFS_BUI_RECOVERED , &buip->bui_flags); -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );xfs_irele (ip);
@@ -502,7 +502,7 @@ xfs_bui_recover(return error; err_inode: -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp);xfs_trans_cancel (tp);if (ip) {xfs_iunlock (ip,XFS_ILOCK_EXCL );
fs/xfs/xfs_log_recover.c +1 -1
@@ -4853,7 +4853,7 @@ xlog_finish_defer_ops(if (error)return error;/* transfer all collected dfops to this transaction */ -xfs_defer_move (tp->t_dfops, itp->t_dfops); +xfs_defer_move (tp, itp);return xfs_trans_commit (tp); }
fs/xfs/xfs_refcount_item.c +3 -3
@@ -457,7 +457,7 @@ xfs_cui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, itp->t_dfops); +xfs_defer_move (tp, itp); cudp =xfs_trans_get_cud (tp, cuip);for (i =0 ; i < cuip->cui_format.cui_nextents; i++) {
@@ -522,13 +522,13 @@ xfs_cui_recover(xfs_refcount_finish_one_cleanup (tp, rcur, error);set_bit (XFS_CUI_RECOVERED , &cuip->cui_flags); -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp); error =xfs_trans_commit (tp);return error; abort_error:xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp);xfs_trans_cancel (tp);return error; }
fs/xfs/xfs_trans.c +1 -1
@@ -125,7 +125,7 @@ xfs_trans_dup(if (tp->t_dfops != &tp->t_dfops_internal) ntp->t_dfops = tp->t_dfops;else -xfs_defer_move (ntp->t_dfops, tp->t_dfops); +xfs_defer_move (ntp, tp);xfs_trans_dup_dqinfo (tp, ntp);
Signature · 1 line
2.17.1
Re: [PATCH 04/15] xfs: pass transaction to dfops reset/move helpers
Quoted 5 lines · Brian Foster
All callers pass ->t_dfops of the associated transactions. Refactor the helpers to receive the transactions and facilitate further cleanups between
xfs_defer_opsandxfs_trans.Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 163 lines
--- fs/xfs/libxfs/xfs_defer.c | 15 ++++++++++----- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_bmap_item.c | 6 +++--- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_refcount_item.c | 6 +++--- fs/xfs/xfs_trans.c | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-)fs/xfs/libxfs/xfs_defer.c +10
-5@@ -324,9 +324,12 @@ xfs_defer_bjoin(*/ static void xfs_defer_reset ( -struct xfs_defer_ops *dop) +struct xfs_trans *tp) { +struct xfs_defer_ops *dop = tp->t_dfops; +ASSERT (!xfs_defer_has_unfinished_work (dop)); + dop->dop_low = false;memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes));memset (dop->dop_bufs,0 ,sizeof (dop->dop_bufs));@@ -457,7 +460,7 @@ xfs_defer_finish(if (error)return error; } -xfs_defer_reset ((*tp)->t_dfops); +xfs_defer_reset (*tp);return 0 ; }@@ -575,9 +578,11 @@ xfs_defer_init(*/ void xfs_defer_move ( -struct xfs_defer_ops *dst, -struct xfs_defer_ops *src) +struct xfs_trans *dtp, +struct xfs_trans *stp) { +struct xfs_defer_ops *dst = dtp->t_dfops; +struct xfs_defer_ops *src = stp->t_dfops;ASSERT (dst != src);list_splice_init (&src->dop_intake, &dst->dop_intake);@@ -587,5 +592,5 @@ xfs_defer_move(memcpy (dst->dop_bufs, src->dop_bufs,sizeof (dst->dop_bufs)); dst->dop_low = src->dop_low; -xfs_defer_reset (src); +xfs_defer_reset (stp); }fs/xfs/libxfs/xfs_defer.h +1
-1@@ -55,7 +55,7 @@ void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip);int xfs_defer_bjoin (struct xfs_defer_ops *dop,struct xfs_buf *bp); -void xfs_defer_move (struct xfs_defer_ops *dst,struct xfs_defer_ops *src); +void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ struct xfs_defer_op_type {fs/xfs/xfs_bmap_item.c +3
-3@@ -446,7 +446,7 @@ xfs_bui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, itp->t_dfops); +xfs_defer_move (tp, itp); budp =xfs_trans_get_bud (tp, buip);/* Grab the inode. */ @@ -494,7 +494,7 @@ xfs_bui_recover( }set_bit (XFS_BUI_RECOVERED , &buip->bui_flags); -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );xfs_irele (ip);@@ -502,7 +502,7 @@ xfs_bui_recover(return error; err_inode: -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp);xfs_trans_cancel (tp);if (ip) {xfs_iunlock (ip,XFS_ILOCK_EXCL );fs/xfs/xfs_log_recover.c +1
-1@@ -4853,7 +4853,7 @@ xlog_finish_defer_ops(if (error)return error;/* transfer all collected dfops to this transaction */ -xfs_defer_move (tp->t_dfops, itp->t_dfops); +xfs_defer_move (tp, itp);return xfs_trans_commit (tp); }fs/xfs/xfs_refcount_item.c +3
-3@@ -457,7 +457,7 @@ xfs_cui_recover(* finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ -xfs_defer_move (tp->t_dfops, itp->t_dfops); +xfs_defer_move (tp, itp); cudp =xfs_trans_get_cud (tp, cuip);for (i =0 ; i < cuip->cui_format.cui_nextents; i++) {@@ -522,13 +522,13 @@ xfs_cui_recover(xfs_refcount_finish_one_cleanup (tp, rcur, error);set_bit (XFS_CUI_RECOVERED , &cuip->cui_flags); -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp); error =xfs_trans_commit (tp);return error; abort_error:xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (itp->t_dfops, tp->t_dfops); +xfs_defer_move (itp, tp);xfs_trans_cancel (tp);return error; }fs/xfs/xfs_trans.c +1
-1@@ -125,7 +125,7 @@ xfs_trans_dup(if (tp->t_dfops != &tp->t_dfops_internal) ntp->t_dfops = tp->t_dfops;else -xfs_defer_move (ntp->t_dfops, tp->t_dfops); +xfs_defer_move (ntp, tp);xfs_trans_dup_dqinfo (tp, ntp);Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/15] xfs: pass transaction to dfops reset/move helpers
In reply to Brian FosterQuoted 5 lines · Brian Foster
All callers pass ->t_dfops of the associated transactions. Refactor the helpers to receive the transactions and facilitate further cleanups between
xfs_defer_opsandxfs_trans.Signed-off-by Brian Foster <[email protected]>
Looks good,
PATCH 5/15 xfs: replace dop_low with transaction flag
In reply to Brian FosterThe dop_low field enables the low free space allocation mode when a previous allocation has detected difficulty allocating blocks. It has historically been part of the xfs_defer_ops structure, which means if enabled, it remains enabled across a set of transactions until the deferred operations have completed and the dfops is reset.
Now that the dfops is embedded in the transaction, we can save a bit more space by using a transaction flag rather than a standalone boolean. Drop the ->dop_low field and replace it with a transaction flag that is set at the same points, carried across rolling transactions and cleared on completion of deferred operations. This essentially emulates the behavior of ->dop_low and so should not change behavior.
--- fs/xfs/libxfs/xfs_bmap.c | 8 ++++---- fs/xfs/libxfs/xfs_bmap_btree.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 16 ++++++++++++++-- fs/xfs/libxfs/xfs_defer.h | 11 ----------- fs/xfs/libxfs/xfs_shared.h | 12 ++++++++++++ fs/xfs/xfs_filestream.c | 3 ++- fs/xfs/xfs_trace.h | 10 ++-------- fs/xfs/xfs_trans.h | 2 -- 8 files changed, 36 insertions(+), 30 deletions(-)
fs/xfs/libxfs/xfs_bmap.c +4 -4
@@ -700,7 +700,7 @@ xfs_bmap_extents_to_btree(if (tp->t_firstblock ==NULLFSBLOCK ) { args.type =XFS_ALLOCTYPE_START_BNO ; args.fsbno =XFS_INO_TO_FSB (mp, ip->i_ino); - }else if (tp->t_dfops->dop_low) { + }else if (tp->t_flags &XFS_TRANS_LOWMODE ) { args.type =XFS_ALLOCTYPE_START_BNO ; args.fsbno = tp->t_firstblock; }else {
@@ -3449,7 +3449,7 @@ xfs_bmap_btalloc( error =xfs_bmap_btalloc_nullfb (ap, &args, &blen);if (error)return error; - }else if (ap->tp->t_dfops->dop_low) { + }else if (ap->tp->t_flags &XFS_TRANS_LOWMODE ) {if (xfs_inode_is_filestream (ap->ip)) args.type =XFS_ALLOCTYPE_FIRST_AG ;else
@@ -3484,7 +3484,7 @@ xfs_bmap_btalloc(* is >= the stripe unit and the allocation offset is * at the end of file. */ -if (!ap->tp->t_dfops->dop_low && ap->aeof) { +if (!(ap->tp->t_flags &XFS_TRANS_LOWMODE ) && ap->aeof) {if (!ap->offset) { args.alignment = stripe_align; atype = args.type;
@@ -3576,7 +3576,7 @@ xfs_bmap_btalloc( args.total = ap->minlen;if ((error =xfs_alloc_vextent (&args)))return error; - ap->tp->t_dfops->dop_low = true; + ap->tp->t_flags |=XFS_TRANS_LOWMODE ; }if (args.fsbno !=NULLFSBLOCK ) {/*
fs/xfs/libxfs/xfs_bmap_btree.c +2 -2
@@ -226,7 +226,7 @@ xfs_bmbt_alloc_block(* block allocation here and corrupt the filesystem. */ args.minleft = args.tp->t_blk_res; - }else if (cur->bc_tp->t_dfops->dop_low) { + }else if (cur->bc_tp->t_flags &XFS_TRANS_LOWMODE ) { args.type =XFS_ALLOCTYPE_START_BNO ; }else { args.type =XFS_ALLOCTYPE_NEAR_BNO ;
@@ -253,7 +253,7 @@ xfs_bmbt_alloc_block( error =xfs_alloc_vextent (&args);if (error) goto error0; - cur->bc_tp->t_dfops->dop_low = true; + cur->bc_tp->t_flags |=XFS_TRANS_LOWMODE ; }if (WARN_ON_ONCE (args.fsbno ==NULLFSBLOCK )) { *stat =0 ;
fs/xfs/libxfs/xfs_defer.c +14 -2
@@ -330,9 +330,14 @@ xfs_defer_reset(ASSERT (!xfs_defer_has_unfinished_work (dop)); - dop->dop_low = false;memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes));memset (dop->dop_bufs,0 ,sizeof (dop->dop_bufs)); + +/* +* Low mode state transfers across transaction rolls to mirror dfops +* lifetime. Clear it now that dfops is reset. +*/ + tp->t_flags &= ~XFS_TRANS_LOWMODE ; }/*
@@ -590,7 +595,14 @@ xfs_defer_move(memcpy (dst->dop_inodes, src->dop_inodes,sizeof (dst->dop_inodes));memcpy (dst->dop_bufs, src->dop_bufs,sizeof (dst->dop_bufs)); - dst->dop_low = src->dop_low; + +/* +* Low free space mode was historically controlled by a dfops field. +* This meant that low mode state potentially carried across multiple +* transaction rolls. Transfer low mode on a dfops move to preserve +* that behavior. +*/ + dtp->t_flags |= stp->t_flags &XFS_TRANS_LOWMODE ;xfs_defer_reset (stp); }
fs/xfs/libxfs/xfs_defer.h +0 -11
@@ -25,17 +25,6 @@ struct xfs_defer_pending {/* * Header for deferred operation list. -* -* dop_low is used by the allocator to activate the lowspace algorithm - -* when free space is running low the extent allocator may choose to -* allocate an extent from an AG without leaving sufficient space for -* a btree split when inserting the new extent. In this case the allocator -* will enable the lowspace algorithm which is supposed to allow further -* allocations (such as btree splits and newroots) to allocate from -* sequential AGs. In order to avoid locking AGs out of order the lowspace -* algorithm will start searching for free space from AG 0. If the correct -* transaction reservations have been made then this algorithm will eventually -* find all the space it needs. */ enum xfs_defer_ops_type {XFS_DEFER_OPS_TYPE_BMAP ,
fs/xfs/libxfs/xfs_shared.h +12 -0
@@ -64,6 +64,18 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,#define XFS_TRANS_RESERVE 0x20/* OK to use reserved data blocks */ #define XFS_TRANS_NO_WRITECOUNT 0x40/* do not elevate SB writecount */ #define XFS_TRANS_NOFS 0x80/* pass KM_NOFS to kmem_alloc */ +/* +* LOWMODE is used by the allocator to activate the lowspace algorithm - when +* free space is running low the extent allocator may choose to allocate an +* extent from an AG without leaving sufficient space for a btree split when +* inserting the new extent. In this case the allocator will enable the +* lowspace algorithm which is supposed to allow further allocations (such as +* btree splits and newroots) to allocate from sequential AGs. In order to +* avoid locking AGs out of order the lowspace algorithm will start searching +* for free space from AG 0. If the correct transaction reservations have been +* made then this algorithm will eventually find all the space it needs. +*/ +#define XFS_TRANS_LOWMODE 0x100/* allocate in low space mode */ /* * Field values for xfs_trans_mod_sb.
fs/xfs/xfs_filestream.c +2 -1
@@ -20,6 +20,7 @@#include "xfs_trace.h" #include "xfs_ag_resv.h" #include "xfs_trans.h" +#include "xfs_shared.h" struct xfs_fstrm_item {struct xfs_mru_cache_elem mru;
@@ -378,7 +379,7 @@ xfs_filestream_new_ag(if (xfs_alloc_is_userdata (ap->datatype)) flags |=XFS_PICK_USERDATA ; -if (ap->tp->t_dfops->dop_low) +if (ap->tp->t_flags &XFS_TRANS_LOWMODE ) flags |=XFS_PICK_LOWSPACE ; err =xfs_filestream_pick_ag (pip, startag, agp, flags, minlen);
fs/xfs/xfs_trace.h +2 -8
@@ -2223,19 +2223,16 @@ DECLARE_EVENT_CLASS(xfs_defer_class, __field(dev_t, dev) __field(void *, dop) __field(char, committed) - __field(char, low) __field(unsigned long, caller_ip) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->low = dop->dop_low; __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d ops %p low %d, caller %pS", + TP_printk("dev %d:%d ops %p caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->low, (char *)__entry->caller_ip) )#define DEFINE_DEFER_EVENT (name) \
@@ -2251,19 +2248,16 @@ DECLARE_EVENT_CLASS(xfs_defer_error_class, __field(dev_t, dev) __field(void *, dop) __field(char, committed) - __field(char, low) __field(int, error) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->low = dop->dop_low; __entry->error = error; ), - TP_printk("dev %d:%d ops %p low %d err %d", + TP_printk("dev %d:%d ops %p err %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->low, __entry->error) )#define DEFINE_DEFER_ERROR_EVENT (name) \
fs/xfs/xfs_trans.h +0 -2
@@ -101,8 +101,6 @@ struct xfs_defer_ops {/* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ];struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS ]; - -bool dop_low;/* alloc in low mode */ };/*
Signature · 1 line
2.17.1
Re: [PATCH 05/15] xfs: replace dop_low with transaction flag
Quoted 14 lines · Brian Foster
The
dop_lowfield enables the low free space allocation mode when a previous allocation has detected difficulty allocating blocks. It has historically been part of thexfs_defer_opsstructure, which means if enabled, it remains enabled across a set of transactions until the deferred operations have completed and the dfops is reset.Now that the dfops is embedded in the transaction, we can save a bit more space by using a transaction flag rather than a standalone boolean. Drop the ->dop_low field and replace it with a transaction flag that is set at the same points, carried across rolling transactions and cleared on completion of deferred operations. This essentially emulates the behavior of ->dop_low and so should not change behavior.
Quoted 1 line
Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 241 lines
--- fs/xfs/libxfs/xfs_bmap.c | 8 ++++---- fs/xfs/libxfs/xfs_bmap_btree.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 16 ++++++++++++++-- fs/xfs/libxfs/xfs_defer.h | 11 ----------- fs/xfs/libxfs/xfs_shared.h | 12 ++++++++++++ fs/xfs/xfs_filestream.c | 3 ++- fs/xfs/xfs_trace.h | 10 ++-------- fs/xfs/xfs_trans.h | 2 -- 8 files changed, 36 insertions(+), 30 deletions(-)fs/xfs/libxfs/xfs_bmap.c +4
-4@@ -700,7 +700,7 @@ xfs_bmap_extents_to_btree(if (tp->t_firstblock ==NULLFSBLOCK ) { args.type =XFS_ALLOCTYPE_START_BNO ; args.fsbno =XFS_INO_TO_FSB (mp, ip->i_ino); - }else if (tp->t_dfops->dop_low) { + }else if (tp->t_flags &XFS_TRANS_LOWMODE ) { args.type =XFS_ALLOCTYPE_START_BNO ; args.fsbno = tp->t_firstblock; }else {@@ -3449,7 +3449,7 @@ xfs_bmap_btalloc( error =xfs_bmap_btalloc_nullfb (ap, &args, &blen);if (error)return error; - }else if (ap->tp->t_dfops->dop_low) { + }else if (ap->tp->t_flags &XFS_TRANS_LOWMODE ) {if (xfs_inode_is_filestream (ap->ip)) args.type =XFS_ALLOCTYPE_FIRST_AG ;else @@ -3484,7 +3484,7 @@ xfs_bmap_btalloc(* is >= the stripe unit and the allocation offset is * at the end of file. */ -if (!ap->tp->t_dfops->dop_low && ap->aeof) { +if (!(ap->tp->t_flags &XFS_TRANS_LOWMODE ) && ap->aeof) {if (!ap->offset) { args.alignment = stripe_align; atype = args.type;@@ -3576,7 +3576,7 @@ xfs_bmap_btalloc( args.total = ap->minlen;if ((error =xfs_alloc_vextent (&args)))return error; - ap->tp->t_dfops->dop_low = true; + ap->tp->t_flags |=XFS_TRANS_LOWMODE ; }if (args.fsbno !=NULLFSBLOCK ) {/* fs/xfs/libxfs/xfs_bmap_btree.c +2
-2@@ -226,7 +226,7 @@ xfs_bmbt_alloc_block(* block allocation here and corrupt the filesystem. */ args.minleft = args.tp->t_blk_res; - }else if (cur->bc_tp->t_dfops->dop_low) { + }else if (cur->bc_tp->t_flags &XFS_TRANS_LOWMODE ) { args.type =XFS_ALLOCTYPE_START_BNO ; }else { args.type =XFS_ALLOCTYPE_NEAR_BNO ;@@ -253,7 +253,7 @@ xfs_bmbt_alloc_block( error =xfs_alloc_vextent (&args);if (error) goto error0; - cur->bc_tp->t_dfops->dop_low = true; + cur->bc_tp->t_flags |=XFS_TRANS_LOWMODE ; }if (WARN_ON_ONCE (args.fsbno ==NULLFSBLOCK )) { *stat =0 ;fs/xfs/libxfs/xfs_defer.c +14
-2@@ -330,9 +330,14 @@ xfs_defer_reset(ASSERT (!xfs_defer_has_unfinished_work (dop)); - dop->dop_low = false;memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes));memset (dop->dop_bufs,0 ,sizeof (dop->dop_bufs)); + +/* +* Low mode state transfers across transaction rolls to mirror dfops +* lifetime. Clear it now that dfops is reset. +*/ + tp->t_flags &= ~XFS_TRANS_LOWMODE ; }/* @@ -590,7 +595,14 @@ xfs_defer_move(memcpy (dst->dop_inodes, src->dop_inodes,sizeof (dst->dop_inodes));memcpy (dst->dop_bufs, src->dop_bufs,sizeof (dst->dop_bufs)); - dst->dop_low = src->dop_low; + +/* +* Low free space mode was historically controlled by a dfops field. +* This meant that low mode state potentially carried across multiple +* transaction rolls. Transfer low mode on a dfops move to preserve +* that behavior. +*/ + dtp->t_flags |= stp->t_flags &XFS_TRANS_LOWMODE ;xfs_defer_reset (stp); }fs/xfs/libxfs/xfs_defer.h +0
-11@@ -25,17 +25,6 @@ struct xfs_defer_pending {/* * Header for deferred operation list. -* -* dop_low is used by the allocator to activate the lowspace algorithm - -* when free space is running low the extent allocator may choose to -* allocate an extent from an AG without leaving sufficient space for -* a btree split when inserting the new extent. In this case the allocator -* will enable the lowspace algorithm which is supposed to allow further -* allocations (such as btree splits and newroots) to allocate from -* sequential AGs. In order to avoid locking AGs out of order the lowspace -* algorithm will start searching for free space from AG 0. If the correct -* transaction reservations have been made then this algorithm will eventually -* find all the space it needs. */ enum xfs_defer_ops_type {XFS_DEFER_OPS_TYPE_BMAP ,fs/xfs/libxfs/xfs_shared.h +12
-0@@ -64,6 +64,18 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,#define XFS_TRANS_RESERVE 0x20/* OK to use reserved data blocks */ #define XFS_TRANS_NO_WRITECOUNT 0x40/* do not elevate SB writecount */ #define XFS_TRANS_NOFS 0x80/* pass KM_NOFS to kmem_alloc */ +/* +* LOWMODE is used by the allocator to activate the lowspace algorithm - when +* free space is running low the extent allocator may choose to allocate an +* extent from an AG without leaving sufficient space for a btree split when +* inserting the new extent. In this case the allocator will enable the +* lowspace algorithm which is supposed to allow further allocations (such as +* btree splits and newroots) to allocate from sequential AGs. In order to +* avoid locking AGs out of order the lowspace algorithm will start searching +* for free space from AG 0. If the correct transaction reservations have been +* made then this algorithm will eventually find all the space it needs. +*/ +#define XFS_TRANS_LOWMODE 0x100/* allocate in low space mode */ /* * Field values for xfs_trans_mod_sb. fs/xfs/xfs_filestream.c +2
-1@@ -20,6 +20,7 @@#include "xfs_trace.h" #include "xfs_ag_resv.h" #include "xfs_trans.h" +#include "xfs_shared.h" struct xfs_fstrm_item {struct xfs_mru_cache_elem mru;@@ -378,7 +379,7 @@ xfs_filestream_new_ag(if (xfs_alloc_is_userdata (ap->datatype)) flags |=XFS_PICK_USERDATA ; -if (ap->tp->t_dfops->dop_low) +if (ap->tp->t_flags &XFS_TRANS_LOWMODE ) flags |=XFS_PICK_LOWSPACE ; err =xfs_filestream_pick_ag (pip, startag, agp, flags, minlen);fs/xfs/xfs_trace.h +2
-8@@ -2223,19 +2223,16 @@ DECLARE_EVENT_CLASS(xfs_defer_class, __field(dev_t, dev) __field(void *, dop) __field(char, committed) - __field(char, low) __field(unsigned long, caller_ip) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->low = dop->dop_low; __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d ops %p low %d, caller %pS", + TP_printk("dev %d:%d ops %p caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->low, (char *)__entry->caller_ip) )#define DEFINE_DEFER_EVENT (name) \@@ -2251,19 +2248,16 @@ DECLARE_EVENT_CLASS(xfs_defer_error_class, __field(dev_t, dev) __field(void *, dop) __field(char, committed) - __field(char, low) __field(int, error) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->low = dop->dop_low; __entry->error = error; ), - TP_printk("dev %d:%d ops %p low %d err %d", + TP_printk("dev %d:%d ops %p err %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->low, __entry->error) )#define DEFINE_DEFER_ERROR_EVENT (name) \fs/xfs/xfs_trans.h +0
-2@@ -101,8 +101,6 @@ struct xfs_defer_ops {/* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ];struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS ]; - -bool dop_low;/* alloc in low mode */ };/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/15] xfs: replace dop_low with transaction flag
In reply to Brian Fosterfs/xfs/libxfs/xfs_defer.c xfs_defer_move( · line 605
Quoted 7 lines
fs/xfs/libxfs/xfs_defer.c +7
-0+/* +* Low free space mode was historically controlled by a dfops field. +* This meant that low mode state potentially carried across multiple +* transaction rolls. Transfer low mode on a dfops move to preserve +* that behavior. +*/ + dtp->t_flags |= stp->t_flags &XFS_TRANS_LOWMODE ;
Maybe add parentheses here for clarity.
Except for that:
Re: [PATCH 05/15] xfs: replace dop_low with transaction flag
Quoted 10 lines · Christoph Hellwig
fs/xfs/libxfs/xfs_defer.c xfs_defer_move( · line 605
Quoted 7 lines
fs/xfs/libxfs/xfs_defer.c +7
-0+/* +* Low free space mode was historically controlled by a dfops field. +* This meant that low mode state potentially carried across multiple +* transaction rolls. Transfer low mode on a dfops move to preserve +* that behavior. +*/ + dtp->t_flags |= stp->t_flags &XFS_TRANS_LOWMODE ;Maybe add parentheses here for clarity.
Added, thanks.
Brian
Quoted 7 lines
Except for that:
Reviewed-by Christoph Hellwig <[email protected]>--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/15 xfs: add missing defer ijoins for held inodes
In reply to Brian FosterLog items that require relogging during deferred operations processing are explicitly joined to the associated dfops via the xfs_defer_*join() helpers. These calls imply that the associated object is "held" by the transaction such that when rolled, the item can be immediately joined to a follow up transaction. For buffers, this means the buffer remains locked and held after each roll. For inodes, this means that the inode remains locked.
Failure to join a held item to the dfops structure means the associated object pins the tail of the log while dfops processing completes, because the item never relogs and is not unlocked or released until deferred processing completes.
Currently, all buffers that are held in transactions (XFS_BLI_HOLD) with deferred operations are explicitly joined to the dfops. This is not the case for inodes, however, as various contexts defer operations to transactions with held inodes without explicit joins to the associated dfops (and thus not relogging).
While this is not a catastrophic problem, it is not ideal. Given that we want to eventually relog such items automatically during dfops processing, start by explicitly adding these missing xfs_defer_ijoin() calls. A call is added everywhere an inode is joined to a transaction without transferring lock ownership and said transaction runs deferred operations.
All xfs_defer_ijoin() calls will eventually be replaced by automatic dfops inode relogging. This patch essentially implements the behavior change that would otherwise occur due to automatic inode dfops relogging.
--- fs/xfs/libxfs/xfs_bmap.c | 1 + fs/xfs/xfs_bmap_util.c | 1 + fs/xfs/xfs_inode.c | 1 + fs/xfs/xfs_iomap.c | 3 +++ fs/xfs/xfs_reflink.c | 1 + 5 files changed, 7 insertions(+)
fs/xfs/libxfs/xfs_bmap.c +1 -0
@@ -1119,6 +1119,7 @@ xfs_bmap_add_attrfork(xfs_log_sb (tp); } +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );return error;
fs/xfs/xfs_bmap_util.c +1 -0
@@ -979,6 +979,7 @@ xfs_alloc_file_space(/* * Complete the transaction */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)
fs/xfs/xfs_inode.c +1 -0
@@ -1810,6 +1810,7 @@ xfs_inactive_ifree(* Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
fs/xfs/xfs_iomap.c +3 -0
@@ -261,6 +261,7 @@ xfs_iomap_write_direct(/* * Complete the transaction */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto out_unlock;
@@ -762,6 +763,7 @@ xfs_iomap_write_allocate(if (error) goto trans_cancel; +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto error0;
@@ -879,6 +881,7 @@ xfs_iomap_write_unwritten(xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE ); } +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)
fs/xfs/xfs_reflink.c +1 -0
@@ -435,6 +435,7 @@ xfs_reflink_allocate_cow(xfs_inode_set_cowblocks_tag (ip);/* Finish up. */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error)return error;
Signature · 1 line
2.17.1
Re: [PATCH 06/15] xfs: add missing defer ijoins for held inodes
Quoted 26 lines · Brian Foster
Log items that require relogging during deferred operations processing are explicitly joined to the associated dfops via the xfs_defer_*join() helpers. These calls imply that the associated object is "held" by the transaction such that when rolled, the item can be immediately joined to a follow up transaction. For buffers, this means the buffer remains locked and held after each roll. For inodes, this means that the inode remains locked.
Failure to join a held item to the dfops structure means the associated object pins the tail of the log while dfops processing completes, because the item never relogs and is not unlocked or released until deferred processing completes.
Currently, all buffers that are held in transactions (
XFS_BLI_HOLD) with deferred operations are explicitly joined to the dfops. This is not the case for inodes, however, as various contexts defer operations to transactions with held inodes without explicit joins to the associated dfops (and thus not relogging).While this is not a catastrophic problem, it is not ideal. Given that we want to eventually relog such items automatically during dfops processing, start by explicitly adding these missing
xfs_defer_ijoin()calls. A call is added everywhere an inode is joined to a transaction without transferring lock ownership and said transaction runs deferred operations.
Quoted 6 lines
All
xfs_defer_ijoin()calls will eventually be replaced by automatic dfops inode relogging. This patch essentially implements the behavior change that would otherwise occur due to automatic inode dfops relogging.Signed-off-by Brian Foster <[email protected]>
Looks ok, though I admit I'm a little skeptical of adding the calls only to replace them with automatic ijoining two patches later... :)
--D
Quoted 91 lines
--- fs/xfs/libxfs/xfs_bmap.c | 1 + fs/xfs/xfs_bmap_util.c | 1 + fs/xfs/xfs_inode.c | 1 + fs/xfs/xfs_iomap.c | 3 +++ fs/xfs/xfs_reflink.c | 1 + 5 files changed, 7 insertions(+)fs/xfs/libxfs/xfs_bmap.c +1
-0@@ -1119,6 +1119,7 @@ xfs_bmap_add_attrfork(xfs_log_sb (tp); } +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );return error;fs/xfs/xfs_bmap_util.c +1
-0@@ -979,6 +979,7 @@ xfs_alloc_file_space(/* * Complete the transaction */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)fs/xfs/xfs_inode.c +1
-0@@ -1810,6 +1810,7 @@ xfs_inactive_ifree(* Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d",fs/xfs/xfs_iomap.c +3
-0@@ -261,6 +261,7 @@ xfs_iomap_write_direct(/* * Complete the transaction */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto out_unlock;@@ -762,6 +763,7 @@ xfs_iomap_write_allocate(if (error) goto trans_cancel; +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto error0;@@ -879,6 +881,7 @@ xfs_iomap_write_unwritten(xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE ); } +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)fs/xfs/xfs_reflink.c +1
-0@@ -435,6 +435,7 @@ xfs_reflink_allocate_cow(xfs_inode_set_cowblocks_tag (ip);/* Finish up. */ +xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error)return error;Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 06/15] xfs: add missing defer ijoins for held inodes
In reply to Brian FosterLooks fine,
PATCH 7/15 xfs: automatic dfops buffer relogging
In reply to Brian FosterBuffers that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While buffers are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for held buffers.
Replace the xfs_defer_bjoin() infrastructure with such detection and automatic relogging of held buffers. This eliminates the need for the per-dfops buffer list, replaced by an on-stack variant in xfs_defer_trans_roll().
--- fs/xfs/libxfs/xfs_attr.c | 1 - fs/xfs/libxfs/xfs_defer.c | 55 ++++++++++++++++----------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_dquot.c | 1 - fs/xfs/xfs_trans.h | 1 - 5 files changed, 23 insertions(+), 36 deletions(-)
fs/xfs/libxfs/xfs_attr.c +0 -1
@@ -320,7 +320,6 @@ xfs_attr_set(* buffer and run into problems with the write verifier. */ xfs_trans_bhold (args.trans, leaf_bp); -xfs_defer_bjoin (args.trans->t_dfops, leaf_bp);xfs_defer_ijoin (args.trans->t_dfops, dp); error =xfs_defer_finish (&args.trans);if (error)
fs/xfs/libxfs/xfs_defer.c +23 -32
97 lines not on this page · raw message
fs/xfs/libxfs/xfs_defer.h +0 -1
@@ -43,7 +43,6 @@ void xfs_defer_cancel(struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip); -int xfs_defer_bjoin (struct xfs_defer_ops *dop,struct xfs_buf *bp);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */
fs/xfs/xfs_dquot.c +0 -1
@@ -362,7 +362,6 @@ xfs_dquot_disk_alloc(* manually or by committing the transaction. */ xfs_trans_bhold (tp, bp); - error =xfs_defer_bjoin (tp->t_dfops, bp);if (error) {xfs_trans_bhold_release (tp, bp);xfs_trans_brelse (tp, bp);
fs/xfs/xfs_trans.h +0 -1
@@ -100,7 +100,6 @@ struct xfs_defer_ops {/* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ]; -struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS ]; };/*
Signature · 1 line
2.17.1
Re: [PATCH 07/15] xfs: automatic dfops buffer relogging
Quoted 59 lines · Brian Foster
Buffers that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While buffers are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for held buffers.
Replace the
xfs_defer_bjoin()infrastructure with such detection and automatic relogging of held buffers. This eliminates the need for the per-dfops buffer list, replaced by an on-stack variant inxfs_defer_trans_roll().Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_attr.c | 1 - fs/xfs/libxfs/xfs_defer.c | 55 ++++++++++++++++----------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_dquot.c | 1 - fs/xfs/xfs_trans.h | 1 - 5 files changed, 23 insertions(+), 36 deletions(-)fs/xfs/libxfs/xfs_attr.c +0
-1@@ -320,7 +320,6 @@ xfs_attr_set(* buffer and run into problems with the write verifier. */ xfs_trans_bhold (args.trans, leaf_bp); -xfs_defer_bjoin (args.trans->t_dfops, leaf_bp);xfs_defer_ijoin (args.trans->t_dfops, dp); error =xfs_defer_finish (&args.trans);if (error)fs/xfs/libxfs/xfs_defer.c +5
-0@@ -14,6 +14,7 @@#include "xfs_mount.h" #include "xfs_defer.h" #include "xfs_trans.h" +#include "xfs_buf_item.h" #include "xfs_trace.h" /* @@ -228,6 +229,10 @@ xfs_defer_trans_roll( struct xfs_trans **tp) {struct xfs_defer_ops *dop = (*tp)->t_dfops; +struct xfs_buf_log_item *bli; +struct xfs_log_item *lip; +struct xfs_buf *bplist[XFS_DEFER_OPS_NR_BUFS ]; +int bpcount =0 ;int i;int error;@@ -235,9 +240,21 @@ xfs_defer_trans_roll(for (i =0 ; i <XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++)xfs_trans_log_inode (*tp, dop->dop_inodes[i],XFS_ILOG_CORE );
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_roll( · line 249
Quoted 10 lines
fs/xfs/libxfs/xfs_defer.c +7
-3-/* Hold the (previously bjoin'd) buffer locked across the roll. */ -for (i =0 ; i <XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) -xfs_trans_dirty_buf (*tp, dop->dop_bufs[i]); +list_for_each_entry (lip, &(*tp)->t_items, li_trans) { +switch (lip->li_type) { +case XFS_LI_BUF : + bli = container_of(lip, struct xfs_buf_log_item, + bli_item); +if (bli->bli_flags &XFS_BLI_HOLD ) { +ASSERT (bpcount <XFS_DEFER_OPS_NR_BUFS );
This is a bit of a behavior change -- previously if we oveflowed the array we'd bail out with -EFSCORRUPTED rather than go corrupting whatever came after dop_bufs. Granted, we were pretty terrible about checking the return values, but I think this ought to be:
if (bpcount >= XFS_DEFER_OPS_NR_BUFS) {
ASSERT(0);
return -EFSCORRUPTED;
}rather than corrupting the on-stack array if we happen to bhold too many buffers to the transaction.
--D
Quoted 114 lines
fs/xfs/libxfs/xfs_defer.c +11
-29+xfs_trans_dirty_buf (*tp, bli->bli_buf); + bplist[bpcount++] = bli->bli_buf; + } +break ; +default : +break ; + } + }trace_xfs_defer_trans_roll ((*tp)->t_mountp, dop, _RET_IP_);@@ -255,9 +272,9 @@ xfs_defer_trans_roll(xfs_trans_ijoin (*tp, dop->dop_inodes[i],0 );/* Rejoin the buffers and dirty them so the log moves forward. */ -for (i =0 ; i <XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { -xfs_trans_bjoin (*tp, dop->dop_bufs[i]); -xfs_trans_bhold (*tp, dop->dop_bufs[i]); +for (i =0 ; i < bpcount; i++) { +xfs_trans_bjoin (*tp, bplist[i]); +xfs_trans_bhold (*tp, bplist[i]); }return error;@@ -295,30 +312,6 @@ xfs_defer_ijoin(return -EFSCORRUPTED ; } -/* -* Add this buffer to the deferred op. Each joined buffer is relogged -* each time we roll the transaction. -*/ -int -xfs_defer_bjoin ( -struct xfs_defer_ops *dop, -struct xfs_buf *bp) -{ -int i; - -for (i =0 ; i <XFS_DEFER_OPS_NR_BUFS ; i++) { -if (dop->dop_bufs[i] == bp) -return 0 ; -else if (dop->dop_bufs[i] ==NULL ) { - dop->dop_bufs[i] = bp; -return 0 ; - } - } - -ASSERT (0 ); -return -EFSCORRUPTED ; -} -/* * Reset an already used dfops after finish. */ @@ -331,7 +324,6 @@ xfs_defer_reset(ASSERT (!xfs_defer_has_unfinished_work (dop));memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes)); -memset (dop->dop_bufs,0 ,sizeof (dop->dop_bufs));/* * Low mode state transfers across transaction rolls to mirror dfops @@ -594,7 +586,6 @@ xfs_defer_move(list_splice_init (&src->dop_pending, &dst->dop_pending);memcpy (dst->dop_inodes, src->dop_inodes,sizeof (dst->dop_inodes)); -memcpy (dst->dop_bufs, src->dop_bufs,sizeof (dst->dop_bufs));/* * Low free space mode was historically controlled by a dfops field. fs/xfs/libxfs/xfs_defer.h +0
-1@@ -43,7 +43,6 @@ void xfs_defer_cancel(struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip); -int xfs_defer_bjoin (struct xfs_defer_ops *dop,struct xfs_buf *bp);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ fs/xfs/xfs_dquot.c +0
-1@@ -362,7 +362,6 @@ xfs_dquot_disk_alloc(* manually or by committing the transaction. */ xfs_trans_bhold (tp, bp); - error =xfs_defer_bjoin (tp->t_dfops, bp);if (error) {xfs_trans_bhold_release (tp, bp);xfs_trans_brelse (tp, bp);fs/xfs/xfs_trans.h +0
-1@@ -100,7 +100,6 @@ struct xfs_defer_ops {/* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ]; -struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS ]; };/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/15] xfs: automatic dfops buffer relogging
Quoted 21 lines · Darrick J. Wong
Quoted 20 lines · Brian Foster
Buffers that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While buffers are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for held buffers.
Replace the
xfs_defer_bjoin()infrastructure with such detection and automatic relogging of held buffers. This eliminates the need for the per-dfops buffer list, replaced by an on-stack variant inxfs_defer_trans_roll().Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_attr.c | 1 - fs/xfs/libxfs/xfs_defer.c | 55 ++++++++++++++++----------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_dquot.c | 1 - fs/xfs/xfs_trans.h | 1 - 5 files changed, 23 insertions(+), 36 deletions(-)
...
Quoted 4 lines
Quoted 4 lines
fs/xfs/libxfs/xfs_defer.c +0
-0
...
Quoted 20 lines
Quoted 4 lines
fs/xfs/libxfs/xfs_defer.c +0
-0@@ -235,9 +240,21 @@ xfs_defer_trans_roll(for (i =0 ; i <XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++)xfs_trans_log_inode (*tp, dop->dop_inodes[i],XFS_ILOG_CORE );fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_roll( · line 249
Quoted 10 lines
fs/xfs/libxfs/xfs_defer.c +7
-3-/* Hold the (previously bjoin'd) buffer locked across the roll. */ -for (i =0 ; i <XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) -xfs_trans_dirty_buf (*tp, dop->dop_bufs[i]); +list_for_each_entry (lip, &(*tp)->t_items, li_trans) { +switch (lip->li_type) { +case XFS_LI_BUF : + bli = container_of(lip, struct xfs_buf_log_item, + bli_item); +if (bli->bli_flags &XFS_BLI_HOLD ) { +ASSERT (bpcount <XFS_DEFER_OPS_NR_BUFS );This is a bit of a behavior change -- previously if we oveflowed the array we'd bail out with
-EFSCORRUPTEDrather than go corrupting whatever came afterdop_bufs. Granted, we were pretty terrible about checking the return values, but I think this ought to be:
Quoted 8 lines
if (bpcount >= XFS_DEFER_OPS_NR_BUFS) { ASSERT(0); return -EFSCORRUPTED; }rather than corrupting the on-stack array if we happen to bhold too many buffers to the transaction.
Yup, good point. I'll fix up the error checking in both of these patches.
Brian
Quoted 120 lines
--D
Quoted 114 lines
fs/xfs/libxfs/xfs_defer.c +11
-29+xfs_trans_dirty_buf (*tp, bli->bli_buf); + bplist[bpcount++] = bli->bli_buf; + } +break ; +default : +break ; + } + }trace_xfs_defer_trans_roll ((*tp)->t_mountp, dop, _RET_IP_);@@ -255,9 +272,9 @@ xfs_defer_trans_roll(xfs_trans_ijoin (*tp, dop->dop_inodes[i],0 );/* Rejoin the buffers and dirty them so the log moves forward. */ -for (i =0 ; i <XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { -xfs_trans_bjoin (*tp, dop->dop_bufs[i]); -xfs_trans_bhold (*tp, dop->dop_bufs[i]); +for (i =0 ; i < bpcount; i++) { +xfs_trans_bjoin (*tp, bplist[i]); +xfs_trans_bhold (*tp, bplist[i]); }return error;@@ -295,30 +312,6 @@ xfs_defer_ijoin(return -EFSCORRUPTED ; } -/* -* Add this buffer to the deferred op. Each joined buffer is relogged -* each time we roll the transaction. -*/ -int -xfs_defer_bjoin ( -struct xfs_defer_ops *dop, -struct xfs_buf *bp) -{ -int i; - -for (i =0 ; i <XFS_DEFER_OPS_NR_BUFS ; i++) { -if (dop->dop_bufs[i] == bp) -return 0 ; -else if (dop->dop_bufs[i] ==NULL ) { - dop->dop_bufs[i] = bp; -return 0 ; - } - } - -ASSERT (0 ); -return -EFSCORRUPTED ; -} -/* * Reset an already used dfops after finish. */ @@ -331,7 +324,6 @@ xfs_defer_reset(ASSERT (!xfs_defer_has_unfinished_work (dop));memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes)); -memset (dop->dop_bufs,0 ,sizeof (dop->dop_bufs));/* * Low mode state transfers across transaction rolls to mirror dfops @@ -594,7 +586,6 @@ xfs_defer_move(list_splice_init (&src->dop_pending, &dst->dop_pending);memcpy (dst->dop_inodes, src->dop_inodes,sizeof (dst->dop_inodes)); -memcpy (dst->dop_bufs, src->dop_bufs,sizeof (dst->dop_bufs));/* * Low free space mode was historically controlled by a dfops field. fs/xfs/libxfs/xfs_defer.h +0
-1@@ -43,7 +43,6 @@ void xfs_defer_cancel(struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop);int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip); -int xfs_defer_bjoin (struct xfs_defer_ops *dop,struct xfs_buf *bp);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ fs/xfs/xfs_dquot.c +0
-1@@ -362,7 +362,6 @@ xfs_dquot_disk_alloc(* manually or by committing the transaction. */ xfs_trans_bhold (tp, bp); - error =xfs_defer_bjoin (tp->t_dfops, bp);if (error) {xfs_trans_bhold_release (tp, bp);xfs_trans_brelse (tp, bp);fs/xfs/xfs_trans.h +0
-1@@ -100,7 +100,6 @@ struct xfs_defer_ops {/* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ]; -struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS ]; };/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/15] xfs: automatic dfops buffer relogging
In reply to Brian FosterQuoted 10 lines · Brian Foster
Buffers that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While buffers are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for held buffers.
Replace the
xfs_defer_bjoin()infrastructure with such detection and automatic relogging of held buffers. This eliminates the need for the per-dfops buffer list, replaced by an on-stack variant inxfs_defer_trans_roll().
Looks good modulo added error checking as noted by Darrick:
PATCH 8/15 xfs: automatic dfops inode relogging
In reply to Brian FosterInodes that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While inodes are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for inodes with ili_lock_flags == 0.
Replace the xfs_defer_ijoin() infrastructure with such detection and automatic relogging of held inodes. This eliminates the need for the per-dfops inode list, replaced by an on-stack variant in xfs_defer_trans_roll().
--- fs/xfs/libxfs/xfs_attr.c | 9 ------ fs/xfs/libxfs/xfs_attr_remote.c | 2 -- fs/xfs/libxfs/xfs_bmap.c | 8 ----- fs/xfs/libxfs/xfs_defer.c | 56 +++++++++++---------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_bmap_util.c | 4 --- fs/xfs/xfs_inode.c | 2 -- fs/xfs/xfs_iomap.c | 3 -- fs/xfs/xfs_reflink.c | 4 --- fs/xfs/xfs_symlink.c | 1 - fs/xfs/xfs_trans.h | 3 -- 11 files changed, 18 insertions(+), 75 deletions(-)
fs/xfs/libxfs/xfs_attr.c +0 -9
@@ -320,7 +320,6 @@ xfs_attr_set(* buffer and run into problems with the write verifier. */ xfs_trans_bhold (args.trans, leaf_bp); -xfs_defer_ijoin (args.trans->t_dfops, dp); error =xfs_defer_finish (&args.trans);if (error) goto out;
@@ -589,7 +588,6 @@ xfs_attr_leaf_addname( error =xfs_attr3_leaf_to_node (args);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -678,7 +676,6 @@ xfs_attr_leaf_addname(/* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -742,7 +739,6 @@ xfs_attr_leaf_removename(/* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -869,7 +865,6 @@ xfs_attr_node_addname( error =xfs_attr3_leaf_to_node (args);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -894,7 +889,6 @@ xfs_attr_node_addname( error =xfs_da3_split (state);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -991,7 +985,6 @@ xfs_attr_node_addname( error =xfs_da3_join (state);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -1115,7 +1108,6 @@ xfs_attr_node_removename( error =xfs_da3_join (state);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -1147,7 +1139,6 @@ xfs_attr_node_removename(/* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
fs/xfs/libxfs/xfs_attr_remote.c +0 -2
@@ -486,7 +486,6 @@ xfs_attr_rmtval_set( &nmap);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
@@ -627,7 +626,6 @@ xfs_attr_rmtval_remove( XFS_BMAPI_ATTRFORK, 1, &done);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, args->dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;
fs/xfs/libxfs/xfs_bmap.c +0 -8
@@ -1119,7 +1119,6 @@ xfs_bmap_add_attrfork(xfs_log_sb (tp); } -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );return error;
@@ -5987,7 +5986,6 @@ __xfs_bmap_add(int whichfork, struct xfs_bmbt_irec *bmap) { - int error; struct xfs_bmap_intent *bi; trace_xfs_bmap_defer(mp,
@@ -6006,12 +6004,6 @@ __xfs_bmap_add( bi->bi_whichfork = whichfork; bi->bi_bmap = *bmap; - error =xfs_defer_ijoin (dfops, bi->bi_owner); -if (error) { -kmem_free (bi); -return error; - } -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_BMAP , &bi->bi_list);return 0 ; }
fs/xfs/libxfs/xfs_defer.c +18 -38
103 lines not on this page · raw message
fs/xfs/libxfs/xfs_defer.h +0 -1
@@ -42,7 +42,6 @@ int xfs_defer_finish(struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop); -int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */
fs/xfs/xfs_bmap_util.c +0 -4
@@ -979,7 +979,6 @@ xfs_alloc_file_space(/* * Complete the transaction */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)
@@ -1037,8 +1036,6 @@ xfs_unmap_extent(if (error) goto out_trans_cancel; -xfs_defer_ijoin (tp->t_dfops, ip); - error =xfs_trans_commit (tp); out_unlock:xfs_iunlock (ip,XFS_ILOCK_EXCL );
@@ -1624,7 +1621,6 @@ xfs_swap_extent_rmap(if (error) goto out_defer; -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (tpp); tp = *tpp;if (error)
fs/xfs/xfs_inode.c +0 -2
@@ -1569,7 +1569,6 @@ xfs_itruncate_extents_flags(* Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (&tp);if (error) goto out_bmap_cancel;
@@ -1810,7 +1809,6 @@ xfs_inactive_ifree(* Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
fs/xfs/xfs_iomap.c +0 -3
@@ -261,7 +261,6 @@ xfs_iomap_write_direct(/* * Complete the transaction */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto out_unlock;
@@ -763,7 +762,6 @@ xfs_iomap_write_allocate(if (error) goto trans_cancel; -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto error0;
@@ -881,7 +879,6 @@ xfs_iomap_write_unwritten(xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE ); } -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)
fs/xfs/xfs_reflink.c +0 -4
@@ -435,7 +435,6 @@ xfs_reflink_allocate_cow(xfs_inode_set_cowblocks_tag (ip);/* Finish up. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error)return error;
@@ -518,7 +517,6 @@ xfs_reflink_cancel_cow_blocks( NULL);/* Roll the transaction */ -xfs_defer_ijoin ((*tpp)->t_dfops, ip); error =xfs_defer_finish (tpp);if (error) {xfs_defer_cancel (*tpp);
@@ -716,7 +714,6 @@ xfs_reflink_end_cow(/* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow (ip, &icur, &got, &del); -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (&tp);if (error) goto out_cancel;
@@ -1077,7 +1074,6 @@ xfs_reflink_remap_extent( next_extent:/* Process all the deferred stuff. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (&tp);if (error) goto out_cancel;
fs/xfs/xfs_symlink.c +0 -1
@@ -454,7 +454,6 @@ xfs_inactive_symlink_rmt(* Commit the transaction. This first logs the EFI and the inode, then * rolls and commits the transaction that frees the extents. */ -xfs_defer_ijoin (tp->t_dfops, ip);xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE ); error =xfs_trans_commit (tp);if (error) {
fs/xfs/xfs_trans.h +0 -3
@@ -97,9 +97,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,struct xfs_defer_ops {struct list_head dop_intake;/* unlogged pending work */ struct list_head dop_pending;/* logged pending work */ - -/* relog these with each roll */ -struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ]; };/*
Signature · 1 line
2.17.1
Re: [PATCH 08/15] xfs: automatic dfops inode relogging
Quoted 189 lines · Brian Foster
Inodes that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While inodes are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for inodes with
ili_lock_flags== 0.Replace the
xfs_defer_ijoin()infrastructure with such detection and automatic relogging of held inodes. This eliminates the need for the per-dfops inode list, replaced by an on-stack variant inxfs_defer_trans_roll().Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_attr.c | 9 ------ fs/xfs/libxfs/xfs_attr_remote.c | 2 -- fs/xfs/libxfs/xfs_bmap.c | 8 ----- fs/xfs/libxfs/xfs_defer.c | 56 +++++++++++---------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_bmap_util.c | 4 --- fs/xfs/xfs_inode.c | 2 -- fs/xfs/xfs_iomap.c | 3 -- fs/xfs/xfs_reflink.c | 4 --- fs/xfs/xfs_symlink.c | 1 - fs/xfs/xfs_trans.h | 3 -- 11 files changed, 18 insertions(+), 75 deletions(-)fs/xfs/libxfs/xfs_attr.c +0
-9@@ -320,7 +320,6 @@ xfs_attr_set(* buffer and run into problems with the write verifier. */ xfs_trans_bhold (args.trans, leaf_bp); -xfs_defer_ijoin (args.trans->t_dfops, dp); error =xfs_defer_finish (&args.trans);if (error) goto out;@@ -589,7 +588,6 @@ xfs_attr_leaf_addname( error =xfs_attr3_leaf_to_node (args);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -678,7 +676,6 @@ xfs_attr_leaf_addname(/* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -742,7 +739,6 @@ xfs_attr_leaf_removename(/* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -869,7 +865,6 @@ xfs_attr_node_addname( error =xfs_attr3_leaf_to_node (args);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -894,7 +889,6 @@ xfs_attr_node_addname( error =xfs_da3_split (state);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -991,7 +985,6 @@ xfs_attr_node_addname( error =xfs_da3_join (state);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -1115,7 +1108,6 @@ xfs_attr_node_removename( error =xfs_da3_join (state);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -1147,7 +1139,6 @@ xfs_attr_node_removename(/* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;fs/xfs/libxfs/xfs_attr_remote.c +0
-2@@ -486,7 +486,6 @@ xfs_attr_rmtval_set( &nmap);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;@@ -627,7 +626,6 @@ xfs_attr_rmtval_remove( XFS_BMAPI_ATTRFORK, 1, &done);if (error) goto out_defer_cancel; -xfs_defer_ijoin (args->trans->t_dfops, args->dp); error =xfs_defer_finish (&args->trans);if (error) goto out_defer_cancel;fs/xfs/libxfs/xfs_bmap.c +0
-8@@ -1119,7 +1119,6 @@ xfs_bmap_add_attrfork(xfs_log_sb (tp); } -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );return error;@@ -5987,7 +5986,6 @@ __xfs_bmap_add(int whichfork, struct xfs_bmbt_irec *bmap) { - int error; struct xfs_bmap_intent *bi; trace_xfs_bmap_defer(mp,@@ -6006,12 +6004,6 @@ __xfs_bmap_add( bi->bi_whichfork = whichfork; bi->bi_bmap = *bmap; - error =xfs_defer_ijoin (dfops, bi->bi_owner); -if (error) { -kmem_free (bi); -return error; - } -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_BMAP , &bi->bi_list);return 0 ; }fs/xfs/libxfs/xfs_defer.c +5
-5@@ -15,6 +15,8 @@#include "xfs_defer.h" #include "xfs_trans.h" #include "xfs_buf_item.h" +#include "xfs_inode.h" +#include "xfs_inode_item.h" #include "xfs_trace.h" /* @@ -230,16 +232,14 @@ xfs_defer_trans_roll( {struct xfs_defer_ops *dop = (*tp)->t_dfops;struct xfs_buf_log_item *bli; +struct xfs_inode_log_item *ili;struct xfs_log_item *lip;struct xfs_buf *bplist[XFS_DEFER_OPS_NR_BUFS ]; -int bpcount =0 ; +struct xfs_inode *iplist[XFS_DEFER_OPS_NR_INODES ]; +int bpcount =0 , ipcount =0 ;int i;int error; -/* Log all the joined inodes. */ -for (i =0 ; i <XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) -xfs_trans_log_inode (*tp, dop->dop_inodes[i],XFS_ILOG_CORE ); -list_for_each_entry (lip, &(*tp)->t_items, li_trans) {switch (lip->li_type) {case XFS_LI_BUF :
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_roll( · line 258
Quoted 8 lines
fs/xfs/libxfs/xfs_defer.c +5
-0@@ -251,6 +251,16 @@ xfs_defer_trans_roll( bplist[bpcount++] = bli->bli_buf; }break ; +case XFS_LI_INODE : + ili = container_of(lip, struct xfs_inode_log_item, + ili_item); +if (ili->ili_lock_flags ==0 ) { +ASSERT (ipcount <XFS_DEFER_OPS_NR_INODES );
Same complaint here as in the previous patch about the behavior change in the overflow check. I admit I sucked at consistently checking the _defer_ijoin return value, sorry about that. :(
--D
Quoted 230 lines
fs/xfs/libxfs/xfs_defer.c +8
-33+xfs_trans_log_inode (*tp, ili->ili_inode, +XFS_ILOG_CORE ); + iplist[ipcount++] = ili->ili_inode; + } +break ;default :break ; }@@ -268,8 +278,8 @@ xfs_defer_trans_roll( }/* Rejoin the joined inodes. */ -for (i =0 ; i <XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) -xfs_trans_ijoin (*tp, dop->dop_inodes[i],0 ); +for (i =0 ; i < ipcount; i++) +xfs_trans_ijoin (*tp, iplist[i],0 );/* Rejoin the buffers and dirty them so the log moves forward. */ for (i =0 ; i < bpcount; i++) {@@ -288,30 +298,6 @@ xfs_defer_has_unfinished_work(return !list_empty (&dop->dop_pending) || !list_empty (&dop->dop_intake); } -/* -* Add this inode to the deferred op. Each joined inode is relogged -* each time we roll the transaction. -*/ -int -xfs_defer_ijoin ( -struct xfs_defer_ops *dop, -struct xfs_inode *ip) -{ -int i; - -for (i =0 ; i <XFS_DEFER_OPS_NR_INODES ; i++) { -if (dop->dop_inodes[i] == ip) -return 0 ; -else if (dop->dop_inodes[i] ==NULL ) { - dop->dop_inodes[i] = ip; -return 0 ; - } - } - -ASSERT (0 ); -return -EFSCORRUPTED ; -} -/* * Reset an already used dfops after finish. */ @@ -319,11 +305,7 @@ static voidxfs_defer_reset ( struct xfs_trans *tp) { -struct xfs_defer_ops *dop = tp->t_dfops; - -ASSERT (!xfs_defer_has_unfinished_work (dop)); - -memset (dop->dop_inodes,0 ,sizeof (dop->dop_inodes)); +ASSERT (!xfs_defer_has_unfinished_work (tp->t_dfops));/* * Low mode state transfers across transaction rolls to mirror dfops @@ -585,8 +567,6 @@ xfs_defer_move(list_splice_init (&src->dop_intake, &dst->dop_intake);list_splice_init (&src->dop_pending, &dst->dop_pending); -memcpy (dst->dop_inodes, src->dop_inodes,sizeof (dst->dop_inodes)); -/* * Low free space mode was historically controlled by a dfops field. * This meant that low mode state potentially carried across multiple fs/xfs/libxfs/xfs_defer.h +0
-1@@ -42,7 +42,6 @@ int xfs_defer_finish(struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop); -int xfs_defer_ijoin (struct xfs_defer_ops *dop,struct xfs_inode *ip);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ fs/xfs/xfs_bmap_util.c +0
-4@@ -979,7 +979,6 @@ xfs_alloc_file_space(/* * Complete the transaction */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)@@ -1037,8 +1036,6 @@ xfs_unmap_extent(if (error) goto out_trans_cancel; -xfs_defer_ijoin (tp->t_dfops, ip); - error =xfs_trans_commit (tp); out_unlock:xfs_iunlock (ip,XFS_ILOCK_EXCL );@@ -1624,7 +1621,6 @@ xfs_swap_extent_rmap(if (error) goto out_defer; -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (tpp); tp = *tpp;if (error)fs/xfs/xfs_inode.c +0
-2@@ -1569,7 +1569,6 @@ xfs_itruncate_extents_flags(* Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (&tp);if (error) goto out_bmap_cancel;@@ -1810,7 +1809,6 @@ xfs_inactive_ifree(* Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d",fs/xfs/xfs_iomap.c +0
-3@@ -261,7 +261,6 @@ xfs_iomap_write_direct(/* * Complete the transaction */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto out_unlock;@@ -763,7 +762,6 @@ xfs_iomap_write_allocate(if (error) goto trans_cancel; -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error) goto error0;@@ -881,7 +879,6 @@ xfs_iomap_write_unwritten(xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE ); } -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );if (error)fs/xfs/xfs_reflink.c +0
-4@@ -435,7 +435,6 @@ xfs_reflink_allocate_cow(xfs_inode_set_cowblocks_tag (ip);/* Finish up. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_trans_commit (tp);if (error)return error;@@ -518,7 +517,6 @@ xfs_reflink_cancel_cow_blocks( NULL);/* Roll the transaction */ -xfs_defer_ijoin ((*tpp)->t_dfops, ip); error =xfs_defer_finish (tpp);if (error) {xfs_defer_cancel (*tpp);@@ -716,7 +714,6 @@ xfs_reflink_end_cow(/* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow (ip, &icur, &got, &del); -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (&tp);if (error) goto out_cancel;@@ -1077,7 +1074,6 @@ xfs_reflink_remap_extent( next_extent:/* Process all the deferred stuff. */ -xfs_defer_ijoin (tp->t_dfops, ip); error =xfs_defer_finish (&tp);if (error) goto out_cancel;fs/xfs/xfs_symlink.c +0
-1@@ -454,7 +454,6 @@ xfs_inactive_symlink_rmt(* Commit the transaction. This first logs the EFI and the inode, then * rolls and commits the transaction that frees the extents. */ -xfs_defer_ijoin (tp->t_dfops, ip);xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE ); error =xfs_trans_commit (tp);if (error) {fs/xfs/xfs_trans.h +0
-3@@ -97,9 +97,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,struct xfs_defer_ops {struct list_head dop_intake;/* unlogged pending work */ struct list_head dop_pending;/* logged pending work */ - -/* relog these with each roll */ -struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES ]; };/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/15] xfs: automatic dfops inode relogging
In reply to Brian FosterQuoted 10 lines · Brian Foster
Inodes that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While inodes are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for inodes with
ili_lock_flags== 0.Replace the
xfs_defer_ijoin()infrastructure with such detection and automatic relogging of held inodes. This eliminates the need for the per-dfops inode list, replaced by an on-stack variant inxfs_defer_trans_roll().
Looks good modulo additional error checking:
PATCH 9/15 xfs: drop dop param from xfs_defer_op_type ->finish_item() callback
In reply to Brian FosterThe dfops infrastructure ->finish_item() callback passes the transaction and dfops as separate parameters. Since dfops is always part of a transaction, the latter parameter is no longer necessary. Remove it from the various callbacks.
--- fs/xfs/libxfs/xfs_bmap.c | 2 -- fs/xfs/libxfs/xfs_bmap.h | 6 +++--- fs/xfs/libxfs/xfs_defer.c | 2 +- fs/xfs/libxfs/xfs_defer.h | 4 ++-- fs/xfs/libxfs/xfs_refcount.c | 2 +- fs/xfs/libxfs/xfs_refcount.h | 7 +++---- fs/xfs/xfs_bmap_item.c | 5 ++--- fs/xfs/xfs_refcount_item.c | 4 ++-- fs/xfs/xfs_trans.h | 10 +++++----- fs/xfs/xfs_trans_bmap.c | 6 ++---- fs/xfs/xfs_trans_extfree.c | 2 -- fs/xfs/xfs_trans_refcount.c | 6 ++---- fs/xfs/xfs_trans_rmap.c | 1 - 13 files changed, 23 insertions(+), 34 deletions(-)
fs/xfs/libxfs/xfs_bmap.c +0 -2
@@ -6045,7 +6045,6 @@ xfs_bmap_unmap_extent( int xfs_bmap_finish_one( struct xfs_trans *tp, - struct xfs_defer_ops *dfops, struct xfs_inode *ip, enum xfs_bmap_intent_type type, int whichfork,
@@ -6072,7 +6071,6 @@ xfs_bmap_finish_one(switch (type) {case XFS_BMAP_MAP : -ASSERT (dfops == tp->t_dfops); error =xfs_bmapi_remap (tp, ip, startoff, *blockcount, startblock,0 ); *blockcount =0 ;
fs/xfs/libxfs/xfs_bmap.h +3 -3
@@ -252,9 +252,9 @@ struct xfs_bmap_intent {struct xfs_bmbt_irec bi_bmap; }; -int xfs_bmap_finish_one (struct xfs_trans *tp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,enum xfs_bmap_intent_type type, -int whichfork,xfs_fileoff_t startoff,xfs_fsblock_t startblock, +int xfs_bmap_finish_one (struct xfs_trans *tp,struct xfs_inode *ip, +enum xfs_bmap_intent_type type,int whichfork, +xfs_fileoff_t startoff,xfs_fsblock_t startblock,xfs_filblks_t *blockcount,xfs_exntst_t state);int xfs_bmap_map_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops,struct xfs_inode *ip,struct xfs_bmbt_irec *imap);
fs/xfs/libxfs/xfs_defer.c +1 -1
@@ -365,7 +365,7 @@ xfs_defer_finish_noroll(list_for_each_safe (li, n, &dfp->dfp_work) {list_del (li); dfp->dfp_count--; - error = dfp->dfp_type->finish_item (*tp, dop, li, + error = dfp->dfp_type->finish_item (*tp, li, dfp->dfp_done, &state);if (error == -EAGAIN ) {/*
fs/xfs/libxfs/xfs_defer.h +2 -2
@@ -50,8 +50,8 @@ struct xfs_defer_op_type {unsigned int max_items;void (*abort_intent)(void *);void *(*create_done)(struct xfs_trans *,void *,unsigned int ); -int (*finish_item)(struct xfs_trans *,struct xfs_defer_ops *, -struct list_head *,void *,void **); +int (*finish_item)(struct xfs_trans *,struct list_head *,void *, +void **);void (*finish_cleanup)(struct xfs_trans *,void *,int );void (*cancel_item)(struct list_head *);int (*diff_items)(void *,struct list_head *,struct list_head *);
fs/xfs/libxfs/xfs_refcount.c +1 -1
@@ -1082,7 +1082,6 @@ xfs_refcount_finish_one_cleanup( int xfs_refcount_finish_one( struct xfs_trans *tp, - struct xfs_defer_ops *dfops, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount,
@@ -1091,6 +1090,7 @@ xfs_refcount_finish_one( struct xfs_btree_cur **pcur) {struct xfs_mount *mp = tp->t_mountp; +struct xfs_defer_ops *dfops = tp->t_dfops;struct xfs_btree_cur *rcur;struct xfs_buf *agbp =NULL ;int error =0 ;
fs/xfs/libxfs/xfs_refcount.h +3 -4
@@ -37,10 +37,9 @@ extern int xfs_refcount_decrease_extent(struct xfs_mount *mp,extern void xfs_refcount_finish_one_cleanup (struct xfs_trans *tp,struct xfs_btree_cur *rcur,int error);extern int xfs_refcount_finish_one (struct xfs_trans *tp, -struct xfs_defer_ops *dfops,enum xfs_refcount_intent_type type, -xfs_fsblock_t startblock,xfs_extlen_t blockcount, -xfs_fsblock_t *new_fsb,xfs_extlen_t *new_len, -struct xfs_btree_cur **pcur); +enum xfs_refcount_intent_type type,xfs_fsblock_t startblock, +xfs_extlen_t blockcount,xfs_fsblock_t *new_fsb, +xfs_extlen_t *new_len,struct xfs_btree_cur **pcur); extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno,
fs/xfs/xfs_bmap_item.c +2 -3
@@ -475,9 +475,8 @@ xfs_bui_recover(xfs_trans_ijoin (tp, ip,0 ); count = bmap->me_len; - error =xfs_trans_log_finish_bmap_update (tp, budp, tp->t_dfops, type, - ip, whichfork, bmap->me_startoff, - bmap->me_startblock, &count, state); + error =xfs_trans_log_finish_bmap_update (tp, budp, type, ip, whichfork, + bmap->me_startoff, bmap->me_startblock, &count, state);if (error) goto err_inode;
fs/xfs/xfs_refcount_item.c +2 -2
@@ -479,8 +479,8 @@ xfs_cui_recover( new_len = refc->pe_len; }else error =xfs_trans_log_finish_refcount_update (tp, cudp, - tp->t_dfops, type, refc->pe_startblock, - refc->pe_len, &new_fsb, &new_len, &rcur); + type, refc->pe_startblock, refc->pe_len, + &new_fsb, &new_len, &rcur);if (error) goto abort_error;
fs/xfs/xfs_trans.h +5 -5
@@ -268,7 +268,7 @@ void xfs_refcount_update_init_defer_op(void);struct xfs_cud_log_item *xfs_trans_get_cud (struct xfs_trans *tp,struct xfs_cui_log_item *cuip);int xfs_trans_log_finish_refcount_update (struct xfs_trans *tp, -struct xfs_cud_log_item *cudp,struct xfs_defer_ops *dfops, +struct xfs_cud_log_item *cudp,enum xfs_refcount_intent_type type,xfs_fsblock_t startblock,xfs_extlen_t blockcount,xfs_fsblock_t *new_fsb,xfs_extlen_t *new_len,struct xfs_btree_cur **pcur);
@@ -280,9 +280,9 @@ void xfs_bmap_update_init_defer_op(void);struct xfs_bud_log_item *xfs_trans_get_bud (struct xfs_trans *tp,struct xfs_bui_log_item *buip);int xfs_trans_log_finish_bmap_update (struct xfs_trans *tp, -struct xfs_bud_log_item *rudp,struct xfs_defer_ops *dfops, -enum xfs_bmap_intent_type type,struct xfs_inode *ip, -int whichfork,xfs_fileoff_t startoff,xfs_fsblock_t startblock, -xfs_filblks_t *blockcount,xfs_exntst_t state); +struct xfs_bud_log_item *rudp,enum xfs_bmap_intent_type type, +struct xfs_inode *ip,int whichfork,xfs_fileoff_t startoff, +xfs_fsblock_t startblock,xfs_filblks_t *blockcount, +xfs_exntst_t state);#endif /* __XFS_TRANS_H__ */
fs/xfs/xfs_trans_bmap.c +2 -4
@@ -43,7 +43,6 @@ intxfs_trans_log_finish_bmap_update ( struct xfs_trans *tp, struct xfs_bud_log_item *budp, - struct xfs_defer_ops *dop, enum xfs_bmap_intent_type type, struct xfs_inode *ip, int whichfork,
@@ -54,7 +53,7 @@ xfs_trans_log_finish_bmap_update( {int error; - error =xfs_bmap_finish_one (tp, dop, ip, type, whichfork, startoff, + error =xfs_bmap_finish_one (tp, ip, type, whichfork, startoff, startblock, blockcount, state);/*
@@ -176,7 +175,6 @@ xfs_bmap_update_create_done( STATIC intxfs_bmap_update_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)
@@ -187,7 +185,7 @@ xfs_bmap_update_finish_item( bmap = container_of(item, struct xfs_bmap_intent, bi_list); count = bmap->bi_bmap.br_blockcount; - error = xfs_trans_log_finish_bmap_update(tp, done_item, dop, + error = xfs_trans_log_finish_bmap_update(tp, done_item, bmap->bi_type, bmap->bi_owner, bmap->bi_whichfork, bmap->bi_bmap.br_startoff,
fs/xfs/xfs_trans_extfree.c +0 -2
@@ -171,7 +171,6 @@ xfs_extent_free_create_done( STATIC intxfs_extent_free_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)
@@ -226,7 +225,6 @@ static const struct xfs_defer_op_type xfs_extent_free_defer_type = { STATIC intxfs_agfl_free_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)
fs/xfs/xfs_trans_refcount.c +2 -4
@@ -42,7 +42,6 @@ intxfs_trans_log_finish_refcount_update ( struct xfs_trans *tp, struct xfs_cud_log_item *cudp, - struct xfs_defer_ops *dop, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount,
@@ -52,7 +51,7 @@ xfs_trans_log_finish_refcount_update( {int error; - error =xfs_refcount_finish_one (tp, dop, type, startblock, + error =xfs_refcount_finish_one (tp, type, startblock, blockcount, new_fsb, new_len, pcur);/*
@@ -169,7 +168,6 @@ xfs_refcount_update_create_done( STATIC intxfs_refcount_update_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)
@@ -180,7 +178,7 @@ xfs_refcount_update_finish_item(int error; refc = container_of(item, struct xfs_refcount_intent, ri_list); - error = xfs_trans_log_finish_refcount_update(tp, done_item, dop, + error = xfs_trans_log_finish_refcount_update(tp, done_item, refc->ri_type, refc->ri_startblock, refc->ri_blockcount,
fs/xfs/xfs_trans_rmap.c +0 -1
@@ -193,7 +193,6 @@ xfs_rmap_update_create_done( STATIC intxfs_rmap_update_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)
Signature · 1 line
2.17.1
Re: [PATCH 09/15] xfs: drop dop param from xfs_defer_op_type ->finish_item() callback
Quoted 6 lines · Brian Foster
The dfops infrastructure ->finish_item() callback passes the transaction and dfops as separate parameters. Since dfops is always part of a transaction, the latter parameter is no longer necessary. Remove it from the various callbacks.
Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 292 lines
--- fs/xfs/libxfs/xfs_bmap.c | 2 -- fs/xfs/libxfs/xfs_bmap.h | 6 +++--- fs/xfs/libxfs/xfs_defer.c | 2 +- fs/xfs/libxfs/xfs_defer.h | 4 ++-- fs/xfs/libxfs/xfs_refcount.c | 2 +- fs/xfs/libxfs/xfs_refcount.h | 7 +++---- fs/xfs/xfs_bmap_item.c | 5 ++--- fs/xfs/xfs_refcount_item.c | 4 ++-- fs/xfs/xfs_trans.h | 10 +++++----- fs/xfs/xfs_trans_bmap.c | 6 ++---- fs/xfs/xfs_trans_extfree.c | 2 -- fs/xfs/xfs_trans_refcount.c | 6 ++---- fs/xfs/xfs_trans_rmap.c | 1 - 13 files changed, 23 insertions(+), 34 deletions(-)fs/xfs/libxfs/xfs_bmap.c +0
-2@@ -6045,7 +6045,6 @@ xfs_bmap_unmap_extent( int xfs_bmap_finish_one( struct xfs_trans *tp, - struct xfs_defer_ops *dfops, struct xfs_inode *ip, enum xfs_bmap_intent_type type, int whichfork,@@ -6072,7 +6071,6 @@ xfs_bmap_finish_one(switch (type) {case XFS_BMAP_MAP : -ASSERT (dfops == tp->t_dfops); error =xfs_bmapi_remap (tp, ip, startoff, *blockcount, startblock,0 ); *blockcount =0 ;fs/xfs/libxfs/xfs_bmap.h +3
-3@@ -252,9 +252,9 @@ struct xfs_bmap_intent {struct xfs_bmbt_irec bi_bmap; }; -int xfs_bmap_finish_one (struct xfs_trans *tp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,enum xfs_bmap_intent_type type, -int whichfork,xfs_fileoff_t startoff,xfs_fsblock_t startblock, +int xfs_bmap_finish_one (struct xfs_trans *tp,struct xfs_inode *ip, +enum xfs_bmap_intent_type type,int whichfork, +xfs_fileoff_t startoff,xfs_fsblock_t startblock,xfs_filblks_t *blockcount,xfs_exntst_t state);int xfs_bmap_map_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops,struct xfs_inode *ip,struct xfs_bmbt_irec *imap);fs/xfs/libxfs/xfs_defer.c +1
-1@@ -365,7 +365,7 @@ xfs_defer_finish_noroll(list_for_each_safe (li, n, &dfp->dfp_work) {list_del (li); dfp->dfp_count--; - error = dfp->dfp_type->finish_item (*tp, dop, li, + error = dfp->dfp_type->finish_item (*tp, li, dfp->dfp_done, &state);if (error == -EAGAIN ) {/* fs/xfs/libxfs/xfs_defer.h +2
-2@@ -50,8 +50,8 @@ struct xfs_defer_op_type {unsigned int max_items;void (*abort_intent)(void *);void *(*create_done)(struct xfs_trans *,void *,unsigned int ); -int (*finish_item)(struct xfs_trans *,struct xfs_defer_ops *, -struct list_head *,void *,void **); +int (*finish_item)(struct xfs_trans *,struct list_head *,void *, +void **);void (*finish_cleanup)(struct xfs_trans *,void *,int );void (*cancel_item)(struct list_head *);int (*diff_items)(void *,struct list_head *,struct list_head *);fs/xfs/libxfs/xfs_refcount.c +1
-1@@ -1082,7 +1082,6 @@ xfs_refcount_finish_one_cleanup( int xfs_refcount_finish_one( struct xfs_trans *tp, - struct xfs_defer_ops *dfops, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount,@@ -1091,6 +1090,7 @@ xfs_refcount_finish_one( struct xfs_btree_cur **pcur) {struct xfs_mount *mp = tp->t_mountp; +struct xfs_defer_ops *dfops = tp->t_dfops;struct xfs_btree_cur *rcur;struct xfs_buf *agbp =NULL ;int error =0 ;fs/xfs/libxfs/xfs_refcount.h +3
-4@@ -37,10 +37,9 @@ extern int xfs_refcount_decrease_extent(struct xfs_mount *mp,extern void xfs_refcount_finish_one_cleanup (struct xfs_trans *tp,struct xfs_btree_cur *rcur,int error);extern int xfs_refcount_finish_one (struct xfs_trans *tp, -struct xfs_defer_ops *dfops,enum xfs_refcount_intent_type type, -xfs_fsblock_t startblock,xfs_extlen_t blockcount, -xfs_fsblock_t *new_fsb,xfs_extlen_t *new_len, -struct xfs_btree_cur **pcur); +enum xfs_refcount_intent_type type,xfs_fsblock_t startblock, +xfs_extlen_t blockcount,xfs_fsblock_t *new_fsb, +xfs_extlen_t *new_len,struct xfs_btree_cur **pcur); extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno,fs/xfs/xfs_bmap_item.c +2
-3@@ -475,9 +475,8 @@ xfs_bui_recover(xfs_trans_ijoin (tp, ip,0 ); count = bmap->me_len; - error =xfs_trans_log_finish_bmap_update (tp, budp, tp->t_dfops, type, - ip, whichfork, bmap->me_startoff, - bmap->me_startblock, &count, state); + error =xfs_trans_log_finish_bmap_update (tp, budp, type, ip, whichfork, + bmap->me_startoff, bmap->me_startblock, &count, state);if (error) goto err_inode;fs/xfs/xfs_refcount_item.c +2
-2@@ -479,8 +479,8 @@ xfs_cui_recover( new_len = refc->pe_len; }else error =xfs_trans_log_finish_refcount_update (tp, cudp, - tp->t_dfops, type, refc->pe_startblock, - refc->pe_len, &new_fsb, &new_len, &rcur); + type, refc->pe_startblock, refc->pe_len, + &new_fsb, &new_len, &rcur);if (error) goto abort_error;fs/xfs/xfs_trans.h +5
-5@@ -268,7 +268,7 @@ void xfs_refcount_update_init_defer_op(void);struct xfs_cud_log_item *xfs_trans_get_cud (struct xfs_trans *tp,struct xfs_cui_log_item *cuip);int xfs_trans_log_finish_refcount_update (struct xfs_trans *tp, -struct xfs_cud_log_item *cudp,struct xfs_defer_ops *dfops, +struct xfs_cud_log_item *cudp,enum xfs_refcount_intent_type type,xfs_fsblock_t startblock,xfs_extlen_t blockcount,xfs_fsblock_t *new_fsb,xfs_extlen_t *new_len,struct xfs_btree_cur **pcur);@@ -280,9 +280,9 @@ void xfs_bmap_update_init_defer_op(void);struct xfs_bud_log_item *xfs_trans_get_bud (struct xfs_trans *tp,struct xfs_bui_log_item *buip);int xfs_trans_log_finish_bmap_update (struct xfs_trans *tp, -struct xfs_bud_log_item *rudp,struct xfs_defer_ops *dfops, -enum xfs_bmap_intent_type type,struct xfs_inode *ip, -int whichfork,xfs_fileoff_t startoff,xfs_fsblock_t startblock, -xfs_filblks_t *blockcount,xfs_exntst_t state); +struct xfs_bud_log_item *rudp,enum xfs_bmap_intent_type type, +struct xfs_inode *ip,int whichfork,xfs_fileoff_t startoff, +xfs_fsblock_t startblock,xfs_filblks_t *blockcount, +xfs_exntst_t state);#endif /* __XFS_TRANS_H__ */ fs/xfs/xfs_trans_bmap.c +2
-4@@ -43,7 +43,6 @@ intxfs_trans_log_finish_bmap_update ( struct xfs_trans *tp, struct xfs_bud_log_item *budp, - struct xfs_defer_ops *dop, enum xfs_bmap_intent_type type, struct xfs_inode *ip, int whichfork,@@ -54,7 +53,7 @@ xfs_trans_log_finish_bmap_update( {int error; - error =xfs_bmap_finish_one (tp, dop, ip, type, whichfork, startoff, + error =xfs_bmap_finish_one (tp, ip, type, whichfork, startoff, startblock, blockcount, state);/* @@ -176,7 +175,6 @@ xfs_bmap_update_create_done( STATIC intxfs_bmap_update_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)@@ -187,7 +185,7 @@ xfs_bmap_update_finish_item( bmap = container_of(item, struct xfs_bmap_intent, bi_list); count = bmap->bi_bmap.br_blockcount; - error = xfs_trans_log_finish_bmap_update(tp, done_item, dop, + error = xfs_trans_log_finish_bmap_update(tp, done_item, bmap->bi_type, bmap->bi_owner, bmap->bi_whichfork, bmap->bi_bmap.br_startoff,fs/xfs/xfs_trans_extfree.c +0
-2@@ -171,7 +171,6 @@ xfs_extent_free_create_done( STATIC intxfs_extent_free_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)@@ -226,7 +225,6 @@ static const struct xfs_defer_op_type xfs_extent_free_defer_type = { STATIC intxfs_agfl_free_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)fs/xfs/xfs_trans_refcount.c +2
-4@@ -42,7 +42,6 @@ intxfs_trans_log_finish_refcount_update ( struct xfs_trans *tp, struct xfs_cud_log_item *cudp, - struct xfs_defer_ops *dop, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount,@@ -52,7 +51,7 @@ xfs_trans_log_finish_refcount_update( {int error; - error =xfs_refcount_finish_one (tp, dop, type, startblock, + error =xfs_refcount_finish_one (tp, type, startblock, blockcount, new_fsb, new_len, pcur);/* @@ -169,7 +168,6 @@ xfs_refcount_update_create_done( STATIC intxfs_refcount_update_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)@@ -180,7 +178,7 @@ xfs_refcount_update_finish_item(int error; refc = container_of(item, struct xfs_refcount_intent, ri_list); - error = xfs_trans_log_finish_refcount_update(tp, done_item, dop, + error = xfs_trans_log_finish_refcount_update(tp, done_item, refc->ri_type, refc->ri_startblock, refc->ri_blockcount,fs/xfs/xfs_trans_rmap.c +0
-1@@ -193,7 +193,6 @@ xfs_rmap_update_create_done( STATIC intxfs_rmap_update_finish_item (struct xfs_trans *tp, -struct xfs_defer_ops *dop,struct list_head *item,void *done_item,void **state)Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 09/15] xfs: drop dop param from xfs_defer_op_type ->finish_item() callback
In reply to Brian FosterQuoted 6 lines · Brian Foster
The dfops infrastructure ->finish_item() callback passes the transaction and dfops as separate parameters. Since dfops is always part of a transaction, the latter parameter is no longer necessary. Remove it from the various callbacks.
Signed-off-by Brian Foster <[email protected]>
Looks good,
PATCH 10/15 xfs: clean out superfluous dfops dop params/vars
In reply to Brian FosterThe dfops code still passes around the xfs_defer_ops pointer superfluously in a few places. Clean this up wherever the transaction will suffice.
--- fs/xfs/libxfs/xfs_defer.c | 43 +++++++++++++++++++-------------------- fs/xfs/libxfs/xfs_defer.h | 2 +- 2 files changed, 22 insertions(+), 23 deletions(-)
fs/xfs/libxfs/xfs_defer.c +21 -22
@@ -181,9 +181,9 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];*/ STATIC voidxfs_defer_intake_work ( -struct xfs_trans *tp, -struct xfs_defer_ops *dop) +struct xfs_trans *tp) { +struct xfs_defer_ops *dop = tp->t_dfops;struct list_head *li;struct xfs_defer_pending *dfp;
@@ -204,9 +204,9 @@ xfs_defer_intake_work( STATIC voidxfs_defer_trans_abort (struct xfs_trans *tp, -struct xfs_defer_ops *dop,int error) { +struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;trace_xfs_defer_trans_abort (tp->t_mountp, dop, _RET_IP_);
@@ -230,7 +230,6 @@ STATIC intxfs_defer_trans_roll ( struct xfs_trans **tp) { -struct xfs_defer_ops *dop = (*tp)->t_dfops;struct xfs_buf_log_item *bli;struct xfs_inode_log_item *ili;struct xfs_log_item *lip;
@@ -266,14 +265,14 @@ xfs_defer_trans_roll( } } -trace_xfs_defer_trans_roll ((*tp)->t_mountp, dop, _RET_IP_); +trace_xfs_defer_trans_roll ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);/* Roll the transaction. */ error =xfs_trans_roll (tp); - dop = (*tp)->t_dfops;if (error) { -trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, dop, error); -xfs_defer_trans_abort (*tp, dop, error); +trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, + (*tp)->t_dfops, error); +xfs_defer_trans_abort (*tp, error);return error; }
@@ -293,9 +292,10 @@ xfs_defer_trans_roll(/* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work ( -struct xfs_defer_ops *dop) +struct xfs_trans *tp) { -return !list_empty (&dop->dop_pending) || !list_empty (&dop->dop_intake); +return !list_empty (&tp->t_dfops->dop_pending) || + !list_empty (&tp->t_dfops->dop_intake); }/*
@@ -305,7 +305,7 @@ static voidxfs_defer_reset ( struct xfs_trans *tp) { -ASSERT (!xfs_defer_has_unfinished_work (tp->t_dfops)); +ASSERT (!xfs_defer_has_unfinished_work (tp));/* * Low mode state transfers across transaction rolls to mirror dfops
@@ -326,7 +326,6 @@ intxfs_defer_finish_noroll ( struct xfs_trans **tp) { -struct xfs_defer_ops *dop = (*tp)->t_dfops;struct xfs_defer_pending *dfp;struct list_head *li;struct list_head *n;
@@ -336,24 +335,22 @@ xfs_defer_finish_noroll(ASSERT ((*tp)->t_flags &XFS_TRANS_PERM_LOG_RES ); -trace_xfs_defer_finish ((*tp)->t_mountp, dop, _RET_IP_); +trace_xfs_defer_finish ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);/* Until we run out of pending work to finish... */ -while (xfs_defer_has_unfinished_work (dop)) { +while (xfs_defer_has_unfinished_work (*tp)) {/* Log intents for work items sitting in the intake. */ -xfs_defer_intake_work (*tp, dop); +xfs_defer_intake_work (*tp);/* -* Roll the transaction and update dop in case dfops was -* embedded in the transaction. +* Roll the transaction. */ error =xfs_defer_trans_roll (tp);if (error) goto out; - dop = (*tp)->t_dfops;/* Log an intent-done item for the first pending item. */ - dfp =list_first_entry (&dop->dop_pending, + dfp =list_first_entry (&(*tp)->t_dfops->dop_pending, struct xfs_defer_pending, dfp_list);trace_xfs_defer_pending_finish ((*tp)->t_mountp, dfp); dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent,
@@ -384,7 +381,7 @@ xfs_defer_finish_noroll(*/ if (cleanup_fn)cleanup_fn (*tp, state, error); -xfs_defer_trans_abort (*tp, dop, error); +xfs_defer_trans_abort (*tp, error); goto out; } }
@@ -414,9 +411,11 @@ xfs_defer_finish_noroll( out:if (error) -trace_xfs_defer_finish_error ((*tp)->t_mountp, dop, error); +trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, + error);else -trace_xfs_defer_finish_done ((*tp)->t_mountp, dop, _RET_IP_); +trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, + _RET_IP_);return error; }
fs/xfs/libxfs/xfs_defer.h +1 -1
@@ -41,7 +41,7 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop); +bool xfs_defer_has_unfinished_work (struct xfs_trans *tp);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */
Signature · 1 line
2.17.1
Re: [PATCH 10/15] xfs: clean out superfluous dfops dop params/vars
Quoted 5 lines · Brian Foster
The dfops code still passes around the
xfs_defer_opspointer superfluously in a few places. Clean this up wherever the transaction will suffice.Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 162 lines
--- fs/xfs/libxfs/xfs_defer.c | 43 +++++++++++++++++++-------------------- fs/xfs/libxfs/xfs_defer.h | 2 +- 2 files changed, 22 insertions(+), 23 deletions(-)fs/xfs/libxfs/xfs_defer.c +21
-22@@ -181,9 +181,9 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];*/ STATIC voidxfs_defer_intake_work ( -struct xfs_trans *tp, -struct xfs_defer_ops *dop) +struct xfs_trans *tp) { +struct xfs_defer_ops *dop = tp->t_dfops;struct list_head *li;struct xfs_defer_pending *dfp;@@ -204,9 +204,9 @@ xfs_defer_intake_work( STATIC voidxfs_defer_trans_abort (struct xfs_trans *tp, -struct xfs_defer_ops *dop,int error) { +struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;trace_xfs_defer_trans_abort (tp->t_mountp, dop, _RET_IP_);@@ -230,7 +230,6 @@ STATIC intxfs_defer_trans_roll ( struct xfs_trans **tp) { -struct xfs_defer_ops *dop = (*tp)->t_dfops;struct xfs_buf_log_item *bli;struct xfs_inode_log_item *ili;struct xfs_log_item *lip;@@ -266,14 +265,14 @@ xfs_defer_trans_roll( } } -trace_xfs_defer_trans_roll ((*tp)->t_mountp, dop, _RET_IP_); +trace_xfs_defer_trans_roll ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);/* Roll the transaction. */ error =xfs_trans_roll (tp); - dop = (*tp)->t_dfops;if (error) { -trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, dop, error); -xfs_defer_trans_abort (*tp, dop, error); +trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, + (*tp)->t_dfops, error); +xfs_defer_trans_abort (*tp, error);return error; }@@ -293,9 +292,10 @@ xfs_defer_trans_roll(/* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work ( -struct xfs_defer_ops *dop) +struct xfs_trans *tp) { -return !list_empty (&dop->dop_pending) || !list_empty (&dop->dop_intake); +return !list_empty (&tp->t_dfops->dop_pending) || + !list_empty (&tp->t_dfops->dop_intake); }/* @@ -305,7 +305,7 @@ static voidxfs_defer_reset ( struct xfs_trans *tp) { -ASSERT (!xfs_defer_has_unfinished_work (tp->t_dfops)); +ASSERT (!xfs_defer_has_unfinished_work (tp));/* * Low mode state transfers across transaction rolls to mirror dfops @@ -326,7 +326,6 @@ intxfs_defer_finish_noroll ( struct xfs_trans **tp) { -struct xfs_defer_ops *dop = (*tp)->t_dfops;struct xfs_defer_pending *dfp;struct list_head *li;struct list_head *n;@@ -336,24 +335,22 @@ xfs_defer_finish_noroll(ASSERT ((*tp)->t_flags &XFS_TRANS_PERM_LOG_RES ); -trace_xfs_defer_finish ((*tp)->t_mountp, dop, _RET_IP_); +trace_xfs_defer_finish ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);/* Until we run out of pending work to finish... */ -while (xfs_defer_has_unfinished_work (dop)) { +while (xfs_defer_has_unfinished_work (*tp)) {/* Log intents for work items sitting in the intake. */ -xfs_defer_intake_work (*tp, dop); +xfs_defer_intake_work (*tp);/* -* Roll the transaction and update dop in case dfops was -* embedded in the transaction. +* Roll the transaction. */ error =xfs_defer_trans_roll (tp);if (error) goto out; - dop = (*tp)->t_dfops;/* Log an intent-done item for the first pending item. */ - dfp =list_first_entry (&dop->dop_pending, + dfp =list_first_entry (&(*tp)->t_dfops->dop_pending, struct xfs_defer_pending, dfp_list);trace_xfs_defer_pending_finish ((*tp)->t_mountp, dfp); dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent,@@ -384,7 +381,7 @@ xfs_defer_finish_noroll(*/ if (cleanup_fn)cleanup_fn (*tp, state, error); -xfs_defer_trans_abort (*tp, dop, error); +xfs_defer_trans_abort (*tp, error); goto out; } }@@ -414,9 +411,11 @@ xfs_defer_finish_noroll( out:if (error) -trace_xfs_defer_finish_error ((*tp)->t_mountp, dop, error); +trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, + error);else -trace_xfs_defer_finish_done ((*tp)->t_mountp, dop, _RET_IP_); +trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, + _RET_IP_);return error; }fs/xfs/libxfs/xfs_defer.h +1
-1@@ -41,7 +41,7 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work (struct xfs_defer_ops *dop); +bool xfs_defer_has_unfinished_work (struct xfs_trans *tp);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/15] xfs: clean out superfluous dfops dop params/vars
In reply to Brian FosterQuoted 5 lines · Brian Foster
The dfops code still passes around the
xfs_defer_opspointer superfluously in a few places. Clean this up wherever the transaction will suffice.Signed-off-by Brian Foster <[email protected]>
Looks good,
PATCH 11/15 xfs: cancel dfops on xfs_defer_finish() error
In reply to Brian FosterThe current semantics of xfs_defer_finish() require the caller to call xfs_defer_cancel() on error. This is slightly inconsistent with transaction commit error handling where a failed commit cleans up the transaction before returning.
More significantly, the only requirement for exposure of ->dop_pending outside of xfs_defer_finish() is so that xfs_defer_cancel() can drain it on error. Since the only recourse of xfs_defer_finish() errors is cancellation, mirror the transaction logic and cancel remaining dfops before returning from xfs_defer_finish() with an error.
Beside simplifying xfs_defer_finish() semantics, this ensures that xfs_defer_finish() always returns with an empty ->dop_pending and thus facilitates removal of the list from xfs_defer_ops.
--- fs/xfs/libxfs/xfs_attr.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_attr_remote.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 11 ++++++----- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_dquot.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_reflink.c | 4 +--- fs/xfs/xfs_trans.c | 4 +--- 8 files changed, 21 insertions(+), 24 deletions(-)
fs/xfs/libxfs/xfs_attr.c +8 -8
@@ -590,7 +590,7 @@ xfs_attr_leaf_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error;/* * Commit the current trans (including the inode) and start
@@ -678,7 +678,7 @@ xfs_attr_leaf_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error; }/*
@@ -741,7 +741,7 @@ xfs_attr_leaf_removename( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error; }return 0 ; out_defer_cancel:
@@ -867,7 +867,7 @@ xfs_attr_node_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out;/* * Commit the node conversion and start the next
@@ -891,7 +891,7 @@ xfs_attr_node_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out; }else {/* * Addition succeeded, update Btree hashvals.
@@ -987,7 +987,7 @@ xfs_attr_node_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out; }/*
@@ -1110,7 +1110,7 @@ xfs_attr_node_removename( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out;/* * Commit the Btree join operation and start a new trans. */
@@ -1141,7 +1141,7 @@ xfs_attr_node_removename( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out; }else xfs_trans_brelse (args->trans, bp); }
fs/xfs/libxfs/xfs_attr_remote.c +2 -2
@@ -488,7 +488,7 @@ xfs_attr_rmtval_set( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error;ASSERT (nmap ==1 ); ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
@@ -628,7 +628,7 @@ xfs_attr_rmtval_remove( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error;/* * Close out trans and start the next one in the chain.
fs/xfs/libxfs/xfs_defer.c +6 -5
@@ -410,14 +410,15 @@ xfs_defer_finish_noroll( } out: -if (error) +if (error) {trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, error); -else -trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, - _RET_IP_); +xfs_defer_cancel (*tp); +return error; + } -return error; +trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); +return 0 ; }int
fs/xfs/xfs_bmap_util.c +1 -1
@@ -1624,7 +1624,7 @@ xfs_swap_extent_rmap( error =xfs_defer_finish (tpp); tp = *tpp;if (error) - goto out_defer; + goto out; tirec.br_startoff += rlen; if (tirec.br_startblock != HOLESTARTBLOCK &&
fs/xfs/xfs_dquot.c +1 -1
@@ -371,7 +371,7 @@ xfs_dquot_disk_alloc( tp = *tpp;if (error) {xfs_buf_relse (bp); - goto error1; + goto error0; } *bpp = bp;return 0 ;
fs/xfs/xfs_inode.c +1 -1
@@ -1571,7 +1571,7 @@ xfs_itruncate_extents_flags(*/ error =xfs_defer_finish (&tp);if (error) - goto out_bmap_cancel; + goto out; error =xfs_trans_roll_inode (&tp, ip);if (error)
fs/xfs/xfs_reflink.c +1 -3
@@ -518,10 +518,8 @@ xfs_reflink_cancel_cow_blocks(/* Roll the transaction */ error =xfs_defer_finish (tpp); -if (error) { -xfs_defer_cancel (*tpp); +if (error)break ; - }/* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow (ip, &icur, &got, &del);
fs/xfs/xfs_trans.c +1 -3
@@ -928,10 +928,8 @@ __xfs_trans_commit(/* finish deferred items on final commit */ if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) { error =xfs_defer_finish_noroll (&tp); -if (error) { -xfs_defer_cancel (tp); +if (error) goto out_unreserve; - } }/*
Signature · 1 line
2.17.1
Re: [PATCH 11/15] xfs: cancel dfops on xfs_defer_finish() error
Quoted 12 lines · Brian Foster
The current semantics of
xfs_defer_finish()require the caller to callxfs_defer_cancel()on error. This is slightly inconsistent with transaction commit error handling where a failed commit cleans up the transaction before returning.More significantly, the only requirement for exposure of ->dop_pending outside of
xfs_defer_finish()is so thatxfs_defer_cancel()can drain it on error. Since the only recourse ofxfs_defer_finish()errors is cancellation, mirror the transaction logic and cancel remaining dfops before returning fromxfs_defer_finish()with an error.
Quoted 5 lines
Beside simplifying
xfs_defer_finish()semantics, this ensures thatxfs_defer_finish()always returns with an empty ->dop_pending and thus facilitates removal of the list fromxfs_defer_ops.Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 212 lines
--- fs/xfs/libxfs/xfs_attr.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_attr_remote.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 11 ++++++----- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_dquot.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_reflink.c | 4 +--- fs/xfs/xfs_trans.c | 4 +--- 8 files changed, 21 insertions(+), 24 deletions(-)fs/xfs/libxfs/xfs_attr.c +8
-8@@ -590,7 +590,7 @@ xfs_attr_leaf_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error;/* * Commit the current trans (including the inode) and start @@ -678,7 +678,7 @@ xfs_attr_leaf_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error; }/* @@ -741,7 +741,7 @@ xfs_attr_leaf_removename( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error; }return 0 ; out_defer_cancel:@@ -867,7 +867,7 @@ xfs_attr_node_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out;/* * Commit the node conversion and start the next @@ -891,7 +891,7 @@ xfs_attr_node_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out; }else {/* * Addition succeeded, update Btree hashvals. @@ -987,7 +987,7 @@ xfs_attr_node_addname( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out; }/* @@ -1110,7 +1110,7 @@ xfs_attr_node_removename( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out;/* * Commit the Btree join operation and start a new trans. */ @@ -1141,7 +1141,7 @@ xfs_attr_node_removename( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; + goto out; }else xfs_trans_brelse (args->trans, bp); }fs/xfs/libxfs/xfs_attr_remote.c +2
-2@@ -488,7 +488,7 @@ xfs_attr_rmtval_set( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error;ASSERT (nmap ==1 ); ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&@@ -628,7 +628,7 @@ xfs_attr_rmtval_remove( goto out_defer_cancel; error =xfs_defer_finish (&args->trans);if (error) - goto out_defer_cancel; +return error;/* * Close out trans and start the next one in the chain. fs/xfs/libxfs/xfs_defer.c +6
-5@@ -410,14 +410,15 @@ xfs_defer_finish_noroll( } out: -if (error) +if (error) {trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, error); -else -trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, - _RET_IP_); +xfs_defer_cancel (*tp); +return error; + } -return error; +trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); +return 0 ; }int fs/xfs/xfs_bmap_util.c +1
-1@@ -1624,7 +1624,7 @@ xfs_swap_extent_rmap( error =xfs_defer_finish (tpp); tp = *tpp;if (error) - goto out_defer; + goto out; tirec.br_startoff += rlen; if (tirec.br_startblock != HOLESTARTBLOCK &&fs/xfs/xfs_dquot.c +1
-1@@ -371,7 +371,7 @@ xfs_dquot_disk_alloc( tp = *tpp;if (error) {xfs_buf_relse (bp); - goto error1; + goto error0; } *bpp = bp;return 0 ;fs/xfs/xfs_inode.c +1
-1@@ -1571,7 +1571,7 @@ xfs_itruncate_extents_flags(*/ error =xfs_defer_finish (&tp);if (error) - goto out_bmap_cancel; + goto out; error =xfs_trans_roll_inode (&tp, ip);if (error)fs/xfs/xfs_reflink.c +1
-3@@ -518,10 +518,8 @@ xfs_reflink_cancel_cow_blocks(/* Roll the transaction */ error =xfs_defer_finish (tpp); -if (error) { -xfs_defer_cancel (*tpp); +if (error)break ; - }/* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow (ip, &icur, &got, &del);fs/xfs/xfs_trans.c +1
-3@@ -928,10 +928,8 @@ __xfs_trans_commit(/* finish deferred items on final commit */ if (!regrant && (tp->t_flags &XFS_TRANS_PERM_LOG_RES )) { error =xfs_defer_finish_noroll (&tp); -if (error) { -xfs_defer_cancel (tp); +if (error) goto out_unreserve; - } }/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 11/15] xfs: cancel dfops on xfs_defer_finish() error
In reply to Brian FosterLooks good,
PATCH 12/15 xfs: replace xfs_defer_ops ->dop_pending with on-stack list
In reply to Brian FosterThe xfs_defer_ops ->dop_pending list is used to track active deferred operations once intents are logged. These items must be aborted in the event of an error. The list is populated as intents are logged and items are removed as they complete (or are aborted).
Now that xfs_defer_finish() cancels on error, there is no need to ever access ->dop_pending outside of xfs_defer_finish(). The list is only ever populated after xfs_defer_finish() begins and is either completed or cancelled before it returns.
Remove ->dop_pending from xfs_defer_ops and replace it with a local list in the xfs_defer_finish() path. Pass the local list to the various helpers now that it is not accessible via dfops. Note that we have to check for NULL in the abort case as the final tx roll occurs outside of the scope of the new local list (once the dfops has completed and thus drained the list).
--- fs/xfs/libxfs/xfs_defer.c | 80 ++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_defer.h | 3 +- fs/xfs/xfs_trace.h | 1 - fs/xfs/xfs_trans.h | 1 - 4 files changed, 43 insertions(+), 42 deletions(-)
fs/xfs/libxfs/xfs_defer.c +41 -39
@@ -174,6 +174,8 @@static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX ]; +static void __xfs_defer_cancel (struct list_head *); +/* * For each pending item in the intake list, log its intent item and the * associated extents, then add the entire intake list to the end of
@@ -181,7 +183,8 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];*/ STATIC voidxfs_defer_intake_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) {struct xfs_defer_ops *dop = tp->t_dfops;struct list_head *li;
@@ -197,13 +200,14 @@ xfs_defer_intake_work( dfp->dfp_type->log_item (tp, dfp->dfp_intent, li); } -list_splice_tail_init (&dop->dop_intake, &dop->dop_pending); +list_splice_tail_init (&dop->dop_intake, dop_pending); }/* Abort all the intents that were committed. */ STATIC voidxfs_defer_trans_abort (struct xfs_trans *tp, +struct list_head *dop_pending,int error) {struct xfs_defer_ops *dop = tp->t_dfops;
@@ -212,11 +216,13 @@ xfs_defer_trans_abort(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) { -trace_xfs_defer_pending_abort (tp->t_mountp, dfp); -if (dfp->dfp_intent && !dfp->dfp_done) { - dfp->dfp_type->abort_intent (dfp->dfp_intent); - dfp->dfp_intent =NULL ; +if (dop_pending) { +list_for_each_entry (dfp, dop_pending, dfp_list) { +trace_xfs_defer_pending_abort (tp->t_mountp, dfp); +if (dfp->dfp_intent && !dfp->dfp_done) { + dfp->dfp_type->abort_intent (dfp->dfp_intent); + dfp->dfp_intent =NULL ; + } } }
@@ -228,7 +234,8 @@ xfs_defer_trans_abort(/* Roll a transaction so we can do some deferred op processing. */ STATIC intxfs_defer_trans_roll ( -struct xfs_trans **tp) +struct xfs_trans **tp, +struct list_head *dop_pending) {struct xfs_buf_log_item *bli;struct xfs_inode_log_item *ili;
@@ -272,7 +279,7 @@ xfs_defer_trans_roll(if (error) {trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, (*tp)->t_dfops, error); -xfs_defer_trans_abort (*tp, error); +xfs_defer_trans_abort (*tp, dop_pending, error);return error; }
@@ -292,9 +299,10 @@ xfs_defer_trans_roll(/* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) { -return !list_empty (&tp->t_dfops->dop_pending) || +return !list_empty (dop_pending) || !list_empty (&tp->t_dfops->dop_intake); }
@@ -305,7 +313,7 @@ static voidxfs_defer_reset ( struct xfs_trans *tp) { -ASSERT (!xfs_defer_has_unfinished_work (tp)); +ASSERT (list_empty (&tp->t_dfops->dop_intake));/* * Low mode state transfers across transaction rolls to mirror dfops
@@ -332,26 +340,27 @@ xfs_defer_finish_noroll(void *state;int error =0 ;void (*cleanup_fn)(struct xfs_trans *,void *,int ); +LIST_HEAD (dop_pending);ASSERT ((*tp)->t_flags &XFS_TRANS_PERM_LOG_RES );trace_xfs_defer_finish ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);/* Until we run out of pending work to finish... */ -while (xfs_defer_has_unfinished_work (*tp)) { +while (xfs_defer_has_unfinished_work (*tp, &dop_pending)) {/* Log intents for work items sitting in the intake. */ -xfs_defer_intake_work (*tp); +xfs_defer_intake_work (*tp, &dop_pending);/* * Roll the transaction. */ - error =xfs_defer_trans_roll (tp); + error =xfs_defer_trans_roll (tp, &dop_pending);if (error) goto out;/* Log an intent-done item for the first pending item. */ - dfp =list_first_entry (&(*tp)->t_dfops->dop_pending, - struct xfs_defer_pending, dfp_list); + dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, + dfp_list);trace_xfs_defer_pending_finish ((*tp)->t_mountp, dfp); dfp->dfp_done = dfp->dfp_type->create_done (*tp, dfp->dfp_intent, dfp->dfp_count);
@@ -381,7 +390,7 @@ xfs_defer_finish_noroll(*/ if (cleanup_fn)cleanup_fn (*tp, state, error); -xfs_defer_trans_abort (*tp, error); +xfs_defer_trans_abort (*tp, &dop_pending, error); goto out; } }
@@ -413,6 +422,7 @@ xfs_defer_finish_noroll(if (error) {trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, error); +__xfs_defer_cancel (&dop_pending);xfs_defer_cancel (*tp);return error; }
@@ -435,7 +445,7 @@ xfs_defer_finish(if (error)return error;if ((*tp)->t_flags &XFS_TRANS_DIRTY ) { - error =xfs_defer_trans_roll (tp); + error =xfs_defer_trans_roll (tp,NULL );if (error)return error; }
@@ -446,34 +456,20 @@ xfs_defer_finish(/* * Free up any items left in the list. */ -void -xfs_defer_cancel ( -struct xfs_trans *tp) +static void +__xfs_defer_cancel ( +struct list_head *dop_list) { -struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;struct xfs_defer_pending *pli;struct list_head *pwi;struct list_head *n; -trace_xfs_defer_cancel (NULL , dop, _RET_IP_); -/* * Free the pending items. Caller should already have arranged * for the intent items to be released. */ -list_for_each_entry_safe (dfp, pli, &dop->dop_intake, dfp_list) { -trace_xfs_defer_intake_cancel (NULL , dfp); -list_del (&dfp->dfp_list); -list_for_each_safe (pwi, n, &dfp->dfp_work) { -list_del (pwi); - dfp->dfp_count--; - dfp->dfp_type->cancel_item (pwi); - } -ASSERT (dfp->dfp_count ==0 ); -kmem_free (dfp); - } -list_for_each_entry_safe (dfp, pli, &dop->dop_pending, dfp_list) { +list_for_each_entry_safe (dfp, pli, dop_list, dfp_list) {trace_xfs_defer_pending_cancel (NULL , dfp);list_del (&dfp->dfp_list);list_for_each_safe (pwi, n, &dfp->dfp_work) {
@@ -486,6 +482,14 @@ xfs_defer_cancel( } } +void +xfs_defer_cancel ( +struct xfs_trans *tp) +{ +trace_xfs_defer_cancel (NULL , tp->t_dfops, _RET_IP_); +__xfs_defer_cancel (&tp->t_dfops->dop_intake); +} +/* Add an item for later deferred processing. */ void xfs_defer_add(
@@ -541,7 +545,6 @@ xfs_defer_init(memset (dop,0 ,sizeof (struct xfs_defer_ops ));INIT_LIST_HEAD (&dop->dop_intake); -INIT_LIST_HEAD (&dop->dop_pending);if (tp) {ASSERT (tp->t_firstblock ==NULLFSBLOCK ); tp->t_dfops = dop;
@@ -565,7 +568,6 @@ xfs_defer_move(ASSERT (dst != src);list_splice_init (&src->dop_intake, &dst->dop_intake); -list_splice_init (&src->dop_pending, &dst->dop_pending);/* * Low free space mode was historically controlled by a dfops field.
fs/xfs/libxfs/xfs_defer.h +2 -1
@@ -41,7 +41,8 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work (struct xfs_trans *tp); +bool xfs_defer_has_unfinished_work (struct xfs_trans *tp, +struct list_head *dop_pending);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */
fs/xfs/xfs_trace.h +0 -1
@@ -2393,7 +2393,6 @@ DEFINE_DEFER_ERROR_EVENT(xfs_defer_trans_roll_error);DEFINE_DEFER_ERROR_EVENT (xfs_defer_finish_error);DEFINE_DEFER_PENDING_EVENT (xfs_defer_intake_work); -DEFINE_DEFER_PENDING_EVENT (xfs_defer_intake_cancel);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_cancel);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_finish);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_abort);
fs/xfs/xfs_trans.h +0 -1
@@ -96,7 +96,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,#define XFS_DEFER_OPS_NR_BUFS 2/* join up to two buffers */ struct xfs_defer_ops {struct list_head dop_intake;/* unlogged pending work */ -struct list_head dop_pending;/* logged pending work */ };/*
Signature · 1 line
2.17.1
Re: [PATCH 12/15] xfs: replace xfs_defer_ops ->dop_pending with on-stack list
Quoted 65 lines · Brian Foster
The
xfs_defer_ops->dop_pending list is used to track active deferred operations once intents are logged. These items must be aborted in the event of an error. The list is populated as intents are logged and items are removed as they complete (or are aborted).Now that
xfs_defer_finish()cancels on error, there is no need to ever access ->dop_pending outside ofxfs_defer_finish(). The list is only ever populated afterxfs_defer_finish()begins and is either completed or cancelled before it returns.Remove ->dop_pending from
xfs_defer_opsand replace it with a local list in thexfs_defer_finish()path. Pass the local list to the various helpers now that it is not accessible via dfops. Note that we have to check for NULL in the abort case as the final tx roll occurs outside of the scope of the new local list (once the dfops has completed and thus drained the list).Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_defer.c | 80 ++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_defer.h | 3 +- fs/xfs/xfs_trace.h | 1 - fs/xfs/xfs_trans.h | 1 - 4 files changed, 43 insertions(+), 42 deletions(-)fs/xfs/libxfs/xfs_defer.c +6
-2@@ -174,6 +174,8 @@static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX ]; +static void __xfs_defer_cancel (struct list_head *); +/* * For each pending item in the intake list, log its intent item and the * associated extents, then add the entire intake list to the end of @@ -181,7 +183,8 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];*/ STATIC voidxfs_defer_intake_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) {struct xfs_defer_ops *dop = tp->t_dfops;struct list_head *li;@@ -197,13 +200,14 @@ xfs_defer_intake_work( dfp->dfp_type->log_item (tp, dfp->dfp_intent, li); } -list_splice_tail_init (&dop->dop_intake, &dop->dop_pending); +list_splice_tail_init (&dop->dop_intake, dop_pending); }/* Abort all the intents that were committed. */ STATIC voidxfs_defer_trans_abort (struct xfs_trans *tp, +struct list_head *dop_pending,int error) {struct xfs_defer_ops *dop = tp->t_dfops;
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_abort( · line 219
Quoted 9 lines
fs/xfs/libxfs/xfs_defer.c +1
-5@@ -212,11 +216,13 @@ xfs_defer_trans_abort(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) { -trace_xfs_defer_pending_abort (tp->t_mountp, dfp); -if (dfp->dfp_intent && !dfp->dfp_done) { - dfp->dfp_type->abort_intent (dfp->dfp_intent); - dfp->dfp_intent =NULL ; +if (dop_pending) {
/me kinda wonders if you could just make xfs_defer_finish pass an empty list_head into xfs_defer_trans_roll to avoid this extra indent, but I don't care all that much and maybe we should save the stack space. :)
Quoted 53 lines
fs/xfs/libxfs/xfs_defer.c +13
-5+list_for_each_entry (dfp, dop_pending, dfp_list) { +trace_xfs_defer_pending_abort (tp->t_mountp, dfp); +if (dfp->dfp_intent && !dfp->dfp_done) { + dfp->dfp_type->abort_intent (dfp->dfp_intent); + dfp->dfp_intent =NULL ; + } } }@@ -228,7 +234,8 @@ xfs_defer_trans_abort(/* Roll a transaction so we can do some deferred op processing. */ STATIC intxfs_defer_trans_roll ( -struct xfs_trans **tp) +struct xfs_trans **tp, +struct list_head *dop_pending) {struct xfs_buf_log_item *bli;struct xfs_inode_log_item *ili;@@ -272,7 +279,7 @@ xfs_defer_trans_roll(if (error) {trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, (*tp)->t_dfops, error); -xfs_defer_trans_abort (*tp, error); +xfs_defer_trans_abort (*tp, dop_pending, error);return error; }@@ -292,9 +299,10 @@ xfs_defer_trans_roll(/* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) { -return !list_empty (&tp->t_dfops->dop_pending) || +return !list_empty (dop_pending) || !list_empty (&tp->t_dfops->dop_intake); }@@ -305,7 +313,7 @@ static voidxfs_defer_reset ( struct xfs_trans *tp) { -ASSERT (!xfs_defer_has_unfinished_work (tp)); +ASSERT (list_empty (&tp->t_dfops->dop_intake));/* * Low mode state transfers across transaction rolls to mirror dfops @@ -332,26 +340,27 @@ xfs_defer_finish_noroll(void *state;int error =0 ;
fs/xfs/libxfs/xfs_defer.c xfs_defer_finish_noroll( · line 350
Quoted 10 lines
fs/xfs/libxfs/xfs_defer.c +2
-1void (*cleanup_fn)(struct xfs_trans *,void *,int ); +LIST_HEAD (dop_pending);ASSERT ((*tp)->t_flags &XFS_TRANS_PERM_LOG_RES );trace_xfs_defer_finish ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);/* Until we run out of pending work to finish... */ -while (xfs_defer_has_unfinished_work (*tp)) { +while (xfs_defer_has_unfinished_work (*tp, &dop_pending)) {
<urk> see discussion below.
Quoted 47 lines
fs/xfs/libxfs/xfs_defer.c +7
-6/* Log intents for work items sitting in the intake. */ -xfs_defer_intake_work (*tp); +xfs_defer_intake_work (*tp, &dop_pending);/* * Roll the transaction. */ - error =xfs_defer_trans_roll (tp); + error =xfs_defer_trans_roll (tp, &dop_pending);if (error) goto out;/* Log an intent-done item for the first pending item. */ - dfp =list_first_entry (&(*tp)->t_dfops->dop_pending, - struct xfs_defer_pending, dfp_list); + dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, + dfp_list);trace_xfs_defer_pending_finish ((*tp)->t_mountp, dfp); dfp->dfp_done = dfp->dfp_type->create_done (*tp, dfp->dfp_intent, dfp->dfp_count);@@ -381,7 +390,7 @@ xfs_defer_finish_noroll(*/ if (cleanup_fn)cleanup_fn (*tp, state, error); -xfs_defer_trans_abort (*tp, error); +xfs_defer_trans_abort (*tp, &dop_pending, error); goto out; } }@@ -413,6 +422,7 @@ xfs_defer_finish_noroll(if (error) {trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, error); +__xfs_defer_cancel (&dop_pending);xfs_defer_cancel (*tp);return error; }@@ -435,7 +445,7 @@ xfs_defer_finish(if (error)return error;if ((*tp)->t_flags &XFS_TRANS_DIRTY ) { - error =xfs_defer_trans_roll (tp); + error =xfs_defer_trans_roll (tp,NULL );if (error)return error; }
fs/xfs/libxfs/xfs_defer.c xfs_defer_finish( · line 460
Quoted 8 lines
fs/xfs/libxfs/xfs_defer.c +2
-3@@ -446,34 +456,20 @@ xfs_defer_finish(/* * Free up any items left in the list. */ -void -xfs_defer_cancel ( -struct xfs_trans *tp) +static void +__xfs_defer_cancel(
Maybe this should be xfs_defer_cancel_list?
Quoted 18 lines
fs/xfs/libxfs/xfs_defer.c +1
-7+ struct list_head *dop_list) { -struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;struct xfs_defer_pending *pli;struct list_head *pwi;struct list_head *n; -trace_xfs_defer_cancel (NULL , dop, _RET_IP_); -/* * Free the pending items. Caller should already have arranged * for the intent items to be released. */ -list_for_each_entry_safe (dfp, pli, &dop->dop_intake, dfp_list) { -trace_xfs_defer_intake_cancel (NULL , dfp); -list_del (&dfp->dfp_list); -list_for_each_safe (pwi, n, &dfp->dfp_work) {
fs/xfs/libxfs/xfs_defer.c xfs_defer_finish( · line 473
Quoted 10 lines
fs/xfs/libxfs/xfs_defer.c +1
-8-list_del (pwi); - dfp->dfp_count--; - dfp->dfp_type->cancel_item (pwi); - } -ASSERT (dfp->dfp_count ==0 ); -kmem_free (dfp); - } -list_for_each_entry_safe (dfp, pli, &dop->dop_pending, dfp_list) { +list_for_each_entry_safe (dfp, pli, dop_list, dfp_list) {trace_xfs_defer_pending_cancel (NULL , dfp);
trace_xfs_defer_cancel_list?
Maybe it's worth passing a *mp into this function so we can pass it to the tracepoint?
fs/xfs/libxfs/xfs_defer.c xfs_defer_cancel( · line 489
Quoted 11 lines
fs/xfs/libxfs/xfs_defer.c +5
-0list_del (&dfp->dfp_list);list_for_each_safe (pwi, n, &dfp->dfp_work) {@@ -486,6 +482,14 @@ xfs_defer_cancel( } } +void +xfs_defer_cancel ( +struct xfs_trans *tp) +{ +trace_xfs_defer_cancel (NULL , tp->t_dfops, _RET_IP_);
That NULL can be tp->t_mountp, right? Since tp should never be NULL?
Quoted 27 lines
fs/xfs/libxfs/xfs_defer.c +3
-2+__xfs_defer_cancel (&tp->t_dfops->dop_intake); +} +/* Add an item for later deferred processing. */ void xfs_defer_add(@@ -541,7 +545,6 @@ xfs_defer_init(memset (dop,0 ,sizeof (struct xfs_defer_ops ));INIT_LIST_HEAD (&dop->dop_intake); -INIT_LIST_HEAD (&dop->dop_pending);if (tp) {ASSERT (tp->t_firstblock ==NULLFSBLOCK ); tp->t_dfops = dop;@@ -565,7 +568,6 @@ xfs_defer_move(ASSERT (dst != src);list_splice_init (&src->dop_intake, &dst->dop_intake); -list_splice_init (&src->dop_pending, &dst->dop_pending);/* * Low free space mode was historically controlled by a dfops field. fs/xfs/libxfs/xfs_defer.h +0
-0
fs/xfs/libxfs/xfs_defer.h int xfs_defer_finish_noroll(struct xfs_trans **tp); · line 45
Quoted 6 lines
fs/xfs/libxfs/xfs_defer.h +2
-1@@ -41,7 +41,8 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work (struct xfs_trans *tp); +bool xfs_defer_has_unfinished_work (struct xfs_trans *tp, +struct list_head *dop_pending);
Eww, I dislike exposing this implementation detail in a public interface. Assuming you take my suggestion in patch 1 to ASSERT if xfs_trans_{cancel,commit} encounter unfinished deferred work and a transaction we can't roll, there will be only three callers of this function, and only one of them knows about the pending item list. Perhaps the list_empty(dop_pending) check can be open-coded in xfs_defer_finish_noroll?
--D
Quoted 34 lines
fs/xfs/libxfs/xfs_defer.h +0
-0void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ fs/xfs/xfs_trace.h +0
-1@@ -2393,7 +2393,6 @@ DEFINE_DEFER_ERROR_EVENT(xfs_defer_trans_roll_error);DEFINE_DEFER_ERROR_EVENT (xfs_defer_finish_error);DEFINE_DEFER_PENDING_EVENT (xfs_defer_intake_work); -DEFINE_DEFER_PENDING_EVENT (xfs_defer_intake_cancel);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_cancel);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_finish);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_abort);fs/xfs/xfs_trans.h +0
-1@@ -96,7 +96,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,#define XFS_DEFER_OPS_NR_BUFS 2/* join up to two buffers */ struct xfs_defer_ops {struct list_head dop_intake;/* unlogged pending work */ -struct list_head dop_pending;/* logged pending work */ };/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 12/15] xfs: replace xfs_defer_ops ->dop_pending with on-stack list
Quoted 30 lines · Darrick J. Wong
Quoted 29 lines · Brian Foster
The
xfs_defer_ops->dop_pending list is used to track active deferred operations once intents are logged. These items must be aborted in the event of an error. The list is populated as intents are logged and items are removed as they complete (or are aborted).Now that
xfs_defer_finish()cancels on error, there is no need to ever access ->dop_pending outside ofxfs_defer_finish(). The list is only ever populated afterxfs_defer_finish()begins and is either completed or cancelled before it returns.Remove ->dop_pending from
xfs_defer_opsand replace it with a local list in thexfs_defer_finish()path. Pass the local list to the various helpers now that it is not accessible via dfops. Note that we have to check for NULL in the abort case as the final tx roll occurs outside of the scope of the new local list (once the dfops has completed and thus drained the list).Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_defer.c | 80 ++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_defer.h | 3 +- fs/xfs/xfs_trace.h | 1 - fs/xfs/xfs_trans.h | 1 - 4 files changed, 43 insertions(+), 42 deletions(-)fs/xfs/libxfs/xfs_defer.c +0
-0
...
Quoted 15 lines
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_abort( · line 219
Quoted 10 lines
fs/xfs/libxfs/xfs_defer.c +1
-5@@ -212,11 +216,13 @@ xfs_defer_trans_abort(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) { -trace_xfs_defer_pending_abort (tp->t_mountp, dfp); -if (dfp->dfp_intent && !dfp->dfp_done) { - dfp->dfp_type->abort_intent (dfp->dfp_intent); - dfp->dfp_intent =NULL ; +if (dop_pending) {/me kinda wonders if you could just make
xfs_defer_finishpass an emptylist_headintoxfs_defer_trans_rollto avoid this extra indent, but I don't care all that much and maybe we should save the stack space. :)
I started with something like that when hacking this up and eventually replaced it because the indent didn't actually create any long lines.
Quoted 9 lines
Quoted 9 lines
fs/xfs/libxfs/xfs_defer.c +6
-0+list_for_each_entry (dfp, dop_pending, dfp_list) { +trace_xfs_defer_pending_abort (tp->t_mountp, dfp); +if (dfp->dfp_intent && !dfp->dfp_done) { + dfp->dfp_type->abort_intent (dfp->dfp_intent); + dfp->dfp_intent =NULL ; + } } }
...
Quoted 12 lines
fs/xfs/libxfs/xfs_defer.c xfs_defer_finish( · line 460
Quoted 9 lines
fs/xfs/libxfs/xfs_defer.c +2
-3@@ -446,34 +456,20 @@ xfs_defer_finish(/* * Free up any items left in the list. */ -void -xfs_defer_cancel ( -struct xfs_trans *tp) +static void +__xfs_defer_cancel(Maybe this should be
xfs_defer_cancel_list?
Sure.
Quoted 31 lines
Quoted 18 lines
fs/xfs/libxfs/xfs_defer.c +1
-7+ struct list_head *dop_list) { -struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp;struct xfs_defer_pending *pli;struct list_head *pwi;struct list_head *n; -trace_xfs_defer_cancel (NULL , dop, _RET_IP_); -/* * Free the pending items. Caller should already have arranged * for the intent items to be released. */ -list_for_each_entry_safe (dfp, pli, &dop->dop_intake, dfp_list) { -trace_xfs_defer_intake_cancel (NULL , dfp); -list_del (&dfp->dfp_list); -list_for_each_safe (pwi, n, &dfp->dfp_work) {fs/xfs/libxfs/xfs_defer.c xfs_defer_finish( · line 473
Quoted 10 lines
fs/xfs/libxfs/xfs_defer.c +1
-8-list_del (pwi); - dfp->dfp_count--; - dfp->dfp_type->cancel_item (pwi); - } -ASSERT (dfp->dfp_count ==0 ); -kmem_free (dfp); - } -list_for_each_entry_safe (dfp, pli, &dop->dop_pending, dfp_list) { +list_for_each_entry_safe (dfp, pli, dop_list, dfp_list) {trace_xfs_defer_pending_cancel (NULL , dfp);
trace_xfs_defer_cancel_list?
Quoted 3 lines
Maybe it's worth passing a *mp into this function so we can pass it to the tracepoint?
Ok.
Quoted 6 lines
Quoted 6 lines
fs/xfs/libxfs/xfs_defer.c +0
-0list_del (&dfp->dfp_list);list_for_each_safe (pwi, n, &dfp->dfp_work) {@@ -486,6 +482,14 @@ xfs_defer_cancel( } }
Quoted 8 lines
fs/xfs/libxfs/xfs_defer.c xfs_defer_cancel( · line 489
Quoted 5 lines
fs/xfs/libxfs/xfs_defer.c +5
-0+void +xfs_defer_cancel ( +struct xfs_trans *tp) +{ +trace_xfs_defer_cancel (NULL , tp->t_dfops, _RET_IP_);That NULL can be
tp->t_mountp, right? Since tp should never be NULL?
Yeah, this will hopefully be replaced with the transaction reference so that makes sense.
Quoted 6 lines
Quoted 6 lines
fs/xfs/libxfs/xfs_defer.c +3
-0+__xfs_defer_cancel (&tp->t_dfops->dop_intake); +} +/* Add an item for later deferred processing. */ void xfs_defer_add(
...
Quoted 12 lines
fs/xfs/libxfs/xfs_defer.h int xfs_defer_finish_noroll(struct xfs_trans **tp); · line 45
Quoted 11 lines
fs/xfs/libxfs/xfs_defer.h +2
-1@@ -41,7 +41,8 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *);void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work (struct xfs_trans *tp); +bool xfs_defer_has_unfinished_work (struct xfs_trans *tp, +struct list_head *dop_pending);
Quoted 8 lines
Eww, I dislike exposing this implementation detail in a public interface. Assuming you take my suggestion in patch 1 to ASSERT if xfs_trans_{cancel,commit} encounter unfinished deferred work and a transaction we can't roll, there will be only three callers of this function, and only one of them knows about the pending item list. Perhaps the
list_empty(dop_pending)check can be open-coded inxfs_defer_finish_noroll?
Christoph points out there's only one caller left so I'll probably just kill this off entirely.
Brian
Quoted 40 lines
--D
Quoted 34 lines
fs/xfs/libxfs/xfs_defer.h +0
-0void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);/* Description of a deferred type. */ fs/xfs/xfs_trace.h +0
-1@@ -2393,7 +2393,6 @@ DEFINE_DEFER_ERROR_EVENT(xfs_defer_trans_roll_error);DEFINE_DEFER_ERROR_EVENT (xfs_defer_finish_error);DEFINE_DEFER_PENDING_EVENT (xfs_defer_intake_work); -DEFINE_DEFER_PENDING_EVENT (xfs_defer_intake_cancel);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_cancel);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_finish);DEFINE_DEFER_PENDING_EVENT (xfs_defer_pending_abort);fs/xfs/xfs_trans.h +0
-1@@ -96,7 +96,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,#define XFS_DEFER_OPS_NR_BUFS 2/* join up to two buffers */ struct xfs_defer_ops {struct list_head dop_intake;/* unlogged pending work */ -struct list_head dop_pending;/* logged pending work */ };/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 12/15] xfs: replace xfs_defer_ops ->dop_pending with on-stack list
In reply to Brian FosterQuoted 30 lines · Brian Foster
The
xfs_defer_ops->dop_pending list is used to track active deferred operations once intents are logged. These items must be aborted in the event of an error. The list is populated as intents are logged and items are removed as they complete (or are aborted).Now that
xfs_defer_finish()cancels on error, there is no need to ever access ->dop_pending outside ofxfs_defer_finish(). The list is only ever populated afterxfs_defer_finish()begins and is either completed or cancelled before it returns.Remove ->dop_pending from
xfs_defer_opsand replace it with a local list in thexfs_defer_finish()path. Pass the local list to the various helpers now that it is not accessible via dfops. Note that we have to check for NULL in the abort case as the final tx roll occurs outside of the scope of the new local list (once the dfops has completed and thus drained the list).Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_defer.c | 80 ++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_defer.h | 3 +- fs/xfs/xfs_trace.h | 1 - fs/xfs/xfs_trans.h | 1 - 4 files changed, 43 insertions(+), 42 deletions(-)fs/xfs/libxfs/xfs_defer.c +0
-0
fs/xfs/libxfs/xfs_defer.c line 177
Quoted 4 lines
fs/xfs/libxfs/xfs_defer.c +1
-0@@ -174,6 +174,8 @@static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX ]; +static void __xfs_defer_cancel (struct list_head *);
Can you just move __xfs_defer_cancel up to here to avoid the forward declaration?
Quoted 15 lines
fs/xfs/libxfs/xfs_defer.c +3
-1+/* * For each pending item in the intake list, log its intent item and the * associated extents, then add the entire intake list to the end of @@ -181,7 +183,8 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];*/ STATIC voidxfs_defer_intake_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) {struct xfs_defer_ops *dop = tp->t_dfops;struct list_head *li;
fs/xfs/libxfs/xfs_defer.c xfs_defer_intake_work( · line 203
Quoted 5 lines
fs/xfs/libxfs/xfs_defer.c +1
-1@@ -197,13 +200,14 @@ xfs_defer_intake_work( dfp->dfp_type->log_item (tp, dfp->dfp_intent, li); } -list_splice_tail_init (&dop->dop_intake, &dop->dop_pending); +list_splice_tail_init (&dop->dop_intake, dop_pending);
It almost seems simpler to just move the list_splice_tail_init to the (only) caller.
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_roll( · line 307
Quoted 12 lines
fs/xfs/libxfs/xfs_defer.c +3
-2@@ -292,9 +299,10 @@ xfs_defer_trans_roll(/* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) { -return !list_empty (&tp->t_dfops->dop_pending) || +return !list_empty (dop_pending) || !list_empty (&tp->t_dfops->dop_intake); }
I'd just opencode this in the only caller that is left.
Re: [PATCH 12/15] xfs: replace xfs_defer_ops ->dop_pending with on-stack list
Quoted 32 lines · Christoph Hellwig
Quoted 31 lines · Brian Foster
The
xfs_defer_ops->dop_pending list is used to track active deferred operations once intents are logged. These items must be aborted in the event of an error. The list is populated as intents are logged and items are removed as they complete (or are aborted).Now that
xfs_defer_finish()cancels on error, there is no need to ever access ->dop_pending outside ofxfs_defer_finish(). The list is only ever populated afterxfs_defer_finish()begins and is either completed or cancelled before it returns.Remove ->dop_pending from
xfs_defer_opsand replace it with a local list in thexfs_defer_finish()path. Pass the local list to the various helpers now that it is not accessible via dfops. Note that we have to check for NULL in the abort case as the final tx roll occurs outside of the scope of the new local list (once the dfops has completed and thus drained the list).Signed-off-by Brian Foster <[email protected]>--- fs/xfs/libxfs/xfs_defer.c | 80 ++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_defer.h | 3 +- fs/xfs/xfs_trace.h | 1 - fs/xfs/xfs_trans.h | 1 - 4 files changed, 43 insertions(+), 42 deletions(-)fs/xfs/libxfs/xfs_defer.c +0
-0@@ -174,6 +174,8 @@
Quoted 7 lines
fs/xfs/libxfs/xfs_defer.c line 177
Quoted 3 lines
fs/xfs/libxfs/xfs_defer.c +1
-0static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX ]; +static void __xfs_defer_cancel (struct list_head *);Can you just move
__xfs_defer_cancelup to here to avoid the forward declaration?
I think so, I'll give it a try.
Quoted 18 lines
Quoted 18 lines
fs/xfs/libxfs/xfs_defer.c +3
-1+/* * For each pending item in the intake list, log its intent item and the * associated extents, then add the entire intake list to the end of @@ -181,7 +183,8 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX];*/ STATIC voidxfs_defer_intake_work ( -struct xfs_trans *tp) +struct xfs_trans *tp, +struct list_head *dop_pending) {struct xfs_defer_ops *dop = tp->t_dfops;struct list_head *li;@@ -197,13 +200,14 @@ xfs_defer_intake_work( dfp->dfp_type->log_item (tp, dfp->dfp_intent, li); }
Quoted 6 lines
fs/xfs/libxfs/xfs_defer.c xfs_defer_intake_work( · line 203
Quoted 2 lines
fs/xfs/libxfs/xfs_defer.c +1
-1-list_splice_tail_init (&dop->dop_intake, &dop->dop_pending); +list_splice_tail_init (&dop->dop_intake, dop_pending);It almost seems simpler to just move the
list_splice_tail_initto the (only) caller.
Hm, yeah. I guess that changes the semantics of the function a bit. I could rename it (and the tracepoint) to something like xfs_defer_create_intents(), drop the dop_pending param and lift the splice into the caller if nobody objects..?
Quoted 6 lines
Quoted 6 lines
fs/xfs/libxfs/xfs_defer.c +1
-1@@ -292,9 +299,10 @@ xfs_defer_trans_roll(/* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work( -struct xfs_trans *tp) + struct xfs_trans *tp,
Quoted 8 lines
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_roll( · line 307
Quoted 6 lines
fs/xfs/libxfs/xfs_defer.c +2
-1+ struct list_head *dop_pending) { -return !list_empty (&tp->t_dfops->dop_pending) || +return !list_empty (dop_pending) || !list_empty (&tp->t_dfops->dop_intake); }I'd just opencode this in the only caller that is left.
Yep, thanks.
Brian
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 13/15 xfs: pass transaction to xfs_defer_add()
In reply to Brian FosterThe majority of remaining references to struct xfs_defer_ops in XFS are associated with xfs_defer_add(). At this point, there are no more external xfs_defer_ops users left. All instances of xfs_defer_ops are embedded in the transaction, which means we can safely pass the transaction down to the dfops add interface.
Update xfs_defer_add() to receive the transaction as a parameter. Various subsystems implement wrappers to allocate and construct the context specific data structures for the associated deferred operation type. Update these to also carry the transaction down as needed and clean up unused dfops parameters along the way.
This removes most of the remaining references to struct xfs_defer_ops throughout the code and facilitates removal of the structure.
--- fs/xfs/libxfs/xfs_alloc.c | 9 ++-- fs/xfs/libxfs/xfs_bmap.c | 75 +++++++++++++++------------------ fs/xfs/libxfs/xfs_bmap.h | 19 ++++----- fs/xfs/libxfs/xfs_bmap_btree.c | 2 +- fs/xfs/libxfs/xfs_defer.c | 3 +- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 25 +++++------ fs/xfs/libxfs/xfs_refcount.c | 76 ++++++++++++++-------------------- fs/xfs/libxfs/xfs_refcount.h | 18 ++++---- fs/xfs/libxfs/xfs_rmap.c | 53 ++++++++++++------------ fs/xfs/libxfs/xfs_rmap.h | 22 ++++------ fs/xfs/xfs_bmap_item.c | 3 +- fs/xfs/xfs_bmap_util.c | 13 ++---- fs/xfs/xfs_refcount_item.c | 14 ++----- fs/xfs/xfs_reflink.c | 21 ++++------ 15 files changed, 156 insertions(+), 199 deletions(-)
fs/xfs/libxfs/xfs_alloc.c +4 -5
@@ -2198,12 +2198,12 @@ xfs_agfl_reset(*/ STATIC voidxfs_defer_agfl_block ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_agnumber_t agno,xfs_fsblock_t agbno,struct xfs_owner_info *oinfo) { +struct xfs_mount *mp = tp->t_mountp;struct xfs_extent_free_item *new;/* new element */ ASSERT (xfs_bmap_free_item_zone !=NULL );
@@ -2216,7 +2216,7 @@ xfs_defer_agfl_block(trace_xfs_agfl_free_defer (mp, agno,0 , agbno,1 ); -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_AGFL_FREE , &new->xefi_list); +xfs_defer_add (tp,XFS_DEFER_OPS_TYPE_AGFL_FREE , &new->xefi_list); }/*
@@ -2325,8 +2325,7 @@ xfs_alloc_fix_freelist(/* defer agfl frees if dfops is provided */ if (tp->t_dfops) { -xfs_defer_agfl_block (mp, tp->t_dfops, args->agno, - bno, &targs.oinfo); +xfs_defer_agfl_block (tp, args->agno, bno, &targs.oinfo); }else { error =xfs_free_agfl_block (tp, args->agno, bno, agbp, &targs.oinfo);
fs/xfs/libxfs/xfs_bmap.c +33 -42
247 lines not on this page · raw message
fs/xfs/libxfs/xfs_bmap.h +9 -10
@@ -184,9 +184,9 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,void xfs_trim_extent_eof (struct xfs_bmbt_irec *,struct xfs_inode *);int xfs_bmap_add_attrfork (struct xfs_inode *ip,int size,int rsvd);void xfs_bmap_local_to_extents_empty (struct xfs_inode *ip,int whichfork); -void __xfs_bmap_add_free (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -xfs_fsblock_t bno,xfs_filblks_t len, -struct xfs_owner_info *oinfo,bool skip_discard); +void __xfs_bmap_add_free (struct xfs_trans *tp,xfs_fsblock_t bno, +xfs_filblks_t len,struct xfs_owner_info *oinfo, +bool skip_discard);void xfs_bmap_compute_maxlevels (struct xfs_mount *mp,int whichfork);int xfs_bmap_first_unused (struct xfs_trans *tp,struct xfs_inode *ip,xfs_extlen_t len,xfs_fileoff_t *unused,int whichfork);
@@ -230,13 +230,12 @@ int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork,static inline void xfs_bmap_add_free ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_fsblock_t bno,xfs_filblks_t len,struct xfs_owner_info *oinfo) { -__xfs_bmap_add_free (mp, dfops, bno, len, oinfo, false); +__xfs_bmap_add_free (tp, bno, len, oinfo, false); }enum xfs_bmap_intent_type {
@@ -256,10 +255,10 @@ int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_inode *ip, enum xfs_bmap_intent_type type, int whichfork, xfs_fileoff_t startoff, xfs_fsblock_t startblock, xfs_filblks_t *blockcount, xfs_exntst_t state); -int xfs_bmap_map_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,struct xfs_bmbt_irec *imap); -int xfs_bmap_unmap_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,struct xfs_bmbt_irec *imap); +int xfs_bmap_map_extent (struct xfs_trans *tp,struct xfs_inode *ip, +struct xfs_bmbt_irec *imap); +int xfs_bmap_unmap_extent (struct xfs_trans *tp,struct xfs_inode *ip, +struct xfs_bmbt_irec *imap);static inline int xfs_bmap_fork_to_state (int whichfork) {
fs/xfs/libxfs/xfs_bmap_btree.c +1 -1
@@ -289,7 +289,7 @@ xfs_bmbt_free_block(struct xfs_owner_info oinfo;xfs_rmap_ino_bmbt_owner (&oinfo, ip->i_ino, cur->bc_private.b.whichfork); -xfs_bmap_add_free (mp, cur->bc_tp->t_dfops, fsbno,1 , &oinfo); +xfs_bmap_add_free (cur->bc_tp, fsbno,1 , &oinfo); ip->i_d.di_nblocks--;xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE );
fs/xfs/libxfs/xfs_defer.c +2 -1
@@ -493,10 +493,11 @@ xfs_defer_cancel(/* Add an item for later deferred processing. */ void xfs_defer_add ( -struct xfs_defer_ops *dop, +struct xfs_trans *tp,enum xfs_defer_ops_type type,struct list_head *li) { +struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp =NULL ;/*
fs/xfs/libxfs/xfs_defer.h +1 -1
@@ -35,7 +35,7 @@ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_MAX, }; -void xfs_defer_add (struct xfs_defer_ops *dop,enum xfs_defer_ops_type type, +void xfs_defer_add (struct xfs_trans *tp,enum xfs_defer_ops_type type,struct list_head *h);int xfs_defer_finish_noroll (struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);
fs/xfs/libxfs/xfs_ialloc.c +13 -12
@@ -1838,23 +1838,24 @@ xfs_dialloc(*/ STATIC voidxfs_difree_inode_chunk ( -struct xfs_mount *mp, +struct xfs_trans *tp,xfs_agnumber_t agno, -struct xfs_inobt_rec_incore *rec, -struct xfs_defer_ops *dfops) +struct xfs_inobt_rec_incore *rec) { -xfs_agblock_t sagbno =XFS_AGINO_TO_AGBNO (mp, rec->ir_startino); -int startidx, endidx; -int nextbit; -xfs_agblock_t agbno; -int contigblk; -struct xfs_owner_info oinfo; +struct xfs_mount *mp = tp->t_mountp; +xfs_agblock_t sagbno =XFS_AGINO_TO_AGBNO (mp, + rec->ir_startino); +int startidx, endidx; +int nextbit; +xfs_agblock_t agbno; +int contigblk; +struct xfs_owner_info oinfo;DECLARE_BITMAP (holemask,XFS_INOBT_HOLEMASK_BITS );xfs_rmap_ag_owner (&oinfo,XFS_RMAP_OWN_INODES );if (!xfs_inobt_issparse (rec->ir_holemask)) {/* not sparse, calculate extent info directly */ -xfs_bmap_add_free (mp, dfops,XFS_AGB_TO_FSB (mp, agno, sagbno), +xfs_bmap_add_free (tp,XFS_AGB_TO_FSB (mp, agno, sagbno), mp->m_ialloc_blks, &oinfo);return ; }
@@ -1898,7 +1899,7 @@ xfs_difree_inode_chunk(ASSERT (agbno % mp->m_sb.sb_spino_align ==0 );ASSERT (contigblk % mp->m_sb.sb_spino_align ==0 ); -xfs_bmap_add_free (mp, dfops,XFS_AGB_TO_FSB (mp, agno, agbno), +xfs_bmap_add_free (tp,XFS_AGB_TO_FSB (mp, agno, agbno), contigblk, &oinfo);/* reset range to current bit and carry on... */
@@ -2002,7 +2003,7 @@ xfs_difree_inobt( goto error0; } -xfs_difree_inode_chunk (mp, agno, &rec, tp->t_dfops); +xfs_difree_inode_chunk (tp, agno, &rec); }else { xic->deleted = false;
fs/xfs/libxfs/xfs_refcount.c +32 -44
234 lines not on this page · raw message
fs/xfs/libxfs/xfs_refcount.h +8 -10
@@ -29,10 +29,10 @@ struct xfs_refcount_intent {xfs_extlen_t ri_blockcount; }; -extern int xfs_refcount_increase_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,struct xfs_bmbt_irec *irec); -extern int xfs_refcount_decrease_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,struct xfs_bmbt_irec *irec); +extern int xfs_refcount_increase_extent (struct xfs_trans *tp, +struct xfs_bmbt_irec *irec); +extern int xfs_refcount_decrease_extent (struct xfs_trans *tp, +struct xfs_bmbt_irec *irec);extern void xfs_refcount_finish_one_cleanup (struct xfs_trans *tp,struct xfs_btree_cur *rcur,int error);
@@ -45,12 +45,10 @@ extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_end_of_shared); -extern int xfs_refcount_alloc_cow_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,xfs_fsblock_t fsb, -xfs_extlen_t len); -extern int xfs_refcount_free_cow_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,xfs_fsblock_t fsb, -xfs_extlen_t len); +extern int xfs_refcount_alloc_cow_extent (struct xfs_trans *tp, +xfs_fsblock_t fsb,xfs_extlen_t len); +extern int xfs_refcount_free_cow_extent (struct xfs_trans *tp, +xfs_fsblock_t fsb,xfs_extlen_t len);extern int xfs_refcount_recover_cow_leftovers (struct xfs_mount *mp,xfs_agnumber_t agno);
fs/xfs/libxfs/xfs_rmap.c +26 -27
142 lines not on this page · raw message
fs/xfs/libxfs/xfs_rmap.h +9 -13
@@ -185,21 +185,17 @@ struct xfs_rmap_intent { };/* functions for updating the rmapbt based on bmbt map/unmap operations */ -int xfs_rmap_map_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, +int xfs_rmap_map_extent (struct xfs_trans *tp,struct xfs_inode *ip, +int whichfork,struct xfs_bmbt_irec *imap); +int xfs_rmap_unmap_extent (struct xfs_trans *tp,struct xfs_inode *ip, +int whichfork,struct xfs_bmbt_irec *imap); +int xfs_rmap_convert_extent (struct xfs_mount *mp,struct xfs_trans *tp,struct xfs_inode *ip,int whichfork,struct xfs_bmbt_irec *imap); -int xfs_rmap_unmap_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,int whichfork, -struct xfs_bmbt_irec *imap); -int xfs_rmap_convert_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,int whichfork, -struct xfs_bmbt_irec *imap); -int xfs_rmap_alloc_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -xfs_agnumber_t agno,xfs_agblock_t bno,xfs_extlen_t len, -uint64_t owner); -int xfs_rmap_free_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -xfs_agnumber_t agno,xfs_agblock_t bno,xfs_extlen_t len, -uint64_t owner); +int xfs_rmap_alloc_extent (struct xfs_trans *tp,xfs_agnumber_t agno, +xfs_agblock_t bno,xfs_extlen_t len,uint64_t owner); +int xfs_rmap_free_extent (struct xfs_trans *tp,xfs_agnumber_t agno, +xfs_agblock_t bno,xfs_extlen_t len,uint64_t owner);void xfs_rmap_finish_one_cleanup (struct xfs_trans *tp,struct xfs_btree_cur *rcur,int error);
fs/xfs/xfs_bmap_item.c +1 -2
@@ -486,8 +486,7 @@ xfs_bui_recover( irec.br_blockcount = count; irec.br_startoff = bmap->me_startoff; irec.br_state = state; - error =xfs_bmap_unmap_extent (tp->t_mountp, tp->t_dfops, ip, - &irec); + error =xfs_bmap_unmap_extent (tp, ip, &irec);if (error) goto err_inode; }
fs/xfs/xfs_bmap_util.c +4 -9
@@ -1534,7 +1534,6 @@ xfs_swap_extent_rmap( struct xfs_inode *tip) {struct xfs_trans *tp = *tpp; -struct xfs_mount *mp = tp->t_mountp;struct xfs_bmbt_irec irec;struct xfs_bmbt_irec uirec;struct xfs_bmbt_irec tirec;
@@ -1598,26 +1597,22 @@ xfs_swap_extent_rmap(trace_xfs_swap_extent_rmap_remap_piece (tip, &uirec);/* Remove the mapping from the donor file. */ - error =xfs_bmap_unmap_extent (mp, tp->t_dfops, tip, - &uirec); + error =xfs_bmap_unmap_extent (tp, tip, &uirec);if (error) goto out_defer;/* Remove the mapping from the source file. */ - error =xfs_bmap_unmap_extent (mp, tp->t_dfops, ip, - &irec); + error =xfs_bmap_unmap_extent (tp, ip, &irec);if (error) goto out_defer;/* Map the donor file's blocks into the source file. */ - error =xfs_bmap_map_extent (mp, tp->t_dfops, ip, - &uirec); + error =xfs_bmap_map_extent (tp, ip, &uirec);if (error) goto out_defer;/* Map the source file's blocks into the donor file. */ - error =xfs_bmap_map_extent (mp, tp->t_dfops, tip, - &irec); + error =xfs_bmap_map_extent (tp, tip, &irec);if (error) goto out_defer;
fs/xfs/xfs_refcount_item.c +4 -10
@@ -490,24 +490,18 @@ xfs_cui_recover( irec.br_blockcount = new_len;switch (type) {case XFS_REFCOUNT_INCREASE : - error =xfs_refcount_increase_extent ( - tp->t_mountp, tp->t_dfops, - &irec); + error =xfs_refcount_increase_extent (tp, &irec);break ;case XFS_REFCOUNT_DECREASE : - error =xfs_refcount_decrease_extent ( - tp->t_mountp, tp->t_dfops, - &irec); + error =xfs_refcount_decrease_extent (tp, &irec);break ;case XFS_REFCOUNT_ALLOC_COW : - error =xfs_refcount_alloc_cow_extent ( - tp->t_mountp, tp->t_dfops, + error =xfs_refcount_alloc_cow_extent (tp, irec.br_startblock, irec.br_blockcount);break ;case XFS_REFCOUNT_FREE_COW : - error =xfs_refcount_free_cow_extent ( - tp->t_mountp, tp->t_dfops, + error =xfs_refcount_free_cow_extent (tp, irec.br_startblock, irec.br_blockcount);break ;
fs/xfs/xfs_reflink.c +9 -12
@@ -506,15 +506,13 @@ xfs_reflink_cancel_cow_blocks(ASSERT ((*tpp)->t_firstblock ==NULLFSBLOCK );/* Free the CoW orphan record. */ - error =xfs_refcount_free_cow_extent (ip->i_mount, - (*tpp)->t_dfops, del.br_startblock, - del.br_blockcount); + error =xfs_refcount_free_cow_extent (*tpp, + del.br_startblock, del.br_blockcount);if (error)break ; -xfs_bmap_add_free (ip->i_mount, (*tpp)->t_dfops, - del.br_startblock, del.br_blockcount, -NULL ); +xfs_bmap_add_free (*tpp, del.br_startblock, + del.br_blockcount,NULL );/* Roll the transaction */ error =xfs_defer_finish (tpp);
@@ -694,14 +692,13 @@ xfs_reflink_end_cow(trace_xfs_reflink_cow_remap (ip, &del);/* Free the CoW orphan record. */ - error =xfs_refcount_free_cow_extent (tp->t_mountp, tp->t_dfops, - del.br_startblock, del.br_blockcount); + error =xfs_refcount_free_cow_extent (tp, del.br_startblock, + del.br_blockcount);if (error) goto out_cancel;/* Map the new blocks into the data fork. */ - error =xfs_bmap_map_extent (tp->t_mountp, tp->t_dfops, ip, - &del); + error =xfs_bmap_map_extent (tp, ip, &del);if (error) goto out_cancel;
@@ -1046,12 +1043,12 @@ xfs_reflink_remap_extent( uirec.br_blockcount, uirec.br_startblock);/* Update the refcount tree */ - error =xfs_refcount_increase_extent (mp, tp->t_dfops, &uirec); + error =xfs_refcount_increase_extent (tp, &uirec);if (error) goto out_cancel;/* Map the new blocks into the data fork. */ - error =xfs_bmap_map_extent (mp, tp->t_dfops, ip, &uirec); + error =xfs_bmap_map_extent (tp, ip, &uirec);if (error) goto out_cancel;
Signature · 1 line
2.17.1
Re: [PATCH 13/15] xfs: pass transaction to xfs_defer_add()
Quoted 12 lines · Brian Foster
The majority of remaining references to struct
xfs_defer_opsin XFS are associated withxfs_defer_add(). At this point, there are no more externalxfs_defer_opsusers left. All instances ofxfs_defer_opsare embedded in the transaction, which means we can safely pass the transaction down to the dfops add interface.Update
xfs_defer_add()to receive the transaction as a parameter. Various subsystems implement wrappers to allocate and construct the context specific data structures for the associated deferred operation type. Update these to also carry the transaction down as needed and clean up unused dfops parameters along the way.
Quoted 5 lines
This removes most of the remaining references to struct
xfs_defer_opsthroughout the code and facilitates removal of the structure.Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 1,107 lines
--- fs/xfs/libxfs/xfs_alloc.c | 9 ++-- fs/xfs/libxfs/xfs_bmap.c | 75 +++++++++++++++------------------ fs/xfs/libxfs/xfs_bmap.h | 19 ++++----- fs/xfs/libxfs/xfs_bmap_btree.c | 2 +- fs/xfs/libxfs/xfs_defer.c | 3 +- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 25 +++++------ fs/xfs/libxfs/xfs_refcount.c | 76 ++++++++++++++-------------------- fs/xfs/libxfs/xfs_refcount.h | 18 ++++---- fs/xfs/libxfs/xfs_rmap.c | 53 ++++++++++++------------ fs/xfs/libxfs/xfs_rmap.h | 22 ++++------ fs/xfs/xfs_bmap_item.c | 3 +- fs/xfs/xfs_bmap_util.c | 13 ++---- fs/xfs/xfs_refcount_item.c | 14 ++----- fs/xfs/xfs_reflink.c | 21 ++++------ 15 files changed, 156 insertions(+), 199 deletions(-)fs/xfs/libxfs/xfs_alloc.c +4
-5@@ -2198,12 +2198,12 @@ xfs_agfl_reset(*/ STATIC voidxfs_defer_agfl_block ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_agnumber_t agno,xfs_fsblock_t agbno,struct xfs_owner_info *oinfo) { +struct xfs_mount *mp = tp->t_mountp;struct xfs_extent_free_item *new;/* new element */ ASSERT (xfs_bmap_free_item_zone !=NULL );@@ -2216,7 +2216,7 @@ xfs_defer_agfl_block(trace_xfs_agfl_free_defer (mp, agno,0 , agbno,1 ); -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_AGFL_FREE , &new->xefi_list); +xfs_defer_add (tp,XFS_DEFER_OPS_TYPE_AGFL_FREE , &new->xefi_list); }/* @@ -2325,8 +2325,7 @@ xfs_alloc_fix_freelist(/* defer agfl frees if dfops is provided */ if (tp->t_dfops) { -xfs_defer_agfl_block (mp, tp->t_dfops, args->agno, - bno, &targs.oinfo); +xfs_defer_agfl_block (tp, args->agno, bno, &targs.oinfo); }else { error =xfs_free_agfl_block (tp, args->agno, bno, agbp, &targs.oinfo);fs/xfs/libxfs/xfs_bmap.c +33
-42@@ -533,13 +533,13 @@ xfs_bmap_validate_ret(*/ void __xfs_bmap_add_free ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_fsblock_t bno,xfs_filblks_t len,struct xfs_owner_info *oinfo,bool skip_discard) { +struct xfs_mount *mp = tp->t_mountp;struct xfs_extent_free_item *new;/* new element */ #ifdef DEBUG xfs_agnumber_t agno;@@ -568,7 +568,7 @@ __xfs_bmap_add_free( new->xefi_skip_discard = skip_discard;trace_xfs_bmap_free_defer (mp,XFS_FSB_TO_AGNO (mp, bno),0 ,XFS_FSB_TO_AGBNO (mp, bno), len); -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_FREE , &new->xefi_list); +xfs_defer_add (tp,XFS_DEFER_OPS_TYPE_FREE , &new->xefi_list); }/* @@ -624,7 +624,7 @@ xfs_bmap_btree_to_extents(if ((error =xfs_btree_check_block (cur, cblock,0 , cbp)))return error;xfs_rmap_ino_bmbt_owner (&oinfo, ip->i_ino, whichfork); -xfs_bmap_add_free (mp, cur->bc_tp->t_dfops, cbno,1 , &oinfo); +xfs_bmap_add_free (cur->bc_tp, cbno,1 , &oinfo); ip->i_d.di_nblocks--;xfs_trans_mod_dquot_byino (tp, ip,XFS_TRANS_DQ_BCOUNT ,-1L );xfs_trans_binval (tp, cbp);@@ -1961,8 +1961,7 @@ xfs_bmap_add_extent_delay_real(/* add reverse mapping unless caller opted out */ if (!(bma->flags &XFS_BMAPI_NORMAP )) { - error =xfs_rmap_map_extent (mp, bma->tp->t_dfops, bma->ip, - whichfork, new); + error =xfs_rmap_map_extent (bma->tp, bma->ip, whichfork, new);if (error) goto done; }@@ -2026,7 +2025,6 @@ xfs_bmap_add_extent_unwritten_real(int state =xfs_bmap_fork_to_state (whichfork);struct xfs_mount *mp = ip->i_mount;struct xfs_bmbt_irec old; -struct xfs_defer_ops *dfops = tp ? tp->t_dfops :NULL ; *logflagsp =0 ;@@ -2445,7 +2443,7 @@ xfs_bmap_add_extent_unwritten_real( }/* update reverse mappings */ - error =xfs_rmap_convert_extent (mp, dfops, ip, whichfork, new); + error =xfs_rmap_convert_extent (mp, tp, ip, whichfork, new);if (error) goto done;@@ -2806,8 +2804,7 @@ xfs_bmap_add_extent_hole_real(/* add reverse mapping unless caller opted out */ if (!(flags &XFS_BMAPI_NORMAP )) { - error =xfs_rmap_map_extent (mp, tp->t_dfops, ip, whichfork, - new); + error =xfs_rmap_map_extent (tp, ip, whichfork, new);if (error) goto done; }@@ -4364,9 +4361,8 @@ xfs_bmapi_write(* the refcount btree for orphan recovery. */ if (whichfork ==XFS_COW_FORK ) { - error =xfs_refcount_alloc_cow_extent (mp, - tp->t_dfops, bma.blkno, - bma.length); + error =xfs_refcount_alloc_cow_extent (tp, + bma.blkno, bma.length);if (error) goto error0; }@@ -4852,7 +4848,6 @@ xfs_bmap_del_extent_real(uint qfield;/* quota field to update */ int state =xfs_bmap_fork_to_state (whichfork);struct xfs_bmbt_irec old; -struct xfs_defer_ops *dfops = tp ? tp->t_dfops :NULL ; mp = ip->i_mount;XFS_STATS_INC (mp, xs_del_exlist);@@ -5036,7 +5031,7 @@ xfs_bmap_del_extent_real( }/* remove reverse mapping */ - error =xfs_rmap_unmap_extent (mp, dfops, ip, whichfork, del); + error =xfs_rmap_unmap_extent (tp, ip, whichfork, del);if (error) goto done;@@ -5045,11 +5040,11 @@ xfs_bmap_del_extent_real(*/ if (do_fx && !(bflags &XFS_BMAPI_REMAP )) {if (xfs_is_reflink_inode (ip) && whichfork ==XFS_DATA_FORK ) { - error =xfs_refcount_decrease_extent (mp, dfops, del); + error =xfs_refcount_decrease_extent (tp, del);if (error) goto done; }else { -__xfs_bmap_add_free (mp, dfops, del->br_startblock, +__xfs_bmap_add_free (tp, del->br_startblock, del->br_blockcount,NULL , (bflags &XFS_BMAPI_NODISCARD ) || del->br_state ==XFS_EXT_UNWRITTEN );@@ -5489,6 +5484,7 @@ xfs_bmse_can_merge(*/ STATIC int xfs_bmse_merge( + struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, xfs_fileoff_t shift, /* shift fsb */@@ -5496,8 +5492,7 @@ xfs_bmse_merge(struct xfs_bmbt_irec *got,/* extent to shift */ struct xfs_bmbt_irec *left, /* preceding extent */ struct xfs_btree_cur *cur, - int *logflags, /* output */ - struct xfs_defer_ops *dfops) + int *logflags) /* output */ { struct xfs_bmbt_irec new;xfs_filblks_t blockcount;@@ -5553,23 +5548,23 @@ xfs_bmse_merge( &new);/* update reverse mapping. rmap functions merge the rmaps for us */ - error =xfs_rmap_unmap_extent (mp, dfops, ip, whichfork, got); + error =xfs_rmap_unmap_extent (tp, ip, whichfork, got);if (error)return error;memcpy (&new, got,sizeof (new)); new.br_startoff = left->br_startoff + left->br_blockcount; -return xfs_rmap_map_extent (mp, dfops, ip, whichfork, &new); +return xfs_rmap_map_extent (tp, ip, whichfork, &new); }static int xfs_bmap_shift_update_extent ( +struct xfs_trans *tp,struct xfs_inode *ip,int whichfork,struct xfs_iext_cursor *icur,struct xfs_bmbt_irec *got,struct xfs_btree_cur *cur,int *logflags, -struct xfs_defer_ops *dfops,xfs_fileoff_t startoff) {struct xfs_mount *mp = ip->i_mount;@@ -5597,10 +5592,10 @@ xfs_bmap_shift_update_extent( got);/* update reverse mapping */ - error =xfs_rmap_unmap_extent (mp, dfops, ip, whichfork, &prev); + error =xfs_rmap_unmap_extent (tp, ip, whichfork, &prev);if (error)return error; -return xfs_rmap_map_extent (mp, dfops, ip, whichfork, got); +return xfs_rmap_map_extent (tp, ip, whichfork, got); }int @@ -5660,9 +5655,9 @@ xfs_bmap_collapse_extents( }if (xfs_bmse_can_merge (&prev, &got, offset_shift_fsb)) { - error =xfs_bmse_merge (ip, whichfork, offset_shift_fsb, - &icur, &got, &prev, cur, &logflags, - tp->t_dfops); + error =xfs_bmse_merge (tp, ip, whichfork, + offset_shift_fsb, &icur, &got, &prev, + cur, &logflags);if (error) goto del_cursor; goto done;@@ -5674,8 +5669,8 @@ xfs_bmap_collapse_extents( } } - error =xfs_bmap_shift_update_extent (ip, whichfork, &icur, &got, cur, - &logflags, tp->t_dfops, new_startoff); + error =xfs_bmap_shift_update_extent (tp, ip, whichfork, &icur, &got, + cur, &logflags, new_startoff);if (error) goto del_cursor;@@ -5801,8 +5796,8 @@ xfs_bmap_insert_extents(WARN_ON_ONCE (1 ); } - error =xfs_bmap_shift_update_extent (ip, whichfork, &icur, &got, cur, - &logflags, tp->t_dfops, new_startoff); + error =xfs_bmap_shift_update_extent (tp, ip, whichfork, &icur, &got, + cur, &logflags, new_startoff);if (error) goto del_cursor;@@ -5979,13 +5974,13 @@ xfs_bmap_is_update_needed(/* Record a bmap intent. */ static int __xfs_bmap_add ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,enum xfs_bmap_intent_type type,struct xfs_inode *ip,int whichfork,struct xfs_bmbt_irec *bmap) { +struct xfs_mount *mp = tp->t_mountp;struct xfs_bmap_intent *bi; trace_xfs_bmap_defer(mp,@@ -6004,38 +5999,34 @@ __xfs_bmap_add( bi->bi_whichfork = whichfork; bi->bi_bmap = *bmap; -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_BMAP , &bi->bi_list); +xfs_defer_add (tp,XFS_DEFER_OPS_TYPE_BMAP , &bi->bi_list);return 0 ; }/* Map an extent into a file. */ int xfs_bmap_map_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_inode *ip,struct xfs_bmbt_irec *PREV ) {if (!xfs_bmap_is_update_needed (PREV ))return 0 ; -return __xfs_bmap_add (mp, dfops,XFS_BMAP_MAP , ip, -XFS_DATA_FORK ,PREV ); +return __xfs_bmap_add (tp,XFS_BMAP_MAP , ip,XFS_DATA_FORK ,PREV ); }/* Unmap an extent out of a file. */ int xfs_bmap_unmap_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_inode *ip,struct xfs_bmbt_irec *PREV ) {if (!xfs_bmap_is_update_needed (PREV ))return 0 ; -return __xfs_bmap_add (mp, dfops,XFS_BMAP_UNMAP , ip, -XFS_DATA_FORK ,PREV ); +return __xfs_bmap_add (tp,XFS_BMAP_UNMAP , ip,XFS_DATA_FORK ,PREV ); }/* fs/xfs/libxfs/xfs_bmap.h +9
-10@@ -184,9 +184,9 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,void xfs_trim_extent_eof (struct xfs_bmbt_irec *,struct xfs_inode *);int xfs_bmap_add_attrfork (struct xfs_inode *ip,int size,int rsvd);void xfs_bmap_local_to_extents_empty (struct xfs_inode *ip,int whichfork); -void __xfs_bmap_add_free (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -xfs_fsblock_t bno,xfs_filblks_t len, -struct xfs_owner_info *oinfo,bool skip_discard); +void __xfs_bmap_add_free (struct xfs_trans *tp,xfs_fsblock_t bno, +xfs_filblks_t len,struct xfs_owner_info *oinfo, +bool skip_discard);void xfs_bmap_compute_maxlevels (struct xfs_mount *mp,int whichfork);int xfs_bmap_first_unused (struct xfs_trans *tp,struct xfs_inode *ip,xfs_extlen_t len,xfs_fileoff_t *unused,int whichfork);@@ -230,13 +230,12 @@ int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork,static inline void xfs_bmap_add_free ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_fsblock_t bno,xfs_filblks_t len,struct xfs_owner_info *oinfo) { -__xfs_bmap_add_free (mp, dfops, bno, len, oinfo, false); +__xfs_bmap_add_free (tp, bno, len, oinfo, false); }enum xfs_bmap_intent_type {@@ -256,10 +255,10 @@ int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_inode *ip, enum xfs_bmap_intent_type type, int whichfork, xfs_fileoff_t startoff, xfs_fsblock_t startblock, xfs_filblks_t *blockcount, xfs_exntst_t state); -int xfs_bmap_map_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,struct xfs_bmbt_irec *imap); -int xfs_bmap_unmap_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,struct xfs_bmbt_irec *imap); +int xfs_bmap_map_extent (struct xfs_trans *tp,struct xfs_inode *ip, +struct xfs_bmbt_irec *imap); +int xfs_bmap_unmap_extent (struct xfs_trans *tp,struct xfs_inode *ip, +struct xfs_bmbt_irec *imap);static inline int xfs_bmap_fork_to_state (int whichfork) {fs/xfs/libxfs/xfs_bmap_btree.c +1
-1@@ -289,7 +289,7 @@ xfs_bmbt_free_block(struct xfs_owner_info oinfo;xfs_rmap_ino_bmbt_owner (&oinfo, ip->i_ino, cur->bc_private.b.whichfork); -xfs_bmap_add_free (mp, cur->bc_tp->t_dfops, fsbno,1 , &oinfo); +xfs_bmap_add_free (cur->bc_tp, fsbno,1 , &oinfo); ip->i_d.di_nblocks--;xfs_trans_log_inode (tp, ip,XFS_ILOG_CORE );fs/xfs/libxfs/xfs_defer.c +2
-1@@ -493,10 +493,11 @@ xfs_defer_cancel(/* Add an item for later deferred processing. */ void xfs_defer_add ( -struct xfs_defer_ops *dop, +struct xfs_trans *tp,enum xfs_defer_ops_type type,struct list_head *li) { +struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp =NULL ;/* fs/xfs/libxfs/xfs_defer.h +1
-1@@ -35,7 +35,7 @@ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_MAX, }; -void xfs_defer_add (struct xfs_defer_ops *dop,enum xfs_defer_ops_type type, +void xfs_defer_add (struct xfs_trans *tp,enum xfs_defer_ops_type type,struct list_head *h);int xfs_defer_finish_noroll (struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);fs/xfs/libxfs/xfs_ialloc.c +13
-12@@ -1838,23 +1838,24 @@ xfs_dialloc(*/ STATIC voidxfs_difree_inode_chunk ( -struct xfs_mount *mp, +struct xfs_trans *tp,xfs_agnumber_t agno, -struct xfs_inobt_rec_incore *rec, -struct xfs_defer_ops *dfops) +struct xfs_inobt_rec_incore *rec) { -xfs_agblock_t sagbno =XFS_AGINO_TO_AGBNO (mp, rec->ir_startino); -int startidx, endidx; -int nextbit; -xfs_agblock_t agbno; -int contigblk; -struct xfs_owner_info oinfo; +struct xfs_mount *mp = tp->t_mountp; +xfs_agblock_t sagbno =XFS_AGINO_TO_AGBNO (mp, + rec->ir_startino); +int startidx, endidx; +int nextbit; +xfs_agblock_t agbno; +int contigblk; +struct xfs_owner_info oinfo;DECLARE_BITMAP (holemask,XFS_INOBT_HOLEMASK_BITS );xfs_rmap_ag_owner (&oinfo,XFS_RMAP_OWN_INODES );if (!xfs_inobt_issparse (rec->ir_holemask)) {/* not sparse, calculate extent info directly */ -xfs_bmap_add_free (mp, dfops,XFS_AGB_TO_FSB (mp, agno, sagbno), +xfs_bmap_add_free (tp,XFS_AGB_TO_FSB (mp, agno, sagbno), mp->m_ialloc_blks, &oinfo);return ; }@@ -1898,7 +1899,7 @@ xfs_difree_inode_chunk(ASSERT (agbno % mp->m_sb.sb_spino_align ==0 );ASSERT (contigblk % mp->m_sb.sb_spino_align ==0 ); -xfs_bmap_add_free (mp, dfops,XFS_AGB_TO_FSB (mp, agno, agbno), +xfs_bmap_add_free (tp,XFS_AGB_TO_FSB (mp, agno, agbno), contigblk, &oinfo);/* reset range to current bit and carry on... */ @@ -2002,7 +2003,7 @@ xfs_difree_inobt( goto error0; } -xfs_difree_inode_chunk (mp, agno, &rec, tp->t_dfops); +xfs_difree_inode_chunk (tp, agno, &rec); }else { xic->deleted = false;fs/xfs/libxfs/xfs_refcount.c +32
-44@@ -34,11 +34,9 @@ enum xfs_refc_adjust_op { }; STATIC int __xfs_refcount_cow_alloc(struct xfs_btree_cur *rcur, -xfs_agblock_t agbno,xfs_extlen_t aglen, -struct xfs_defer_ops *dfops); +xfs_agblock_t agbno,xfs_extlen_t aglen); STATIC int __xfs_refcount_cow_free(struct xfs_btree_cur *rcur, -xfs_agblock_t agbno,xfs_extlen_t aglen, -struct xfs_defer_ops *dfops); +xfs_agblock_t agbno,xfs_extlen_t aglen);/* * Look up the first record less than or equal to [bno, len] in the btree @@ -870,7 +868,6 @@ xfs_refcount_adjust_extents( xfs_agblock_t *agbno, xfs_extlen_t *aglen, enum xfs_refc_adjust_op adj, - struct xfs_defer_ops *dfops, struct xfs_owner_info *oinfo) { struct xfs_refcount_irec ext, tmp;@@ -925,8 +922,8 @@ xfs_refcount_adjust_extents( fsbno =XFS_AGB_TO_FSB (cur->bc_mp, cur->bc_private.a.agno, tmp.rc_startblock); -xfs_bmap_add_free (cur->bc_mp, dfops, fsbno, - tmp.rc_blockcount, oinfo); +xfs_bmap_add_free (cur->bc_tp, fsbno, + tmp.rc_blockcount, oinfo); } (*agbno) += tmp.rc_blockcount;@@ -968,8 +965,8 @@ xfs_refcount_adjust_extents( fsbno =XFS_AGB_TO_FSB (cur->bc_mp, cur->bc_private.a.agno, ext.rc_startblock); -xfs_bmap_add_free (cur->bc_mp, dfops, fsbno, - ext.rc_blockcount, oinfo); +xfs_bmap_add_free (cur->bc_tp, fsbno, ext.rc_blockcount, + oinfo); } skip:@@ -998,7 +995,6 @@ xfs_refcount_adjust( xfs_agblock_t *new_agbno, xfs_extlen_t *new_aglen, enum xfs_refc_adjust_op adj, - struct xfs_defer_ops *dfops, struct xfs_owner_info *oinfo) { bool shape_changed;@@ -1043,7 +1039,7 @@ xfs_refcount_adjust(/* Now that we've taken care of the ends, adjust the middle extents */ error =xfs_refcount_adjust_extents (cur, new_agbno, new_aglen, - adj, dfops, oinfo); + adj, oinfo);if (error) goto out_error;@@ -1090,7 +1086,6 @@ xfs_refcount_finish_one( struct xfs_btree_cur **pcur) {struct xfs_mount *mp = tp->t_mountp; -struct xfs_defer_ops *dfops = tp->t_dfops;struct xfs_btree_cur *rcur;struct xfs_buf *agbp =NULL ;int error =0 ;@@ -1145,23 +1140,23 @@ xfs_refcount_finish_one(switch (type) {case XFS_REFCOUNT_INCREASE : error =xfs_refcount_adjust (rcur, bno, blockcount, &new_agbno, - new_len,XFS_REFCOUNT_ADJUST_INCREASE , dfops,NULL ); + new_len,XFS_REFCOUNT_ADJUST_INCREASE ,NULL ); *new_fsb =XFS_AGB_TO_FSB (mp, agno, new_agbno);break ;case XFS_REFCOUNT_DECREASE : error =xfs_refcount_adjust (rcur, bno, blockcount, &new_agbno, - new_len,XFS_REFCOUNT_ADJUST_DECREASE , dfops,NULL ); + new_len,XFS_REFCOUNT_ADJUST_DECREASE ,NULL ); *new_fsb =XFS_AGB_TO_FSB (mp, agno, new_agbno);break ;case XFS_REFCOUNT_ALLOC_COW : *new_fsb = startblock + blockcount; *new_len =0 ; - error =__xfs_refcount_cow_alloc (rcur, bno, blockcount, dfops); + error =__xfs_refcount_cow_alloc (rcur, bno, blockcount);break ;case XFS_REFCOUNT_FREE_COW : *new_fsb = startblock + blockcount; *new_len =0 ; - error =__xfs_refcount_cow_free (rcur, bno, blockcount, dfops); + error =__xfs_refcount_cow_free (rcur, bno, blockcount);break ;default :ASSERT (0 );@@ -1183,12 +1178,12 @@ xfs_refcount_finish_one(*/ static int __xfs_refcount_add ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,enum xfs_refcount_intent_type type,xfs_fsblock_t startblock,xfs_extlen_t blockcount) { +struct xfs_mount *mp = tp->t_mountp;struct xfs_refcount_intent *ri; trace_xfs_refcount_defer(mp, XFS_FSB_TO_AGNO(mp, startblock),@@ -1202,7 +1197,7 @@ __xfs_refcount_add( ri->ri_startblock = startblock; ri->ri_blockcount = blockcount; -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_REFCOUNT , &ri->ri_list); +xfs_defer_add (tp,XFS_DEFER_OPS_TYPE_REFCOUNT , &ri->ri_list);return 0 ; }@@ -1211,14 +1206,13 @@ __xfs_refcount_add(*/ int xfs_refcount_increase_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_bmbt_irec *PREV ) { -if (!xfs_sb_version_hasreflink (&mp->m_sb)) +if (!xfs_sb_version_hasreflink (&tp->t_mountp->m_sb))return 0 ; -return __xfs_refcount_add (mp, dfops,XFS_REFCOUNT_INCREASE , +return __xfs_refcount_add (tp,XFS_REFCOUNT_INCREASE ,PREV ->br_startblock,PREV ->br_blockcount); }@@ -1227,14 +1221,13 @@ xfs_refcount_increase_extent(*/ int xfs_refcount_decrease_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_bmbt_irec *PREV ) { -if (!xfs_sb_version_hasreflink (&mp->m_sb)) +if (!xfs_sb_version_hasreflink (&tp->t_mountp->m_sb))return 0 ; -return __xfs_refcount_add (mp, dfops,XFS_REFCOUNT_DECREASE , +return __xfs_refcount_add (tp,XFS_REFCOUNT_DECREASE ,PREV ->br_startblock,PREV ->br_blockcount); }@@ -1522,8 +1515,7 @@ STATIC int__xfs_refcount_cow_alloc ( struct xfs_btree_cur *rcur, xfs_agblock_t agbno, - xfs_extlen_t aglen, - struct xfs_defer_ops *dfops) + xfs_extlen_t aglen) { trace_xfs_refcount_cow_increase(rcur->bc_mp, rcur->bc_private.a.agno, agbno, aglen);@@ -1540,8 +1532,7 @@ STATIC int__xfs_refcount_cow_free ( struct xfs_btree_cur *rcur, xfs_agblock_t agbno, - xfs_extlen_t aglen, - struct xfs_defer_ops *dfops) + xfs_extlen_t aglen) { trace_xfs_refcount_cow_decrease(rcur->bc_mp, rcur->bc_private.a.agno, agbno, aglen);@@ -1554,47 +1545,45 @@ __xfs_refcount_cow_free(/* Record a CoW staging extent in the refcount btree. */ int xfs_refcount_alloc_cow_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_fsblock_t fsb,xfs_extlen_t len) { +struct xfs_mount *mp = tp->t_mountp;int error;if (!xfs_sb_version_hasreflink (&mp->m_sb))return 0 ; - error =__xfs_refcount_add (mp, dfops,XFS_REFCOUNT_ALLOC_COW , - fsb, len); + error =__xfs_refcount_add (tp,XFS_REFCOUNT_ALLOC_COW , fsb, len);if (error)return error;/* Add rmap entry */ -return xfs_rmap_alloc_extent (mp, dfops,XFS_FSB_TO_AGNO (mp, fsb), +return xfs_rmap_alloc_extent (tp,XFS_FSB_TO_AGNO (mp, fsb),XFS_FSB_TO_AGBNO (mp, fsb), len,XFS_RMAP_OWN_COW ); }/* Forget a CoW staging event in the refcount btree. */ int xfs_refcount_free_cow_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,xfs_fsblock_t fsb,xfs_extlen_t len) { +struct xfs_mount *mp = tp->t_mountp;int error;if (!xfs_sb_version_hasreflink (&mp->m_sb))return 0 ;/* Remove rmap entry */ - error =xfs_rmap_free_extent (mp, dfops,XFS_FSB_TO_AGNO (mp, fsb), + error =xfs_rmap_free_extent (tp,XFS_FSB_TO_AGNO (mp, fsb),XFS_FSB_TO_AGBNO (mp, fsb), len,XFS_RMAP_OWN_COW );if (error)return error; -return __xfs_refcount_add (mp, dfops,XFS_REFCOUNT_FREE_COW , - fsb, len); +return __xfs_refcount_add (tp,XFS_REFCOUNT_FREE_COW , fsb, len); }struct xfs_refcount_recovery {@@ -1692,14 +1681,13 @@ xfs_refcount_recover_cow_leftovers(/* Free the orphan record */ agbno = rr->rr_rrec.rc_startblock -XFS_REFC_COW_START ; fsb =XFS_AGB_TO_FSB (mp, agno, agbno); - error =xfs_refcount_free_cow_extent (mp, tp->t_dfops, fsb, + error =xfs_refcount_free_cow_extent (tp, fsb, rr->rr_rrec.rc_blockcount);if (error) goto out_trans;/* Free the block. */ -xfs_bmap_add_free (mp, tp->t_dfops, fsb, - rr->rr_rrec.rc_blockcount,NULL ); +xfs_bmap_add_free (tp, fsb, rr->rr_rrec.rc_blockcount,NULL ); error =xfs_trans_commit (tp);if (error)fs/xfs/libxfs/xfs_refcount.h +8
-10@@ -29,10 +29,10 @@ struct xfs_refcount_intent {xfs_extlen_t ri_blockcount; }; -extern int xfs_refcount_increase_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,struct xfs_bmbt_irec *irec); -extern int xfs_refcount_decrease_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,struct xfs_bmbt_irec *irec); +extern int xfs_refcount_increase_extent (struct xfs_trans *tp, +struct xfs_bmbt_irec *irec); +extern int xfs_refcount_decrease_extent (struct xfs_trans *tp, +struct xfs_bmbt_irec *irec);extern void xfs_refcount_finish_one_cleanup (struct xfs_trans *tp,struct xfs_btree_cur *rcur,int error);@@ -45,12 +45,10 @@ extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_end_of_shared); -extern int xfs_refcount_alloc_cow_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,xfs_fsblock_t fsb, -xfs_extlen_t len); -extern int xfs_refcount_free_cow_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops,xfs_fsblock_t fsb, -xfs_extlen_t len); +extern int xfs_refcount_alloc_cow_extent (struct xfs_trans *tp, +xfs_fsblock_t fsb,xfs_extlen_t len); +extern int xfs_refcount_free_cow_extent (struct xfs_trans *tp, +xfs_fsblock_t fsb,xfs_extlen_t len);extern int xfs_refcount_recover_cow_leftovers (struct xfs_mount *mp,xfs_agnumber_t agno);fs/xfs/libxfs/xfs_rmap.c +26
-27@@ -2277,14 +2277,14 @@ xfs_rmap_update_is_needed(*/ static int __xfs_rmap_add ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,enum xfs_rmap_intent_type type,uint64_t owner,int whichfork,struct xfs_bmbt_irec *bmap) { -struct xfs_rmap_intent *ri; +struct xfs_mount *mp = tp->t_mountp; +struct xfs_rmap_intent *ri; trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock), type,@@ -2301,23 +2301,22 @@ __xfs_rmap_add( ri->ri_whichfork = whichfork; ri->ri_bmap = *bmap; -xfs_defer_add (dfops,XFS_DEFER_OPS_TYPE_RMAP , &ri->ri_list); +xfs_defer_add (tp,XFS_DEFER_OPS_TYPE_RMAP , &ri->ri_list);return 0 ; }/* Map an extent into a file. */ int xfs_rmap_map_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_inode *ip,int whichfork,struct xfs_bmbt_irec *PREV ) { -if (!xfs_rmap_update_is_needed (mp, whichfork)) +if (!xfs_rmap_update_is_needed (tp->t_mountp, whichfork))return 0 ; -return __xfs_rmap_add (mp, dfops,xfs_is_reflink_inode (ip) ? +return __xfs_rmap_add (tp,xfs_is_reflink_inode (ip) ?XFS_RMAP_MAP_SHARED :XFS_RMAP_MAP , ip->i_ino, whichfork,PREV ); }@@ -2325,25 +2324,29 @@ xfs_rmap_map_extent(/* Unmap an extent out of a file. */ int xfs_rmap_unmap_extent ( -struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_inode *ip,int whichfork,struct xfs_bmbt_irec *PREV ) { -if (!xfs_rmap_update_is_needed (mp, whichfork)) +if (!xfs_rmap_update_is_needed (tp->t_mountp, whichfork))return 0 ; -return __xfs_rmap_add (mp, dfops,xfs_is_reflink_inode (ip) ? +return __xfs_rmap_add (tp,xfs_is_reflink_inode (ip) ?XFS_RMAP_UNMAP_SHARED :XFS_RMAP_UNMAP , ip->i_ino, whichfork,PREV ); } -/* Convert a data fork extent from unwritten to real or vice versa. */ +/* +* Convert a data fork extent from unwritten to real or vice versa. +* +* Note that tp can be NULL here as no transaction is used for COW fork +* unwritten conversion. +*/ int xfs_rmap_convert_extent (struct xfs_mount *mp, -struct xfs_defer_ops *dfops, +struct xfs_trans *tp,struct xfs_inode *ip,int whichfork,struct xfs_bmbt_irec *PREV )@@ -2351,7 +2354,7 @@ xfs_rmap_convert_extent(if (!xfs_rmap_update_is_needed (mp, whichfork))return 0 ; -return __xfs_rmap_add (mp, dfops,xfs_is_reflink_inode (ip) ? +return __xfs_rmap_add (tp,xfs_is_reflink_inode (ip) ?XFS_RMAP_CONVERT_SHARED :XFS_RMAP_CONVERT , ip->i_ino, whichfork,PREV ); }@@ -2359,8 +2362,7 @@ xfs_rmap_convert_extent(/* Schedule the creation of an rmap for non-file data. */ int xfs_rmap_alloc_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,@@ -2368,23 +2370,21 @@ xfs_rmap_alloc_extent( {struct xfs_bmbt_irec bmap; -if (!xfs_rmap_update_is_needed (mp,XFS_DATA_FORK )) +if (!xfs_rmap_update_is_needed (tp->t_mountp,XFS_DATA_FORK ))return 0 ; - bmap.br_startblock =XFS_AGB_TO_FSB (mp, agno, bno); + bmap.br_startblock =XFS_AGB_TO_FSB (tp->t_mountp, agno, bno); bmap.br_blockcount = len; bmap.br_startoff =0 ; bmap.br_state =XFS_EXT_NORM ; -return __xfs_rmap_add (mp, dfops,XFS_RMAP_ALLOC , owner, -XFS_DATA_FORK , &bmap); +return __xfs_rmap_add (tp,XFS_RMAP_ALLOC , owner,XFS_DATA_FORK , &bmap); }/* Schedule the deletion of an rmap for non-file data. */ int xfs_rmap_free_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,@@ -2392,16 +2392,15 @@ xfs_rmap_free_extent( {struct xfs_bmbt_irec bmap; -if (!xfs_rmap_update_is_needed (mp,XFS_DATA_FORK )) +if (!xfs_rmap_update_is_needed (tp->t_mountp,XFS_DATA_FORK ))return 0 ; - bmap.br_startblock =XFS_AGB_TO_FSB (mp, agno, bno); + bmap.br_startblock =XFS_AGB_TO_FSB (tp->t_mountp, agno, bno); bmap.br_blockcount = len; bmap.br_startoff =0 ; bmap.br_state =XFS_EXT_NORM ; -return __xfs_rmap_add (mp, dfops,XFS_RMAP_FREE , owner, -XFS_DATA_FORK , &bmap); +return __xfs_rmap_add (tp,XFS_RMAP_FREE , owner,XFS_DATA_FORK , &bmap); }/* Compare rmap records. Returns -1 if a < b, 1 if a > b, and 0 if equal. */ fs/xfs/libxfs/xfs_rmap.h +9
-13@@ -185,21 +185,17 @@ struct xfs_rmap_intent { };/* functions for updating the rmapbt based on bmbt map/unmap operations */ -int xfs_rmap_map_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, +int xfs_rmap_map_extent (struct xfs_trans *tp,struct xfs_inode *ip, +int whichfork,struct xfs_bmbt_irec *imap); +int xfs_rmap_unmap_extent (struct xfs_trans *tp,struct xfs_inode *ip, +int whichfork,struct xfs_bmbt_irec *imap); +int xfs_rmap_convert_extent (struct xfs_mount *mp,struct xfs_trans *tp,struct xfs_inode *ip,int whichfork,struct xfs_bmbt_irec *imap); -int xfs_rmap_unmap_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,int whichfork, -struct xfs_bmbt_irec *imap); -int xfs_rmap_convert_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -struct xfs_inode *ip,int whichfork, -struct xfs_bmbt_irec *imap); -int xfs_rmap_alloc_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -xfs_agnumber_t agno,xfs_agblock_t bno,xfs_extlen_t len, -uint64_t owner); -int xfs_rmap_free_extent (struct xfs_mount *mp,struct xfs_defer_ops *dfops, -xfs_agnumber_t agno,xfs_agblock_t bno,xfs_extlen_t len, -uint64_t owner); +int xfs_rmap_alloc_extent (struct xfs_trans *tp,xfs_agnumber_t agno, +xfs_agblock_t bno,xfs_extlen_t len,uint64_t owner); +int xfs_rmap_free_extent (struct xfs_trans *tp,xfs_agnumber_t agno, +xfs_agblock_t bno,xfs_extlen_t len,uint64_t owner);void xfs_rmap_finish_one_cleanup (struct xfs_trans *tp,struct xfs_btree_cur *rcur,int error);fs/xfs/xfs_bmap_item.c +1
-2@@ -486,8 +486,7 @@ xfs_bui_recover( irec.br_blockcount = count; irec.br_startoff = bmap->me_startoff; irec.br_state = state; - error =xfs_bmap_unmap_extent (tp->t_mountp, tp->t_dfops, ip, - &irec); + error =xfs_bmap_unmap_extent (tp, ip, &irec);if (error) goto err_inode; }fs/xfs/xfs_bmap_util.c +4
-9@@ -1534,7 +1534,6 @@ xfs_swap_extent_rmap( struct xfs_inode *tip) {struct xfs_trans *tp = *tpp; -struct xfs_mount *mp = tp->t_mountp;struct xfs_bmbt_irec irec;struct xfs_bmbt_irec uirec;struct xfs_bmbt_irec tirec;@@ -1598,26 +1597,22 @@ xfs_swap_extent_rmap(trace_xfs_swap_extent_rmap_remap_piece (tip, &uirec);/* Remove the mapping from the donor file. */ - error =xfs_bmap_unmap_extent (mp, tp->t_dfops, tip, - &uirec); + error =xfs_bmap_unmap_extent (tp, tip, &uirec);if (error) goto out_defer;/* Remove the mapping from the source file. */ - error =xfs_bmap_unmap_extent (mp, tp->t_dfops, ip, - &irec); + error =xfs_bmap_unmap_extent (tp, ip, &irec);if (error) goto out_defer;/* Map the donor file's blocks into the source file. */ - error =xfs_bmap_map_extent (mp, tp->t_dfops, ip, - &uirec); + error =xfs_bmap_map_extent (tp, ip, &uirec);if (error) goto out_defer;/* Map the source file's blocks into the donor file. */ - error =xfs_bmap_map_extent (mp, tp->t_dfops, tip, - &irec); + error =xfs_bmap_map_extent (tp, tip, &irec);if (error) goto out_defer;fs/xfs/xfs_refcount_item.c +4
-10@@ -490,24 +490,18 @@ xfs_cui_recover( irec.br_blockcount = new_len;switch (type) {case XFS_REFCOUNT_INCREASE : - error =xfs_refcount_increase_extent ( - tp->t_mountp, tp->t_dfops, - &irec); + error =xfs_refcount_increase_extent (tp, &irec);break ;case XFS_REFCOUNT_DECREASE : - error =xfs_refcount_decrease_extent ( - tp->t_mountp, tp->t_dfops, - &irec); + error =xfs_refcount_decrease_extent (tp, &irec);break ;case XFS_REFCOUNT_ALLOC_COW : - error =xfs_refcount_alloc_cow_extent ( - tp->t_mountp, tp->t_dfops, + error =xfs_refcount_alloc_cow_extent (tp, irec.br_startblock, irec.br_blockcount);break ;case XFS_REFCOUNT_FREE_COW : - error =xfs_refcount_free_cow_extent ( - tp->t_mountp, tp->t_dfops, + error =xfs_refcount_free_cow_extent (tp, irec.br_startblock, irec.br_blockcount);break ;fs/xfs/xfs_reflink.c +9
-12@@ -506,15 +506,13 @@ xfs_reflink_cancel_cow_blocks(ASSERT ((*tpp)->t_firstblock ==NULLFSBLOCK );/* Free the CoW orphan record. */ - error =xfs_refcount_free_cow_extent (ip->i_mount, - (*tpp)->t_dfops, del.br_startblock, - del.br_blockcount); + error =xfs_refcount_free_cow_extent (*tpp, + del.br_startblock, del.br_blockcount);if (error)break ; -xfs_bmap_add_free (ip->i_mount, (*tpp)->t_dfops, - del.br_startblock, del.br_blockcount, -NULL ); +xfs_bmap_add_free (*tpp, del.br_startblock, + del.br_blockcount,NULL );/* Roll the transaction */ error =xfs_defer_finish (tpp);@@ -694,14 +692,13 @@ xfs_reflink_end_cow(trace_xfs_reflink_cow_remap (ip, &del);/* Free the CoW orphan record. */ - error =xfs_refcount_free_cow_extent (tp->t_mountp, tp->t_dfops, - del.br_startblock, del.br_blockcount); + error =xfs_refcount_free_cow_extent (tp, del.br_startblock, + del.br_blockcount);if (error) goto out_cancel;/* Map the new blocks into the data fork. */ - error =xfs_bmap_map_extent (tp->t_mountp, tp->t_dfops, ip, - &del); + error =xfs_bmap_map_extent (tp, ip, &del);if (error) goto out_cancel;@@ -1046,12 +1043,12 @@ xfs_reflink_remap_extent( uirec.br_blockcount, uirec.br_startblock);/* Update the refcount tree */ - error =xfs_refcount_increase_extent (mp, tp->t_dfops, &uirec); + error =xfs_refcount_increase_extent (tp, &uirec);if (error) goto out_cancel;/* Map the new blocks into the data fork. */ - error =xfs_bmap_map_extent (mp, tp->t_dfops, ip, &uirec); + error =xfs_bmap_map_extent (tp, ip, &uirec);if (error) goto out_cancel;Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/15] xfs: pass transaction to xfs_defer_add()
In reply to Brian FosterThis is the right patch to add an assert for a permanent transaction in xfs_defer_add.
Except for that this looks good:
PATCH 14/15 xfs: always defer agfl block frees
In reply to Brian FosterThe AGFL fixup code conditionally defers block frees from the free list based on whether the current transaction has an associated xfs_defer_ops structure. Now that dfops is embedded in the transaction and the internal dfops is used unconditionally, this invariant is always true.
Remove the now dead logic to check for ->t_dfops in xfs_alloc_fix_freelist() and unconditionally defer AGFL block frees.
--- fs/xfs/libxfs/xfs_alloc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
fs/xfs/libxfs/xfs_alloc.c +2 -9
@@ -2323,15 +2323,8 @@ xfs_alloc_fix_freelist(if (error) goto out_agbp_relse; -/* defer agfl frees if dfops is provided */ -if (tp->t_dfops) { -xfs_defer_agfl_block (tp, args->agno, bno, &targs.oinfo); - }else { - error =xfs_free_agfl_block (tp, args->agno, bno, agbp, - &targs.oinfo); -if (error) - goto out_agbp_relse; - } +/* defer agfl frees */ +xfs_defer_agfl_block (tp, args->agno, bno, &targs.oinfo); } targs.tp = tp;
Signature · 1 line
2.17.1
Re: [PATCH 14/15] xfs: always defer agfl block frees
Quoted 10 lines · Brian Foster
The AGFL fixup code conditionally defers block frees from the free list based on whether the current transaction has an associated
xfs_defer_opsstructure. Now that dfops is embedded in the transaction and the internal dfops is used unconditionally, this invariant is always true.Remove the now dead logic to check for ->t_dfops in
xfs_alloc_fix_freelist()and unconditionally defer AGFL block frees.Signed-off-by Brian Foster <[email protected]>
Looks ok,
--D
Quoted 33 lines
--- fs/xfs/libxfs/xfs_alloc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)fs/xfs/libxfs/xfs_alloc.c +2
-9@@ -2323,15 +2323,8 @@ xfs_alloc_fix_freelist(if (error) goto out_agbp_relse; -/* defer agfl frees if dfops is provided */ -if (tp->t_dfops) { -xfs_defer_agfl_block (tp, args->agno, bno, &targs.oinfo); - }else { - error =xfs_free_agfl_block (tp, args->agno, bno, agbp, - &targs.oinfo); -if (error) - goto out_agbp_relse; - } +/* defer agfl frees */ +xfs_defer_agfl_block (tp, args->agno, bno, &targs.oinfo); } targs.tp = tp;Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 14/15] xfs: always defer agfl block frees
In reply to Brian FosterQuoted 10 lines · Brian Foster
The AGFL fixup code conditionally defers block frees from the free list based on whether the current transaction has an associated
xfs_defer_opsstructure. Now that dfops is embedded in the transaction and the internal dfops is used unconditionally, this invariant is always true.Remove the now dead logic to check for ->t_dfops in
xfs_alloc_fix_freelist()and unconditionally defer AGFL block frees.Signed-off-by Brian Foster <[email protected]>
Looks good,
PATCH 15/15 xfs: fold dfops into the transaction
In reply to Brian Fosterstruct xfs_defer_ops has now been reduced to a single list_head. The external dfops mechanism is unused and thus everywhere a (permanent) transaction is accessible the associated dfops structure is as well.
Remove the xfs_defer_ops structure and fold the list_head into the transaction. Also remove the last remnant of external dfops in xfs_trans_dup().
--- fs/xfs/libxfs/xfs_bmap.c | 1 - fs/xfs/libxfs/xfs_btree.h | 1 - fs/xfs/libxfs/xfs_da_btree.h | 1 - fs/xfs/libxfs/xfs_defer.c | 65 +++++++++++------------------------- fs/xfs/libxfs/xfs_defer.h | 2 -- fs/xfs/libxfs/xfs_dir2.c | 2 -- fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/xfs_inode.h | 1 - fs/xfs/xfs_reflink.c | 5 ++- fs/xfs/xfs_trace.h | 33 +++++++++--------- fs/xfs/xfs_trans.c | 11 +++--- fs/xfs/xfs_trans.h | 8 ++--- 12 files changed, 43 insertions(+), 88 deletions(-)
fs/xfs/libxfs/xfs_bmap.c +0 -1
@@ -4285,7 +4285,6 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype =0 ; -ASSERT (!tp || tp->t_dfops);while (bno < end && n < *nmap) {bool need_alloc = false, wasdelay = false;
fs/xfs/libxfs/xfs_btree.h +0 -1
@@ -7,7 +7,6 @@#define __XFS_BTREE_H__struct xfs_buf ; -struct xfs_defer_ops ;struct xfs_inode ;struct xfs_mount ;struct xfs_trans ;
fs/xfs/libxfs/xfs_da_btree.h +0 -1
@@ -7,7 +7,6 @@#ifndef __XFS_DA_BTREE_H__#define __XFS_DA_BTREE_H__ -struct xfs_defer_ops ;struct xfs_inode ;struct xfs_trans ;struct zone ;
fs/xfs/libxfs/xfs_defer.c +19 -46
164 lines not on this page · raw message
fs/xfs/libxfs/xfs_defer.h +0 -2
@@ -7,7 +7,6 @@#define __XFS_DEFER_H__struct xfs_defer_op_type ; -struct xfs_defer_ops ;/* * Save a log intent item and a list of extents, so that we can replay
@@ -40,7 +39,6 @@ void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,int xfs_defer_finish_noroll (struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *); -void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_trans *tp,struct list_head *dop_pending);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);
fs/xfs/libxfs/xfs_dir2.c +0 -2
@@ -424,7 +424,6 @@ xfs_dir_removename(int v;/* type-checking value */ ASSERT (S_ISDIR (VFS_I (dp)->i_mode)); -ASSERT (tp->t_dfops);XFS_STATS_INC (dp->i_mount, xs_dir_remove); args =kmem_zalloc (sizeof (*args),KM_SLEEP |KM_NOFS );
@@ -483,7 +482,6 @@ xfs_dir_replace(int v;/* type-checking value */ ASSERT (S_ISDIR (VFS_I (dp)->i_mode)); -ASSERT (tp->t_dfops); rval =xfs_dir_ino_validate (tp->t_mountp, inum);if (rval)
fs/xfs/libxfs/xfs_dir2.h +0 -1
@@ -9,7 +9,6 @@#include "xfs_da_format.h" #include "xfs_da_btree.h" -struct xfs_defer_ops ;struct xfs_da_args ;struct xfs_inode ;struct xfs_mount ;
fs/xfs/xfs_inode.h +0 -1
@@ -15,7 +15,6 @@struct xfs_dinode ;struct xfs_inode ;struct xfs_buf ; -struct xfs_defer_ops ;struct xfs_bmbt_irec ;struct xfs_inode_log_item ;struct xfs_mount ;
fs/xfs/xfs_reflink.c +2 -3
@@ -502,7 +502,6 @@ xfs_reflink_cancel_cow_blocks(if (error)break ; }else if (del.br_state ==XFS_EXT_UNWRITTEN || cancel_real) { -ASSERT ((*tpp)->t_dfops);ASSERT ((*tpp)->t_firstblock ==NULLFSBLOCK );/* Free the CoW orphan record. */
@@ -678,7 +677,7 @@ xfs_reflink_end_cow( goto prev_extent;/* Unmap the old blocks in the data fork. */ -ASSERT (tp->t_dfops && tp->t_firstblock ==NULLFSBLOCK ); +ASSERT (tp->t_firstblock ==NULLFSBLOCK ); rlen = del.br_blockcount; error =__xfs_bunmapi (tp, ip, del.br_startoff, &rlen,0 ,1 );if (error)
@@ -1021,7 +1020,7 @@ xfs_reflink_remap_extent(/* Unmap the old blocks in the data fork. */ rlen = unmap_len;while (rlen) { -ASSERT (tp->t_dfops && tp->t_firstblock ==NULLFSBLOCK ); +ASSERT (tp->t_firstblock ==NULLFSBLOCK ); error =__xfs_bunmapi (tp, ip, destoff, &rlen,0 ,1 );if (error) goto out_cancel;
fs/xfs/xfs_trace.h +16 -17
@@ -2213,57 +2213,56 @@ DEFINE_BTREE_CUR_EVENT(xfs_btree_overlapped_query_range);/* deferred ops */ struct xfs_defer_pending ; -struct xfs_defer_ops ;DECLARE_EVENT_CLASS (xfs_defer_class, - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, unsigned long caller_ip), -TP_ARGS (mp, dop, caller_ip), +TP_ARGS (mp, tp, caller_ip),TP_STRUCT__entry ( __field(dev_t, dev) - __field(void *, dop) + __field(void *, tp) __field(char, committed) __field(unsigned long, caller_ip) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; - __entry->dop = dop; + __entry->tp = tp; __entry->caller_ip = caller_ip; ), -TP_printk ("dev %d:%d ops %p caller %pS" , +TP_printk ("dev %d:%d tp %p caller %pS" ,MAJOR (__entry->dev),MINOR (__entry->dev), - __entry->dop, + __entry->tp, (char *)__entry->caller_ip) )#define DEFINE_DEFER_EVENT (name) \ DEFINE_EVENT(xfs_defer_class, name, \ - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, \ + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, \ unsigned long caller_ip), \ - TP_ARGS(mp, dop, caller_ip)) + TP_ARGS(mp, tp, caller_ip))DECLARE_EVENT_CLASS (xfs_defer_error_class, - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, int error), -TP_ARGS (mp, dop, error), + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, int error), +TP_ARGS (mp, tp, error),TP_STRUCT__entry ( __field(dev_t, dev) - __field(void *, dop) + __field(void *, tp) __field(char, committed)__field (int, error) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; - __entry->dop = dop; + __entry->tp = tp; __entry->error = error; ), -TP_printk ("dev %d:%d ops %p err %d" , +TP_printk ("dev %d:%d tp %p err %d" ,MAJOR (__entry->dev),MINOR (__entry->dev), - __entry->dop, + __entry->tp, __entry->error) )#define DEFINE_DEFER_ERROR_EVENT (name) \ DEFINE_EVENT(xfs_defer_error_class, name, \ - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, int error), \ - TP_ARGS(mp, dop, error)) + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, int error), \ + TP_ARGS(mp, tp, error)) DECLARE_EVENT_CLASS(xfs_defer_pending_class, TP_PROTO(struct xfs_mount *mp, struct xfs_defer_pending *dfp),
fs/xfs/xfs_trans.c +4 -7
@@ -100,6 +100,7 @@ xfs_trans_dup( ntp->t_mountp = tp->t_mountp;INIT_LIST_HEAD (&ntp->t_items);INIT_LIST_HEAD (&ntp->t_busy); +INIT_LIST_HEAD (&ntp->t_dfops); ntp->t_firstblock =NULLFSBLOCK ;ASSERT (tp->t_flags &XFS_TRANS_PERM_LOG_RES );
@@ -120,12 +121,8 @@ xfs_trans_dup( tp->t_rtx_res = tp->t_rtx_res_used; ntp->t_pflags = tp->t_pflags; -/* copy the dfops pointer if it's external, otherwise move it */ -xfs_defer_init (ntp, &ntp->t_dfops_internal); -if (tp->t_dfops != &tp->t_dfops_internal) - ntp->t_dfops = tp->t_dfops; -else -xfs_defer_move (ntp, tp); +/* move deferred ops over to the new tp */ +xfs_defer_move (ntp, tp);xfs_trans_dup_dqinfo (tp, ntp);
@@ -280,8 +277,8 @@ xfs_trans_alloc( tp->t_mountp = mp;INIT_LIST_HEAD (&tp->t_items);INIT_LIST_HEAD (&tp->t_busy); +INIT_LIST_HEAD (&tp->t_dfops); tp->t_firstblock =NULLFSBLOCK ; -xfs_defer_init (tp, &tp->t_dfops_internal); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error) {
fs/xfs/xfs_trans.h +2 -6
@@ -90,13 +90,10 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,#define XFS_ITEM_FLUSHING 3/* -* Deferred operations tracking structure. +* Deferred operation item relogging limits. */ #define XFS_DEFER_OPS_NR_INODES 2/* join up to two inodes */ #define XFS_DEFER_OPS_NR_BUFS 2/* join up to two buffers */ -struct xfs_defer_ops { -struct list_head dop_intake;/* unlogged pending work */ -};/* * This is the structure maintained for every active transaction.
@@ -114,7 +111,6 @@ typedef struct xfs_trans {struct xlog_ticket *t_ticket;/* log mgr ticket */ struct xfs_mount *t_mountp;/* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo;/* acctg info for dquots */ -struct xfs_defer_ops *t_dfops;/* dfops reference */ int64_t t_icount_delta;/* superblock icount change */ int64_t t_ifree_delta;/* superblock ifree change */ int64_t t_fdblocks_delta;/* superblock fdblocks chg */
@@ -136,8 +132,8 @@ typedef struct xfs_trans {int64_t t_rextslog_delta;/* superblocks rextslog chg */ struct list_head t_items;/* log item descriptors */ struct list_head t_busy;/* list of busy extents */ +struct list_head t_dfops;/* deferred operations */ unsigned long t_pflags;/* saved process flags state */ -struct xfs_defer_ops t_dfops_internal; } xfs_trans_t;/*
Signature · 1 line
2.17.1
Re: [PATCH 15/15] xfs: fold dfops into the transaction
Quoted 9 lines · Brian Foster
struct
xfs_defer_opshas now been reduced to a singlelist_head. The external dfops mechanism is unused and thus everywhere a (permanent) transaction is accessible the associated dfops structure is as well.Remove the
xfs_defer_opsstructure and fold thelist_headinto the transaction. Also remove the last remnant of external dfops inxfs_trans_dup().Signed-off-by Brian Foster <[email protected]>
Looks ok, I'll give it a spin to see how it does...
--D
Quoted 485 lines
--- fs/xfs/libxfs/xfs_bmap.c | 1 - fs/xfs/libxfs/xfs_btree.h | 1 - fs/xfs/libxfs/xfs_da_btree.h | 1 - fs/xfs/libxfs/xfs_defer.c | 65 +++++++++++------------------------- fs/xfs/libxfs/xfs_defer.h | 2 -- fs/xfs/libxfs/xfs_dir2.c | 2 -- fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/xfs_inode.h | 1 - fs/xfs/xfs_reflink.c | 5 ++- fs/xfs/xfs_trace.h | 33 +++++++++--------- fs/xfs/xfs_trans.c | 11 +++--- fs/xfs/xfs_trans.h | 8 ++--- 12 files changed, 43 insertions(+), 88 deletions(-)fs/xfs/libxfs/xfs_bmap.c +0
-1@@ -4285,7 +4285,6 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype =0 ; -ASSERT (!tp || tp->t_dfops);while (bno < end && n < *nmap) {bool need_alloc = false, wasdelay = false;fs/xfs/libxfs/xfs_btree.h +0
-1@@ -7,7 +7,6 @@#define __XFS_BTREE_H__struct xfs_buf ; -struct xfs_defer_ops ;struct xfs_inode ;struct xfs_mount ;struct xfs_trans ;fs/xfs/libxfs/xfs_da_btree.h +0
-1@@ -7,7 +7,6 @@#ifndef __XFS_DA_BTREE_H__#define __XFS_DA_BTREE_H__ -struct xfs_defer_ops ;struct xfs_inode ;struct xfs_trans ;struct zone ;fs/xfs/libxfs/xfs_defer.c +19
-46@@ -186,11 +186,10 @@ xfs_defer_intake_work(struct xfs_trans *tp, struct list_head *dop_pending) { - struct xfs_defer_ops *dop = tp->t_dfops; struct list_head *li;struct xfs_defer_pending *dfp; -list_for_each_entry (dfp, &dop->dop_intake, dfp_list) { +list_for_each_entry (dfp, &tp->t_dfops, dfp_list) { dfp->dfp_intent = dfp->dfp_type->create_intent (tp, dfp->dfp_count);trace_xfs_defer_intake_work (tp->t_mountp, dfp);@@ -200,7 +199,7 @@ xfs_defer_intake_work( dfp->dfp_type->log_item (tp, dfp->dfp_intent, li); } -list_splice_tail_init (&dop->dop_intake, dop_pending); +list_splice_tail_init (&tp->t_dfops, dop_pending); }/* Abort all the intents that were committed. */ @@ -210,10 +209,9 @@ xfs_defer_trans_abort( struct list_head *dop_pending, int error) { -struct xfs_defer_ops *dop = tp->t_dfops;struct xfs_defer_pending *dfp; -trace_xfs_defer_trans_abort (tp->t_mountp, dop, _RET_IP_); +trace_xfs_defer_trans_abort (tp->t_mountp, tp, _RET_IP_);/* Abort intent items that don't have a done item. */ if (dop_pending) {@@ -272,13 +270,12 @@ xfs_defer_trans_roll( } } -trace_xfs_defer_trans_roll ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); +trace_xfs_defer_trans_roll ((*tp)->t_mountp, *tp, _RET_IP_);/* Roll the transaction. */ error =xfs_trans_roll (tp);if (error) { -trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, - (*tp)->t_dfops, error); +trace_xfs_defer_trans_roll_error ((*tp)->t_mountp, *tp, error);xfs_defer_trans_abort (*tp, dop_pending, error);return error; }@@ -303,7 +300,7 @@ xfs_defer_has_unfinished_work( struct list_head *dop_pending) {return !list_empty (dop_pending) || - !list_empty (&tp->t_dfops->dop_intake); + !list_empty (&tp->t_dfops); }/* @@ -313,7 +310,7 @@ static voidxfs_defer_reset ( struct xfs_trans *tp) { -ASSERT (list_empty (&tp->t_dfops->dop_intake)); +ASSERT (list_empty (&tp->t_dfops));/* * Low mode state transfers across transaction rolls to mirror dfops @@ -344,7 +341,7 @@ xfs_defer_finish_noroll(ASSERT ((*tp)->t_flags &XFS_TRANS_PERM_LOG_RES ); -trace_xfs_defer_finish ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); +trace_xfs_defer_finish ((*tp)->t_mountp, *tp, _RET_IP_);/* Until we run out of pending work to finish... */ while (xfs_defer_has_unfinished_work (*tp, &dop_pending)) {@@ -420,14 +417,13 @@ xfs_defer_finish_noroll( out:if (error) { -trace_xfs_defer_finish_error ((*tp)->t_mountp, (*tp)->t_dfops, - error); +trace_xfs_defer_finish_error ((*tp)->t_mountp, *tp, error);__xfs_defer_cancel (&dop_pending);xfs_defer_cancel (*tp);return error; } -trace_xfs_defer_finish_done ((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); +trace_xfs_defer_finish_done ((*tp)->t_mountp, *tp, _RET_IP_);return 0 ; }@@ -486,8 +482,8 @@ voidxfs_defer_cancel ( struct xfs_trans *tp) { -trace_xfs_defer_cancel (NULL , tp->t_dfops, _RET_IP_); -__xfs_defer_cancel (&tp->t_dfops->dop_intake); +trace_xfs_defer_cancel (NULL , tp, _RET_IP_); +__xfs_defer_cancel (&tp->t_dfops); }/* Add an item for later deferred processing. */ @@ -497,7 +493,6 @@ xfs_defer_add(enum xfs_defer_ops_type type, struct list_head *li) { - struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp = NULL;/* @@ -505,8 +500,8 @@ xfs_defer_add(* If the last pending item has the same type, reuse it. Else, * create a new pending item at the end of the intake list. */ -if (!list_empty (&dop->dop_intake)) { - dfp =list_last_entry (&dop->dop_intake, +if (!list_empty (&tp->t_dfops)) { + dfp =list_last_entry (&tp->t_dfops, struct xfs_defer_pending, dfp_list); if (dfp->dfp_type->type != type || (dfp->dfp_type->max_items &&@@ -521,7 +516,7 @@ xfs_defer_add( dfp->dfp_done =NULL ; dfp->dfp_count =0 ;INIT_LIST_HEAD (&dfp->dfp_work); -list_add_tail (&dfp->dfp_list, &dop->dop_intake); +list_add_tail (&dfp->dfp_list, &tp->t_dfops); }list_add_tail (li, &dfp->dfp_work);@@ -536,39 +531,17 @@ xfs_defer_init_op_type( defer_op_types[type->type] = type; } -/* Initialize a deferred operation. */ -void -xfs_defer_init ( -struct xfs_trans *tp, -struct xfs_defer_ops *dop) -{ -struct xfs_mount *mp =NULL ; - -memset (dop,0 ,sizeof (struct xfs_defer_ops )); -INIT_LIST_HEAD (&dop->dop_intake); -if (tp) { -ASSERT (tp->t_firstblock ==NULLFSBLOCK ); - tp->t_dfops = dop; - mp = tp->t_mountp; - } -trace_xfs_defer_init (mp, dop, _RET_IP_); -} -/* -* Move state from one xfs_defer_ops to another and reset the source to initial -* state. This is primarily used to carry state forward across transaction rolls -* with internal dfops. +* Move deferred ops from one transaction to another and reset the source to +* initial state. This is primarily used to carry state forward across +* transaction rolls with pending dfops. */ void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp) { -struct xfs_defer_ops *dst = dtp->t_dfops; -struct xfs_defer_ops *src = stp->t_dfops; -ASSERT (dst != src); - -list_splice_init (&src->dop_intake, &dst->dop_intake); +list_splice_init (&stp->t_dfops, &dtp->t_dfops);/* * Low free space mode was historically controlled by a dfops field. fs/xfs/libxfs/xfs_defer.h +0
-2@@ -7,7 +7,6 @@#define __XFS_DEFER_H__struct xfs_defer_op_type ; -struct xfs_defer_ops ;/* * Save a log intent item and a list of extents, so that we can replay @@ -40,7 +39,6 @@ void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,int xfs_defer_finish_noroll (struct xfs_trans **tp);int xfs_defer_finish (struct xfs_trans **tp);void xfs_defer_cancel (struct xfs_trans *); -void xfs_defer_init (struct xfs_trans *tp,struct xfs_defer_ops *dop);bool xfs_defer_has_unfinished_work (struct xfs_trans *tp,struct list_head *dop_pending);void xfs_defer_move (struct xfs_trans *dtp,struct xfs_trans *stp);fs/xfs/libxfs/xfs_dir2.c +0
-2@@ -424,7 +424,6 @@ xfs_dir_removename(int v;/* type-checking value */ ASSERT (S_ISDIR (VFS_I (dp)->i_mode)); -ASSERT (tp->t_dfops);XFS_STATS_INC (dp->i_mount, xs_dir_remove); args =kmem_zalloc (sizeof (*args),KM_SLEEP |KM_NOFS );@@ -483,7 +482,6 @@ xfs_dir_replace(int v;/* type-checking value */ ASSERT (S_ISDIR (VFS_I (dp)->i_mode)); -ASSERT (tp->t_dfops); rval =xfs_dir_ino_validate (tp->t_mountp, inum);if (rval)fs/xfs/libxfs/xfs_dir2.h +0
-1@@ -9,7 +9,6 @@#include "xfs_da_format.h" #include "xfs_da_btree.h" -struct xfs_defer_ops ;struct xfs_da_args ;struct xfs_inode ;struct xfs_mount ;fs/xfs/xfs_inode.h +0
-1@@ -15,7 +15,6 @@struct xfs_dinode ;struct xfs_inode ;struct xfs_buf ; -struct xfs_defer_ops ;struct xfs_bmbt_irec ;struct xfs_inode_log_item ;struct xfs_mount ;fs/xfs/xfs_reflink.c +2
-3@@ -502,7 +502,6 @@ xfs_reflink_cancel_cow_blocks(if (error)break ; }else if (del.br_state ==XFS_EXT_UNWRITTEN || cancel_real) { -ASSERT ((*tpp)->t_dfops);ASSERT ((*tpp)->t_firstblock ==NULLFSBLOCK );/* Free the CoW orphan record. */ @@ -678,7 +677,7 @@ xfs_reflink_end_cow( goto prev_extent;/* Unmap the old blocks in the data fork. */ -ASSERT (tp->t_dfops && tp->t_firstblock ==NULLFSBLOCK ); +ASSERT (tp->t_firstblock ==NULLFSBLOCK ); rlen = del.br_blockcount; error =__xfs_bunmapi (tp, ip, del.br_startoff, &rlen,0 ,1 );if (error)@@ -1021,7 +1020,7 @@ xfs_reflink_remap_extent(/* Unmap the old blocks in the data fork. */ rlen = unmap_len;while (rlen) { -ASSERT (tp->t_dfops && tp->t_firstblock ==NULLFSBLOCK ); +ASSERT (tp->t_firstblock ==NULLFSBLOCK ); error =__xfs_bunmapi (tp, ip, destoff, &rlen,0 ,1 );if (error) goto out_cancel;fs/xfs/xfs_trace.h +16
-17@@ -2213,57 +2213,56 @@ DEFINE_BTREE_CUR_EVENT(xfs_btree_overlapped_query_range);/* deferred ops */ struct xfs_defer_pending ; -struct xfs_defer_ops ;DECLARE_EVENT_CLASS (xfs_defer_class, - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, unsigned long caller_ip), -TP_ARGS (mp, dop, caller_ip), +TP_ARGS (mp, tp, caller_ip),TP_STRUCT__entry ( __field(dev_t, dev) - __field(void *, dop) + __field(void *, tp) __field(char, committed) __field(unsigned long, caller_ip) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; - __entry->dop = dop; + __entry->tp = tp; __entry->caller_ip = caller_ip; ), -TP_printk ("dev %d:%d ops %p caller %pS" , +TP_printk ("dev %d:%d tp %p caller %pS" ,MAJOR (__entry->dev),MINOR (__entry->dev), - __entry->dop, + __entry->tp, (char *)__entry->caller_ip) )#define DEFINE_DEFER_EVENT (name) \ DEFINE_EVENT(xfs_defer_class, name, \ - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, \ + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, \ unsigned long caller_ip), \ - TP_ARGS(mp, dop, caller_ip)) + TP_ARGS(mp, tp, caller_ip))DECLARE_EVENT_CLASS (xfs_defer_error_class, - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, int error), -TP_ARGS (mp, dop, error), + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, int error), +TP_ARGS (mp, tp, error),TP_STRUCT__entry ( __field(dev_t, dev) - __field(void *, dop) + __field(void *, tp) __field(char, committed)__field (int, error) ),TP_fast_assign ( __entry->dev = mp ? mp->m_super->s_dev : 0; - __entry->dop = dop; + __entry->tp = tp; __entry->error = error; ), -TP_printk ("dev %d:%d ops %p err %d" , +TP_printk ("dev %d:%d tp %p err %d" ,MAJOR (__entry->dev),MINOR (__entry->dev), - __entry->dop, + __entry->tp, __entry->error) )#define DEFINE_DEFER_ERROR_EVENT (name) \ DEFINE_EVENT(xfs_defer_error_class, name, \ - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, int error), \ - TP_ARGS(mp, dop, error)) + TP_PROTO(struct xfs_mount *mp, struct xfs_trans *tp, int error), \ + TP_ARGS(mp, tp, error)) DECLARE_EVENT_CLASS(xfs_defer_pending_class, TP_PROTO(struct xfs_mount *mp, struct xfs_defer_pending *dfp),fs/xfs/xfs_trans.c +4
-7@@ -100,6 +100,7 @@ xfs_trans_dup( ntp->t_mountp = tp->t_mountp;INIT_LIST_HEAD (&ntp->t_items);INIT_LIST_HEAD (&ntp->t_busy); +INIT_LIST_HEAD (&ntp->t_dfops); ntp->t_firstblock =NULLFSBLOCK ;ASSERT (tp->t_flags &XFS_TRANS_PERM_LOG_RES );@@ -120,12 +121,8 @@ xfs_trans_dup( tp->t_rtx_res = tp->t_rtx_res_used; ntp->t_pflags = tp->t_pflags; -/* copy the dfops pointer if it's external, otherwise move it */ -xfs_defer_init (ntp, &ntp->t_dfops_internal); -if (tp->t_dfops != &tp->t_dfops_internal) - ntp->t_dfops = tp->t_dfops; -else -xfs_defer_move (ntp, tp); +/* move deferred ops over to the new tp */ +xfs_defer_move (ntp, tp);xfs_trans_dup_dqinfo (tp, ntp);@@ -280,8 +277,8 @@ xfs_trans_alloc( tp->t_mountp = mp;INIT_LIST_HEAD (&tp->t_items);INIT_LIST_HEAD (&tp->t_busy); +INIT_LIST_HEAD (&tp->t_dfops); tp->t_firstblock =NULLFSBLOCK ; -xfs_defer_init (tp, &tp->t_dfops_internal); error =xfs_trans_reserve (tp, resp, blocks, rtextents);if (error) {fs/xfs/xfs_trans.h +2
-6@@ -90,13 +90,10 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,#define XFS_ITEM_FLUSHING 3/* -* Deferred operations tracking structure. +* Deferred operation item relogging limits. */ #define XFS_DEFER_OPS_NR_INODES 2/* join up to two inodes */ #define XFS_DEFER_OPS_NR_BUFS 2/* join up to two buffers */ -struct xfs_defer_ops { -struct list_head dop_intake;/* unlogged pending work */ -};/* * This is the structure maintained for every active transaction. @@ -114,7 +111,6 @@ typedef struct xfs_trans {struct xlog_ticket *t_ticket;/* log mgr ticket */ struct xfs_mount *t_mountp;/* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo;/* acctg info for dquots */ -struct xfs_defer_ops *t_dfops;/* dfops reference */ int64_t t_icount_delta;/* superblock icount change */ int64_t t_ifree_delta;/* superblock ifree change */ int64_t t_fdblocks_delta;/* superblock fdblocks chg */ @@ -136,8 +132,8 @@ typedef struct xfs_trans {int64_t t_rextslog_delta;/* superblocks rextslog chg */ struct list_head t_items;/* log item descriptors */ struct list_head t_busy;/* list of busy extents */ +struct list_head t_dfops;/* deferred operations */ unsigned long t_pflags;/* saved process flags state */ -struct xfs_defer_ops t_dfops_internal; } xfs_trans_t;/* Signature · 6 lines
2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 15/15] xfs: fold dfops into the transaction
In reply to Brian Fosterfs/xfs/libxfs/xfs_defer.c xfs_defer_trans_abort( · line 214
Quoted 2 lines
fs/xfs/libxfs/xfs_defer.c +1
-1-trace_xfs_defer_trans_abort (tp->t_mountp, dop, _RET_IP_); +trace_xfs_defer_trans_abort (tp->t_mountp, tp, _RET_IP_);
Can't we stop passing the explicit xfs_mount to these tracepoints now?
Otherwise looks good:
Re: [PATCH 15/15] xfs: fold dfops into the transaction
Quoted 5 lines · Christoph Hellwig
fs/xfs/libxfs/xfs_defer.c xfs_defer_trans_abort( · line 214
Quoted 2 lines
fs/xfs/libxfs/xfs_defer.c +1
-1-trace_xfs_defer_trans_abort (tp->t_mountp, dop, _RET_IP_); +trace_xfs_defer_trans_abort (tp->t_mountp, tp, _RET_IP_);Can't we stop passing the explicit
xfs_mountto these tracepoints now?
I thought I tried that and ran into xfs_trans definition issues. Looking again, I see that we're using ->t_mountp in other tracepoints so perhaps something else was going on. I don't recall exactly so I'll make another pass and try to clean these up wherever we have a transaction.
Brian
Quoted 7 lines
Otherwise looks good:
Reviewed-by Christoph Hellwig <[email protected]>--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html