Re: [f2fs-dev] [PATCH v4 1/2] dump.f2fs: Add ability to dump folders

2024-05-23 Thread Daeho Jeong
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

2024-05-23 Thread Daeho Jeong
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

2024-05-23 Thread Daniel Rosenberg via Linux-f2fs-devel
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

2024-05-23 Thread Daniel Rosenberg via Linux-f2fs-devel
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

2024-05-23 Thread Daniel Rosenberg via Linux-f2fs-devel
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

2024-05-23 Thread Daniel Rosenberg via Linux-f2fs-devel
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

2024-05-23 Thread Jaegeuk Kim
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

2024-05-23 Thread Jaegeuk Kim
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()

2024-05-23 Thread Chao Yu
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

2024-05-23 Thread Chao Yu
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

2024-05-23 Thread bugzilla-daemon
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

2024-05-23 Thread bugzilla-daemon
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