All of lore.kernel.org
 help / color / mirror / Atom feed
* [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO
@ 2021-06-21  2:39 Jaegeuk Kim
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map Jaegeuk Kim
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Jaegeuk Kim @ 2021-06-21  2:39 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

We don't need to enable all android features for RO.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 mkfs/f2fs_format_main.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
index 03eb748170ad..031244d5d67a 100644
--- a/mkfs/f2fs_format_main.c
+++ b/mkfs/f2fs_format_main.c
@@ -110,11 +110,16 @@ static void add_default_options(void)
 		/* -d1 -f -O encrypt -O quota -O verity -w 4096 -R 0:0 */
 		c.dbg_lv = 1;
 		force_overwrite = 1;
+		c.wanted_sector_size = 4096;
+		c.root_uid = c.root_gid = 0;
+
+		/* RO doesn't need any other features */
+		if (c.feature & cpu_to_le32(F2FS_FEATURE_RO))
+			return;
+
 		c.feature |= cpu_to_le32(F2FS_FEATURE_ENCRYPT);
 		c.feature |= cpu_to_le32(F2FS_FEATURE_QUOTA_INO);
 		c.feature |= cpu_to_le32(F2FS_FEATURE_VERITY);
-		c.wanted_sector_size = 4096;
-		c.root_uid = c.root_gid = 0;
 		break;
 	}
 #ifdef CONF_CASEFOLD
-- 
2.32.0.288.g62a8d224e6-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map
  2021-06-21  2:39 [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Jaegeuk Kim
@ 2021-06-21  2:39 ` Jaegeuk Kim
  2021-06-23 14:28   ` Chao Yu
  2021-06-23 16:04   ` [f2fs-dev] [PATCH 2/4 v2] " Jaegeuk Kim
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset Jaegeuk Kim
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 10+ messages in thread
From: Jaegeuk Kim @ 2021-06-21  2:39 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

This option shows all the file names in the disk.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/dump.c       | 74 ++++++++++++++++++++++++++++++++++++++++++-----
 fsck/fsck.c       | 64 +++++++++++++++++++++++++++++++++++-----
 fsck/fsck.h       | 15 ++++++++--
 fsck/main.c       | 15 ++++++++--
 fsck/mount.c      |  3 ++
 include/f2fs_fs.h |  7 +++--
 lib/libf2fs.c     | 11 ++++++-
 man/dump.f2fs.8   |  7 +++++
 man/fsck.f2fs.8   |  7 +++++
 9 files changed, 179 insertions(+), 24 deletions(-)

diff --git a/fsck/dump.c b/fsck/dump.c
index 042a2e52edca..f9ef5725c7be 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -23,6 +23,9 @@
 
 #define BUF_SZ	80
 
+/* current extent info */
+struct extent_info dump_extent = { 0, 0, 0};
+
 const char *seg_type_name[SEG_TYPE_MAX + 1] = {
 	"SEG_TYPE_DATA",
 	"SEG_TYPE_CUR_DATA",
@@ -227,10 +230,51 @@ void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa)
 	close(fd);
 }
 
+static void print_extent(bool last)
+{
+	if (dump_extent.len == 0)
+		goto out;
+
+	if (dump_extent.len == 1)
+		printf(" %d", dump_extent.blk);
+	else
+		printf(" %d-%d",
+			dump_extent.blk,
+			dump_extent.blk + dump_extent.len - 1);
+	dump_extent.len = 0;
+out:
+	if (last)
+		printf("\n");
+}
+
 static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
 {
 	char buf[F2FS_BLKSIZE];
 
+	if (c.show_file_map) {
+		if (c.show_file_map_max_offset < offset) {
+			ASSERT(blkaddr == NULL_ADDR);
+			return;
+		}
+		if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR ||
+					blkaddr == COMPRESS_ADDR) {
+			print_extent(false);
+			dump_extent.blk = 0;
+			dump_extent.len = 1;
+			print_extent(false);
+		} else if (dump_extent.len == 0) {
+			dump_extent.blk = blkaddr;
+			dump_extent.len = 1;
+		} else if (dump_extent.blk + dump_extent.len == blkaddr) {
+			dump_extent.len++;
+		} else {
+			print_extent(false);
+			dump_extent.blk = blkaddr;
+			dump_extent.len = 1;
+		}
+		return;
+	}
+
 	if (blkaddr == NULL_ADDR)
 		return;
 
@@ -239,6 +283,7 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
 		memset(buf, 0, F2FS_BLKSIZE);
 	} else {
 		int ret;
+
 		ret = dev_read_block(buf, blkaddr);
 		ASSERT(ret >= 0);
 	}
@@ -371,7 +416,7 @@ static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi),
 }
 #endif
 
-static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
+static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 					struct f2fs_node *node_blk)
 {
 	u32 i = 0;
@@ -382,9 +427,11 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 		/* recover from inline data */
 		dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET,
 						0, MAX_INLINE_DATA(node_blk));
-		return;
+		return -1;
 	}
 
+	c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i);
+
 	/* check data blocks in inode */
 	for (i = 0; i < ADDRS_PER_INODE(&node_blk->i); i++, ofs++)
 		dump_data_blk(sbi, ofs * F2FS_BLKSIZE, le32_to_cpu(
@@ -404,11 +451,14 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 		else
 			ASSERT(0);
 	}
+	/* last block in extent cache */
+	print_extent(true);
 
 	dump_xattr(sbi, node_blk);
+	return 0;
 }
 
-static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
+static int dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
 				struct f2fs_node *node_blk, int force)
 {
 	struct f2fs_inode *inode = &node_blk->i;
@@ -422,17 +472,21 @@ static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
 
 	if (is_encrypted) {
 		MSG(force, "File is encrypted\n");
-		return;
+		return -1;
 	}
 
 	if ((!S_ISREG(imode) && !S_ISLNK(imode)) ||
 				namelen == 0 || namelen > F2FS_NAME_LEN) {
 		MSG(force, "Not a regular file or wrong name info\n\n");
-		return;
+		return -1;
 	}
 	if (force)
 		goto dump;
 
+	/* dump file's data */
+	if (c.show_file_map)
+		return dump_inode_blk(sbi, ni->ino, node_blk);
+
 	printf("Do you want to dump this file into ./lost_found/? [Y/N] ");
 	ret = scanf("%s", ans);
 	ASSERT(ret >= 0);
@@ -459,6 +513,7 @@ dump:
 
 		close(c.dump_fd);
 	}
+	return 0;
 }
 
 static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
@@ -473,10 +528,11 @@ static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
 			(const char *)se->cur_valid_map) != 0;
 }
 
-void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
+int dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
 {
 	struct node_info ni;
 	struct f2fs_node *node_blk;
+	int ret = 0;
 
 	get_node_info(sbi, nid, &ni);
 
@@ -505,16 +561,18 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
 
 	if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
 			le32_to_cpu(node_blk->footer.nid) == ni.nid) {
-		print_node_info(sbi, node_blk, force);
+		if (!c.show_file_map)
+			print_node_info(sbi, node_blk, force);
 
 		if (ni.ino == ni.nid)
-			dump_file(sbi, &ni, node_blk, force);
+			ret = dump_file(sbi, &ni, node_blk, force);
 	} else {
 		print_node_info(sbi, node_blk, force);
 		MSG(force, "Invalid (i)node block\n\n");
 	}
 out:
 	free(node_blk);
+	return ret;
 }
 
 static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 80a6d8edfe71..2c741c16124f 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -695,6 +695,8 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 
 	if (ftype == F2FS_FT_DIR) {
 		f2fs_set_main_bitmap(sbi, ni->blk_addr, CURSEG_HOT_NODE);
+		memcpy(child.p_name, node_blk->i.i_name,
+					node_blk->i.i_namelen);;
 	} else {
 		if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
 			f2fs_set_main_bitmap(sbi, ni->blk_addr,
@@ -1298,10 +1300,12 @@ void pretty_print_filename(const u8 *raw_name, u32 len,
 	out[len] = 0;
 }
 
-static void print_dentry(__u32 depth, __u8 *name,
+static void print_dentry(struct f2fs_sb_info *sbi, __u8 *name,
 		u8 *bitmap, struct f2fs_dir_entry *dentry,
 		int max, int idx, int last_blk, int enc_name)
 {
+	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+	u32 depth = fsck->dentry_depth;
 	int last_de = 0;
 	int next_idx = 0;
 	u32 name_len;
@@ -1309,7 +1313,7 @@ static void print_dentry(__u32 depth, __u8 *name,
 	int bit_offset;
 	char new[F2FS_PRINT_NAMELEN];
 
-	if (!c.show_dentry)
+	if (!c.show_dentry && !c.show_file_map)
 		return;
 
 	name_len = le16_to_cpu(dentry[idx].name_len);
@@ -1334,15 +1338,31 @@ static void print_dentry(__u32 depth, __u8 *name,
 	if (tree_mark[depth - 1] == '`')
 		tree_mark[depth - 1] = ' ';
 
-	for (i = 1; i < depth; i++)
-		printf("%c   ", tree_mark[i]);
-
 	pretty_print_filename(name, name_len, new, enc_name);
 
-	printf("%c-- %s <ino = 0x%x>, <encrypted (%d)>\n",
+	if (c.show_file_map) {
+		struct f2fs_dentry *d = fsck->dentry;
+
+		if (dentry[idx].file_type != F2FS_FT_REG_FILE)
+			return;
+
+		while (d) {
+			if (d->depth > 1)
+				printf("/%s", d->name);
+			d = d->next;
+		}
+		printf("/%s", new);
+		if (dump_node(sbi, le32_to_cpu(dentry[idx].ino), 0))
+			printf("\33[2K\r");
+	} else {
+		for (i = 1; i < depth; i++)
+			printf("%c   ", tree_mark[i]);
+
+		printf("%c-- %s <ino = 0x%x>, <encrypted (%d)>\n",
 			last_de ? '`' : '|',
 			new, le32_to_cpu(dentry[idx].ino),
 			enc_name);
+	}
 }
 
 static int f2fs_check_hash_code(int encoding, int casefolded,
@@ -1609,7 +1629,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, int casefolded,
 				le32_to_cpu(dentry[i].ino),
 				dentry[i].file_type);
 
-		print_dentry(fsck->dentry_depth, name, bitmap,
+		print_dentry(sbi, name, bitmap,
 				dentry, max, i, last_blk, enc_name);
 
 		blk_cnt = 1;
@@ -1645,6 +1665,8 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
 		struct f2fs_node *node_blk, struct child_info *child)
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+	struct f2fs_dentry *cur_dentry = fsck->dentry_end;
+	struct f2fs_dentry *new_dentry;
 	struct f2fs_dentry_ptr d;
 	void *inline_dentry;
 	int dentries;
@@ -1655,6 +1677,12 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
 	make_dentry_ptr(&d, node_blk, inline_dentry, 2);
 
 	fsck->dentry_depth++;
+	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);
+	new_dentry->depth = fsck->dentry_depth;
+	memcpy(new_dentry->name, child->p_name, F2FS_NAME_LEN);
+	cur_dentry->next = new_dentry;
+	fsck->dentry_end = new_dentry;
+
 	dentries = __chk_dentries(sbi, IS_CASEFOLDED(&node_blk->i), child,
 			d.bitmap, d.dentry, d.filename, d.max, 1,
 			file_is_encrypt(&node_blk->i));// pass through
