As we have cdev in super block now, we can provide get_super_cdev to get super_block by a cdev reference, similar with get_super which is working only for block_device. Signed-off-by: Dongsheng Yang <yangds.fnst@xxxxxxxxxxxxxx> --- fs/super.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ 2 files changed, 47 insertions(+) diff --git a/fs/super.c b/fs/super.c index 928c20f..4a9031a 100644 --- a/fs/super.c +++ b/fs/super.c @@ -605,6 +605,37 @@ rescan: EXPORT_SYMBOL(get_super); +struct super_block *get_super_cdev(struct cdev *cdev) +{ + struct super_block *sb; + + if (!cdev) + return NULL; + + spin_lock(&sb_lock); +rescan: + list_for_each_entry(sb, &super_blocks, s_list) { + if (hlist_unhashed(&sb->s_instances)) + continue; + if (sb->s_cdev == cdev) { + sb->s_count++; + spin_unlock(&sb_lock); + down_read(&sb->s_umount); + /* still alive? */ + if (sb->s_root && (sb->s_flags & MS_BORN)) + return sb; + up_read(&sb->s_umount); + /* nope, got unmounted */ + spin_lock(&sb_lock); + __put_super(sb); + goto rescan; + } + } + spin_unlock(&sb_lock); + return NULL; +} +EXPORT_SYMBOL(get_super_cdev); + /** * get_super_thawed - get thawed superblock of a device * @bdev: device to get the superblock for @@ -628,6 +659,20 @@ struct super_block *get_super_thawed(struct block_device *bdev) } EXPORT_SYMBOL(get_super_thawed); +struct super_block *get_super_cdev_thawed(struct cdev *cdev) +{ + while (1) { + struct super_block *s = get_super_cdev(cdev); + if (!s || s->s_writers.frozen == SB_UNFROZEN) + return s; + up_read(&s->s_umount); + wait_event(s->s_writers.wait_unfrozen, + s->s_writers.frozen == SB_UNFROZEN); + put_super(s); + } +} +EXPORT_SYMBOL(get_super_cdev_thawed); + /** * get_active_super - get an active reference to the superblock of a device * @bdev: device to get the superblock for diff --git a/include/linux/fs.h b/include/linux/fs.h index 2f1d9499..5c7d789 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2744,7 +2744,9 @@ extern void get_filesystem(struct file_system_type *fs); extern void put_filesystem(struct file_system_type *fs); extern struct file_system_type *get_fs_type(const char *name); extern struct super_block *get_super(struct block_device *); +extern struct super_block *get_super_cdev(struct cdev *); extern struct super_block *get_super_thawed(struct block_device *); +extern struct super_block *get_super_cdev_thawed(struct cdev *); extern struct super_block *get_active_super(struct block_device *bdev); extern void drop_super(struct super_block *sb); extern void iterate_supers(void (*)(struct super_block *, void *), void *); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html