@@ -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);
+}
@@ -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. */