aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/log.c20
-rw-r--r--fs/ubifs/recovery.c26
-rw-r--r--fs/ubifs/replay.c18
-rw-r--r--fs/ubifs/super.c44
4 files changed, 63 insertions, 45 deletions
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index 4d0cb1241460..40fa780ebea7 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -175,26 +175,6 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
175} 175}
176 176
177/** 177/**
178 * ubifs_create_buds_lists - create journal head buds lists for remount rw.
179 * @c: UBIFS file-system description object
180 */
181void ubifs_create_buds_lists(struct ubifs_info *c)
182{
183 struct rb_node *p;
184
185 spin_lock(&c->buds_lock);
186 p = rb_first(&c->buds);
187 while (p) {
188 struct ubifs_bud *bud = rb_entry(p, struct ubifs_bud, rb);
189 struct ubifs_jhead *jhead = &c->jheads[bud->jhead];
190
191 list_add_tail(&bud->list, &jhead->buds_list);
192 p = rb_next(p);
193 }
194 spin_unlock(&c->buds_lock);
195}
196
197/**
198 * ubifs_add_bud_to_log - add a new bud to the log. 178 * ubifs_add_bud_to_log - add a new bud to the log.
199 * @c: UBIFS file-system description object 179 * @c: UBIFS file-system description object
200 * @jhead: journal head the bud belongs to 180 * @jhead: journal head the bud belongs to
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 936f2cbfe6b6..3dbad6fbd1eb 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -317,6 +317,32 @@ int ubifs_recover_master_node(struct ubifs_info *c)
317 goto out_free; 317 goto out_free;
318 } 318 }
319 memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ); 319 memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ);
320
321 /*
322 * We had to recover the master node, which means there was an
323 * unclean reboot. However, it is possible that the master node
324 * is clean at this point, i.e., %UBIFS_MST_DIRTY is not set.
325 * E.g., consider the following chain of events:
326 *
327 * 1. UBIFS was cleanly unmounted, so the master node is clean
328 * 2. UBIFS is being mounted R/W and starts changing the master
329 * node in the first (%UBIFS_MST_LNUM). A power cut happens,
330 * so this LEB ends up with some amount of garbage at the
331 * end.
332 * 3. UBIFS is being mounted R/O. We reach this place and
333 * recover the master node from the second LEB
334 * (%UBIFS_MST_LNUM + 1). But we cannot update the media
335 * because we are being mounted R/O. We have to defer the
336 * operation.
337 * 4. However, this master node (@c->mst_node) is marked as
338 * clean (since the step 1). And if we just return, the
339 * mount code will be confused and won't recover the master
340 * node when it is re-mounter R/W later.
341 *
342 * Thus, to force the recovery by marking the master node as
343 * dirty.
344 */
345 c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY);
320 } else { 346 } else {
321 /* Write the recovered master node */ 347 /* Write the recovered master node */
322 c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1; 348 c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1;
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
162out: 169out:
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 */
660static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, 664static 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 }
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index c75f6133206c..04ad07f4fcc3 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1257,12 +1257,12 @@ static int mount_ubifs(struct ubifs_info *c)
1257 goto out_free; 1257 goto out_free;
1258 } 1258 }
1259 1259
1260 err = alloc_wbufs(c);
1261 if (err)
1262 goto out_cbuf;
1263
1260 sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); 1264 sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id);
1261 if (!c->ro_mount) { 1265 if (!c->ro_mount) {
1262 err = alloc_wbufs(c);
1263 if (err)
1264 goto out_cbuf;
1265
1266 /* Create background thread */ 1266 /* Create background thread */
1267 c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name); 1267 c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name);
1268 if (IS_ERR(c->bgt)) { 1268 if (IS_ERR(c->bgt)) {
@@ -1631,12 +1631,6 @@ static int ubifs_remount_rw(struct ubifs_info *c)
1631 if (err) 1631 if (err)
1632 goto out; 1632 goto out;
1633 1633
1634 err = alloc_wbufs(c);
1635 if (err)
1636 goto out;
1637
1638 ubifs_create_buds_lists(c);
1639
1640 /* Create background thread */ 1634 /* Create background thread */
1641 c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name); 1635 c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name);
1642 if (IS_ERR(c->bgt)) { 1636 if (IS_ERR(c->bgt)) {
@@ -1671,14 +1665,25 @@ static int ubifs_remount_rw(struct ubifs_info *c)
1671 if (err) 1665 if (err)
1672 goto out; 1666 goto out;
1673 1667
1668 dbg_gen("re-mounted read-write");
1669 c->remounting_rw = 0;
1670
1674 if (c->need_recovery) { 1671 if (c->need_recovery) {
1675 c->need_recovery = 0; 1672 c->need_recovery = 0;
1676 ubifs_msg("deferred recovery completed"); 1673 ubifs_msg("deferred recovery completed");
1674 } else {
1675 /*
1676 * Do not run the debugging space check if the were doing
1677 * recovery, because when we saved the information we had the
1678 * file-system in a state where the TNC and lprops has been
1679 * modified in memory, but all the I/O operations (including a
1680 * commit) were deferred. So the file-system was in
1681 * "non-committed" state. Now the file-system is in committed
1682 * state, and of course the amount of free space will change
1683 * because, for example, the old index size was imprecise.
1684 */
1685 err = dbg_check_space_info(c);
1677 } 1686 }
1678
1679 dbg_gen("re-mounted read-write");
1680 c->remounting_rw = 0;
1681 err = dbg_check_space_info(c);
1682 mutex_unlock(&c->umount_mutex); 1687 mutex_unlock(&c->umount_mutex);
1683 return err; 1688 return err;
1684 1689
@@ -1733,7 +1738,6 @@ static void ubifs_remount_ro(struct ubifs_info *c)
1733 if (err) 1738 if (err)
1734 ubifs_ro_mode(c, err); 1739 ubifs_ro_mode(c, err);
1735 1740
1736 free_wbufs(c);
1737 vfree(c->orph_buf); 1741 vfree(c->orph_buf);
1738 c->orph_buf = NULL; 1742 c->orph_buf = NULL;
1739 kfree(c->write_reserve_buf); 1743 kfree(c->write_reserve_buf);
@@ -1761,10 +1765,12 @@ static void ubifs_put_super(struct super_block *sb)
1761 * of the media. For example, there will be dirty inodes if we failed 1765 * of the media. For example, there will be dirty inodes if we failed
1762 * to write them back because of I/O errors. 1766 * to write them back because of I/O errors.
1763 */ 1767 */
1764 ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); 1768 if (!c->ro_error) {
1765 ubifs_assert(c->budg_idx_growth == 0); 1769 ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0);
1766 ubifs_assert(c->budg_dd_growth == 0); 1770 ubifs_assert(c->budg_idx_growth == 0);
1767 ubifs_assert(c->budg_data_growth == 0); 1771 ubifs_assert(c->budg_dd_growth == 0);
1772 ubifs_assert(c->budg_data_growth == 0);
1773 }
1768 1774
1769 /* 1775 /*
1770 * The 'c->umount_lock' prevents races between UBIFS memory shrinker 1776 * The 'c->umount_lock' prevents races between UBIFS memory shrinker