linux-f2fs-devel.lists.sourceforge.net archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).