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