Re: [f2fs-dev] [PATCH v4 1/2] dump.f2fs: Add ability to dump folders
On Thu, May 23, 2024 at 3:48 PM Daniel Rosenberg via Linux-f2fs-devel wrote: > > This adds the ability to dump folders as well as files. Folders are > dumped recursively. Additionally, dumped files/folders may be directed > to a folder specified by -o [path] instead of ./lost_found. The -r flag > will dump the entire fs from the root inode. -f or -y will skip the > prompt before dumping, and -P will preserve the mode/owner info for the > created file/folder. > > Signed-off-by: Daniel Rosenberg > Reviewed-by: Daeho Jeong > --- > fsck/dump.c | 178 ++-- > fsck/fsck.c | 4 +- > fsck/fsck.h | 4 +- > fsck/main.c | 29 +++- > man/dump.f2fs.8 | 17 - > 5 files changed, 190 insertions(+), 42 deletions(-) > > diff --git a/fsck/dump.c b/fsck/dump.c > index b2e990b..fa68456 100644 > --- a/fsck/dump.c > +++ b/fsck/dump.c > @@ -247,7 +247,26 @@ out: > printf("\n"); > } > > -static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 > blkaddr) > +static void dump_folder_contents(struct f2fs_sb_info *sbi, u8 *bitmap, > + struct f2fs_dir_entry *dentry, > + __u8 (*filenames)[F2FS_SLOT_LEN], int max) > +{ > + int i; > + int name_len; > + > + for (i = 0; i < max; i++) { > + if (test_bit_le(i, bitmap) == 0) > + continue; > + name_len = le16_to_cpu(dentry[i].name_len); > + if (name_len == 1 && filenames[i][0] == '.') > + continue; > + if (name_len == 2 && filenames[i][0] == '.' && > filenames[i][1] == '.') > + continue; > + dump_node(sbi, le32_to_cpu(dentry[i].ino), 1, NULL, 0, 1); > + } > +} > + > +static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 > blkaddr, bool is_folder) > { > char buf[F2FS_BLKSIZE]; > > @@ -288,12 +307,19 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, > __u64 offset, u32 blkaddr) > ASSERT(ret >= 0); > } > > - /* write blkaddr */ > - dev_write_dump(buf, offset, F2FS_BLKSIZE); > + if (is_folder) { > + struct f2fs_dentry_block *d = (struct f2fs_dentry_block *) > buf; > + > + dump_folder_contents(sbi, d->dentry_bitmap, > F2FS_DENTRY_BLOCK_DENTRIES(d), > + F2FS_DENTRY_BLOCK_FILENAMES(d), > NR_DENTRY_IN_BLOCK); > + } else { > + /* write blkaddr */ > + dev_write_dump(buf, offset, F2FS_BLKSIZE); > + } > } > > static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, > - u32 nid, u32 addr_per_block, u64 *ofs) > + u32 nid, u32 addr_per_block, u64 *ofs, int > is_dir) > { > struct node_info ni; > struct f2fs_node *node_blk; > @@ -330,20 +356,20 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int > ntype, > switch (ntype) { > case TYPE_DIRECT_NODE: > dump_data_blk(sbi, *ofs * F2FS_BLKSIZE, > - le32_to_cpu(node_blk->dn.addr[i])); > + le32_to_cpu(node_blk->dn.addr[i]), > is_dir); > (*ofs)++; > break; > case TYPE_INDIRECT_NODE: > dump_node_blk(sbi, TYPE_DIRECT_NODE, > le32_to_cpu(node_blk->in.nid[i]), > addr_per_block, > - ofs); > + ofs, is_dir); > break; > case TYPE_DOUBLE_INDIRECT_NODE: > dump_node_blk(sbi, TYPE_INDIRECT_NODE, > le32_to_cpu(node_blk->in.nid[i]), > addr_per_block, > - ofs); > + ofs, is_dir); > break; > } > } > @@ -435,8 +461,9 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 > nid, > u32 i = 0; > u64 ofs = 0; > u32 addr_per_block; > + bool is_dir = S_ISDIR(le16_to_cpu(node_blk->i.i_mode)); > > - if((node_blk->i.i_inline & F2FS_INLINE_DATA)) { > + if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) { > DBG(3, "ino[0x%x] has inline data!\n", nid); > /* recover from inline data */ > dev_write_dump(((unsigned char *)node_blk) + > INLINE_DATA_OFFSET, > @@ -444,13 +471,25 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 > nid, > return -1; > } > > + if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { > + void *inline_dentry = in
Re: [f2fs-dev] [PATCH v4 2/2] dump.f2fs: Fix xattr dumping
On Thu, May 23, 2024 at 3:48 PM Daniel Rosenberg via Linux-f2fs-devel wrote: > > Xattrs for files with inline data were being skipped. This dumps those, > as well as xattrs for folders. > > Signed-off-by: Daniel Rosenberg > Reviewed-by: Daeho Jeong > --- > fsck/dump.c | 39 +++ > 1 file changed, 27 insertions(+), 12 deletions(-) > > diff --git a/fsck/dump.c b/fsck/dump.c > index fa68456..90e3e0e 100644 > --- a/fsck/dump.c > +++ b/fsck/dump.c > @@ -377,7 +377,7 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int > ntype, > } > > #ifdef HAVE_FSETXATTR > -static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) > +static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk, > int is_dir) > { > void *xattr; > void *last_base_addr; > @@ -431,12 +431,24 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct > f2fs_node *node_blk) > > DBG(1, "fd %d xattr_name %s\n", c.dump_fd, xattr_name); > #if defined(__linux__) > - ret = fsetxattr(c.dump_fd, xattr_name, value, > - le16_to_cpu(ent->e_value_size), 0); > + if (is_dir) { > + ret = setxattr(".", xattr_name, value, > + > le16_to_cpu(ent->e_value_size), 0); > + } else { > + ret = fsetxattr(c.dump_fd, xattr_name, value, > + > le16_to_cpu(ent->e_value_size), 0); > + } > + > #elif defined(__APPLE__) > - ret = fsetxattr(c.dump_fd, xattr_name, value, > - le16_to_cpu(ent->e_value_size), 0, > - XATTR_CREATE); > + if (is_dir) { > + ret = setxattr(".", xattr_name, value, > + le16_to_cpu(ent->e_value_size), 0, > + XATTR_CREATE); > + } else { > + ret = fsetxattr(c.dump_fd, xattr_name, value, > + le16_to_cpu(ent->e_value_size), 0, > + XATTR_CREATE); > + } > #endif > if (ret) > MSG(0, "XATTR index 0x%x set xattr failed error %d\n", > @@ -449,7 +461,7 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct > f2fs_node *node_blk) > } > #else > static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi), > - struct f2fs_node *UNUSED(node_blk)) > + struct f2fs_node *UNUSED(node_blk), int > UNUSED(is_dir)) > { > MSG(0, "XATTR does not support\n"); > } > @@ -462,13 +474,15 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 > nid, > u64 ofs = 0; > u32 addr_per_block; > bool is_dir = S_ISDIR(le16_to_cpu(node_blk->i.i_mode)); > + int ret = 0; > > if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) { > DBG(3, "ino[0x%x] has inline data!\n", nid); > /* recover from inline data */ > dev_write_dump(((unsigned char *)node_blk) + > INLINE_DATA_OFFSET, > 0, MAX_INLINE_DATA(node_blk)); > - return -1; > + ret = -1; > + goto dump_xattr; > } > > if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { > @@ -480,7 +494,8 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 > nid, > DBG(3, "ino[0x%x] has inline dentries!\n", nid); > /* recover from inline dentry */ > dump_folder_contents(sbi, d.bitmap, d.dentry, d.filename, > d.max); > - return -1; > + ret = -1; > + goto dump_xattr; > } > > c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i); > @@ -516,9 +531,9 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 > nid, > } > /* last block in extent cache */ > print_extent(true); > - > - dump_xattr(sbi, node_blk); > - return 0; > +dump_xattr: > + dump_xattr(sbi, node_blk, is_dir); > + return ret; > } > > static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni, > -- > 2.45.1.288.g0e0cd299f1-goog > > Reviewed-by: Daeho Jeong Thanks, > > ___ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v4 1/2] dump.f2fs: Add ability to dump folders
This adds the ability to dump folders as well as files. Folders are dumped recursively. Additionally, dumped files/folders may be directed to a folder specified by -o [path] instead of ./lost_found. The -r flag will dump the entire fs from the root inode. -f or -y will skip the prompt before dumping, and -P will preserve the mode/owner info for the created file/folder. Signed-off-by: Daniel Rosenberg Reviewed-by: Daeho Jeong --- fsck/dump.c | 178 ++-- fsck/fsck.c | 4 +- fsck/fsck.h | 4 +- fsck/main.c | 29 +++- man/dump.f2fs.8 | 17 - 5 files changed, 190 insertions(+), 42 deletions(-) diff --git a/fsck/dump.c b/fsck/dump.c index b2e990b..fa68456 100644 --- a/fsck/dump.c +++ b/fsck/dump.c @@ -247,7 +247,26 @@ out: printf("\n"); } -static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr) +static void dump_folder_contents(struct f2fs_sb_info *sbi, u8 *bitmap, + struct f2fs_dir_entry *dentry, + __u8 (*filenames)[F2FS_SLOT_LEN], int max) +{ + int i; + int name_len; + + for (i = 0; i < max; i++) { + if (test_bit_le(i, bitmap) == 0) + continue; + name_len = le16_to_cpu(dentry[i].name_len); + if (name_len == 1 && filenames[i][0] == '.') + continue; + if (name_len == 2 && filenames[i][0] == '.' && filenames[i][1] == '.') + continue; + dump_node(sbi, le32_to_cpu(dentry[i].ino), 1, NULL, 0, 1); + } +} + +static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr, bool is_folder) { char buf[F2FS_BLKSIZE]; @@ -288,12 +307,19 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr) ASSERT(ret >= 0); } - /* write blkaddr */ - dev_write_dump(buf, offset, F2FS_BLKSIZE); + if (is_folder) { + struct f2fs_dentry_block *d = (struct f2fs_dentry_block *) buf; + + dump_folder_contents(sbi, d->dentry_bitmap, F2FS_DENTRY_BLOCK_DENTRIES(d), + F2FS_DENTRY_BLOCK_FILENAMES(d), NR_DENTRY_IN_BLOCK); + } else { + /* write blkaddr */ + dev_write_dump(buf, offset, F2FS_BLKSIZE); + } } static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, - u32 nid, u32 addr_per_block, u64 *ofs) + u32 nid, u32 addr_per_block, u64 *ofs, int is_dir) { struct node_info ni; struct f2fs_node *node_blk; @@ -330,20 +356,20 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, switch (ntype) { case TYPE_DIRECT_NODE: dump_data_blk(sbi, *ofs * F2FS_BLKSIZE, - le32_to_cpu(node_blk->dn.addr[i])); + le32_to_cpu(node_blk->dn.addr[i]), is_dir); (*ofs)++; break; case TYPE_INDIRECT_NODE: dump_node_blk(sbi, TYPE_DIRECT_NODE, le32_to_cpu(node_blk->in.nid[i]), addr_per_block, - ofs); + ofs, is_dir); break; case TYPE_DOUBLE_INDIRECT_NODE: dump_node_blk(sbi, TYPE_INDIRECT_NODE, le32_to_cpu(node_blk->in.nid[i]), addr_per_block, - ofs); + ofs, is_dir); break; } } @@ -435,8 +461,9 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, u32 i = 0; u64 ofs = 0; u32 addr_per_block; + bool is_dir = S_ISDIR(le16_to_cpu(node_blk->i.i_mode)); - if((node_blk->i.i_inline & F2FS_INLINE_DATA)) { + if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) { DBG(3, "ino[0x%x] has inline data!\n", nid); /* recover from inline data */ dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET, @@ -444,13 +471,25 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, return -1; } + if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { + void *inline_dentry = inline_data_addr(node_blk); + struct f2fs_dentry_ptr d; + + make_dentry_ptr(&d, node_blk, inline_dentry, 2); + + DBG(3, "ino[0x%x] has inline dentries!\n", nid); + /* recover from inline dentry */ + dump_folder_contents(sbi, d.bitmap, d.dentry, d.filenam
[f2fs-dev] [PATCH v4 2/2] dump.f2fs: Fix xattr dumping
Xattrs for files with inline data were being skipped. This dumps those, as well as xattrs for folders. Signed-off-by: Daniel Rosenberg Reviewed-by: Daeho Jeong --- fsck/dump.c | 39 +++ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/fsck/dump.c b/fsck/dump.c index fa68456..90e3e0e 100644 --- a/fsck/dump.c +++ b/fsck/dump.c @@ -377,7 +377,7 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, } #ifdef HAVE_FSETXATTR -static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) +static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk, int is_dir) { void *xattr; void *last_base_addr; @@ -431,12 +431,24 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) DBG(1, "fd %d xattr_name %s\n", c.dump_fd, xattr_name); #if defined(__linux__) - ret = fsetxattr(c.dump_fd, xattr_name, value, - le16_to_cpu(ent->e_value_size), 0); + if (is_dir) { + ret = setxattr(".", xattr_name, value, + le16_to_cpu(ent->e_value_size), 0); + } else { + ret = fsetxattr(c.dump_fd, xattr_name, value, + le16_to_cpu(ent->e_value_size), 0); + } + #elif defined(__APPLE__) - ret = fsetxattr(c.dump_fd, xattr_name, value, - le16_to_cpu(ent->e_value_size), 0, - XATTR_CREATE); + if (is_dir) { + ret = setxattr(".", xattr_name, value, + le16_to_cpu(ent->e_value_size), 0, + XATTR_CREATE); + } else { + ret = fsetxattr(c.dump_fd, xattr_name, value, + le16_to_cpu(ent->e_value_size), 0, + XATTR_CREATE); + } #endif if (ret) MSG(0, "XATTR index 0x%x set xattr failed error %d\n", @@ -449,7 +461,7 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) } #else static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi), - struct f2fs_node *UNUSED(node_blk)) + struct f2fs_node *UNUSED(node_blk), int UNUSED(is_dir)) { MSG(0, "XATTR does not support\n"); } @@ -462,13 +474,15 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, u64 ofs = 0; u32 addr_per_block; bool is_dir = S_ISDIR(le16_to_cpu(node_blk->i.i_mode)); + int ret = 0; if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) { DBG(3, "ino[0x%x] has inline data!\n", nid); /* recover from inline data */ dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET, 0, MAX_INLINE_DATA(node_blk)); - return -1; + ret = -1; + goto dump_xattr; } if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { @@ -480,7 +494,8 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, DBG(3, "ino[0x%x] has inline dentries!\n", nid); /* recover from inline dentry */ dump_folder_contents(sbi, d.bitmap, d.dentry, d.filename, d.max); - return -1; + ret = -1; + goto dump_xattr; } c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i); @@ -516,9 +531,9 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, } /* last block in extent cache */ print_extent(true); - - dump_xattr(sbi, node_blk); - return 0; +dump_xattr: + dump_xattr(sbi, node_blk, is_dir); + return ret; } static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni, -- 2.45.1.288.g0e0cd299f1-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 2/2] dump.f2fs: Fix xattr dumping
Xattrs for files with inline data were being skipped. This dumps those, as well as xattrs for folders. Signed-off-by: Daniel Rosenberg Reviewed-by: Daeho Jeong --- fsck/dump.c | 39 +++ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/fsck/dump.c b/fsck/dump.c index 1a733f8..dd5a02f 100644 --- a/fsck/dump.c +++ b/fsck/dump.c @@ -377,7 +377,7 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, } #ifdef HAVE_FSETXATTR -static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) +static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk, int is_dir) { void *xattr; void *last_base_addr; @@ -431,12 +431,24 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) DBG(1, "fd %d xattr_name %s\n", c.dump_fd, xattr_name); #if defined(__linux__) - ret = fsetxattr(c.dump_fd, xattr_name, value, - le16_to_cpu(ent->e_value_size), 0); + if (is_dir) { + ret = setxattr(".", xattr_name, value, + le16_to_cpu(ent->e_value_size), 0); + } else { + ret = fsetxattr(c.dump_fd, xattr_name, value, + le16_to_cpu(ent->e_value_size), 0); + } + #elif defined(__APPLE__) - ret = fsetxattr(c.dump_fd, xattr_name, value, - le16_to_cpu(ent->e_value_size), 0, - XATTR_CREATE); + if (is_dir) { + ret = setxattr(".", xattr_name, value, + le16_to_cpu(ent->e_value_size), 0, + XATTR_CREATE); + } else { + ret = fsetxattr(c.dump_fd, xattr_name, value, + le16_to_cpu(ent->e_value_size), 0, + XATTR_CREATE); + } #endif if (ret) MSG(0, "XATTR index 0x%x set xattr failed error %d\n", @@ -449,7 +461,7 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) } #else static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi), - struct f2fs_node *UNUSED(node_blk)) + struct f2fs_node *UNUSED(node_blk), int UNUSED(is_dir)) { MSG(0, "XATTR does not support\n"); } @@ -462,13 +474,15 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, u64 ofs = 0; u32 addr_per_block; bool is_dir = S_ISDIR(le16_to_cpu(node_blk->i.i_mode)); + int ret = 0; if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) { DBG(3, "ino[0x%x] has inline data!\n", nid); /* recover from inline data */ dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET, 0, MAX_INLINE_DATA(node_blk)); - return -1; + ret = -1; + goto dump_xattr; } if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { @@ -480,7 +494,8 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, DBG(3, "ino[0x%x] has inline dentries!\n", nid); /* recover from inline dentry */ dump_folder_contents(sbi, d.bitmap, d.dentry, d.filename, d.max); - return -1; + ret = -1; + goto dump_xattr; } c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i); @@ -516,9 +531,9 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, } /* last block in extent cache */ print_extent(true); - - dump_xattr(sbi, node_blk); - return 0; +dump_xattr: + dump_xattr(sbi, node_blk, is_dir); + return ret; } static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni, -- 2.45.1.288.g0e0cd299f1-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 1/2] dump.f2fs: Add ability to dump folders
This adds the ability to dump folders as well as files. Folders are dumped recursively. Additionally, dumped files/folders may be directed to a folder specified by -o [path] instead of ./lost_found. The -r flag will dump the entire fs from the root inode. -f or -y will skip the prompt before dumping, and -P will preserve the mode/owner info for the created file/folder. Signed-off-by: Daniel Rosenberg Reviewed-by: Daeho Jeong --- fsck/dump.c | 178 ++-- fsck/fsck.c | 4 +- fsck/fsck.h | 4 +- fsck/main.c | 29 +++- man/dump.f2fs.8 | 17 - 5 files changed, 190 insertions(+), 42 deletions(-) diff --git a/fsck/dump.c b/fsck/dump.c index b2e990b..1a733f8 100644 --- a/fsck/dump.c +++ b/fsck/dump.c @@ -247,7 +247,26 @@ out: printf("\n"); } -static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr) +static void dump_folder_contents(struct f2fs_sb_info *sbi, u8 *bitmap, + struct f2fs_dir_entry *dentry, + __u8 (*filenames)[F2FS_SLOT_LEN], int max) +{ + int i; + int name_len; + + for (i = 0; i < max; i++) { + if (test_bit_le(i, bitmap) == 0) + continue; + name_len = le16_to_cpu(dentry[i].name_len); + if (name_len == 1 && filenames[i][0] == '.') + continue; + if (name_len == 2 && filenames[i][0] == '.' && filenames[i][1] == '.') + continue; + dump_node(sbi, le32_to_cpu(dentry[i].ino), 1, NULL, 0, 1); + } +} + +static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr, bool is_folder) { char buf[F2FS_BLKSIZE]; @@ -288,12 +307,19 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr) ASSERT(ret >= 0); } - /* write blkaddr */ - dev_write_dump(buf, offset, F2FS_BLKSIZE); + if (is_folder) { + struct f2fs_dentry_block *d = (struct f2fs_dentry_block *) buf; + + dump_folder_contents(sbi, d->dentry_bitmap, F2FS_DENTRY_BLOCK_DENTRIES(d), + F2FS_DENTRY_BLOCK_FILENAMES(d), NR_DENTRY_IN_BLOCK); + } else { + /* write blkaddr */ + dev_write_dump(buf, offset, F2FS_BLKSIZE); + } } static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, - u32 nid, u32 addr_per_block, u64 *ofs) + u32 nid, u32 addr_per_block, u64 *ofs, int is_dir) { struct node_info ni; struct f2fs_node *node_blk; @@ -330,20 +356,20 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, switch (ntype) { case TYPE_DIRECT_NODE: dump_data_blk(sbi, *ofs * F2FS_BLKSIZE, - le32_to_cpu(node_blk->dn.addr[i])); + le32_to_cpu(node_blk->dn.addr[i]), is_dir); (*ofs)++; break; case TYPE_INDIRECT_NODE: dump_node_blk(sbi, TYPE_DIRECT_NODE, le32_to_cpu(node_blk->in.nid[i]), addr_per_block, - ofs); + ofs, is_dir); break; case TYPE_DOUBLE_INDIRECT_NODE: dump_node_blk(sbi, TYPE_INDIRECT_NODE, le32_to_cpu(node_blk->in.nid[i]), addr_per_block, - ofs); + ofs, is_dir); break; } } @@ -435,8 +461,9 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, u32 i = 0; u64 ofs = 0; u32 addr_per_block; + bool is_dir = S_ISDIR(le16_to_cpu(node_blk->i.i_mode)); - if((node_blk->i.i_inline & F2FS_INLINE_DATA)) { + if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) { DBG(3, "ino[0x%x] has inline data!\n", nid); /* recover from inline data */ dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET, @@ -444,13 +471,25 @@ static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, return -1; } + if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { + void *inline_dentry = inline_data_addr(node_blk); + struct f2fs_dentry_ptr d; + + make_dentry_ptr(&d, node_blk, inline_dentry, 2); + + DBG(3, "ino[0x%x] has inline dentries!\n", nid); + /* recover from inline dentry */ + dump_folder_contents(sbi, d.bitmap, d.dentry, d.filenam
Re: [f2fs-dev] [PATCH] f2fs: fix false alarm on invalid block address
Fixed the stable mailing list. On 05/23, Jaegeuk Kim wrote: > Hi Greg, > > Could you please consider to cherry-pick this patch in stable-6.9, since > there are many users suffering from unnecessary fsck runs during boot? > > You can get this from Linus's tree by > (b864ddb57eb0 "f2fs: fix false alarm on invalid block address") > > Thanks, > > On 05/20, Jaegeuk Kim wrote: > > f2fs_ra_meta_pages can try to read ahead on invalid block address which is > > not the corruption case. > > > > Cc: # v6.9+ > > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218770 > > Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of > > f2fs_is_valid_blkaddr") > > Reviewed-by: Chao Yu > > Signed-off-by: Jaegeuk Kim > > --- > > fs/f2fs/checkpoint.c | 9 + > > 1 file changed, 5 insertions(+), 4 deletions(-) > > > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > > index 5d05a413f451..55d444bec5c0 100644 > > --- a/fs/f2fs/checkpoint.c > > +++ b/fs/f2fs/checkpoint.c > > @@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct > > f2fs_sb_info *sbi, > > break; > > case META_SIT: > > if (unlikely(blkaddr >= SIT_BLK_CNT(sbi))) > > - goto err; > > + goto check_only; > > break; > > case META_SSA: > > if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) || > > blkaddr < SM_I(sbi)->ssa_blkaddr)) > > - goto err; > > + goto check_only; > > break; > > case META_CP: > > if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr || > > blkaddr < __start_cp_addr(sbi))) > > - goto err; > > + goto check_only; > > break; > > case META_POR: > > if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || > > blkaddr < MAIN_BLKADDR(sbi))) > > - goto err; > > + goto check_only; > > break; > > case DATA_GENERIC: > > case DATA_GENERIC_ENHANCE: > > @@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info > > *sbi, > > return true; > > err: > > f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); > > +check_only: > > return false; > > } > > > > -- > > 2.45.0.rc1.225.g2a3ae87e7f-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH] f2fs: fix false alarm on invalid block address
Hi Greg, Could you please consider to cherry-pick this patch in stable-6.9, since there are many users suffering from unnecessary fsck runs during boot? You can get this from Linus's tree by (b864ddb57eb0 "f2fs: fix false alarm on invalid block address") Thanks, On 05/20, Jaegeuk Kim wrote: > f2fs_ra_meta_pages can try to read ahead on invalid block address which is > not the corruption case. > > Cc: # v6.9+ > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218770 > Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of > f2fs_is_valid_blkaddr") > Reviewed-by: Chao Yu > Signed-off-by: Jaegeuk Kim > --- > fs/f2fs/checkpoint.c | 9 + > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > index 5d05a413f451..55d444bec5c0 100644 > --- a/fs/f2fs/checkpoint.c > +++ b/fs/f2fs/checkpoint.c > @@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info > *sbi, > break; > case META_SIT: > if (unlikely(blkaddr >= SIT_BLK_CNT(sbi))) > - goto err; > + goto check_only; > break; > case META_SSA: > if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) || > blkaddr < SM_I(sbi)->ssa_blkaddr)) > - goto err; > + goto check_only; > break; > case META_CP: > if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr || > blkaddr < __start_cp_addr(sbi))) > - goto err; > + goto check_only; > break; > case META_POR: > if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || > blkaddr < MAIN_BLKADDR(sbi))) > - goto err; > + goto check_only; > break; > case DATA_GENERIC: > case DATA_GENERIC_ENHANCE: > @@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info > *sbi, > return true; > err: > f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); > +check_only: > return false; > } > > -- > 2.45.0.rc1.225.g2a3ae87e7f-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] f2fs_io: fix output of do_read()
echo 1 > file f2fs_io read 1 0 1 dio 4096 ./file Read 0 bytes total_time = 17 us, print 4096 bytes: : ffd537 ffc957 0500 0100 : 0200 : 0300 : ffc10f 0200 For the case reading across EOF, it missed to copy returned data to print_buf. After: f2fs_io read 1 0 1 dio 4096 ./file pread expected: 4096, readed: 2 Read 2 bytes total_time = 177 us, print 4096 bytes: : 310a Signed-off-by: Chao Yu --- tools/f2fs_io/f2fs_io.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c index a7b593a..79b4d04 100644 --- a/tools/f2fs_io/f2fs_io.c +++ b/tools/f2fs_io/f2fs_io.c @@ -867,8 +867,15 @@ static void do_read(int argc, char **argv, const struct cmd_desc *cmd) if (!do_mmap) { for (i = 0; i < count; i++) { ret = pread(fd, buf, buf_size, offset + buf_size * i); - if (ret != buf_size) + if (ret != buf_size) { + printf("pread expected: %"PRIu64", readed: %"PRIu64"\n", + buf_size, ret); + if (ret > 0) { + read_cnt += ret; + memcpy(print_buf, buf, print_bytes); + } break; + } read_cnt += ret; if (i == 0) -- 2.40.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] f2fs: fix to force buffered IO on inline_data inode
It will return all zero data when DIO reading from inline_data inode, it is because f2fs_iomap_begin() assign iomap->type w/ IOMAP_HOLE incorrectly for this case. We can let iomap framework handle inline data via assigning iomap->type and iomap->inline_data correctly, however, it will be a little bit complicated when handling race case in between direct IO and buffered IO. So, let's force to use buffered IO to fix this issue. Cc: sta...@vger.kernel.org Reported-by: Barry Song Signed-off-by: Chao Yu --- fs/f2fs/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index db6236f27852..e038910ad1e5 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -851,6 +851,8 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw) return true; if (f2fs_compressed_file(inode)) return true; + if (f2fs_has_inline_data(inode)) + return true; /* disallow direct IO if any of devices has unaligned blksize */ if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize) -- 2.40.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [Bug 218870] F2FS mount/unmount results in invalid_blkaddr
https://bugzilla.kernel.org/show_bug.cgi?id=218870 --- Comment #3 from Paul Gover (pmw.go...@yahoo.co.uk) --- Created attachment 306325 --> https://bugzilla.kernel.org/attachment.cgi?id=306325&action=edit syslog showing the problem -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug. ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [Bug 218870] F2FS mount/unmount results in invalid_blkaddr
https://bugzilla.kernel.org/show_bug.cgi?id=218870 Paul Gover (pmw.go...@yahoo.co.uk) changed: What|Removed |Added CC||pmw.go...@yahoo.co.uk --- Comment #2 from Paul Gover (pmw.go...@yahoo.co.uk) --- I can confirm the problem on my Gentoo system with a custom kernel. As above, with the 6.8.9 kernel , no problems, but with the 6.9.1 kernel (same configuration apart from a couple of new items resulting from "make oldconfig") I get the invalid_blkaddr message and a full fsck. That full fsck fails to fix the problem, so the long boot occurs on all subsequent boots. In my case I'm running "fsck.f2fs -f /dev/nvme0n1p3" from a shell script in my home-rolled initramfs, using sys-fs/f2fs-tools-1.16.0-r1. I'll put my log in an attachment. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug. ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel