@@ -217,11 +217,13 @@ struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
} while (true);
}
-static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc)
+static int kernfs_fill_super(struct super_block *sb, struct fs_context *fc)
{
+ struct kernfs_fs_context *kfc = fc->fs_private;
struct kernfs_super_info *info = kernfs_info(sb);
struct inode *inode;
struct dentry *root;
+ int ret;
info->sb = sb;
/* Userspace would break if executables or devices appear on sysfs */
@@ -238,6 +240,12 @@ static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *k
/* sysfs dentries and inodes don't require IO to create */
sb->s_shrink.seeks = 0;
+ if (kfc->fill_super) {
+ ret = kfc->fill_super(sb, fc);
+ if (ret < 0)
+ return ret;
+ }
+
/* get root inode, initialize and unlock it */
mutex_lock(&kernfs_mutex);
inode = kernfs_get_inode(sb, info->root->kn);
@@ -290,6 +298,7 @@ const void *kernfs_super_ns(struct super_block *sb)
/**
* kernfs_get_tree - kernfs filesystem access/retrieval helper
* @fc: The filesystem context.
+ * @fill_super: The subclass's superblock initialiser function
*
* This is to be called from each kernfs user's fs_context->ops->get_tree()
* implementation, which should set the specified ->@fs_type and ->@flags, and
@@ -321,7 +330,7 @@ int kernfs_get_tree(struct fs_context *fc)
kfc->new_sb_created = true;
- error = kernfs_fill_super(sb, kfc);
+ error = kernfs_fill_super(sb, fc);
if (error) {
deactivate_locked_super(sb);
return error;
@@ -277,6 +277,7 @@ struct kernfs_fs_context {
struct kernfs_root *root; /* Root of the hierarchy being mounted */
void *ns_tag; /* Namespace tag of the mount (or NULL) */
unsigned long magic; /* File system specific magic number */
+ int (*fill_super)(struct super_block *sb, struct fs_context *fc);
/* The following are set/used by kernfs_mount() */
bool new_sb_created; /* Set to T if we allocated a new sb */
Provide a fill_super hook for a subclass filesystem to use to get a reference on the resource it attaches to struct kernfs_super_info::root. Without this, error handling becomes tricky in the event that, say, kernfs_get_inode() fails in kernfs_fill_super() as the superblock destructor will be invoked before kernfs_get_tree() returns. Fixes: b3678086951a ("kernfs, sysfs, cgroup, intel_rdt: Support fs_context") Signed-off-by: David Howells <dhowells@redhat.com> --- fs/kernfs/mount.c | 13 +++++++++++-- include/linux/kernfs.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-)