Skip to content

Commit dd70edb

Browse files
Vyacheslav Dubeykotorvalds
Vyacheslav Dubeyko
authored andcommitted
nilfs2: integrate sysfs support into driver
This patch integrates creation of sysfs groups and attributes into NILFS file system driver. It was found the issue with nilfs_sysfs_{create/delete}_snapshot_group functions by Michael L Semon <mlsemon35@gmail.com> in the first version of the patch: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:579 in_atomic(): 1, irqs_disabled(): 0, pid: 32676, name: umount.nilfs2 2 locks held by umount.nilfs2/32676: #0: (&type->s_umount_key#21){++++..}, at: [<790c18e2>] deactivate_super+0x37/0x58 #1: (&(&nilfs->ns_cptree_lock)->rlock){+.+...}, at: [<791bf659>] nilfs_put_root+0x23/0x5a Preemption disabled at:[<791bf659>] nilfs_put_root+0x23/0x5a CPU: 0 PID: 32676 Comm: umount.nilfs2 Not tainted 3.14.0+ #2 Hardware name: Dell Computer Corporation Dimension 2350/07W080, BIOS A01 12/17/2002 Call Trace: dump_stack+0x4b/0x75 __might_sleep+0x111/0x16f mutex_lock_nested+0x1e/0x3ad kernfs_remove+0x12/0x26 sysfs_remove_dir+0x3d/0x62 kobject_del+0x13/0x38 nilfs_sysfs_delete_snapshot_group+0xb/0xd nilfs_put_root+0x2a/0x5a nilfs_detach_log_writer+0x1ab/0x2c1 nilfs_put_super+0x13/0x68 generic_shutdown_super+0x60/0xd1 kill_block_super+0x1d/0x60 deactivate_locked_super+0x22/0x3f deactivate_super+0x3e/0x58 mntput_no_expire+0xe2/0x141 SyS_oldumount+0x70/0xa5 syscall_call+0x7/0xb The reason of the issue was placement of nilfs_sysfs_{create/delete}_snapshot_group() call under nilfs->ns_cptree_lock protection. But this protection is unnecessary and wrong solution. The second version of the patch fixes this issue. [fengguang.wu@intel.com: nilfs_sysfs_create_mounted_snapshots_group can be static] Reported-by: Michael L. Semon <mlsemon35@gmail.com> Signed-off-by: Vyacheslav Dubeyko <Vyacheslav.Dubeyko@hgst.com> Cc: Vyacheslav Dubeyko <slava@dubeyko.com> Cc: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Tested-by: Michael L. Semon <mlsemon35@gmail.com> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a5a7332 commit dd70edb

File tree

5 files changed

+34
-5
lines changed

5 files changed

+34
-5
lines changed

fs/nilfs2/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ obj-$(CONFIG_NILFS2_FS) += nilfs2.o
22
nilfs2-y := inode.o file.o dir.o super.o namei.o page.o mdt.o \
33
btnode.o bmap.o btree.o direct.o dat.o recovery.o \
44
the_nilfs.o segbuf.o segment.o cpfile.o sufile.o \
5-
ifile.o alloc.o gcinode.o ioctl.o
5+
ifile.o alloc.o gcinode.o ioctl.o sysfs.o

fs/nilfs2/nilfs.h

+8
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,14 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *);
320320
int nilfs_init_gcinode(struct inode *inode);
321321
void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs);
322322

323+
/* sysfs.c */
324+
int __init nilfs_sysfs_init(void);
325+
void nilfs_sysfs_exit(void);
326+
int nilfs_sysfs_create_device_group(struct super_block *);
327+
void nilfs_sysfs_delete_device_group(struct the_nilfs *);
328+
int nilfs_sysfs_create_snapshot_group(struct nilfs_root *);
329+
void nilfs_sysfs_delete_snapshot_group(struct nilfs_root *);
330+
323331
/*
324332
* Inodes and files operations
325333
*/

fs/nilfs2/super.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -1452,13 +1452,19 @@ static int __init init_nilfs_fs(void)
14521452
if (err)
14531453
goto fail;
14541454

