xfs: add xfs_metadir_create_file helper

Factor the metadata inode create/commit/cleanup lifecycle out of
xfs_metadir_mkdir into a reusable helper that takes an optional callback
to initialize the new inode, and convert xfs_metadir_mkdir to it.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Johannes Thumshirn 2026-07-13 14:42:47 +02:00 committed by Carlos Maiolino
parent b16b63a479
commit daf43402da
2 changed files with 53 additions and 31 deletions

View File

@ -438,6 +438,52 @@ xfs_metadir_cancel(
xfs_metadir_teardown(upd, error);
}
int
xfs_metadir_create_file(
struct xfs_metadir_update *upd,
umode_t mode,
xfs_metadir_createfn create,
void *priv,
struct xfs_inode **ipp)
{
int error;
if (xfs_is_shutdown(upd->dp->i_mount))
return -EIO;
error = xfs_metadir_start_create(upd);
if (error)
return error;
error = xfs_metadir_create(upd, mode);
if (error)
goto out_cancel;
if (create) {
error = create(upd, priv);
if (error)
goto out_cancel;
}
error = xfs_metadir_commit(upd);
if (error)
goto out_irele;
xfs_finish_inode_setup(upd->ip);
*ipp = upd->ip;
return 0;
out_cancel:
xfs_metadir_cancel(upd, error);
out_irele:
/* Have to finish setting up the inode to ensure it's deleted. */
if (upd->ip) {
xfs_finish_inode_setup(upd->ip);
xfs_irele(upd->ip);
}
return error;
}
/* Create a metadata for the last component of the path. */
int
xfs_metadir_mkdir(
@ -450,36 +496,6 @@ xfs_metadir_mkdir(
.path = path,
.metafile_type = XFS_METAFILE_DIR,
};
int error;
if (xfs_is_shutdown(dp->i_mount))
return -EIO;
/* Allocate a transaction to create the last directory. */
error = xfs_metadir_start_create(&upd);
if (error)
return error;
/* Create the subdirectory and take our reference. */
error = xfs_metadir_create(&upd, S_IFDIR);
if (error)
goto out_cancel;
error = xfs_metadir_commit(&upd);
if (error)
goto out_irele;
xfs_finish_inode_setup(upd.ip);
*ipp = upd.ip;
return 0;
out_cancel:
xfs_metadir_cancel(&upd, error);
out_irele:
/* Have to finish setting up the inode to ensure it's deleted. */
if (upd.ip) {
xfs_finish_inode_setup(upd.ip);
xfs_irele(upd.ip);
}
return error;
return xfs_metadir_create_file(&upd, S_IFDIR, NULL, NULL, ipp);
}

View File

@ -35,6 +35,12 @@ int xfs_metadir_load(struct xfs_trans *tp, struct xfs_inode *dp,
int xfs_metadir_start_create(struct xfs_metadir_update *upd);
int xfs_metadir_create(struct xfs_metadir_update *upd, umode_t mode);
typedef int (*xfs_metadir_createfn)(struct xfs_metadir_update *upd, void *priv);
int xfs_metadir_create_file(struct xfs_metadir_update *upd, umode_t mode,
xfs_metadir_createfn create, void *priv,
struct xfs_inode **ipp);
int xfs_metadir_start_link(struct xfs_metadir_update *upd);
int xfs_metadir_link(struct xfs_metadir_update *upd);