From 69881be3d9a00cca770886af40913cfc5274b2d0 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 29 Aug 2023 17:23:56 +0200 Subject: [PATCH] fs: export sget_dev() They will be used for mtd devices as well. Acked-by: Richard Weinberger Reviewed-by: Jan Kara Message-Id: <20230829-vfs-super-mtd-v1-1-fecb572e5df3@kernel.org> Signed-off-by: Christian Brauner Reviewed-by: Christoph Hellwig Signed-off-by: Christian Brauner --- fs/super.c | 64 ++++++++++++++++++++++++++++++++-------------- include/linux/fs.h | 1 + 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/fs/super.c b/fs/super.c index bd8dcfc822c3..2d762ce67f6e 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1373,6 +1373,50 @@ int get_tree_keyed(struct fs_context *fc, } EXPORT_SYMBOL(get_tree_keyed); +static int set_bdev_super(struct super_block *s, void *data) +{ + s->s_dev = *(dev_t *)data; + return 0; +} + +static int super_s_dev_set(struct super_block *s, struct fs_context *fc) +{ + return set_bdev_super(s, fc->sget_key); +} + +static int super_s_dev_test(struct super_block *s, struct fs_context *fc) +{ + return !(s->s_iflags & SB_I_RETIRED) && + s->s_dev == *(dev_t *)fc->sget_key; +} + +/** + * sget_dev - Find or create a superblock by device number + * @fc: Filesystem context. + * @dev: device number + * + * Find or create a superblock using the provided device number that + * will be stored in fc->sget_key. + * + * If an extant superblock is matched, then that will be returned with + * an elevated reference count that the caller must transfer or discard. + * + * If no match is made, a new superblock will be allocated and basic + * initialisation will be performed (s_type, s_fs_info, s_id, s_dev will + * be set). The superblock will be published and it will be returned in + * a partially constructed state with SB_BORN and SB_ACTIVE as yet + * unset. + * + * Return: an existing or newly created superblock on success, an error + * pointer on failure. + */ +struct super_block *sget_dev(struct fs_context *fc, dev_t dev) +{ + fc->sget_key = &dev; + return sget_fc(fc, super_s_dev_test, super_s_dev_set); +} +EXPORT_SYMBOL(sget_dev); + #ifdef CONFIG_BLOCK /* * Lock a super block that the callers holds a reference to. @@ -1431,23 +1475,6 @@ const struct blk_holder_ops fs_holder_ops = { }; EXPORT_SYMBOL_GPL(fs_holder_ops); -static int set_bdev_super(struct super_block *s, void *data) -{ - s->s_dev = *(dev_t *)data; - return 0; -} - -static int set_bdev_super_fc(struct super_block *s, struct fs_context *fc) -{ - return set_bdev_super(s, fc->sget_key); -} - -static int test_bdev_super_fc(struct super_block *s, struct fs_context *fc) -{ - return !(s->s_iflags & SB_I_RETIRED) && - s->s_dev == *(dev_t *)fc->sget_key; -} - int setup_bdev_super(struct super_block *sb, int sb_flags, struct fs_context *fc) { @@ -1525,8 +1552,7 @@ int get_tree_bdev(struct fs_context *fc, } fc->sb_flags |= SB_NOSEC; - fc->sget_key = &dev; - s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc); + s = sget_dev(fc, dev); if (IS_ERR(s)) return PTR_ERR(s); diff --git a/include/linux/fs.h b/include/linux/fs.h index c8ff4156a0a1..4aeb3fa11927 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2397,6 +2397,7 @@ struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block *,void *), int (*set)(struct super_block *,void *), int flags, void *data); +struct super_block *sget_dev(struct fs_context *fc, dev_t dev); /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \