diff options
-rw-r--r-- | fs/jbd/commit.c | 23 | ||||
-rw-r--r-- | fs/jbd/transaction.c | 2 | ||||
-rw-r--r-- | include/linux/jbd.h | 5 |
3 files changed, 22 insertions, 8 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 3fbffb1ea714..f8077b9c8981 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/bio.h> | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Default IO end handler for temporary BJ_IO buffer_heads. | 26 | * Default IO end handler for temporary BJ_IO buffer_heads. |
@@ -171,14 +172,15 @@ static int journal_write_commit_record(journal_t *journal, | |||
171 | return (ret == -EIO); | 172 | return (ret == -EIO); |
172 | } | 173 | } |
173 | 174 | ||
174 | static void journal_do_submit_data(struct buffer_head **wbuf, int bufs) | 175 | static void journal_do_submit_data(struct buffer_head **wbuf, int bufs, |
176 | int write_op) | ||
175 | { | 177 | { |
176 | int i; | 178 | int i; |
177 | 179 | ||
178 | for (i = 0; i < bufs; i++) { | 180 | for (i = 0; i < bufs; i++) { |
179 | wbuf[i]->b_end_io = end_buffer_write_sync; | 181 | wbuf[i]->b_end_io = end_buffer_write_sync; |
180 | /* We use-up our safety reference in submit_bh() */ | 182 | /* We use-up our safety reference in submit_bh() */ |
181 | submit_bh(WRITE, wbuf[i]); | 183 | submit_bh(write_op, wbuf[i]); |
182 | } | 184 | } |
183 | } | 185 | } |
184 | 186 | ||
@@ -186,7 +188,8 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs) | |||
186 | * Submit all the data buffers to disk | 188 | * Submit all the data buffers to disk |
187 | */ | 189 | */ |
188 | static int journal_submit_data_buffers(journal_t *journal, | 190 | static int journal_submit_data_buffers(journal_t *journal, |
189 | transaction_t *commit_transaction) | 191 | transaction_t *commit_transaction, |
192 | int write_op) | ||
190 | { | 193 | { |
191 | struct journal_head *jh; | 194 | struct journal_head *jh; |
192 | struct buffer_head *bh; | 195 | struct buffer_head *bh; |
@@ -225,7 +228,7 @@ write_out_data: | |||
225 | BUFFER_TRACE(bh, "needs blocking lock"); | 228 | BUFFER_TRACE(bh, "needs blocking lock"); |
226 | spin_unlock(&journal->j_list_lock); | 229 | spin_unlock(&journal->j_list_lock); |
227 | /* Write out all data to prevent deadlocks */ | 230 | /* Write out all data to prevent deadlocks */ |
228 | journal_do_submit_data(wbuf, bufs); | 231 | journal_do_submit_data(wbuf, bufs, write_op); |
229 | bufs = 0; | 232 | bufs = 0; |
230 | lock_buffer(bh); | 233 | lock_buffer(bh); |
231 | spin_lock(&journal->j_list_lock); | 234 | spin_lock(&journal->j_list_lock); |
@@ -256,7 +259,7 @@ write_out_data: | |||
256 | jbd_unlock_bh_state(bh); | 259 | jbd_unlock_bh_state(bh); |
257 | if (bufs == journal->j_wbufsize) { | 260 | if (bufs == journal->j_wbufsize) { |
258 | spin_unlock(&journal->j_list_lock); | 261 | spin_unlock(&journal->j_list_lock); |
259 | journal_do_submit_data(wbuf, bufs); | 262 | journal_do_submit_data(wbuf, bufs, write_op); |
260 | bufs = 0; | 263 | bufs = 0; |
261 | goto write_out_data; | 264 | goto write_out_data; |
262 | } | 265 | } |
@@ -286,7 +289,7 @@ write_out_data: | |||
286 | } | 289 | } |
287 | } | 290 | } |
288 | spin_unlock(&journal->j_list_lock); | 291 | spin_unlock(&journal->j_list_lock); |
289 | journal_do_submit_data(wbuf, bufs); | 292 | journal_do_submit_data(wbuf, bufs, write_op); |
290 | 293 | ||
291 | return err; | 294 | return err; |
292 | } | 295 | } |
@@ -315,6 +318,7 @@ void journal_commit_transaction(journal_t *journal) | |||
315 | int first_tag = 0; | 318 | int first_tag = 0; |
316 | int tag_flag; | 319 | int tag_flag; |
317 | int i; | 320 | int i; |
321 | int write_op = WRITE; | ||
318 | 322 | ||
319 | /* | 323 | /* |
320 | * First job: lock down the current transaction and wait for | 324 | * First job: lock down the current transaction and wait for |
@@ -347,6 +351,8 @@ void journal_commit_transaction(journal_t *journal) | |||
347 | spin_lock(&journal->j_state_lock); | 351 | spin_lock(&journal->j_state_lock); |
348 | commit_transaction->t_state = T_LOCKED; | 352 | commit_transaction->t_state = T_LOCKED; |
349 | 353 | ||
354 | if (commit_transaction->t_synchronous_commit) | ||
355 | write_op = WRITE_SYNC; | ||
350 | spin_lock(&commit_transaction->t_handle_lock); | 356 | spin_lock(&commit_transaction->t_handle_lock); |
351 | while (commit_transaction->t_updates) { | 357 | while (commit_transaction->t_updates) { |
352 | DEFINE_WAIT(wait); | 358 | DEFINE_WAIT(wait); |
@@ -431,7 +437,8 @@ void journal_commit_transaction(journal_t *journal) | |||
431 | * Now start flushing things to disk, in the order they appear | 437 | * Now start flushing things to disk, in the order they appear |
432 | * on the transaction lists. Data blocks go first. | 438 | * on the transaction lists. Data blocks go first. |
433 | */ | 439 | */ |
434 | err = journal_submit_data_buffers(journal, commit_transaction); | 440 | err = journal_submit_data_buffers(journal, commit_transaction, |
441 | write_op); | ||
435 | 442 | ||
436 | /* | 443 | /* |
437 | * Wait for all previously submitted IO to complete. | 444 | * Wait for all previously submitted IO to complete. |
@@ -660,7 +667,7 @@ start_journal_io: | |||
660 | clear_buffer_dirty(bh); | 667 | clear_buffer_dirty(bh); |
661 | set_buffer_uptodate(bh); | 668 | set_buffer_uptodate(bh); |
662 | bh->b_end_io = journal_end_buffer_io_sync; | 669 | bh->b_end_io = journal_end_buffer_io_sync; |
663 | submit_bh(WRITE, bh); | 670 | submit_bh(write_op, bh); |
664 | } | 671 | } |
665 | cond_resched(); | 672 | cond_resched(); |
666 | 673 | ||
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index e6a117431277..ed886e6db399 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -1440,6 +1440,8 @@ int journal_stop(handle_t *handle) | |||
1440 | } | 1440 | } |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | if (handle->h_sync) | ||
1444 | transaction->t_synchronous_commit = 1; | ||
1443 | current->journal_info = NULL; | 1445 | current->journal_info = NULL; |
1444 | spin_lock(&journal->j_state_lock); | 1446 | spin_lock(&journal->j_state_lock); |
1445 | spin_lock(&transaction->t_handle_lock); | 1447 | spin_lock(&transaction->t_handle_lock); |
diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 64246dce5663..2c6943152c21 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h | |||
@@ -552,6 +552,11 @@ struct transaction_s | |||
552 | */ | 552 | */ |
553 | int t_handle_count; | 553 | int t_handle_count; |
554 | 554 | ||
555 | /* | ||
556 | * This transaction is being forced and some process is | ||
557 | * waiting for it to finish. | ||
558 | */ | ||
559 | int t_synchronous_commit:1; | ||
555 | }; | 560 | }; |
556 | 561 | ||
557 | /** | 562 | /** |