From: Darrick J. Wong Date: Tue, 6 Apr 2021 20:55:40 +0000 (-0400) Subject: xfs: refactor common transaction/inode/quota allocation idiom X-Git-Tag: v5.12.0-rc0~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d2b662c29c22f403d908676eabaa962b45129343;p=thirdparty%2Fxfsprogs-dev.git xfs: refactor common transaction/inode/quota allocation idiom Source kernel commit: 3a1af6c317d0a55524f39079183be107be4c1f39 Create a new helper xfs_trans_alloc_inode that allocates a transaction, locks and joins an inode to it, and then reserves the appropriate amount of quota against that transction. Then replace all the open-coded idioms with a single call to this helper. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Eric Sandeen --- diff --git a/include/xfs_trans.h b/include/xfs_trans.h index a2f188998..281caf306 100644 --- a/include/xfs_trans.h +++ b/include/xfs_trans.h @@ -85,6 +85,8 @@ int xfs_trans_roll(struct xfs_trans **); int libxfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp, uint blocks, uint rtextents, uint flags, struct xfs_trans **tpp); +int libxfs_trans_alloc_inode(struct xfs_inode *ip, struct xfs_trans_res *resv, + unsigned int dblocks, bool force, struct xfs_trans **tpp); int libxfs_trans_alloc_rollable(struct xfs_mount *mp, uint blocks, struct xfs_trans **tpp); int libxfs_trans_alloc_empty(struct xfs_mount *mp, struct xfs_trans **tpp); diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index e4192e1b1..d759ff654 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -165,6 +165,7 @@ #define xfs_trans_add_item libxfs_trans_add_item #define xfs_trans_alloc_empty libxfs_trans_alloc_empty #define xfs_trans_alloc libxfs_trans_alloc +#define xfs_trans_alloc_inode libxfs_trans_alloc_inode #define xfs_trans_bhold libxfs_trans_bhold #define xfs_trans_bhold_release libxfs_trans_bhold_release #define xfs_trans_binval libxfs_trans_binval diff --git a/libxfs/trans.c b/libxfs/trans.c index a4a5cbe07..04f878c52 100644 --- a/libxfs/trans.c +++ b/libxfs/trans.c @@ -996,3 +996,34 @@ libxfs_trans_commit( { return __xfs_trans_commit(tp, false); } + +/* + * Allocate an transaction, lock and join the inode to it, and reserve quota. + * + * The caller must ensure that the on-disk dquots attached to this inode have + * already been allocated and initialized. The caller is responsible for + * releasing ILOCK_EXCL if a new transaction is returned. + */ +int +libxfs_trans_alloc_inode( + struct xfs_inode *ip, + struct xfs_trans_res *resv, + unsigned int dblocks, + bool force, + struct xfs_trans **tpp) +{ + struct xfs_trans *tp; + struct xfs_mount *mp = ip->i_mount; + int error; + + error = libxfs_trans_alloc(mp, resv, dblocks, 0, + force ? XFS_TRANS_RESERVE : 0, &tp); + if (error) + return error; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, ip, 0); + + *tpp = tp; + return 0; +} diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 6e38eae5f..8cf631b67 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -458,14 +458,10 @@ xfs_attr_set( * Root fork attributes can use reserved data blocks for this * operation if necessary */ - error = xfs_trans_alloc(mp, &tres, total, 0, - rsvd ? XFS_TRANS_RESERVE : 0, &args->trans); + error = xfs_trans_alloc_inode(dp, &tres, total, rsvd, &args->trans); if (error) return error; - xfs_ilock(dp, XFS_ILOCK_EXCL); - xfs_trans_ijoin(args->trans, dp, 0); - if (args->value || xfs_inode_hasattr(dp)) { error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK, XFS_IEXT_ATTR_MANIP_CNT(rmt_blks)); @@ -474,11 +470,6 @@ xfs_attr_set( } if (args->value) { - error = xfs_trans_reserve_quota_nblks(args->trans, dp, - args->total, 0, rsvd); - if (error) - goto out_trans_cancel; - error = xfs_has_attr(args); if (error == -EEXIST && (args->attr_flags & XATTR_CREATE)) goto out_trans_cancel; diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 2079bc2f9..445280f44 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -1072,19 +1072,13 @@ xfs_bmap_add_attrfork( blks = XFS_ADDAFORK_SPACE_RES(mp); - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_addafork, blks, 0, - rsvd ? XFS_TRANS_RESERVE : 0, &tp); + error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, + rsvd, &tp); if (error) return error; - - xfs_ilock(ip, XFS_ILOCK_EXCL); - error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd); - if (error) - goto trans_cancel; if (XFS_IFORK_Q(ip)) goto trans_cancel; - xfs_trans_ijoin(tp, ip, 0); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = xfs_bmap_set_attrforkoff(ip, size, &version); if (error)