diff mbox

[1/2] ocfs2: add kobject for online file check

Message ID 1482139287-19040-2-git-send-email-ghe@suse.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gang He Dec. 19, 2016, 9:21 a.m. UTC
Use embedded kobject mechanism for online file check feature,
this will avoid to use a global list to save/search per-device online file
check related data. The changed code is based on Goldwyn Rodrigues's
patches and ext4 fs code.
Second, some small adjustment/fixes are also included.
1) move some data structure definitions to the header file;
2) tune mlog message level from ERROR to NOTICE;
3) add file check duplicative ino number check;
4) the other miscellaneous.

Signed-off-by: Gang He <ghe@suse.com>
---
 fs/ocfs2/filecheck.c | 360 ++++++++++++++++++++-------------------------------
 fs/ocfs2/filecheck.h |  29 ++++-
 2 files changed, 165 insertions(+), 224 deletions(-)

Comments

kernel test robot Dec. 19, 2016, 10:56 a.m. UTC | #1
Hi Gang,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.9 next-20161219]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Gang-He/ocfs2-add-kobject-for-online-file-check/20161219-181858
config: x86_64-randconfig-x000-201651 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: the linux-review/Gang-He/ocfs2-add-kobject-for-online-file-check/20161219-181858 HEAD 6ef9256cd25ef72a5e69490cc3dacde95b8e2ac4 builds fine.
      It only hurts bisectibility.

All error/warnings (new ones prefixed by >>):

   fs/ocfs2/super.c: In function 'ocfs2_fill_super':
>> fs/ocfs2/super.c:1204:31: error: passing argument 1 of 'ocfs2_filecheck_create_sysfs' from incompatible pointer type [-Werror=incompatible-pointer-types]
     ocfs2_filecheck_create_sysfs(sb);
                                  ^~
   In file included from fs/ocfs2/super.c:77:0:
   fs/ocfs2/filecheck.h:71:5: note: expected 'struct ocfs2_super *' but argument is of type 'struct super_block *'
    int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/ocfs2/super.c: In function 'ocfs2_put_super':
>> fs/ocfs2/super.c:1656:31: error: passing argument 1 of 'ocfs2_filecheck_remove_sysfs' from incompatible pointer type [-Werror=incompatible-pointer-types]
     ocfs2_filecheck_remove_sysfs(sb);
                                  ^~
   In file included from fs/ocfs2/super.c:77:0:
   fs/ocfs2/filecheck.h:72:6: note: expected 'struct ocfs2_super *' but argument is of type 'struct super_block *'
    void ocfs2_filecheck_remove_sysfs(struct ocfs2_super *osb);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   fs/ocfs2/filecheck.c: In function 'ocfs2_filecheck_create_sysfs':
>> fs/ocfs2/filecheck.c:179:50: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     struct ocfs2_filecheck_sysfs_entry *entry = &osb->osb_fc_ent;
                                                     ^~
>> fs/ocfs2/filecheck.c:191:27: error: 'struct ocfs2_super' has no member named 'osb_dev_kset'; did you mean 'osb_dx_seed'?
     entry->fs_kobj.kset = osb->osb_dev_kset;
                              ^~
   fs/ocfs2/filecheck.c: In function 'ocfs2_filecheck_remove_sysfs':
   fs/ocfs2/filecheck.c:206:10: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     if (!osb->osb_fc_ent.fs_fcheck)
             ^~
   fs/ocfs2/filecheck.c:209:18: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     kobject_del(&osb->osb_fc_ent.fs_kobj);
                     ^~
   fs/ocfs2/filecheck.c:210:18: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     kobject_put(&osb->osb_fc_ent.fs_kobj);
                     ^~
   fs/ocfs2/filecheck.c:211:26: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     wait_for_completion(&osb->osb_fc_ent.fs_kobj_unregister);
                             ^~
   fs/ocfs2/filecheck.c:212:33: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     ocfs2_filecheck_sysfs_free(&osb->osb_fc_ent);
                                    ^~
   In file included from include/linux/list.h:8:0,
                    from fs/ocfs2/filecheck.c:20:
   fs/ocfs2/filecheck.c: In function 'ocfs2_filecheck_handle_entry':
>> include/linux/kernel.h:850:27: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                              ^
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   include/linux/kernel.h:850:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   include/linux/kernel.h:850:48: note: (near initialization for 'osb')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   In file included from include/linux/compiler.h:58:0,
                    from include/uapi/linux/stddef.h:1,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from include/linux/list.h:4,
                    from fs/ocfs2/filecheck.c:20:
