]> www.infradead.org Git - mtd-utils.git/commitdiff
fsck.ubifs: rebuild_fs: Write master node
authorZhihao Cheng <chengzhihao1@huawei.com>
Mon, 11 Nov 2024 09:01:20 +0000 (17:01 +0800)
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>
Mon, 11 Nov 2024 09:32:46 +0000 (10:32 +0100)
This is the 12/12 step of rebuilding. Since all meta areas are ready,
master node can be updated. After this step, a consistent UBIFS image
can be mounted, and it should pass all tests from chk_fs, chk_general,
chk_index, chk_lprops and chk_orphans.

Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
ubifs-utils/fsck.ubifs/rebuild_fs.c

index 9ea4c224f8d6072d5aae874692b0f851eeb525c9..382687b34f356c947445459e172727fc5a1de862 100644 (file)
@@ -1126,6 +1126,7 @@ static int record_file_used_lebs(struct ubifs_info *c,
                 file->ino.is_xattr ? "xattr" :
                 ubifs_get_type_name(ubifs_get_dent_type(file->ino.mode)),
                 c->dev_name);
+       c->highest_inum = max_t(ino_t, c->highest_inum, file->inum);
 
        err = parse_node_info(c, &file->ino.header, &file->ino.key,
                              NULL, 0, idx_list, idx_cnt);
@@ -1344,6 +1345,75 @@ static int clean_log(struct ubifs_info *c)
        return 0;
 }
 
+/**
+ * write_master - write master nodes.
+ * @c: UBIFS file-system description object
+ *
+ * This function updates meta information into master node and writes master
+ * node into master area.
+ */
+static int write_master(struct ubifs_info *c)
+{
+       int err, lnum;
+       struct ubifs_mst_node *mst;
+
+       mst = kzalloc(c->mst_node_alsz, GFP_KERNEL);
+       if (!mst)
+               return -ENOMEM;
+
+       mst->ch.node_type = UBIFS_MST_NODE;
+       mst->log_lnum     = cpu_to_le32(UBIFS_LOG_LNUM);
+       mst->highest_inum = cpu_to_le64(c->highest_inum);
+       mst->cmt_no       = 0;
+       mst->root_lnum    = cpu_to_le32(c->zroot.lnum);
+       mst->root_offs    = cpu_to_le32(c->zroot.offs);
+       mst->root_len     = cpu_to_le32(c->zroot.len);
+       mst->gc_lnum      = cpu_to_le32(c->gc_lnum);
+       mst->ihead_lnum   = cpu_to_le32(c->ihead_lnum);
+       mst->ihead_offs   = cpu_to_le32(c->ihead_offs);
+       mst->index_size   = cpu_to_le64(c->calc_idx_sz);
+       mst->lpt_lnum     = cpu_to_le32(c->lpt_lnum);
+       mst->lpt_offs     = cpu_to_le32(c->lpt_offs);
+       mst->nhead_lnum   = cpu_to_le32(c->nhead_lnum);
+       mst->nhead_offs   = cpu_to_le32(c->nhead_offs);
+       mst->ltab_lnum    = cpu_to_le32(c->ltab_lnum);
+       mst->ltab_offs    = cpu_to_le32(c->ltab_offs);
+       mst->lsave_lnum   = cpu_to_le32(c->lsave_lnum);
+       mst->lsave_offs   = cpu_to_le32(c->lsave_offs);
+       mst->lscan_lnum   = cpu_to_le32(c->main_first);
+       mst->empty_lebs   = cpu_to_le32(c->lst.empty_lebs);
+       mst->idx_lebs     = cpu_to_le32(c->lst.idx_lebs);
+       mst->leb_cnt      = cpu_to_le32(c->leb_cnt);
+       mst->total_free   = cpu_to_le64(c->lst.total_free);
+       mst->total_dirty  = cpu_to_le64(c->lst.total_dirty);
+       mst->total_used   = cpu_to_le64(c->lst.total_used);
+       mst->total_dead   = cpu_to_le64(c->lst.total_dead);
+       mst->total_dark   = cpu_to_le64(c->lst.total_dark);
+       mst->flags        |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
+
+       lnum = UBIFS_MST_LNUM;
+       err = ubifs_leb_unmap(c, lnum);
+       if (err)
+               goto out;
+       err = ubifs_write_node_hmac(c, mst, UBIFS_MST_NODE_SZ, lnum, 0,
+                                   offsetof(struct ubifs_mst_node, hmac));
+       if (err)
+               goto out;
+       lnum++;
+       err = ubifs_leb_unmap(c, lnum);
+       if (err)
+               goto out;
+       err = ubifs_write_node_hmac(c, mst, UBIFS_MST_NODE_SZ, lnum, 0,
+                                   offsetof(struct ubifs_mst_node, hmac));
+       if (err)
+               goto out;
+
+out:
+       kfree(mst);
+
+       return err;
+}
+
 /**
  * ubifs_rebuild_filesystem - Rebuild filesystem.
  * @c: UBIFS file-system description object
@@ -1429,6 +1499,14 @@ int ubifs_rebuild_filesystem(struct ubifs_info *c)
                goto out;
        }
        err = ubifs_clear_orphans(c);
+       if (err) {
+               exit_code |= FSCK_ERROR;
+               goto out;
+       }
+
+       /* Step 12. Write master node. */
+       log_out(c, "Write master");
+       err = write_master(c);
        if (err)
                exit_code |= FSCK_ERROR;