@@ -1667,6 +1695,10 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
 			fsck->dentry_depth, dentries,
 			d.max, F2FS_NAME_LEN);
 	}
+	fsck->dentry = cur_dentry;
+	fsck->dentry_end =cur_dentry;
+	cur_dentry->next = NULL;
+	free(new_dentry);
 	fsck->dentry_depth--;
 	return dentries;
 }
@@ -1676,6 +1708,8 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 	struct f2fs_dentry_block *de_blk;
+	struct f2fs_dentry *cur_dentry = fsck->dentry_end;
+	struct f2fs_dentry *new_dentry;
 	int dentries, ret;
 
 	de_blk = (struct f2fs_dentry_block *)calloc(BLOCK_SZ, 1);
@@ -1685,6 +1719,12 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
 	ASSERT(ret >= 0);
 
 	fsck->dentry_depth++;
+	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);
+	new_dentry->depth = fsck->dentry_depth;
+	memcpy(new_dentry->name, child->p_name, F2FS_NAME_LEN);
+	cur_dentry->next = new_dentry;
+	fsck->dentry_end = new_dentry;
+
 	dentries = __chk_dentries(sbi, casefolded, child,
 			de_blk->dentry_bitmap,
 			de_blk->dentry, de_blk->filename,
@@ -1701,6 +1741,10 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
 			fsck->dentry_depth, blk_addr, dentries,
 			NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN);
 	}
+	fsck->dentry = cur_dentry;
+	fsck->dentry_end =cur_dentry;
+	cur_dentry->next = NULL;
+	free(new_dentry);
 	fsck->dentry_depth--;
 	free(de_blk);
 	return 0;
@@ -2061,6 +2105,9 @@ void fsck_init(struct f2fs_sb_info *sbi)
 	ASSERT(tree_mark_size != 0);
 	tree_mark = calloc(tree_mark_size, 1);
 	ASSERT(tree_mark != NULL);
+	fsck->dentry = calloc(sizeof(struct f2fs_dentry), 1);
+	memcpy(fsck->dentry->name, "/", 1);
+	fsck->dentry_end = fsck->dentry;
 }
 
 static void fix_hard_links(struct f2fs_sb_info *sbi)
@@ -3022,6 +3069,9 @@ int fsck_verify(struct f2fs_sb_info *sbi)
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 	struct hard_link_node *node = NULL;
 
