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