Merge branch 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 Dec 2009 15:58:15 +0000 (07:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 Dec 2009 15:58:15 +0000 (07:58 -0800)
* 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing: (31 commits)
  kill-the-bkl/reiserfs: turn GFP_ATOMIC flag to GFP_NOFS in reiserfs_get_block()
  kill-the-bkl/reiserfs: drop the fs race watchdog from _get_block_create_0()
  kill-the-bkl/reiserfs: definitely drop the bkl from reiserfs_ioctl()
  kill-the-bkl/reiserfs: always lock the ioctl path
  kill-the-bkl/reiserfs: fix reiserfs lock to cpu_add_remove_lock dependency
  kill-the-bkl/reiserfs: Fix induced mm->mmap_sem to sysfs_mutex dependency
  kill-the-bkl/reiserfs: panic in case of lock imbalance
  kill-the-bkl/reiserfs: fix recursive reiserfs write lock in reiserfs_commit_write()
  kill-the-bkl/reiserfs: fix recursive reiserfs lock in reiserfs_mkdir()
  kill-the-bkl/reiserfs: fix "reiserfs lock" / "inode mutex" lock inversion dependency
  kill-the-bkl/reiserfs: move the concurrent tree accesses checks per superblock
  kill-the-bkl/reiserfs: acquire the inode mutex safely
  kill-the-bkl/reiserfs: unlock only when needed in search_by_key
  kill-the-bkl/reiserfs: use mutex_lock in reiserfs_mutex_lock_safe
  kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end()
  kill-the-bkl/reiserfs: reduce number of contentions in search_by_key()
  kill-the-bkl/reiserfs: don't hold the write recursively in reiserfs_lookup()
  kill-the-bkl/reiserfs: lock only once on reiserfs_get_block()
  kill-the-bkl/reiserfs: conditionaly release the write lock on fs_changed()
  kill-the-BKL/reiserfs: add reiserfs_cond_resched()
  ...

1  2 
fs/reiserfs/super.c

diff --combined fs/reiserfs/super.c
index f0ad05f380223736cd9a8a121c59d6f1c7ecd7e3,58727b5b4351c24795e79a75e8406c57b2dc9fbb..339b0baf2af6ed0a721c3aa3b1f4941f633ec59a
@@@ -465,7 -465,7 +465,7 @@@ static void reiserfs_put_super(struct s
        struct reiserfs_transaction_handle th;
        th.t_trans_id = 0;
  
-       lock_kernel();
+       reiserfs_write_lock(s);
  
        if (s->s_dirt)
                reiserfs_write_super(s);
  
        reiserfs_proc_info_done(s);
  
+       reiserfs_write_unlock(s);
+       mutex_destroy(&REISERFS_SB(s)->lock);
        kfree(s->s_fs_info);
        s->s_fs_info = NULL;
-       unlock_kernel();
  }
  
  static struct kmem_cache *reiserfs_inode_cachep;
@@@ -554,25 -554,28 +554,28 @@@ static void reiserfs_dirty_inode(struc
        struct reiserfs_transaction_handle th;
  
        int err = 0;
+       int lock_depth;
        if (inode->i_sb->s_flags & MS_RDONLY) {
                reiserfs_warning(inode->i_sb, "clm-6006",
                                 "writing inode %lu on readonly FS",
                                 inode->i_ino);
                return;
        }
-       reiserfs_write_lock(inode->i_sb);
+       lock_depth = reiserfs_write_lock_once(inode->i_sb);
  
        /* this is really only used for atime updates, so they don't have
         ** to be included in O_SYNC or fsync
         */
        err = journal_begin(&th, inode->i_sb, 1);
-       if (err) {
-               reiserfs_write_unlock(inode->i_sb);
-               return;
-       }
+       if (err)
+               goto out;
        reiserfs_update_sd(&th, inode);
        journal_end(&th, inode->i_sb, 1);
-       reiserfs_write_unlock(inode->i_sb);
+ out:
+       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
  }
  
  #ifdef CONFIG_QUOTA
@@@ -612,7 -615,7 +615,7 @@@ static int reiserfs_mark_dquot_dirty(st
  static int reiserfs_write_info(struct super_block *, int);
  static int reiserfs_quota_on(struct super_block *, int, int, char *, int);
  
 -static struct dquot_operations reiserfs_quota_operations = {
 +static const struct dquot_operations reiserfs_quota_operations = {
        .initialize = dquot_initialize,
        .drop = dquot_drop,
        .alloc_space = dquot_alloc_space,
        .destroy_dquot  = dquot_destroy,
  };
  
 -static struct quotactl_ops reiserfs_qctl_operations = {
 +static const struct quotactl_ops reiserfs_qctl_operations = {
        .quota_on = reiserfs_quota_on,
        .quota_off = vfs_quota_off,
        .quota_sync = vfs_quota_sync,
@@@ -1168,11 -1171,14 +1171,14 @@@ static int reiserfs_remount(struct supe
        unsigned int qfmt = 0;
  #ifdef CONFIG_QUOTA
        int i;
+ #endif
+       reiserfs_write_lock(s);
  
+ #ifdef CONFIG_QUOTA
        memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names));
  #endif
  
-       lock_kernel();
        rs = SB_DISK_SUPER_BLOCK(s);
  
        if (!reiserfs_parse_options
  
  out_ok:
        replace_mount_options(s, new_opts);
-       unlock_kernel();
+       reiserfs_write_unlock(s);
        return 0;
  
  out_err:
        kfree(new_opts);
-       unlock_kernel();
+       reiserfs_write_unlock(s);
        return err;
  }
  
@@@ -1404,7 -1410,9 +1410,9 @@@ static int read_super_block(struct supe
  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;
@@@ -1613,7 -1621,7 +1621,7 @@@ static int reiserfs_fill_super(struct s
        sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
        if (!sbi) {
                errval = -ENOMEM;
-               goto error;
+               goto error_alloc;
        }
        s->s_fs_info = sbi;
        /* Set default values for options: non-aggressive tails, RO on errors */
        /* setup default block allocator options */
        reiserfs_init_alloc_options(s);
  
+       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,
        init_waitqueue_head(&(sbi->s_wait));
        spin_lock_init(&sbi->bitmap_lock);
  
+       reiserfs_write_unlock(s);
        return (0);
  
  error:
+       reiserfs_write_unlock(s);
+ error_alloc:
        if (jinit_done) {       /* kill the commit thread, free journal ram */
                journal_release_error(NULL, s);
        }