UBIFS: seek journal heads to the latest bud in replay

This is the second fix of the following symptom:

UBIFS error (pid 34456): could not find an empty LEB

which sometimes happens after power cuts when we mount the file-system - UBIFS
refuses it with the above error message which comes from the
'ubifs_rcvry_gc_commit()' function. I can reproduce this using the integck test
with the UBIFS power cut emulation enabled.

Analysis of the problem.

Currently UBIFS replay seeks the journal heads to the last _replayed_ bud.
But the buds are replayed out-of-order, so the replay basically seeks journal
heads to the "random" bud belonging to this head, and not to the _last_ one.

The result of this is that the GC head may be seeked to a full LEB with no free
space, or very little free space. And 'ubifs_rcvry_gc_commit()' tries to find a
fully or mostly dirty LEB to match the current GC head (because we need to
garbage-collect that dirty LEB at one go, because we do not have @c->gc_lnum).
So 'ubifs_find_dirty_leb()' fails and we fall back to finding an empty LEB and
also fail. As a result - recovery fails and mounting fails.

This patch teaches the replay to initialize the GC heads exactly to the latest
buds, i.e. the buds which have the largest sequence number in corresponding
log reference nodes.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Cc: stable@kernel.org

+12 -6
+12 -6
fs/ubifs/replay.c
··· 59 59 * @new_size: truncation new size 60 60 * @free: amount of free space in a bud 61 61 * @dirty: amount of dirty space in a bud from padding and deletion nodes 62 + * @jhead: journal head number of the bud 62 63 * 63 64 * UBIFS journal replay must compare node sequence numbers, which means it must 64 65 * build a tree of node information to insert into the TNC. ··· 81 80 struct { 82 81 int free; 83 82 int dirty; 83 + int jhead; 84 84 }; 85 85 }; 86 86 }; ··· 161 159 err = PTR_ERR(lp); 162 160 goto out; 163 161 } 162 + 163 + /* Make sure the journal head points to the latest bud */ 164 + err = ubifs_wbuf_seek_nolock(&c->jheads[r->jhead].wbuf, r->lnum, 165 + c->leb_size - r->free, UBI_SHORTTERM); 166 + 164 167 out: 165 168 ubifs_release_lprops(c); 166 169 return err; ··· 634 627 ubifs_assert(sleb->endpt - offs >= used); 635 628 ubifs_assert(sleb->endpt % c->min_io_size == 0); 636 629 637 - if (sleb->endpt + c->min_io_size <= c->leb_size && !c->ro_mount) 638 - err = ubifs_wbuf_seek_nolock(&c->jheads[jhead].wbuf, lnum, 639 - sleb->endpt, UBI_SHORTTERM); 640 - 641 630 *dirty = sleb->endpt - offs - used; 642 631 *free = c->leb_size - sleb->endpt; 643 632 ··· 656 653 * @sqnum: sequence number 657 654 * @free: amount of free space in bud 658 655 * @dirty: amount of dirty space from padding and deletion nodes 656 + * @jhead: journal head number for the bud 659 657 * 660 658 * This function inserts a reference node to the replay tree and returns zero 661 659 * in case of success or a negative error code in case of failure. 662 660 */ 663 661 static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, 664 - unsigned long long sqnum, int free, int dirty) 662 + unsigned long long sqnum, int free, int dirty, 663 + int jhead) 665 664 { 666 665 struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; 667 666 struct replay_entry *r; ··· 693 688 r->flags = REPLAY_REF; 694 689 r->free = free; 695 690 r->dirty = dirty; 691 + r->jhead = jhead; 696 692 697 693 rb_link_node(&r->rb, parent, p); 698 694 rb_insert_color(&r->rb, &c->replay_tree); ··· 718 712 if (err) 719 713 return err; 720 714 err = insert_ref_node(c, b->bud->lnum, b->bud->start, b->sqnum, 721 - free, dirty); 715 + free, dirty, b->bud->jhead); 722 716 if (err) 723 717 return err; 724 718 }