>> include/linux/compiler-gcc.h:159:2: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     __builtin_offsetof(a, b)
     ^
   include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
    #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
                                   ^~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:851:29: note: in expansion of macro 'offsetof'
     (type *)( (char *)__mptr - offsetof(type,member) );})
                                ^~~~~~~~
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/ocfs2_filecheck_create_sysfs +1204 fs/ocfs2/super.c

19ece546 Jan Kara      2008-08-21  1198  	wake_up(&osb->osb_mount_event);
19ece546 Jan Kara      2008-08-21  1199  
df152c24 Sunil Mushran 2009-06-22  1200  	/* Start this when the mount is almost sure of being successful */
8b712cd5 Jeff Mahoney  2009-07-07  1201  	ocfs2_orphan_scan_start(osb);
df152c24 Sunil Mushran 2009-06-22  1202  
a849d468 Gang He       2016-03-22  1203  	/* Create filecheck sysfile /sys/fs/ocfs2/<devname>/filecheck */
a849d468 Gang He       2016-03-22 @1204  	ocfs2_filecheck_create_sysfs(sb);
a849d468 Gang He       2016-03-22  1205  
ccd979bd Mark Fasheh   2005-12-15  1206  	return status;
ccd979bd Mark Fasheh   2005-12-15  1207  

:::::: The code at line 1204 was first introduced by commit
:::::: a849d46816fe9e11d59aae78ea95c54f640b1904 ocfs2: create/remove sysfile for online file check

:::::: TO: Gang He <ghe@suse.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Gang He Dec. 20, 2016, 1:43 a.m. UTC | #2
Hello Kbuild,
Could you build my whole patch set (2 patch)? I think that the code is OK.

Thanks
Gang


>>> kbuild test robot <lkp@intel.com> 2016-12-19 下午 18:56 >>>
Hi Gang,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.9 next-20161219]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Gang-He/ocfs2-add-kobject-for-online-file-check/20161219-181858
config: x86_64-randconfig-x000-201651 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: the linux-review/Gang-He/ocfs2-add-kobject-for-online-file-check/20161219-181858 HEAD 6ef9256cd25ef72a5e69490cc3dacde95b8e2ac4 builds fine.
      It only hurts bisectibility.

All error/warnings (new ones prefixed by >>):

   fs/ocfs2/super.c: In function 'ocfs2_fill_super':
>> fs/ocfs2/super.c:1204:31: error: passing argument 1 of 'ocfs2_filecheck_create_sysfs' from incompatible pointer type [-Werror=incompatible-pointer-types]
     ocfs2_filecheck_create_sysfs(sb);
                                  ^~
   In file included from fs/ocfs2/super.c:77:0:
   fs/ocfs2/filecheck.h:71:5: note: expected 'struct ocfs2_super *' but argument is of type 'struct super_block *'
    int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/ocfs2/super.c: In function 'ocfs2_put_super':
>> fs/ocfs2/super.c:1656:31: error: passing argument 1 of 'ocfs2_filecheck_remove_sysfs' from incompatible pointer type [-Werror=incompatible-pointer-types]
     ocfs2_filecheck_remove_sysfs(sb);
                                  ^~
   In file included from fs/ocfs2/super.c:77:0:
   fs/ocfs2/filecheck.h:72:6: note: expected 'struct ocfs2_super *' but argument is of type 'struct super_block *'
    void ocfs2_filecheck_remove_sysfs(struct ocfs2_super *osb);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   fs/ocfs2/filecheck.c: In function 'ocfs2_filecheck_create_sysfs':
>> fs/ocfs2/filecheck.c:179:50: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     struct ocfs2_filecheck_sysfs_entry *entry = &osb->osb_fc_ent;
                                                     ^~
>> fs/ocfs2/filecheck.c:191:27: error: 'struct ocfs2_super' has no member named 'osb_dev_kset'; did you mean 'osb_dx_seed'?
     entry->fs_kobj.kset = osb->osb_dev_kset;
                              ^~
   fs/ocfs2/filecheck.c: In function 'ocfs2_filecheck_remove_sysfs':
   fs/ocfs2/filecheck.c:206:10: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     if (!osb->osb_fc_ent.fs_fcheck)
             ^~
   fs/ocfs2/filecheck.c:209:18: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     kobject_del(&osb->osb_fc_ent.fs_kobj);
                     ^~
   fs/ocfs2/filecheck.c:210:18: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     kobject_put(&osb->osb_fc_ent.fs_kobj);
                     ^~
   fs/ocfs2/filecheck.c:211:26: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     wait_for_completion(&osb->osb_fc_ent.fs_kobj_unregister);
                             ^~
   fs/ocfs2/filecheck.c:212:33: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     ocfs2_filecheck_sysfs_free(&osb->osb_fc_ent);
                                    ^~
   In file included from include/linux/list.h:8:0,
                    from fs/ocfs2/filecheck.c:20:
   fs/ocfs2/filecheck.c: In function 'ocfs2_filecheck_handle_entry':