+	if (c.show_file_map)
+		return 0;
+
 	printf("\n");
 
 	if (c.zoned_model == F2FS_ZONED_HM) {
diff --git a/fsck/fsck.h b/fsck/fsck.h
index b9dcd5c27982..6b3246aa57fa 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -72,13 +72,20 @@ struct child_info {
 	u32 pgofs;
 	u8 dots;
 	u8 dir_level;
-	u32 p_ino;		/*parent ino*/
-	u32 pp_ino;		/*parent parent ino*/
+	u32 p_ino;		/* parent ino */
+	char p_name[F2FS_NAME_LEN]; /* parent name */
+	u32 pp_ino;		/* parent parent ino*/
 	struct extent_info ei;
 	u32 last_blk;
 	u32 i_namelen;  /* dentry namelen */
 };
 
+struct f2fs_dentry {
+	char name[F2FS_NAME_LEN];
+	int depth;
+	struct f2fs_dentry *next;
+};
+
 struct f2fs_fsck {
 	struct f2fs_sb_info sbi;
 
@@ -110,6 +117,8 @@ struct f2fs_fsck {
 	u32 nr_nat_entries;
 
 	u32 dentry_depth;
+	struct f2fs_dentry *dentry;
+	struct f2fs_dentry *dentry_end;
 	struct f2fs_nat_entry *entries;
 	u32 nat_valid_inode_cnt;
 
@@ -253,7 +262,7 @@ struct dump_option {
 extern void nat_dump(struct f2fs_sb_info *, nid_t, nid_t);
 extern void sit_dump(struct f2fs_sb_info *, unsigned int, unsigned int);
 extern void ssa_dump(struct f2fs_sb_info *, int, int);
-extern void dump_node(struct f2fs_sb_info *, nid_t, int);
+extern int dump_node(struct f2fs_sb_info *, nid_t, int);
 extern int dump_info_from_blkaddr(struct f2fs_sb_info *, u32);
 extern unsigned int start_bidx_of_node(unsigned int, struct f2fs_node *);
 
diff --git a/fsck/main.c b/fsck/main.c
index c0b871b48276..bea5e0ff5c33 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -72,6 +72,7 @@ void fsck_usage()
 	MSG(0, "  -f check/fix entire partition\n");
 	MSG(0, "  -g add default options\n");
 	MSG(0, "  -l show superblock/checkpoint\n");
+	MSG(0, "  -M show a file map\n");
 	MSG(0, "  -O feature1[feature2,feature3,...] e.g. \"encrypt\"\n");
 	MSG(0, "  -p preen mode [default:0 the same as -a [0|1]]\n");
 	MSG(0, "  -S sparse_mode\n");
@@ -93,6 +94,7 @@ void dump_usage()
 	MSG(0, "  -d debug level [default:0]\n");
 	MSG(0, "  -i inode no (hex)\n");
 	MSG(0, "  -n [NAT dump nid from #1~#2 (decimal), for all 0~-1]\n");
+	MSG(0, "  -M show a block map\n");
 	MSG(0, "  -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]\n");
 	MSG(0, "  -S sparse_mode\n");
 	MSG(0, "  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
@@ -228,7 +230,7 @@ void f2fs_parse_options(int argc, char *argv[])
 	}
 
 	if (!strcmp("fsck.f2fs", prog)) {
-		const char *option_string = ":aC:c:m:d:fg:lO:p:q:StyV";
+		const char *option_string = ":aC:c:m:Md:fg:lO:p:q:StyV";
 		int opt = 0, val;
 		char *token;
 		struct option long_opt[] = {
@@ -278,6 +280,9 @@ void f2fs_parse_options(int argc, char *argv[])
 			case 'l':
 				c.layout = 1;
 				break;
+			case 'M':
+				c.show_file_map = 1;
+				break;
 			case 'O':
 				if (parse_feature(feature_table, optarg))
 					fsck_usage();
@@ -377,7 +382,7 @@ void f2fs_parse_options(int argc, char *argv[])
 		}
 	} else if (!strcmp("dump.f2fs", prog)) {
 #ifdef WITH_DUMP
-		const char *option_string = "d:i:n:s:Sa:b:V";
+		const char *option_string = "d:i:n:Ms:Sa:b:V";
 		static struct dump_option dump_opt = {
 			.nid = 0,	/* default root ino */
 			.start_nat = -1,
@@ -424,6 +429,9 @@ void f2fs_parse_options(int argc, char *argv[])
 							&dump_opt.start_nat,
 							&dump_opt.end_nat);
 				break;
+			case 'M':
+				c.show_file_map = 1;
+				break;
 			case 's':
 				ret = sscanf(optarg, "%d~%d",
 							&dump_opt.start_sit,
@@ -1209,7 +1217,8 @@ retry:
 	if (c.func == SLOAD)
 		c.compress.filter_ops->destroy();
 
-	printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0);
+	if (!c.show_file_map)
+		printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0);
 	return ret;
 
 out_err:
diff --git a/fsck/mount.c b/fsck/mount.c
index de692b62e1c2..598410e5f4fa 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -489,6 +489,9 @@ printout:
 
 void print_cp_state(u32 flag)
 {
+	if (c.show_file_map)
+		return;
+
 	MSG(0, "Info: checkpoint state = %x : ", flag);
 	if (flag & CP_QUOTA_NEED_FSCK_FLAG)
 		MSG(0, "%s", " quota_need_fsck");
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 8969ae2ebc34..45f72573dadd 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -240,14 +240,14 @@ static inline uint64_t bswap_64(uint64_t val)
 
 #define MSG(n, fmt, ...)						\
 	do {								\
-		if (c.dbg_lv >= n && !c.layout) {			\
+		if (c.dbg_lv >= n && !c.layout && !c.show_file_map) {	\
 			printf(fmt, ##__VA_ARGS__);			\
 		}							\
 	} while (0)
 
 #define DBG(n, fmt, ...)						\
 	do {								\
-		if (c.dbg_lv >= n && !c.layout) {			\
+		if (c.dbg_lv >= n && !c.layout && !c.show_file_map) {	\
 			printf("[%s:%4d] " fmt,				\
 				__func__, __LINE__, ##__VA_ARGS__);	\
 		}							\
@@ -491,6 +491,8 @@ struct f2fs_configuration {
 	int alloc_failed;
 	int auto_fix;
 	int layout;
+	int show_file_map;
+	u64 show_file_map_max_offset;
 	int quota_fix;
 	int preen_mode;
 	int ro;
@@ -1298,6 +1300,7 @@ extern int utf16_to_utf8(char *, const u_int16_t *, size_t, size_t);
 extern int log_base_2(u_int32_t);
 extern unsigned int addrs_per_inode(struct f2fs_inode *);
 extern unsigned int addrs_per_block(struct f2fs_inode *);
+extern unsigned int f2fs_max_file_offset(struct f2fs_inode *);
 extern __u32 f2fs_inode_chksum(struct f2fs_node *);
 extern __u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *);
 extern int write_inode(struct f2fs_node *, u64);
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 0add9018d2ce..876c1dc848b3 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -499,7 +499,8 @@ opaque_seq:
 	return __f2fs_dentry_hash(name, len);
 }
 
-#define ALIGN_DOWN(addrs, size)		(((addrs) / (size)) * (size))
+#define ALIGN_DOWN(addrs, size)	(((addrs) / (size)) * (size))
+#define ALIGN_UP(addrs, size)	ALIGN_DOWN(((addrs) + (size) - 1), (size))
 unsigned int addrs_per_inode(struct f2fs_inode *i)
 {
 	unsigned int addrs = CUR_ADDRS_PER_INODE(i) - get_inline_xattr_addrs(i);
@@ -518,6 +519,14 @@ unsigned int addrs_per_block(struct f2fs_inode *i)
 	return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, 1 << i->i_log_cluster_size);
 }
 
+unsigned int f2fs_max_file_offset(struct f2fs_inode *i)
+{
+	if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
+			!(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
+		return le64_to_cpu(i->i_size);
+	return ALIGN_UP(le64_to_cpu(i->i_size), 1 << i->i_log_cluster_size);
+}
+
 /*
  * CRC32
  */
diff --git a/man/dump.f2fs.8 b/man/dump.f2fs.8
index eedba855721f..1ddb7fc5d0d9 100644
--- a/man/dump.f2fs.8
+++ b/man/dump.f2fs.8
@@ -14,6 +14,10 @@ dump.f2fs \- retrieve directory and file entries from an F2FS-formated image
 .I NAT range
 ]
 [
+.B \-M
+.I Block map
+]
+[
 .B \-s
 .I SIT range
 ]
@@ -51,6 +55,9 @@ Specify an inode number to dump out.
 .BI \-n " NAT range"
 Specify a range presented by nids to dump NAT entries.
 .TP
+.BI \-M " Block map"
+Show all the allocated block addresses given inode number.
+.TP
 .BI \-s " SIT range"
 Specify a range presented by segment numbers to dump SIT entries.
 .TP
diff --git a/man/fsck.f2fs.8 b/man/fsck.f2fs.8
index af1076cb72bc..aff4ff24a2e1 100644
--- a/man/fsck.f2fs.8
+++ b/man/fsck.f2fs.8
@@ -14,6 +14,10 @@ fsck.f2fs \- check a Linux F2FS file system
 .I enable force fix
 ]
 [
+.B \-M
+.I show file map
+]
+[
 .B \-p
 .I enable preen mode
 ]
@@ -44,6 +48,9 @@ module. It is disabled by default.
 .BI \-f " enable force fix"
 Enable to fix all the inconsistency in the partition.
 .TP
+.BI \-M " show files map"
+Enable to show all the filenames and inode numbers stored in the image
+.TP
 .BI \-p " enable preen mode"
 Same as "-a" to support general fsck convention.
 .TP
-- 
2.32.0.288.g62a8d224e6-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset
  2021-06-21  2:39 [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Jaegeuk Kim
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map Jaegeuk Kim
@ 2021-06-21  2:39 ` Jaegeuk Kim
  2021-06-23 14:47   ` Chao Yu
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 4/4] f2fs-tools: add extent cache for each file Jaegeuk Kim
  2021-06-23 13:51 ` [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Chao Yu
  3 siblings, 1 reply; 10+ messages in thread
From: Jaegeuk Kim @ 2021-06-21  2:39 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

This fixes wrong file offset updates.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/dump.c | 48 ++++++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/fsck/dump.c b/fsck/dump.c
index f9ef5725c7be..2f796b81febc 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -293,27 +293,20 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
 }
 
 static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype,
-						u32 nid, u64 *ofs)
+				u32 nid, u32 addr_per_block, u64 *ofs)
 {
 	struct node_info ni;
 	struct f2fs_node *node_blk;
 	u32 skip = 0;
 	u32 i, idx = 0;
 
-	get_node_info(sbi, nid, &ni);
-
-	node_blk = calloc(BLOCK_SZ, 1);
-	ASSERT(node_blk);
-
-	dev_read_block(node_blk, ni.blk_addr);
-
 	switch (ntype) {
 	case TYPE_DIRECT_NODE:
-		skip = idx = ADDRS_PER_BLOCK(&node_blk->i);
+		skip = idx = addr_per_block;
 		break;
 	case TYPE_INDIRECT_NODE:
 		idx = NIDS_PER_BLOCK;
-		skip = idx * ADDRS_PER_BLOCK(&node_blk->i);
+		skip = idx * addr_per_block;
 		break;
 	case TYPE_DOUBLE_INDIRECT_NODE:
 		skip = 0;
@@ -323,26 +316,37 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype,
 
 	if (nid == 0) {
 		*ofs += skip;
-		goto out;
+		return;
 	}
 
-	for (i = 0; i < idx; i++, (*ofs)++) {
+	get_node_info(sbi, nid, &ni);
+
+	node_blk = calloc(BLOCK_SZ, 1);
+	ASSERT(node_blk);
+
+	dev_read_block(node_blk, ni.blk_addr);
+
+	for (i = 0; i < idx; i++) {
 		switch (ntype) {
 		case TYPE_DIRECT_NODE:
 			dump_data_blk(sbi, *ofs * F2FS_BLKSIZE,
 					le32_to_cpu(node_blk->dn.addr[i]));
+			(*ofs)++;
 			break;
 		case TYPE_INDIRECT_NODE:
 			dump_node_blk(sbi, TYPE_DIRECT_NODE,
-					le32_to_cpu(node_blk->in.nid[i]), ofs);
+					le32_to_cpu(node_blk->in.nid[i]),
+					addr_per_block,
+					ofs);
 			break;
 		case TYPE_DOUBLE_INDIRECT_NODE:
 			dump_node_blk(sbi, TYPE_INDIRECT_NODE,
-					le32_to_cpu(node_blk->in.nid[i]), ofs);
+					le32_to_cpu(node_blk->in.nid[i]),
+					addr_per_block,
+					ofs);
 			break;
 		}
 	}
-out:
 	free(node_blk);
 }
 
@@ -421,6 +425,7 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 {
 	u32 i = 0;
 	u64 ofs = 0;
+	u32 addr_per_block;
 
 	if((node_blk->i.i_inline & F2FS_INLINE_DATA)) {
 		DBG(3, "ino[0x%x] has inline data!\n", nid);
@@ -431,6 +436,7 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 	}
 
 	c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i);
+	addr_per_block = ADDRS_PER_BLOCK(&node_blk->i);
 
 	/* check data blocks in inode */
 	for (i = 0; i < ADDRS_PER_INODE(&node_blk->i); i++, ofs++)
@@ -441,13 +447,19 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 	for (i = 0; i < 5; i++) {
 		if (i == 0 || i == 1)
 			dump_node_blk(sbi, TYPE_DIRECT_NODE,
-					le32_to_cpu(node_blk->i.i_nid[i]), &ofs);
+					le32_to_cpu(node_blk->i.i_nid[i]),
+					addr_per_block,
+					&ofs);
 		else if (i == 2 || i == 3)
 			dump_node_blk(sbi, TYPE_INDIRECT_NODE,
-					le32_to_cpu(node_blk->i.i_nid[i]), &ofs);
+					le32_to_cpu(node_blk->i.i_nid[i]),
+					addr_per_block,
+					&ofs);
 		else if (i == 4)
 			dump_node_blk(sbi, TYPE_DOUBLE_INDIRECT_NODE,
-					le32_to_cpu(node_blk->i.i_nid[i]), &ofs);
+					le32_to_cpu(node_blk->i.i_nid[i]),
+					addr_per_block,
+					&ofs);
 		else
 			ASSERT(0);
 	}
-- 
2.32.0.288.g62a8d224e6-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [f2fs-dev] [PATCH 4/4] f2fs-tools: add extent cache for each file
  2021-06-21  2:39 [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Jaegeuk Kim
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map Jaegeuk Kim
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset Jaegeuk Kim
@ 2021-06-21  2:39 ` Jaegeuk Kim
  2021-06-23 13:51 ` [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Chao Yu
  3 siblings, 0 replies; 10+ messages in thread
From: Jaegeuk Kim @ 2021-06-21  2:39 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim, Daeho Jeong

From: Daeho Jeong <daehojeong@google.com>

This patch adds an extent cache for ro partition.

Signed-off-by: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/f2fs.h    |   8 ++++
 fsck/mount.c   |   8 ----
 fsck/segment.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+), 8 deletions(-)

diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 9c6b0e4ad7b0..7fb328ff8861 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -527,6 +527,14 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
 	return 1;
 }
 
+static inline bool is_valid_data_blkaddr(block_t blkaddr)
+{
+	if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR ||
+				blkaddr == COMPRESS_ADDR)
+		return 0;
+	return 1;
+}
+
 static inline int IS_CUR_SEGNO(struct f2fs_sb_info *sbi, u32 segno)
 {
 	int i;
diff --git a/fsck/mount.c b/fsck/mount.c
index 598410e5f4fa..1f2d7e059454 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -582,14 +582,6 @@ void print_sb_state(struct f2fs_super_block *sb)
 	MSG(0, "\n");
 }
 
-static inline bool is_valid_data_blkaddr(block_t blkaddr)
-{
-	if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR ||
-				blkaddr == COMPRESS_ADDR)
-		return 0;
-	return 1;
-}
-
 bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
 					block_t blkaddr, int type)
 {
diff --git a/fsck/segment.c b/fsck/segment.c
index 0156690ed9aa..fe63615423f7 100644
--- a/fsck/segment.c
+++ b/fsck/segment.c
@@ -450,6 +450,109 @@ u64 f2fs_fix_mutable(struct f2fs_sb_info *sbi, nid_t ino, pgoff_t offset,
 	return 0;
 }
 
+static inline int is_consecutive(u32 prev_addr, u32 cur_addr)
+{
+	if (is_valid_data_blkaddr(cur_addr) && (cur_addr == prev_addr + 1))
+		return 1;
+	return 0;
+}
+
+static inline void copy_extent_info(struct extent_info *t_ext,
+				struct extent_info *s_ext)
+{
+	t_ext->fofs = s_ext->fofs;
+	t_ext->blk = s_ext->blk;
+	t_ext->len = s_ext->len;
+}
+
+static inline void update_extent_info(struct f2fs_node *inode,
+				struct extent_info *ext)
+{
+	inode->i.i_ext.fofs = cpu_to_le32(ext->fofs);
+	inode->i.i_ext.blk_addr = cpu_to_le32(ext->blk);
+	inode->i.i_ext.len = cpu_to_le32(ext->len);
+}
+
+static void update_largest_extent(struct f2fs_sb_info *sbi, nid_t ino)
+{
+	struct dnode_of_data dn;
+	struct node_info ni;
+	struct f2fs_node *inode;
+	u32 blkaddr, prev_blkaddr, cur_blk = 0, end_blk;
+	struct extent_info largest_ext, cur_ext;
+	u64 remained_blkentries = 0;
+	u32 cluster_size;
+	int count;
+	void *index_node = NULL;
+
+	memset(&dn, 0, sizeof(dn));
+	largest_ext.len = cur_ext.len = 0;
+
+	inode = (struct f2fs_node *) calloc(BLOCK_SZ, 1);
+	ASSERT(inode);
+
+	/* Read inode info */
+	get_node_info(sbi, ino, &ni);
+	ASSERT(dev_read_block(inode, ni.blk_addr) >= 0);
+	cluster_size = 1 << inode->i.i_log_cluster_size;
+
+	if (inode->i.i_inline & F2FS_INLINE_DATA)
+		goto exit;
+
+	end_blk  = f2fs_max_file_offset(&inode->i) >> F2FS_BLKSIZE_BITS;
+
+	while (cur_blk <= end_blk) {
+		if (remained_blkentries == 0) {
+			set_new_dnode(&dn, inode, NULL, ino);
+			get_dnode_of_data(sbi, &dn, cur_blk, LOOKUP_NODE);
+			if (index_node)
+				free(index_node);
+			index_node = (dn.node_blk == dn.inode_blk) ?
+				NULL : dn.node_blk;
+			remained_blkentries = ADDRS_PER_PAGE(sbi,
+					dn.node_blk, dn.inode_blk);
+		}
+		ASSERT(remained_blkentries > 0);
+
+		blkaddr = datablock_addr(dn.node_blk, dn.ofs_in_node);
+		if (cur_ext.len > 0) {
+			if (is_consecutive(prev_blkaddr, blkaddr))
+				cur_ext.len++;
+			else {
+				if (cur_ext.len > largest_ext.len)
+					copy_extent_info(&largest_ext,
+							&cur_ext);
+				cur_ext.len = 0;
+			}
+		}
+
+		if (cur_ext.len == 0 && is_valid_data_blkaddr(blkaddr)) {
+			cur_ext.fofs = cur_blk;
+			cur_ext.len = 1;
+			cur_ext.blk = blkaddr;
+		}
+
+		prev_blkaddr = blkaddr;
+		count = blkaddr == COMPRESS_ADDR ? cluster_size : 1;
+		cur_blk += count;
+		dn.ofs_in_node += count;
+		remained_blkentries -= count;
+		ASSERT(remained_blkentries >= 0);
+	}
+
+exit:
+	if (cur_ext.len > largest_ext.len)
+		copy_extent_info(&largest_ext, &cur_ext);
+	if (largest_ext.len > 0) {
+		update_extent_info(inode, &largest_ext);
+		ASSERT(write_inode(inode, ni.blk_addr) >= 0);
+	}
+
+	if (index_node)
+		free(index_node);
+	free(inode);
+}
+
 int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
 {
 	int fd, n;
@@ -595,6 +698,8 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
 	if (n < 0)
 		return -1;
 
+	if (!c.compress.enabled || (c.feature & cpu_to_le32(F2FS_FEATURE_RO)))
+		update_largest_extent(sbi, de->ino);
 	update_free_segments(sbi);
 
 	MSG(1, "Info: Create %s -> %s\n"
-- 
2.32.0.288.g62a8d224e6-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO
  2021-06-21  2:39 [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Jaegeuk Kim
                   ` (2 preceding siblings ...)
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 4/4] f2fs-tools: add extent cache for each file Jaegeuk Kim
@ 2021-06-23 13:51 ` Chao Yu
  3 siblings, 0 replies; 10+ messages in thread
From: Chao Yu @ 2021-06-23 13:51 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-f2fs-devel

On 2021/6/21 10:39, Jaegeuk Kim wrote:
> We don't need to enable all android features for RO.
> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Reviewed-by: Chao Yu <yuchao0@huawei.com>

Thanks,


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map Jaegeuk Kim
@ 2021-06-23 14:28   ` Chao Yu
  2021-06-23 16:04   ` [f2fs-dev] [PATCH 2/4 v2] " Jaegeuk Kim
  1 sibling, 0 replies; 10+ messages in thread
From: Chao Yu @ 2021-06-23 14:28 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-f2fs-devel

On 2021/6/21 10:39, Jaegeuk Kim wrote:
> This option shows all the file names in the disk.
> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> ---
>   fsck/dump.c       | 74 ++++++++++++++++++++++++++++++++++++++++++-----
>   fsck/fsck.c       | 64 +++++++++++++++++++++++++++++++++++-----
>   fsck/fsck.h       | 15 ++++++++--
>   fsck/main.c       | 15 ++++++++--
>   fsck/mount.c      |  3 ++
>   include/f2fs_fs.h |  7 +++--
>   lib/libf2fs.c     | 11 ++++++-
>   man/dump.f2fs.8   |  7 +++++
>   man/fsck.f2fs.8   |  7 +++++
>   9 files changed, 179 insertions(+), 24 deletions(-)
> 
> diff --git a/fsck/dump.c b/fsck/dump.c
> index 042a2e52edca..f9ef5725c7be 100644
> --- a/fsck/dump.c
> +++ b/fsck/dump.c
> @@ -23,6 +23,9 @@
>   
>   #define BUF_SZ	80
>   
> +/* current extent info */
> +struct extent_info dump_extent = { 0, 0, 0};

Global variable will always be initialized as zero.

> +
>   const char *seg_type_name[SEG_TYPE_MAX + 1] = {
>   	"SEG_TYPE_DATA",
>   	"SEG_TYPE_CUR_DATA",
> @@ -227,10 +230,51 @@ void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa)
>   	close(fd);
>   }
>   
> +static void print_extent(bool last)
> +{
> +	if (dump_extent.len == 0)
> +		goto out;
> +
> +	if (dump_extent.len == 1)
> +		printf(" %d", dump_extent.blk);
> +	else
> +		printf(" %d-%d",
> +			dump_extent.blk,
> +			dump_extent.blk + dump_extent.len - 1);
> +	dump_extent.len = 0;
> +out:
> +	if (last)
> +		printf("\n");
> +}
> +
>   static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
>   {
>   	char buf[F2FS_BLKSIZE];
>   
> +	if (c.show_file_map) {
> +		if (c.show_file_map_max_offset < offset) {
> +			ASSERT(blkaddr == NULL_ADDR);
> +			return;
> +		}
> +		if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR ||
> +					blkaddr == COMPRESS_ADDR) {
> +			print_extent(false);
> +			dump_extent.blk = 0;
> +			dump_extent.len = 1;
> +			print_extent(false);
> +		} else if (dump_extent.len == 0) {
> +			dump_extent.blk = blkaddr;
> +			dump_extent.len = 1;
> +		} else if (dump_extent.blk + dump_extent.len == blkaddr) {
> +			dump_extent.len++;
> +		} else {
> +			print_extent(false);
> +			dump_extent.blk = blkaddr;
> +			dump_extent.len = 1;
> +		}
> +		return;
> +	}
> +
>   	if (blkaddr == NULL_ADDR)
>   		return;
>   
> @@ -239,6 +283,7 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
>   		memset(buf, 0, F2FS_BLKSIZE);
>   	} else {
>   		int ret;
> +
>   		ret = dev_read_block(buf, blkaddr);
>   		ASSERT(ret >= 0);
>   	}
> @@ -371,7 +416,7 @@ static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi),
>   }
>   #endif
>   
> -static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
> +static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
>   					struct f2fs_node *node_blk)
>   {
>   	u32 i = 0;
> @@ -382,9 +427,11 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
>   		/* recover from inline data */
>   		dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET,
>   						0, MAX_INLINE_DATA(node_blk));
> -		return;
> +		return -1;
>   	}
>   
> +	c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i);
> +
>   	/* check data blocks in inode */
>   	for (i = 0; i < ADDRS_PER_INODE(&node_blk->i); i++, ofs++)
>   		dump_data_blk(sbi, ofs * F2FS_BLKSIZE, le32_to_cpu(
> @@ -404,11 +451,14 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
>   		else
>   			ASSERT(0);
>   	}
> +	/* last block in extent cache */
> +	print_extent(true);
>   
>   	dump_xattr(sbi, node_blk);
> +	return 0;
>   }
>   
> -static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
> +static int dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
>   				struct f2fs_node *node_blk, int force)
>   {
>   	struct f2fs_inode *inode = &node_blk->i;
> @@ -422,17 +472,21 @@ static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
>   
>   	if (is_encrypted) {
>   		MSG(force, "File is encrypted\n");
> -		return;
> +		return -1;
>   	}
>   
>   	if ((!S_ISREG(imode) && !S_ISLNK(imode)) ||
>   				namelen == 0 || namelen > F2FS_NAME_LEN) {
>   		MSG(force, "Not a regular file or wrong name info\n\n");
> -		return;
> +		return -1;
>   	}
>   	if (force)
>   		goto dump;
>   
> +	/* dump file's data */
> +	if (c.show_file_map)
> +		return dump_inode_blk(sbi, ni->ino, node_blk);
> +
>   	printf("Do you want to dump this file into ./lost_found/? [Y/N] ");
>   	ret = scanf("%s", ans);
>   	ASSERT(ret >= 0);
> @@ -459,6 +513,7 @@ dump:
>   
>   		close(c.dump_fd);
>   	}
> +	return 0;
>   }
>   
>   static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
> @@ -473,10 +528,11 @@ static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
>   			(const char *)se->cur_valid_map) != 0;
>   }
>   
> -void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
> +int dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
>   {
>   	struct node_info ni;
>   	struct f2fs_node *node_blk;
> +	int ret = 0;
>   
>   	get_node_info(sbi, nid, &ni);
>   
> @@ -505,16 +561,18 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
>   
>   	if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
>   			le32_to_cpu(node_blk->footer.nid) == ni.nid) {
> -		print_node_info(sbi, node_blk, force);
> +		if (!c.show_file_map)
> +			print_node_info(sbi, node_blk, force);
>   
>   		if (ni.ino == ni.nid)
> -			dump_file(sbi, &ni, node_blk, force);
> +			ret = dump_file(sbi, &ni, node_blk, force);
>   	} else {
>   		print_node_info(sbi, node_blk, force);
>   		MSG(force, "Invalid (i)node block\n\n");
>   	}
>   out:
>   	free(node_blk);
> +	return ret;
>   }
>   
>   static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
> diff --git a/fsck/fsck.c b/fsck/fsck.c
> index 80a6d8edfe71..2c741c16124f 100644
> --- a/fsck/fsck.c
> +++ b/fsck/fsck.c
> @@ -695,6 +695,8 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
>   
>   	if (ftype == F2FS_FT_DIR) {
>   		f2fs_set_main_bitmap(sbi, ni->blk_addr, CURSEG_HOT_NODE);
> +		memcpy(child.p_name, node_blk->i.i_name,
> +					node_blk->i.i_namelen);;

Unneeded double semicolon.

>   	} else {
>   		if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
>   			f2fs_set_main_bitmap(sbi, ni->blk_addr,
> @@ -1298,10 +1300,12 @@ void pretty_print_filename(const u8 *raw_name, u32 len,
>   	out[len] = 0;
>   }
>   
> -static void print_dentry(__u32 depth, __u8 *name,
> +static void print_dentry(struct f2fs_sb_info *sbi, __u8 *name,
>   		u8 *bitmap, struct f2fs_dir_entry *dentry,
>   		int max, int idx, int last_blk, int enc_name)
>   {
> +	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
> +	u32 depth = fsck->dentry_depth;
>   	int last_de = 0;
>   	int next_idx = 0;
>   	u32 name_len;
> @@ -1309,7 +1313,7 @@ static void print_dentry(__u32 depth, __u8 *name,
>   	int bit_offset;
>   	char new[F2FS_PRINT_NAMELEN];
>   
> -	if (!c.show_dentry)
> +	if (!c.show_dentry && !c.show_file_map)
>   		return;
>   
>   	name_len = le16_to_cpu(dentry[idx].name_len);
> @@ -1334,15 +1338,31 @@ static void print_dentry(__u32 depth, __u8 *name,
>   	if (tree_mark[depth - 1] == '`')
>   		tree_mark[depth - 1] = ' ';
>   
> -	for (i = 1; i < depth; i++)
> -		printf("%c   ", tree_mark[i]);
> -
>   	pretty_print_filename(name, name_len, new, enc_name);
>   
> -	printf("%c-- %s <ino = 0x%x>, <encrypted (%d)>\n",
> +	if (c.show_file_map) {
> +		struct f2fs_dentry *d = fsck->dentry;
> +
> +		if (dentry[idx].file_type != F2FS_FT_REG_FILE)
> +			return;
> +
> +		while (d) {
> +			if (d->depth > 1)
> +				printf("/%s", d->name);
> +			d = d->next;
> +		}
> +		printf("/%s", new);
> +		if (dump_node(sbi, le32_to_cpu(dentry[idx].ino), 0))
> +			printf("\33[2K\r");
> +	} else {
> +		for (i = 1; i < depth; i++)
> +			printf("%c   ", tree_mark[i]);
> +
> +		printf("%c-- %s <ino = 0x%x>, <encrypted (%d)>\n",
>   			last_de ? '`' : '|',
>   			new, le32_to_cpu(dentry[idx].ino),
>   			enc_name);
> +	}
>   }
>   
>   static int f2fs_check_hash_code(int encoding, int casefolded,
> @@ -1609,7 +1629,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, int casefolded,
>   				le32_to_cpu(dentry[i].ino),
>   				dentry[i].file_type);
>   
> -		print_dentry(fsck->dentry_depth, name, bitmap,
> +		print_dentry(sbi, name, bitmap,
>   				dentry, max, i, last_blk, enc_name);
>   
>   		blk_cnt = 1;
> @@ -1645,6 +1665,8 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
>   		struct f2fs_node *node_blk, struct child_info *child)
>   {
>   	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
> +	struct f2fs_dentry *cur_dentry = fsck->dentry_end;
> +	struct f2fs_dentry *new_dentry;
>   	struct f2fs_dentry_ptr d;
>   	void *inline_dentry;
>   	int dentries;
> @@ -1655,6 +1677,12 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
>   	make_dentry_ptr(&d, node_blk, inline_dentry, 2);
>   
>   	fsck->dentry_depth++;
> +	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);

ASSERT()?

> +	new_dentry->depth = fsck->dentry_depth;
> +	memcpy(new_dentry->name, child->p_name, F2FS_NAME_LEN);
> +	cur_dentry->next = new_dentry;
> +	fsck->dentry_end = new_dentry;
> +
>   	dentries = __chk_dentries(sbi, IS_CASEFOLDED(&node_blk->i), child,
>   			d.bitmap, d.dentry, d.filename, d.max, 1,
>   			file_is_encrypt(&node_blk->i));// pass through
> @@ -1667,6 +1695,10 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
>   			fsck->dentry_depth, dentries,
>   			d.max, F2FS_NAME_LEN);
>   	}
> +	fsck->dentry = cur_dentry;

Any place to free fsck->dentry allocate in fsck_init()?

> +	fsck->dentry_end =cur_dentry;

fsck->dentry_end = cur_dentry;

> +	cur_dentry->next = NULL;
> +	free(new_dentry);
>   	fsck->dentry_depth--;
>   	return dentries;
>   }
> @@ -1676,6 +1708,8 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
>   {
>   	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
>   	struct f2fs_dentry_block *de_blk;
> +	struct f2fs_dentry *cur_dentry = fsck->dentry_end;
> +	struct f2fs_dentry *new_dentry;
>   	int dentries, ret;
>   
>   	de_blk = (struct f2fs_dentry_block *)calloc(BLOCK_SZ, 1);
> @@ -1685,6 +1719,12 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
>   	ASSERT(ret >= 0);
>   
>   	fsck->dentry_depth++;
> +	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);
> +	new_dentry->depth = fsck->dentry_depth;
> +	memcpy(new_dentry->name, child->p_name, F2FS_NAME_LEN);
> +	cur_dentry->next = new_dentry;
> +	fsck->dentry_end = new_dentry;
> +
>   	dentries = __chk_dentries(sbi, casefolded, child,
>   			de_blk->dentry_bitmap,
>   			de_blk->dentry, de_blk->filename,
> @@ -1701,6 +1741,10 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
>   			fsck->dentry_depth, blk_addr, dentries,
>   			NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN);
>   	}
> +	fsck->dentry = cur_dentry;
> +	fsck->dentry_end =cur_dentry;

Ditto,

> +	cur_dentry->next = NULL;
> +	free(new_dentry);
>   	fsck->dentry_depth--;
>   	free(de_blk);
>   	return 0;
> @@ -2061,6 +2105,9 @@ void fsck_init(struct f2fs_sb_info *sbi)
>   	ASSERT(tree_mark_size != 0);
>   	tree_mark = calloc(tree_mark_size, 1);
>   	ASSERT(tree_mark != NULL);
> +	fsck->dentry = calloc(sizeof(struct f2fs_dentry), 1);
> +	memcpy(fsck->dentry->name, "/", 1);
> +	fsck->dentry_end = fsck->dentry;
>   }
>   
>   static void fix_hard_links(struct f2fs_sb_info *sbi)
> @@ -3022,6 +3069,9 @@ int fsck_verify(struct f2fs_sb_info *sbi)
>   	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
>   	struct hard_link_node *node = NULL;
>   
> +	if (c.show_file_map)
> +		return 0;
> +
>   	printf("\n");
>   
>   	if (c.zoned_model == F2FS_ZONED_HM) {
> diff --git a/fsck/fsck.h b/fsck/fsck.h
> index b9dcd5c27982..6b3246aa57fa 100644
> --- a/fsck/fsck.h
> +++ b/fsck/fsck.h
> @@ -72,13 +72,20 @@ struct child_info {
>   	u32 pgofs;
>   	u8 dots;
>   	u8 dir_level;
> -	u32 p_ino;		/*parent ino*/
> -	u32 pp_ino;		/*parent parent ino*/
> +	u32 p_ino;		/* parent ino */
> +	char p_name[F2FS_NAME_LEN]; /* parent name */

Should leave at least one byte slot for '\0' character, so
F2FS_NAME_LEN + 1 will be safe here.

> +	u32 pp_ino;		/* parent parent ino*/
>   	struct extent_info ei;
>   	u32 last_blk;
>   	u32 i_namelen;  /* dentry namelen */
>   };
>   
> +struct f2fs_dentry {
> +	char name[F2FS_NAME_LEN];

Ditto,

Thanks,

> +	int depth;
> +	struct f2fs_dentry *next;
> +};
> +
>   struct f2fs_fsck {
>   	struct f2fs_sb_info sbi;
>   
> @@ -110,6 +117,8 @@ struct f2fs_fsck {
>   	u32 nr_nat_entries;
>   
>   	u32 dentry_depth;
> +	struct f2fs_dentry *dentry;
> +	struct f2fs_dentry *dentry_end;
>   	struct f2fs_nat_entry *entries;
>   	u32 nat_valid_inode_cnt;
>   
> @@ -253,7 +262,7 @@ struct dump_option {
>   extern void nat_dump(struct f2fs_sb_info *, nid_t, nid_t);
>   extern void sit_dump(struct f2fs_sb_info *, unsigned int, unsigned int);
>   extern void ssa_dump(struct f2fs_sb_info *, int, int);
> -extern void dump_node(struct f2fs_sb_info *, nid_t, int);
> +extern int dump_node(struct f2fs_sb_info *, nid_t, int);
>   extern int dump_info_from_blkaddr(struct f2fs_sb_info *, u32);
>   extern unsigned int start_bidx_of_node(unsigned int, struct f2fs_node *);
>   
> diff --git a/fsck/main.c b/fsck/main.c
> index c0b871b48276..bea5e0ff5c33 100644
> --- a/fsck/main.c
> +++ b/fsck/main.c
> @@ -72,6 +72,7 @@ void fsck_usage()
>   	MSG(0, "  -f check/fix entire partition\n");
>   	MSG(0, "  -g add default options\n");
>   	MSG(0, "  -l show superblock/checkpoint\n");
> +	MSG(0, "  -M show a file map\n");
>   	MSG(0, "  -O feature1[feature2,feature3,...] e.g. \"encrypt\"\n");
>   	MSG(0, "  -p preen mode [default:0 the same as -a [0|1]]\n");
>   	MSG(0, "  -S sparse_mode\n");
> @@ -93,6 +94,7 @@ void dump_usage()
>   	MSG(0, "  -d debug level [default:0]\n");
>   	MSG(0, "  -i inode no (hex)\n");
>   	MSG(0, "  -n [NAT dump nid from #1~#2 (decimal), for all 0~-1]\n");
> +	MSG(0, "  -M show a block map\n");
>   	MSG(0, "  -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]\n");
>   	MSG(0, "  -S sparse_mode\n");
>   	MSG(0, "  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
> @@ -228,7 +230,7 @@ void f2fs_parse_options(int argc, char *argv[])
>   	}
>   
>   	if (!strcmp("fsck.f2fs", prog)) {
> -		const char *option_string = ":aC:c:m:d:fg:lO:p:q:StyV";
> +		const char *option_string = ":aC:c:m:Md:fg:lO:p:q:StyV";
>   		int opt = 0, val;
>   		char *token;
>   		struct option long_opt[] = {
> @@ -278,6 +280,9 @@ void f2fs_parse_options(int argc, char *argv[])
>   			case 'l':
>   				c.layout = 1;
>   				break;
> +			case 'M':
> +				c.show_file_map = 1;
> +				break;
>   			case 'O':
>   				if (parse_feature(feature_table, optarg))
>   					fsck_usage();
> @@ -377,7 +382,7 @@ void f2fs_parse_options(int argc, char *argv[])
>   		}
>   	} else if (!strcmp("dump.f2fs", prog)) {
>   #ifdef WITH_DUMP
> -		const char *option_string = "d:i:n:s:Sa:b:V";
> +		const char *option_string = "d:i:n:Ms:Sa:b:V";
>   		static struct dump_option dump_opt = {
>   			.nid = 0,	/* default root ino */
>   			.start_nat = -1,
> @@ -424,6 +429,9 @@ void f2fs_parse_options(int argc, char *argv[])
>   							&dump_opt.start_nat,
>   							&dump_opt.end_nat);
>   				break;
> +			case 'M':
> +				c.show_file_map = 1;
> +				break;
>   			case 's':
>   				ret = sscanf(optarg, "%d~%d",
>   							&dump_opt.start_sit,
> @@ -1209,7 +1217,8 @@ retry:
>   	if (c.func == SLOAD)
>   		c.compress.filter_ops->destroy();
>   
> -	printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0);
> +	if (!c.show_file_map)
> +		printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0);
>   	return ret;
>   
>   out_err:
> diff --git a/fsck/mount.c b/fsck/mount.c
> index de692b62e1c2..598410e5f4fa 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -489,6 +489,9 @@ printout:
>   
>   void print_cp_state(u32 flag)
>   {
> +	if (c.show_file_map)
> +		return;
> +
>   	MSG(0, "Info: checkpoint state = %x : ", flag);
>   	if (flag & CP_QUOTA_NEED_FSCK_FLAG)
>   		MSG(0, "%s", " quota_need_fsck");
> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
> index 8969ae2ebc34..45f72573dadd 100644
> --- a/include/f2fs_fs.h
> +++ b/include/f2fs_fs.h
> @@ -240,14 +240,14 @@ static inline uint64_t bswap_64(uint64_t val)
>   
>   #define MSG(n, fmt, ...)						\
>   	do {								\
> -		if (c.dbg_lv >= n && !c.layout) {			\
> +		if (c.dbg_lv >= n && !c.layout && !c.show_file_map) {	\
>   			printf(fmt, ##__VA_ARGS__);			\
>   		}							\
>   	} while (0)
>   
>   #define DBG(n, fmt, ...)						\
>   	do {								\
> -		if (c.dbg_lv >= n && !c.layout) {			\
> +		if (c.dbg_lv >= n && !c.layout && !c.show_file_map) {	\
>   			printf("[%s:%4d] " fmt,				\
>   				__func__, __LINE__, ##__VA_ARGS__);	\
>   		}							\
> @@ -491,6 +491,8 @@ struct f2fs_configuration {
>   	int alloc_failed;
>   	int auto_fix;
>   	int layout;
> +	int show_file_map;
> +	u64 show_file_map_max_offset;
>   	int quota_fix;
>   	int preen_mode;
>   	int ro;
> @@ -1298,6 +1300,7 @@ extern int utf16_to_utf8(char *, const u_int16_t *, size_t, size_t);
>   extern int log_base_2(u_int32_t);
>   extern unsigned int addrs_per_inode(struct f2fs_inode *);
>   extern unsigned int addrs_per_block(struct f2fs_inode *);
> +extern unsigned int f2fs_max_file_offset(struct f2fs_inode *);
>   extern __u32 f2fs_inode_chksum(struct f2fs_node *);
>   extern __u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *);
>   extern int write_inode(struct f2fs_node *, u64);
> diff --git a/lib/libf2fs.c b/lib/libf2fs.c
> index 0add9018d2ce..876c1dc848b3 100644
> --- a/lib/libf2fs.c
> +++ b/lib/libf2fs.c
> @@ -499,7 +499,8 @@ opaque_seq:
>   	return __f2fs_dentry_hash(name, len);
>   }
>   
> -#define ALIGN_DOWN(addrs, size)		(((addrs) / (size)) * (size))
> +#define ALIGN_DOWN(addrs, size)	(((addrs) / (size)) * (size))
> +#define ALIGN_UP(addrs, size)	ALIGN_DOWN(((addrs) + (size) - 1), (size))
>   unsigned int addrs_per_inode(struct f2fs_inode *i)
>   {
>   	unsigned int addrs = CUR_ADDRS_PER_INODE(i) - get_inline_xattr_addrs(i);
> @@ -518,6 +519,14 @@ unsigned int addrs_per_block(struct f2fs_inode *i)
>   	return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, 1 << i->i_log_cluster_size);
>   }
>   
> +unsigned int f2fs_max_file_offset(struct f2fs_inode *i)
> +{
> +	if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
> +			!(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
> +		return le64_to_cpu(i->i_size);
> +	return ALIGN_UP(le64_to_cpu(i->i_size), 1 << i->i_log_cluster_size);
> +}
> +
>   /*
>    * CRC32
>    */
> diff --git a/man/dump.f2fs.8 b/man/dump.f2fs.8
> index eedba855721f..1ddb7fc5d0d9 100644
> --- a/man/dump.f2fs.8
> +++ b/man/dump.f2fs.8
> @@ -14,6 +14,10 @@ dump.f2fs \- retrieve directory and file entries from an F2FS-formated image
>   .I NAT range
>   ]
>   [
> +.B \-M
> +.I Block map
> +]
> +[
>   .B \-s
>   .I SIT range
>   ]
> @@ -51,6 +55,9 @@ Specify an inode number to dump out.
>   .BI \-n " NAT range"
>   Specify a range presented by nids to dump NAT entries.
>   .TP
> +.BI \-M " Block map"
> +Show all the allocated block addresses given inode number.
> +.TP
>   .BI \-s " SIT range"
>   Specify a range presented by segment numbers to dump SIT entries.
>   .TP
> diff --git a/man/fsck.f2fs.8 b/man/fsck.f2fs.8
> index af1076cb72bc..aff4ff24a2e1 100644
> --- a/man/fsck.f2fs.8
> +++ b/man/fsck.f2fs.8
> @@ -14,6 +14,10 @@ fsck.f2fs \- check a Linux F2FS file system
>   .I enable force fix
>   ]
>   [
> +.B \-M
> +.I show file map
> +]
> +[
>   .B \-p
>   .I enable preen mode
>   ]
> @@ -44,6 +48,9 @@ module. It is disabled by default.
>   .BI \-f " enable force fix"
>   Enable to fix all the inconsistency in the partition.
>   .TP
> +.BI \-M " show files map"
> +Enable to show all the filenames and inode numbers stored in the image
> +.TP
>   .BI \-p " enable preen mode"
>   Same as "-a" to support general fsck convention.
>   .TP
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset Jaegeuk Kim
@ 2021-06-23 14:47   ` Chao Yu
  2021-06-23 16:03     ` Jaegeuk Kim
  0 siblings, 1 reply; 10+ messages in thread
From: Chao Yu @ 2021-06-23 14:47 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-f2fs-devel

On 2021/6/21 10:39, Jaegeuk Kim wrote:
> This fixes wrong file offset updates.

Better to describe why the file offset is wrong in original
code...

> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Reviewed-by: Chao Yu <yuchao0@huawei.com>

Thanks,


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset
  2021-06-23 14:47   ` Chao Yu
@ 2021-06-23 16:03     ` Jaegeuk Kim
  0 siblings, 0 replies; 10+ messages in thread
From: Jaegeuk Kim @ 2021-06-23 16:03 UTC (permalink / raw)
  To: Chao Yu; +Cc: linux-f2fs-devel

On 06/23, Chao Yu wrote:
> On 2021/6/21 10:39, Jaegeuk Kim wrote:
> > This fixes wrong file offset updates.
> 
> Better to describe why the file offset is wrong in original
> code...

Added.

> 
> > 
> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> 
> Reviewed-by: Chao Yu <yuchao0@huawei.com>
> 
> Thanks,


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [f2fs-dev] [PATCH 2/4 v2] fsck|dump.f2fs: add -M to get file map
  2021-06-21  2:39 ` [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map Jaegeuk Kim
  2021-06-23 14:28   ` Chao Yu
@ 2021-06-23 16:04   ` Jaegeuk Kim
  2021-07-08  6:30     ` Chao Yu
  1 sibling, 1 reply; 10+ messages in thread
From: Jaegeuk Kim @ 2021-06-23 16:04 UTC (permalink / raw)
  To: linux-f2fs-devel

This option shows all the file names in the disk.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---

Change log from v1:
 - fix typos and add asserts 
 - add memory free
 
 fsck/dump.c       | 74 ++++++++++++++++++++++++++++++++++++++++++-----
 fsck/fsck.c       | 74 ++++++++++++++++++++++++++++++++++++++++++-----
 fsck/fsck.h       | 15 ++++++++--
 fsck/main.c       | 15 ++++++++--
 fsck/mount.c      |  3 ++
 include/f2fs_fs.h |  7 +++--
 lib/libf2fs.c     | 11 ++++++-
 man/dump.f2fs.8   |  7 +++++
 man/fsck.f2fs.8   |  7 +++++
 9 files changed, 189 insertions(+), 24 deletions(-)

diff --git a/fsck/dump.c b/fsck/dump.c
index 042a2e52edca..3307a54474ac 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -23,6 +23,9 @@
 
 #define BUF_SZ	80
 
+/* current extent info */
+struct extent_info dump_extent;
+
 const char *seg_type_name[SEG_TYPE_MAX + 1] = {
 	"SEG_TYPE_DATA",
 	"SEG_TYPE_CUR_DATA",
@@ -227,10 +230,51 @@ void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa)
 	close(fd);
 }
 
+static void print_extent(bool last)
+{
+	if (dump_extent.len == 0)
+		goto out;
+
+	if (dump_extent.len == 1)
+		printf(" %d", dump_extent.blk);
+	else
+		printf(" %d-%d",
+			dump_extent.blk,
+			dump_extent.blk + dump_extent.len - 1);
+	dump_extent.len = 0;
+out:
+	if (last)
+		printf("\n");
+}
+
 static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
 {
 	char buf[F2FS_BLKSIZE];
 
+	if (c.show_file_map) {
+		if (c.show_file_map_max_offset < offset) {
+			ASSERT(blkaddr == NULL_ADDR);
+			return;
+		}
+		if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR ||
+					blkaddr == COMPRESS_ADDR) {
+			print_extent(false);
+			dump_extent.blk = 0;
+			dump_extent.len = 1;
+			print_extent(false);
+		} else if (dump_extent.len == 0) {
+			dump_extent.blk = blkaddr;
+			dump_extent.len = 1;
+		} else if (dump_extent.blk + dump_extent.len == blkaddr) {
+			dump_extent.len++;
+		} else {
+			print_extent(false);
+			dump_extent.blk = blkaddr;
+			dump_extent.len = 1;
+		}
+		return;
+	}
+
 	if (blkaddr == NULL_ADDR)
 		return;
 
@@ -239,6 +283,7 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
 		memset(buf, 0, F2FS_BLKSIZE);
 	} else {
 		int ret;
+
 		ret = dev_read_block(buf, blkaddr);
 		ASSERT(ret >= 0);
 	}
@@ -371,7 +416,7 @@ static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi),
 }
 #endif
 
-static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
+static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 					struct f2fs_node *node_blk)
 {
 	u32 i = 0;
@@ -382,9 +427,11 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 		/* recover from inline data */
 		dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET,
 						0, MAX_INLINE_DATA(node_blk));
-		return;
+		return -1;
 	}
 
+	c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i);
+
 	/* check data blocks in inode */
 	for (i = 0; i < ADDRS_PER_INODE(&node_blk->i); i++, ofs++)
 		dump_data_blk(sbi, ofs * F2FS_BLKSIZE, le32_to_cpu(
@@ -404,11 +451,14 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 		else
 			ASSERT(0);
 	}
+	/* last block in extent cache */
+	print_extent(true);
 
 	dump_xattr(sbi, node_blk);
+	return 0;
 }
 
-static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
+static int dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
 				struct f2fs_node *node_blk, int force)
 {
 	struct f2fs_inode *inode = &node_blk->i;
@@ -422,17 +472,21 @@ static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
 
 	if (is_encrypted) {
 		MSG(force, "File is encrypted\n");
-		return;
+		return -1;
 	}
 
 	if ((!S_ISREG(imode) && !S_ISLNK(imode)) ||
 				namelen == 0 || namelen > F2FS_NAME_LEN) {
 		MSG(force, "Not a regular file or wrong name info\n\n");
-		return;
+		return -1;
 	}
 	if (force)
 		goto dump;
 
+	/* dump file's data */
+	if (c.show_file_map)
+		return dump_inode_blk(sbi, ni->ino, node_blk);
+
 	printf("Do you want to dump this file into ./lost_found/? [Y/N] ");
 	ret = scanf("%s", ans);
 	ASSERT(ret >= 0);
@@ -459,6 +513,7 @@ dump:
 
 		close(c.dump_fd);
 	}
