diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/reiserfs/journal.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/reiserfs/journal.c')
-rw-r--r-- | fs/reiserfs/journal.c | 164 |
1 files changed, 122 insertions, 42 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 90622200b39c..19fbc810e8e7 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/blkdev.h> | 50 | #include <linux/blkdev.h> |
51 | #include <linux/backing-dev.h> | 51 | #include <linux/backing-dev.h> |
52 | #include <linux/uaccess.h> | 52 | #include <linux/uaccess.h> |
53 | #include <linux/slab.h> | ||
53 | 54 | ||
54 | #include <asm/system.h> | 55 | #include <asm/system.h> |
55 | 56 | ||
@@ -429,21 +430,6 @@ static void clear_prepared_bits(struct buffer_head *bh) | |||
429 | clear_buffer_journal_restore_dirty(bh); | 430 | clear_buffer_journal_restore_dirty(bh); |
430 | } | 431 | } |
431 | 432 | ||
432 | /* utility function to force a BUG if it is called without the big | ||
433 | ** kernel lock held. caller is the string printed just before calling BUG() | ||
434 | */ | ||
435 | void reiserfs_check_lock_depth(struct super_block *sb, char *caller) | ||
436 | { | ||
437 | #ifdef CONFIG_SMP | ||
438 | if (current->lock_depth < 0) { | ||
439 | reiserfs_panic(sb, "journal-1", "%s called without kernel " | ||
440 | "lock held", caller); | ||
441 | } | ||
442 | #else | ||
443 | ; | ||
444 | #endif | ||
445 | } | ||
446 | |||
447 | /* return a cnode with same dev, block number and size in table, or null if not found */ | 433 | /* return a cnode with same dev, block number and size in table, or null if not found */ |
448 | static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct | 434 | static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct |
449 | super_block | 435 | super_block |
@@ -556,7 +542,8 @@ static inline void insert_journal_hash(struct reiserfs_journal_cnode **table, | |||
556 | static inline void lock_journal(struct super_block *sb) | 542 | static inline void lock_journal(struct super_block *sb) |
557 | { | 543 | { |
558 | PROC_INFO_INC(sb, journal.lock_journal); | 544 | PROC_INFO_INC(sb, journal.lock_journal); |
559 | mutex_lock(&SB_JOURNAL(sb)->j_mutex); | 545 | |
546 | reiserfs_mutex_lock_safe(&SB_JOURNAL(sb)->j_mutex, sb); | ||
560 | } | 547 | } |
561 | 548 | ||
562 | /* unlock the current transaction */ | 549 | /* unlock the current transaction */ |
@@ -708,7 +695,9 @@ static void check_barrier_completion(struct super_block *s, | |||
708 | disable_barrier(s); | 695 | disable_barrier(s); |
709 | set_buffer_uptodate(bh); | 696 | set_buffer_uptodate(bh); |
710 | set_buffer_dirty(bh); | 697 | set_buffer_dirty(bh); |
698 | reiserfs_write_unlock(s); | ||
711 | sync_dirty_buffer(bh); | 699 | sync_dirty_buffer(bh); |
700 | reiserfs_write_lock(s); | ||
712 | } | 701 | } |
713 | } | 702 | } |
714 | 703 | ||
@@ -996,8 +985,13 @@ static int reiserfs_async_progress_wait(struct super_block *s) | |||
996 | { | 985 | { |
997 | DEFINE_WAIT(wait); | 986 | DEFINE_WAIT(wait); |
998 | struct reiserfs_journal *j = SB_JOURNAL(s); | 987 | struct reiserfs_journal *j = SB_JOURNAL(s); |
999 | if (atomic_read(&j->j_async_throttle)) | 988 | |
989 | if (atomic_read(&j->j_async_throttle)) { | ||
990 | reiserfs_write_unlock(s); | ||
1000 | congestion_wait(BLK_RW_ASYNC, HZ / 10); | 991 | congestion_wait(BLK_RW_ASYNC, HZ / 10); |
992 | reiserfs_write_lock(s); | ||
993 | } | ||
994 | |||
1001 | return 0; | 995 | return 0; |
1002 | } | 996 | } |
1003 | 997 | ||
@@ -1043,7 +1037,8 @@ static int flush_commit_list(struct super_block *s, | |||
1043 | } | 1037 | } |
1044 | 1038 | ||
1045 | /* make sure nobody is trying to flush this one at the same time */ | 1039 | /* make sure nobody is trying to flush this one at the same time */ |
1046 | mutex_lock(&jl->j_commit_mutex); | 1040 | reiserfs_mutex_lock_safe(&jl->j_commit_mutex, s); |
1041 | |||
1047 | if (!journal_list_still_alive(s, trans_id)) { | 1042 | if (!journal_list_still_alive(s, trans_id)) { |
1048 | mutex_unlock(&jl->j_commit_mutex); | 1043 | mutex_unlock(&jl->j_commit_mutex); |
1049 | goto put_jl; | 1044 | goto put_jl; |
@@ -1061,12 +1056,17 @@ static int flush_commit_list(struct super_block *s, | |||
1061 | 1056 | ||
1062 | if (!list_empty(&jl->j_bh_list)) { | 1057 | if (!list_empty(&jl->j_bh_list)) { |
1063 | int ret; | 1058 | int ret; |
1064 | unlock_kernel(); | 1059 | |
1060 | /* | ||
1061 | * We might sleep in numerous places inside | ||
1062 | * write_ordered_buffers. Relax the write lock. | ||
1063 | */ | ||
1064 | reiserfs_write_unlock(s); | ||
1065 | ret = write_ordered_buffers(&journal->j_dirty_buffers_lock, | 1065 | ret = write_ordered_buffers(&journal->j_dirty_buffers_lock, |
1066 | journal, jl, &jl->j_bh_list); | 1066 | journal, jl, &jl->j_bh_list); |
1067 | if (ret < 0 && retval == 0) | 1067 | if (ret < 0 && retval == 0) |
1068 | retval = ret; | 1068 | retval = ret; |
1069 | lock_kernel(); | 1069 | reiserfs_write_lock(s); |
1070 | } | 1070 | } |
1071 | BUG_ON(!list_empty(&jl->j_bh_list)); | 1071 | BUG_ON(!list_empty(&jl->j_bh_list)); |
1072 | /* | 1072 | /* |
@@ -1085,8 +1085,11 @@ static int flush_commit_list(struct super_block *s, | |||
1085 | SB_ONDISK_JOURNAL_SIZE(s); | 1085 | SB_ONDISK_JOURNAL_SIZE(s); |
1086 | tbh = journal_find_get_block(s, bn); | 1086 | tbh = journal_find_get_block(s, bn); |
1087 | if (tbh) { | 1087 | if (tbh) { |
1088 | if (buffer_dirty(tbh)) | 1088 | if (buffer_dirty(tbh)) { |
1089 | ll_rw_block(WRITE, 1, &tbh) ; | 1089 | reiserfs_write_unlock(s); |
1090 | ll_rw_block(WRITE, 1, &tbh); | ||
1091 | reiserfs_write_lock(s); | ||
1092 | } | ||
1090 | put_bh(tbh) ; | 1093 | put_bh(tbh) ; |
1091 | } | 1094 | } |
1092 | } | 1095 | } |
@@ -1114,12 +1117,19 @@ static int flush_commit_list(struct super_block *s, | |||
1114 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + | 1117 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + |
1115 | (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s); | 1118 | (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s); |
1116 | tbh = journal_find_get_block(s, bn); | 1119 | tbh = journal_find_get_block(s, bn); |
1120 | |||
1121 | reiserfs_write_unlock(s); | ||
1117 | wait_on_buffer(tbh); | 1122 | wait_on_buffer(tbh); |
1123 | reiserfs_write_lock(s); | ||
1118 | // since we're using ll_rw_blk above, it might have skipped over | 1124 | // since we're using ll_rw_blk above, it might have skipped over |
1119 | // a locked buffer. Double check here | 1125 | // a locked buffer. Double check here |
1120 | // | 1126 | // |
1121 | if (buffer_dirty(tbh)) /* redundant, sync_dirty_buffer() checks */ | 1127 | /* redundant, sync_dirty_buffer() checks */ |
1128 | if (buffer_dirty(tbh)) { | ||
1129 | reiserfs_write_unlock(s); | ||
1122 | sync_dirty_buffer(tbh); | 1130 | sync_dirty_buffer(tbh); |
1131 | reiserfs_write_lock(s); | ||
1132 | } | ||
1123 | if (unlikely(!buffer_uptodate(tbh))) { | 1133 | if (unlikely(!buffer_uptodate(tbh))) { |
1124 | #ifdef CONFIG_REISERFS_CHECK | 1134 | #ifdef CONFIG_REISERFS_CHECK |
1125 | reiserfs_warning(s, "journal-601", | 1135 | reiserfs_warning(s, "journal-601", |
@@ -1143,10 +1153,15 @@ static int flush_commit_list(struct super_block *s, | |||
1143 | if (buffer_dirty(jl->j_commit_bh)) | 1153 | if (buffer_dirty(jl->j_commit_bh)) |
1144 | BUG(); | 1154 | BUG(); |
1145 | mark_buffer_dirty(jl->j_commit_bh) ; | 1155 | mark_buffer_dirty(jl->j_commit_bh) ; |
1156 | reiserfs_write_unlock(s); | ||
1146 | sync_dirty_buffer(jl->j_commit_bh) ; | 1157 | sync_dirty_buffer(jl->j_commit_bh) ; |
1158 | reiserfs_write_lock(s); | ||
1147 | } | 1159 | } |
1148 | } else | 1160 | } else { |
1161 | reiserfs_write_unlock(s); | ||
1149 | wait_on_buffer(jl->j_commit_bh); | 1162 | wait_on_buffer(jl->j_commit_bh); |
1163 | reiserfs_write_lock(s); | ||
1164 | } | ||
1150 | 1165 | ||
1151 | check_barrier_completion(s, jl->j_commit_bh); | 1166 | check_barrier_completion(s, jl->j_commit_bh); |
1152 | 1167 | ||
@@ -1286,7 +1301,9 @@ static int _update_journal_header_block(struct super_block *sb, | |||
1286 | 1301 | ||
1287 | if (trans_id >= journal->j_last_flush_trans_id) { | 1302 | if (trans_id >= journal->j_last_flush_trans_id) { |
1288 | if (buffer_locked((journal->j_header_bh))) { | 1303 | if (buffer_locked((journal->j_header_bh))) { |
1304 | reiserfs_write_unlock(sb); | ||
1289 | wait_on_buffer((journal->j_header_bh)); | 1305 | wait_on_buffer((journal->j_header_bh)); |
1306 | reiserfs_write_lock(sb); | ||
1290 | if (unlikely(!buffer_uptodate(journal->j_header_bh))) { | 1307 | if (unlikely(!buffer_uptodate(journal->j_header_bh))) { |
1291 | #ifdef CONFIG_REISERFS_CHECK | 1308 | #ifdef CONFIG_REISERFS_CHECK |
1292 | reiserfs_warning(sb, "journal-699", | 1309 | reiserfs_warning(sb, "journal-699", |
@@ -1312,12 +1329,16 @@ static int _update_journal_header_block(struct super_block *sb, | |||
1312 | disable_barrier(sb); | 1329 | disable_barrier(sb); |
1313 | goto sync; | 1330 | goto sync; |
1314 | } | 1331 | } |
1332 | reiserfs_write_unlock(sb); | ||
1315 | wait_on_buffer(journal->j_header_bh); | 1333 | wait_on_buffer(journal->j_header_bh); |
1334 | reiserfs_write_lock(sb); | ||
1316 | check_barrier_completion(sb, journal->j_header_bh); | 1335 | check_barrier_completion(sb, journal->j_header_bh); |
1317 | } else { | 1336 | } else { |
1318 | sync: | 1337 | sync: |
1319 | set_buffer_dirty(journal->j_header_bh); | 1338 | set_buffer_dirty(journal->j_header_bh); |
1339 | reiserfs_write_unlock(sb); | ||
1320 | sync_dirty_buffer(journal->j_header_bh); | 1340 | sync_dirty_buffer(journal->j_header_bh); |
1341 | reiserfs_write_lock(sb); | ||
1321 | } | 1342 | } |
1322 | if (!buffer_uptodate(journal->j_header_bh)) { | 1343 | if (!buffer_uptodate(journal->j_header_bh)) { |
1323 | reiserfs_warning(sb, "journal-837", | 1344 | reiserfs_warning(sb, "journal-837", |
@@ -1409,7 +1430,7 @@ static int flush_journal_list(struct super_block *s, | |||
1409 | 1430 | ||
1410 | /* if flushall == 0, the lock is already held */ | 1431 | /* if flushall == 0, the lock is already held */ |
1411 | if (flushall) { | 1432 | if (flushall) { |
1412 | mutex_lock(&journal->j_flush_mutex); | 1433 | reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s); |
1413 | } else if (mutex_trylock(&journal->j_flush_mutex)) { | 1434 | } else if (mutex_trylock(&journal->j_flush_mutex)) { |
1414 | BUG(); | 1435 | BUG(); |
1415 | } | 1436 | } |
@@ -1553,7 +1574,11 @@ static int flush_journal_list(struct super_block *s, | |||
1553 | reiserfs_panic(s, "journal-1011", | 1574 | reiserfs_panic(s, "journal-1011", |
1554 | "cn->bh is NULL"); | 1575 | "cn->bh is NULL"); |
1555 | } | 1576 | } |
1577 | |||
1578 | reiserfs_write_unlock(s); | ||
1556 | wait_on_buffer(cn->bh); | 1579 | wait_on_buffer(cn->bh); |
1580 | reiserfs_write_lock(s); | ||
1581 | |||
1557 | if (!cn->bh) { | 1582 | if (!cn->bh) { |
1558 | reiserfs_panic(s, "journal-1012", | 1583 | reiserfs_panic(s, "journal-1012", |
1559 | "cn->bh is NULL"); | 1584 | "cn->bh is NULL"); |
@@ -1769,7 +1794,7 @@ static int kupdate_transactions(struct super_block *s, | |||
1769 | struct reiserfs_journal *journal = SB_JOURNAL(s); | 1794 | struct reiserfs_journal *journal = SB_JOURNAL(s); |
1770 | chunk.nr = 0; | 1795 | chunk.nr = 0; |
1771 | 1796 | ||
1772 | mutex_lock(&journal->j_flush_mutex); | 1797 | reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s); |
1773 | if (!journal_list_still_alive(s, orig_trans_id)) { | 1798 | if (!journal_list_still_alive(s, orig_trans_id)) { |
1774 | goto done; | 1799 | goto done; |
1775 | } | 1800 | } |
@@ -1973,7 +1998,14 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
1973 | reiserfs_mounted_fs_count--; | 1998 | reiserfs_mounted_fs_count--; |
1974 | /* wait for all commits to finish */ | 1999 | /* wait for all commits to finish */ |
1975 | cancel_delayed_work(&SB_JOURNAL(sb)->j_work); | 2000 | cancel_delayed_work(&SB_JOURNAL(sb)->j_work); |
2001 | |||
2002 | /* | ||
2003 | * We must release the write lock here because | ||
2004 | * the workqueue job (flush_async_commit) needs this lock | ||
2005 | */ | ||
2006 | reiserfs_write_unlock(sb); | ||
1976 | flush_workqueue(commit_wq); | 2007 | flush_workqueue(commit_wq); |
2008 | |||
1977 | if (!reiserfs_mounted_fs_count) { | 2009 | if (!reiserfs_mounted_fs_count) { |
1978 | destroy_workqueue(commit_wq); | 2010 | destroy_workqueue(commit_wq); |
1979 | commit_wq = NULL; | 2011 | commit_wq = NULL; |
@@ -1981,6 +2013,8 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
1981 | 2013 | ||
1982 | free_journal_ram(sb); | 2014 | free_journal_ram(sb); |
1983 | 2015 | ||
2016 | reiserfs_write_lock(sb); | ||
2017 | |||
1984 | return 0; | 2018 | return 0; |
1985 | } | 2019 | } |
1986 | 2020 | ||
@@ -2184,6 +2218,15 @@ static int journal_read_transaction(struct super_block *sb, | |||
2184 | brelse(d_bh); | 2218 | brelse(d_bh); |
2185 | return 1; | 2219 | return 1; |
2186 | } | 2220 | } |
2221 | |||
2222 | if (bdev_read_only(sb->s_bdev)) { | ||
2223 | reiserfs_warning(sb, "clm-2076", | ||
2224 | "device is readonly, unable to replay log"); | ||
2225 | brelse(c_bh); | ||
2226 | brelse(d_bh); | ||
2227 | return -EROFS; | ||
2228 | } | ||
2229 | |||
2187 | trans_id = get_desc_trans_id(desc); | 2230 | trans_id = get_desc_trans_id(desc); |
2188 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ | 2231 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ |
2189 | log_blocks = kmalloc(get_desc_trans_len(desc) * | 2232 | log_blocks = kmalloc(get_desc_trans_len(desc) * |
@@ -2243,7 +2286,11 @@ static int journal_read_transaction(struct super_block *sb, | |||
2243 | /* read in the log blocks, memcpy to the corresponding real block */ | 2286 | /* read in the log blocks, memcpy to the corresponding real block */ |
2244 | ll_rw_block(READ, get_desc_trans_len(desc), log_blocks); | 2287 | ll_rw_block(READ, get_desc_trans_len(desc), log_blocks); |
2245 | for (i = 0; i < get_desc_trans_len(desc); i++) { | 2288 | for (i = 0; i < get_desc_trans_len(desc); i++) { |
2289 | |||
2290 | reiserfs_write_unlock(sb); | ||
2246 | wait_on_buffer(log_blocks[i]); | 2291 | wait_on_buffer(log_blocks[i]); |
2292 | reiserfs_write_lock(sb); | ||
2293 | |||
2247 | if (!buffer_uptodate(log_blocks[i])) { | 2294 | if (!buffer_uptodate(log_blocks[i])) { |
2248 | reiserfs_warning(sb, "journal-1212", | 2295 | reiserfs_warning(sb, "journal-1212", |
2249 | "REPLAY FAILURE fsck required! " | 2296 | "REPLAY FAILURE fsck required! " |
@@ -2422,12 +2469,6 @@ static int journal_read(struct super_block *sb) | |||
2422 | goto start_log_replay; | 2469 | goto start_log_replay; |
2423 | } | 2470 | } |
2424 | 2471 | ||
2425 | if (continue_replay && bdev_read_only(sb->s_bdev)) { | ||
2426 | reiserfs_warning(sb, "clm-2076", | ||
2427 | "device is readonly, unable to replay log"); | ||
2428 | return -1; | ||
2429 | } | ||
2430 | |||
2431 | /* ok, there are transactions that need to be replayed. start with the first log block, find | 2472 | /* ok, there are transactions that need to be replayed. start with the first log block, find |
2432 | ** all the valid transactions, and pick out the oldest. | 2473 | ** all the valid transactions, and pick out the oldest. |
2433 | */ | 2474 | */ |
@@ -2722,11 +2763,18 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2722 | struct reiserfs_journal *journal; | 2763 | struct reiserfs_journal *journal; |
2723 | struct reiserfs_journal_list *jl; | 2764 | struct reiserfs_journal_list *jl; |
2724 | char b[BDEVNAME_SIZE]; | 2765 | char b[BDEVNAME_SIZE]; |
2766 | int ret; | ||
2725 | 2767 | ||
2768 | /* | ||
2769 | * Unlock here to avoid various RECLAIM-FS-ON <-> IN-RECLAIM-FS | ||
2770 | * dependency inversion warnings. | ||
2771 | */ | ||
2772 | reiserfs_write_unlock(sb); | ||
2726 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); | 2773 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); |
2727 | if (!journal) { | 2774 | if (!journal) { |
2728 | reiserfs_warning(sb, "journal-1256", | 2775 | reiserfs_warning(sb, "journal-1256", |
2729 | "unable to get memory for journal structure"); | 2776 | "unable to get memory for journal structure"); |
2777 | reiserfs_write_lock(sb); | ||
2730 | return 1; | 2778 | return 1; |
2731 | } | 2779 | } |
2732 | memset(journal, 0, sizeof(struct reiserfs_journal)); | 2780 | memset(journal, 0, sizeof(struct reiserfs_journal)); |
@@ -2735,10 +2783,12 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2735 | INIT_LIST_HEAD(&journal->j_working_list); | 2783 | INIT_LIST_HEAD(&journal->j_working_list); |
2736 | INIT_LIST_HEAD(&journal->j_journal_list); | 2784 | INIT_LIST_HEAD(&journal->j_journal_list); |
2737 | journal->j_persistent_trans = 0; | 2785 | journal->j_persistent_trans = 0; |
2738 | if (reiserfs_allocate_list_bitmaps(sb, | 2786 | ret = reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap, |
2739 | journal->j_list_bitmap, | 2787 | reiserfs_bmap_count(sb)); |
2740 | reiserfs_bmap_count(sb))) | 2788 | reiserfs_write_lock(sb); |
2789 | if (ret) | ||
2741 | goto free_and_return; | 2790 | goto free_and_return; |
2791 | |||
2742 | allocate_bitmap_nodes(sb); | 2792 | allocate_bitmap_nodes(sb); |
2743 | 2793 | ||
2744 | /* reserved for journal area support */ | 2794 | /* reserved for journal area support */ |
@@ -2765,11 +2815,27 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2765 | goto free_and_return; | 2815 | goto free_and_return; |
2766 | } | 2816 | } |
2767 | 2817 | ||
2818 | /* | ||
2819 | * We need to unlock here to avoid creating the following | ||
2820 | * dependency: | ||
2821 | * reiserfs_lock -> sysfs_mutex | ||
2822 | * Because the reiserfs mmap path creates the following dependency: | ||
2823 | * mm->mmap -> reiserfs_lock, hence we have | ||
2824 | * mm->mmap -> reiserfs_lock ->sysfs_mutex | ||
2825 | * This would ends up in a circular dependency with sysfs readdir path | ||
2826 | * which does sysfs_mutex -> mm->mmap_sem | ||
2827 | * This is fine because the reiserfs lock is useless in mount path, | ||
2828 | * at least until we call journal_begin. We keep it for paranoid | ||
2829 | * reasons. | ||
2830 | */ | ||
2831 | reiserfs_write_unlock(sb); | ||
2768 | if (journal_init_dev(sb, journal, j_dev_name) != 0) { | 2832 | if (journal_init_dev(sb, journal, j_dev_name) != 0) { |
2833 | reiserfs_write_lock(sb); | ||
2769 | reiserfs_warning(sb, "sh-462", | 2834 | reiserfs_warning(sb, "sh-462", |
2770 | "unable to initialize jornal device"); | 2835 | "unable to initialize jornal device"); |
2771 | goto free_and_return; | 2836 | goto free_and_return; |
2772 | } | 2837 | } |
2838 | reiserfs_write_lock(sb); | ||
2773 | 2839 | ||
2774 | rs = SB_DISK_SUPER_BLOCK(sb); | 2840 | rs = SB_DISK_SUPER_BLOCK(sb); |
2775 | 2841 | ||
@@ -2851,7 +2917,9 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2851 | journal->j_mount_id = 10; | 2917 | journal->j_mount_id = 10; |
2852 | journal->j_state = 0; | 2918 | journal->j_state = 0; |
2853 | atomic_set(&(journal->j_jlock), 0); | 2919 | atomic_set(&(journal->j_jlock), 0); |
2920 | reiserfs_write_unlock(sb); | ||
2854 | journal->j_cnode_free_list = allocate_cnodes(num_cnodes); | 2921 | journal->j_cnode_free_list = allocate_cnodes(num_cnodes); |
2922 | reiserfs_write_lock(sb); | ||
2855 | journal->j_cnode_free_orig = journal->j_cnode_free_list; | 2923 | journal->j_cnode_free_orig = journal->j_cnode_free_list; |
2856 | journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0; | 2924 | journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0; |
2857 | journal->j_cnode_used = 0; | 2925 | journal->j_cnode_used = 0; |
@@ -2881,8 +2949,11 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2881 | } | 2949 | } |
2882 | 2950 | ||
2883 | reiserfs_mounted_fs_count++; | 2951 | reiserfs_mounted_fs_count++; |
2884 | if (reiserfs_mounted_fs_count <= 1) | 2952 | if (reiserfs_mounted_fs_count <= 1) { |
2953 | reiserfs_write_unlock(sb); | ||
2885 | commit_wq = create_workqueue("reiserfs"); | 2954 | commit_wq = create_workqueue("reiserfs"); |
2955 | reiserfs_write_lock(sb); | ||
2956 | } | ||
2886 | 2957 | ||
2887 | INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); | 2958 | INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); |
2888 | journal->j_work_sb = sb; | 2959 | journal->j_work_sb = sb; |
@@ -2964,8 +3035,11 @@ static void queue_log_writer(struct super_block *s) | |||
2964 | init_waitqueue_entry(&wait, current); | 3035 | init_waitqueue_entry(&wait, current); |
2965 | add_wait_queue(&journal->j_join_wait, &wait); | 3036 | add_wait_queue(&journal->j_join_wait, &wait); |
2966 | set_current_state(TASK_UNINTERRUPTIBLE); | 3037 | set_current_state(TASK_UNINTERRUPTIBLE); |
2967 | if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) | 3038 | if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) { |
3039 | reiserfs_write_unlock(s); | ||
2968 | schedule(); | 3040 | schedule(); |
3041 | reiserfs_write_lock(s); | ||
3042 | } | ||
2969 | __set_current_state(TASK_RUNNING); | 3043 | __set_current_state(TASK_RUNNING); |
2970 | remove_wait_queue(&journal->j_join_wait, &wait); | 3044 | remove_wait_queue(&journal->j_join_wait, &wait); |
2971 | } | 3045 | } |
@@ -2982,7 +3056,9 @@ static void let_transaction_grow(struct super_block *sb, unsigned int trans_id) | |||
2982 | struct reiserfs_journal *journal = SB_JOURNAL(sb); | 3056 | struct reiserfs_journal *journal = SB_JOURNAL(sb); |
2983 | unsigned long bcount = journal->j_bcount; | 3057 | unsigned long bcount = journal->j_bcount; |
2984 | while (1) { | 3058 | while (1) { |
3059 | reiserfs_write_unlock(sb); | ||
2985 | schedule_timeout_uninterruptible(1); | 3060 | schedule_timeout_uninterruptible(1); |
3061 | reiserfs_write_lock(sb); | ||
2986 | journal->j_current_jl->j_state |= LIST_COMMIT_PENDING; | 3062 | journal->j_current_jl->j_state |= LIST_COMMIT_PENDING; |
2987 | while ((atomic_read(&journal->j_wcount) > 0 || | 3063 | while ((atomic_read(&journal->j_wcount) > 0 || |
2988 | atomic_read(&journal->j_jlock)) && | 3064 | atomic_read(&journal->j_jlock)) && |
@@ -3033,7 +3109,9 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th, | |||
3033 | 3109 | ||
3034 | if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) { | 3110 | if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) { |
3035 | unlock_journal(sb); | 3111 | unlock_journal(sb); |
3112 | reiserfs_write_unlock(sb); | ||
3036 | reiserfs_wait_on_write_block(sb); | 3113 | reiserfs_wait_on_write_block(sb); |
3114 | reiserfs_write_lock(sb); | ||
3037 | PROC_INFO_INC(sb, journal.journal_relock_writers); | 3115 | PROC_INFO_INC(sb, journal.journal_relock_writers); |
3038 | goto relock; | 3116 | goto relock; |
3039 | } | 3117 | } |
@@ -3506,14 +3584,14 @@ static void flush_async_commits(struct work_struct *work) | |||
3506 | struct reiserfs_journal_list *jl; | 3584 | struct reiserfs_journal_list *jl; |
3507 | struct list_head *entry; | 3585 | struct list_head *entry; |
3508 | 3586 | ||
3509 | lock_kernel(); | 3587 | reiserfs_write_lock(sb); |
3510 | if (!list_empty(&journal->j_journal_list)) { | 3588 | if (!list_empty(&journal->j_journal_list)) { |
3511 | /* last entry is the youngest, commit it and you get everything */ | 3589 | /* last entry is the youngest, commit it and you get everything */ |
3512 | entry = journal->j_journal_list.prev; | 3590 | entry = journal->j_journal_list.prev; |
3513 | jl = JOURNAL_LIST_ENTRY(entry); | 3591 | jl = JOURNAL_LIST_ENTRY(entry); |
3514 | flush_commit_list(sb, jl, 1); | 3592 | flush_commit_list(sb, jl, 1); |
3515 | } | 3593 | } |
3516 | unlock_kernel(); | 3594 | reiserfs_write_unlock(sb); |
3517 | } | 3595 | } |
3518 | 3596 | ||
3519 | /* | 3597 | /* |
@@ -4041,7 +4119,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
4041 | * the new transaction is fully setup, and we've already flushed the | 4119 | * the new transaction is fully setup, and we've already flushed the |
4042 | * ordered bh list | 4120 | * ordered bh list |
4043 | */ | 4121 | */ |
4044 | mutex_lock(&jl->j_commit_mutex); | 4122 | reiserfs_mutex_lock_safe(&jl->j_commit_mutex, sb); |
4045 | 4123 | ||
4046 | /* save the transaction id in case we need to commit it later */ | 4124 | /* save the transaction id in case we need to commit it later */ |
4047 | commit_trans_id = jl->j_trans_id; | 4125 | commit_trans_id = jl->j_trans_id; |
@@ -4156,7 +4234,9 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
4156 | next = cn->next; | 4234 | next = cn->next; |
4157 | free_cnode(sb, cn); | 4235 | free_cnode(sb, cn); |
4158 | cn = next; | 4236 | cn = next; |
4237 | reiserfs_write_unlock(sb); | ||
4159 | cond_resched(); | 4238 | cond_resched(); |
4239 | reiserfs_write_lock(sb); | ||
4160 | } | 4240 | } |
4161 | 4241 | ||
4162 | /* we are done with both the c_bh and d_bh, but | 4242 | /* we are done with both the c_bh and d_bh, but |
@@ -4203,10 +4283,10 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
4203 | * is lost. | 4283 | * is lost. |
4204 | */ | 4284 | */ |
4205 | if (!list_empty(&jl->j_tail_bh_list)) { | 4285 | if (!list_empty(&jl->j_tail_bh_list)) { |
4206 | unlock_kernel(); | 4286 | reiserfs_write_unlock(sb); |
4207 | write_ordered_buffers(&journal->j_dirty_buffers_lock, | 4287 | write_ordered_buffers(&journal->j_dirty_buffers_lock, |
4208 | journal, jl, &jl->j_tail_bh_list); | 4288 | journal, jl, &jl->j_tail_bh_list); |
4209 | lock_kernel(); | 4289 | reiserfs_write_lock(sb); |
4210 | } | 4290 | } |
4211 | BUG_ON(!list_empty(&jl->j_tail_bh_list)); | 4291 | BUG_ON(!list_empty(&jl->j_tail_bh_list)); |
4212 | mutex_unlock(&jl->j_commit_mutex); | 4292 | mutex_unlock(&jl->j_commit_mutex); |