>> include/linux/kernel.h:850:27: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                              ^
>> fs/ocfs2/filecheck.c:444:     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   include/linux/kernel.h:850:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   include/linux/kernel.h:850:48: note: (near initialization for 'osb')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   In file included from include/linux/compiler.h:58:0,
                    from include/uapi/linux/stddef.h:1,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from include/linux/list.h:4,
                    from fs/ocfs2/filecheck.c:20:
>> include/linux/compiler-gcc.h:159:2: error: 'struct ocfs2_super' has no member named 'osb_fc_ent'; did you mean 'osb_ctxt'?
     __builtin_offsetof(a, b)
     ^
   include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
    #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
                                   ^~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:851:29: note: in expansion of macro 'offsetof'
     (type *)( (char *)__mptr - offsetof(type,member) );})
                                ^~~~~~~~
>> fs/ocfs2/filecheck.c:444:28: note: in expansion of macro 'container_of'
     struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
                               ^~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/ocfs2_filecheck_create_sysfs +1204 fs/ocfs2/super.c

19ece546 Jan Kara      2008-08-21  1198  	wake_up(&osb->osb_mount_event);
19ece546 Jan Kara      2008-08-21  1199  
df152c24 Sunil Mushran 2009-06-22  1200  	/* Start this when the mount is almost sure of being successful */
8b712cd5 Jeff Mahoney  2009-07-07  1201  	ocfs2_orphan_scan_start(osb);
df152c24 Sunil Mushran 2009-06-22  1202  
a849d468 Gang He       2016-03-22  1203  	/* Create filecheck sysfile /sys/fs/ocfs2/<devname>/filecheck */
a849d468 Gang He       2016-03-22 @1204  	ocfs2_filecheck_create_sysfs(sb);
a849d468 Gang He       2016-03-22  1205  
ccd979bd Mark Fasheh   2005-12-15  1206  	return status;
ccd979bd Mark Fasheh   2005-12-15  1207  

:::::: The code at line 1204 was first introduced by commit
:::::: a849d46816fe9e11d59aae78ea95c54f640b1904 ocfs2: create/remove sysfile for online file check

:::::: TO: Gang He <ghe@suse.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Dec. 20, 2016, 1:47 a.m. UTC | #3
Hi Gang,

On Mon, Dec 19, 2016 at 06:43:48PM -0700, Gang He wrote:
>Hello Kbuild,
>Could you build my whole patch set (2 patch)? I think that the code is OK.

We test your whole patch as well as first-N patches, and noticed that
the first-1 patch breaks bisectibility:

>Note: the linux-review/Gang-He/ocfs2-add-kobject-for-online-file-check/20161219-181858 HEAD 6ef9256cd25ef72a5e69490cc3dacde95b8e2ac4 builds fine.
>      It only hurts bisectibility.

Thanks,
Fengguang
Gang He Dec. 20, 2016, 3 a.m. UTC | #4
Hi Fengguang and all,
I will reconstruct my patch set, to make sure each patch can follow this rule.

Thanks
Gang 

>>> Fengguang Wu <lkp@intel.com> 2016-12-20 上午 9:47 >>>
Hi Gang,

On Mon, Dec 19, 2016 at 06:43:48PM -0700, Gang He wrote:
>Hello Kbuild,
>Could you build my whole patch set (2 patch)? I think that the code is OK.

We test your whole patch as well as first-N patches, and noticed that
the first-1 patch breaks bisectibility:

>Note: the linux-review/Gang-He/ocfs2-add-kobject-for-online-file-check/20161219-181858 HEAD 6ef9256cd25ef72a5e69490cc3dacde95b8e2ac4 builds fine.
>      It only hurts bisectibility.

Thanks,
Fengguang
diff mbox

Patch

diff --git a/fs/ocfs2/filecheck.c b/fs/ocfs2/filecheck.c
index 2cabbcf..5a6ae70 100644
--- a/fs/ocfs2/filecheck.c
+++ b/fs/ocfs2/filecheck.c
@@ -53,36 +53,6 @@ 
 	"UNSUPPORTED"
 };
 
