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 | } |