1455-
err = register_filesystem(&nilfs_fs_type);
1455+
err = nilfs_sysfs_init();
14561456
if (err)
14571457
goto free_cachep;
14581458

1459+
err = register_filesystem(&nilfs_fs_type);
1460+
if (err)
1461+
goto deinit_sysfs_entry;
1462+
14591463
printk(KERN_INFO "NILFS version 2 loaded\n");
14601464
return 0;
14611465

1466+
deinit_sysfs_entry:
1467+
nilfs_sysfs_exit();
14621468
free_cachep:
14631469
nilfs_destroy_cachep();
14641470
fail:
@@ -1468,6 +1474,7 @@ static int __init init_nilfs_fs(void)
14681474
static void __exit exit_nilfs_fs(void)
14691475
{
14701476
nilfs_destroy_cachep();
1477+
nilfs_sysfs_exit();
14711478
unregister_filesystem(&nilfs_fs_type);
14721479
}
14731480

fs/nilfs2/sysfs.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static struct kobj_type nilfs_##name##_ktype = { \
8787
};
8888

8989
#define NILFS_DEV_INT_GROUP_FNS(name, parent_name) \
90-
int nilfs_sysfs_create_##name##_group(struct the_nilfs *nilfs) \
90+
static int nilfs_sysfs_create_##name##_group(struct the_nilfs *nilfs) \
9191
{ \
9292
struct kobject *parent; \
9393
struct kobject *kobj; \
@@ -106,7 +106,7 @@ int nilfs_sysfs_create_##name##_group(struct the_nilfs *nilfs) \
106106
return err; \
107107
return 0; \
108108
} \
109-
void nilfs_sysfs_delete_##name##_group(struct the_nilfs *nilfs) \
109+
static void nilfs_sysfs_delete_##name##_group(struct the_nilfs *nilfs) \
110110
{ \
111111
kobject_del(&nilfs->ns_##parent_name##_subgroups->sg_##name##_kobj); \
112112
}

fs/nilfs2/the_nilfs.c

+15-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ void destroy_nilfs(struct the_nilfs *nilfs)
9898
{
9999
might_sleep();
100100
if (nilfs_init(nilfs)) {
101+
nilfs_sysfs_delete_device_group(nilfs);
101102
brelse(nilfs->ns_sbh[0]);
102103
brelse(nilfs->ns_sbh[1]);
103104
}
@@ -641,6 +642,10 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
641642
if (err)
642643
goto failed_sbh;
643644

645+
err = nilfs_sysfs_create_device_group(sb);
646+
if (err)
647+
goto failed_sbh;
648+
644649
set_nilfs_init(nilfs);
645650
err = 0;
646651
out:
@@ -741,12 +746,13 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno)
741746
{
742747
struct rb_node **p, *parent;
743748
struct nilfs_root *root, *new;
749+
int err;
744750

745751
root = nilfs_lookup_root(nilfs, cno);
746752
if (root)
747753
return root;
748754

749-
new = kmalloc(sizeof(*root), GFP_KERNEL);
755+
new = kzalloc(sizeof(*root), GFP_KERNEL);
750756
if (!new)
751757
return NULL;
752758

@@ -783,6 +789,12 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno)
783789

784790
spin_unlock(&nilfs->ns_cptree_lock);
785791

792+
err = nilfs_sysfs_create_snapshot_group(new);
793+
if (err) {
794+
kfree(new);
795+
new = NULL;
796+
}
797+
786798
return new;
787799
}
788800

@@ -791,6 +803,8 @@ void nilfs_put_root(struct nilfs_root *root)
791803
if (atomic_dec_and_test(&root->count)) {
792804
struct the_nilfs *nilfs = root->nilfs;
793805

806+
nilfs_sysfs_delete_snapshot_group(root);
807+
794808
spin_lock(&nilfs->ns_cptree_lock);
795809
rb_erase(&root->rb_node, &nilfs->ns_cptree);
796810
spin_unlock(&nilfs->ns_cptree_lock);

0 commit comments

Comments
 (0)