-static DEFINE_SPINLOCK(ocfs2_filecheck_sysfs_lock);
-static LIST_HEAD(ocfs2_filecheck_sysfs_list);
-
-struct ocfs2_filecheck {
-	struct list_head fc_head;	/* File check entry list head */
-	spinlock_t fc_lock;
-	unsigned int fc_max;	/* Maximum number of entry in list */
-	unsigned int fc_size;	/* Current entry count in list */
-	unsigned int fc_done;	/* Finished entry count in list */
-};
-
-struct ocfs2_filecheck_sysfs_entry {	/* sysfs entry per mounting */
-	struct list_head fs_list;
-	atomic_t fs_count;
-	struct super_block *fs_sb;
-	struct kset *fs_devicekset;
-	struct kset *fs_fcheckkset;
-	struct ocfs2_filecheck *fs_fcheck;
-};
-
-#define OCFS2_FILECHECK_MAXSIZE		100
-#define OCFS2_FILECHECK_MINSIZE		10
-
-/* File check operation type */
-enum {
-	OCFS2_FILECHECK_TYPE_CHK = 0,	/* Check a file(inode) */
-	OCFS2_FILECHECK_TYPE_FIX,	/* Fix a file(inode) */
-	OCFS2_FILECHECK_TYPE_SET = 100	/* Set entry list maximum size */
-};
-
 struct ocfs2_filecheck_entry {
 	struct list_head fe_list;
 	unsigned long fe_ino;
@@ -110,40 +80,84 @@  struct ocfs2_filecheck_args {
 	return ocfs2_filecheck_errs[errno - OCFS2_FILECHECK_ERR_START + 1];
 }
 
-static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
-				    struct kobj_attribute *attr,
-				    char *buf);
-static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
-				     struct kobj_attribute *attr,
-				     const char *buf, size_t count);
-static struct kobj_attribute ocfs2_attr_filecheck_chk =
+static ssize_t ocfs2_filecheck_attr_show(struct kobject *kobj,
+					struct kobj_attribute *attr,
+					char *buf);
+static ssize_t ocfs2_filecheck_attr_store(struct kobject *kobj,
+					struct kobj_attribute *attr,
+					const char *buf, size_t count);
+static struct kobj_attribute ocfs2_filecheck_attr_chk =
 					__ATTR(check, S_IRUSR | S_IWUSR,
-					ocfs2_filecheck_show,
-					ocfs2_filecheck_store);
-static struct kobj_attribute ocfs2_attr_filecheck_fix =
+					ocfs2_filecheck_attr_show,
+					ocfs2_filecheck_attr_store);
+static struct kobj_attribute ocfs2_filecheck_attr_fix =
 					__ATTR(fix, S_IRUSR | S_IWUSR,
-					ocfs2_filecheck_show,
-					ocfs2_filecheck_store);
-static struct kobj_attribute ocfs2_attr_filecheck_set =
+					ocfs2_filecheck_attr_show,
+					ocfs2_filecheck_attr_store);
+static struct kobj_attribute ocfs2_filecheck_attr_set =
 					__ATTR(set, S_IRUSR | S_IWUSR,
-					ocfs2_filecheck_show,
-					ocfs2_filecheck_store);
+					ocfs2_filecheck_attr_show,
+					ocfs2_filecheck_attr_store);
+static struct attribute *ocfs2_filecheck_attrs[] = {
+	&ocfs2_filecheck_attr_chk.attr,
+	&ocfs2_filecheck_attr_fix.attr,
+	&ocfs2_filecheck_attr_set.attr,
+	NULL
+};
 
-static int ocfs2_filecheck_sysfs_wait(atomic_t *p)
+static void ocfs2_filecheck_release(struct kobject *kobj)
 {
-	schedule();
-	return 0;
+	struct ocfs2_filecheck_sysfs_entry *entry = container_of(kobj,
+				struct ocfs2_filecheck_sysfs_entry, fs_kobj);
+
+	complete(&entry->fs_kobj_unregister);
 }
 
