1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/time.h>
21#include <linux/fs.h>
22#include <linux/jbd2.h>
23#include <linux/errno.h>
24#include <linux/slab.h>
25#include <linux/blkdev.h>
26#include <trace/events/jbd2.h>
27
28
29
30
31
32
33static inline void __buffer_unlink_first(struct journal_head *jh)
34{
35 transaction_t *transaction = jh->b_cp_transaction;
36
37 jh->b_cpnext->b_cpprev = jh->b_cpprev;
38 jh->b_cpprev->b_cpnext = jh->b_cpnext;
39 if (transaction->t_checkpoint_list == jh) {
40 transaction->t_checkpoint_list = jh->b_cpnext;
41 if (transaction->t_checkpoint_list == jh)
42 transaction->t_checkpoint_list = NULL;
43 }
44}
45
46
47
48
49
50
51static inline void __buffer_unlink(struct journal_head *jh)
52{
53 transaction_t *transaction = jh->b_cp_transaction;
54
55 __buffer_unlink_first(jh);
56 if (transaction->t_checkpoint_io_list == jh) {
57 transaction->t_checkpoint_io_list = jh->b_cpnext;
58 if (transaction->t_checkpoint_io_list == jh)
59 transaction->t_checkpoint_io_list = NULL;
60 }
61}
62
63
64
65
66
67
68static inline void __buffer_relink_io(struct journal_head *jh)
69{
70 transaction_t *transaction = jh->b_cp_transaction;
71
72 __buffer_unlink_first(jh);
73
74 if (!transaction->t_checkpoint_io_list) {
75 jh->b_cpnext = jh->b_cpprev = jh;
76 } else {
77 jh->b_cpnext = transaction->t_checkpoint_io_list;
78 jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
79 jh->b_cpprev->b_cpnext = jh;
80 jh->b_cpnext->b_cpprev = jh;
81 }
82 transaction->t_checkpoint_io_list = jh;
83}
84
85
86
87
88
89
90
91
92static int __try_to_free_cp_buf(struct journal_head *jh)
93{
94 int ret = 0;
95 struct buffer_head *bh = jh2bh(jh);
96
97 if (jh->b_transaction == NULL && !buffer_locked(bh) &&
98 !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
99
100
101
102
103 get_bh(bh);
104 JBUFFER_TRACE(jh, "remove from checkpoint list");
105 ret = __jbd2_journal_remove_checkpoint(jh) + 1;
106 BUFFER_TRACE(bh, "release");
107 __brelse(bh);
108 }
109 return ret;
110}
111
112
113
114
115
116
117
118void __jbd2_log_wait_for_space(journal_t *journal)
119{
120 int nblocks, space_left;
121
122
123 nblocks = jbd2_space_needed(journal);
124 while (jbd2_log_space_left(journal) < nblocks) {
125 write_unlock(&journal->j_state_lock);
126 mutex_lock(&journal->j_checkpoint_mutex);
127
128
129
130
131
132
133
134
135
136
137
138
139 write_lock(&journal->j_state_lock);
140 if (journal->j_flags & JBD2_ABORT) {
141 mutex_unlock(&journal->j_checkpoint_mutex);
142 return;
143 }
144 spin_lock(&journal->j_list_lock);
145 nblocks = jbd2_space_needed(journal);
146 space_left = jbd2_log_space_left(journal);
147 if (space_left < nblocks) {
148 int chkpt = journal->j_checkpoint_transactions != NULL;
149 tid_t tid = 0;
150
151 if (journal->j_committing_transaction)
152 tid = journal->j_committing_transaction->t_tid;
153 spin_unlock(&journal->j_list_lock);
154 write_unlock(&journal->j_state_lock);
155 if (chkpt) {
156 jbd2_log_do_checkpoint(journal);
157 } else if (jbd2_cleanup_journal_tail(journal) == 0) {
158
159 ;
160 } else if (tid) {
161
162
163
164
165
166 mutex_unlock(&journal->j_checkpoint_mutex);
167 jbd2_log_wait_commit(journal, tid);
168 write_lock(&journal->j_state_lock);
169 continue;
170 } else {
171 printk(KERN_ERR "%s: needed %d blocks and "
172 "only had %d space available\n",
173 __func__, nblocks, space_left);
174 printk(KERN_ERR "%s: no way to get more "
175 "journal space in %s\n", __func__,
176 journal->j_devname);
177 WARN_ON(1);
178 jbd2_journal_abort(journal, 0);
179 }
180 write_lock(&journal->j_state_lock);
181 } else {
182 spin_unlock(&journal->j_list_lock);
183 }
184 mutex_unlock(&journal->j_checkpoint_mutex);
185 }
186}
187
188
189
190
191
192
193
194
195
196
197
198
199static int __wait_cp_io(journal_t *journal, transaction_t *transaction)
200{
201 struct journal_head *jh;
202 struct buffer_head *bh;
203 tid_t this_tid;
204 int released = 0;
205 int ret = 0;
206
207 this_tid = transaction->t_tid;
208restart:
209
210 if (journal->j_checkpoint_transactions != transaction ||
211 transaction->t_tid != this_tid)
212 return ret;
213 while (!released && transaction->t_checkpoint_io_list) {
214 jh = transaction->t_checkpoint_io_list;
215 bh = jh2bh(jh);
216 get_bh(bh);
217 if (buffer_locked(bh)) {
218 spin_unlock(&journal->j_list_lock);
219 wait_on_buffer(bh);
220
221 BUFFER_TRACE(bh, "brelse");
222 __brelse(bh);
223 spin_lock(&journal->j_list_lock);
224 goto restart;
225 }
226 if (unlikely(buffer_write_io_error(bh)))
227 ret = -EIO;
228
229
230
231
232
233 released = __jbd2_journal_remove_checkpoint(jh);
234 __brelse(bh);
235 }
236
237 return ret;
238}
239
240static void
241__flush_batch(journal_t *journal, int *batch_count)
242{
243 int i;
244 struct blk_plug plug;
245
246 blk_start_plug(&plug);
247 for (i = 0; i < *batch_count; i++)
248 write_dirty_buffer(journal->j_chkpt_bhs[i], WRITE_SYNC);
249 blk_finish_plug(&plug);
250
251 for (i = 0; i < *batch_count; i++) {
252 struct buffer_head *bh = journal->j_chkpt_bhs[i];
253 BUFFER_TRACE(bh, "brelse");
254 __brelse(bh);
255 }
256 *batch_count = 0;
257}
258
259
260
261
262
263
264
265
266
267
268static int __process_buffer(journal_t *journal, struct journal_head *jh,
269 int *batch_count, transaction_t *transaction)
270{
271 struct buffer_head *bh = jh2bh(jh);
272 int ret = 0;
273
274 if (buffer_locked(bh)) {
275 get_bh(bh);
276 spin_unlock(&journal->j_list_lock);
277 wait_on_buffer(bh);
278
279 BUFFER_TRACE(bh, "brelse");
280 __brelse(bh);
281 ret = 1;
282 } else if (jh->b_transaction != NULL) {
283 transaction_t *t = jh->b_transaction;
284 tid_t tid = t->t_tid;
285
286 transaction->t_chp_stats.cs_forced_to_close++;
287 spin_unlock(&journal->j_list_lock);
288 if (unlikely(journal->j_flags & JBD2_UNMOUNT))
289
290
291
292
293
294 printk(KERN_ERR "JBD2: %s: "
295 "Waiting for Godot: block %llu\n",
296 journal->j_devname,
297 (unsigned long long) bh->b_blocknr);
298 jbd2_log_start_commit(journal, tid);
299 jbd2_log_wait_commit(journal, tid);
300 ret = 1;
301 } else if (!buffer_dirty(bh)) {
302 ret = 1;
303 if (unlikely(buffer_write_io_error(bh)))
304 ret = -EIO;
305 get_bh(bh);
306 BUFFER_TRACE(bh, "remove from checkpoint");
307 __jbd2_journal_remove_checkpoint(jh);
308 spin_unlock(&journal->j_list_lock);
309 __brelse(bh);
310 } else {
311
312
313
314
315
316
317
318 BUFFER_TRACE(bh, "queue");
319 get_bh(bh);
320 J_ASSERT_BH(bh, !buffer_jwrite(bh));
321 journal->j_chkpt_bhs[*batch_count] = bh;
322 __buffer_relink_io(jh);
323 transaction->t_chp_stats.cs_written++;
324 (*batch_count)++;
325 if (*batch_count == JBD2_NR_BATCH) {
326 spin_unlock(&journal->j_list_lock);
327 __flush_batch(journal, batch_count);
328 ret = 1;
329 }
330 }
331 return ret;
332}
333
334
335
336
337
338
339
340
341
342int jbd2_log_do_checkpoint(journal_t *journal)
343{
344 transaction_t *transaction;
345 tid_t this_tid;
346 int result;
347
348 jbd_debug(1, "Start checkpoint\n");
349
350
351
352
353
354
355 result = jbd2_cleanup_journal_tail(journal);
356 trace_jbd2_checkpoint(journal, result);
357 jbd_debug(1, "cleanup_journal_tail returned %d\n", result);
358 if (result <= 0)
359 return result;
360
361
362
363
364
365 result = 0;
366 spin_lock(&journal->j_list_lock);
367 if (!journal->j_checkpoint_transactions)
368 goto out;
369 transaction = journal->j_checkpoint_transactions;
370 if (transaction->t_chp_stats.cs_chp_time == 0)
371 transaction->t_chp_stats.cs_chp_time = jiffies;
372 this_tid = transaction->t_tid;
373restart:
374
375
376
377
378
379 if (journal->j_checkpoint_transactions == transaction &&
380 transaction->t_tid == this_tid) {
381 int batch_count = 0;
382 struct journal_head *jh;
383 int retry = 0, err;
384
385 while (!retry && transaction->t_checkpoint_list) {
386 jh = transaction->t_checkpoint_list;
387 retry = __process_buffer(journal, jh, &batch_count,
388 transaction);
389 if (retry < 0 && !result)
390 result = retry;
391 if (!retry && (need_resched() ||
392 spin_needbreak(&journal->j_list_lock))) {
393 spin_unlock(&journal->j_list_lock);
394 retry = 1;
395 break;
396 }
397 }
398
399 if (batch_count) {
400 if (!retry) {
401 spin_unlock(&journal->j_list_lock);
402 retry = 1;
403 }
404 __flush_batch(journal, &batch_count);
405 }
406
407 if (retry) {
408 spin_lock(&journal->j_list_lock);
409 goto restart;
410 }
411
412
413
414
415 err = __wait_cp_io(journal, transaction);
416 if (!result)
417 result = err;
418 }
419out:
420 spin_unlock(&journal->j_list_lock);
421 if (result < 0)
422 jbd2_journal_abort(journal, result);
423 else
424 result = jbd2_cleanup_journal_tail(journal);
425
426 return (result < 0) ? result : 0;
427}
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447int jbd2_cleanup_journal_tail(journal_t *journal)
448{
449 tid_t first_tid;
450 unsigned long blocknr;
451
452 if (is_journal_aborted(journal))
453 return -EIO;
454
455 if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr))
456 return 1;
457 J_ASSERT(blocknr != 0);
458
459
460
461
462
463
464
465
466
467 if (journal->j_flags & JBD2_BARRIER)
468 blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
469
470 return __jbd2_update_log_tail(journal, first_tid, blocknr);
471}
472
473
474
475
476
477
478
479
480
481
482
483
484
485static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy)
486{
487 struct journal_head *last_jh;
488 struct journal_head *next_jh = jh;
489 int ret;
490
491 if (!jh)
492 return 0;
493
494 last_jh = jh->b_cpprev;
495 do {
496 jh = next_jh;
497 next_jh = jh->b_cpnext;
498 if (!destroy)
499 ret = __try_to_free_cp_buf(jh);
500 else
501 ret = __jbd2_journal_remove_checkpoint(jh) + 1;
502 if (!ret)
503 return 0;
504 if (ret == 2)
505 return 1;
506
507
508
509
510
511
512 if (need_resched())
513 return 0;
514 } while (jh != last_jh);
515
516 return 0;
517}
518
519
520
521
522
523
524
525
526
527void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)
528{
529 transaction_t *transaction, *last_transaction, *next_transaction;
530 int ret;
531
532 transaction = journal->j_checkpoint_transactions;
533 if (!transaction)
534 return;
535
536 last_transaction = transaction->t_cpprev;
537 next_transaction = transaction;
538 do {
539 transaction = next_transaction;
540 next_transaction = transaction->t_cpnext;
541 ret = journal_clean_one_cp_list(transaction->t_checkpoint_list,
542 destroy);
543
544
545
546
547
548 if (need_resched())
549 return;
550 if (ret)
551 continue;
552
553
554
555
556
557 ret = journal_clean_one_cp_list(transaction->
558 t_checkpoint_io_list, destroy);
559 if (need_resched())
560 return;
561
562
563
564
565
566 if (!ret)
567 return;
568 } while (transaction != last_transaction);
569}
570
571
572
573
574
575void jbd2_journal_destroy_checkpoint(journal_t *journal)
576{
577
578
579
580
581 while (1) {
582 spin_lock(&journal->j_list_lock);
583 if (!journal->j_checkpoint_transactions) {
584 spin_unlock(&journal->j_list_lock);
585 break;
586 }
587 __jbd2_journal_clean_checkpoint_list(journal, true);
588 spin_unlock(&journal->j_list_lock);
589 cond_resched();
590 }
591}
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
612{
613 struct transaction_chp_stats_s *stats;
614 transaction_t *transaction;
615 journal_t *journal;
616 int ret = 0;
617
618 JBUFFER_TRACE(jh, "entry");
619
620 if ((transaction = jh->b_cp_transaction) == NULL) {
621 JBUFFER_TRACE(jh, "not on transaction");
622 goto out;
623 }
624 journal = transaction->t_journal;
625
626 JBUFFER_TRACE(jh, "removing from transaction");
627 __buffer_unlink(jh);
628 jh->b_cp_transaction = NULL;
629 jbd2_journal_put_journal_head(jh);
630
631 if (transaction->t_checkpoint_list != NULL ||
632 transaction->t_checkpoint_io_list != NULL)
633 goto out;
634
635
636
637
638
639
640
641
642
643
644 if (transaction->t_state != T_FINISHED)
645 goto out;
646
647
648
649 stats = &transaction->t_chp_stats;
650 if (stats->cs_chp_time)
651 stats->cs_chp_time = jbd2_time_diff(stats->cs_chp_time,
652 jiffies);
653 trace_jbd2_checkpoint_stats(journal->j_fs_dev->bd_dev,
654 transaction->t_tid, stats);
655
656 __jbd2_journal_drop_transaction(journal, transaction);
657 jbd2_journal_free_transaction(transaction);
658 ret = 1;
659out:
660 return ret;
661}
662
663
664
665
666
667
668
669
670
671void __jbd2_journal_insert_checkpoint(struct journal_head *jh,
672 transaction_t *transaction)
673{
674 JBUFFER_TRACE(jh, "entry");
675 J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
676 J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
677
678
679 jbd2_journal_grab_journal_head(jh2bh(jh));
680 jh->b_cp_transaction = transaction;
681
682 if (!transaction->t_checkpoint_list) {
683 jh->b_cpnext = jh->b_cpprev = jh;
684 } else {
685 jh->b_cpnext = transaction->t_checkpoint_list;
686 jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev;
687 jh->b_cpprev->b_cpnext = jh;
688 jh->b_cpnext->b_cpprev = jh;
689 }
690 transaction->t_checkpoint_list = jh;
691}
692
693
694
695
696
697
698
699
700
701
702
703void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction)
704{
705 assert_spin_locked(&journal->j_list_lock);
706 if (transaction->t_cpnext) {
707 transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
708 transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
709 if (journal->j_checkpoint_transactions == transaction)
710 journal->j_checkpoint_transactions =
711 transaction->t_cpnext;
712 if (journal->j_checkpoint_transactions == transaction)
713 journal->j_checkpoint_transactions = NULL;
714 }
715
716 J_ASSERT(transaction->t_state == T_FINISHED);
717 J_ASSERT(transaction->t_buffers == NULL);
718 J_ASSERT(transaction->t_forget == NULL);
719 J_ASSERT(transaction->t_shadow_list == NULL);
720 J_ASSERT(transaction->t_checkpoint_list == NULL);
721 J_ASSERT(transaction->t_checkpoint_io_list == NULL);
722 J_ASSERT(atomic_read(&transaction->t_updates) == 0);
723 J_ASSERT(journal->j_committing_transaction != transaction);
724 J_ASSERT(journal->j_running_transaction != transaction);
725
726 trace_jbd2_drop_transaction(journal, transaction);
727
728 jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
729}
730