[PATCH 04/25] fs: super: introduce the functions to get super by cdev reference

Dongsheng Yang yangds.fnst at cn.fujitsu.com
Tue Jul 21 17:37:58 PDT 2015


On 07/21/2015 05:04 PM, Jan Kara wrote:
> On Tue 21-07-15 16:37:35, Dongsheng Yang wrote:
>> 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 at cn.fujitsu.com>
>
> Instead of duplicating the superblock searching functions, can you please
> create common __get_super() function like:
>
> struct super_block *__get_super(
> 		int (*compare)(struct super_block *, void *), void *key)
>
> And it will use the compare function to check whether the sb is the right
> one or not. You will then have one comparion functions for searching by
> bdev used by get_super() and one comparison function for searching by cdev
> used by get_super_cdev().
>
> Similarly you can create __get_super_thawed() to avoid the duplication
> there.

Haha, that's what I wanted to do, but forgive my lazy, I will update it
in next version.

Yang
>
> 								Honza
>
>> ---
>>   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
>>
>>




More information about the linux-mtd mailing list