+static ssize_t
+ocfs2_filecheck_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	ssize_t ret = -EIO;
+	struct kobj_attribute *kattr = container_of(attr,
+					struct kobj_attribute, attr);
+
+	kobject_get(kobj);
+	if (kattr->show)
+		ret = kattr->show(kobj, kattr, buf);
+	kobject_put(kobj);
+	return ret;
+}
+
+static ssize_t
+ocfs2_filecheck_store(struct kobject *kobj, struct attribute *attr,
+			const char *buf, size_t count)
+{
+	ssize_t ret = -EIO;
+	struct kobj_attribute *kattr = container_of(attr,
+					struct kobj_attribute, attr);
+
+	kobject_get(kobj);
+	if (kattr->store)
+		ret = kattr->store(kobj, kattr, buf, count);
+	kobject_put(kobj);
+	return ret;
+}
+
+static const struct sysfs_ops ocfs2_filecheck_ops = {
+	.show = ocfs2_filecheck_show,
+	.store = ocfs2_filecheck_store,
+};
+
+static struct kobj_type ocfs2_ktype_filecheck = {
+	.default_attrs = ocfs2_filecheck_attrs,
+	.sysfs_ops = &ocfs2_filecheck_ops,
+	.release = ocfs2_filecheck_release,
+};
+
 static void
 ocfs2_filecheck_sysfs_free(struct ocfs2_filecheck_sysfs_entry *entry)
 {
 	struct ocfs2_filecheck_entry *p;
 
-	if (!atomic_dec_and_test(&entry->fs_count))
-		wait_on_atomic_t(&entry->fs_count, ocfs2_filecheck_sysfs_wait,
-				 TASK_UNINTERRUPTIBLE);
-
 	spin_lock(&entry->fs_fcheck->fc_lock);
 	while (!list_empty(&entry->fs_fcheck->fc_head)) {
 		p = list_first_entry(&entry->fs_fcheck->fc_head,
@@ -154,151 +168,48 @@  static int ocfs2_filecheck_sysfs_wait(atomic_t *p)
 	}
 	spin_unlock(&entry->fs_fcheck->fc_lock);
 
-	kset_unregister(entry->fs_fcheckkset);
-	kset_unregister(entry->fs_devicekset);
 	kfree(entry->fs_fcheck);
-	kfree(entry);
-}
-
-static void
-ocfs2_filecheck_sysfs_add(struct ocfs2_filecheck_sysfs_entry *entry)
-{
-	spin_lock(&ocfs2_filecheck_sysfs_lock);
-	list_add_tail(&entry->fs_list, &ocfs2_filecheck_sysfs_list);
-	spin_unlock(&ocfs2_filecheck_sysfs_lock);
+	entry->fs_fcheck = NULL;
 }
 
-static int ocfs2_filecheck_sysfs_del(const char *devname)
-{
-	struct ocfs2_filecheck_sysfs_entry *p;
-
-	spin_lock(&ocfs2_filecheck_sysfs_lock);
-	list_for_each_entry(p, &ocfs2_filecheck_sysfs_list, fs_list) {
-		if (!strcmp(p->fs_sb->s_id, devname)) {
-			list_del(&p->fs_list);
-			spin_unlock(&ocfs2_filecheck_sysfs_lock);
-			ocfs2_filecheck_sysfs_free(p);
-			return 0;
-		}
-	}
-	spin_unlock(&ocfs2_filecheck_sysfs_lock);
-	return 1;
-}
-
-static void
-ocfs2_filecheck_sysfs_put(struct ocfs2_filecheck_sysfs_entry *entry)
+int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb)
 {
-	if (atomic_dec_and_test(&entry->fs_count))
-		wake_up_atomic_t(&entry->fs_count);
-}
-
-static struct ocfs2_filecheck_sysfs_entry *
-ocfs2_filecheck_sysfs_get(const char *devname)
-{
-	struct ocfs2_filecheck_sysfs_entry *p = NULL;
-
-	spin_lock(&ocfs2_filecheck_sysfs_lock);
-	list_for_each_entry(p, &ocfs2_filecheck_sysfs_list, fs_list) {
-		if (!strcmp(p->fs_sb->s_id, devname)) {
-			atomic_inc(&p->fs_count);
-			spin_unlock(&ocfs2_filecheck_sysfs_lock);
-			return p;
-		}
-	}
-	spin_unlock(&ocfs2_filecheck_sysfs_lock);
-	return NULL;
-}
-
-int ocfs2_filecheck_create_sysfs(struct super_block *sb)
-{
-	int ret = 0;
-	struct kset *device_kset = NULL;
-	struct kset *fcheck_kset = NULL;
-	struct ocfs2_filecheck *fcheck = NULL;
-	struct ocfs2_filecheck_sysfs_entry *entry = NULL;
-	struct attribute **attrs = NULL;
-	struct attribute_group attrgp;
-
-	if (!ocfs2_kset)
-		return -ENOMEM;
-
-	attrs = kmalloc(sizeof(struct attribute *) * 4, GFP_NOFS);
-	if (!attrs) {
-		ret = -ENOMEM;
-		goto error;
-	} else {
-		attrs[0] = &ocfs2_attr_filecheck_chk.attr;
-		attrs[1] = &ocfs2_attr_filecheck_fix.attr;
-		attrs[2] = &ocfs2_attr_filecheck_set.attr;
-		attrs[3] = NULL;
-		memset(&attrgp, 0, sizeof(attrgp));
-		attrgp.attrs = attrs;
-	}
+	int ret;
+	struct ocfs2_filecheck *fcheck;
+	struct ocfs2_filecheck_sysfs_entry *entry = &osb->osb_fc_ent;
 
 	fcheck = kmalloc(sizeof(struct ocfs2_filecheck), GFP_NOFS);
-	if (!fcheck) {
-		ret = -ENOMEM;
-		goto error;
-	} else {
-		INIT_LIST_HEAD(&fcheck->fc_head);
-		spin_lock_init(&fcheck->fc_lock);
-		fcheck->fc_max = OCFS2_FILECHECK_MINSIZE;
-		fcheck->fc_size = 0;
-		fcheck->fc_done = 0;
-	}
-
-	if (strlen(sb->s_id) <= 0) {
-		mlog(ML_ERROR,
-		"Cannot get device basename when create filecheck sysfs\n");
-		ret = -ENODEV;
-		goto error;
-	}
-
-	device_kset = kset_create_and_add(sb->s_id, NULL, &ocfs2_kset->kobj);
-	if (!device_kset) {
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	fcheck_kset = kset_create_and_add("filecheck", NULL,
-					  &device_kset->kobj);
-	if (!fcheck_kset) {
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	ret = sysfs_create_group(&fcheck_kset->kobj, &attrgp);
-	if (ret)
-		goto error;
+	if (!fcheck)
+		return -ENOMEM;
 
-	entry = kmalloc(sizeof(struct ocfs2_filecheck_sysfs_entry), GFP_NOFS);
-	if (!entry) {
-		ret = -ENOMEM;
-		goto error;
-	} else {
-		atomic_set(&entry->fs_count, 1);
-		entry->fs_sb = sb;
-		entry->fs_devicekset = device_kset;
-		entry->fs_fcheckkset = fcheck_kset;
-		entry->fs_fcheck = fcheck;
-		ocfs2_filecheck_sysfs_add(entry);
+	INIT_LIST_HEAD(&fcheck->fc_head);
+	spin_lock_init(&fcheck->fc_lock);
+	fcheck->fc_max = OCFS2_FILECHECK_MINSIZE;
+	fcheck->fc_size = 0;
+	fcheck->fc_done = 0;
+
+	entry->fs_kobj.kset = osb->osb_dev_kset;
+	init_completion(&entry->fs_kobj_unregister);
+	ret = kobject_init_and_add(&entry->fs_kobj, &ocfs2_ktype_filecheck,
+					NULL, "filecheck");
+	if (ret) {
+		kfree(fcheck);
+		return ret;
 	}
 
-	kfree(attrs);
+	entry->fs_fcheck = fcheck;
 	return 0;
-
-error:
-	kfree(attrs);
-	kfree(entry);
-	kfree(fcheck);
-	kset_unregister(fcheck_kset);
-	kset_unregister(device_kset);
-	return ret;
 }
 
-int ocfs2_filecheck_remove_sysfs(struct super_block *sb)
+void ocfs2_filecheck_remove_sysfs(struct ocfs2_super *osb)
 {
-	return ocfs2_filecheck_sysfs_del(sb->s_id);
+	if (!osb->osb_fc_ent.fs_fcheck)
+		return;
+
+	kobject_del(&osb->osb_fc_ent.fs_kobj);
+	kobject_put(&osb->osb_fc_ent.fs_kobj);
+	wait_for_completion(&osb->osb_fc_ent.fs_kobj_unregister);
+	ocfs2_filecheck_sysfs_free(&osb->osb_fc_ent);
 }
 
 static int
@@ -315,7 +226,7 @@  int ocfs2_filecheck_remove_sysfs(struct super_block *sb)
 
 	spin_lock(&ent->fs_fcheck->fc_lock);
 	if (len < (ent->fs_fcheck->fc_size - ent->fs_fcheck->fc_done)) {
-		mlog(ML_ERROR,
+		mlog(ML_NOTICE,
 		"Cannot set online file check maximum entry number "
 		"to %u due to too many pending entries(%u)\n",
 		len, ent->fs_fcheck->fc_size - ent->fs_fcheck->fc_done);
@@ -392,7 +303,7 @@  int ocfs2_filecheck_remove_sysfs(struct super_block *sb)
 	return 0;
 }
 
-static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
+static ssize_t ocfs2_filecheck_attr_show(struct kobject *kobj,
 				    struct kobj_attribute *attr,
 				    char *buf)
 {
@@ -400,19 +311,12 @@  static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
 	ssize_t ret = 0, total = 0, remain = PAGE_SIZE;
 	unsigned int type;
 	struct ocfs2_filecheck_entry *p;
-	struct ocfs2_filecheck_sysfs_entry *ent;
+	struct ocfs2_filecheck_sysfs_entry *ent = container_of(kobj,
+				struct ocfs2_filecheck_sysfs_entry, fs_kobj);
 
 	if (ocfs2_filecheck_type_parse(attr->attr.name, &type))
 		return -EINVAL;
 
-	ent = ocfs2_filecheck_sysfs_get(kobj->parent->name);
-	if (!ent) {
-		mlog(ML_ERROR,
-		"Cannot get the corresponding entry via device basename %s\n",
-		kobj->name);
-		return -ENODEV;
-	}
-
 	if (type == OCFS2_FILECHECK_TYPE_SET) {
 		spin_lock(&ent->fs_fcheck->fc_lock);
 		total = snprintf(buf, remain, "%u\n", ent->fs_fcheck->fc_max);
@@ -446,11 +350,27 @@  static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
 	spin_unlock(&ent->fs_fcheck->fc_lock);
 
 exit:
-	ocfs2_filecheck_sysfs_put(ent);
 	return total;
 }
 
-static int
+
+static inline int
+ocfs2_filecheck_is_dup_entry(struct ocfs2_filecheck_sysfs_entry *ent,
+				unsigned long ino)
+{
+	struct ocfs2_filecheck_entry *p;
+
+	list_for_each_entry(p, &ent->fs_fcheck->fc_head, fe_list) {
+		if (!p->fe_done) {
+			if (p->fe_ino == ino)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static inline int
 ocfs2_filecheck_erase_entry(struct ocfs2_filecheck_sysfs_entry *ent)
 {
 	struct ocfs2_filecheck_entry *p;
@@ -489,21 +409,21 @@  static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
 ocfs2_filecheck_done_entry(struct ocfs2_filecheck_sysfs_entry *ent,
 			   struct ocfs2_filecheck_entry *entry)
 {
-	entry->fe_done = 1;
 	spin_lock(&ent->fs_fcheck->fc_lock);
+	entry->fe_done = 1;
 	ent->fs_fcheck->fc_done++;
 	spin_unlock(&ent->fs_fcheck->fc_lock);
 }
 
 static unsigned int
-ocfs2_filecheck_handle(struct super_block *sb,
+ocfs2_filecheck_handle(struct ocfs2_super *osb,
 		       unsigned long ino, unsigned int flags)
 {
 	unsigned int ret = OCFS2_FILECHECK_ERR_SUCCESS;
 	struct inode *inode = NULL;
 	int rc;
 
-	inode = ocfs2_iget(OCFS2_SB(sb), ino, flags, 0);
+	inode = ocfs2_iget(osb, ino, flags, 0);
 	if (IS_ERR(inode)) {
 		rc = (int)(-(long)inode);
 		if (rc >= OCFS2_FILECHECK_ERR_START &&
@@ -521,11 +441,14 @@  static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
 ocfs2_filecheck_handle_entry(struct ocfs2_filecheck_sysfs_entry *ent,
 			     struct ocfs2_filecheck_entry *entry)
 {
+	struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
+						osb_fc_ent);
+
 	if (entry->fe_type == OCFS2_FILECHECK_TYPE_CHK)
-		entry->fe_status = ocfs2_filecheck_handle(ent->fs_sb,
+		entry->fe_status = ocfs2_filecheck_handle(osb,
 				entry->fe_ino, OCFS2_FI_FLAG_FILECHECK_CHK);
 	else if (entry->fe_type == OCFS2_FILECHECK_TYPE_FIX)
-		entry->fe_status = ocfs2_filecheck_handle(ent->fs_sb,
+		entry->fe_status = ocfs2_filecheck_handle(osb,
 				entry->fe_ino, OCFS2_FI_FLAG_FILECHECK_FIX);
 	else
 		entry->fe_status = OCFS2_FILECHECK_ERR_UNSUPPORTED;
@@ -533,30 +456,21 @@  static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
 	ocfs2_filecheck_done_entry(ent, entry);
 }
 
-static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
+static ssize_t ocfs2_filecheck_attr_store(struct kobject *kobj,
 				     struct kobj_attribute *attr,
 				     const char *buf, size_t count)
 {
+	ssize_t ret = 0;
 	struct ocfs2_filecheck_args args;
 	struct ocfs2_filecheck_entry *entry;
-	struct ocfs2_filecheck_sysfs_entry *ent;
-	ssize_t ret = 0;
+	struct ocfs2_filecheck_sysfs_entry *ent = container_of(kobj,
+				struct ocfs2_filecheck_sysfs_entry, fs_kobj);
 
 	if (count == 0)
-		return count;
+		return 0; /* nothing to do */
 
-	if (ocfs2_filecheck_args_parse(attr->attr.name, buf, count, &args)) {
-		mlog(ML_ERROR, "Invalid arguments for online file check\n");
+	if (ocfs2_filecheck_args_parse(attr->attr.name, buf, count, &args))
 		return -EINVAL;
-	}
-
-	ent = ocfs2_filecheck_sysfs_get(kobj->parent->name);
-	if (!ent) {
-		mlog(ML_ERROR,
-		"Cannot get the corresponding entry via device basename %s\n",
-		kobj->parent->name);
-		return -ENODEV;
-	}
 
 	if (args.fa_type == OCFS2_FILECHECK_TYPE_SET) {
 		ret = ocfs2_filecheck_adjust_max(ent, args.fa_len);
@@ -570,13 +484,16 @@  static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
 	}
 
 	spin_lock(&ent->fs_fcheck->fc_lock);
-	if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
-	    (ent->fs_fcheck->fc_done == 0)) {
-		mlog(ML_ERROR,
+	if (ocfs2_filecheck_is_dup_entry(ent, args.fa_ino)) {
+		ret = -EEXIST;
+		kfree(entry);
+	} else if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
+		(ent->fs_fcheck->fc_done == 0)) {
+		mlog(ML_NOTICE,
 		"Cannot do more file check "
 		"since file check queue(%u) is full now\n",
 		ent->fs_fcheck->fc_max);
-		ret = -EBUSY;
+		ret = -EAGAIN;
 		kfree(entry);
 	} else {
 		if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
@@ -601,6 +518,5 @@  static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
 		ocfs2_filecheck_handle_entry(ent, entry);
 
 exit:
-	ocfs2_filecheck_sysfs_put(ent);
 	return (!ret ? count : ret);
 }
diff --git a/fs/ocfs2/filecheck.h b/fs/ocfs2/filecheck.h
index e5cd002..6a22ee7 100644
--- a/fs/ocfs2/filecheck.h
+++ b/fs/ocfs2/filecheck.h
@@ -43,7 +43,32 @@  enum {
 #define OCFS2_FILECHECK_ERR_START	OCFS2_FILECHECK_ERR_FAILED
 #define OCFS2_FILECHECK_ERR_END		OCFS2_FILECHECK_ERR_UNSUPPORTED
 
-int ocfs2_filecheck_create_sysfs(struct super_block *sb);
-int ocfs2_filecheck_remove_sysfs(struct super_block *sb);
+struct ocfs2_filecheck {
+	struct list_head fc_head;	/* File check entry list head */
+	spinlock_t fc_lock;
+	unsigned int fc_max;	/* Maximum number of entry in list */
+	unsigned int fc_size;	/* Current entry count in list */
+	unsigned int fc_done;	/* Finished entry count in list */
+};
+
+#define OCFS2_FILECHECK_MAXSIZE		100
+#define OCFS2_FILECHECK_MINSIZE		10
+
+/* File check operation type */
+enum {
+	OCFS2_FILECHECK_TYPE_CHK = 0,	/* Check a file(inode) */
+	OCFS2_FILECHECK_TYPE_FIX,	/* Fix a file(inode) */
+	OCFS2_FILECHECK_TYPE_SET = 100	/* Set entry list maximum size */
+};
+
+struct ocfs2_filecheck_sysfs_entry {	/* sysfs entry per partition */
+	struct kobject fs_kobj;
+	struct completion fs_kobj_unregister;
+	struct ocfs2_filecheck *fs_fcheck;
+};
+
+
+int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb);
+void ocfs2_filecheck_remove_sysfs(struct ocfs2_super *osb);
 
 #endif  /* FILECHECK_H */