]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/super.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / fs / super.c
index ca696155cd9aea65d527af3e8d25a8bdc9cc40f0..7e9dd4cc2c01170d0d7a38035a430e554c90cc57 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/idr.h>
 #include <linux/mutex.h>
 #include <linux/backing-dev.h>
+#include <linux/rculist_bl.h>
 #include "internal.h"
 
 
@@ -71,7 +72,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
                INIT_LIST_HEAD(&s->s_files);
 #endif
                INIT_LIST_HEAD(&s->s_instances);
-               INIT_HLIST_HEAD(&s->s_anon);
+               INIT_HLIST_BL_HEAD(&s->s_anon);
                INIT_LIST_HEAD(&s->s_inodes);
                INIT_LIST_HEAD(&s->s_dentry_lru);
                init_rwsem(&s->s_umount);
@@ -176,6 +177,11 @@ void deactivate_locked_super(struct super_block *s)
        struct file_system_type *fs = s->s_type;
        if (atomic_dec_and_test(&s->s_active)) {
                fs->kill_sb(s);
+               /*
+                * We need to call rcu_barrier so all the delayed rcu free
+                * inodes are flushed before we release the fs module.
+                */
+               rcu_barrier();
                put_filesystem(fs);
                put_super(s);
        } else {
@@ -766,13 +772,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
 {
        struct block_device *bdev;
        struct super_block *s;
-       fmode_t mode = FMODE_READ;
+       fmode_t mode = FMODE_READ | FMODE_EXCL;
        int error = 0;
 
        if (!(flags & MS_RDONLY))
                mode |= FMODE_WRITE;
 
-       bdev = open_bdev_exclusive(dev_name, mode, fs_type);
+       bdev = blkdev_get_by_path(dev_name, mode, fs_type);
        if (IS_ERR(bdev))
                return ERR_CAST(bdev);
 
@@ -801,13 +807,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
 
                /*
                 * s_umount nests inside bd_mutex during
-                * __invalidate_device().  close_bdev_exclusive()
-                * acquires bd_mutex and can't be called under
-                * s_umount.  Drop s_umount temporarily.  This is safe
-                * as we're holding an active reference.
+                * __invalidate_device().  blkdev_put() acquires
+                * bd_mutex and can't be called under s_umount.  Drop
+                * s_umount temporarily.  This is safe as we're
+                * holding an active reference.
                 */
                up_write(&s->s_umount);
-               close_bdev_exclusive(bdev, mode);
+               blkdev_put(bdev, mode);
                down_write(&s->s_umount);
        } else {
                char b[BDEVNAME_SIZE];
@@ -831,7 +837,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
 error_s:
        error = PTR_ERR(s);
 error_bdev:
-       close_bdev_exclusive(bdev, mode);
+       blkdev_put(bdev, mode);
 error:
        return ERR_PTR(error);
 }
@@ -862,7 +868,8 @@ void kill_block_super(struct super_block *sb)
        bdev->bd_super = NULL;
        generic_shutdown_super(sb);
        sync_blockdev(bdev);
-       close_bdev_exclusive(bdev, mode);
+       WARN_ON_ONCE(!(mode & FMODE_EXCL));
+       blkdev_put(bdev, mode | FMODE_EXCL);
 }
 
 EXPORT_SYMBOL(kill_block_super);