Skip to content

Commit db1a28c

Browse files
allisonhendersondjwong
authored andcommitted
xfs: Add helpers xfs_attr_is_shortform and xfs_attr_set_shortform
In this patch, we hoist code from xfs_attr_set_args into two new helpers xfs_attr_is_shortform and xfs_attr_set_shortform. These two will help to simplify xfs_attr_set_args when we get into delayed attrs later. Signed-off-by: Allison Collins <[email protected]> Reviewed-by: Brian Foster <[email protected]> Reviewed-by: Chandan Rajendra <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]> Acked-by: Dave Chinner <[email protected]>
1 parent a237f2d commit db1a28c

File tree

1 file changed

+72
-35
lines changed

1 file changed

+72
-35
lines changed

fs/xfs/libxfs/xfs_attr.c

Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,66 @@ xfs_attr_try_sf_addname(
203203
return error;
204204
}
205205

206+
/*
207+
* Check to see if the attr should be upgraded from non-existent or shortform to
208+
* single-leaf-block attribute list.
209+
*/
210+
static inline bool
211+
xfs_attr_is_shortform(
212+
struct xfs_inode *ip)
213+
{
214+
return ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL ||
215+
(ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
216+
ip->i_afp->if_nextents == 0);
217+
}
218+
219+
/*
220+
* Attempts to set an attr in shortform, or converts short form to leaf form if
221+
* there is not enough room. If the attr is set, the transaction is committed
222+
* and set to NULL.
223+
*/
224+
STATIC int
225+
xfs_attr_set_shortform(
226+
struct xfs_da_args *args,
227+
struct xfs_buf **leaf_bp)
228+
{
229+
struct xfs_inode *dp = args->dp;
230+
int error, error2 = 0;
231+
232+
/*
233+
* Try to add the attr to the attribute list in the inode.
234+
*/
235+
error = xfs_attr_try_sf_addname(dp, args);
236+
if (error != -ENOSPC) {
237+
error2 = xfs_trans_commit(args->trans);
238+
args->trans = NULL;
239+
return error ? error : error2;
240+
}
241+
/*
242+
* It won't fit in the shortform, transform to a leaf block. GROT:
243+
* another possible req'mt for a double-split btree op.
244+
*/
245+
error = xfs_attr_shortform_to_leaf(args, leaf_bp);
246+
if (error)
247+
return error;
248+
249+
/*
250+
* Prevent the leaf buffer from being unlocked so that a concurrent AIL
251+
* push cannot grab the half-baked leaf buffer and run into problems
252+
* with the write verifier. Once we're done rolling the transaction we
253+
* can release the hold and add the attr to the leaf.
254+
*/
255+
xfs_trans_bhold(args->trans, *leaf_bp);
256+
error = xfs_defer_finish(&args->trans);
257+
xfs_trans_bhold_release(args->trans, *leaf_bp);
258+
if (error) {
259+
xfs_trans_brelse(args->trans, *leaf_bp);
260+
return error;
261+
}
262+
263+
return 0;
264+
}
265+
206266
/*
207267
* Set the attribute specified in @args.
208268
*/
@@ -212,48 +272,25 @@ xfs_attr_set_args(
212272
{
213273
struct xfs_inode *dp = args->dp;
214274
struct xfs_buf *leaf_bp = NULL;
215-
int error, error2 = 0;
275+
int error = 0;
216276

217277
/*
218-
* If the attribute list is non-existent or a shortform list,
219-
* upgrade it to a single-leaf-block attribute list.
278+
* If the attribute list is already in leaf format, jump straight to
279+
* leaf handling. Otherwise, try to add the attribute to the shortform
280+
* list; if there's no room then convert the list to leaf format and try
281+
* again.
220282
*/
221-
if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL ||
222-
(dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
223-
dp->i_afp->if_nextents == 0)) {
283+
if (xfs_attr_is_shortform(dp)) {
224284

225285
/*
226-
* Try to add the attr to the attribute list in the inode.
286+
* If the attr was successfully set in shortform, the
287+
* transaction is committed and set to NULL. Otherwise, is it
288+
* converted from shortform to leaf, and the transaction is
289+
* retained.
227290
*/
228-
error = xfs_attr_try_sf_addname(dp, args);
229-
if (error != -ENOSPC) {
230-
error2 = xfs_trans_commit(args->trans);
231-
args->trans = NULL;
232-
return error ? error : error2;
233-
}
234-
235-
/*
236-
* It won't fit in the shortform, transform to a leaf block.
237-
* GROT: another possible req'mt for a double-split btree op.
238-
*/
239-
error = xfs_attr_shortform_to_leaf(args, &leaf_bp);
240-
if (error)
241-
return error;
242-
243-
/*
244-
* Prevent the leaf buffer from being unlocked so that a
245-
* concurrent AIL push cannot grab the half-baked leaf
246-
* buffer and run into problems with the write verifier.
247-
* Once we're done rolling the transaction we can release
248-
* the hold and add the attr to the leaf.
249-
*/
250-
xfs_trans_bhold(args->trans, leaf_bp);
251-
error = xfs_defer_finish(&args->trans);
252-
xfs_trans_bhold_release(args->trans, leaf_bp);
253-
if (error) {
254-
xfs_trans_brelse(args->trans, leaf_bp);
291+
error = xfs_attr_set_shortform(args, &leaf_bp);
292+
if (error || !args->trans)
255293
return error;
256-
}
257294
}
258295

259296
if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {

0 commit comments

Comments
 (0)