* [PATCH] btrfs: fix leaks during sysfs teardown
@ 2013-11-20 21:59 Jeff Mahoney
2013-11-21 13:07 ` Filipe David Manana
0 siblings, 1 reply; 3+ messages in thread
From: Jeff Mahoney @ 2013-11-20 21:59 UTC (permalink / raw)
To: linux-btrfs, Josef Bacik; +Cc: Filipe David Borba Manana
Filipe noticed that we were leaking the features attribute group
after umount. His fix of just calling sysfs_remove_group() wasn't enough
since that removes just the supported features and not the unknown
features (but a regular test wouldn't show that).
This patch changes the unknown feature handling to add them individually
so we can skip the kmalloc and uses the same iteration to tear them down
later.
We also fix the error handling during mount so that we catch the
failing creation of the per-super kobject, and handle proper teardown
of a half-setup sysfs context.
Reported-by: Filipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
fs/btrfs/sysfs.c | 132 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 72 insertions(+), 60 deletions(-)
--- a/fs/btrfs/sysfs.c 2013-11-20 14:58:40.907456459 -0500
+++ b/fs/btrfs/sysfs.c 2013-11-20 16:59:02.359951682 -0500
@@ -417,28 +417,83 @@ static inline struct btrfs_fs_info *to_f
return container_of(kobj, struct btrfs_fs_info, super_kobj);
}
-void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
+#define NUM_FEATURE_BITS 64
+static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
+static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
+
+static u64 supported_feature_masks[3] = {
+ [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
+ [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
+ [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP,
+};
+
+static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
+{
+ int set;
+
+ for (set = 0; set < FEAT_MAX; set++) {
+ int i;
+ struct attribute *attrs[2];
+ struct attribute_group agroup = {
+ .name = "features",
+ .attrs = attrs,
+ };
+ u64 features = get_features(fs_info, set);
+ features &= ~supported_feature_masks[set];
+
+ if (!features)
+ continue;
+
+ attrs[1] = NULL;
+ for (i = 0; i < NUM_FEATURE_BITS; i++) {
+ struct btrfs_feature_attr *fa;
+
+ if (!(features & (1ULL << i)))
+ continue;
+
+ fa = &btrfs_feature_attrs[set][i];
+ attrs[0] = &fa->kobj_attr.attr;
+ if (add) {
+ int ret;
+ ret = sysfs_merge_group(&fs_info->super_kobj,
+ &agroup);
+ if (ret)
+ return ret;
+ } else
+ sysfs_unmerge_group(&fs_info->super_kobj,
+ &agroup);
+ }
+
+ }
+ return 0;
+}
+
+static void __btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
{
- sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
- kobject_del(fs_info->device_dir_kobj);
- kobject_put(fs_info->device_dir_kobj);
- kobject_del(fs_info->space_info_kobj);
- kobject_put(fs_info->space_info_kobj);
kobject_del(&fs_info->super_kobj);
kobject_put(&fs_info->super_kobj);
wait_for_completion(&fs_info->kobj_unregister);
}
+void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
+{
+ if (fs_info->space_info_kobj) {
+ sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
+ kobject_del(fs_info->space_info_kobj);
+ kobject_put(fs_info->space_info_kobj);
+ }
+ kobject_del(fs_info->device_dir_kobj);
+ kobject_put(fs_info->device_dir_kobj);
+ addrm_unknown_feature_attrs(fs_info, false);
+ __btrfs_sysfs_remove_one(fs_info);
+}
+
const char * const btrfs_feature_set_names[3] = {
[FEAT_COMPAT] = "compat",
[FEAT_COMPAT_RO] = "compat_ro",
[FEAT_INCOMPAT] = "incompat",
};
-#define NUM_FEATURE_BITS 64
-static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
-static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
-
char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags)
{
size_t bufsize = 4096; /* safe max, 64 names * 64 bytes */
@@ -508,53 +563,6 @@ static void init_feature_attrs(void)
}
}
-static u64 supported_feature_masks[3] = {
- [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
- [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
- [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP,
-};
-
-static int add_unknown_feature_attrs(struct btrfs_fs_info *fs_info)
-{
- int set;
-
- for (set = 0; set < FEAT_MAX; set++) {
- int i, count, ret, index = 0;
- struct attribute **attrs;
- struct attribute_group agroup = {
- .name = "features",
- };
- u64 features = get_features(fs_info, set);
- features &= ~supported_feature_masks[set];
-
- count = hweight64(features);
-
- if (!count)
- continue;
-
- attrs = kcalloc(count + 1, sizeof(void *), GFP_KERNEL);
-
- for (i = 0; i < NUM_FEATURE_BITS; i++) {
- struct btrfs_feature_attr *fa;
-
- if (!(features & (1ULL << i)))
- continue;
-
- fa = &btrfs_feature_attrs[set][i];
- attrs[index++] = &fa->kobj_attr.attr;
- }
-
- attrs[index] = NULL;
- agroup.attrs = attrs;
-
- ret = sysfs_merge_group(&fs_info->super_kobj, &agroup);
- kfree(attrs);
- if (ret)
- return ret;
- }
- return 0;
-}
-
static int add_device_membership(struct btrfs_fs_info *fs_info)
{
int error = 0;
@@ -590,13 +598,17 @@ int btrfs_sysfs_add_one(struct btrfs_fs_
fs_info->super_kobj.kset = btrfs_kset;
error = kobject_init_and_add(&fs_info->super_kobj, &btrfs_ktype, NULL,
"%pU", fs_info->fsid);
+ if (error)
+ return error;
error = sysfs_create_group(&fs_info->super_kobj,
&btrfs_feature_attr_group);
- if (error)
- goto failure;
+ if (error) {
+ __btrfs_sysfs_remove_one(fs_info);
+ return error;
+ }
- error = add_unknown_feature_attrs(fs_info);
+ error = addrm_unknown_feature_attrs(fs_info, true);
if (error)
goto failure;
--
Jeff Mahoney
SUSE Labs
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] btrfs: fix leaks during sysfs teardown
2013-11-20 21:59 [PATCH] btrfs: fix leaks during sysfs teardown Jeff Mahoney
@ 2013-11-21 13:07 ` Filipe David Manana
2013-11-21 15:05 ` Jeff Mahoney
0 siblings, 1 reply; 3+ messages in thread
From: Filipe David Manana @ 2013-11-21 13:07 UTC (permalink / raw)
To: Jeff Mahoney; +Cc: linux-btrfs, Josef Bacik
On Wed, Nov 20, 2013 at 9:59 PM, Jeff Mahoney <jeffm@suse.com> wrote:
> Filipe noticed that we were leaking the features attribute group
> after umount. His fix of just calling sysfs_remove_group() wasn't enough
> since that removes just the supported features and not the unknown
> features (but a regular test wouldn't show that).
>
> This patch changes the unknown feature handling to add them individually
> so we can skip the kmalloc and uses the same iteration to tear them down
> later.
>
> We also fix the error handling during mount so that we catch the
> failing creation of the per-super kobject, and handle proper teardown
> of a half-setup sysfs context.
>
> Reported-by: Filipe David Borba Manana <fdmanana@gmail.com>
> Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Hi Jeff, I tested this patch (reverted my patch and applied yours) and
after about 20 minutes of running xfstests I had 169 kmemleak
warnings, see below some of the stack traces. Thanks.
unreferenced object 0xffff8807424bdb90 (size 64):
comm "mount", pid 20697, jiffies 4295160287 (age 1117.544s)
hex dump (first 32 bytes):
64 36 61 34 61 30 64 30 2d 39 62 31 63 2d 34 31 d6a4a0d0-9b1c-41
37 62 2d 38 31 30 37 2d 34 36 66 32 39 63 30 39 7b-8107-46f29c09
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
[<ffffffff81157102>] kstrdup+0x42/0x70
[<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
[<ffffffff813e3416>] kobject_add_internal+0x96/0x210
[<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
[<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
unreferenced object 0xffff8800968254f8 (size 160):
comm "mount", pid 20697, jiffies 4295160287 (age 1117.544s)
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
[<ffffffff813e3416>] kobject_add_internal+0x96/0x210
[<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
[<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8806b3cf22b0 (size 16):
comm "mount", pid 20697, jiffies 4295160287 (age 1117.544s)
hex dump (first 16 bytes):
66 65 61 74 75 72 65 73 00 6b 6b 6b 6b 6b 6b a5 features.kkkkkk.
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
[<ffffffff81157102>] kstrdup+0x42/0x70
[<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
[<ffffffff8121b51e>] internal_create_group+0x5e/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
unreferenced object 0xffff880096825310 (size 160):
comm "mount", pid 20697, jiffies 4295160287 (age 1117.648s)
hex dump (first 32 bytes):
03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
[<ffffffff8121b51e>] internal_create_group+0x5e/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff880096824b70 (size 160):
comm "mount", pid 20697, jiffies 4295160287 (age 1117.648s)
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 b8 4d 72 a0 ff ff ff ff .........Mr.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff8121847a>] sysfs_add_file_mode+0x6a/0x110
[<ffffffff8121b5a1>] internal_create_group+0xe1/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff880096825128 (size 160):
comm "mount", pid 20697, jiffies 4295160287 (age 1117.648s)
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 38 4f 72 a0 ff ff ff ff ........8Or.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff8121847a>] sysfs_add_file_mode+0x6a/0x110
[<ffffffff8121b5a1>] internal_create_group+0xe1/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff880758bbb6f8 (size 64):
comm "mount", pid 20762, jiffies 4295160425 (age 1117.192s)
hex dump (first 32 bytes):
34 62 31 39 39 65 37 35 2d 30 62 31 32 2d 34 34 4b199e75-0b12-44
64 39 2d 61 31 61 34 2d 31 32 39 31 66 37 63 30 d9-a1a4-1291f7c0
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
[<ffffffff81157102>] kstrdup+0x42/0x70
[<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
[<ffffffff813e3416>] kobject_add_internal+0x96/0x210
[<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
[<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
unreferenced object 0xffff8806649361e8 (size 160):
comm "mount", pid 20762, jiffies 4295160425 (age 1117.192s)
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
[<ffffffff813e3416>] kobject_add_internal+0x96/0x210
[<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
[<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8806b3cf32d0 (size 16):
comm "mount", pid 20762, jiffies 4295160425 (age 1117.192s)
hex dump (first 16 bytes):
66 65 61 74 75 72 65 73 00 6b 6b 6b 6b 6b 6b a5 features.kkkkkk.
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
[<ffffffff81157102>] kstrdup+0x42/0x70
[<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
[<ffffffff8121b51e>] internal_create_group+0x5e/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
unreferenced object 0xffff8806649363d0 (size 160):
comm "mount", pid 20762, jiffies 4295160425 (age 1117.272s)
hex dump (first 32 bytes):
03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff812196e2>] create_dir+0x42/0xd0
[<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
[<ffffffff8121b51e>] internal_create_group+0x5e/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8806649378c8 (size 160):
comm "mount", pid 20762, jiffies 4295160425 (age 1117.272s)
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 b8 4d 72 a0 ff ff ff ff .........Mr.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
[<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
[<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
[<ffffffff8121847a>] sysfs_add_file_mode+0x6a/0x110
[<ffffffff8121b5a1>] internal_create_group+0xe1/0x270
[<ffffffff8121b763>] sysfs_create_group+0x13/0x20
[<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
[<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
[<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
[<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
[<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
[<ffffffff811c1d87>] do_mount+0x237/0xa70
[<ffffffff811c2650>] SyS_mount+0x90/0xe0
[<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
> ---
> fs/btrfs/sysfs.c | 132 ++++++++++++++++++++++++++++++-------------------------
> 1 file changed, 72 insertions(+), 60 deletions(-)
>
> --- a/fs/btrfs/sysfs.c 2013-11-20 14:58:40.907456459 -0500
> +++ b/fs/btrfs/sysfs.c 2013-11-20 16:59:02.359951682 -0500
> @@ -417,28 +417,83 @@ static inline struct btrfs_fs_info *to_f
> return container_of(kobj, struct btrfs_fs_info, super_kobj);
> }
>
> -void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
> +#define NUM_FEATURE_BITS 64
> +static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
> +static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
> +
> +static u64 supported_feature_masks[3] = {
> + [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
> + [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
> + [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP,
> +};
> +
> +static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
> +{
> + int set;
> +
> + for (set = 0; set < FEAT_MAX; set++) {
> + int i;
> + struct attribute *attrs[2];
> + struct attribute_group agroup = {
> + .name = "features",
> + .attrs = attrs,
> + };
> + u64 features = get_features(fs_info, set);
> + features &= ~supported_feature_masks[set];
> +
> + if (!features)
> + continue;
> +
> + attrs[1] = NULL;
> + for (i = 0; i < NUM_FEATURE_BITS; i++) {
> + struct btrfs_feature_attr *fa;
> +
> + if (!(features & (1ULL << i)))
> + continue;
> +
> + fa = &btrfs_feature_attrs[set][i];
> + attrs[0] = &fa->kobj_attr.attr;
> + if (add) {
> + int ret;
> + ret = sysfs_merge_group(&fs_info->super_kobj,
> + &agroup);
> + if (ret)
> + return ret;
> + } else
> + sysfs_unmerge_group(&fs_info->super_kobj,
> + &agroup);
> + }
> +
> + }
> + return 0;
> +}
> +
> +static void __btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
> {
> - sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
> - kobject_del(fs_info->device_dir_kobj);
> - kobject_put(fs_info->device_dir_kobj);
> - kobject_del(fs_info->space_info_kobj);
> - kobject_put(fs_info->space_info_kobj);
> kobject_del(&fs_info->super_kobj);
> kobject_put(&fs_info->super_kobj);
> wait_for_completion(&fs_info->kobj_unregister);
> }
>
> +void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
> +{
> + if (fs_info->space_info_kobj) {
> + sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
> + kobject_del(fs_info->space_info_kobj);
> + kobject_put(fs_info->space_info_kobj);
> + }
> + kobject_del(fs_info->device_dir_kobj);
> + kobject_put(fs_info->device_dir_kobj);
> + addrm_unknown_feature_attrs(fs_info, false);
> + __btrfs_sysfs_remove_one(fs_info);
> +}
> +
> const char * const btrfs_feature_set_names[3] = {
> [FEAT_COMPAT] = "compat",
> [FEAT_COMPAT_RO] = "compat_ro",
> [FEAT_INCOMPAT] = "incompat",
> };
>
> -#define NUM_FEATURE_BITS 64
> -static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
> -static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
> -
> char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags)
> {
> size_t bufsize = 4096; /* safe max, 64 names * 64 bytes */
> @@ -508,53 +563,6 @@ static void init_feature_attrs(void)
> }
> }
>
> -static u64 supported_feature_masks[3] = {
> - [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
> - [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
> - [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP,
> -};
> -
> -static int add_unknown_feature_attrs(struct btrfs_fs_info *fs_info)
> -{
> - int set;
> -
> - for (set = 0; set < FEAT_MAX; set++) {
> - int i, count, ret, index = 0;
> - struct attribute **attrs;
> - struct attribute_group agroup = {
> - .name = "features",
> - };
> - u64 features = get_features(fs_info, set);
> - features &= ~supported_feature_masks[set];
> -
> - count = hweight64(features);
> -
> - if (!count)
> - continue;
> -
> - attrs = kcalloc(count + 1, sizeof(void *), GFP_KERNEL);
> -
> - for (i = 0; i < NUM_FEATURE_BITS; i++) {
> - struct btrfs_feature_attr *fa;
> -
> - if (!(features & (1ULL << i)))
> - continue;
> -
> - fa = &btrfs_feature_attrs[set][i];
> - attrs[index++] = &fa->kobj_attr.attr;
> - }
> -
> - attrs[index] = NULL;
> - agroup.attrs = attrs;
> -
> - ret = sysfs_merge_group(&fs_info->super_kobj, &agroup);
> - kfree(attrs);
> - if (ret)
> - return ret;
> - }
> - return 0;
> -}
> -
> static int add_device_membership(struct btrfs_fs_info *fs_info)
> {
> int error = 0;
> @@ -590,13 +598,17 @@ int btrfs_sysfs_add_one(struct btrfs_fs_
> fs_info->super_kobj.kset = btrfs_kset;
> error = kobject_init_and_add(&fs_info->super_kobj, &btrfs_ktype, NULL,
> "%pU", fs_info->fsid);
> + if (error)
> + return error;
>
> error = sysfs_create_group(&fs_info->super_kobj,
> &btrfs_feature_attr_group);
> - if (error)
> - goto failure;
> + if (error) {
> + __btrfs_sysfs_remove_one(fs_info);
> + return error;
> + }
>
> - error = add_unknown_feature_attrs(fs_info);
> + error = addrm_unknown_feature_attrs(fs_info, true);
> if (error)
> goto failure;
>
>
>
> --
> Jeff Mahoney
> SUSE Labs
--
Filipe David Manana,
"Reasonable men adapt themselves to the world.
Unreasonable men adapt the world to themselves.
That's why all progress depends on unreasonable men."
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] btrfs: fix leaks during sysfs teardown
2013-11-21 13:07 ` Filipe David Manana
@ 2013-11-21 15:05 ` Jeff Mahoney
0 siblings, 0 replies; 3+ messages in thread
From: Jeff Mahoney @ 2013-11-21 15:05 UTC (permalink / raw)
To: fdmanana; +Cc: linux-btrfs, Josef Bacik
[-- Attachment #1: Type: text/plain, Size: 21012 bytes --]
On 11/21/13, 8:07 AM, Filipe David Manana wrote:
> On Wed, Nov 20, 2013 at 9:59 PM, Jeff Mahoney <jeffm@suse.com> wrote:
>> Filipe noticed that we were leaking the features attribute group
>> after umount. His fix of just calling sysfs_remove_group() wasn't enough
>> since that removes just the supported features and not the unknown
>> features (but a regular test wouldn't show that).
>>
>> This patch changes the unknown feature handling to add them individually
>> so we can skip the kmalloc and uses the same iteration to tear them down
>> later.
>>
>> We also fix the error handling during mount so that we catch the
>> failing creation of the per-super kobject, and handle proper teardown
>> of a half-setup sysfs context.
>>
>> Reported-by: Filipe David Borba Manana <fdmanana@gmail.com>
>> Signed-off-by: Jeff Mahoney <jeffm@suse.com>
>
> Hi Jeff, I tested this patch (reverted my patch and applied yours) and
> after about 20 minutes of running xfstests I had 169 kmemleak
> warnings, see below some of the stack traces. Thanks.
*sigh*
I missed the original sysfs_remove_group that was the point of all this.
(Well done, Jeff.)
-Jeff
> unreferenced object 0xffff8807424bdb90 (size 64):
> comm "mount", pid 20697, jiffies 4295160287 (age 1117.544s)
> hex dump (first 32 bytes):
> 64 36 61 34 61 30 64 30 2d 39 62 31 63 2d 34 31 d6a4a0d0-9b1c-41
> 37 62 2d 38 31 30 37 2d 34 36 66 32 39 63 30 39 7b-8107-46f29c09
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
> [<ffffffff81157102>] kstrdup+0x42/0x70
> [<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
> [<ffffffff813e3416>] kobject_add_internal+0x96/0x210
> [<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
> [<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> unreferenced object 0xffff8800968254f8 (size 160):
> comm "mount", pid 20697, jiffies 4295160287 (age 1117.544s)
> hex dump (first 32 bytes):
> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
> [<ffffffff813e3416>] kobject_add_internal+0x96/0x210
> [<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
> [<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
> unreferenced object 0xffff8806b3cf22b0 (size 16):
> comm "mount", pid 20697, jiffies 4295160287 (age 1117.544s)
> hex dump (first 16 bytes):
> 66 65 61 74 75 72 65 73 00 6b 6b 6b 6b 6b 6b a5 features.kkkkkk.
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
> [<ffffffff81157102>] kstrdup+0x42/0x70
> [<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
> [<ffffffff8121b51e>] internal_create_group+0x5e/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> unreferenced object 0xffff880096825310 (size 160):
> comm "mount", pid 20697, jiffies 4295160287 (age 1117.648s)
> hex dump (first 32 bytes):
> 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
> [<ffffffff8121b51e>] internal_create_group+0x5e/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
> unreferenced object 0xffff880096824b70 (size 160):
> comm "mount", pid 20697, jiffies 4295160287 (age 1117.648s)
> hex dump (first 32 bytes):
> 01 00 00 00 00 00 00 00 b8 4d 72 a0 ff ff ff ff .........Mr.....
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff8121847a>] sysfs_add_file_mode+0x6a/0x110
> [<ffffffff8121b5a1>] internal_create_group+0xe1/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
> unreferenced object 0xffff880096825128 (size 160):
> comm "mount", pid 20697, jiffies 4295160287 (age 1117.648s)
> hex dump (first 32 bytes):
> 01 00 00 00 00 00 00 00 38 4f 72 a0 ff ff ff ff ........8Or.....
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff8121847a>] sysfs_add_file_mode+0x6a/0x110
> [<ffffffff8121b5a1>] internal_create_group+0xe1/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
> unreferenced object 0xffff880758bbb6f8 (size 64):
> comm "mount", pid 20762, jiffies 4295160425 (age 1117.192s)
> hex dump (first 32 bytes):
> 34 62 31 39 39 65 37 35 2d 30 62 31 32 2d 34 34 4b199e75-0b12-44
> 64 39 2d 61 31 61 34 2d 31 32 39 31 66 37 63 30 d9-a1a4-1291f7c0
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
> [<ffffffff81157102>] kstrdup+0x42/0x70
> [<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
> [<ffffffff813e3416>] kobject_add_internal+0x96/0x210
> [<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
> [<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> unreferenced object 0xffff8806649361e8 (size 160):
> comm "mount", pid 20762, jiffies 4295160425 (age 1117.192s)
> hex dump (first 32 bytes):
> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219aa9>] sysfs_create_dir+0x89/0xe0
> [<ffffffff813e3416>] kobject_add_internal+0x96/0x210
> [<ffffffff813e37a3>] kobject_init_and_add+0x63/0x90
> [<ffffffffa06adadd>] btrfs_sysfs_add_one+0x7d/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
> unreferenced object 0xffff8806b3cf32d0 (size 16):
> comm "mount", pid 20762, jiffies 4295160425 (age 1117.192s)
> hex dump (first 16 bytes):
> 66 65 61 74 75 72 65 73 00 6b 6b 6b 6b 6b 6b a5 features.kkkkkk.
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8119061b>] __kmalloc_track_caller+0x1cb/0x240
> [<ffffffff81157102>] kstrdup+0x42/0x70
> [<ffffffff81219271>] sysfs_new_dirent+0x31/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
> [<ffffffff8121b51e>] internal_create_group+0x5e/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> unreferenced object 0xffff8806649363d0 (size 160):
> comm "mount", pid 20762, jiffies 4295160425 (age 1117.272s)
> hex dump (first 32 bytes):
> 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff812196e2>] create_dir+0x42/0xd0
> [<ffffffff81219a0f>] sysfs_create_subdir+0x1f/0x30
> [<ffffffff8121b51e>] internal_create_group+0x5e/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
> unreferenced object 0xffff8806649378c8 (size 160):
> comm "mount", pid 20762, jiffies 4295160425 (age 1117.272s)
> hex dump (first 32 bytes):
> 01 00 00 00 00 00 00 00 b8 4d 72 a0 ff ff ff ff .........Mr.....
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<ffffffff8175f606>] kmemleak_alloc+0x26/0x50
> [<ffffffff8118f294>] kmem_cache_alloc+0x114/0x200
> [<ffffffff81219291>] sysfs_new_dirent+0x51/0x130
> [<ffffffff8121847a>] sysfs_add_file_mode+0x6a/0x110
> [<ffffffff8121b5a1>] internal_create_group+0xe1/0x270
> [<ffffffff8121b763>] sysfs_create_group+0x13/0x20
> [<ffffffffa06adb07>] btrfs_sysfs_add_one+0xa7/0x1b0 [btrfs]
> [<ffffffffa0693792>] open_ctree+0x17d2/0x21f0 [btrfs]
> [<ffffffffa066983a>] btrfs_mount+0x53a/0x7d0 [btrfs]
> [<ffffffff811a3ae3>] mount_fs+0x43/0x1b0
> [<ffffffff811bfa66>] vfs_kern_mount+0x76/0x120
> [<ffffffff811c1d87>] do_mount+0x237/0xa70
> [<ffffffff811c2650>] SyS_mount+0x90/0xe0
> [<ffffffff8177ef12>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
>
>
>
>> ---
>> fs/btrfs/sysfs.c | 132 ++++++++++++++++++++++++++++++-------------------------
>> 1 file changed, 72 insertions(+), 60 deletions(-)
>>
>> --- a/fs/btrfs/sysfs.c 2013-11-20 14:58:40.907456459 -0500
>> +++ b/fs/btrfs/sysfs.c 2013-11-20 16:59:02.359951682 -0500
>> @@ -417,28 +417,83 @@ static inline struct btrfs_fs_info *to_f
>> return container_of(kobj, struct btrfs_fs_info, super_kobj);
>> }
>>
>> -void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
>> +#define NUM_FEATURE_BITS 64
>> +static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
>> +static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
>> +
>> +static u64 supported_feature_masks[3] = {
>> + [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
>> + [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
>> + [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP,
>> +};
>> +
>> +static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
>> +{
>> + int set;
>> +
>> + for (set = 0; set < FEAT_MAX; set++) {
>> + int i;
>> + struct attribute *attrs[2];
>> + struct attribute_group agroup = {
>> + .name = "features",
>> + .attrs = attrs,
>> + };
>> + u64 features = get_features(fs_info, set);
>> + features &= ~supported_feature_masks[set];
>> +
>> + if (!features)
>> + continue;
>> +
>> + attrs[1] = NULL;
>> + for (i = 0; i < NUM_FEATURE_BITS; i++) {
>> + struct btrfs_feature_attr *fa;
>> +
>> + if (!(features & (1ULL << i)))
>> + continue;
>> +
>> + fa = &btrfs_feature_attrs[set][i];
>> + attrs[0] = &fa->kobj_attr.attr;
>> + if (add) {
>> + int ret;
>> + ret = sysfs_merge_group(&fs_info->super_kobj,
>> + &agroup);
>> + if (ret)
>> + return ret;
>> + } else
>> + sysfs_unmerge_group(&fs_info->super_kobj,
>> + &agroup);
>> + }
>> +
>> + }
>> + return 0;
>> +}
>> +
>> +static void __btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
>> {
>> - sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
>> - kobject_del(fs_info->device_dir_kobj);
>> - kobject_put(fs_info->device_dir_kobj);
>> - kobject_del(fs_info->space_info_kobj);
>> - kobject_put(fs_info->space_info_kobj);
>> kobject_del(&fs_info->super_kobj);
>> kobject_put(&fs_info->super_kobj);
>> wait_for_completion(&fs_info->kobj_unregister);
>> }
>>
>> +void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
>> +{
>> + if (fs_info->space_info_kobj) {
>> + sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
>> + kobject_del(fs_info->space_info_kobj);
>> + kobject_put(fs_info->space_info_kobj);
>> + }
>> + kobject_del(fs_info->device_dir_kobj);
>> + kobject_put(fs_info->device_dir_kobj);
>> + addrm_unknown_feature_attrs(fs_info, false);
>> + __btrfs_sysfs_remove_one(fs_info);
>> +}
>> +
>> const char * const btrfs_feature_set_names[3] = {
>> [FEAT_COMPAT] = "compat",
>> [FEAT_COMPAT_RO] = "compat_ro",
>> [FEAT_INCOMPAT] = "incompat",
>> };
>>
>> -#define NUM_FEATURE_BITS 64
>> -static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
>> -static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
>> -
>> char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags)
>> {
>> size_t bufsize = 4096; /* safe max, 64 names * 64 bytes */
>> @@ -508,53 +563,6 @@ static void init_feature_attrs(void)
>> }
>> }
>>
>> -static u64 supported_feature_masks[3] = {
>> - [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP,
>> - [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
>> - [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP,
>> -};
>> -
>> -static int add_unknown_feature_attrs(struct btrfs_fs_info *fs_info)
>> -{
>> - int set;
>> -
>> - for (set = 0; set < FEAT_MAX; set++) {
>> - int i, count, ret, index = 0;
>> - struct attribute **attrs;
>> - struct attribute_group agroup = {
>> - .name = "features",
>> - };
>> - u64 features = get_features(fs_info, set);
>> - features &= ~supported_feature_masks[set];
>> -
>> - count = hweight64(features);
>> -
>> - if (!count)
>> - continue;
>> -
>> - attrs = kcalloc(count + 1, sizeof(void *), GFP_KERNEL);
>> -
>> - for (i = 0; i < NUM_FEATURE_BITS; i++) {
>> - struct btrfs_feature_attr *fa;
>> -
>> - if (!(features & (1ULL << i)))
>> - continue;
>> -
>> - fa = &btrfs_feature_attrs[set][i];
>> - attrs[index++] = &fa->kobj_attr.attr;
>> - }
>> -
>> - attrs[index] = NULL;
>> - agroup.attrs = attrs;
>> -
>> - ret = sysfs_merge_group(&fs_info->super_kobj, &agroup);
>> - kfree(attrs);
>> - if (ret)
>> - return ret;
>> - }
>> - return 0;
>> -}
>> -
>> static int add_device_membership(struct btrfs_fs_info *fs_info)
>> {
>> int error = 0;
>> @@ -590,13 +598,17 @@ int btrfs_sysfs_add_one(struct btrfs_fs_
>> fs_info->super_kobj.kset = btrfs_kset;
>> error = kobject_init_and_add(&fs_info->super_kobj, &btrfs_ktype, NULL,
>> "%pU", fs_info->fsid);
>> + if (error)
>> + return error;
>>
>> error = sysfs_create_group(&fs_info->super_kobj,
>> &btrfs_feature_attr_group);
>> - if (error)
>> - goto failure;
>> + if (error) {
>> + __btrfs_sysfs_remove_one(fs_info);
>> + return error;
>> + }
>>
>> - error = add_unknown_feature_attrs(fs_info);
>> + error = addrm_unknown_feature_attrs(fs_info, true);
>> if (error)
>> goto failure;
>>
>>
>>
>> --
>> Jeff Mahoney
>> SUSE Labs
>
>
>
--
Jeff Mahoney
SUSE Labs
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 841 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-11-21 15:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-20 21:59 [PATCH] btrfs: fix leaks during sysfs teardown Jeff Mahoney
2013-11-21 13:07 ` Filipe David Manana
2013-11-21 15:05 ` Jeff Mahoney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).