+	return 0;
 }
 
 static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
@@ -473,10 +528,11 @@ static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
 			(const char *)se->cur_valid_map) != 0;
 }
 
-void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
+int dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
 {
 	struct node_info ni;
 	struct f2fs_node *node_blk;
+	int ret = 0;
 
 	get_node_info(sbi, nid, &ni);
 
@@ -505,16 +561,18 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force)
 
 	if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
 			le32_to_cpu(node_blk->footer.nid) == ni.nid) {
-		print_node_info(sbi, node_blk, force);
+		if (!c.show_file_map)
+			print_node_info(sbi, node_blk, force);
 
 		if (ni.ino == ni.nid)
-			dump_file(sbi, &ni, node_blk, force);
+			ret = dump_file(sbi, &ni, node_blk, force);
 	} else {
 		print_node_info(sbi, node_blk, force);
 		MSG(force, "Invalid (i)node block\n\n");
 	}
 out:
 	free(node_blk);
+	return ret;
 }
 
 static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 80a6d8edfe71..6ca85f0870b9 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -695,6 +695,8 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 
 	if (ftype == F2FS_FT_DIR) {
 		f2fs_set_main_bitmap(sbi, ni->blk_addr, CURSEG_HOT_NODE);
+		memcpy(child.p_name, node_blk->i.i_name,
+					node_blk->i.i_namelen);
 	} else {
 		if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
 			f2fs_set_main_bitmap(sbi, ni->blk_addr,
@@ -1298,10 +1300,12 @@ void pretty_print_filename(const u8 *raw_name, u32 len,
 	out[len] = 0;
 }
 
-static void print_dentry(__u32 depth, __u8 *name,
+static void print_dentry(struct f2fs_sb_info *sbi, __u8 *name,
 		u8 *bitmap, struct f2fs_dir_entry *dentry,
 		int max, int idx, int last_blk, int enc_name)
 {
+	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+	u32 depth = fsck->dentry_depth;
 	int last_de = 0;
 	int next_idx = 0;
 	u32 name_len;
@@ -1309,7 +1313,7 @@ static void print_dentry(__u32 depth, __u8 *name,
 	int bit_offset;
 	char new[F2FS_PRINT_NAMELEN];
 
-	if (!c.show_dentry)
+	if (!c.show_dentry && !c.show_file_map)
 		return;
 
 	name_len = le16_to_cpu(dentry[idx].name_len);
@@ -1334,15 +1338,31 @@ static void print_dentry(__u32 depth, __u8 *name,
 	if (tree_mark[depth - 1] == '`')
 		tree_mark[depth - 1] = ' ';
 
-	for (i = 1; i < depth; i++)
-		printf("%c   ", tree_mark[i]);
-
 	pretty_print_filename(name, name_len, new, enc_name);
 
-	printf("%c-- %s <ino = 0x%x>, <encrypted (%d)>\n",
+	if (c.show_file_map) {
+		struct f2fs_dentry *d = fsck->dentry;
+
+		if (dentry[idx].file_type != F2FS_FT_REG_FILE)
+			return;
+
+		while (d) {
+			if (d->depth > 1)
+				printf("/%s", d->name);
+			d = d->next;
+		}
+		printf("/%s", new);
+		if (dump_node(sbi, le32_to_cpu(dentry[idx].ino), 0))
+			printf("\33[2K\r");
+	} else {
+		for (i = 1; i < depth; i++)
+			printf("%c   ", tree_mark[i]);
+
+		printf("%c-- %s <ino = 0x%x>, <encrypted (%d)>\n",
 			last_de ? '`' : '|',
 			new, le32_to_cpu(dentry[idx].ino),
 			enc_name);
+	}
 }
 
 static int f2fs_check_hash_code(int encoding, int casefolded,
@@ -1609,7 +1629,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, int casefolded,
 				le32_to_cpu(dentry[i].ino),
 				dentry[i].file_type);
 
-		print_dentry(fsck->dentry_depth, name, bitmap,
+		print_dentry(sbi, name, bitmap,
 				dentry, max, i, last_blk, enc_name);
 
 		blk_cnt = 1;
@@ -1645,6 +1665,8 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
 		struct f2fs_node *node_blk, struct child_info *child)
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+	struct f2fs_dentry *cur_dentry = fsck->dentry_end;
+	struct f2fs_dentry *new_dentry;
 	struct f2fs_dentry_ptr d;
 	void *inline_dentry;
 	int dentries;
@@ -1655,6 +1677,14 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
 	make_dentry_ptr(&d, node_blk, inline_dentry, 2);
 
 	fsck->dentry_depth++;
+	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);
+	ASSERT(new_dentry != NULL);
+
+	new_dentry->depth = fsck->dentry_depth;
+	memcpy(new_dentry->name, child->p_name, F2FS_NAME_LEN);
+	cur_dentry->next = new_dentry;
+	fsck->dentry_end = new_dentry;
+
 	dentries = __chk_dentries(sbi, IS_CASEFOLDED(&node_blk->i), child,
 			d.bitmap, d.dentry, d.filename, d.max, 1,
 			file_is_encrypt(&node_blk->i));// pass through
@@ -1667,6 +1697,10 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
 			fsck->dentry_depth, dentries,
 			d.max, F2FS_NAME_LEN);
 	}
+	fsck->dentry = cur_dentry;
+	fsck->dentry_end = cur_dentry;
+	cur_dentry->next = NULL;
+	free(new_dentry);
 	fsck->dentry_depth--;
 	return dentries;
 }
@@ -1676,6 +1710,8 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 	struct f2fs_dentry_block *de_blk;
+	struct f2fs_dentry *cur_dentry = fsck->dentry_end;
+	struct f2fs_dentry *new_dentry;
 	int dentries, ret;
 
 	de_blk = (struct f2fs_dentry_block *)calloc(BLOCK_SZ, 1);
@@ -1685,6 +1721,12 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
 	ASSERT(ret >= 0);
 
 	fsck->dentry_depth++;
+	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);
+	new_dentry->depth = fsck->dentry_depth;
+	memcpy(new_dentry->name, child->p_name, F2FS_NAME_LEN);
+	cur_dentry->next = new_dentry;
+	fsck->dentry_end = new_dentry;
+
 	dentries = __chk_dentries(sbi, casefolded, child,
 			de_blk->dentry_bitmap,
 			de_blk->dentry, de_blk->filename,
@@ -1701,6 +1743,10 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
 			fsck->dentry_depth, blk_addr, dentries,
 			NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN);
 	}
