Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
[cascardo/linux.git] / fs / reiserfs / super.c
index 1d42e70..e12d8b9 100644 (file)
@@ -1519,9 +1519,7 @@ static int read_super_block(struct super_block *s, int offset)
 static int reread_meta_blocks(struct super_block *s)
 {
        ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
-       reiserfs_write_unlock(s);
        wait_on_buffer(SB_BUFFER_WITH_SB(s));
-       reiserfs_write_lock(s);
        if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
                reiserfs_warning(s, "reiserfs-2504", "error reading the super");
                return 1;
@@ -1746,22 +1744,11 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        mutex_init(&REISERFS_SB(s)->lock);
        REISERFS_SB(s)->lock_depth = -1;
 
-       /*
-        * This function is called with the bkl, which also was the old
-        * locking used here.
-        * do_journal_begin() will soon check if we hold the lock (ie: was the
-        * bkl). This is likely because do_journal_begin() has several another
-        * callers because at this time, it doesn't seem to be necessary to
-        * protect against anything.
-        * Anyway, let's be conservative and lock for now.
-        */
-       reiserfs_write_lock(s);
-
        jdev_name = NULL;
        if (reiserfs_parse_options
            (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name,
             &commit_max_age, qf_names, &qfmt) == 0) {
-               goto error;
+               goto error_unlocked;
        }
        if (jdev_name && jdev_name[0]) {
                REISERFS_SB(s)->s_jdev = kstrdup(jdev_name, GFP_KERNEL);
@@ -1777,7 +1764,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
 
        if (blocks) {
                SWARN(silent, s, "jmacd-7", "resize option for remount only");
-               goto error;
+               goto error_unlocked;
        }
 
        /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
@@ -1787,7 +1774,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) {
                SWARN(silent, s, "sh-2021", "can not find reiserfs on %s",
                      reiserfs_bdevname(s));
-               goto error;
+               goto error_unlocked;
        }
 
        rs = SB_DISK_SUPER_BLOCK(s);
@@ -1803,7 +1790,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
                      "or increase size of your LVM partition");
                SWARN(silent, s, "", "Or may be you forgot to "
                      "reboot after fdisk when it told you to");
-               goto error;
+               goto error_unlocked;
        }
 
        sbi->s_mount_state = SB_REISERFS_STATE(s);
@@ -1811,8 +1798,9 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
 
        if ((errval = reiserfs_init_bitmap_cache(s))) {
                SWARN(silent, s, "jmacd-8", "unable to read bitmap");
-               goto error;
+               goto error_unlocked;
        }
+
        errval = -EINVAL;
 #ifdef CONFIG_REISERFS_CHECK
        SWARN(silent, s, "", "CONFIG_REISERFS_CHECK is set ON");
@@ -1835,24 +1823,26 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        if (reiserfs_barrier_flush(s)) {
                printk("reiserfs: using flush barriers\n");
        }
+
        // set_device_ro(s->s_dev, 1) ;
        if (journal_init(s, jdev_name, old_format, commit_max_age)) {
                SWARN(silent, s, "sh-2022",
                      "unable to initialize journal space");
-               goto error;
+               goto error_unlocked;
        } else {
                jinit_done = 1; /* once this is set, journal_release must be called
                                 ** if we error out of the mount
                                 */
        }
+
        if (reread_meta_blocks(s)) {
                SWARN(silent, s, "jmacd-9",
                      "unable to reread meta blocks after journal init");
-               goto error;
+               goto error_unlocked;
        }
 
        if (replay_only(s))
-               goto error;
+               goto error_unlocked;
 
        if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
                SWARN(silent, s, "clm-7000",
@@ -1866,9 +1856,19 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
                         reiserfs_init_locked_inode, (void *)(&args));
        if (!root_inode) {
                SWARN(silent, s, "jmacd-10", "get root inode failed");
-               goto error;
+               goto error_unlocked;
        }
 
+       /*
+        * This path assumed to be called with the BKL in the old times.
+        * Now we have inherited the big reiserfs lock from it and many
+        * reiserfs helpers called in the mount path and elsewhere require
+        * this lock to be held even if it's not always necessary. Let's be
+        * conservative and hold it early. The window can be reduced after
+        * careful review of the code.
+        */
+       reiserfs_write_lock(s);
+
        if (root_inode->i_state & I_NEW) {
                reiserfs_read_locked_inode(root_inode, &args);
                unlock_new_inode(root_inode);
@@ -1995,12 +1995,16 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        return (0);
 
 error:
-       if (jinit_done) {       /* kill the commit thread, free journal ram */
+       reiserfs_write_unlock(s);
+
+error_unlocked:
+       /* kill the commit thread, free journal ram */
+       if (jinit_done) {
+               reiserfs_write_lock(s);
                journal_release_error(NULL, s);
+               reiserfs_write_unlock(s);
        }
 
-       reiserfs_write_unlock(s);
-
        reiserfs_free_bitmap_cache(s);
        if (SB_BUFFER_WITH_SB(s))
                brelse(SB_BUFFER_WITH_SB(s));