From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dongsheng Yang Subject: Re: [PATCH 04/25] fs: super: introduce the functions to get super by cdev reference Date: Wed, 22 Jul 2015 08:37:58 +0800 Message-ID: <55AEE5E6.3090807@cn.fujitsu.com> References: <1437467876-22106-1-git-send-email-yangds.fnst@cn.fujitsu.com> <1437467876-22106-5-git-send-email-yangds.fnst@cn.fujitsu.com> <20150721090457.GF6533@quack.suse.cz> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Cc: , , , , To: Jan Kara Return-path: Received: from cn.fujitsu.com ([59.151.112.132]:18798 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S934008AbbGVAn1 (ORCPT ); Tue, 21 Jul 2015 20:43:27 -0400 In-Reply-To: <20150721090457.GF6533@quack.suse.cz> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: 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 > > 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 >> >>