Branch data Line data Source code
1 : : /*
2 : : * linux/fs/jbd2/checkpoint.c
3 : : *
4 : : * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
5 : : *
6 : : * Copyright 1999 Red Hat Software --- All Rights Reserved
7 : : *
8 : : * This file is part of the Linux kernel and is made available under
9 : : * the terms of the GNU General Public License, version 2, or at your
10 : : * option, any later version, incorporated herein by reference.
11 : : *
12 : : * Checkpoint routines for the generic filesystem journaling code.
13 : : * Part of the ext2fs journaling system.
14 : : *
15 : : * Checkpointing is the process of ensuring that a section of the log is
16 : : * committed fully to disk, so that that portion of the log can be
17 : : * reused.
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 : : * Unlink a buffer from a transaction checkpoint list.
30 : : *
31 : : * Called with j_list_lock held.
32 : : */
33 : : static inline void __buffer_unlink_first(struct journal_head *jh)
34 : : {
35 : : transaction_t *transaction = jh->b_cp_transaction;
36 : :
37 : 70065 : jh->b_cpnext->b_cpprev = jh->b_cpprev;
38 : 70065 : jh->b_cpprev->b_cpnext = jh->b_cpnext;
39 [ # # ][ + + ]: 70065 : if (transaction->t_checkpoint_list == jh) {
40 : 32651 : transaction->t_checkpoint_list = jh->b_cpnext;
41 [ # # ][ + + ]: 32651 : if (transaction->t_checkpoint_list == jh)
42 : 20600 : transaction->t_checkpoint_list = NULL;
43 : : }
44 : : }
45 : :
46 : : /*
47 : : * Unlink a buffer from a transaction checkpoint(io) list.
48 : : *
49 : : * Called with j_list_lock held.
50 : : */
51 : : static inline void __buffer_unlink(struct journal_head *jh)
52 : : {
53 : : transaction_t *transaction = jh->b_cp_transaction;
54 : :
55 : : __buffer_unlink_first(jh);
56 [ - + ]: 70065 : if (transaction->t_checkpoint_io_list == jh) {
57 : 0 : transaction->t_checkpoint_io_list = jh->b_cpnext;
58 [ # # ]: 0 : if (transaction->t_checkpoint_io_list == jh)
59 : 0 : transaction->t_checkpoint_io_list = NULL;
60 : : }
61 : : }
62 : :
63 : : /*
64 : : * Move a buffer from the checkpoint list to the checkpoint io list
65 : : *
66 : : * Called with j_list_lock held
67 : : */
68 : : static inline void __buffer_relink_io(struct journal_head *jh)
69 : : {
70 : 0 : transaction_t *transaction = jh->b_cp_transaction;
71 : :
72 : : __buffer_unlink_first(jh);
73 : :
74 [ # # ]: 0 : if (!transaction->t_checkpoint_io_list) {
75 : 0 : jh->b_cpnext = jh->b_cpprev = jh;
76 : : } else {
77 : 0 : jh->b_cpnext = transaction->t_checkpoint_io_list;
78 : 0 : jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
79 : 0 : jh->b_cpprev->b_cpnext = jh;
80 : 0 : jh->b_cpnext->b_cpprev = jh;
81 : : }
82 : 0 : transaction->t_checkpoint_io_list = jh;
83 : : }
84 : :
85 : : /*
86 : : * Try to release a checkpointed buffer from its transaction.
87 : : * Returns 1 if we released it and 2 if we also released the
88 : : * whole transaction.
89 : : *
90 : : * Requires j_list_lock
91 : : */
92 : 0 : static int __try_to_free_cp_buf(struct journal_head *jh)
93 : : {
94 : : int ret = 0;
95 : : struct buffer_head *bh = jh2bh(jh);
96 : :
97 [ + + ][ + + ]: 263410 : if (jh->b_transaction == NULL && !buffer_locked(bh) &&
[ + + ]
98 [ + - ]: 18155 : !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
99 : : /*
100 : : * Get our reference so that bh cannot be freed before
101 : : * we unlock it
102 : : */
103 : : get_bh(bh);
104 : : JBUFFER_TRACE(jh, "remove from checkpoint list");
105 : 18155 : ret = __jbd2_journal_remove_checkpoint(jh) + 1;
106 : : BUFFER_TRACE(bh, "release");
107 : 18155 : __brelse(bh);
108 : : }
109 : 0 : return ret;
110 : : }
111 : :
112 : : /*
113 : : * __jbd2_log_wait_for_space: wait until there is space in the journal.
114 : : *
115 : : * Called under j-state_lock *only*. It will be unlocked if we have to wait
116 : : * for a checkpoint to free up some space in the log.
117 : : */
118 : 0 : void __jbd2_log_wait_for_space(journal_t *journal)
119 : : {
120 : : int nblocks, space_left;
121 : : /* assert_spin_locked(&journal->j_state_lock); */
122 : :
123 : : nblocks = jbd2_space_needed(journal);
124 [ # # ]: 0 : while (jbd2_log_space_left(journal) < nblocks) {
125 [ # # ]: 0 : if (journal->j_flags & JBD2_ABORT)
126 : 0 : return;
127 : : write_unlock(&journal->j_state_lock);
128 : 0 : mutex_lock(&journal->j_checkpoint_mutex);
129 : :
130 : : /*
131 : : * Test again, another process may have checkpointed while we
132 : : * were waiting for the checkpoint lock. If there are no
133 : : * transactions ready to be checkpointed, try to recover
134 : : * journal space by calling cleanup_journal_tail(), and if
135 : : * that doesn't work, by waiting for the currently committing
136 : : * transaction to complete. If there is absolutely no way
137 : : * to make progress, this is either a BUG or corrupted
138 : : * filesystem, so abort the journal and leave a stack
139 : : * trace for forensic evidence.
140 : : */
141 : 0 : write_lock(&journal->j_state_lock);
142 : : spin_lock(&journal->j_list_lock);
143 : : nblocks = jbd2_space_needed(journal);
144 : 0 : space_left = jbd2_log_space_left(journal);
145 [ # # ]: 0 : if (space_left < nblocks) {
146 : 0 : int chkpt = journal->j_checkpoint_transactions != NULL;
147 : : tid_t tid = 0;
148 : :
149 [ # # ]: 0 : if (journal->j_committing_transaction)
150 : 0 : tid = journal->j_committing_transaction->t_tid;
151 : : spin_unlock(&journal->j_list_lock);
152 : : write_unlock(&journal->j_state_lock);
153 [ # # ]: 0 : if (chkpt) {
154 : 0 : jbd2_log_do_checkpoint(journal);
155 [ # # ]: 0 : } else if (jbd2_cleanup_journal_tail(journal) == 0) {
156 : : /* We were able to recover space; yay! */
157 : : ;
158 [ # # ]: 0 : } else if (tid) {
159 : : /*
160 : : * jbd2_journal_commit_transaction() may want
161 : : * to take the checkpoint_mutex if JBD2_FLUSHED
162 : : * is set. So we need to temporarily drop it.
163 : : */
164 : 0 : mutex_unlock(&journal->j_checkpoint_mutex);
165 : 0 : jbd2_log_wait_commit(journal, tid);
166 : 0 : write_lock(&journal->j_state_lock);
167 : 0 : continue;
168 : : } else {
169 : 0 : printk(KERN_ERR "%s: needed %d blocks and "
170 : : "only had %d space available\n",
171 : : __func__, nblocks, space_left);
172 : 0 : printk(KERN_ERR "%s: no way to get more "
173 : : "journal space in %s\n", __func__,
174 : 0 : journal->j_devname);
175 : 0 : WARN_ON(1);
176 : 0 : jbd2_journal_abort(journal, 0);
177 : : }
178 : 0 : write_lock(&journal->j_state_lock);
179 : : } else {
180 : : spin_unlock(&journal->j_list_lock);
181 : : }
182 : 0 : mutex_unlock(&journal->j_checkpoint_mutex);
183 : : }
184 : : }
185 : :
186 : : /*
187 : : * Clean up transaction's list of buffers submitted for io.
188 : : * We wait for any pending IO to complete and remove any clean
189 : : * buffers. Note that we take the buffers in the opposite ordering
190 : : * from the one in which they were submitted for IO.
191 : : *
192 : : * Return 0 on success, and return <0 if some buffers have failed
193 : : * to be written out.
194 : : *
195 : : * Called with j_list_lock held.
196 : : */
197 : 0 : static int __wait_cp_io(journal_t *journal, transaction_t *transaction)
198 : : {
199 : 0 : struct journal_head *jh;
200 : : struct buffer_head *bh;
201 : : tid_t this_tid;
202 : : int released = 0;
203 : : int ret = 0;
204 : :
205 : 0 : this_tid = transaction->t_tid;
206 : : restart:
207 : : /* Did somebody clean up the transaction in the meanwhile? */
208 [ # # ][ # # ]: 0 : if (journal->j_checkpoint_transactions != transaction ||
209 : 0 : transaction->t_tid != this_tid)
210 : : return ret;
211 [ # # ][ # # ]: 0 : while (!released && transaction->t_checkpoint_io_list) {
212 : : jh = transaction->t_checkpoint_io_list;
213 : : bh = jh2bh(jh);
214 : : get_bh(bh);
215 [ # # ]: 0 : if (buffer_locked(bh)) {
216 : : spin_unlock(&journal->j_list_lock);
217 : : wait_on_buffer(bh);
218 : : /* the journal_head may have gone by now */
219 : : BUFFER_TRACE(bh, "brelse");
220 : 0 : __brelse(bh);
221 : : spin_lock(&journal->j_list_lock);
222 : : goto restart;
223 : : }
224 [ # # ]: 0 : if (unlikely(buffer_write_io_error(bh)))
225 : : ret = -EIO;
226 : :
227 : : /*
228 : : * Now in whatever state the buffer currently is, we know that
229 : : * it has been written out and so we can drop it from the list
230 : : */
231 : 0 : released = __jbd2_journal_remove_checkpoint(jh);
232 : 0 : __brelse(bh);
233 : : }
234 : :
235 : : return ret;
236 : : }
237 : :
238 : : static void
239 : 0 : __flush_batch(journal_t *journal, int *batch_count)
240 : : {
241 : : int i;
242 : : struct blk_plug plug;
243 : :
244 : 0 : blk_start_plug(&plug);
245 [ # # ]: 0 : for (i = 0; i < *batch_count; i++)
246 : 0 : write_dirty_buffer(journal->j_chkpt_bhs[i], WRITE_SYNC);
247 : 0 : blk_finish_plug(&plug);
248 : :
249 [ # # ]: 0 : for (i = 0; i < *batch_count; i++) {
250 : 0 : struct buffer_head *bh = journal->j_chkpt_bhs[i];
251 : : BUFFER_TRACE(bh, "brelse");
252 : 0 : __brelse(bh);
253 : : }
254 : 0 : *batch_count = 0;
255 : 0 : }
256 : :
257 : : /*
258 : : * Try to flush one buffer from the checkpoint list to disk.
259 : : *
260 : : * Return 1 if something happened which requires us to abort the current
261 : : * scan of the checkpoint list. Return <0 if the buffer has failed to
262 : : * be written out.
263 : : *
264 : : * Called with j_list_lock held and drops it if 1 is returned
265 : : */
266 : 0 : static int __process_buffer(journal_t *journal, struct journal_head *jh,
267 : : int *batch_count, transaction_t *transaction)
268 : : {
269 : : struct buffer_head *bh = jh2bh(jh);
270 : : int ret = 0;
271 : :
272 [ # # ]: 0 : if (buffer_locked(bh)) {
273 : : get_bh(bh);
274 : : spin_unlock(&journal->j_list_lock);
275 : : wait_on_buffer(bh);
276 : : /* the journal_head may have gone by now */
277 : : BUFFER_TRACE(bh, "brelse");
278 : 0 : __brelse(bh);
279 : : ret = 1;
280 [ # # ]: 0 : } else if (jh->b_transaction != NULL) {
281 : : transaction_t *t = jh->b_transaction;
282 : 0 : tid_t tid = t->t_tid;
283 : :
284 : 0 : transaction->t_chp_stats.cs_forced_to_close++;
285 : : spin_unlock(&journal->j_list_lock);
286 [ # # ]: 0 : if (unlikely(journal->j_flags & JBD2_UNMOUNT))
287 : : /*
288 : : * The journal thread is dead; so starting and
289 : : * waiting for a commit to finish will cause
290 : : * us to wait for a _very_ long time.
291 : : */
292 : 0 : printk(KERN_ERR "JBD2: %s: "
293 : : "Waiting for Godot: block %llu\n",
294 : 0 : journal->j_devname,
295 : : (unsigned long long) bh->b_blocknr);
296 : 0 : jbd2_log_start_commit(journal, tid);
297 : 0 : jbd2_log_wait_commit(journal, tid);
298 : : ret = 1;
299 [ # # ]: 0 : } else if (!buffer_dirty(bh)) {
300 : : ret = 1;
301 [ # # ]: 0 : if (unlikely(buffer_write_io_error(bh)))
302 : : ret = -EIO;
303 : : get_bh(bh);
304 : : BUFFER_TRACE(bh, "remove from checkpoint");
305 : 0 : __jbd2_journal_remove_checkpoint(jh);
306 : : spin_unlock(&journal->j_list_lock);
307 : 0 : __brelse(bh);
308 : : } else {
309 : : /*
310 : : * Important: we are about to write the buffer, and
311 : : * possibly block, while still holding the journal lock.
312 : : * We cannot afford to let the transaction logic start
313 : : * messing around with this buffer before we write it to
314 : : * disk, as that would break recoverability.
315 : : */
316 : : BUFFER_TRACE(bh, "queue");
317 : : get_bh(bh);
318 [ # # ]: 0 : J_ASSERT_BH(bh, !buffer_jwrite(bh));
319 : 0 : journal->j_chkpt_bhs[*batch_count] = bh;
320 : : __buffer_relink_io(jh);
321 : 0 : transaction->t_chp_stats.cs_written++;
322 : 0 : (*batch_count)++;
323 [ # # ]: 0 : if (*batch_count == JBD2_NR_BATCH) {
324 : : spin_unlock(&journal->j_list_lock);
325 : 0 : __flush_batch(journal, batch_count);
326 : : ret = 1;
327 : : }
328 : : }
329 : 0 : return ret;
330 : : }
331 : :
332 : : /*
333 : : * Perform an actual checkpoint. We take the first transaction on the
334 : : * list of transactions to be checkpointed and send all its buffers
335 : : * to disk. We submit larger chunks of data at once.
336 : : *
337 : : * The journal should be locked before calling this function.
338 : : * Called with j_checkpoint_mutex held.
339 : : */
340 : 0 : int jbd2_log_do_checkpoint(journal_t *journal)
341 : : {
342 : : transaction_t *transaction;
343 : : tid_t this_tid;
344 : : int result;
345 : :
346 : : jbd_debug(1, "Start checkpoint\n");
347 : :
348 : : /*
349 : : * First thing: if there are any transactions in the log which
350 : : * don't need checkpointing, just eliminate them from the
351 : : * journal straight away.
352 : : */
353 : 0 : result = jbd2_cleanup_journal_tail(journal);
354 : : trace_jbd2_checkpoint(journal, result);
355 : : jbd_debug(1, "cleanup_journal_tail returned %d\n", result);
356 [ # # ]: 0 : if (result <= 0)
357 : : return result;
358 : :
359 : : /*
360 : : * OK, we need to start writing disk blocks. Take one transaction
361 : : * and write it.
362 : : */
363 : : result = 0;
364 : : spin_lock(&journal->j_list_lock);
365 [ # # ]: 0 : if (!journal->j_checkpoint_transactions)
366 : : goto out;
367 : : transaction = journal->j_checkpoint_transactions;
368 [ # # ]: 0 : if (transaction->t_chp_stats.cs_chp_time == 0)
369 : 0 : transaction->t_chp_stats.cs_chp_time = jiffies;
370 : 0 : this_tid = transaction->t_tid;
371 : : restart:
372 : : /*
373 : : * If someone cleaned up this transaction while we slept, we're
374 : : * done (maybe it's a new transaction, but it fell at the same
375 : : * address).
376 : : */
377 [ # # ][ # # ]: 0 : if (journal->j_checkpoint_transactions == transaction &&
378 : 0 : transaction->t_tid == this_tid) {
379 : 0 : int batch_count = 0;
380 : : struct journal_head *jh;
381 : : int retry = 0, err;
382 : :
383 [ # # ][ # # ]: 0 : while (!retry && transaction->t_checkpoint_list) {
384 : : jh = transaction->t_checkpoint_list;
385 : 0 : retry = __process_buffer(journal, jh, &batch_count,
386 : : transaction);
387 [ # # ]: 0 : if (retry < 0 && !result)
388 : : result = retry;
389 [ # # ][ # # ]: 0 : if (!retry && (need_resched() ||
390 : : spin_needbreak(&journal->j_list_lock))) {
391 : : spin_unlock(&journal->j_list_lock);
392 : : retry = 1;
393 : 0 : break;
394 : : }
395 : : }
396 : :
397 [ # # ]: 0 : if (batch_count) {
398 [ # # ]: 0 : if (!retry) {
399 : : spin_unlock(&journal->j_list_lock);
400 : : retry = 1;
401 : : }
402 : 0 : __flush_batch(journal, &batch_count);
403 : : }
404 : :
405 [ # # ]: 0 : if (retry) {
406 : : spin_lock(&journal->j_list_lock);
407 : 0 : goto restart;
408 : : }
409 : : /*
410 : : * Now we have cleaned up the first transaction's checkpoint
411 : : * list. Let's clean up the second one
412 : : */
413 : 0 : err = __wait_cp_io(journal, transaction);
414 [ # # ]: 0 : if (!result)
415 : : result = err;
416 : : }
417 : : out:
418 : : spin_unlock(&journal->j_list_lock);
419 [ # # ]: 0 : if (result < 0)
420 : 0 : jbd2_journal_abort(journal, result);
421 : : else
422 : 0 : result = jbd2_cleanup_journal_tail(journal);
423 : :
424 : 0 : return (result < 0) ? result : 0;
425 : : }
426 : :
427 : : /*
428 : : * Check the list of checkpoint transactions for the journal to see if
429 : : * we have already got rid of any since the last update of the log tail
430 : : * in the journal superblock. If so, we can instantly roll the
431 : : * superblock forward to remove those transactions from the log.
432 : : *
433 : : * Return <0 on error, 0 on success, 1 if there was nothing to clean up.
434 : : *
435 : : * Called with the journal lock held.
436 : : *
437 : : * This is the only part of the journaling code which really needs to be
438 : : * aware of transaction aborts. Checkpointing involves writing to the
439 : : * main filesystem area rather than to the journal, so it can proceed
440 : : * even in abort state, but we must not update the super block if
441 : : * checkpointing may have failed. Otherwise, we would lose some metadata
442 : : * buffers which should be written-back to the filesystem.
443 : : */
444 : :
445 : 0 : int jbd2_cleanup_journal_tail(journal_t *journal)
446 : : {
447 : : tid_t first_tid;
448 : : unsigned long blocknr;
449 : :
450 [ # # ]: 0 : if (is_journal_aborted(journal))
451 : : return 1;
452 : :
453 [ # # ]: 0 : if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr))
454 : : return 1;
455 [ # # ]: 0 : J_ASSERT(blocknr != 0);
456 : :
457 : : /*
458 : : * We need to make sure that any blocks that were recently written out
459 : : * --- perhaps by jbd2_log_do_checkpoint() --- are flushed out before
460 : : * we drop the transactions from the journal. It's unlikely this will
461 : : * be necessary, especially with an appropriately sized journal, but we
462 : : * need this to guarantee correctness. Fortunately
463 : : * jbd2_cleanup_journal_tail() doesn't get called all that often.
464 : : */
465 [ # # ]: 0 : if (journal->j_flags & JBD2_BARRIER)
466 : 0 : blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
467 : :
468 : 0 : __jbd2_update_log_tail(journal, first_tid, blocknr);
469 : 0 : return 0;
470 : : }
471 : :
472 : :
473 : : /* Checkpoint list management */
474 : :
475 : : /*
476 : : * journal_clean_one_cp_list
477 : : *
478 : : * Find all the written-back checkpoint buffers in the given list and
479 : : * release them.
480 : : *
481 : : * Called with the journal locked.
482 : : * Called with j_list_lock held.
483 : : * Returns number of buffers reaped (for debug)
484 : : */
485 : :
486 : 0 : static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
487 : : {
488 : : struct journal_head *last_jh;
489 : : struct journal_head *next_jh = jh;
490 : : int ret, freed = 0;
491 : :
492 : 90911 : *released = 0;
493 [ + + ]: 90911 : if (!jh)
494 : : return 0;
495 : :
496 : 45787 : last_jh = jh->b_cpprev;
497 : : do {
498 : : jh = next_jh;
499 : 263410 : next_jh = jh->b_cpnext;
500 : 263410 : ret = __try_to_free_cp_buf(jh);
501 [ + + ]: 263410 : if (ret) {
502 : 18155 : freed++;
503 [ + + ]: 18155 : if (ret == 2) {
504 : 660 : *released = 1;
505 : 660 : return freed;
506 : : }
507 : : }
508 : : /*
509 : : * This function only frees up some memory
510 : : * if possible so we dont have an obligation
511 : : * to finish processing. Bail out if preemption
512 : : * requested:
513 : : */
514 [ + + ]: 262750 : if (need_resched())
515 : : return freed;
516 [ + + ]: 262747 : } while (jh != last_jh);
517 : :
518 : : return freed;
519 : : }
520 : :
521 : : /*
522 : : * journal_clean_checkpoint_list
523 : : *
524 : : * Find all the written-back checkpoint buffers in the journal and release them.
525 : : *
526 : : * Called with the journal locked.
527 : : * Called with j_list_lock held.
528 : : * Returns number of buffers reaped (for debug)
529 : : */
530 : :
531 : 0 : int __jbd2_journal_clean_checkpoint_list(journal_t *journal)
532 : : {
533 : : transaction_t *transaction, *last_transaction, *next_transaction;
534 : : int ret = 0;
535 : : int released;
536 : :
537 : 20656 : transaction = journal->j_checkpoint_transactions;
538 [ + + ]: 20656 : if (!transaction)
539 : : goto out;
540 : :
541 : 20639 : last_transaction = transaction->t_cpprev;
542 : : next_transaction = transaction;
543 : : do {
544 : : transaction = next_transaction;
545 : 45787 : next_transaction = transaction->t_cpnext;
546 : 45787 : ret += journal_clean_one_cp_list(transaction->
547 : : t_checkpoint_list, &released);
548 : : /*
549 : : * This function only frees up some memory if possible so we
550 : : * dont have an obligation to finish processing. Bail out if
551 : : * preemption requested:
552 : : */
553 [ + + ]: 45787 : if (need_resched())
554 : : goto out;
555 [ + + ]: 45784 : if (released)
556 : 660 : continue;
557 : : /*
558 : : * It is essential that we are as careful as in the case of
559 : : * t_checkpoint_list with removing the buffer from the list as
560 : : * we can possibly see not yet submitted buffers on io_list
561 : : */
562 : 45124 : ret += journal_clean_one_cp_list(transaction->
563 : : t_checkpoint_io_list, &released);
564 [ + - ]: 45124 : if (need_resched())
565 : : goto out;
566 [ + + ]: 45784 : } while (transaction != last_transaction);
567 : : out:
568 : 0 : return ret;
569 : : }
570 : :
571 : : /*
572 : : * journal_remove_checkpoint: called after a buffer has been committed
573 : : * to disk (either by being write-back flushed to disk, or being
574 : : * committed to the log).
575 : : *
576 : : * We cannot safely clean a transaction out of the log until all of the
577 : : * buffer updates committed in that transaction have safely been stored
578 : : * elsewhere on disk. To achieve this, all of the buffers in a
579 : : * transaction need to be maintained on the transaction's checkpoint
580 : : * lists until they have been rewritten, at which point this function is
581 : : * called to remove the buffer from the existing transaction's
582 : : * checkpoint lists.
583 : : *
584 : : * The function returns 1 if it frees the transaction, 0 otherwise.
585 : : * The function can free jh and bh.
586 : : *
587 : : * This function is called with j_list_lock held.
588 : : */
589 : 0 : int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
590 : : {
591 : : struct transaction_chp_stats_s *stats;
592 : : transaction_t *transaction;
593 : : journal_t *journal;
594 : : int ret = 0;
595 : :
596 : : JBUFFER_TRACE(jh, "entry");
597 : :
598 [ + - ]: 70065 : if ((transaction = jh->b_cp_transaction) == NULL) {
599 : : JBUFFER_TRACE(jh, "not on transaction");
600 : : goto out;
601 : : }
602 : 70065 : journal = transaction->t_journal;
603 : :
604 : : JBUFFER_TRACE(jh, "removing from transaction");
605 : : __buffer_unlink(jh);
606 : 70065 : jh->b_cp_transaction = NULL;
607 : 70065 : jbd2_journal_put_journal_head(jh);
608 : :
609 [ + + ][ + - ]: 70065 : if (transaction->t_checkpoint_list != NULL ||
610 : 20600 : transaction->t_checkpoint_io_list != NULL)
611 : : goto out;
612 : :
613 : : /*
614 : : * There is one special case to worry about: if we have just pulled the
615 : : * buffer off a running or committing transaction's checkpoing list,
616 : : * then even if the checkpoint list is empty, the transaction obviously
617 : : * cannot be dropped!
618 : : *
619 : : * The locking here around t_state is a bit sleazy.
620 : : * See the comment at the end of jbd2_journal_commit_transaction().
621 : : */
622 [ + - ]: 20600 : if (transaction->t_state != T_FINISHED)
623 : : goto out;
624 : :
625 : : /* OK, that was the last buffer for the transaction: we can now
626 : : safely remove this transaction from the log */
627 : 20600 : stats = &transaction->t_chp_stats;
628 [ - + ]: 20600 : if (stats->cs_chp_time)
629 : 0 : stats->cs_chp_time = jbd2_time_diff(stats->cs_chp_time,
630 : : jiffies);
631 : 20600 : trace_jbd2_checkpoint_stats(journal->j_fs_dev->bd_dev,
632 : 20600 : transaction->t_tid, stats);
633 : :
634 : 0 : __jbd2_journal_drop_transaction(journal, transaction);
635 : 20600 : jbd2_journal_free_transaction(transaction);
636 : : ret = 1;
637 : : out:
638 : 70065 : return ret;
639 : : }
640 : :
641 : : /*
642 : : * journal_insert_checkpoint: put a committed buffer onto a checkpoint
643 : : * list so that we know when it is safe to clean the transaction out of
644 : : * the log.
645 : : *
646 : : * Called with the journal locked.
647 : : * Called with j_list_lock held.
648 : : */
649 : 0 : void __jbd2_journal_insert_checkpoint(struct journal_head *jh,
650 : : transaction_t *transaction)
651 : : {
652 : : JBUFFER_TRACE(jh, "entry");
653 [ + - ][ - + ]: 70418 : J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
654 [ - + ]: 70418 : J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
655 : :
656 : : /* Get reference for checkpointing transaction */
657 : 70418 : jbd2_journal_grab_journal_head(jh2bh(jh));
658 : 70418 : jh->b_cp_transaction = transaction;
659 : :
660 [ + + ]: 140836 : if (!transaction->t_checkpoint_list) {
661 : 20600 : jh->b_cpnext = jh->b_cpprev = jh;
662 : : } else {
663 : 49818 : jh->b_cpnext = transaction->t_checkpoint_list;
664 : 49818 : jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev;
665 : 49818 : jh->b_cpprev->b_cpnext = jh;
666 : 49818 : jh->b_cpnext->b_cpprev = jh;
667 : : }
668 : 70418 : transaction->t_checkpoint_list = jh;
669 : 70418 : }
670 : :
671 : : /*
672 : : * We've finished with this transaction structure: adios...
673 : : *
674 : : * The transaction must have no links except for the checkpoint by this
675 : : * point.
676 : : *
677 : : * Called with the journal locked.
678 : : * Called with j_list_lock held.
679 : : */
680 : :
681 : 0 : void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction)
682 : : {
683 [ - + ]: 20656 : assert_spin_locked(&journal->j_list_lock);
684 [ + - ]: 20656 : if (transaction->t_cpnext) {
685 : 20656 : transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
686 : 20656 : transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
687 [ + + ]: 20656 : if (journal->j_checkpoint_transactions == transaction)
688 : 8668 : journal->j_checkpoint_transactions =
689 : 8668 : transaction->t_cpnext;
690 [ + + ]: 20656 : if (journal->j_checkpoint_transactions == transaction)
691 : 7932 : journal->j_checkpoint_transactions = NULL;
692 : : }
693 : :
694 [ - + ]: 20656 : J_ASSERT(transaction->t_state == T_FINISHED);
695 [ - + ]: 20656 : J_ASSERT(transaction->t_buffers == NULL);
696 [ - + ]: 20656 : J_ASSERT(transaction->t_forget == NULL);
697 [ - + ]: 20656 : J_ASSERT(transaction->t_shadow_list == NULL);
698 [ - + ]: 20656 : J_ASSERT(transaction->t_checkpoint_list == NULL);
699 [ - + ]: 20656 : J_ASSERT(transaction->t_checkpoint_io_list == NULL);
700 [ - + ]: 20656 : J_ASSERT(atomic_read(&transaction->t_updates) == 0);
701 [ - + ]: 20656 : J_ASSERT(journal->j_committing_transaction != transaction);
702 [ - + ]: 20656 : J_ASSERT(journal->j_running_transaction != transaction);
703 : :
704 : : trace_jbd2_drop_transaction(journal, transaction);
705 : :
706 : : jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
707 : 0 : }
|