+	fsck->dentry = cur_dentry;
+	fsck->dentry_end = cur_dentry;
+	cur_dentry->next = NULL;
+	free(new_dentry);
 	fsck->dentry_depth--;
 	free(de_blk);
 	return 0;
@@ -2061,6 +2107,10 @@ void fsck_init(struct f2fs_sb_info *sbi)
 	ASSERT(tree_mark_size != 0);
 	tree_mark = calloc(tree_mark_size, 1);
 	ASSERT(tree_mark != NULL);
+	fsck->dentry = calloc(sizeof(struct f2fs_dentry), 1);
+	ASSERT(fsck->dentry != NULL);
+	memcpy(fsck->dentry->name, "/", 1);
+	fsck->dentry_end = fsck->dentry;
 }
 
 static void fix_hard_links(struct f2fs_sb_info *sbi)
@@ -3022,6 +3072,9 @@ int fsck_verify(struct f2fs_sb_info *sbi)
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 	struct hard_link_node *node = NULL;
 
+	if (c.show_file_map)
+		return 0;
+
 	printf("\n");
 
 	if (c.zoned_model == F2FS_ZONED_HM) {
@@ -3229,4 +3282,11 @@ void fsck_free(struct f2fs_sb_info *sbi)
 
 	if (tree_mark)
 		free(tree_mark);
+
+	while (fsck->dentry) {
+		struct f2fs_dentry *dentry = fsck->dentry;
+
+		fsck->dentry = fsck->dentry->next;
+		free(dentry);
+	}
 }
