[RFC PATCH mtd-utils 084/110] fsck.ubifs: Update files' size for check mode

Zhihao Cheng chengzhihao1 at huawei.com
Thu Jun 6 21:25:49 PDT 2024


This is the 7/18 step of fsck. Update files' size according to size
tree for check mode, now all files are updated after replaying journal.

Signed-off-by: Zhihao Cheng <chengzhihao1 at huawei.com>
---
 ubifs-utils/fsck.ubifs/check_files.c | 45 ++++++++++++++++++++++++++++++++++++
 ubifs-utils/fsck.ubifs/fsck.ubifs.c  |  3 +++
 ubifs-utils/fsck.ubifs/fsck.ubifs.h  |  1 +
 ubifs-utils/libubifs/recovery.c      | 16 -------------
 ubifs-utils/libubifs/ubifs.h         | 16 +++++++++++++
 5 files changed, 65 insertions(+), 16 deletions(-)

diff --git a/ubifs-utils/fsck.ubifs/check_files.c b/ubifs-utils/fsck.ubifs/check_files.c
index 29848c4e..0fd6b32a 100644
--- a/ubifs-utils/fsck.ubifs/check_files.c
+++ b/ubifs-utils/fsck.ubifs/check_files.c
@@ -309,3 +309,48 @@ out:
 	}
 	return err;
 }
+
+/**
+ * update_files_size - Update files' size.
+ * @c: UBIFS file-system description object
+ *
+ * This function updates files' size according to @c->size_tree for check mode.
+ */
+void update_files_size(struct ubifs_info *c)
+{
+	struct rb_node *this;
+
+	if (FSCK(c)->mode != CHECK_MODE) {
+		/* Other modes(rw) have updated inode size in place. */
+		dbg_fsck("skip updating files' size%s, in %s",
+			 mode_name(c), c->dev_name);
+		return;
+	}
+
+	log_out(c, "Update files' size");
+
+	this = rb_first(&c->size_tree);
+	while (this) {
+		struct size_entry *e;
+
+		e = rb_entry(this, struct size_entry, rb);
+		this = rb_next(this);
+
+		if (e->exists && e->i_size < e->d_size) {
+			struct scanned_file *file;
+
+			file = lookup_file(&FSCK(c)->scanned_files, e->inum);
+			if (file && file->ino.header.exist &&
+			    file->ino.size < e->d_size) {
+				dbg_fsck("update file(%lu) size %llu->%llu, in %s",
+					 e->inum, file->ino.size,
+					 (unsigned long long)e->d_size,
+					 c->dev_name);
+				file->ino.size = e->d_size;
+			}
+		}
+
+		rb_erase(&e->rb, &c->size_tree);
+		kfree(e);
+	}
+}
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c
index 1486ab4d..79b0babc 100644
--- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c
+++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c
@@ -443,6 +443,8 @@ static int do_fsck(void)
 		return err;
 	}
 
+	update_files_size(c);
+
 	kfree(FSCK(c)->used_lebs);
 	destroy_file_tree(c, &FSCK(c)->scanned_files);
 	return err;
@@ -481,6 +483,7 @@ int main(int argc, char *argv[])
 
 	/*
 	 * Step 6: Traverse tnc and construct files
+	 * Step 7: Update files' size
 	 */
 	err = do_fsck();
 	if (err && FSCK(c)->try_rebuild) {
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.h b/ubifs-utils/fsck.ubifs/fsck.ubifs.h
index 0d4a0d63..6c93eb6b 100644
--- a/ubifs-utils/fsck.ubifs/fsck.ubifs.h
+++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.h
@@ -298,5 +298,6 @@ int ubifs_rebuild_filesystem(struct ubifs_info *c);
 
 /* check_files.c */
 int traverse_tnc_and_construct_files(struct ubifs_info *c);
+void update_files_size(struct ubifs_info *c);
 
 #endif
diff --git a/ubifs-utils/libubifs/recovery.c b/ubifs-utils/libubifs/recovery.c
index a5133a0f..905e1645 100644
--- a/ubifs-utils/libubifs/recovery.c
+++ b/ubifs-utils/libubifs/recovery.c
@@ -1082,22 +1082,6 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
 }
 
 /**
- * struct size_entry - inode size information for recovery.
- * @rb: link in the RB-tree of sizes
- * @inum: inode number
- * @i_size: size on inode
- * @d_size: maximum size based on data nodes
- * @exists: indicates whether the inode exists
- */
-struct size_entry {
-	struct rb_node rb;
-	ino_t inum;
-	loff_t i_size;
-	loff_t d_size;
-	int exists;
-};
-
-/**
  * add_ino - add an entry to the size tree.
  * @c: UBIFS file-system description object
  * @inum: inode number
diff --git a/ubifs-utils/libubifs/ubifs.h b/ubifs-utils/libubifs/ubifs.h
index 03150cdb..72497cd9 100644
--- a/ubifs-utils/libubifs/ubifs.h
+++ b/ubifs-utils/libubifs/ubifs.h
@@ -1297,6 +1297,22 @@ static inline int ubifs_authenticated(const struct ubifs_info *c)
 	return c->authenticated;
 }
 
+/**
+ * struct size_entry - inode size information for recovery.
+ * @rb: link in the RB-tree of sizes
+ * @inum: inode number
+ * @i_size: size on inode
+ * @d_size: maximum size based on data nodes
+ * @exists: indicates whether the inode exists
+ */
+struct size_entry {
+	struct rb_node rb;
+	ino_t inum;
+	loff_t i_size;
+	loff_t d_size;
+	int exists;
+};
+
 #ifdef WITH_CRYPTO
 int ubifs_init_authentication(struct ubifs_info *c);
 int ubifs_shash_init(const struct ubifs_info *c, struct shash_desc *desc);
-- 
2.13.6




More information about the linux-mtd mailing list