take private bits of reiserfs_xattr.h to fs/reiserfs/xattr.h
[linux-2.6.git] / fs / reiserfs / journal.c
index e2fce51..c3cf54f 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ** Write ahead logging implementation copyright Chris Mason 2000
 **
-** The background commits make this code very interelated, and
+** The background commits make this code very interrelated, and
 ** overly complex.  I need to rethink things a bit....The major players:
 **
 ** journal_begin -- call with the number of blocks you expect to log.
@@ -43,7 +43,6 @@
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/workqueue.h>
 #include <linux/writeback.h>
@@ -292,14 +291,13 @@ int reiserfs_allocate_list_bitmaps(struct super_block *sb,
        for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
                jb = jb_array + i;
                jb->journal_list = NULL;
-               jb->bitmaps = vmalloc(mem);
+               jb->bitmaps = vzalloc(mem);
                if (!jb->bitmaps) {
                        reiserfs_warning(sb, "clm-2000", "unable to "
                                         "allocate bitmaps for journal lists");
                        failed = 1;
                        break;
                }
-               memset(jb->bitmaps, 0, mem);
        }
        if (failed) {
                free_list_bitmaps(sb, jb_array);
@@ -354,11 +352,10 @@ static struct reiserfs_journal_cnode *allocate_cnodes(int num_cnodes)
        if (num_cnodes <= 0) {
                return NULL;
        }
-       head = vmalloc(num_cnodes * sizeof(struct reiserfs_journal_cnode));
+       head = vzalloc(num_cnodes * sizeof(struct reiserfs_journal_cnode));
        if (!head) {
                return NULL;
        }
-       memset(head, 0, num_cnodes * sizeof(struct reiserfs_journal_cnode));
        head[0].prev = NULL;
        head[0].next = head + 1;
        for (i = 1; i < num_cnodes; i++) {
@@ -679,23 +676,19 @@ struct buffer_chunk {
 static void write_chunk(struct buffer_chunk *chunk)
 {
        int i;
-       get_fs_excl();
        for (i = 0; i < chunk->nr; i++) {
                submit_logged_buffer(chunk->bh[i]);
        }
        chunk->nr = 0;
-       put_fs_excl();
 }
 
 static void write_ordered_chunk(struct buffer_chunk *chunk)
 {
        int i;
-       get_fs_excl();
        for (i = 0; i < chunk->nr; i++) {
                submit_ordered_buffer(chunk->bh[i]);
        }
        chunk->nr = 0;
-       put_fs_excl();
 }
 
 static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
@@ -987,8 +980,6 @@ static int flush_commit_list(struct super_block *s,
                return 0;
        }
 
-       get_fs_excl();
-
        /* before we can put our commit blocks on disk, we have to make sure everyone older than
         ** us is on disk too
         */
@@ -1146,7 +1137,6 @@ static int flush_commit_list(struct super_block *s,
        if (retval)
                reiserfs_abort(s, retval, "Journal write error in %s",
                               __func__);
-       put_fs_excl();
        return retval;
 }
 
@@ -1375,8 +1365,6 @@ static int flush_journal_list(struct super_block *s,
                return 0;
        }
 
-       get_fs_excl();
-
        /* if all the work is already done, get out of here */
        if (atomic_read(&(jl->j_nonzerolen)) <= 0 &&
            atomic_read(&(jl->j_commit_left)) <= 0) {
@@ -1598,7 +1586,6 @@ static int flush_journal_list(struct super_block *s,
        put_journal_list(s, jl);
        if (flushall)
                mutex_unlock(&journal->j_flush_mutex);
-       put_fs_excl();
        return err;
 }
 
@@ -2691,28 +2678,19 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
        char b[BDEVNAME_SIZE];
        int ret;
 
-       /*
-        * Unlock here to avoid various RECLAIM-FS-ON <-> IN-RECLAIM-FS
-        * dependency inversion warnings.
-        */
-       reiserfs_write_unlock(sb);
-       journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal));
+       journal = SB_JOURNAL(sb) = vzalloc(sizeof(struct reiserfs_journal));
        if (!journal) {
                reiserfs_warning(sb, "journal-1256",
                                 "unable to get memory for journal structure");
-               reiserfs_write_lock(sb);
                return 1;
        }
-       memset(journal, 0, sizeof(struct reiserfs_journal));
        INIT_LIST_HEAD(&journal->j_bitmap_nodes);
        INIT_LIST_HEAD(&journal->j_prealloc_list);
        INIT_LIST_HEAD(&journal->j_working_list);
        INIT_LIST_HEAD(&journal->j_journal_list);
        journal->j_persistent_trans = 0;
-       ret = reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap,
-                                          reiserfs_bmap_count(sb));
-       reiserfs_write_lock(sb);
-       if (ret)
+       if (reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap,
+                                          reiserfs_bmap_count(sb)))
                goto free_and_return;
 
        allocate_bitmap_nodes(sb);
@@ -2726,7 +2704,7 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
                                                 REISERFS_DISK_OFFSET_IN_BYTES /
                                                 sb->s_blocksize + 2);
 
