aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/replay.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs/replay.c')
-rw-r--r--fs/ubifs/replay.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 0f50fbfe630f..6617280d1679 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -473,6 +473,65 @@ int ubifs_validate_entry(struct ubifs_info *c,
473} 473}
474 474
475/** 475/**
476 * is_last_bud - check if the bud is the last in the journal head.
477 * @c: UBIFS file-system description object
478 * @bud: bud description object
479 *
480 * This function checks if bud @bud is the last bud in its journal head. This
481 * information is then used by 'replay_bud()' to decide whether the bud can
482 * have corruptions or not. Indeed, only last buds can be corrupted by power
483 * cuts. Returns %1 if this is the last bud, and %0 if not.
484 */
485static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud)
486{
487 struct ubifs_jhead *jh = &c->jheads[bud->jhead];
488 struct ubifs_bud *next;
489 uint32_t data;
490 int err;
491
492 if (list_is_last(&bud->list, &jh->buds_list))
493 return 1;
494
495 /*
496 * The following is a quirk to make sure we work correctly with UBIFS
497 * images used with older UBIFS.
498 *
499 * Normally, the last bud will be the last in the journal head's list
500 * of bud. However, there is one exception if the UBIFS image belongs
501 * to older UBIFS. This is fairly unlikely: one would need to use old
502 * UBIFS, then have a power cut exactly at the right point, and then
503 * try to mount this image with new UBIFS.
504 *
505 * The exception is: it is possible to have 2 buds A and B, A goes
506 * before B, and B is the last, bud B is contains no data, and bud A is
507 * corrupted at the end. The reason is that in older versions when the
508 * journal code switched the next bud (from A to B), it first added a
509 * log reference node for the new bud (B), and only after this it
510 * synchronized the write-buffer of current bud (A). But later this was
511 * changed and UBIFS started to always synchronize the write-buffer of
512 * the bud (A) before writing the log reference for the new bud (B).
513 *
514 * But because older UBIFS always synchronized A's write-buffer before
515 * writing to B, we can recognize this exceptional situation but
516 * checking the contents of bud B - if it is empty, then A can be
517 * treated as the last and we can recover it.
518 *
519 * TODO: remove this piece of code in a couple of years (today it is
520 * 16.05.2011).
521 */
522 next = list_entry(bud->list.next, struct ubifs_bud, list);
523 if (!list_is_last(&next->list, &jh->buds_list))
524 return 0;
525
526 err = ubi_read(c->ubi, next->lnum, (char *)&data,
527 next->start, 4);
528 if (err)
529 return 0;
530
531 return data == 0xFFFFFFFF;
532}
533
534/**
476 * replay_bud - replay a bud logical eraseblock. 535 * replay_bud - replay a bud logical eraseblock.
477 * @c: UBIFS file-system description object 536 * @c: UBIFS file-system description object
478 * @b: bud entry which describes the bud 537 * @b: bud entry which describes the bud
@@ -483,15 +542,23 @@ int ubifs_validate_entry(struct ubifs_info *c,
483 */ 542 */
484static int replay_bud(struct ubifs_info *c, struct bud_entry *b) 543static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
485{ 544{
545 int is_last = is_last_bud(c, b->bud);
486 int err = 0, used = 0, lnum = b->bud->lnum, offs = b->bud->start; 546 int err = 0, used = 0, lnum = b->bud->lnum, offs = b->bud->start;
487 int jhead = b->bud->jhead;
488 struct ubifs_scan_leb *sleb; 547 struct ubifs_scan_leb *sleb;
489 struct ubifs_scan_node *snod; 548 struct ubifs_scan_node *snod;
490 549
491 dbg_mnt("replay bud LEB %d, head %d, offs %d", lnum, jhead, offs); 550 dbg_mnt("replay bud LEB %d, head %d, offs %d, is_last %d",
551 lnum, b->bud->jhead, offs, is_last);
492 552
493 if (c->need_recovery) 553 if (c->need_recovery && is_last)
494 sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, jhead != GCHD); 554 /*
555 * Recover only last LEBs in the journal heads, because power
556 * cuts may cause corruptions only in these LEBs, because only
557 * these LEBs could possibly be written to at the power cut
558 * time.
559 */
560 sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf,
561 b->bud->jhead != GCHD);
495 else 562 else
496 sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0); 563 sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0);
497 if (IS_ERR(sleb)) 564 if (IS_ERR(sleb))