aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/journal.c
diff options
context:
space:
mode:
authorChris Mason <mason@suse.com>2006-02-01 06:06:49 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-01 11:53:26 -0500
commite0e851cf30f1a9bd2e2a7624e9810378d6a2b072 (patch)
treea8cf33d9b22594fb5c1094bd8b15f2f315b53f2d /fs/reiserfs/journal.c
parentfc5cd582e9c934ddaf6f310179488932cd154794 (diff)
[PATCH] reiserfs: reiserfs hang and performance fix for data=journal mode
In data=journal mode, reiserfs writepage needs to make sure not to trigger transactions while being run under PF_MEMALLOC. This patch makes sure to redirty the page instead of forcing a transaction start in this case. Also, calling filemap_fdata* in order to trigger io on the block device can cause lock inversions on the page lock. Instead, do simple batching from flush_commit_list. Signed-off-by: Chris Mason <mason@suse.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/reiserfs/journal.c')
-rw-r--r--fs/reiserfs/journal.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index bc8fe963b3cc..1b2402a9a8e1 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -988,6 +988,7 @@ static int flush_commit_list(struct super_block *s,
988 struct reiserfs_journal *journal = SB_JOURNAL(s); 988 struct reiserfs_journal *journal = SB_JOURNAL(s);
989 int barrier = 0; 989 int barrier = 0;
990 int retval = 0; 990 int retval = 0;
991 int write_len;
991 992
992 reiserfs_check_lock_depth(s, "flush_commit_list"); 993 reiserfs_check_lock_depth(s, "flush_commit_list");
993 994
@@ -1037,16 +1038,24 @@ static int flush_commit_list(struct super_block *s,
1037 BUG_ON(!list_empty(&jl->j_bh_list)); 1038 BUG_ON(!list_empty(&jl->j_bh_list));
1038 /* 1039 /*
1039 * for the description block and all the log blocks, submit any buffers 1040 * for the description block and all the log blocks, submit any buffers
1040 * that haven't already reached the disk 1041 * that haven't already reached the disk. Try to write at least 256
1042 * log blocks. later on, we will only wait on blocks that correspond
1043 * to this transaction, but while we're unplugging we might as well
1044 * get a chunk of data on there.
1041 */ 1045 */
1042 atomic_inc(&journal->j_async_throttle); 1046 atomic_inc(&journal->j_async_throttle);
1043 for (i = 0; i < (jl->j_len + 1); i++) { 1047 write_len = jl->j_len + 1;
1048 if (write_len < 256)
1049 write_len = 256;
1050 for (i = 0 ; i < write_len ; i++) {
1044 bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % 1051 bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) %
1045 SB_ONDISK_JOURNAL_SIZE(s); 1052 SB_ONDISK_JOURNAL_SIZE(s);
1046 tbh = journal_find_get_block(s, bn); 1053 tbh = journal_find_get_block(s, bn);
1047 if (buffer_dirty(tbh)) /* redundant, ll_rw_block() checks */ 1054 if (tbh) {
1048 ll_rw_block(SWRITE, 1, &tbh); 1055 if (buffer_dirty(tbh))
1049 put_bh(tbh); 1056 ll_rw_block(WRITE, 1, &tbh) ;
1057 put_bh(tbh) ;
1058 }
1050 } 1059 }
1051 atomic_dec(&journal->j_async_throttle); 1060 atomic_dec(&journal->j_async_throttle);
1052 1061