diff options
author | Christoph Hellwig <hch@lst.de> | 2024-04-25 15:16:59 +0200 |
---|---|---|
committer | Chandan Babu R <chandanbabu@kernel.org> | 2024-04-26 11:19:03 +0530 |
commit | 14ee22fef420c864c0869419e54aa4e88f64b4e6 (patch) | |
tree | 98cd75e66707afa3511e0b700fa0a7cee173b972 /fs/xfs/libxfs/xfs_dir2.c | |
parent | 08e012a62de877e77d7d44d5bddace63d760741b (diff) |
xfs: factor out a xfs_dir_lookup_args helper
Add a helper to switch between the different directory formats for
lookup and to handle the -EEXIST return for a successful lookup.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs/xfs_dir2.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_dir2.c | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 7634344dc515..b4f935908911 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -352,6 +352,45 @@ xfs_dir_cilookup_result( return -EEXIST; } +int +xfs_dir_lookup_args( + struct xfs_da_args *args) +{ + bool is_block, is_leaf; + int error; + + if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { + error = xfs_dir2_sf_lookup(args); + goto out; + } + + /* dir2 functions require that the data fork is loaded */ + error = xfs_iread_extents(args->trans, args->dp, XFS_DATA_FORK); + if (error) + goto out; + + error = xfs_dir2_isblock(args, &is_block); + if (error) + goto out; + + if (is_block) { + error = xfs_dir2_block_lookup(args); + goto out; + } + + error = xfs_dir2_isleaf(args, &is_leaf); + if (error) + goto out; + if (is_leaf) + error = xfs_dir2_leaf_lookup(args); + else + error = xfs_dir2_node_lookup(args); +out: + if (error != -EEXIST) + return error; + return 0; +} + /* * Lookup a name in a directory, give back the inode number. * If ci_name is not NULL, returns the actual name in ci_name if it differs @@ -368,7 +407,6 @@ xfs_dir_lookup( { struct xfs_da_args *args; int rval; - bool v; int lock_mode; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -390,30 +428,7 @@ xfs_dir_lookup( args->op_flags |= XFS_DA_OP_CILOOKUP; lock_mode = xfs_ilock_data_map_shared(dp); - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { - rval = xfs_dir2_sf_lookup(args); - goto out_check_rval; - } - - rval = xfs_dir2_isblock(args, &v); - if (rval) - goto out_free; - if (v) { - rval = xfs_dir2_block_lookup(args); - goto out_check_rval; - } - - rval = xfs_dir2_isleaf(args, &v); - if (rval) - goto out_free; - if (v) - rval = xfs_dir2_leaf_lookup(args); - else - rval = xfs_dir2_node_lookup(args); - -out_check_rval: - if (rval == -EEXIST) - rval = 0; + rval = xfs_dir_lookup_args(args); if (!rval) { *inum = args->inumber; if (ci_name) { @@ -421,7 +436,6 @@ out_check_rval: ci_name->len = args->valuelen; } } -out_free: xfs_iunlock(dp, lock_mode); kfree(args); return rval; |