-       /* Sanity check to see is the standard journal fitting withing first bitmap
+       /* Sanity check to see is the standard journal fitting within first bitmap
           (actual for small blocksizes) */
        if (!SB_ONDISK_JOURNAL_DEVICE(sb) &&
            (SB_JOURNAL_1st_RESERVED_BLOCK(sb) +
@@ -2741,27 +2719,11 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
                goto free_and_return;
        }
 
-       /*
-        * We need to unlock here to avoid creating the following
-        * dependency:
-        * reiserfs_lock -> sysfs_mutex
-        * Because the reiserfs mmap path creates the following dependency:
-        * mm->mmap -> reiserfs_lock, hence we have
-        * mm->mmap -> reiserfs_lock ->sysfs_mutex
-        * This would ends up in a circular dependency with sysfs readdir path
-        * which does sysfs_mutex -> mm->mmap_sem
-        * This is fine because the reiserfs lock is useless in mount path,
-        * at least until we call journal_begin. We keep it for paranoid
-        * reasons.
-        */
-       reiserfs_write_unlock(sb);
        if (journal_init_dev(sb, journal, j_dev_name) != 0) {
-               reiserfs_write_lock(sb);
                reiserfs_warning(sb, "sh-462",
                                 "unable to initialize jornal device");
                goto free_and_return;
        }
-       reiserfs_write_lock(sb);
 
        rs = SB_DISK_SUPER_BLOCK(sb);
 
@@ -2843,9 +2805,7 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
        journal->j_mount_id = 10;
        journal->j_state = 0;
        atomic_set(&(journal->j_jlock), 0);
-       reiserfs_write_unlock(sb);
        journal->j_cnode_free_list = allocate_cnodes(num_cnodes);
-       reiserfs_write_lock(sb);
        journal->j_cnode_free_orig = journal->j_cnode_free_list;
        journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0;
        journal->j_cnode_used = 0;
@@ -2862,24 +2822,37 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
 
        init_journal_hash(sb);
        jl = journal->j_current_jl;
+
+       /*
+        * get_list_bitmap() may call flush_commit_list() which
+        * requires the lock. Calling flush_commit_list() shouldn't happen
+        * this early but I like to be paranoid.
+        */
+       reiserfs_write_lock(sb);
        jl->j_list_bitmap = get_list_bitmap(sb, jl);
+       reiserfs_write_unlock(sb);
        if (!jl->j_list_bitmap) {
                reiserfs_warning(sb, "journal-2005",
                                 "get_list_bitmap failed for journal list 0");
                goto free_and_return;
        }
-       if (journal_read(sb) < 0) {
+
+       /*
+        * Journal_read needs to be inspected in order to push down
+        * the lock further inside (or even remove it).
+        */
+       reiserfs_write_lock(sb);
+       ret = journal_read(sb);
+       reiserfs_write_unlock(sb);
+       if (ret < 0) {
                reiserfs_warning(sb, "reiserfs-2006",
                                 "Replay Failure, unable to mount");
                goto free_and_return;
        }
 
        reiserfs_mounted_fs_count++;
-       if (reiserfs_mounted_fs_count <= 1) {
-               reiserfs_write_unlock(sb);
-               commit_wq = create_workqueue("reiserfs");
-               reiserfs_write_lock(sb);
-       }
+       if (reiserfs_mounted_fs_count <= 1)
+               commit_wq = alloc_workqueue("reiserfs", WQ_MEM_RECLAIM, 0);
 
        INIT_DELAYED_WORK(&journal->j_work, flush_async_commits);
        journal->j_work_sb = sb;
@@ -2910,14 +2883,13 @@ int journal_transaction_should_end(struct reiserfs_transaction_handle *th,
            journal->j_cnode_free < (journal->j_trans_max * 3)) {
                return 1;
        }
-       /* protected by the BKL here */
+
        journal->j_len_alloc += new_alloc;
        th->t_blocks_allocated += new_alloc ;
        return 0;
 }
 
-/* this must be called inside a transaction, and requires the
-** kernel_lock to be held
+/* this must be called inside a transaction
 */
 void reiserfs_block_writes(struct reiserfs_transaction_handle *th)
 {
@@ -2928,8 +2900,7 @@ void reiserfs_block_writes(struct reiserfs_transaction_handle *th)
        return;
 }
 
-/* this must be called without a transaction started, and does not
-** require BKL
+/* this must be called without a transaction started
 */
 void reiserfs_allow_writes(struct super_block *s)
 {
@@ -2938,8 +2909,7 @@ void reiserfs_allow_writes(struct super_block *s)
        wake_up(&journal->j_join_wait);
 }
 
-/* this must be called without a transaction started, and does not
-** require BKL
+/* this must be called without a transaction started
 */
 void reiserfs_wait_on_write_block(struct super_block *s)
 {
@@ -3109,7 +3079,6 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
        th->t_trans_id = journal->j_trans_id;
        unlock_journal(sb);
        INIT_LIST_HEAD(&th->t_list);
-       get_fs_excl();
        return 0;
 
       out_fail:
@@ -3965,7 +3934,6 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
        flush = flags & FLUSH_ALL;
        wait_on_commit = flags & WAIT;
 
-       put_fs_excl();
        current->journal_info = th->t_handle_save;
        reiserfs_check_lock_depth(sb, "journal end");
        if (journal->j_len == 0) {
@@ -4317,4 +4285,3 @@ void reiserfs_abort_journal(struct super_block *sb, int errno)
        dump_stack();
 #endif
 }
-