From: Darrick J. Wong <djwong@xxxxxxxxxx> Add a few helper functions so that it's possible to allocate xfs_imeta_path objects dynamically, along with dynamically allocated path components. Eventually we're going to want to support paths of the form "/realtime/$rtgroup.rmap", and this is necessary for that. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_imeta.c | 43 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_imeta.h | 8 ++++++++ 2 files changed, 51 insertions(+) diff --git a/fs/xfs/libxfs/xfs_imeta.c b/fs/xfs/libxfs/xfs_imeta.c index 07f88df7a7e5..8960c13117fc 100644 --- a/fs/xfs/libxfs/xfs_imeta.c +++ b/fs/xfs/libxfs/xfs_imeta.c @@ -1149,3 +1149,46 @@ xfs_imeta_lookup_update( return error; } + +/* Create a path to a file within the metadata directory tree. */ +int +xfs_imeta_create_file_path( + struct xfs_mount *mp, + unsigned int nr_components, + struct xfs_imeta_path **pathp) +{ + struct xfs_imeta_path *p; + char **components; + + p = kmalloc(sizeof(struct xfs_imeta_path), GFP_KERNEL); + if (!p) + return -ENOMEM; + + components = kvcalloc(nr_components, sizeof(char *), GFP_KERNEL); + if (!components) { + kfree(p); + return -ENOMEM; + } + + p->im_depth = nr_components; + p->im_path = (const char **)components; + p->im_ftype = XFS_DIR3_FT_REG_FILE; + p->im_dynamicmask = 0; + *pathp = p; + return 0; +} + +/* Free a metadata directory tree path. */ +void +xfs_imeta_free_path( + struct xfs_imeta_path *path) +{ + unsigned int i; + + for (i = 0; i < path->im_depth; i++) { + if ((path->im_dynamicmask & (1ULL << i)) && path->im_path[i]) + kfree(path->im_path[i]); + } + kfree(path->im_path); + kfree(path); +} diff --git a/fs/xfs/libxfs/xfs_imeta.h b/fs/xfs/libxfs/xfs_imeta.h index 741f426c6a4a..7840087b71da 100644 --- a/fs/xfs/libxfs/xfs_imeta.h +++ b/fs/xfs/libxfs/xfs_imeta.h @@ -15,6 +15,7 @@ const struct xfs_imeta_path name = { \ .im_path = (path), \ .im_ftype = XFS_DIR3_FT_REG_FILE, \ .im_depth = ARRAY_SIZE(path), \ + .im_dynamicmask = 0, \ } /* Key for looking up metadata inodes. */ @@ -27,6 +28,9 @@ struct xfs_imeta_path { /* Expected file type. */ unsigned int im_ftype; + + /* Each bit corresponds to an element of im_path needing to be freed */ + unsigned long long im_dynamicmask; }; /* Cleanup widget for metadata inode creation and deletion. */ @@ -52,6 +56,10 @@ int xfs_imeta_lookup_update(struct xfs_mount *mp, const struct xfs_imeta_path *path, struct xfs_imeta_update *upd, xfs_ino_t *inop); +int xfs_imeta_create_file_path(struct xfs_mount *mp, + unsigned int nr_components, struct xfs_imeta_path **pathp); +void xfs_imeta_free_path(struct xfs_imeta_path *path); + void xfs_imeta_set_metaflag(struct xfs_trans *tp, struct xfs_inode *ip); /* Don't allocate quota for this file. */