aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2024-11-11 17:01:20 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:46 +0100
commit410f5bb08c0dd44358822031e59f64b4b840bd9e (patch)
tree985820452e0c2857b4c46ab33b233b0a27daa33a /ubifs-utils
parent869f3ae30950469d0d4e730857469477d4872dd8 (diff)
fsck.ubifs: rebuild_fs: Write master node
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>
Diffstat (limited to 'ubifs-utils')
-rw-r--r--ubifs-utils/fsck.ubifs/rebuild_fs.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/ubifs-utils/fsck.ubifs/rebuild_fs.c b/ubifs-utils/fsck.ubifs/rebuild_fs.c
index 9ea4c22..382687b 100644
--- a/ubifs-utils/fsck.ubifs/rebuild_fs.c
+++ b/ubifs-utils/fsck.ubifs/rebuild_fs.c
@@ -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);
@@ -1345,6 +1346,75 @@ static int clean_log(struct ubifs_info *c)
}
/**
+ * 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;