From 8c85e125124a473d6f3e9bb187b0b84207f81d91 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 28 Apr 2009 18:00:26 +0200 Subject: remove ->write_super call in generic_shutdown_super We just did a full fs writeout using sync_filesystem before, and if that's not enough for the filesystem it can perform it's own writeout in ->put_super, which many filesystems already do. Move a call to foofs_write_super into every foofs_put_super for now to guarantee identical behaviour until it's cleaned up by the individual filesystem maintainers. Exceptions: - affs already has identical copy & pasted code at the beginning of affs_put_super so no need to do it twice. - xfs does the right thing without it and I have changes pending for the xfs tree touching this are so I don't really need conflicts here.. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/nilfs2/super.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 6989b03e97a..7901d8cbb9b 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -65,6 +65,7 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem " "(NILFS)"); MODULE_LICENSE("GPL"); +static void nilfs_write_super(struct super_block *sb); static int nilfs_remount(struct super_block *sb, int *flags, char *data); static int test_exclusive_mount(struct file_system_type *fs_type, struct block_device *bdev, int flags); @@ -315,6 +316,9 @@ static void nilfs_put_super(struct super_block *sb) struct nilfs_sb_info *sbi = NILFS_SB(sb); struct the_nilfs *nilfs = sbi->s_nilfs; + if (sb->s_dirt) + nilfs_write_super(sb); + nilfs_detach_segment_constructor(sbi); if (!(sb->s_flags & MS_RDONLY)) { -- cgit v1.2.3 From 6cfd0148425e528b859b26e436b01f23f6926224 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 5 May 2009 15:40:36 +0200 Subject: push BKL down into ->put_super Move BKL into ->put_super from the only caller. A couple of filesystems had trivial enough ->put_super (only kfree and NULLing of s_fs_info + stuff in there) to not get any locking: coda, cramfs, efs, hugetlbfs, omfs, qnx4, shmem, all others got the full treatment. Most of them probably don't need it, but I'd rather sort that out individually. Preferably after all the other BKL pushdowns in that area. [AV: original used to move lock_super() down as well; these changes are removed since we don't do lock_super() at all in generic_shutdown_super() now] [AV: fuse, btrfs and xfs are known to need no damn BKL, exempt] Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/nilfs2/super.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 7901d8cbb9b..7262e8427c2 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -316,6 +316,8 @@ static void nilfs_put_super(struct super_block *sb) struct nilfs_sb_info *sbi = NILFS_SB(sb); struct the_nilfs *nilfs = sbi->s_nilfs; + lock_kernel(); + if (sb->s_dirt) nilfs_write_super(sb); @@ -333,6 +335,8 @@ static void nilfs_put_super(struct super_block *sb) sbi->s_super = NULL; sb->s_fs_info = NULL; kfree(sbi); + + unlock_kernel(); } /** -- cgit v1.2.3 From 337eb00a2c3a421999c39c94ce7e33545ee8baa7 Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Tue, 12 May 2009 15:10:54 +0200 Subject: Push BKL down into ->remount_fs() [xfs, btrfs, capifs, shmem don't need BKL, exempt] Signed-off-by: Alessio Igor Bogani Signed-off-by: Al Viro --- fs/nilfs2/super.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 7262e8427c2..11151eaa2c4 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -906,6 +906,8 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) struct nilfs_mount_options old_opts; int err; + lock_kernel(); + old_sb_flags = sb->s_flags; old_opts.mount_opt = sbi->s_mount_opt; old_opts.snapshot_cno = sbi->s_snapshot_cno; @@ -985,6 +987,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) up(&sb->s_bdev->bd_mount_sem); } out: + unlock_kernel(); return 0; rw_remount_failed: @@ -993,6 +996,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.mount_opt; sbi->s_snapshot_cno = old_opts.snapshot_cno; + unlock_kernel(); return err; } -- cgit v1.2.3 From d731e06323cb705003e4172ec209e469be4c18e1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Jun 2009 10:08:36 +0200 Subject: nilfs2: call nilfs2_write_super from nilfs2_sync_fs The call to ->write_super from __sync_filesystem will go away, so make sure nilfs2 performs the same actions from inside ->sync_fs. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/nilfs2/super.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 11151eaa2c4..122dc1e489f 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -391,6 +391,8 @@ static int nilfs_sync_fs(struct super_block *sb, int wait) { int err = 0; + nilfs_write_super(sb); + /* This function is called when super block should be written back */ if (wait) err = nilfs_construct_segment(sb); -- cgit v1.2.3 From 81fc20bd0e75ba6357bce2403767d7c2585d8f28 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 8 Jun 2009 01:39:28 +0900 Subject: nilfs2: remove meaningless EBUSY case from nilfs_get_sb function The following EBUSY case in nilfs_get_sb() is meaningless. Indeed, this error code is never returned to the caller. if (!s->s_root) { ... } else if (!(s->s_flags & MS_RDONLY)) { err = -EBUSY; } This simply removes the else case. Signed-off-by: Ryusuke Konishi Signed-off-by: Al Viro --- fs/nilfs2/super.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 122dc1e489f..1c505d0e031 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1186,8 +1186,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, s->s_flags |= MS_ACTIVE; need_to_close = 0; - } else if (!(s->s_flags & MS_RDONLY)) { - err = -EBUSY; } up(&sd.bdev->bd_mount_sem); -- cgit v1.2.3 From 33c8e57c86d1bd1548c12a4f7c4bceb94b862cca Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 8 Jun 2009 01:39:29 +0900 Subject: nilfs2: get rid of sget use for acquiring nilfs object This will change the way to obtain nilfs object in nilfs_get_sb() function. Previously, a preliminary sget() call was performed, and the nilfs object was acquired from a super block instance found by the sget() call. This patch, instead, instroduces a new dedicated function find_or_create_nilfs(); as the name implies, the function finds an existent nilfs object from a global list or creates a new one if no object is found on the device. Signed-off-by: Ryusuke Konishi Cc: Al Viro Signed-off-by: Al Viro --- fs/nilfs2/super.c | 80 +++++++++++++------------------------------------------ 1 file changed, 19 insertions(+), 61 deletions(-) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 1c505d0e031..3c9833e3e74 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1059,13 +1059,6 @@ static int nilfs_set_bdev_super(struct super_block *s, void *data) } static int nilfs_test_bdev_super(struct super_block *s, void *data) -{ - struct nilfs_super_data *sd = data; - - return s->s_bdev == sd->bdev; -} - -static int nilfs_test_bdev_super2(struct super_block *s, void *data) { struct nilfs_super_data *sd = data; int ret; @@ -1096,8 +1089,8 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { struct nilfs_super_data sd; - struct super_block *s, *s2; - struct the_nilfs *nilfs = NULL; + struct super_block *s; + struct the_nilfs *nilfs; int err, need_to_close = 1; sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type); @@ -1118,11 +1111,12 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, goto failed; } - /* - * once the super is inserted into the list by sget, s_umount - * will protect the lockfs code from trying to start a snapshot - * while we are mounting - */ + nilfs = find_or_create_nilfs(sd.bdev); + if (!nilfs) { + err = -ENOMEM; + goto failed; + } + down(&sd.bdev->bd_mount_sem); if (!sd.cno && (err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) { @@ -1131,51 +1125,22 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, } /* - * Phase-1: search any existent instance and get the_nilfs + * Search specified snapshot or R/W mode super_block */ - s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd); - if (IS_ERR(s)) - goto error_s; - - if (!s->s_root) { - err = -ENOMEM; - nilfs = alloc_nilfs(sd.bdev); - if (!nilfs) - goto cancel_new; - } else { - struct nilfs_sb_info *sbi = NILFS_SB(s); + if (!sd.cno) + /* trying to get the latest checkpoint. */ + sd.cno = nilfs_last_cno(nilfs); - /* - * s_umount protects super_block from unmount process; - * It covers pointers of nilfs_sb_info and the_nilfs. - */ - nilfs = sbi->s_nilfs; - get_nilfs(nilfs); - up_write(&s->s_umount); - - /* - * Phase-2: search specified snapshot or R/W mode super_block - */ - if (!sd.cno) - /* trying to get the latest checkpoint. */ - sd.cno = nilfs_last_cno(nilfs); - - s2 = sget(fs_type, nilfs_test_bdev_super2, - nilfs_set_bdev_super, &sd); - deactivate_super(s); - /* - * Although deactivate_super() invokes close_bdev_exclusive() at - * kill_block_super(). Here, s is an existent mount; we need - * one more close_bdev_exclusive() call. - */ - s = s2; - if (IS_ERR(s)) - goto error_s; + s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd); + if (IS_ERR(s)) { + err = PTR_ERR(s); + goto failed_unlock; } if (!s->s_root) { char b[BDEVNAME_SIZE]; + /* New superblock instance created */ s->s_flags = flags; strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); sb_set_blocksize(s, block_size(sd.bdev)); @@ -1195,15 +1160,9 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, simple_set_mnt(mnt, s); return 0; - error_s: - up(&sd.bdev->bd_mount_sem); - if (nilfs) - put_nilfs(nilfs); - close_bdev_exclusive(sd.bdev, flags); - return PTR_ERR(s); - failed_unlock: up(&sd.bdev->bd_mount_sem); + put_nilfs(nilfs); failed: close_bdev_exclusive(sd.bdev, flags); @@ -1212,8 +1171,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, cancel_new: /* Abandoning the newly allocated superblock */ up(&sd.bdev->bd_mount_sem); - if (nilfs) - put_nilfs(nilfs); + put_nilfs(nilfs); up_write(&s->s_umount); deactivate_super(s); /* -- cgit v1.2.3 From 3f82ff55168e92859119bf348e9e0bd6714d2fea Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 8 Jun 2009 01:39:30 +0900 Subject: nilfs2: get rid of sget use for checking if current mount is present This stops using sget() for checking if an r/w-mount or an r/o-mount exists on the device. This elimination uses a back pointer to the current mount added to nilfs object. Signed-off-by: Ryusuke Konishi Cc: Al Viro Signed-off-by: Al Viro --- fs/nilfs2/super.c | 92 +++++++++++++++++++------------------------------------ 1 file changed, 32 insertions(+), 60 deletions(-) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 3c9833e3e74..5a8c5e4731b 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -67,8 +67,6 @@ MODULE_LICENSE("GPL"); static void nilfs_write_super(struct super_block *sb); static int nilfs_remount(struct super_block *sb, int *flags, char *data); -static int test_exclusive_mount(struct file_system_type *fs_type, - struct block_device *bdev, int flags); /** * nilfs_error() - report failure condition on a filesystem @@ -329,6 +327,10 @@ static void nilfs_put_super(struct super_block *sb) nilfs_commit_super(sbi, 1); up_write(&nilfs->ns_sem); } + down_write(&nilfs->ns_sem); + if (nilfs->ns_current == sbi) + nilfs->ns_current = NULL; + up_write(&nilfs->ns_sem); nilfs_detach_checkpoint(sbi); put_nilfs(sbi->s_nilfs); @@ -880,6 +882,11 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, goto failed_root; } + down_write(&nilfs->ns_sem); + if (!nilfs_test_opt(sbi, SNAPSHOT)) + nilfs->ns_current = sbi; + up_write(&nilfs->ns_sem); + return 0; failed_root: @@ -958,14 +965,16 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) * by fsck since we originally mounted the partition.) */ down(&sb->s_bdev->bd_mount_sem); - /* Check existing RW-mount */ - if (test_exclusive_mount(sb->s_type, sb->s_bdev, 0)) { + down_read(&nilfs->ns_sem); + if (nilfs->ns_current && nilfs->ns_current != sbi) { printk(KERN_WARNING "NILFS (device %s): couldn't " - "remount because a RW-mount exists.\n", + "remount because an RW-mount exists.\n", sb->s_id); + up_read(&nilfs->ns_sem); err = -EBUSY; goto rw_remount_failed; } + up_read(&nilfs->ns_sem); if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) { printk(KERN_WARNING "NILFS (device %s): couldn't " "remount because the current RO-mount is not " @@ -984,6 +993,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) down_write(&nilfs->ns_sem); nilfs_setup_super(sbi); + nilfs->ns_current = sbi; up_write(&nilfs->ns_sem); up(&sb->s_bdev->bd_mount_sem); @@ -1118,10 +1128,23 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, } down(&sd.bdev->bd_mount_sem); - if (!sd.cno && - (err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) { - err = (err < 0) ? : -EBUSY; - goto failed_unlock; + + if (!sd.cno) { + /* + * Check if an exclusive mount exists or not. + * Snapshot mounts coexist with a current mount + * (i.e. rw-mount or ro-mount), whereas rw-mount and + * ro-mount are mutually exclusive. + */ + down_read(&nilfs->ns_sem); + if (nilfs->ns_current && + ((nilfs->ns_current->s_super->s_flags ^ flags) + & MS_RDONLY)) { + up_read(&nilfs->ns_sem); + err = -EBUSY; + goto failed_unlock; + } + up_read(&nilfs->ns_sem); } /* @@ -1182,57 +1205,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, return err; } -static int nilfs_test_bdev_super3(struct super_block *s, void *data) -{ - struct nilfs_super_data *sd = data; - int ret; - - if (s->s_bdev != sd->bdev) - return 0; - if (down_read_trylock(&s->s_umount)) { - ret = (s->s_flags & MS_RDONLY) && s->s_root && - nilfs_test_opt(NILFS_SB(s), SNAPSHOT); - up_read(&s->s_umount); - if (ret) - return 0; /* ignore snapshot mounts */ - } - return !((sd->flags ^ s->s_flags) & MS_RDONLY); -} - -static int __false_bdev_super(struct super_block *s, void *data) -{ -#if 0 /* XXX: workaround for lock debug. This is not good idea */ - up_write(&s->s_umount); -#endif - return -EFAULT; -} - -/** - * test_exclusive_mount - check whether an exclusive RW/RO mount exists or not. - * fs_type: filesystem type - * bdev: block device - * flag: 0 (check rw-mount) or MS_RDONLY (check ro-mount) - * res: pointer to an integer to store result - * - * This function must be called within a section protected by bd_mount_mutex. - */ -static int test_exclusive_mount(struct file_system_type *fs_type, - struct block_device *bdev, int flags) -{ - struct super_block *s; - struct nilfs_super_data sd = { .flags = flags, .bdev = bdev }; - - s = sget(fs_type, nilfs_test_bdev_super3, __false_bdev_super, &sd); - if (IS_ERR(s)) { - if (PTR_ERR(s) != -EFAULT) - return PTR_ERR(s); - return 0; /* Not found */ - } - up_write(&s->s_umount); - deactivate_super(s); - return 1; /* Found */ -} - struct file_system_type nilfs_fs_type = { .owner = THIS_MODULE, .name = "nilfs2", -- cgit v1.2.3 From 6dd4740662405a68bb229ac2b9e0aeaaf2188bf2 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 8 Jun 2009 01:39:31 +0900 Subject: nilfs2: simplify remaining sget() use This simplifies the test function passed on the remaining sget() callsite in nilfs. Instead of checking mount type (i.e. ro-mount/rw-mount/snapshot mount) in the test function passed to sget(), this patch first looks up the nilfs_sb_info struct which the given mount type matches, and then acquires the super block instance holding the nilfs_sb_info. Signed-off-by: Ryusuke Konishi Cc: Al Viro Signed-off-by: Al Viro --- fs/nilfs2/super.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 5a8c5e4731b..1d1b6e12515 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -336,7 +336,7 @@ static void nilfs_put_super(struct super_block *sb) put_nilfs(sbi->s_nilfs); sbi->s_super = NULL; sb->s_fs_info = NULL; - kfree(sbi); + nilfs_put_sbinfo(sbi); unlock_kernel(); } @@ -785,6 +785,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, get_nilfs(nilfs); sbi->s_nilfs = nilfs; sbi->s_super = sb; + atomic_set(&sbi->s_count, 1); err = init_nilfs(nilfs, sbi, (char *)data); if (err) @@ -902,7 +903,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, failed_sbi: put_nilfs(nilfs); sb->s_fs_info = NULL; - kfree(sbi); + nilfs_put_sbinfo(sbi); return err; } @@ -1014,6 +1015,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) struct nilfs_super_data { struct block_device *bdev; + struct nilfs_sb_info *sbi; __u64 cno; int flags; }; @@ -1071,27 +1073,8 @@ static int nilfs_set_bdev_super(struct super_block *s, void *data) static int nilfs_test_bdev_super(struct super_block *s, void *data) { struct nilfs_super_data *sd = data; - int ret; - - if (s->s_bdev != sd->bdev) - return 0; - - if (!((s->s_flags | sd->flags) & MS_RDONLY)) - return 1; /* Reuse an old R/W-mode super_block */ - - if (s->s_flags & sd->flags & MS_RDONLY) { - if (down_read_trylock(&s->s_umount)) { - ret = s->s_root && - (sd->cno == NILFS_SB(s)->s_snapshot_cno); - up_read(&s->s_umount); - /* - * This path is locked with sb_lock by sget(). - * So, drop_super() causes deadlock. - */ - return ret; - } - } - return 0; + + return sd->sbi && s->s_fs_info == (void *)sd->sbi; } static int @@ -1112,7 +1095,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, * much more information than normal filesystems to identify mount * instance. For snapshot mounts, not only a mount type (ro-mount * or rw-mount) but also a checkpoint number is required. - * The results are passed in sget() using nilfs_super_data. */ sd.cno = 0; sd.flags = flags; @@ -1148,13 +1130,23 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, } /* - * Search specified snapshot or R/W mode super_block + * Find existing nilfs_sb_info struct */ + sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno); + if (!sd.cno) /* trying to get the latest checkpoint. */ sd.cno = nilfs_last_cno(nilfs); + /* + * Get super block instance holding the nilfs_sb_info struct. + * A new instance is allocated if no existing mount is present or + * existing instance has been unmounted. + */ s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd); + if (sd.sbi) + nilfs_put_sbinfo(sd.sbi); + if (IS_ERR(s)) { err = PTR_ERR(s); goto failed_unlock; -- cgit v1.2.3 From e59399d0102c1813cec48db5cebe1750313f88a0 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 8 Jun 2009 01:39:32 +0900 Subject: nilfs2: correct exclusion control in nilfs_remount function nilfs_remount() changes mount state of a superblock instance. Even though nilfs accesses other superblock instances during mount or remount, the mount state was not properly protected in nilfs_remount(). Moreover, nilfs_remount() has a lock order reversal problem; nilfs_get_sb() holds: 1. bdev->bd_mount_sem 2. sb->s_umount (sget acquires) and nilfs_remount() holds: 1. sb->s_umount (locked by the caller in vfs) 2. bdev->bd_mount_sem To avoid these problems, this patch divides a semaphore protecting super block instances from nilfs->ns_sem, and applies it to the mount state protection in nilfs_remount(). With this change, bd_mount_sem use is removed from nilfs_remount() and the lock order reversal will be resolved. And the new rw-semaphore, nilfs->ns_super_sem will properly protect the mount state except the modification from nilfs_error function. Signed-off-by: Ryusuke Konishi Signed-off-by: Al Viro --- fs/nilfs2/super.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 1d1b6e12515..f02762fa8ea 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -327,10 +327,10 @@ static void nilfs_put_super(struct super_block *sb) nilfs_commit_super(sbi, 1); up_write(&nilfs->ns_sem); } - down_write(&nilfs->ns_sem); + down_write(&nilfs->ns_super_sem); if (nilfs->ns_current == sbi) nilfs->ns_current = NULL; - up_write(&nilfs->ns_sem); + up_write(&nilfs->ns_super_sem); nilfs_detach_checkpoint(sbi); put_nilfs(sbi->s_nilfs); @@ -408,9 +408,9 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) struct buffer_head *bh_cp; int err; - down_write(&nilfs->ns_sem); + down_write(&nilfs->ns_super_sem); list_add(&sbi->s_list, &nilfs->ns_supers); - up_write(&nilfs->ns_sem); + up_write(&nilfs->ns_super_sem); sbi->s_ifile = nilfs_mdt_new( nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP); @@ -448,9 +448,9 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) nilfs_mdt_destroy(sbi->s_ifile); sbi->s_ifile = NULL; - down_write(&nilfs->ns_sem); + down_write(&nilfs->ns_super_sem); list_del_init(&sbi->s_list); - up_write(&nilfs->ns_sem); + up_write(&nilfs->ns_super_sem); return err; } @@ -462,9 +462,9 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi) nilfs_mdt_clear(sbi->s_ifile); nilfs_mdt_destroy(sbi->s_ifile); sbi->s_ifile = NULL; - down_write(&nilfs->ns_sem); + down_write(&nilfs->ns_super_sem); list_del_init(&sbi->s_list); - up_write(&nilfs->ns_sem); + up_write(&nilfs->ns_super_sem); } static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi) @@ -883,10 +883,10 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, goto failed_root; } - down_write(&nilfs->ns_sem); + down_write(&nilfs->ns_super_sem); if (!nilfs_test_opt(sbi, SNAPSHOT)) nilfs->ns_current = sbi; - up_write(&nilfs->ns_sem); + up_write(&nilfs->ns_super_sem); return 0; @@ -918,6 +918,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) lock_kernel(); + down_write(&nilfs->ns_super_sem); old_sb_flags = sb->s_flags; old_opts.mount_opt = sbi->s_mount_opt; old_opts.snapshot_cno = sbi->s_snapshot_cno; @@ -965,24 +966,20 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) * store the current valid flag. (It may have been changed * by fsck since we originally mounted the partition.) */ - down(&sb->s_bdev->bd_mount_sem); - down_read(&nilfs->ns_sem); if (nilfs->ns_current && nilfs->ns_current != sbi) { printk(KERN_WARNING "NILFS (device %s): couldn't " "remount because an RW-mount exists.\n", sb->s_id); - up_read(&nilfs->ns_sem); err = -EBUSY; - goto rw_remount_failed; + goto restore_opts; } - up_read(&nilfs->ns_sem); if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) { printk(KERN_WARNING "NILFS (device %s): couldn't " "remount because the current RO-mount is not " "the latest one.\n", sb->s_id); err = -EINVAL; - goto rw_remount_failed; + goto restore_opts; } sb->s_flags &= ~MS_RDONLY; nilfs_clear_opt(sbi, SNAPSHOT); @@ -990,25 +987,24 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) err = nilfs_attach_segment_constructor(sbi); if (err) - goto rw_remount_failed; + goto restore_opts; down_write(&nilfs->ns_sem); nilfs_setup_super(sbi); - nilfs->ns_current = sbi; up_write(&nilfs->ns_sem); - up(&sb->s_bdev->bd_mount_sem); + nilfs->ns_current = sbi; } out: + up_write(&nilfs->ns_super_sem); unlock_kernel(); return 0; - rw_remount_failed: - up(&sb->s_bdev->bd_mount_sem); restore_opts: sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.mount_opt; sbi->s_snapshot_cno = old_opts.snapshot_cno; + up_write(&nilfs->ns_super_sem); unlock_kernel(); return err; } @@ -1118,15 +1114,15 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, * (i.e. rw-mount or ro-mount), whereas rw-mount and * ro-mount are mutually exclusive. */ - down_read(&nilfs->ns_sem); + down_read(&nilfs->ns_super_sem); if (nilfs->ns_current && ((nilfs->ns_current->s_super->s_flags ^ flags) & MS_RDONLY)) { - up_read(&nilfs->ns_sem); + up_read(&nilfs->ns_super_sem); err = -EBUSY; goto failed_unlock; } - up_read(&nilfs->ns_sem); + up_read(&nilfs->ns_super_sem); } /* -- cgit v1.2.3 From aa7dfb8954ccf49e026ba13d12991a4eb7defb96 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 8 Jun 2009 01:39:33 +0900 Subject: nilfs2: get rid of bd_mount_sem use from nilfs This will remove every bd_mount_sem use in nilfs. The intended exclusion control was replaced by the previous patch ("nilfs2: correct exclusion control in nilfs_remount function") for nilfs_remount(), and this patch will replace remains with a new mutex that this inserts in nilfs object. Signed-off-by: Ryusuke Konishi Cc: Christoph Hellwig Signed-off-by: Al Viro --- fs/nilfs2/super.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'fs/nilfs2/super.c') diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index f02762fa8ea..1777a3467bd 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -764,7 +764,7 @@ int nilfs_store_magic_and_option(struct super_block *sb, * @silent: silent mode flag * @nilfs: the_nilfs struct * - * This function is called exclusively by bd_mount_mutex. + * This function is called exclusively by nilfs->ns_mount_mutex. * So, the recovery process is protected from other simultaneous mounts. */ static int @@ -1105,7 +1105,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, goto failed; } - down(&sd.bdev->bd_mount_sem); + mutex_lock(&nilfs->ns_mount_mutex); if (!sd.cno) { /* @@ -1164,7 +1164,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, need_to_close = 0; } - up(&sd.bdev->bd_mount_sem); + mutex_unlock(&nilfs->ns_mount_mutex); put_nilfs(nilfs); if (need_to_close) close_bdev_exclusive(sd.bdev, flags); @@ -1172,7 +1172,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, return 0; failed_unlock: - up(&sd.bdev->bd_mount_sem); + mutex_unlock(&nilfs->ns_mount_mutex); put_nilfs(nilfs); failed: close_bdev_exclusive(sd.bdev, flags); @@ -1181,14 +1181,14 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, cancel_new: /* Abandoning the newly allocated superblock */ - up(&sd.bdev->bd_mount_sem); + mutex_unlock(&nilfs->ns_mount_mutex); put_nilfs(nilfs); up_write(&s->s_umount); deactivate_super(s); /* * deactivate_super() invokes close_bdev_exclusive(). * We must finish all post-cleaning before this call; - * put_nilfs() and unlocking bd_mount_sem need the block device. + * put_nilfs() needs the block device. */ return err; } -- cgit v1.2.3