aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd
diff options
context:
space:
mode:
authorHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>2008-10-18 23:27:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 11:52:37 -0400
commit960a22ae60c8a723bd17da3b929fe0bcea6d007e (patch)
tree844e3726fb6bdedd433854966e90116eb1d03c99 /fs/jbd
parent0e4fb5e283870757024294bc4567a7c59d936f0b (diff)
jbd: ordered data integrity fix
In ordered mode, if a file data buffer being dirtied exists in the committing transaction, we write the buffer to the disk, move it from the committing transaction to the running transaction, then dirty it. But we don't have to remove the buffer from the committing transaction when the buffer couldn't be written out, otherwise it would miss the error and the committing transaction would not abort. This patch adds an error check before removing the buffer from the committing transaction. Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/jbd')
-rw-r--r--fs/jbd/transaction.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 0540ca27a446..d15cd6e7251e 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -954,9 +954,10 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
954 journal_t *journal = handle->h_transaction->t_journal; 954 journal_t *journal = handle->h_transaction->t_journal;
955 int need_brelse = 0; 955 int need_brelse = 0;
956 struct journal_head *jh; 956 struct journal_head *jh;
957 int ret = 0;
957 958
958 if (is_handle_aborted(handle)) 959 if (is_handle_aborted(handle))
959 return 0; 960 return ret;
960 961
961 jh = journal_add_journal_head(bh); 962 jh = journal_add_journal_head(bh);
962 JBUFFER_TRACE(jh, "entry"); 963 JBUFFER_TRACE(jh, "entry");
@@ -1067,7 +1068,16 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
1067 time if it is redirtied */ 1068 time if it is redirtied */
1068 } 1069 }
1069 1070
1070 /* journal_clean_data_list() may have got there first */ 1071 /*
1072 * We cannot remove the buffer with io error from the
1073 * committing transaction, because otherwise it would
1074 * miss the error and the commit would not abort.
1075 */
1076 if (unlikely(!buffer_uptodate(bh))) {
1077 ret = -EIO;
1078 goto no_journal;
1079 }
1080
1071 if (jh->b_transaction != NULL) { 1081 if (jh->b_transaction != NULL) {
1072 JBUFFER_TRACE(jh, "unfile from commit"); 1082 JBUFFER_TRACE(jh, "unfile from commit");
1073 __journal_temp_unlink_buffer(jh); 1083 __journal_temp_unlink_buffer(jh);
@@ -1108,7 +1118,7 @@ no_journal:
1108 } 1118 }
1109 JBUFFER_TRACE(jh, "exit"); 1119 JBUFFER_TRACE(jh, "exit");
1110 journal_put_journal_head(jh); 1120 journal_put_journal_head(jh);
1111 return 0; 1121 return ret;
1112} 1122}
1113 1123
1114/** 1124/**