diff --git a/fsck/fsck.h b/fsck/fsck.h
index b9dcd5c27982..d79afef55025 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -72,13 +72,20 @@ struct child_info {
 	u32 pgofs;
 	u8 dots;
 	u8 dir_level;
-	u32 p_ino;		/*parent ino*/
-	u32 pp_ino;		/*parent parent ino*/
+	u32 p_ino;		/* parent ino */
+	char p_name[F2FS_NAME_LEN + 1]; /* parent name */
+	u32 pp_ino;		/* parent parent ino*/
 	struct extent_info ei;
 	u32 last_blk;
 	u32 i_namelen;  /* dentry namelen */
 };
 
+struct f2fs_dentry {
+	char name[F2FS_NAME_LEN + 1];
+	int depth;
+	struct f2fs_dentry *next;
+};
+
 struct f2fs_fsck {
 	struct f2fs_sb_info sbi;
 
@@ -110,6 +117,8 @@ struct f2fs_fsck {
 	u32 nr_nat_entries;
 
 	u32 dentry_depth;
+	struct f2fs_dentry *dentry;
+	struct f2fs_dentry *dentry_end;
 	struct f2fs_nat_entry *entries;
 	u32 nat_valid_inode_cnt;
 
@@ -253,7 +262,7 @@ struct dump_option {
 extern void nat_dump(struct f2fs_sb_info *, nid_t, nid_t);
 extern void sit_dump(struct f2fs_sb_info *, unsigned int, unsigned int);
 extern void ssa_dump(struct f2fs_sb_info *, int, int);
-extern void dump_node(struct f2fs_sb_info *, nid_t, int);
+extern int dump_node(struct f2fs_sb_info *, nid_t, int);
 extern int dump_info_from_blkaddr(struct f2fs_sb_info *, u32);
 extern unsigned int start_bidx_of_node(unsigned int, struct f2fs_node *);
 
diff --git a/fsck/main.c b/fsck/main.c
index b36169845762..260ff29dcdd2 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -72,6 +72,7 @@ void fsck_usage()
 	MSG(0, "  -f check/fix entire partition\n");
 	MSG(0, "  -g add default options\n");
 	MSG(0, "  -l show superblock/checkpoint\n");
+	MSG(0, "  -M show a file map\n");
 	MSG(0, "  -O feature1[feature2,feature3,...] e.g. \"encrypt\"\n");
 	MSG(0, "  -p preen mode [default:0 the same as -a [0|1]]\n");
 	MSG(0, "  -S sparse_mode\n");
@@ -93,6 +94,7 @@ void dump_usage()
 	MSG(0, "  -d debug level [default:0]\n");
 	MSG(0, "  -i inode no (hex)\n");
 	MSG(0, "  -n [NAT dump nid from #1~#2 (decimal), for all 0~-1]\n");
+	MSG(0, "  -M show a block map\n");
 	MSG(0, "  -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]\n");
 	MSG(0, "  -S sparse_mode\n");
 	MSG(0, "  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
@@ -228,7 +230,7 @@ void f2fs_parse_options(int argc, char *argv[])
 	}
 
 	if (!strcmp("fsck.f2fs", prog)) {
-		const char *option_string = ":aC:c:m:d:fg:lO:p:q:StyV";
+		const char *option_string = ":aC:c:m:Md:fg:lO:p:q:StyV";
 		int opt = 0, val;
 		char *token;
 		struct option long_opt[] = {
@@ -278,6 +280,9 @@ void f2fs_parse_options(int argc, char *argv[])
 			case 'l':
 				c.layout = 1;
 				break;
+			case 'M':
+				c.show_file_map = 1;
+				break;
 			case 'O':
 				if (parse_feature(feature_table, optarg))
 					fsck_usage();
@@ -377,7 +382,7 @@ void f2fs_parse_options(int argc, char *argv[])
 		}
 	} else if (!strcmp("dump.f2fs", prog)) {
 #ifdef WITH_DUMP
-		const char *option_string = "d:i:n:s:Sa:b:V";
+		const char *option_string = "d:i:n:Ms:Sa:b:V";
 		static struct dump_option dump_opt = {
 			.nid = 0,	/* default root ino */
 			.start_nat = -1,
@@ -424,6 +429,9 @@ void f2fs_parse_options(int argc, char *argv[])
 							&dump_opt.start_nat,
 							&dump_opt.end_nat);
 				break;
+			case 'M':
+				c.show_file_map = 1;
+				break;
 			case 's':
 				ret = sscanf(optarg, "%d~%d",
 							&dump_opt.start_sit,
@@ -1209,7 +1217,8 @@ retry:
 	if (c.func == SLOAD)
 		c.compress.filter_ops->destroy();
 
-	printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0);
+	if (!c.show_file_map)
+		printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0);
 	return ret;
 
 out_err:
diff --git a/fsck/mount.c b/fsck/mount.c
index de692b62e1c2..598410e5f4fa 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -489,6 +489,9 @@ printout:
 
 void print_cp_state(u32 flag)
 {
+	if (c.show_file_map)
+		return;
+
 	MSG(0, "Info: checkpoint state = %x : ", flag);
 	if (flag & CP_QUOTA_NEED_FSCK_FLAG)
 		MSG(0, "%s", " quota_need_fsck");
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 8969ae2ebc34..45f72573dadd 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -240,14 +240,14 @@ static inline uint64_t bswap_64(uint64_t val)
 
 #define MSG(n, fmt, ...)						\
 	do {								\
-		if (c.dbg_lv >= n && !c.layout) {			\
+		if (c.dbg_lv >= n && !c.layout && !c.show_file_map) {	\
 			printf(fmt, ##__VA_ARGS__);			\
 		}							\
 	} while (0)
 
 #define DBG(n, fmt, ...)						\
 	do {								\
-		if (c.dbg_lv >= n && !c.layout) {			\
+		if (c.dbg_lv >= n && !c.layout && !c.show_file_map) {	\
 			printf("[%s:%4d] " fmt,				\
 				__func__, __LINE__, ##__VA_ARGS__);	\
 		}							\
@@ -491,6 +491,8 @@ struct f2fs_configuration {
 	int alloc_failed;
 	int auto_fix;
 	int layout;
+	int show_file_map;
+	u64 show_file_map_max_offset;
 	int quota_fix;
 	int preen_mode;
 	int ro;
@@ -1298,6 +1300,7 @@ extern int utf16_to_utf8(char *, const u_int16_t *, size_t, size_t);
 extern int log_base_2(u_int32_t);
 extern unsigned int addrs_per_inode(struct f2fs_inode *);
 extern unsigned int addrs_per_block(struct f2fs_inode *);
+extern unsigned int f2fs_max_file_offset(struct f2fs_inode *);
 extern __u32 f2fs_inode_chksum(struct f2fs_node *);
 extern __u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *);
 extern int write_inode(struct f2fs_node *, u64);
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 0add9018d2ce..876c1dc848b3 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -499,7 +499,8 @@ opaque_seq:
 	return __f2fs_dentry_hash(name, len);
 }
 
-#define ALIGN_DOWN(addrs, size)		(((addrs) / (size)) * (size))
+#define ALIGN_DOWN(addrs, size)	(((addrs) / (size)) * (size))
+#define ALIGN_UP(addrs, size)	ALIGN_DOWN(((addrs) + (size) - 1), (size))
 unsigned int addrs_per_inode(struct f2fs_inode *i)
 {
 	unsigned int addrs = CUR_ADDRS_PER_INODE(i) - get_inline_xattr_addrs(i);
@@ -518,6 +519,14 @@ unsigned int addrs_per_block(struct f2fs_inode *i)
 	return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, 1 << i->i_log_cluster_size);
 }
 
+unsigned int f2fs_max_file_offset(struct f2fs_inode *i)
+{
+	if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
+			!(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
+		return le64_to_cpu(i->i_size);
+	return ALIGN_UP(le64_to_cpu(i->i_size), 1 << i->i_log_cluster_size);
+}
+
 /*
  * CRC32
  */
diff --git a/man/dump.f2fs.8 b/man/dump.f2fs.8
index eedba855721f..1ddb7fc5d0d9 100644
--- a/man/dump.f2fs.8
+++ b/man/dump.f2fs.8
@@ -14,6 +14,10 @@ dump.f2fs \- retrieve directory and file entries from an F2FS-formated image
 .I NAT range
 ]
 [
+.B \-M
+.I Block map
+]
+[
 .B \-s
 .I SIT range
 ]
@@ -51,6 +55,9 @@ Specify an inode number to dump out.
 .BI \-n " NAT range"
 Specify a range presented by nids to dump NAT entries.
 .TP
+.BI \-M " Block map"
+Show all the allocated block addresses given inode number.
+.TP
 .BI \-s " SIT range"
 Specify a range presented by segment numbers to dump SIT entries.
 .TP
diff --git a/man/fsck.f2fs.8 b/man/fsck.f2fs.8
index af1076cb72bc..aff4ff24a2e1 100644
--- a/man/fsck.f2fs.8
+++ b/man/fsck.f2fs.8
@@ -14,6 +14,10 @@ fsck.f2fs \- check a Linux F2FS file system
 .I enable force fix
 ]
 [
+.B \-M
+.I show file map
+]
+[
 .B \-p
 .I enable preen mode
 ]
@@ -44,6 +48,9 @@ module. It is disabled by default.
 .BI \-f " enable force fix"
 Enable to fix all the inconsistency in the partition.
 .TP
+.BI \-M " show files map"
+Enable to show all the filenames and inode numbers stored in the image
+.TP
 .BI \-p " enable preen mode"
 Same as "-a" to support general fsck convention.
 .TP
-- 
2.32.0.288.g62a8d224e6-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [f2fs-dev] [PATCH 2/4 v2] fsck|dump.f2fs: add -M to get file map
  2021-06-23 16:04   ` [f2fs-dev] [PATCH 2/4 v2] " Jaegeuk Kim
@ 2021-07-08  6:30     ` Chao Yu
  0 siblings, 0 replies; 10+ messages in thread
From: Chao Yu @ 2021-07-08  6:30 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-f2fs-devel

On 2021/6/24 0:04, Jaegeuk Kim wrote:>   static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr)
>   {
>   	char buf[F2FS_BLKSIZE];
>   
> +	if (c.show_file_map) {
> +		if (c.show_file_map_max_offset < offset) {
> +			ASSERT(blkaddr == NULL_ADDR);
> +			return;
> +		}
> +		if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR ||
> +					blkaddr == COMPRESS_ADDR) {

is_valid_data_blkaddr()

> @@ -1685,6 +1721,12 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, int casefolded, u32 blk_addr,
>   	ASSERT(ret >= 0);
>   
>   	fsck->dentry_depth++;
> +	new_dentry = calloc(sizeof(struct f2fs_dentry), 1);

ASSERT(new_dentry != NULL);

Reviewed-by: Chao Yu <chao@kernel.org>

Thanks,


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-07-08  6:31 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-21  2:39 [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Jaegeuk Kim
2021-06-21  2:39 ` [f2fs-dev] [PATCH 2/4] fsck|dump.f2fs: add -M to get file map Jaegeuk Kim
2021-06-23 14:28   ` Chao Yu
2021-06-23 16:04   ` [f2fs-dev] [PATCH 2/4 v2] " Jaegeuk Kim
2021-07-08  6:30     ` Chao Yu
2021-06-21  2:39 ` [f2fs-dev] [PATCH 3/4] f2fs-tools: fix wrong file offset Jaegeuk Kim
2021-06-23 14:47   ` Chao Yu
2021-06-23 16:03     ` Jaegeuk Kim
2021-06-21  2:39 ` [f2fs-dev] [PATCH 4/4] f2fs-tools: add extent cache for each file Jaegeuk Kim
2021-06-23 13:51 ` [f2fs-dev] [PATCH 1/4] mkfs.f2fs: remove android features for RO Chao Yu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.