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