[f2fs-dev] [PATCH v2] f2fs: fix to avoid use SSR allocate when do defragment

2024-05-29 Thread Zhiguo Niu
SSR allocate mode will be used when doing file defragment
if ATGC is working at the same time, that is because
set_page_private_gcing may make CURSEG_ALL_DATA_ATGC segment
type got in f2fs_allocate_data_block when defragment page
is writeback, which may cause file fragmentation is worse.

A file with 2 fragmentations is changed as following after defragment:

file info---
sensorsdata :

dev   [254:48]
ino   [0x3029 : 12329]
mode  [0x81b0 : 33200]
nlink [0x   1 : 1]
uid   [0x27e6 : 10214]
gid   [0x27e6 : 10214]
size  [0x  242000 : 2367488]
blksize   [0x1000 : 4096]
blocks[0x1210 : 4624]


file_pos   start_blk end_blkblks
   01136112111361207  87
  3563521136121511361216   2
  3645441136121811361218   1
  3686401136122011361221   2
  3768321136122411361225   2
  3850241136122711361238  12
  4341761136124011361252  13
  4874241136125411361254   1
  4915201136127111361279   9
  528384 3681794 3681795   2
  536576 3681797 3681797   1
  540672 3681799 3681799   1
  544768 3681803 3681803   1
  548864 3681805 3681805   1
  552960 3681807 3681807   1
  557056 3681809 3681809   1

Signed-off-by: Zhiguo Niu 
---
v2: check FI_OPU_WRITE without adding new FI flag.
---
---
 fs/f2fs/segment.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 7caf20a..f0c0906 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3482,7 +3482,8 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
if (page_private_gcing(fio->page)) {
if (fio->sbi->am.atgc_enabled &&
(fio->io_type == FS_DATA_IO) &&
-   (fio->sbi->gc_mode != GC_URGENT_HIGH))
+   (fio->sbi->gc_mode != GC_URGENT_HIGH) &&
+   !is_inode_flag_set(inode, FI_OPU_WRITE))
return CURSEG_ALL_DATA_ATGC;
else
return CURSEG_COLD_DATA;
-- 
1.9.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 avoid use SSR allocate when do defragment

2024-05-29 Thread Zhiguo Niu
SSR allocate mode will be used when doing file defragment
if ATGC is working at the same time, that is because
set_page_private_gcing may make CURSEG_ALL_DATA_ATGC segment
type got in f2fs_allocate_data_block when defragment page
is writeback, which may cause file fragmentation is worse.

A file with 2 fragmentations is changed as following after defragment:

file info---
sensorsdata :

dev   [254:48]
ino   [0x3029 : 12329]
mode  [0x81b0 : 33200]
nlink [0x   1 : 1]
uid   [0x27e6 : 10214]
gid   [0x27e6 : 10214]
size  [0x  242000 : 2367488]
blksize   [0x1000 : 4096]
blocks[0x1210 : 4624]


file_pos   start_blk end_blkblks
   01136112111361207  87
  3563521136121511361216   2
  3645441136121811361218   1
  3686401136122011361221   2
  3768321136122411361225   2
  3850241136122711361238  12
  4341761136124011361252  13
  4874241136125411361254   1
  4915201136127111361279   9
  528384 3681794 3681795   2
  536576 3681797 3681797   1
  540672 3681799 3681799   1
  544768 3681803 3681803   1
  548864 3681805 3681805   1
  552960 3681807 3681807   1
  557056 3681809 3681809   1

A new FI flag FI_DEFRAG_IN_PROGRESS is introduced to avoid
this scenarios.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/f2fs.h| 1 +
 fs/f2fs/file.c| 2 ++
 fs/f2fs/segment.c | 3 ++-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4044e67..9281c5e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -803,6 +803,7 @@ enum {
FI_COW_FILE,/* indicate COW file */
FI_ATOMIC_COMMITTED,/* indicate atomic commit completed except disk 
sync */
FI_ATOMIC_REPLACE,  /* indicate atomic replace */
+   FI_DEFRAG_IN_PROGRESS,  /* indicate file was defragmenting */
FI_MAX, /* max flag, never be used */
 };
 
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 5c0b281..93d2767 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2717,6 +2717,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
goto out;
}
 
+   set_inode_flag(inode, FI_DEFRAG_IN_PROGRESS);
map.m_lblk = pg_start;
map.m_len = pg_end - pg_start;
total = 0;
@@ -2772,6 +2773,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
 clear_out:
clear_inode_flag(inode, FI_SKIP_WRITES);
 out:
+   clear_inode_flag(inode, FI_DEFRAG_IN_PROGRESS);
clear_inode_flag(inode, FI_OPU_WRITE);
 unlock_out:
inode_unlock(inode);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 7caf20a..dd6f8ac 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3482,7 +3482,8 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
if (page_private_gcing(fio->page)) {
if (fio->sbi->am.atgc_enabled &&
(fio->io_type == FS_DATA_IO) &&
-   (fio->sbi->gc_mode != GC_URGENT_HIGH))
+   (fio->sbi->gc_mode != GC_URGENT_HIGH) &&
+   !is_inode_flag_set(inode, 
FI_DEFRAG_IN_PROGRESS))
return CURSEG_ALL_DATA_ATGC;
else
return CURSEG_COLD_DATA;
-- 
1.9.1



___
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 to check return value of f2fs_allocate_new_section

2024-05-20 Thread Zhiguo Niu
On Tue, May 21, 2024 at 3:52 AM Jaegeuk Kim  wrote:
>
> On 05/17, Zhiguo Niu wrote:
> > commit 245930617c9b ("f2fs: fix to handle error paths of 
> > {new,change}_curseg()")
> > missed this allocated path, fix it.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> >  fs/f2fs/segment.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index a0ce3d0..71dc8042 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -5190,7 +5190,9 @@ static int fix_curseg_write_pointer(struct 
> > f2fs_sb_info *sbi, int type)
> >   if (cs->next_blkoff) {
> >   unsigned int old_segno = cs->segno, old_blkoff = 
> > cs->next_blkoff;
> >
> > - f2fs_allocate_new_section(sbi, type, true);
> > + err = f2fs_allocate_new_section(sbi, type, true);
> > + if (err)
> > + return err;
>
> I hesitate to apply this, since this may give mount failures forever. Do you 
> see
> a real issue with this?
Hi Jaegeuk,
No I did not have a real issue related to this, just found it by code review.
it is ok not to apply this for me .
thanks a lot.
>
> >   f2fs_notice(sbi, "Assign new section to curseg[%d]: "
> >   "[0x%x,0x%x] -> [0x%x,0x%x]",
> >   type, old_segno, old_blkoff,
> > --
> > 1.9.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: enable atgc if atgc_age_threshold from user is less than elapsed_time

2024-05-20 Thread Zhiguo Niu
Now atgc can be enabled based on the following conditions:
-ATGC mount option is set
-elapsed_time is more than atgc_age_threshold already
but these conditions are check when umounted->mounted device again.
If the device has not be umounted->mounted for a long time, atgc can
not work even the above conditions met.

It is better to enable atgc dynamiclly when user change atgc_age_threshold
meanwhile this vale is less than elapsed_time and ATGC mount option is on.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/f2fs.h|  1 +
 fs/f2fs/segment.c |  9 -
 fs/f2fs/sysfs.c   | 16 
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 1974b6a..e441d2d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3694,6 +3694,7 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
 int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
+int f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi);
 int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
unsigned int start, unsigned int end);
 int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 71dc8042..44923d4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2931,14 +2931,11 @@ static int get_atssr_segment(struct f2fs_sb_info *sbi, 
int type,
return ret;
 }
 
-static int __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi)
+int f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi)
 {
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_ALL_DATA_ATGC);
int ret = 0;
 
-   if (!sbi->am.atgc_enabled)
-   return 0;
-
f2fs_down_read(_I(sbi)->curseg_lock);
 
mutex_lock(>curseg_mutex);
@@ -2955,7 +2952,9 @@ static int __f2fs_init_atgc_curseg(struct f2fs_sb_info 
*sbi)
 }
 int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi)
 {
-   return __f2fs_init_atgc_curseg(sbi);
+   if (!sbi->am.atgc_enabled)
+   return 0;
+   return f2fs_init_atgc_curseg(sbi);
 }
 
 static void __f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi, int type)
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 09d3ecf..72676c5 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -673,6 +673,22 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
return count;
}
 
+   if (!strcmp(a->attr.name, "atgc_age_threshold")) {
+   if (t < 0)
+   return -EINVAL;
+   sbi->am.age_threshold = t;
+   if (sbi->am.atgc_enabled)
+   return count;
+
+   if (test_opt(sbi, ATGC) &&
+   le64_to_cpu(sbi->ckpt->elapsed_time) >= t) {
+   if (f2fs_init_atgc_curseg(sbi))
+   return -EINVAL;
+   sbi->am.atgc_enabled = true;
+   }
+   return count;
+   }
+
if (!strcmp(a->attr.name, "gc_segment_mode")) {
if (t < MAX_GC_MODE)
sbi->gc_segment_mode = t;
-- 
1.9.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 check return value of f2fs_allocate_new_section

2024-05-17 Thread Zhiguo Niu
commit 245930617c9b ("f2fs: fix to handle error paths of {new,change}_curseg()")
missed this allocated path, fix it.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index a0ce3d0..71dc8042 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -5190,7 +5190,9 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info 
*sbi, int type)
if (cs->next_blkoff) {
unsigned int old_segno = cs->segno, old_blkoff = 
cs->next_blkoff;
 
-   f2fs_allocate_new_section(sbi, type, true);
+   err = f2fs_allocate_new_section(sbi, type, true);
+   if (err)
+   return err;
f2fs_notice(sbi, "Assign new section to curseg[%d]: "
"[0x%x,0x%x] -> [0x%x,0x%x]",
type, old_segno, old_blkoff,
-- 
1.9.1



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


[f2fs-dev] [PATCH V2] f2fs: fix some ambiguous comments

2024-04-26 Thread Zhiguo Niu
After commit d7e9a9037de2 ("f2fs: Support Block Size == Page Size"),
Some comments are confused and just correct with block size is 4KB.

Signed-off-by: Zhiguo Niu 
---
v2: add comments "support 64 TB disk size for 16K page size"
---
---
 include/linux/f2fs_fs.h | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index a357287..41d1d71 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -394,7 +394,8 @@ struct f2fs_nat_block {
 
 /*
  * F2FS uses 4 bytes to represent block address. As a result, supported size of
- * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
+ * disk is 16 TB for a 4K page size and 64 TB for a 16K page size and it equals
+ * to 16 * 1024 * 1024 / 2 segments.
  */
 #define F2FS_MAX_SEGMENT   ((16 * 1024 * 1024) / 2)
 
@@ -424,8 +425,10 @@ struct f2fs_sit_block {
 /*
  * For segment summary
  *
- * One summary block contains exactly 512 summary entries, which represents
- * exactly one segment by default. Not allow to change the basic units.
+ * One summary block with 4KB size contains exactly 512 summary entries, which
+ * represents exactly one segment with 2MB size.
+ * Similarly, in the case of block with 16KB size, it represents one segment 
with 8MB size.
+ * Not allow to change the basic units.
  *
  * NOTE: For initializing fields, you must use set_summary
  *
@@ -556,6 +559,7 @@ struct f2fs_summary_block {
 
 /*
  * space utilization of regular dentry and inline dentry (w/o extra 
reservation)
+ * when block size is 4KB.
  * regular dentry  inline dentry (def) inline dentry 
(min)
  * bitmap  1 * 27 = 27 1 * 23 = 23 1 * 1 = 1
  * reserved1 * 3 = 3   1 * 7 = 7   1 * 1 = 1
-- 
1.9.1



___
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: zone: fix to don't trigger OPU on pinfile for direct IO

2024-04-26 Thread Zhiguo Niu
Dear Chao,

On Fri, Apr 26, 2024 at 6:37 PM Chao Yu  wrote:
>
> Otherwise, it breaks pinfile's sematics.
>
> Cc: Daeho Jeong 
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/data.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index bee1e45f76b8..e29000d83d52 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -1596,7 +1596,8 @@ int f2fs_map_blocks(struct inode *inode, struct 
> f2fs_map_blocks *map, int flag)
>
> /* use out-place-update for direct IO under LFS mode */
> if (map->m_may_create &&
> -   (is_hole || (f2fs_lfs_mode(sbi) && flag == F2FS_GET_BLOCK_DIO))) {
> +   (is_hole || (flag == F2FS_GET_BLOCK_DIO && (f2fs_lfs_mode(sbi) &&
> +   (!f2fs_sb_has_blkzoned(sbi) || !f2fs_is_pinned_file(inode)) {
Excuse me I a little question, should pin files not be written in OPU
mode regardless of device type(conventional or  zone)?
thanks!
> if (unlikely(f2fs_cp_error(sbi))) {
> err = -EIO;
> goto sync_out;
> --
> 2.40.1
>
>
>
> ___
> 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


Re: [f2fs-dev] [PATCH 2/2] f2fs: remove unnecessary block size check in init_f2fs_fs()

2024-04-26 Thread Zhiguo Niu
Fixed!

On Fri, Apr 26, 2024 at 5:37 PM Chao Yu  wrote:
>
> On 2024/4/16 19:12, Zhiguo Niu wrote:
> > On Tue, Apr 16, 2024 at 3:22 PM Chao Yu  wrote:
> >>
> >> After commit d7e9a9037de2 ("f2fs: Support Block Size == Page Size"),
> >> F2FS_BLKSIZE equals to PAGE_SIZE, remove unnecessary check condition.
> >>
> >> Signed-off-by: Chao Yu 
> >> ---
> >>   fs/f2fs/super.c | 6 --
> >>   1 file changed, 6 deletions(-)
> >>
> >> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> >> index 6d1e4fc629e2..32aa6d6fa871 100644
> >> --- a/fs/f2fs/super.c
> >> +++ b/fs/f2fs/super.c
> >> @@ -4933,12 +4933,6 @@ static int __init init_f2fs_fs(void)
> >>   {
> >>  int err;
> >>
> >> -   if (PAGE_SIZE != F2FS_BLKSIZE) {
> >> -   printk("F2FS not supported on PAGE_SIZE(%lu) != 
> >> BLOCK_SIZE(%lu)\n",
> >> -   PAGE_SIZE, F2FS_BLKSIZE);
> >> -   return -EINVAL;
> >> -   }
> >> -
> >>  err = init_inodecache();
> >>  if (err)
> >>  goto fail;
> > Dear Chao,
> >
> > Can you help modify the following  comment msg together with this patch?
> > They are also related to commit d7e9a9037de2 ("f2fs: Support Block
> > Size == Page Size").
> > If you think there is a more suitable description, please help modify
> > it directly.
>
> Zhiguo,
>
> I missed to reply this, I guess you can update
> "f2fs: fix some ambiguous comments".
Dear Chao,
OK, I got it.
thanks!
>
> > thanks!
> >
> > diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> > index a357287..241e7b18 100644
> > --- a/include/linux/f2fs_fs.h
> > +++ b/include/linux/f2fs_fs.h
> > @@ -394,7 +394,8 @@ struct f2fs_nat_block {
> >
> >   /*
> >* F2FS uses 4 bytes to represent block address. As a result, supported 
> > size of
> > - * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
> > + * disk is 16 TB for a 4K page size and 64 TB for a 16K page size and it 
> > equals
>
> disk is 16 TB for 4K size block and 64 TB for 16K size block and it equals
> to (1 << 32) / 512 segments.
>
> #define F2FS_MAX_SEGMENT((1 << 32) / 512)
>
> Thanks,
>
> > + * to 16 * 1024 * 1024 / 2 segments.
> >*/
> >   #define F2FS_MAX_SEGMENT   ((16 * 1024 * 1024) / 2)
> >
> > @@ -424,8 +425,10 @@ struct f2fs_sit_block {
> >   /*
> >* For segment summary
> >*
> > - * One summary block contains exactly 512 summary entries, which represents
> > - * exactly one segment by default. Not allow to change the basic units.
> > + * One summary block with 4KB size contains exactly 512 summary entries, 
> > which
> > + * represents exactly one segment with 2MB size.
> > + * Similarly, in the case of 16k block size, it represents one
> > segment with 8MB size.
> > + * Not allow to change the basic units.
> >*
> >* NOTE: For initializing fields, you must use set_summary
> >*
> > @@ -556,6 +559,7 @@ struct f2fs_summary_block {
> >
> >   /*
> >* space utilization of regular dentry and inline dentry (w/o extra
> > reservation)
> > + * when block size is 4KB.
> >
> >
> >
> >> --
> >> 2.40.1
> >>
> >>
> >>
> >> ___
> >> 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


Re: [f2fs-dev] [PATCH 2/2] f2fs: remove unnecessary block size check in init_f2fs_fs()

2024-04-16 Thread Zhiguo Niu
On Tue, Apr 16, 2024 at 3:22 PM Chao Yu  wrote:
>
> After commit d7e9a9037de2 ("f2fs: Support Block Size == Page Size"),
> F2FS_BLKSIZE equals to PAGE_SIZE, remove unnecessary check condition.
>
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/super.c | 6 --
>  1 file changed, 6 deletions(-)
>
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 6d1e4fc629e2..32aa6d6fa871 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4933,12 +4933,6 @@ static int __init init_f2fs_fs(void)
>  {
> int err;
>
> -   if (PAGE_SIZE != F2FS_BLKSIZE) {
> -   printk("F2FS not supported on PAGE_SIZE(%lu) != 
> BLOCK_SIZE(%lu)\n",
> -   PAGE_SIZE, F2FS_BLKSIZE);
> -   return -EINVAL;
> -   }
> -
> err = init_inodecache();
> if (err)
> goto fail;
Dear Chao,

Can you help modify the following  comment msg together with this patch?
They are also related to commit d7e9a9037de2 ("f2fs: Support Block
Size == Page Size").
If you think there is a more suitable description, please help modify
it directly.
thanks!

diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index a357287..241e7b18 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -394,7 +394,8 @@ struct f2fs_nat_block {

 /*
  * F2FS uses 4 bytes to represent block address. As a result, supported size of
- * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
+ * disk is 16 TB for a 4K page size and 64 TB for a 16K page size and it equals
+ * to 16 * 1024 * 1024 / 2 segments.
  */
 #define F2FS_MAX_SEGMENT   ((16 * 1024 * 1024) / 2)

@@ -424,8 +425,10 @@ struct f2fs_sit_block {
 /*
  * For segment summary
  *
- * One summary block contains exactly 512 summary entries, which represents
- * exactly one segment by default. Not allow to change the basic units.
+ * One summary block with 4KB size contains exactly 512 summary entries, which
+ * represents exactly one segment with 2MB size.
+ * Similarly, in the case of 16k block size, it represents one
segment with 8MB size.
+ * Not allow to change the basic units.
  *
  * NOTE: For initializing fields, you must use set_summary
  *
@@ -556,6 +559,7 @@ struct f2fs_summary_block {

 /*
  * space utilization of regular dentry and inline dentry (w/o extra
reservation)
+ * when block size is 4KB.



> --
> 2.40.1
>
>
>
> ___
> 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


Re: [f2fs-dev] [PATCH V3] f2fs: add REQ_TIME time update for some user behaviors

2024-04-10 Thread Zhiguo Niu
Hi Jaegeuk
Any comments about this patch?
thanks!

On Wed, Mar 20, 2024 at 5:33 PM Chao Yu  wrote:
>
> On 2024/3/20 14:22, Zhiguo Niu wrote:
> > some user behaviors requested filesystem operations, which
> > will cause filesystem not idle.
> > Meanwhile adjust some f2fs_update_time(REQ_TIME) positions.
> >
> > Signed-off-by: Zhiguo Niu 
>
> Reviewed-by: Chao Yu 
>
> Thanks,


___
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 some ambiguous comments

2024-04-07 Thread Zhiguo Niu
Some comments are confused and just correct with block size is 4KB.

Signed-off-by: Zhiguo Niu 
---
 include/linux/f2fs_fs.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index a357287..4a56d18 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -424,8 +424,8 @@ struct f2fs_sit_block {
 /*
  * For segment summary
  *
- * One summary block contains exactly 512 summary entries, which represents
- * exactly one segment by default. Not allow to change the basic units.
+ * One summary block with 4KB size contains exactly 512 summary entries, which
+ * represents exactly one segment with 2MB size. Not allow to change the basic 
units.
  *
  * NOTE: For initializing fields, you must use set_summary
  *
@@ -556,6 +556,7 @@ struct f2fs_summary_block {
 
 /*
  * space utilization of regular dentry and inline dentry (w/o extra 
reservation)
+ * when block size is 4KB.
  * regular dentry  inline dentry (def) inline dentry 
(min)
  * bitmap  1 * 27 = 27 1 * 23 = 23 1 * 1 = 1
  * reserved1 * 3 = 3   1 * 7 = 7   1 * 1 = 1
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH 1/2] f2fs: fix to relocate check condition in f2fs_fallocate()

2024-04-07 Thread Zhiguo Niu
On Sun, Apr 7, 2024 at 3:29 PM Chao Yu  wrote:
>
> On 2024/4/7 10:11, Zhiguo Niu wrote:
> > On Wed, Apr 3, 2024 at 10:26 PM Chao Yu  wrote:
> >>
> >> compress and pinfile flag should be checked after inode lock held to
> >> avoid race condition, fix it.
> >>
> >> Fixes: 4c8ff7095bef ("f2fs: support data compression")
> >> Fixes: 5fed0be8583f ("f2fs: do not allow partial truncation on pinned 
> >> file")
> >> Signed-off-by: Chao Yu 
> >> ---
> >>   fs/f2fs/file.c | 20 +++-
> >>   1 file changed, 11 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> >> index 148bfe3effdf..83a807e25e31 100644
> >> --- a/fs/f2fs/file.c
> >> +++ b/fs/f2fs/file.c
> >> @@ -1820,15 +1820,6 @@ static long f2fs_fallocate(struct file *file, int 
> >> mode,
> >>  (mode & (FALLOC_FL_COLLAPSE_RANGE | 
> >> FALLOC_FL_INSERT_RANGE)))
> >>  return -EOPNOTSUPP;
> >>
> >> -   /*
> >> -* Pinned file should not support partial truncation since the 
> >> block
> >> -* can be used by applications.
> >> -*/
> >> -   if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
> >> -   (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
> >> -   FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE)))
> >> -   return -EOPNOTSUPP;
> >> -
> >>  if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
> >>  FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE |
> >>  FALLOC_FL_INSERT_RANGE))
> >> @@ -1836,6 +1827,17 @@ static long f2fs_fallocate(struct file *file, int 
> >> mode,
> >>
> >>  inode_lock(inode);
> >>
> >> +   /*
> >> +* Pinned file should not support partial truncation since the 
> >> block
> >> +* can be used by applications.
> >> +*/
> >> +   if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
> >> +   (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
> >> +   FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE))) {
> >> +   ret = -EOPNOTSUPP;
> >> +   goto out;
> >> +   }
> >> +
> > Dear Chao,
> > I see  the judgment code "if(!f2fs_compressed_file(inode))" also is
> > before inode_lock in functions
> > f2fs_ioc_decompress_file/f2fs_ioc_compress_file/f2fs_reserve_compress_blocks/f2fs_release_compress_blocks.
> > should they are changed together?
>
> Zhiguo,
>
> Thanks for noticing that, I've submitted separated patches for fixing
> because those bugs were introduced by separated commits.
>
> Thanks,
Dear Chao,
You're welcome^^

>
> > thanks!
> >>  ret = file_modified(file);
> >>  if (ret)
> >>  goto out;
> >> --
> >> 2.40.1
> >>
> >>
> >>
> >> ___
> >> 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


Re: [f2fs-dev] [PATCH 1/2] f2fs: fix to relocate check condition in f2fs_fallocate()

2024-04-06 Thread Zhiguo Niu
On Wed, Apr 3, 2024 at 10:26 PM Chao Yu  wrote:
>
> compress and pinfile flag should be checked after inode lock held to
> avoid race condition, fix it.
>
> Fixes: 4c8ff7095bef ("f2fs: support data compression")
> Fixes: 5fed0be8583f ("f2fs: do not allow partial truncation on pinned file")
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/file.c | 20 +++-
>  1 file changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 148bfe3effdf..83a807e25e31 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -1820,15 +1820,6 @@ static long f2fs_fallocate(struct file *file, int mode,
> (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
> return -EOPNOTSUPP;
>
> -   /*
> -* Pinned file should not support partial truncation since the block
> -* can be used by applications.
> -*/
> -   if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
> -   (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
> -   FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE)))
> -   return -EOPNOTSUPP;
> -
> if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
> FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE |
> FALLOC_FL_INSERT_RANGE))
> @@ -1836,6 +1827,17 @@ static long f2fs_fallocate(struct file *file, int mode,
>
> inode_lock(inode);
>
> +   /*
> +* Pinned file should not support partial truncation since the block
> +* can be used by applications.
> +*/
> +   if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
> +   (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
> +   FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE))) {
> +   ret = -EOPNOTSUPP;
> +   goto out;
> +   }
> +
Dear Chao,
I see  the judgment code "if(!f2fs_compressed_file(inode))" also is
before inode_lock in functions
f2fs_ioc_decompress_file/f2fs_ioc_compress_file/f2fs_reserve_compress_blocks/f2fs_release_compress_blocks.
should they are changed together?
thanks!
> ret = file_modified(file);
> if (ret)
> goto out;
> --
> 2.40.1
>
>
>
> ___
> 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 V3] f2fs: fix to adjust appropirate defragment pg_end

2024-03-27 Thread Zhiguo Niu
A length that exceeds the real size of the inode may be
specified from user, although these out-of-range areas
are not mapped, but they still need to be check in
while loop, which is unnecessary.

Signed-off-by: Zhiguo Niu 
---
v3: adjust code positions according to Chao's suggestions
v2: check i_size within inode lock according to Chao's suggestions
---
---
 fs/f2fs/file.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index bc190d5..9908017 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2627,12 +2627,13 @@ static int f2fs_defragment_range(struct f2fs_sb_info 
*sbi,
bool fragmented = false;
int err;
 
-   pg_start = range->start >> PAGE_SHIFT;
-   pg_end = (range->start + range->len) >> PAGE_SHIFT;
-
f2fs_balance_fs(sbi, true);
 
inode_lock(inode);
+   pg_start = range->start >> PAGE_SHIFT;
+   pg_end = min_t(pgoff_t,
+   (range->start + range->len) >> PAGE_SHIFT,
+   DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE));
 
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
err = -EINVAL;
@@ -2647,8 +2648,9 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
}
 
/* writeback all dirty pages in the range */
-   err = filemap_write_and_wait_range(inode->i_mapping, range->start,
-   range->start + range->len - 1);
+   err = filemap_write_and_wait_range(inode->i_mapping,
+   pg_start << PAGE_SHIFT,
+   pg_end << PAGE_SHIFT - 1);
if (err)
goto out;
 
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH V2] f2fs: fix to adjust appropirate defragment pg_end

2024-03-26 Thread Zhiguo Niu
On Tue, Mar 26, 2024 at 7:11 PM Chao Yu  wrote:
>
> On 2024/3/25 13:56, Zhiguo Niu wrote:
> > A length that exceeds the real size of the inode may be
> > specified from user, although these out-of-range areas
> > are not mapped, but they still need to be check in
> > while loop, which is unnecessary.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> > v2: check i_size within inode lock according to Chao's suggestions
> > ---
> > ---
> >   fs/f2fs/file.c | 11 +++
> >   1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > index 128e53d..cf63db7 100644
> > --- a/fs/f2fs/file.c
> > +++ b/fs/f2fs/file.c
> > @@ -2608,9 +2608,6 @@ static int f2fs_defragment_range(struct f2fs_sb_info 
> > *sbi,
> >   bool fragmented = false;
> >   int err;
> >
> > - pg_start = range->start >> PAGE_SHIFT;
> > - pg_end = (range->start + range->len) >> PAGE_SHIFT;
> > -
> >   f2fs_balance_fs(sbi, true);
> >
> >   inode_lock(inode);
> > @@ -2629,10 +2626,16 @@ static int f2fs_defragment_range(struct 
> > f2fs_sb_info *sbi,
>
> pg_start = range->start >> PAGE_SHIFT;
> pg_end = min_t(pgoff_t, (range->start + range->len) >> PAGE_SHIFT,
> DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE));
>
> >
> >   /* writeback all dirty pages in the range */
> >   err = filemap_write_and_wait_range(inode->i_mapping, range->start,
> > - range->start + range->len - 
> > 1);
> > + min_t(loff_t, range->start + 
> > range->len - 1,
> > + i_size_read(inode) - 1));
>
> , pg_start << PAGE_SHIFT - 1, pg_end << PAGE_SHIFT - 1); ?
should be  pg_start << PAGE_SHIFT , pg_end << PAGE_SHIFT - 1)??
if range.start=0, pg_start is also 0, lstart in
filemap_write_and_wait_range is 0,
but pg_start << PAGE_SHIFT - 1 will get lstart=-1?
thanks!
>
> Thanks,
>
> >   if (err)
> >   goto out;
> >
> > + pg_start = range->start >> PAGE_SHIFT;
> > + pg_end = min_t(pgoff_t,
> > + (range->start + range->len) >> PAGE_SHIFT,
> > + DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE));
> > +
> >   /*
> >* lookup mapping info in extent cache, skip defragmenting if physical
> >* block addresses are continuous.


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


[f2fs-dev] [PATCH V2] f2fs: fix to adjust appropirate defragment pg_end

2024-03-24 Thread Zhiguo Niu
A length that exceeds the real size of the inode may be
specified from user, although these out-of-range areas
are not mapped, but they still need to be check in
while loop, which is unnecessary.

Signed-off-by: Zhiguo Niu 
---
v2: check i_size within inode lock according to Chao's suggestions
---
---
 fs/f2fs/file.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 128e53d..cf63db7 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2608,9 +2608,6 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
bool fragmented = false;
int err;
 
-   pg_start = range->start >> PAGE_SHIFT;
-   pg_end = (range->start + range->len) >> PAGE_SHIFT;
-
f2fs_balance_fs(sbi, true);
 
inode_lock(inode);
@@ -2629,10 +2626,16 @@ static int f2fs_defragment_range(struct f2fs_sb_info 
*sbi,
 
/* writeback all dirty pages in the range */
err = filemap_write_and_wait_range(inode->i_mapping, range->start,
-   range->start + range->len - 1);
+   min_t(loff_t, range->start + 
range->len - 1,
+   i_size_read(inode) - 1));
if (err)
goto out;
 
+   pg_start = range->start >> PAGE_SHIFT;
+   pg_end = min_t(pgoff_t,
+   (range->start + range->len) >> PAGE_SHIFT,
+   DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE));
+
/*
 * lookup mapping info in extent cache, skip defragmenting if physical
 * block addresses are continuous.
-- 
1.9.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 adjust appropirate defragment pg_end

2024-03-22 Thread Zhiguo Niu
A length that exceeds the real size of the inode may be
specified from user, although these out-of-range areas
are not mapped, but they still need to be check in
while loop, which is unnecessary.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/file.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 128e53d..0e7eac6 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2609,7 +2609,9 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
int err;
 
pg_start = range->start >> PAGE_SHIFT;
-   pg_end = (range->start + range->len) >> PAGE_SHIFT;
+   pg_end = min_t(pgoff_t,
+   (range->start + range->len) >> PAGE_SHIFT,
+   DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE));
 
f2fs_balance_fs(sbi, true);
 
-- 
1.9.1



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


[f2fs-dev] [PATCH V3] f2fs: add REQ_TIME time update for some user behaviors

2024-03-20 Thread Zhiguo Niu
some user behaviors requested filesystem operations, which
will cause filesystem not idle.
Meanwhile adjust some f2fs_update_time(REQ_TIME) positions.

Signed-off-by: Zhiguo Niu 
---
v3: modify some update conditions according to Chao's suggeestions
v2: update patch according to Chao's suggestions
---
---
 fs/f2fs/file.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 1761ad1..128e53d 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2354,13 +2354,14 @@ static bool uuid_is_nonzero(__u8 u[16])
 static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 {
struct inode *inode = file_inode(filp);
+   int ret;
 
if (!f2fs_sb_has_encrypt(F2FS_I_SB(inode)))
return -EOPNOTSUPP;
 
+   ret = fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
-
-   return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
+   return ret;
 }
 
 static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
@@ -2786,7 +2787,8 @@ static int f2fs_ioc_defragment(struct file *filp, 
unsigned long arg)
err = f2fs_defragment_range(sbi, filp, );
mnt_drop_write_file(filp);
 
-   f2fs_update_time(sbi, REQ_TIME);
+   if (range.len)
+   f2fs_update_time(sbi, REQ_TIME);
if (err < 0)
return err;
 
@@ -3600,6 +3602,8 @@ static int f2fs_release_compress_blocks(struct file 
*filp, unsigned long arg)
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
 out:
+   if (released_blocks)
+   f2fs_update_time(sbi, REQ_TIME);
inode_unlock(inode);
 
mnt_drop_write_file(filp);
@@ -3770,6 +3774,8 @@ static int f2fs_reserve_compress_blocks(struct file 
*filp, unsigned long arg)
f2fs_mark_inode_dirty_sync(inode, true);
}
 unlock_inode:
+   if (reserved_blocks)
+   f2fs_update_time(sbi, REQ_TIME);
inode_unlock(inode);
mnt_drop_write_file(filp);
 
@@ -3966,6 +3972,7 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned 
long arg)
if (len)
ret = f2fs_secure_erase(prev_bdev, inode, prev_index,
prev_block, len, range.flags);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
filemap_invalidate_unlock(mapping);
f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
@@ -4175,6 +4182,7 @@ static int f2fs_ioc_decompress_file(struct file *filp)
if (ret)
f2fs_warn(sbi, "%s: The file might be partially decompressed 
(errno=%d). Please delete the file.",
  __func__, ret);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
file_end_write(filp);
@@ -4254,6 +4262,7 @@ static int f2fs_ioc_compress_file(struct file *filp)
if (ret)
f2fs_warn(sbi, "%s: The file might be partially compressed 
(errno=%d). Please delete the file.",
  __func__, ret);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
file_end_write(filp);
-- 
1.9.1



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


[f2fs-dev] [PATCH V2] f2fs: add REQ_TIME time update for some user behaviors

2024-03-15 Thread Zhiguo Niu
some user behaviors requested filesystem operations, which
will cause filesystem not idle.
Meanwhile adjust some f2fs_update_time(REQ_TIME) positions.

Signed-off-by: Zhiguo Niu 
---
v2: update patch according to Chao's suggestions
---
---
 fs/f2fs/file.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 1761ad1..8c9d6ea 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2354,13 +2354,14 @@ static bool uuid_is_nonzero(__u8 u[16])
 static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 {
struct inode *inode = file_inode(filp);
+   int ret;
 
if (!f2fs_sb_has_encrypt(F2FS_I_SB(inode)))
return -EOPNOTSUPP;
 
+   ret = fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
-
-   return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
+   return ret;
 }
 
 static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
@@ -2786,7 +2787,8 @@ static int f2fs_ioc_defragment(struct file *filp, 
unsigned long arg)
err = f2fs_defragment_range(sbi, filp, );
mnt_drop_write_file(filp);
 
-   f2fs_update_time(sbi, REQ_TIME);
+   if (range.len)
+   f2fs_update_time(sbi, REQ_TIME);
if (err < 0)
return err;
 
@@ -3599,6 +3601,7 @@ static int f2fs_release_compress_blocks(struct file 
*filp, unsigned long arg)
 
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
 
@@ -3768,6 +3771,7 @@ static int f2fs_reserve_compress_blocks(struct file 
*filp, unsigned long arg)
clear_inode_flag(inode, FI_COMPRESS_RELEASED);
inode_set_ctime_current(inode);
f2fs_mark_inode_dirty_sync(inode, true);
+   f2fs_update_time(sbi, REQ_TIME);
}
 unlock_inode:
inode_unlock(inode);
@@ -3966,6 +3970,7 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned 
long arg)
if (len)
ret = f2fs_secure_erase(prev_bdev, inode, prev_index,
prev_block, len, range.flags);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
filemap_invalidate_unlock(mapping);
f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
@@ -4175,6 +4180,7 @@ static int f2fs_ioc_decompress_file(struct file *filp)
if (ret)
f2fs_warn(sbi, "%s: The file might be partially decompressed 
(errno=%d). Please delete the file.",
  __func__, ret);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
file_end_write(filp);
@@ -4254,6 +4260,7 @@ static int f2fs_ioc_compress_file(struct file *filp)
if (ret)
f2fs_warn(sbi, "%s: The file might be partially compressed 
(errno=%d). Please delete the file.",
  __func__, ret);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
file_end_write(filp);
-- 
1.9.1



___
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: add REQ_TIME time update for some user behaviors

2024-03-14 Thread Zhiguo Niu
On Fri, Mar 15, 2024 at 11:07 AM Chao Yu  wrote:
>
> On 2024/3/15 9:46, Zhiguo Niu wrote:
> > On Thu, Mar 14, 2024 at 9:06 PM Chao Yu  wrote:
> >>
> >> On 2024/3/13 12:11, Zhiguo Niu wrote:
> >>> some user behaviors requested filesystem operations, which
> >>> will cause filesystem not idle.
> >>> Meanwhile adjust f2fs_update_time(REQ_TIME) of
> >>> f2fs_ioc_defragment to successful case.
> >>>
> >>> Signed-off-by: Zhiguo Niu 
> >>> ---
> >>>fs/f2fs/file.c | 9 -
> >>>1 file changed, 8 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> >>> index 4dfe38e..dac3836 100644
> >>> --- a/fs/f2fs/file.c
> >>> +++ b/fs/f2fs/file.c
> >>> @@ -2784,7 +2784,6 @@ static int f2fs_ioc_defragment(struct file *filp, 
> >>> unsigned long arg)
> >>>err = f2fs_defragment_range(sbi, filp, );
> >>>mnt_drop_write_file(filp);
> >>>
> >>> - f2fs_update_time(sbi, REQ_TIME);
> >>
> >> I guess we need to call f2fs_update_time() here if any data was
> >> migrated.
> > OK!
> >>
> >> if (range->len)
> >>  f2fs_update_time(sbi, REQ_TIME);
> >>
> >>>if (err < 0)
> >>>return err;
> >>>
> >>> @@ -2792,6 +2791,7 @@ static int f2fs_ioc_defragment(struct file *filp, 
> >>> unsigned long arg)
> >>>sizeof(range)))
> >>>return -EFAULT;
> >>>
> >>> + f2fs_update_time(sbi, REQ_TIME);
> >>>return 0;
> >>>}
> >>>
> >>> @@ -3331,6 +3331,7 @@ static int f2fs_ioc_resize_fs(struct file *filp, 
> >>> unsigned long arg)
> >>>if (copy_from_user(_count, (void __user *)arg,
> >>>   sizeof(block_count)))
> >>>return -EFAULT;
> >>> + f2fs_update_time(sbi, REQ_TIME);
> >>
> >> There will be no further IO in the end of f2fs_ioc_resize_fs(), so we don't
> >> need to update time to delay gc/discard thread?
> >>
> >>>
> >>>return f2fs_resize_fs(filp, block_count);
> >>>}
> >>> @@ -3424,6 +3425,7 @@ static int f2fs_ioc_setfslabel(struct file *filp, 
> >>> unsigned long arg)
> >>>f2fs_up_write(>sb_lock);
> >>>
> >>>mnt_drop_write_file(filp);
> >>> + f2fs_update_time(sbi, REQ_TIME);
> >>
> >> Ditto,
> > Dear Chao,
> >
> > The two parts you proposed should be similar to the below scenario?
> > -
> > static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long 
> > arg)
> > {
> > struct inode *inode = file_inode(filp);
> >
> > if (!f2fs_sb_has_encrypt(F2FS_I_SB(inode)))
> > return -EOPNOTSUPP;
> >
> > f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
> >
> > return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
>
> fscrypt_ioctl_set_policy() will dirty inode, so we need to keep
> f2fs_update_time(), but it's better to update time after
> fscrypt_ioctl_set_policy()?
>
> Thanks,
Dear Chao,
agree all your suggestions. thanks a lot.
>
> > }
> > ---
> > thanks!
> >
> >
> >>
> >> Thanks,
> >>
> >>>out:
> >>>kfree(vbuf);
> >>>return err;
> >>> @@ -3597,6 +3599,7 @@ static int f2fs_release_compress_blocks(struct file 
> >>> *filp, unsigned long arg)
> >>>
> >>>filemap_invalidate_unlock(inode->i_mapping);
> >>>f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>> + f2fs_update_time(sbi, REQ_TIME);
> >>>out:
> >>>inode_unlock(inode);
> >>>
> >>> @@ -3766,6 +3769,7 @@ static int f2fs_reserve_compress_blocks(struct file 
> >>> *filp, unsigned long arg)
> >>>clear_inode_flag(inode, FI_COMPRESS_RELEASED);
> >>>inode_set_ctime_current(inode);
> >>>f2fs_mark_inode_dirty_sync(inode, true);
> >>> + f2fs_update_time(sbi, REQ_TIME);
> >>>}
&

Re: [f2fs-dev] [PATCH] f2fs: add REQ_TIME time update for some user behaviors

2024-03-14 Thread Zhiguo Niu
On Thu, Mar 14, 2024 at 9:06 PM Chao Yu  wrote:
>
> On 2024/3/13 12:11, Zhiguo Niu wrote:
> > some user behaviors requested filesystem operations, which
> > will cause filesystem not idle.
> > Meanwhile adjust f2fs_update_time(REQ_TIME) of
> > f2fs_ioc_defragment to successful case.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/file.c | 9 -
> >   1 file changed, 8 insertions(+), 1 deletion(-)
> >
> > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > index 4dfe38e..dac3836 100644
> > --- a/fs/f2fs/file.c
> > +++ b/fs/f2fs/file.c
> > @@ -2784,7 +2784,6 @@ static int f2fs_ioc_defragment(struct file *filp, 
> > unsigned long arg)
> >   err = f2fs_defragment_range(sbi, filp, );
> >   mnt_drop_write_file(filp);
> >
> > - f2fs_update_time(sbi, REQ_TIME);
>
> I guess we need to call f2fs_update_time() here if any data was
> migrated.
OK!
>
> if (range->len)
> f2fs_update_time(sbi, REQ_TIME);
>
> >   if (err < 0)
> >   return err;
> >
> > @@ -2792,6 +2791,7 @@ static int f2fs_ioc_defragment(struct file *filp, 
> > unsigned long arg)
> >   sizeof(range)))
> >   return -EFAULT;
> >
> > + f2fs_update_time(sbi, REQ_TIME);
> >   return 0;
> >   }
> >
> > @@ -3331,6 +3331,7 @@ static int f2fs_ioc_resize_fs(struct file *filp, 
> > unsigned long arg)
> >   if (copy_from_user(_count, (void __user *)arg,
> >  sizeof(block_count)))
> >   return -EFAULT;
> > + f2fs_update_time(sbi, REQ_TIME);
>
> There will be no further IO in the end of f2fs_ioc_resize_fs(), so we don't
> need to update time to delay gc/discard thread?
>
> >
> >   return f2fs_resize_fs(filp, block_count);
> >   }
> > @@ -3424,6 +3425,7 @@ static int f2fs_ioc_setfslabel(struct file *filp, 
> > unsigned long arg)
> >   f2fs_up_write(>sb_lock);
> >
> >   mnt_drop_write_file(filp);
> > + f2fs_update_time(sbi, REQ_TIME);
>
> Ditto,
Dear Chao,

The two parts you proposed should be similar to the below scenario?
-
static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
{
struct inode *inode = file_inode(filp);

if (!f2fs_sb_has_encrypt(F2FS_I_SB(inode)))
return -EOPNOTSUPP;

f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);

return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
}
---
thanks!


>
> Thanks,
>
> >   out:
> >   kfree(vbuf);
> >   return err;
> > @@ -3597,6 +3599,7 @@ static int f2fs_release_compress_blocks(struct file 
> > *filp, unsigned long arg)
> >
> >   filemap_invalidate_unlock(inode->i_mapping);
> >   f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
> > + f2fs_update_time(sbi, REQ_TIME);
> >   out:
> >   inode_unlock(inode);
> >
> > @@ -3766,6 +3769,7 @@ static int f2fs_reserve_compress_blocks(struct file 
> > *filp, unsigned long arg)
> >   clear_inode_flag(inode, FI_COMPRESS_RELEASED);
> >   inode_set_ctime_current(inode);
> >   f2fs_mark_inode_dirty_sync(inode, true);
> > + f2fs_update_time(sbi, REQ_TIME);
> >   }
> >   unlock_inode:
> >   inode_unlock(inode);
> > @@ -3964,6 +3968,7 @@ static int f2fs_sec_trim_file(struct file *filp, 
> > unsigned long arg)
> >   if (len)
> >   ret = f2fs_secure_erase(prev_bdev, inode, prev_index,
> >   prev_block, len, range.flags);
> > + f2fs_update_time(sbi, REQ_TIME);
> >   out:
> >   filemap_invalidate_unlock(mapping);
> >   f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
> > @@ -4173,6 +4178,7 @@ static int f2fs_ioc_decompress_file(struct file *filp)
> >   if (ret)
> >   f2fs_warn(sbi, "%s: The file might be partially decompressed 
> > (errno=%d). Please delete the file.",
> > __func__, ret);
> > + f2fs_update_time(sbi, REQ_TIME);
> >   out:
> >   inode_unlock(inode);
> >   file_end_write(filp);
> > @@ -4252,6 +4258,7 @@ static int f2fs_ioc_compress_file(struct file *filp)
> >   if (ret)
> >   f2fs_warn(sbi, "%s: The file might be partially compressed 
> > (errno=%d). Please delete the file.",
> > __func__, ret);
> > + f2fs_update_time(sbi, REQ_TIME);
> >   out:
> >   inode_unlock(inode);
> >   file_end_write(filp);


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


[f2fs-dev] [PATCH] f2fs: add REQ_TIME time update for some user behaviors

2024-03-12 Thread Zhiguo Niu
some user behaviors requested filesystem operations, which
will cause filesystem not idle.
Meanwhile adjust f2fs_update_time(REQ_TIME) of
f2fs_ioc_defragment to successful case.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/file.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 4dfe38e..dac3836 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2784,7 +2784,6 @@ static int f2fs_ioc_defragment(struct file *filp, 
unsigned long arg)
err = f2fs_defragment_range(sbi, filp, );
mnt_drop_write_file(filp);
 
-   f2fs_update_time(sbi, REQ_TIME);
if (err < 0)
return err;
 
@@ -2792,6 +2791,7 @@ static int f2fs_ioc_defragment(struct file *filp, 
unsigned long arg)
sizeof(range)))
return -EFAULT;
 
+   f2fs_update_time(sbi, REQ_TIME);
return 0;
 }
 
@@ -3331,6 +3331,7 @@ static int f2fs_ioc_resize_fs(struct file *filp, unsigned 
long arg)
if (copy_from_user(_count, (void __user *)arg,
   sizeof(block_count)))
return -EFAULT;
+   f2fs_update_time(sbi, REQ_TIME);
 
return f2fs_resize_fs(filp, block_count);
 }
@@ -3424,6 +3425,7 @@ static int f2fs_ioc_setfslabel(struct file *filp, 
unsigned long arg)
f2fs_up_write(>sb_lock);
 
mnt_drop_write_file(filp);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
kfree(vbuf);
return err;
@@ -3597,6 +3599,7 @@ static int f2fs_release_compress_blocks(struct file 
*filp, unsigned long arg)
 
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
 
@@ -3766,6 +3769,7 @@ static int f2fs_reserve_compress_blocks(struct file 
*filp, unsigned long arg)
clear_inode_flag(inode, FI_COMPRESS_RELEASED);
inode_set_ctime_current(inode);
f2fs_mark_inode_dirty_sync(inode, true);
+   f2fs_update_time(sbi, REQ_TIME);
}
 unlock_inode:
inode_unlock(inode);
@@ -3964,6 +3968,7 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned 
long arg)
if (len)
ret = f2fs_secure_erase(prev_bdev, inode, prev_index,
prev_block, len, range.flags);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
filemap_invalidate_unlock(mapping);
f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]);
@@ -4173,6 +4178,7 @@ static int f2fs_ioc_decompress_file(struct file *filp)
if (ret)
f2fs_warn(sbi, "%s: The file might be partially decompressed 
(errno=%d). Please delete the file.",
  __func__, ret);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
file_end_write(filp);
@@ -4252,6 +4258,7 @@ static int f2fs_ioc_compress_file(struct file *filp)
if (ret)
f2fs_warn(sbi, "%s: The file might be partially compressed 
(errno=%d). Please delete the file.",
  __func__, ret);
+   f2fs_update_time(sbi, REQ_TIME);
 out:
inode_unlock(inode);
file_end_write(filp);
-- 
1.9.1



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


[f2fs-dev] [PATCH V2 2/2] f2fs: fix to handle error paths of {new, change}_curseg()

2024-03-11 Thread Zhiguo Niu
{new,change}_curseg() may return error in some special cases,
error handling should be did in their callers, and this will also
facilitate subsequent error path expansion in {new,change}_curseg().

Signed-off-by: Zhiguo Niu 
Signed-off-by: Chao Yu 
---
v2: remove the part that are irrelevant to this patch
---
---
 fs/f2fs/f2fs.h|  4 ++--
 fs/f2fs/gc.c  |  7 +--
 fs/f2fs/segment.c | 57 ++-
 fs/f2fs/super.c   |  4 +++-
 4 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4836e7c..7beb074 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3700,10 +3700,10 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info 
*sbi,
 void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
 bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
-void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
+int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
-void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
unsigned int start, unsigned int end);
 int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
 int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index ca1bf41..8852814 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2035,8 +2035,11 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
mutex_unlock(_I(sbi)->seglist_lock);
 
/* Move out cursegs from the target range */
-   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
-   f2fs_allocate_segment_for_resize(sbi, type, start, end);
+   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++) {
+   err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
+   if (err)
+   goto out;
+   }
 
/* do GC to move out valid blocks in the range */
err = f2fs_gc_range(sbi, start, end, dry_run, 0);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4e4a51a..c1c1308 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2863,7 +2863,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, 
int segno)
  * This function always allocates a used segment(from dirty seglist) by SSR
  * manner, so it should recover the existing segment information of valid 
blocks
  */
-static void change_curseg(struct f2fs_sb_info *sbi, int type)
+static int change_curseg(struct f2fs_sb_info *sbi, int type)
 {
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, type);
@@ -2888,21 +2888,23 @@ static void change_curseg(struct f2fs_sb_info *sbi, int 
type)
if (IS_ERR(sum_page)) {
/* GC won't be able to use stale summary pages by cp_error */
memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE);
-   return;
+   return PTR_ERR(sum_page);
}
sum_node = (struct f2fs_summary_block *)page_address(sum_page);
memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
f2fs_put_page(sum_page, 1);
+   return 0;
 }
 
 static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
int alloc_mode, unsigned long long age);
 
-static void get_atssr_segment(struct f2fs_sb_info *sbi, int type,
+static int get_atssr_segment(struct f2fs_sb_info *sbi, int type,
int target_type, int alloc_mode,
unsigned long long age)
 {
struct curseg_info *curseg = CURSEG_I(sbi, type);
+   int ret = 0;
 
curseg->seg_type = target_type;
 
@@ -2910,38 +2912,41 @@ static void get_atssr_segment(struct f2fs_sb_info *sbi, 
int type,
struct seg_entry *se = get_seg_entry(sbi, curseg->next_segno);
 
curseg->seg_type = se->type;
-   change_curseg(sbi, type);
+   ret = change_curseg(sbi, type);
} else {
/* allocate cold segment by default */
curseg->seg_type = CURSEG_COLD_DATA;
-   new_curseg(sbi, type, true);
+   ret = new_curseg(sbi, type, true);
}
stat_inc_seg_type(sbi, curseg);
+   return ret;
 }
 
-static void __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi)
+static int __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi)
 {
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_ALL_DATA_ATGC);
+   int ret = 0;
 
if (!sbi->am.atgc_enabled)
-   return;
+   return 0;
 
f2fs_down_read(_I(sbi)-&g

Re: [f2fs-dev] [PATCH 1/2] f2fs: fix to remove f2fs_bug_on in add_bio_entry

2024-03-11 Thread Zhiguo Niu
On Mon, Mar 11, 2024 at 11:54 AM Chao Yu  wrote:
>
> On 2024/3/8 18:12, Zhiguo Niu wrote:
> > add_bio_entry should not trigger system panic when bio_add_page fail,
> > fix to remove it.
> >
> > Fixes: 0b20fcec8651 ("f2fs: cache global IPU bio")
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/data.c | 6 --
> >   1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index d9494b5..f8ae684 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -759,8 +759,10 @@ static void add_bio_entry(struct f2fs_sb_info *sbi, 
> > struct bio *bio,
> >   be->bio = bio;
> >   bio_get(bio);
> >
> > - if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE)
> > - f2fs_bug_on(sbi, 1);
> > + if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
> > + bio_put(bio);
>
> I didn't get it, why new created bio has no space to store one page?
>
> Thanks,

Dear Chao,
I got what you mean.

We are doing bio merge optimization in bio_add_page.
After looking at all the locations where bio_add_page is called,
and think it is unreasonable to panic the system if bio_add_page fails.
but it is not impossible to panic in the current flow about bio_add_page.
so keeping it as is is a good choice.
thanks!
> > + return;
> > + }
> >
> >   f2fs_down_write(>bio_list_lock);
> >   list_add_tail(>list, >bio_list);


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


Re: [f2fs-dev] [PATCH 2/2] f2fs: fix to handle error paths of {new, change}_curseg()

2024-03-11 Thread Zhiguo Niu
On Mon, Mar 11, 2024 at 2:09 PM Chao Yu  wrote:
>
> On 2024/3/8 18:12, Zhiguo Niu wrote:
> > {new,change}_curseg() may return error in some special cases,
> > error handling should be did in their callers, and this will also
> > facilitate subsequent error path expansion in {new,change}_curseg().
> >
> > Signed-off-by: Zhiguo Niu 
> > Signed-off-by: Chao Yu 
> > ---
> >   fs/f2fs/extent_cache.c |  2 +-
> >   fs/f2fs/f2fs.h |  4 ++--
> >   fs/f2fs/gc.c   |  7 +--
> >   fs/f2fs/segment.c  | 57 
> > +++---
> >   fs/f2fs/super.c|  4 +++-
> >   5 files changed, 46 insertions(+), 28 deletions(-)
> >
> > diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
> > index 48048fa..dce00cf 100644
> > --- a/fs/f2fs/extent_cache.c
> > +++ b/fs/f2fs/extent_cache.c
> > @@ -988,7 +988,7 @@ bool f2fs_lookup_read_extent_cache_block(struct inode 
> > *inode, pgoff_t index,
> >
> >   void f2fs_update_read_extent_cache(struct dnode_of_data *dn)
> >   {
> > - return __update_extent_cache(dn, EX_READ);
> > + __update_extent_cache(dn, EX_READ);
>
> Above change is not related to this patch?
>
> Otherwise, it looks good to me.
>
> Thanks,
Dear Chao,

Okay, I see that both functions here are void type, so there is no
need to use return^^.
I will remove this part and update.

By the way, I did a stability test on this patch and the result passed
thanks!

>
> >   }
> >
> >   void f2fs_update_read_extent_cache_range(struct dnode_of_data *dn,
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index 4836e7c..7beb074 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -3700,10 +3700,10 @@ void f2fs_clear_prefree_segments(struct 
> > f2fs_sb_info *sbi,
> >   void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
> >   int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
> >   bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
> > -void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
> > +int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
> >   void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
> >   void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
> > -void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> > +int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >   unsigned int start, unsigned int end);
> >   int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool 
> > force);
> >   int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index ca1bf41..8852814 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -2035,8 +2035,11 @@ static int free_segment_range(struct f2fs_sb_info 
> > *sbi,
> >   mutex_unlock(_I(sbi)->seglist_lock);
> >
> >   /* Move out cursegs from the target range */
> > - for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
> > - f2fs_allocate_segment_for_resize(sbi, type, start, end);
> > + for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++) {
> > + err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
> > + if (err)
> > + goto out;
> > + }
> >
> >   /* do GC to move out valid blocks in the range */
> >   err = f2fs_gc_range(sbi, start, end, dry_run, 0);
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index 4e4a51a..c1c1308 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -2863,7 +2863,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info 
> > *sbi, int segno)
> >* This function always allocates a used segment(from dirty seglist) by 
> > SSR
> >* manner, so it should recover the existing segment information of valid 
> > blocks
> >*/
> > -static void change_curseg(struct f2fs_sb_info *sbi, int type)
> > +static int change_curseg(struct f2fs_sb_info *sbi, int type)
> >   {
> >   struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
> >   struct curseg_info *curseg = CURSEG_I(sbi, type);
> > @@ -2888,21 +2888,23 @@ static void change_curseg(struct f2fs_sb_info *sbi, 
> > int type)
> >   if (IS_ERR(sum_page)) {
> >   /* GC won't be able to use stale summary pages by cp_error */
> >   memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE);
> &g

[f2fs-dev] [PATCH 2/2] f2fs: fix to handle error paths of {new, change}_curseg()

2024-03-08 Thread Zhiguo Niu
{new,change}_curseg() may return error in some special cases,
error handling should be did in their callers, and this will also
facilitate subsequent error path expansion in {new,change}_curseg().

Signed-off-by: Zhiguo Niu 
Signed-off-by: Chao Yu 
---
 fs/f2fs/extent_cache.c |  2 +-
 fs/f2fs/f2fs.h |  4 ++--
 fs/f2fs/gc.c   |  7 +--
 fs/f2fs/segment.c  | 57 +++---
 fs/f2fs/super.c|  4 +++-
 5 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index 48048fa..dce00cf 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -988,7 +988,7 @@ bool f2fs_lookup_read_extent_cache_block(struct inode 
*inode, pgoff_t index,
 
 void f2fs_update_read_extent_cache(struct dnode_of_data *dn)
 {
-   return __update_extent_cache(dn, EX_READ);
+   __update_extent_cache(dn, EX_READ);
 }
 
 void f2fs_update_read_extent_cache_range(struct dnode_of_data *dn,
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4836e7c..7beb074 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3700,10 +3700,10 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info 
*sbi,
 void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
 bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
-void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
+int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
-void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
unsigned int start, unsigned int end);
 int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
 int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index ca1bf41..8852814 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2035,8 +2035,11 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
mutex_unlock(_I(sbi)->seglist_lock);
 
/* Move out cursegs from the target range */
-   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
-   f2fs_allocate_segment_for_resize(sbi, type, start, end);
+   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++) {
+   err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
+   if (err)
+   goto out;
+   }
 
/* do GC to move out valid blocks in the range */
err = f2fs_gc_range(sbi, start, end, dry_run, 0);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4e4a51a..c1c1308 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2863,7 +2863,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, 
int segno)
  * This function always allocates a used segment(from dirty seglist) by SSR
  * manner, so it should recover the existing segment information of valid 
blocks
  */
-static void change_curseg(struct f2fs_sb_info *sbi, int type)
+static int change_curseg(struct f2fs_sb_info *sbi, int type)
 {
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, type);
@@ -2888,21 +2888,23 @@ static void change_curseg(struct f2fs_sb_info *sbi, int 
type)
if (IS_ERR(sum_page)) {
/* GC won't be able to use stale summary pages by cp_error */
memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE);
-   return;
+   return PTR_ERR(sum_page);
}
sum_node = (struct f2fs_summary_block *)page_address(sum_page);
memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
f2fs_put_page(sum_page, 1);
+   return 0;
 }
 
 static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
int alloc_mode, unsigned long long age);
 
-static void get_atssr_segment(struct f2fs_sb_info *sbi, int type,
+static int get_atssr_segment(struct f2fs_sb_info *sbi, int type,
int target_type, int alloc_mode,
unsigned long long age)
 {
struct curseg_info *curseg = CURSEG_I(sbi, type);
+   int ret = 0;
 
curseg->seg_type = target_type;
 
@@ -2910,38 +2912,41 @@ static void get_atssr_segment(struct f2fs_sb_info *sbi, 
int type,
struct seg_entry *se = get_seg_entry(sbi, curseg->next_segno);
 
curseg->seg_type = se->type;
-   change_curseg(sbi, type);
+   ret = change_curseg(sbi, type);
} else {
/* allocate cold segment by default */
curseg->seg_type = CURSEG_COLD_DATA;
-   new_curseg(sbi, type, true);
+   

[f2fs-dev] [PATCH 1/2] f2fs: fix to remove f2fs_bug_on in add_bio_entry

2024-03-08 Thread Zhiguo Niu
add_bio_entry should not trigger system panic when bio_add_page fail,
fix to remove it.

Fixes: 0b20fcec8651 ("f2fs: cache global IPU bio")
Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/data.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index d9494b5..f8ae684 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -759,8 +759,10 @@ static void add_bio_entry(struct f2fs_sb_info *sbi, struct 
bio *bio,
be->bio = bio;
bio_get(bio);
 
-   if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE)
-   f2fs_bug_on(sbi, 1);
+   if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
+   bio_put(bio);
+   return;
+   }
 
f2fs_down_write(>bio_list_lock);
list_add_tail(>list, >bio_list);
-- 
1.9.1



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


[f2fs-dev] [PATCH V8] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-03-07 Thread Zhiguo Niu
There are some cases of f2fs_is_valid_blkaddr not handled as
ERROR_INVALID_BLKADDR,so unify the error handling about all of
f2fs_is_valid_blkaddr.
Do f2fs_handle_error in __f2fs_is_valid_blkaddr for cleanup.

Signed-off-by: Zhiguo Niu 
Signed-off-by: Chao Yu 
---
v8: do reboot/monkey stability test for this version and result pass.
do f2fs_handle_error in __is_bitmap_valid  for resolving the
ugly code problem mentioned by Jaegeuk, besides handle the situation
of “type == DATA_GENERIC_ENHANCE_UPDATE” reasonably.
---
---
 fs/f2fs/checkpoint.c   | 41 ++---
 fs/f2fs/data.c | 22 +++---
 fs/f2fs/extent_cache.c |  5 +
 fs/f2fs/file.c | 16 +++-
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/recovery.c |  4 
 fs/f2fs/segment.c  |  2 --
 7 files changed, 29 insertions(+), 63 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index a09a960..b8a7e83 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -154,19 +154,19 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
if (unlikely(f2fs_cp_error(sbi)))
return exist;
 
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
-
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   dump_stack();
-   }
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE))
+   goto out_err;
+   if (!exist && type != DATA_GENERIC_ENHANCE_UPDATE)
+   goto out_handle;
+   return exist;
+out_err:
+   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+blkaddr, exist);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   dump_stack();
+out_handle:
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
return exist;
 }
 
@@ -178,22 +178,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -210,7 +210,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
  blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
-   return false;
+   goto err;
} else {
return __is_bitmap_valid(sbi, blkaddr, type);
}
@@ -218,13 +218,16 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
case META_GENERIC:
if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
blkaddr >= MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
default:
BUG();
}
 
return true;
+err:
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+   return false;
 }
 
 bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 2fbbf8f..f8ae684 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -690,10 +690,8 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
 
if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
fio->is_por ? META_POR : (__is_meta_io(fio) ?
-   META_GENERIC : DATA_GENERIC_ENHANCE))) {
-   f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR);
+   META_GENERIC : DATA_GENERIC_ENHANCE)))
return -EFSCORRUPTED;
-   }
 
trace_f2fs_submit_page_b

Re: [f2fs-dev] [PATCH v3] f2fs: reduce expensive checkpoint trigger frequency

2024-03-04 Thread Zhiguo Niu
Sorry, move jaegeuk to the "To"   list

Dear  Jaegeuk,

Let me describe the problem process, it is reproduced by monkey stability test:

 1.SBI_NEED_CP flag bit is set,
 set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);

 2.Ckpt thread is blocked by IO busy when it is doing CP,  it can not
get request tag from block queue,
 PID: 505  TASK: ff80ed7f49c0  CPU: 4COMMAND: "f2fs_ckpt-254:4"
 #0 [ffc015fcb330] __switch_to at ffc010196350
 #1 [ffc015fcb390] __schedule at ffc01168e53c
 #2 [ffc015fcb3f0] schedule at ffc01168ed7c
 #3 [ffc015fcb450] io_schedule at ffc01168f7a0
 #4 [ffc015fcb4c0] blk_mq_get_tag at ffc0101008a4
 #5 [ffc015fcb530] blk_mq_get_request at ffc0109241b0
 #6 [ffc015fcb5f0] blk_mq_make_request at ffc0109233bc
 #7 [ffc015fcb680] generic_make_request at ffc0100fc6ec
 #8 [ffc015fcb700] submit_bio at ffc0100fc3b8
 #9 [ffc015fcb750] __submit_bio at ffc01081a2e0
 #10 [ffc015fcb7d0] __submit_merged_bio at ffc01081b07c
 #11 [ffc015fcb8a0] f2fs_submit_page_write at ffc0100ecd3c
 #12 [ffc015fcb990] f2fs_do_write_meta_page at ffc010845738
 #13 [ffc015fcb9d0] __f2fs_write_meta_page at ffc01080a8f4
 #14 [ffc015fcbb60] f2fs_sync_meta_pages at ffc01080a684
 #15 [ffc015fcbca0] do_checkpoint at ffc01080f0a8
 #16 [ffc015fcbd10] f2fs_write_checkpoint at ffc01080e50c
 #17 [ffc015fcbdb0] __checkpoint_and_complete_reqs at ffc010810f54
 #18 [ffc015fcbe40] issue_checkpoint_thread at ffc0108113ec
 #19 [ffc015fcbe80] kthread at ffc0102665b0

 3.Subsequent regular file fsync will trigger ckpt because SBI_NEED_CP
has not been cleared.
 In fact, these cases should not trigger ckpt.

 4.If some processes that perform f2fs_do_sync_file are important processes
 in the system(such as init) and are blocked for too long, it will
cause other problems in the system, ANR or android reboot
 PID: 287  TASK: ff80f9eb0ec0  CPU: 2COMMAND: "init"
 #0 [ffc01389bab0] __switch_to at ffc010196350
 #1 [ffc01389bb10] __schedule at ffc01168e53c
 #2 [ffc01389bb70] schedule at ffc01168ed7c
 #3 [ffc01389bbc0] wait_for_completion at ffc011692368
 #4 [ffc01389bca0] f2fs_issue_checkpoint at ffc010810cb0
 #5 [ffc01389bd00] f2fs_sync_fs at ffc0107f4e1c
 #6 [ffc01389bdc0] f2fs_do_sync_file at ffc0107d4d44
 #7 [ffc01389be20] f2fs_sync_file at ffc0107d492c
 #8 [ffc01389be30] __arm64_sys_fsync at ffc0105d31d8
 #9 [ffc01389be70] el0_svc_common at ffc0101aa550
 #10 [ffc01389beb0] el0_svc_handler at ffc0100886fc

and I tested Chao's patch can avoid the above case, please help
consider this patch or
any comment/suggestions about this?

thanks!

On Tue, Mar 5, 2024 at 9:56 AM Zhiguo Niu  wrote:
>
> Dear  Jaegeuk,
>
> Let me describe the problem process, it is reproduced by monkey stability 
> test:
>
>  1.SBI_NEED_CP flag bit is set,
>  set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
>
>  2.Ckpt thread is blocked by IO busy when it is doing CP,  it can not
> get request tag from block queue,
>  PID: 505  TASK: ff80ed7f49c0  CPU: 4COMMAND: "f2fs_ckpt-254:4"
>  #0 [ffc015fcb330] __switch_to at ffc010196350
>  #1 [ffc015fcb390] __schedule at ffc01168e53c
>  #2 [ffc015fcb3f0] schedule at ffc01168ed7c
>  #3 [ffc015fcb450] io_schedule at ffc01168f7a0
>  #4 [ffc015fcb4c0] blk_mq_get_tag at ffc0101008a4
>  #5 [ffc015fcb530] blk_mq_get_request at ffc0109241b0
>  #6 [ffc015fcb5f0] blk_mq_make_request at ffc0109233bc
>  #7 [ffc015fcb680] generic_make_request at ffc0100fc6ec
>  #8 [ffc015fcb700] submit_bio at ffc0100fc3b8
>  #9 [ffc015fcb750] __submit_bio at ffc01081a2e0
>  #10 [ffc015fcb7d0] __submit_merged_bio at ffc01081b07c
>  #11 [ffc015fcb8a0] f2fs_submit_page_write at ffc0100ecd3c
>  #12 [ffc015fcb990] f2fs_do_write_meta_page at ffc010845738
>  #13 [ffc015fcb9d0] __f2fs_write_meta_page at ffc01080a8f4
>  #14 [ffc015fcbb60] f2fs_sync_meta_pages at ffc01080a684
>  #15 [ffc015fcbca0] do_checkpoint at ffc01080f0a8
>  #16 [ffc015fcbd10] f2fs_write_checkpoint at ffc01080e50c
>  #17 [ffc015fcbdb0] __checkpoint_and_complete_reqs at ffc010810f54
>  #18 [ffc015fcbe40] issue_checkpoint_thread at ffc0108113ec
>  #19 [ffc015fcbe80] kthread at ffc0102665b0
>
>  3.Subsequent regular file fsync will trigger ckpt because SBI_NEED_CP
> has not been cleared.
>  In fact, these cases should not trigger ckpt.
>
>  4.If some processes that perform f2fs_do_sync_file are important processes
>  in the system(such as init) and are blocked for too long, it will
> cause other problems in the

Re: [f2fs-dev] [PATCH v3] f2fs: reduce expensive checkpoint trigger frequency

2024-03-04 Thread Zhiguo Niu
Dear  Jaegeuk,

Let me describe the problem process, it is reproduced by monkey stability test:

 1.SBI_NEED_CP flag bit is set,
 set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);

 2.Ckpt thread is blocked by IO busy when it is doing CP,  it can not
get request tag from block queue,
 PID: 505  TASK: ff80ed7f49c0  CPU: 4COMMAND: "f2fs_ckpt-254:4"
 #0 [ffc015fcb330] __switch_to at ffc010196350
 #1 [ffc015fcb390] __schedule at ffc01168e53c
 #2 [ffc015fcb3f0] schedule at ffc01168ed7c
 #3 [ffc015fcb450] io_schedule at ffc01168f7a0
 #4 [ffc015fcb4c0] blk_mq_get_tag at ffc0101008a4
 #5 [ffc015fcb530] blk_mq_get_request at ffc0109241b0
 #6 [ffc015fcb5f0] blk_mq_make_request at ffc0109233bc
 #7 [ffc015fcb680] generic_make_request at ffc0100fc6ec
 #8 [ffc015fcb700] submit_bio at ffc0100fc3b8
 #9 [ffc015fcb750] __submit_bio at ffc01081a2e0
 #10 [ffc015fcb7d0] __submit_merged_bio at ffc01081b07c
 #11 [ffc015fcb8a0] f2fs_submit_page_write at ffc0100ecd3c
 #12 [ffc015fcb990] f2fs_do_write_meta_page at ffc010845738
 #13 [ffc015fcb9d0] __f2fs_write_meta_page at ffc01080a8f4
 #14 [ffc015fcbb60] f2fs_sync_meta_pages at ffc01080a684
 #15 [ffc015fcbca0] do_checkpoint at ffc01080f0a8
 #16 [ffc015fcbd10] f2fs_write_checkpoint at ffc01080e50c
 #17 [ffc015fcbdb0] __checkpoint_and_complete_reqs at ffc010810f54
 #18 [ffc015fcbe40] issue_checkpoint_thread at ffc0108113ec
 #19 [ffc015fcbe80] kthread at ffc0102665b0

 3.Subsequent regular file fsync will trigger ckpt because SBI_NEED_CP
has not been cleared.
 In fact, these cases should not trigger ckpt.

 4.If some processes that perform f2fs_do_sync_file are important processes
 in the system(such as init) and are blocked for too long, it will
cause other problems in the system, ANR or android reboot
 PID: 287  TASK: ff80f9eb0ec0  CPU: 2COMMAND: "init"
 #0 [ffc01389bab0] __switch_to at ffc010196350
 #1 [ffc01389bb10] __schedule at ffc01168e53c
 #2 [ffc01389bb70] schedule at ffc01168ed7c
 #3 [ffc01389bbc0] wait_for_completion at ffc011692368
 #4 [ffc01389bca0] f2fs_issue_checkpoint at ffc010810cb0
 #5 [ffc01389bd00] f2fs_sync_fs at ffc0107f4e1c
 #6 [ffc01389bdc0] f2fs_do_sync_file at ffc0107d4d44
 #7 [ffc01389be20] f2fs_sync_file at ffc0107d492c
 #8 [ffc01389be30] __arm64_sys_fsync at ffc0105d31d8
 #9 [ffc01389be70] el0_svc_common at ffc0101aa550
 #10 [ffc01389beb0] el0_svc_handler at ffc0100886fc

and I tested Chao's patch can avoid the above case, please help
consider this patch or
any comment/suggestions about this?

thanks!

On Mon, Feb 26, 2024 at 9:22 AM 牛志国 (Zhiguo Niu)  wrote:
>
>
> Hi Jaegeuk
>
> Sorry for disturbing you, Do you have any comments about this patch from 
> Chao, I’ve met this issue several times on our platform when do monkey test.
> Thanks!
>
> -邮件原件-
> 发件人: Chao Yu 
> 发送时间: 2024年2月19日 15:19
> 收件人: jaeg...@kernel.org
> 抄送: linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org; 牛志国 
> (Zhiguo Niu) 
> 主题: Re: [PATCH v3] f2fs: reduce expensive checkpoint trigger frequency
>
>
> 注意: 这封邮件来自于外部。除非你确定邮件内容安全,否则不要点击任何链接和附件。
> CAUTION: This email originated from outside of the organization. Do not click 
> links or open attachments unless you recognize the sender and know the 
> content is safe.
>
>
>
> Jaegeuk,
>
> Any comments?
>
> On 2024/1/11 16:17, Chao Yu wrote:
> > We may trigger high frequent checkpoint for below case:
> > 1. mkdir /mnt/dir1; set dir1 encrypted 2. touch /mnt/file1; fsync
> > /mnt/file1 3. mkdir /mnt/dir2; set dir2 encrypted 4. touch /mnt/file2;
> > fsync /mnt/file2 ...
> >
> > Although, newly created dir and file are not related, due to commit
> > bbf156f7afa7 ("f2fs: fix lost xattrs of directories"), we will trigger
> > checkpoint whenever fsync() comes after a new encrypted dir created.
> >
> > In order to avoid such condition, let's record an entry including
> > directory's ino into global cache when we initialize encryption policy
> > in a checkpointed directory, and then only trigger checkpoint() when
> > target file's parent has non-persisted encryption policy, for the case
> > its parent is not checkpointed, need_do_checkpoint() has cover that by
> > verifying it with f2fs_is_checkpointed_node().
> >
> > Reported-by: Zhiguo Niu 
> > Tested-by: Zhiguo Niu 
> > Reported-by: Yunlei He 
> > Signed-off-by: Chao Yu 
> > ---
> > v3:
> > - Recently, Zhiguo Niu reported the same issue, so I repost this patch
> > for comments.
> >   fs/f2fs/f2fs.h  |  2 ++
> >   fs/f2fs/file.c 

[f2fs-dev] [PATCH] f2fs: fix to remove f2fs_bug_on in add_bio_entry

2024-03-04 Thread Zhiguo Niu
add_bio_entry should not trigger system panic when bio_add_page fail,
fix to remove it.

Fixes: 0b20fcec8651 ("f2fs: cache global IPU bio")
Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/data.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index bd8674b..2fbbf8f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -761,8 +761,10 @@ static void add_bio_entry(struct f2fs_sb_info *sbi, struct 
bio *bio,
be->bio = bio;
bio_get(bio);
 
-   if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE)
-   f2fs_bug_on(sbi, 1);
+   if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
+   bio_put(bio);
+   return;
+   }
 
f2fs_down_write(>bio_list_lock);
list_add_tail(>list, >bio_list);
-- 
1.9.1



___
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 to check result of new_curseg in f2fs_allocate_segment_for_resize

2024-03-04 Thread Zhiguo Niu
On Mon, Mar 4, 2024 at 5:19 PM Chao Yu  wrote:
>
> On 2024/3/4 15:52, Zhiguo Niu wrote:
> > On Mon, Mar 4, 2024 at 3:17 PM Chao Yu  wrote:
> >>
> >> On 2024/3/4 11:33, Zhiguo Niu wrote:
> >>> On Mon, Mar 4, 2024 at 11:19 AM Chao Yu  wrote:
> >>>>
> >>>> On 2024/3/1 19:36, Zhiguo Niu wrote:
> >>>>> new_curseg may return error if get_new_segment fail, so its result
> >>>>> should be check in its caller f2fs_allocate_segment_for_resize,
> >>>>> alos pass this results to free_segment_range.
> >>>>
> >>>> Zhiguo,
> >>>>
> >>>> What about handling all error paths of new_curseg() and change_curseg()
> >>>> in one patch?
> >>> Dear Chao,
> >>>
> >>> Do you mean to merge it with the previous patch “f2fs: fix to check
> >>> return value of f2fs_gc_range”?
> >>> Because in addition to new_curseg/change_curseg error handling, there
> >>> are some other changes in the previous patch.
> >>> besides, I searched for new related codes, and there should be the
> >>> only place left without error handling about new_curseg/
> >>> change_curseg .
> >>
> >> Zhiguo, I meant something like this?
> >>
> >> Subject: [PATCH] f2fs: fix to handle error paths of {new,change}_curseg()
> > Dear Chao,
> > I got your meaning and I think this patch looks good.
> > Please ignore my patch and use your version:).
>
> Zhiguo,
>
> This is a raw patch, can you please write commit message for it, and
> resend it once you've tested it.
Dear Chao,
OK, no problem.
thanks!
>
> Thanks,
>
> > thanks!
> >>
> >> ---
> >>fs/f2fs/f2fs.h|  4 +--
> >>fs/f2fs/gc.c  |  7 +++--
> >>fs/f2fs/segment.c | 67 +++
> >>fs/f2fs/super.c   |  4 ++-
> >>4 files changed, 54 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >> index 80789255bf68..03927f1b2ea1 100644
> >> --- a/fs/f2fs/f2fs.h
> >> +++ b/fs/f2fs/f2fs.h
> >> @@ -3702,10 +3702,10 @@ int f2fs_disable_cp_again(struct f2fs_sb_info 
> >> *sbi, block_t unusable);
> >>void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
> >>int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool 
> >> for_ra);
> >>bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
> >> -void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
> >> +int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
> >>void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
> >>void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
> >> -void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >> +int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >>  unsigned int start, unsigned int 
> >> end);
> >>int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool 
> >> force);
> >>int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
> >> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> >> index f8314765246a..854ad0a3f6ea 100644
> >> --- a/fs/f2fs/gc.c
> >> +++ b/fs/f2fs/gc.c
> >> @@ -2033,8 +2033,11 @@ static int free_segment_range(struct f2fs_sb_info 
> >> *sbi,
> >>  mutex_unlock(_I(sbi)->seglist_lock);
> >>
> >>  /* Move out cursegs from the target range */
> >> -   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
> >> -   f2fs_allocate_segment_for_resize(sbi, type, start, end);
> >> +   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; 
> >> type++) {
> >> +   err = f2fs_allocate_segment_for_resize(sbi, type, start, 
> >> end);
> >> +   if (err)
> >> +   goto out;
> >> +   }
> >>
> >>  /* do GC to move out valid blocks in the range */
> >>  err = f2fs_gc_range(sbi, start, end, dry_run, 0);
> >> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >> index 22241aba6564..2bcf01fde143 100644
> >> --- a/fs/f2fs/segment.c
> >> +++ b/fs/f2fs/segment.c
> >> @@ -2863,7 +2863,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info 
> >> *sbi, int segno)
> >> * Thi

Re: [f2fs-dev] [PATCH] f2fs: fix to check result of new_curseg in f2fs_allocate_segment_for_resize

2024-03-03 Thread Zhiguo Niu
On Mon, Mar 4, 2024 at 3:17 PM Chao Yu  wrote:
>
> On 2024/3/4 11:33, Zhiguo Niu wrote:
> > On Mon, Mar 4, 2024 at 11:19 AM Chao Yu  wrote:
> >>
> >> On 2024/3/1 19:36, Zhiguo Niu wrote:
> >>> new_curseg may return error if get_new_segment fail, so its result
> >>> should be check in its caller f2fs_allocate_segment_for_resize,
> >>> alos pass this results to free_segment_range.
> >>
> >> Zhiguo,
> >>
> >> What about handling all error paths of new_curseg() and change_curseg()
> >> in one patch?
> > Dear Chao,
> >
> > Do you mean to merge it with the previous patch “f2fs: fix to check
> > return value of f2fs_gc_range”?
> > Because in addition to new_curseg/change_curseg error handling, there
> > are some other changes in the previous patch.
> > besides, I searched for new related codes, and there should be the
> > only place left without error handling about new_curseg/
> > change_curseg .
>
> Zhiguo, I meant something like this?
>
> Subject: [PATCH] f2fs: fix to handle error paths of {new,change}_curseg()
Dear Chao,
I got your meaning and I think this patch looks good.
Please ignore my patch and use your version:).
thanks!
>
> ---
>   fs/f2fs/f2fs.h|  4 +--
>   fs/f2fs/gc.c  |  7 +++--
>   fs/f2fs/segment.c | 67 +++
>   fs/f2fs/super.c   |  4 ++-
>   4 files changed, 54 insertions(+), 28 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 80789255bf68..03927f1b2ea1 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -3702,10 +3702,10 @@ int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, 
> block_t unusable);
>   void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>   int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>   bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
> -void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
> +int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
>   void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
>   void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
> -void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> +int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> unsigned int start, unsigned int end);
>   int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool 
> force);
>   int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index f8314765246a..854ad0a3f6ea 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -2033,8 +2033,11 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
> mutex_unlock(_I(sbi)->seglist_lock);
>
> /* Move out cursegs from the target range */
> -   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
> -   f2fs_allocate_segment_for_resize(sbi, type, start, end);
> +   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++) {
> +   err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
> +   if (err)
> +   goto out;
> +   }
>
> /* do GC to move out valid blocks in the range */
> err = f2fs_gc_range(sbi, start, end, dry_run, 0);
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 22241aba6564..2bcf01fde143 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -2863,7 +2863,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info 
> *sbi, int segno)
>* This function always allocates a used segment(from dirty seglist) by SSR
>* manner, so it should recover the existing segment information of valid 
> blocks
>*/
> -static void change_curseg(struct f2fs_sb_info *sbi, int type)
> +static int change_curseg(struct f2fs_sb_info *sbi, int type)
>   {
> struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
> struct curseg_info *curseg = CURSEG_I(sbi, type);
> @@ -2888,21 +2888,24 @@ static void change_curseg(struct f2fs_sb_info *sbi, 
> int type)
> if (IS_ERR(sum_page)) {
> /* GC won't be able to use stale summary pages by cp_error */
> memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE);
> -   return;
> +   return PTR_ERR(sum_page);
> }
> sum_node = (struct f2fs_summary_block *)page_address(sum_page);
> memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
> f2fs_put_page(sum_page, 1);
> +
> +   return 0;
>   }
>
>   static int get_ssr_segment(struct f2fs_sb_info *sbi, int type

Re: [f2fs-dev] [PATCH] f2fs: fix to check result of new_curseg in f2fs_allocate_segment_for_resize

2024-03-03 Thread Zhiguo Niu
On Mon, Mar 4, 2024 at 11:19 AM Chao Yu  wrote:
>
> On 2024/3/1 19:36, Zhiguo Niu wrote:
> > new_curseg may return error if get_new_segment fail, so its result
> > should be check in its caller f2fs_allocate_segment_for_resize,
> > alos pass this results to free_segment_range.
>
> Zhiguo,
>
> What about handling all error paths of new_curseg() and change_curseg()
> in one patch?
Dear Chao,

Do you mean to merge it with the previous patch “f2fs: fix to check
return value of f2fs_gc_range”?
Because in addition to new_curseg/change_curseg error handling, there
are some other changes in the previous patch.
besides, I searched for new related codes, and there should be the
only place left without error handling about new_curseg/
change_curseg .

thanks!
>
> Thanks,
>
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/f2fs.h| 2 +-
> >   fs/f2fs/gc.c  | 7 +--
> >   fs/f2fs/segment.c | 9 +++--
> >   3 files changed, 13 insertions(+), 5 deletions(-)
> >
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index 4331012..39dda7d 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -3701,7 +3701,7 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info 
> > *sbi,
> >   void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
> >   void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
> >   void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
> > -void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> > +int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >   unsigned int start, unsigned int end);
> >   int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool 
> > force);
> >   int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index c60b747..7a458fa 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -2037,8 +2037,11 @@ static int free_segment_range(struct f2fs_sb_info 
> > *sbi,
> >   mutex_unlock(_I(sbi)->seglist_lock);
> >
> >   /* Move out cursegs from the target range */
> > - for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
> > - f2fs_allocate_segment_for_resize(sbi, type, start, end);
> > + for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++) {
> > + err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
> > + if (err)
> > + goto out;
> > + }
> >
> >   /* do GC to move out valid blocks in the range */
> >   err = f2fs_gc_range(sbi, start, end, dry_run, 0);
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index 1bb3019..2a07b9d 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -3071,11 +3071,12 @@ static bool need_new_seg(struct f2fs_sb_info *sbi, 
> > int type)
> >   return false;
> >   }
> >
> > -void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> > +int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >   unsigned int start, unsigned int end)
> >   {
> >   struct curseg_info *curseg = CURSEG_I(sbi, type);
> >   unsigned int segno;
> > + int err = 0;
> >
> >   f2fs_down_read(_I(sbi)->curseg_lock);
> >   mutex_lock(>curseg_mutex);
> > @@ -3089,7 +3090,10 @@ void f2fs_allocate_segment_for_resize(struct 
> > f2fs_sb_info *sbi, int type,
> >   change_curseg(sbi, type);
> >   else
> >   new_curseg(sbi, type, true);
> > -
> > + if (curseg->segno == NULL_SEGNO) {
> > + err = -ENOSPC;
> > + goto unlock;
> > + }
> >   stat_inc_seg_type(sbi, curseg);
> >
> >   locate_dirty_segment(sbi, segno);
> > @@ -3102,6 +3106,7 @@ void f2fs_allocate_segment_for_resize(struct 
> > f2fs_sb_info *sbi, int type,
> >
> >   mutex_unlock(>curseg_mutex);
> >   f2fs_up_read(_I(sbi)->curseg_lock);
> > + return err;
> >   }
> >
> >   static int __allocate_new_segment(struct f2fs_sb_info *sbi, int type,


___
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 check result of new_curseg in f2fs_allocate_segment_for_resize

2024-03-01 Thread Zhiguo Niu
new_curseg may return error if get_new_segment fail, so its result
should be check in its caller f2fs_allocate_segment_for_resize,
alos pass this results to free_segment_range.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/f2fs.h| 2 +-
 fs/f2fs/gc.c  | 7 +--
 fs/f2fs/segment.c | 9 +++--
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4331012..39dda7d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3701,7 +3701,7 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
 void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
 void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
-void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
unsigned int start, unsigned int end);
 int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
 int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index c60b747..7a458fa 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2037,8 +2037,11 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
mutex_unlock(_I(sbi)->seglist_lock);
 
/* Move out cursegs from the target range */
-   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
-   f2fs_allocate_segment_for_resize(sbi, type, start, end);
+   for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++) {
+   err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
+   if (err)
+   goto out;
+   }
 
/* do GC to move out valid blocks in the range */
err = f2fs_gc_range(sbi, start, end, dry_run, 0);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 1bb3019..2a07b9d 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3071,11 +3071,12 @@ static bool need_new_seg(struct f2fs_sb_info *sbi, int 
type)
return false;
 }
 
-void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
unsigned int start, unsigned int end)
 {
struct curseg_info *curseg = CURSEG_I(sbi, type);
unsigned int segno;
+   int err = 0;
 
f2fs_down_read(_I(sbi)->curseg_lock);
mutex_lock(>curseg_mutex);
@@ -3089,7 +3090,10 @@ void f2fs_allocate_segment_for_resize(struct 
f2fs_sb_info *sbi, int type,
change_curseg(sbi, type);
else
new_curseg(sbi, type, true);
-
+   if (curseg->segno == NULL_SEGNO) {
+   err = -ENOSPC;
+   goto unlock;
+   }
stat_inc_seg_type(sbi, curseg);
 
locate_dirty_segment(sbi, segno);
@@ -3102,6 +3106,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info 
*sbi, int type,
 
mutex_unlock(>curseg_mutex);
f2fs_up_read(_I(sbi)->curseg_lock);
+   return err;
 }
 
 static int __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
-- 
1.9.1



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


[f2fs-dev] [PATCH 1/2] f2fs: fix to check return value __allocate_new_segment

2024-03-01 Thread Zhiguo Niu
__allocate_new_segment may return error when get_new_segment
fails, so its caller should check its return value.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/f2fs.h | 2 +-
 fs/f2fs/recovery.c | 2 +-
 fs/f2fs/segment.c  | 7 +--
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index db05fd0..4331012 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3705,7 +3705,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info 
*sbi, int type,
unsigned int start, unsigned int end);
 int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
 int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi);
-void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
+int f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
 int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
 bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
struct cp_control *cpc);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 3078d56..c381f0a 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -851,7 +851,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct 
list_head *inode_list,
f2fs_ra_meta_pages_cond(sbi, blkaddr, ra_blocks);
}
if (!err)
-   f2fs_allocate_new_segments(sbi);
+   err = f2fs_allocate_new_segments(sbi);
return err;
 }
 
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index cdac4cb..72f6ee3 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3163,16 +3163,19 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info 
*sbi)
return err;
 }
 
-void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
+int f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
 {
int i;
+   int err = 0;
 
f2fs_down_read(_I(sbi)->curseg_lock);
down_write(_I(sbi)->sentry_lock);
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
-   __allocate_new_segment(sbi, i, false, false);
+   err += __allocate_new_segment(sbi, i, false, false);
up_write(_I(sbi)->sentry_lock);
f2fs_up_read(_I(sbi)->curseg_lock);
+
+   return err;
 }
 
 bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
-- 
1.9.1



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


[f2fs-dev] [PATCH 2/2] f2fs: fix to check return value of f2fs_gc_range

2024-03-01 Thread Zhiguo Niu
f2fs_gc_range may return error, so its caller
f2fs_allocate_pinning_section should determine whether
to do retry based on ist return value.

Also just do f2fs_gc_range when f2fs_allocate_new_section
return -EAGAIN, and check cp error case in f2fs_gc_range.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/gc.c  |  3 +++
 fs/f2fs/segment.c | 13 -
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index e435e1f..c60b747 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1986,6 +1986,9 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi,
unsigned int segno;
unsigned int gc_secs = dry_run_sections;
 
+   if (unlikely(f2fs_cp_error(sbi)))
+   return -EIO;
+
for (segno = start_seg; segno <= end_seg; segno += SEGS_PER_SEC(sbi)) {
struct gc_inode_list gc_list = {
.ilist = LIST_HEAD_INIT(gc_list.ilist),
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 72f6ee3..1bb3019 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3109,6 +3109,7 @@ static int __allocate_new_segment(struct f2fs_sb_info 
*sbi, int type,
 {
struct curseg_info *curseg = CURSEG_I(sbi, type);
unsigned int old_segno;
+   int err = 0;
 
if (type == CURSEG_COLD_DATA_PINNED && !curseg->inited)
goto allocate;
@@ -3121,8 +3122,9 @@ static int __allocate_new_segment(struct f2fs_sb_info 
*sbi, int type,
 
 allocate:
old_segno = curseg->segno;
-   if (new_curseg(sbi, type, true))
-   return -EAGAIN;
+   err = new_curseg(sbi, type, true);
+   if (err)
+   return err;
stat_inc_seg_type(sbi, curseg);
locate_dirty_segment(sbi, old_segno);
return 0;
@@ -3151,13 +3153,14 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info 
*sbi)
err = f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false);
f2fs_unlock_op(sbi);
 
-   if (f2fs_sb_has_blkzoned(sbi) && err && gc_required) {
+   if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
f2fs_down_write(>gc_lock);
-   f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk), true, 1);
+   err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk), 
true, 1);
f2fs_up_write(>gc_lock);
 
gc_required = false;
-   goto retry;
+   if (!err)
+   goto retry;
}
 
return err;
-- 
1.9.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 do sanity check in update_sit_entry

2024-02-28 Thread Zhiguo Niu
If GET_SEGNO return NULL_SEGNO for some unecpected case,
update_sit_entry will access invalid memory address,
cause system crash. It is better to do sanity check about
GET_SEGNO just like update_segment_mtime & locate_dirty_segment.

Also remove some redundant judgment code.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c616e7a..f8a823f 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2407,6 +2407,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, 
block_t blkaddr, int del)
 #endif
 
segno = GET_SEGNO(sbi, blkaddr);
+   if (segno == NULL_SEGNO)
+   return;
 
se = get_seg_entry(sbi, segno);
new_vblocks = se->valid_blocks + del;
@@ -3504,8 +3506,7 @@ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, 
struct page *page,
 * since SSR needs latest valid block information.
 */
update_sit_entry(sbi, *new_blkaddr, 1);
-   if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
-   update_sit_entry(sbi, old_blkaddr, -1);
+   update_sit_entry(sbi, old_blkaddr, -1);
 
/*
 * If the current segment is full, flush it out and replace it with a
-- 
1.9.1



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


[f2fs-dev] 答复: [bug report] f2fs: stop checkpoint when get a out-of-bounds segment

2024-02-27 Thread Zhiguo Niu
Hi Jaegeuk,
I understand what you mean^^, 
please ignore my last email, sorry again:).
Thanks!
-邮件原件-
发件人: 牛志国 (Zhiguo Niu) 
发送时间: 2024年2月28日 8:55
收件人: 'Jaegeuk Kim' ; 'Dan Carpenter' 

抄送: 'linux-f2fs-devel@lists.sourceforge.net' 
; 金红宇 (Hongyu Jin) 
; 'Chao Yu' 
主题: 答复: [f2fs-dev] [bug report] f2fs: stop checkpoint when get a out-of-bounds 
segment


Hi Jaegeuk,
Chao's patch  fix should can fix this warning:
f2fs: fix to don't call f2fs_stop_checkpoint in spinlock coverage thanks!
-邮件原件-
发件人: Jaegeuk Kim 
发送时间: 2024年2月28日 1:38
收件人: Dan Carpenter 
抄送: 牛志国 (Zhiguo Niu) ; 
linux-f2fs-devel@lists.sourceforge.net
主题: Re: [f2fs-dev] [bug report] f2fs: stop checkpoint when get a out-of-bounds 
segment


注意: 这封邮件来自于外部。除非你确定邮件内容安全,否则不要点击任何链接和附件。
CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe.



Hi,

I merged two patches, which addresses this.

f2fs: stop checkpoint when get a out-of-bounds segment
f2fs: fix to don't call f2fs_stop_checkpoint in spinlock coverage

On 02/27, Dan Carpenter wrote:
> Hello Zhiguo Niu,
>
> The patch 7a0392932f97: "f2fs: stop checkpoint when get a 
> out-of-bounds segment" from Feb 20, 2024 (linux-next), leads to the 
> following Smatch static checker warning:
>
>   fs/f2fs/checkpoint.c:34 f2fs_stop_checkpoint()
>   warn: sleeping in atomic context
>
> fs/f2fs/segment.c
>   2650  static void get_new_segment(struct f2fs_sb_info *sbi,
>   2651  unsigned int *newseg, bool new_sec, bool 
> pinning)
>   2652  {
>   2653  struct free_segmap_info *free_i = FREE_I(sbi);
>   2654  unsigned int segno, secno, zoneno;
>   2655  unsigned int total_zones = MAIN_SECS(sbi) / 
> sbi->secs_per_zone;
>   2656  unsigned int hint = GET_SEC_FROM_SEG(sbi, *newseg);
>   2657  unsigned int old_zoneno = GET_ZONE_FROM_SEG(sbi, *newseg);
>   2658  bool init = true;
>   2659  int i;
>   2660
>   2661  spin_lock(_i->segmap_lock);
> ^^^ preempt disabled here
>
>   2662
>   2663  if (!new_sec && ((*newseg + 1) % SEGS_PER_SEC(sbi))) {
>   2664  segno = find_next_zero_bit(free_i->free_segmap,
>   2665  GET_SEG_FROM_SEC(sbi, hint + 1), *newseg + 1);
>   2666  if (segno < GET_SEG_FROM_SEC(sbi, hint + 1))
>   2667  goto got_it;
>   2668  }
>   2669
>   2670  /*
>   2671   * If we format f2fs on zoned storage, let's try to get 
> pinned sections
>   2672   * from beginning of the storage, which should be a 
> conventional one.
>   2673   */
>   2674  if (f2fs_sb_has_blkzoned(sbi)) {
>   2675  segno = pinning ? 0 : max(first_zoned_segno(sbi), 
> *newseg);
>   2676  hint = GET_SEC_FROM_SEG(sbi, segno);
>   2677  }
>   2678
>   2679  find_other_zone:
>   2680  secno = find_next_zero_bit(free_i->free_secmap, 
> MAIN_SECS(sbi), hint);
>   2681  if (secno >= MAIN_SECS(sbi)) {
>   2682  secno = find_first_zero_bit(free_i->free_secmap,
>   2683  
> MAIN_SECS(sbi));
>   2684  if (secno >= MAIN_SECS(sbi)) {
>   2685  f2fs_stop_checkpoint(sbi, false,
>   ^ This 
> false means we sleep while holding a spin lock.
>
>   2686  STOP_CP_REASON_NO_SEGMENT);
>   2687  f2fs_bug_on(sbi, 1);
>   2688  }
>   2689  }
>   2690  segno = GET_SEG_FROM_SEC(sbi, secno);
>   2691  zoneno = GET_ZONE_FROM_SEC(sbi, secno);
>
> fs/f2fs/checkpoint.c
> 29 void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
> 30 unsigned char reason)
> 31 {
> 32 f2fs_build_fault_attr(sbi, 0, 0);
> 33 if (!end_io)
> --> 34 f2fs_flush_merged_writes(sbi);
> 35 f2fs_handle_critical_error(sbi, reason, end_io);
> 36 }
>
> regards,
> dan carpenter
>
>
> ___
> 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


Re: [f2fs-dev] [PATCH v2 0/4] f2fs: fix panic issue in small capacity device

2024-02-27 Thread Zhiguo Niu
On Wed, Feb 28, 2024 at 1:18 AM Jaegeuk Kim  wrote:
>
> On 02/27, Zhiguo Niu wrote:
> > On Tue, Feb 27, 2024 at 9:13 AM Jaegeuk Kim  wrote:
> > >
> > > On 02/26, Zhiguo Niu wrote:
> > > > Dear Chao,
> > > >
> > > > On Fri, Feb 23, 2024 at 10:38 AM Chao Yu  wrote:
> > > > >
> > > > > On 2024/2/23 10:01, Zhiguo Niu wrote:
> > > > > >
> > > > > >
> > > > > > On Thu, Feb 22, 2024 at 8:30 PM Chao Yu  > > > > > <mailto:c...@kernel.org>> wrote:
> > > > > >
> > > > > > On 2024/2/7 10:01, Zhiguo Niu wrote:
> > > > > >  > A panic issue happened in a reboot test in small capacity 
> > > > > > device
> > > > > >  > as following:
> > > > > >  > 1.The device size is 64MB, and main area has 24 segments, and
> > > > > >  > CONFIG_F2FS_CHECK_FS is not enabled.
> > > > > >  > 2.There is no any free segments left shown in 
> > > > > > free_segmap_info,
> > > > > >  > then another write request cause get_new_segment get a 
> > > > > > out-of-bound
> > > > > >  > segment with segno 24.
> > > > > >  > 3.panic happen in update_sit_entry because access invalid 
> > > > > > bitmap
> > > > > >  > pointer.
> > > > > >
> > > > > > Zhiguo,
> > > > > >
> > > > > > Can you please try below patch to see whether it can fix your 
> > > > > > problem?
> > > > > >
> > > > > > 
> > > > > > https://lore.kernel.org/linux-f2fs-devel/20240222121851.883141-3-c...@kernel.org
> > > > > >  
> > > > > > <https://lore.kernel.org/linux-f2fs-devel/20240222121851.883141-3-c...@kernel.org>
> > > > > >
> > > > > > Thanks,
> > > > > >
> > > > > >
> > > > > > Dear Chao,
> > > > > > I need to coordinate the testing resources. The previous testing 
> > > > > > has been stopped because it was fixed with the current patch. In 
> > > > > > addition, this requires stability testing to reproduce, so it will 
> > > > > > take a certain amount of time. If there is any situation, I will 
> > > > > > tell you in time.
> > > > >
> > > > > Zhiguo, thank you!
> > > >
> > > > We tested this patch  this weekend on the previous version with
> > > > problem, and it can not reproduce panic issues,
> > > > so this patch should fix the original issue.
> > > > thanks!
> > >
> > Dear Jaegeuk,
> > > Hey, do you guys please point out which patches were tested without what?
> > This problem occurred during our platform stability testing.
> > it can be fixed by my  this patch set, mainly be fixed by:
> > f2fs: fix panic issue in update_sit_entry & f2fs: enhance judgment
> > conditions of GET_SEGNO
> > and Chao's patch can also fix this problems testing without my patch
> > > IOWs, which patches should I remove and keep Chao's patch?
> > I think chao's patch is more reasonable, it does error handling more 
> > complete.
> > but my patch just do some sanity check for return value of GET_SEGNO
> > Same as other codes(update_segment_mtime)
> > and i think it also needed except this part:
>
> Thanks for confirmation. It seems it'd be better to revert yours and apply
> Chao's patch first. If you think there's something to improve on top of it,
> could you please send another patch afterwards?

OK, I think this two patches still needed
  f2fs: correct counting methods of free_segments in __set_inuse
  f2fs: fix panic issue in update_sit_entry
and I'll reorganize it
thanks
>
> >
> > diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> > index 3bf2ce46fa0907..bb22feeae1cfcb 100644
> > --- a/fs/f2fs/segment.h
> > +++ b/fs/f2fs/segment.h
> > @@ -96,7 +96,8 @@ static inline void sanity_check_seg_type(struct
> > f2fs_sb_info *sbi,
> > (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (BLKS_PER_SEG(sbi) - 1))
> > #define GET_SEGNO(sbi, blk_addr) \
> > - ((!__is_valid_data_blkaddr(blk_addr)) ? \
> > + ((!__is_valid_data_blkaddr(blk_addr) || \
> > + !f2fs_is_valid_blkaddr(sbi, blk_addr, DATA_GENERIC)) ? \
> > NULL_SEGNO : GET_L2

[f2fs-dev] 答复: [bug report] f2fs: stop checkpoint when get a out-of-bounds segment

2024-02-27 Thread Zhiguo Niu

Hi Jaegeuk,
Chao's patch  fix should can fix this warning:
f2fs: fix to don't call f2fs_stop_checkpoint in spinlock coverage thanks!
-邮件原件-
发件人: Jaegeuk Kim 
发送时间: 2024年2月28日 1:38
收件人: Dan Carpenter 
抄送: 牛志国 (Zhiguo Niu) ; 
linux-f2fs-devel@lists.sourceforge.net
主题: Re: [f2fs-dev] [bug report] f2fs: stop checkpoint when get a out-of-bounds 
segment


注意: 这封邮件来自于外部。除非你确定邮件内容安全,否则不要点击任何链接和附件。
CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe.



Hi,

I merged two patches, which addresses this.

f2fs: stop checkpoint when get a out-of-bounds segment
f2fs: fix to don't call f2fs_stop_checkpoint in spinlock coverage

On 02/27, Dan Carpenter wrote:
> Hello Zhiguo Niu,
>
> The patch 7a0392932f97: "f2fs: stop checkpoint when get a 
> out-of-bounds segment" from Feb 20, 2024 (linux-next), leads to the 
> following Smatch static checker warning:
>
>   fs/f2fs/checkpoint.c:34 f2fs_stop_checkpoint()
>   warn: sleeping in atomic context
>
> fs/f2fs/segment.c
>   2650  static void get_new_segment(struct f2fs_sb_info *sbi,
>   2651  unsigned int *newseg, bool new_sec, bool 
> pinning)
>   2652  {
>   2653  struct free_segmap_info *free_i = FREE_I(sbi);
>   2654  unsigned int segno, secno, zoneno;
>   2655  unsigned int total_zones = MAIN_SECS(sbi) / 
> sbi->secs_per_zone;
>   2656  unsigned int hint = GET_SEC_FROM_SEG(sbi, *newseg);
>   2657  unsigned int old_zoneno = GET_ZONE_FROM_SEG(sbi, *newseg);
>   2658  bool init = true;
>   2659  int i;
>   2660
>   2661  spin_lock(_i->segmap_lock);
> ^^^ preempt disabled here
>
>   2662
>   2663  if (!new_sec && ((*newseg + 1) % SEGS_PER_SEC(sbi))) {
>   2664  segno = find_next_zero_bit(free_i->free_segmap,
>   2665  GET_SEG_FROM_SEC(sbi, hint + 1), *newseg + 1);
>   2666  if (segno < GET_SEG_FROM_SEC(sbi, hint + 1))
>   2667  goto got_it;
>   2668  }
>   2669
>   2670  /*
>   2671   * If we format f2fs on zoned storage, let's try to get 
> pinned sections
>   2672   * from beginning of the storage, which should be a 
> conventional one.
>   2673   */
>   2674  if (f2fs_sb_has_blkzoned(sbi)) {
>   2675  segno = pinning ? 0 : max(first_zoned_segno(sbi), 
> *newseg);
>   2676  hint = GET_SEC_FROM_SEG(sbi, segno);
>   2677  }
>   2678
>   2679  find_other_zone:
>   2680  secno = find_next_zero_bit(free_i->free_secmap, 
> MAIN_SECS(sbi), hint);
>   2681  if (secno >= MAIN_SECS(sbi)) {
>   2682  secno = find_first_zero_bit(free_i->free_secmap,
>   2683  
> MAIN_SECS(sbi));
>   2684  if (secno >= MAIN_SECS(sbi)) {
>   2685  f2fs_stop_checkpoint(sbi, false,
>   ^ This 
> false means we sleep while holding a spin lock.
>
>   2686  STOP_CP_REASON_NO_SEGMENT);
>   2687  f2fs_bug_on(sbi, 1);
>   2688  }
>   2689  }
>   2690  segno = GET_SEG_FROM_SEC(sbi, secno);
>   2691  zoneno = GET_ZONE_FROM_SEC(sbi, secno);
>
> fs/f2fs/checkpoint.c
> 29 void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
> 30 unsigned char reason)
> 31 {
> 32 f2fs_build_fault_attr(sbi, 0, 0);
> 33 if (!end_io)
> --> 34 f2fs_flush_merged_writes(sbi);
> 35 f2fs_handle_critical_error(sbi, reason, end_io);
> 36 }
>
> regards,
> dan carpenter
>
>
> ___
> 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


Re: [f2fs-dev] [PATCH v2 0/4] f2fs: fix panic issue in small capacity device

2024-02-26 Thread Zhiguo Niu
On Tue, Feb 27, 2024 at 9:13 AM Jaegeuk Kim  wrote:
>
> On 02/26, Zhiguo Niu wrote:
> > Dear Chao,
> >
> > On Fri, Feb 23, 2024 at 10:38 AM Chao Yu  wrote:
> > >
> > > On 2024/2/23 10:01, Zhiguo Niu wrote:
> > > >
> > > >
> > > > On Thu, Feb 22, 2024 at 8:30 PM Chao Yu  > > > <mailto:c...@kernel.org>> wrote:
> > > >
> > > > On 2024/2/7 10:01, Zhiguo Niu wrote:
> > > >  > A panic issue happened in a reboot test in small capacity device
> > > >  > as following:
> > > >  > 1.The device size is 64MB, and main area has 24 segments, and
> > > >  > CONFIG_F2FS_CHECK_FS is not enabled.
> > > >  > 2.There is no any free segments left shown in free_segmap_info,
> > > >  > then another write request cause get_new_segment get a 
> > > > out-of-bound
> > > >  > segment with segno 24.
> > > >  > 3.panic happen in update_sit_entry because access invalid bitmap
> > > >  > pointer.
> > > >
> > > > Zhiguo,
> > > >
> > > > Can you please try below patch to see whether it can fix your 
> > > > problem?
> > > >
> > > > 
> > > > https://lore.kernel.org/linux-f2fs-devel/20240222121851.883141-3-c...@kernel.org
> > > >  
> > > > <https://lore.kernel.org/linux-f2fs-devel/20240222121851.883141-3-c...@kernel.org>
> > > >
> > > > Thanks,
> > > >
> > > >
> > > > Dear Chao,
> > > > I need to coordinate the testing resources. The previous testing has 
> > > > been stopped because it was fixed with the current patch. In addition, 
> > > > this requires stability testing to reproduce, so it will take a certain 
> > > > amount of time. If there is any situation, I will tell you in time.
> > >
> > > Zhiguo, thank you!
> >
> > We tested this patch  this weekend on the previous version with
> > problem, and it can not reproduce panic issues,
> > so this patch should fix the original issue.
> > thanks!
>
Dear Jaegeuk,
> Hey, do you guys please point out which patches were tested without what?
This problem occurred during our platform stability testing.
it can be fixed by my  this patch set, mainly be fixed by:
f2fs: fix panic issue in update_sit_entry & f2fs: enhance judgment
conditions of GET_SEGNO
and Chao's patch can also fix this problems testing without my patch
> IOWs, which patches should I remove and keep Chao's patch?
I think chao's patch is more reasonable, it does error handling more complete.
but my patch just do some sanity check for return value of GET_SEGNO
Same as other codes(update_segment_mtime)
and i think it also needed except this part:

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 3bf2ce46fa0907..bb22feeae1cfcb 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -96,7 +96,8 @@ static inline void sanity_check_seg_type(struct
f2fs_sb_info *sbi,
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (BLKS_PER_SEG(sbi) - 1))
#define GET_SEGNO(sbi, blk_addr) \
- ((!__is_valid_data_blkaddr(blk_addr)) ? \
+ ((!__is_valid_data_blkaddr(blk_addr) || \
+ !f2fs_is_valid_blkaddr(sbi, blk_addr, DATA_GENERIC)) ? \
NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \
GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
#define CAP_BLKS_PER_SEC(sbi)
because Chao's patch let new_addr=null_addr when  get_new_segment
returns NOSPACE,
so I think this can be reverted and it also saves code running time.
How about Chao's opinions?
thanks!
>
> >
> > >
> > > BTW, I've tested this patch for a while, and it looks there is no issue w/
> > > FAULT_NO_SEGMENT fault injection is on.
> > >
> > > > btw, Why can’t I see this patch on your branch^^?
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/chao/linux.git/log/?h=dev-test
> > > >  
> > > > <https://git.kernel.org/pub/scm/linux/kernel/git/chao/linux.git/log/?h=dev-test>
> > >
> > > Too lazy to push patches in time, will do it in this weekend. :P
> > >
> > > > thanks!
> > > >
> > > >
> > > >  >
> > > >  > More detail shown in following patch sets.
> > > >  > The three patches are splited here because the modifications are
> > > >  > relatively independent and more readable.
> > > >  >
> > > >  > ---
> > > >  > Changes of v2: stop checkpoint when get a out-of-bound segment
> > > >  > ---
> > > >  >
> > > >  > Zhiguo Niu (4):
> > > >  >f2fs: correct counting methods of free_segments in __set_inuse
> > > >  >f2fs: fix panic issue in update_sit_entry
> > > >  >f2fs: enhance judgment conditions of GET_SEGNO
> > > >  >f2fs: stop checkpoint when get a out-of-bounds segment
> > > >  >
> > > >  >   fs/f2fs/file.c  |  7 ++-
> > > >  >   fs/f2fs/segment.c   | 21 -
> > > >  >   fs/f2fs/segment.h   |  7 ---
> > > >  >   include/linux/f2fs_fs.h |  1 +
> > > >  >   4 files changed, 27 insertions(+), 9 deletions(-)
> > > >  >
> > > >


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


Re: [f2fs-dev] [PATCH 3/4] f2fs: fix to handle segment allocation failure correctly

2024-02-26 Thread Zhiguo Niu
On Mon, Feb 26, 2024 at 3:46 PM Chao Yu  wrote:
>
> Loop to Zhiguo,
>
> On 2024/2/22 20:18, Chao Yu wrote:
> > If CONFIG_F2FS_CHECK_FS is off, and for very rare corner case that
> > we run out of free segment, we should not panic kernel, instead,
> > let's handle such error correctly in its caller.
> >
> > Signed-off-by: Chao Yu 
Tested-by: Zhiguo Niu 
Thanks!
> > ---
> >   fs/f2fs/data.c|  7 +--
> >   fs/f2fs/f2fs.h|  2 +-
> >   fs/f2fs/file.c|  7 ++-
> >   fs/f2fs/gc.c  |  7 ++-
> >   fs/f2fs/segment.c | 46 +++---
> >   5 files changed, 57 insertions(+), 12 deletions(-)
> >
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index 0c9aa3082fcf..c21b92f18463 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -1416,8 +1416,11 @@ static int __allocate_data_block(struct 
> > dnode_of_data *dn, int seg_type)
> >
> >   set_summary(, dn->nid, dn->ofs_in_node, ni.version);
> >   old_blkaddr = dn->data_blkaddr;
> > - f2fs_allocate_data_block(sbi, NULL, old_blkaddr, >data_blkaddr,
> > - , seg_type, NULL);
> > + err = f2fs_allocate_data_block(sbi, NULL, old_blkaddr,
> > + >data_blkaddr, , seg_type, NULL);
> > + if (err)
> > + return err;
> > +
> >   if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
> >   f2fs_invalidate_internal_cache(sbi, old_blkaddr);
> >
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index fbbe9a0a4221..6390c3d551cb 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -3726,7 +3726,7 @@ void f2fs_replace_block(struct f2fs_sb_info *sbi, 
> > struct dnode_of_data *dn,
> >   block_t old_addr, block_t new_addr,
> >   unsigned char version, bool recover_curseg,
> >   bool recover_newaddr);
> > -void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
> > +int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
> >   block_t old_blkaddr, block_t *new_blkaddr,
> >   struct f2fs_summary *sum, int type,
> >   struct f2fs_io_info *fio);
> > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > index 088d0e79fbbc..d6ec744f1545 100644
> > --- a/fs/f2fs/file.c
> > +++ b/fs/f2fs/file.c
> > @@ -2262,8 +2262,11 @@ static int f2fs_ioc_shutdown(struct file *filp, 
> > unsigned long arg)
> >   case F2FS_GOING_DOWN_METASYNC:
> >   /* do checkpoint only */
> >   ret = f2fs_sync_fs(sb, 1);
> > - if (ret)
> > + if (ret) {
> > + if (ret == -EIO)
> > + ret = 0;
> >   goto out;
> > + }
> >   f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
> >   break;
> >   case F2FS_GOING_DOWN_NOSYNC:
> > @@ -2279,6 +2282,8 @@ static int f2fs_ioc_shutdown(struct file *filp, 
> > unsigned long arg)
> >   set_sbi_flag(sbi, SBI_IS_DIRTY);
> >   /* do checkpoint only */
> >   ret = f2fs_sync_fs(sb, 1);
> > + if (ret == -EIO)
> > + ret = 0;
> >   goto out;
> >   default:
> >   ret = -EINVAL;
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index 6d160d50e14e..42e75e9b8b6b 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -1358,8 +1358,13 @@ static int move_data_block(struct inode *inode, 
> > block_t bidx,
> >   set_summary(, dn.nid, dn.ofs_in_node, ni.version);
> >
> >   /* allocate block address */
> > - f2fs_allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, ,
> > + err = f2fs_allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, 
> > ,
> >   , type, NULL);
> > + if (err) {
> > + f2fs_put_page(mpage, 1);
> > + /* filesystem should shutdown, no need to recovery block */
> > + goto up_out;
> > + }
> >
> >   fio.encrypted_page = f2fs_pagecache_get_page(META_MAPPING(fio.sbi),
> >   newaddr, FGP_LOCK | FGP_CREAT, GFP_NOFS);
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index 8edc42071e6f..71f523431e87 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -400,6 

Re: [f2fs-dev] [PATCH v2 0/4] f2fs: fix panic issue in small capacity device

2024-02-25 Thread Zhiguo Niu
Dear Chao,

On Fri, Feb 23, 2024 at 10:38 AM Chao Yu  wrote:
>
> On 2024/2/23 10:01, Zhiguo Niu wrote:
> >
> >
> > On Thu, Feb 22, 2024 at 8:30 PM Chao Yu  > <mailto:c...@kernel.org>> wrote:
> >
> > On 2024/2/7 10:01, Zhiguo Niu wrote:
> >  > A panic issue happened in a reboot test in small capacity device
> >  > as following:
> >  > 1.The device size is 64MB, and main area has 24 segments, and
> >  > CONFIG_F2FS_CHECK_FS is not enabled.
> >  > 2.There is no any free segments left shown in free_segmap_info,
> >  > then another write request cause get_new_segment get a out-of-bound
> >  > segment with segno 24.
> >  > 3.panic happen in update_sit_entry because access invalid bitmap
> >  > pointer.
> >
> > Zhiguo,
> >
> > Can you please try below patch to see whether it can fix your problem?
> >
> > 
> > https://lore.kernel.org/linux-f2fs-devel/20240222121851.883141-3-c...@kernel.org
> >  
> > <https://lore.kernel.org/linux-f2fs-devel/20240222121851.883141-3-c...@kernel.org>
> >
> > Thanks,
> >
> >
> > Dear Chao,
> > I need to coordinate the testing resources. The previous testing has been 
> > stopped because it was fixed with the current patch. In addition, this 
> > requires stability testing to reproduce, so it will take a certain amount 
> > of time. If there is any situation, I will tell you in time.
>
> Zhiguo, thank you!

We tested this patch  this weekend on the previous version with
problem, and it can not reproduce panic issues,
so this patch should fix the original issue.
thanks!

>
> BTW, I've tested this patch for a while, and it looks there is no issue w/
> FAULT_NO_SEGMENT fault injection is on.
>
> > btw, Why can’t I see this patch on your branch^^?
> > https://git.kernel.org/pub/scm/linux/kernel/git/chao/linux.git/log/?h=dev-test
> >  
> > <https://git.kernel.org/pub/scm/linux/kernel/git/chao/linux.git/log/?h=dev-test>
>
> Too lazy to push patches in time, will do it in this weekend. :P
>
> > thanks!
> >
> >
> >  >
> >  > More detail shown in following patch sets.
> >  > The three patches are splited here because the modifications are
> >  > relatively independent and more readable.
> >  >
> >  > ---
> >  > Changes of v2: stop checkpoint when get a out-of-bound segment
> >  > ---
> >  >
> >  > Zhiguo Niu (4):
> >  >f2fs: correct counting methods of free_segments in __set_inuse
> >  >f2fs: fix panic issue in update_sit_entry
> >  >f2fs: enhance judgment conditions of GET_SEGNO
> >  >f2fs: stop checkpoint when get a out-of-bounds segment
> >  >
> >  >   fs/f2fs/file.c  |  7 ++-
> >  >   fs/f2fs/segment.c   | 21 -
> >  >   fs/f2fs/segment.h   |  7 ---
> >  >   include/linux/f2fs_fs.h |  1 +
> >  >   4 files changed, 27 insertions(+), 9 deletions(-)
> >  >
> >


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


[f2fs-dev] 答复: [PATCH v3] f2fs: reduce expensive checkpoint trigger frequency

2024-02-25 Thread Zhiguo Niu

Hi Jaegeuk

Sorry for disturbing you, Do you have any comments about this patch from Chao, 
I’ve met this issue several times on our platform when do monkey test.
Thanks!

-邮件原件-
发件人: Chao Yu 
发送时间: 2024年2月19日 15:19
收件人: jaeg...@kernel.org
抄送: linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org; 牛志国 
(Zhiguo Niu) 
主题: Re: [PATCH v3] f2fs: reduce expensive checkpoint trigger frequency


注意: 这封邮件来自于外部。除非你确定邮件内容安全,否则不要点击任何链接和附件。
CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe.



Jaegeuk,

Any comments?

On 2024/1/11 16:17, Chao Yu wrote:
> We may trigger high frequent checkpoint for below case:
> 1. mkdir /mnt/dir1; set dir1 encrypted 2. touch /mnt/file1; fsync 
> /mnt/file1 3. mkdir /mnt/dir2; set dir2 encrypted 4. touch /mnt/file2; 
> fsync /mnt/file2 ...
>
> Although, newly created dir and file are not related, due to commit 
> bbf156f7afa7 ("f2fs: fix lost xattrs of directories"), we will trigger 
> checkpoint whenever fsync() comes after a new encrypted dir created.
>
> In order to avoid such condition, let's record an entry including 
> directory's ino into global cache when we initialize encryption policy 
> in a checkpointed directory, and then only trigger checkpoint() when 
> target file's parent has non-persisted encryption policy, for the case 
> its parent is not checkpointed, need_do_checkpoint() has cover that by 
> verifying it with f2fs_is_checkpointed_node().
>
> Reported-by: Zhiguo Niu 
> Tested-by: Zhiguo Niu 
> Reported-by: Yunlei He 
> Signed-off-by: Chao Yu 
> ---
> v3:
> - Recently, Zhiguo Niu reported the same issue, so I repost this patch 
> for comments.
>   fs/f2fs/f2fs.h  |  2 ++
>   fs/f2fs/file.c  |  3 +++
>   fs/f2fs/xattr.c | 16 ++--
>   include/trace/events/f2fs.h |  3 ++-
>   4 files changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 
> e2e0ca45f881..0094a8c85f4a 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -279,6 +279,7 @@ enum {
>   APPEND_INO, /* for append ino list */
>   UPDATE_INO, /* for update ino list */
>   TRANS_DIR_INO,  /* for transactions dir ino list */
> + ENC_DIR_INO,/* for encrypted dir ino list */
>   FLUSH_INO,  /* for multiple device flushing */
>   MAX_INO_ENTRY,  /* max. list */
>   };
> @@ -1147,6 +1148,7 @@ enum cp_reason_type {
>   CP_FASTBOOT_MODE,
>   CP_SPEC_LOG_NUM,
>   CP_RECOVER_DIR,
> + CP_ENC_DIR,
>   };
>
>   enum iostat_type {
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 
> 8198afb5fb9c..18b33b1f0c83 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -218,6 +218,9 @@ static inline enum cp_reason_type 
> need_do_checkpoint(struct inode *inode)
>   f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino,
>   TRANS_DIR_INO))
>   cp_reason = CP_RECOVER_DIR;
> + else if (f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino,
> + ENC_DIR_INO))
> + cp_reason = CP_ENC_DIR;
>
>   return cp_reason;
>   }
> diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 
> f290fe9327c4..cbd1b88297fe 100644
> --- a/fs/f2fs/xattr.c
> +++ b/fs/f2fs/xattr.c
> @@ -629,6 +629,7 @@ static int __f2fs_setxattr(struct inode *inode, int index,
>   const char *name, const void *value, size_t size,
>   struct page *ipage, int flags)
>   {
> + struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
>   struct f2fs_xattr_entry *here, *last;
>   void *base_addr, *last_base_addr;
>   int found, newsize;
> @@ -772,8 +773,19 @@ static int __f2fs_setxattr(struct inode *inode, int 
> index,
>   if (index == F2FS_XATTR_INDEX_ENCRYPTION &&
>   !strcmp(name, F2FS_XATTR_NAME_ENCRYPTION_CONTEXT))
>   f2fs_set_encrypted_inode(inode);
> - if (S_ISDIR(inode->i_mode))
> - set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
> +
> + if (S_ISDIR(inode->i_mode)) {
> + /*
> +  * In restrict mode, fsync() always tries triggering checkpoint
> +  * for all metadata consistency, in other mode, it only triggers
> +  * checkpoint when parent's encryption metadata updates.
> +  */
> + if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
> + set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
> + else if

[f2fs-dev] [PATCH] f2fs-tools: add a new stop cp reason STOP_CP_REASON_NO_SEGMENT

2024-02-20 Thread Zhiguo Niu
Add a new stop cp reason STOP_CP_REASON_NO_SEGMENT for keeping
consistent with kernel codes.

Signed-off-by: Zhiguo Niu 
---
 fsck/mount.c  | 1 +
 include/f2fs_fs.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/fsck/mount.c b/fsck/mount.c
index 50afd01..b983920 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -679,6 +679,7 @@ static char *stop_reason_str[] = {
[STOP_CP_REASON_CORRUPTED_SUMMARY]  = "corrupted_summary",
[STOP_CP_REASON_UPDATE_INODE]   = "update_inode",
[STOP_CP_REASON_FLUSH_FAIL] = "flush_fail",
+   [STOP_CP_REASON_NO_SEGMENT] = "no_segment",
 };
 
 void print_sb_stop_reason(struct f2fs_super_block *sb)
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 5e9dfad..fb2a863 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -718,6 +718,7 @@ enum stop_cp_reason {
STOP_CP_REASON_CORRUPTED_SUMMARY,
STOP_CP_REASON_UPDATE_INODE,
STOP_CP_REASON_FLUSH_FAIL,
+   STOP_CP_REASON_NO_SEGMENT,
STOP_CP_REASON_MAX,
 };
 
-- 
1.9.1



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


[f2fs-dev] [PATCH v4 4/4] f2fs: stop checkpoint when get a out-of-bounds segment

2024-02-19 Thread Zhiguo Niu
There is low probability that an out-of-bounds segment will be got
on a small-capacity device. In order to prevent subsequent write requests
allocating block address from this invalid segment, which may cause
unexpected issue, stop checkpoint should be performed.

Also introduce a new stop cp reason: STOP_CP_REASON_NO_SEGMENT.

Signed-off-by: Zhiguo Niu 
---
changes of v4: use more suitable MACRO name according to Chao's suggestions
changes of v3: correct MACRO spelling and update based on the lastes code
---
---
 fs/f2fs/segment.c   | 7 ++-
 include/linux/f2fs_fs.h | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c25aaec..e42e34c 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2665,7 +2665,12 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
if (secno >= MAIN_SECS(sbi)) {
secno = find_first_zero_bit(free_i->free_secmap,
MAIN_SECS(sbi));
-   f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi));
+   if (secno >= MAIN_SECS(sbi)) {
+   f2fs_stop_checkpoint(sbi, false,
+   STOP_CP_REASON_NO_SEGMENT);
+   f2fs_bug_on(sbi, 1);
+   }
+
}
segno = GET_SEG_FROM_SEC(sbi, secno);
zoneno = GET_ZONE_FROM_SEC(sbi, secno);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 9b69c50..755e9a4 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -75,6 +75,7 @@ enum stop_cp_reason {
STOP_CP_REASON_CORRUPTED_SUMMARY,
STOP_CP_REASON_UPDATE_INODE,
STOP_CP_REASON_FLUSH_FAIL,
+   STOP_CP_REASON_NO_SEGMENT,
STOP_CP_REASON_MAX,
 };
 
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH v7] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-02-19 Thread Zhiguo Niu
On Tue, Feb 20, 2024 at 10:36 AM Chao Yu  wrote:
>
> On 2024/2/19 22:36, Chao Yu wrote:
>  Please think about how to optimize this, which is really ugly now
> ---
>   fs/f2fs/checkpoint.c | 12 
>   1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index 87b7c988c8ca..089c26b80be3 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -135,7 +135,7 @@ struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, 
> pgoff_t index)
>   }
>
>   static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
> -   int type)
> +   int type, bool *record_error)
>   {
> struct seg_entry *se;
> unsigned int segno, offset;
> @@ -160,6 +160,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
> block_t blkaddr,
>  blkaddr, exist);
> set_sbi_flag(sbi, SBI_NEED_FSCK);
> dump_stack();
> +   *record_error = true;
> }
>
> return exist;
> @@ -209,10 +210,13 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
> *sbi,
> dump_stack();
> goto err;
> } else {
> -   valid = __is_bitmap_valid(sbi, blkaddr, type);
> -   if ((!valid && type != DATA_GENERIC_ENHANCE_UPDATE) ||
> -   (valid && type == 
> DATA_GENERIC_ENHANCE_UPDATE))
> +   bool record_error = false;
> +
> +   valid = __is_bitmap_valid(sbi, blkaddr, type,
> +   _error);
> +   if (!valid || record_error)
if   type == DATA_GENERIC_ENHANCE_UPDATE && bitmap check invalid,  it
is a OK case, but !valid
will goto do error handling.
I think do f2fs_handle_error in __is_bitmap_valid is a good way.

> goto err;
> +   return valid;
> }
> break;
> case META_GENERIC:
> --
> 2.40.1
>


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


Re: [f2fs-dev] [PATCH v7] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-02-19 Thread Zhiguo Niu
Dear Chao

On Mon, Feb 19, 2024 at 11:46 AM Chao Yu  wrote:
>
> On 2024/2/6 11:32, Jaegeuk Kim wrote:
> > On 02/05, Chao Yu wrote:
> >> On 2024/2/5 11:30, Zhiguo Niu wrote:
> >>> There are some cases of f2fs_is_valid_blkaddr not handled as
> >>> ERROR_INVALID_BLKADDR,so unify the error handling about all of
> >>> f2fs_is_valid_blkaddr.
> >>>
> >>> Signed-off-by: Zhiguo Niu 
> >>> Signed-off-by: Chao Yu 
> >>> ---
> >>> changes of v7: update patch according to sync with Chao
> >>> -restore some code to original
> >>> -modify err handle of __is_bitmap_valid for covering all cases
> >>> changes of v6: improve patch according to Chao's suggestions
> >>> -restore dump_stack to original position
> >>> -adjuest code sequence of __is_bitmap_check_valid
> >>> changes of v5: improve patch according to Jaegeuk's suggestiongs
> >>> -restore return value of some f2fs_is_valid_blkaddr error case to 
> >>> original
> >>> -move cp_err checking to outermost for unified processing
> >>> -return true directly for case (type=DATA_GENERIC_ENHANCE_READ) in
> >>>  __is_bitmap_valid to avoid meaningless flow
> >>> -rename __is_bitmap_valid to __is_bitmap_check_valid for avoiding 
> >>> ambiguity
> >>>  and handling its return value in the caller uniformly, also cooperate
> >>>  switch checking true to false for error case of
> >>>  f2fs_is_valid_blkaddr(type=DATA_GENERIC_ENHANCE_UPDATE) in 
> >>> do_recover_data
> >>>  for more readable
> >>> changes of v4: update according to the latest code
> >>> changes of v3:
> >>> -rebase patch to dev-test
> >>> -correct return value for some f2fs_is_valid_blkaddr error case
> >>> changes of v2: improve patch according Chao's suggestions.
> >>> ---
> >>> ---
> >>>fs/f2fs/checkpoint.c   | 33 ++---
> >>>fs/f2fs/data.c | 22 +++---
> >>>fs/f2fs/extent_cache.c |  5 +
> >>>fs/f2fs/file.c | 16 +++-
> >>>fs/f2fs/gc.c   |  2 --
> >>>fs/f2fs/recovery.c |  4 
> >>>fs/f2fs/segment.c  |  2 --
> >>>7 files changed, 25 insertions(+), 59 deletions(-)
> >>>
> >>> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> >>> index b85820e..3335619 100644
> >>> --- a/fs/f2fs/checkpoint.c
> >>> +++ b/fs/f2fs/checkpoint.c
> >>> @@ -154,46 +154,43 @@ static bool __is_bitmap_valid(struct f2fs_sb_info 
> >>> *sbi, block_t blkaddr,
> >>> if (unlikely(f2fs_cp_error(sbi)))
> >>> return exist;
> >>> -   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> >>> -   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> >>> -blkaddr, exist);
> >>> -   set_sbi_flag(sbi, SBI_NEED_FSCK);
> >>> -   return exist;
> >>> -   }
> >>> -
> >>> -   if (!exist && type == DATA_GENERIC_ENHANCE) {
> >>> +   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> >>> +   (!exist && type == DATA_GENERIC_ENHANCE)) {
> >>> f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> >>>  blkaddr, exist);
> >>> set_sbi_flag(sbi, SBI_NEED_FSCK);
> >>> dump_stack();
> >>> }
> >>> +
> >>
> >> No need to add one blank line.
> >>
> >> Otherwise, it looks good to me.
> >>
> >> Reviewed-by: Chao Yu 
> >>
> >> Thanks,
> >>
> >>> return exist;
> >>>}
> >>>static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> >>> block_t blkaddr, int type)
> >>>{
> >>> +   bool valid = false;
> >>> +
> >>> switch (type) {
> >>> case META_NAT:
> >>> break;
> >>> case META_SIT:
> >>> if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> >>> -   return false;
> >>> +   goto err;
> >>> break;
>

[f2fs-dev] [PATCH v3 4/4] f2fs: stop checkpoint when get a out-of-bounds segment

2024-02-18 Thread Zhiguo Niu
There is low probability that an out-of-bounds segment will be got
on a small-capacity device. In order to prevent subsequent write requests
allocating block address from this invalid segment, which may cause
unexpected issue, stop checkpoint should be performed.

Also introduce a new stop cp reason:  STOP_CP_REASON_OUT_OF_RANGE.

Signed-off-by: Zhiguo Niu 
---
changes of v3: correct MACRO spelling and update based on the lastes code
---
---
 fs/f2fs/segment.c   | 7 ++-
 include/linux/f2fs_fs.h | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c25aaec..8f7ac49 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2665,7 +2665,12 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
if (secno >= MAIN_SECS(sbi)) {
secno = find_first_zero_bit(free_i->free_secmap,
MAIN_SECS(sbi));
-   f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi));
+   if (secno >= MAIN_SECS(sbi)) {
+   f2fs_stop_checkpoint(sbi, false,
+   STOP_CP_REASON_OUT_OF_RANGE);
+   f2fs_bug_on(sbi, 1);
+   }
+
}
segno = GET_SEG_FROM_SEC(sbi, secno);
zoneno = GET_ZONE_FROM_SEC(sbi, secno);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 9b69c50..56e260c 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -75,6 +75,7 @@ enum stop_cp_reason {
STOP_CP_REASON_CORRUPTED_SUMMARY,
STOP_CP_REASON_UPDATE_INODE,
STOP_CP_REASON_FLUSH_FAIL,
+   STOP_CP_REASON_OUT_OF_RANGE,
STOP_CP_REASON_MAX,
 };
 
-- 
1.9.1



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


[f2fs-dev] [PATCH v2 2/4] f2fs: fix panic issue in update_sit_entry

2024-02-06 Thread Zhiguo Niu
When CONFIG_F2FS_CHECK_FS is not enabled, f2fs_bug_on just printing
warning, get_new_segment may get an out-of-bounds segment when there
is no free segments. Then a block is allocated from this invalid
segment, update_sit_entry will access the invalid bitmap address,
cause system panic. Just as below call stack:

f2fs_allocate_data_block get a block address with 0x4000 and
partition size is 64MB

[   13.401997] Unable to handle kernel NULL pointer dereference at virtual 
address 
[   13.402003] Mem abort info:
[   13.402006]   ESR = 0x9605
[   13.402009]   EC = 0x25: DABT (current EL), IL = 32 bits
[   13.402015]   SET = 0, FnV = 0
[   13.402018]   EA = 0, S1PTW = 0
[   13.402021]   FSC = 0x05: level 1 translation fault
[   13.402025] Data abort info:
[   13.402027]   ISV = 0, ISS = 0x0005
[   13.402030]   CM = 0, WnR = 0
[   13.402034] user pgtable: 4k pages, 39-bit VAs, pgdp=0001066ab000
[   13.402038] [] pgd=, p4d=, 
pud=
[   13.402052] Internal error: Oops: 9605 [#1] PREEMPT SMP
[   13.489854] pc : update_sit_entry+0x128/0x420
[   13.490497] lr : f2fs_allocate_data_block+0x6b0/0xc2c
[   13.491218] sp : ffc00e023440
[   13.501530] Call trace:
[   13.501930]  update_sit_entry+0x128/0x420
[   13.502523]  f2fs_allocate_data_block+0x6b0/0xc2c
[   13.503203]  do_write_page+0xf0/0x1d4
[   13.503752]  f2fs_outplace_write_data+0x68/0xfc
[   13.504408]  f2fs_do_write_data_page+0x3a8/0x65c
[   13.505076]  move_data_page+0x294/0x7a8
[   13.505647]  gc_data_segment+0x4b8/0x800
[   13.506229]  do_garbage_collect+0x354/0x674
[   13.506843]  f2fs_gc+0x280/0x68c
[   13.507340]  f2fs_balance_fs+0x104/0x144
[   13.507921]  f2fs_create+0x310/0x3d8
[   13.508458]  path_openat+0x53c/0xc28
[   13.508997]  do_filp_open+0xbc/0x16c
[   13.509535]  do_sys_openat2+0xa0/0x2a0

So sanity check should be add in update_sit_entry.
Also remove some redundant judgment code.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index ad6511f..f373ff7 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2399,6 +2399,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, 
block_t blkaddr, int del)
 #endif
 
segno = GET_SEGNO(sbi, blkaddr);
+   if (segno == NULL_SEGNO)
+   return;
 
se = get_seg_entry(sbi, segno);
new_vblocks = se->valid_blocks + del;
@@ -3464,8 +3466,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, 
struct page *page,
 * since SSR needs latest valid block information.
 */
update_sit_entry(sbi, *new_blkaddr, 1);
-   if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
-   update_sit_entry(sbi, old_blkaddr, -1);
+   update_sit_entry(sbi, old_blkaddr, -1);
 
/*
 * If the current segment is full, flush it out and replace it with a
-- 
1.9.1



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


[f2fs-dev] [PATCH v2 1/4] f2fs: correct counting methods of free_segments in __set_inuse

2024-02-06 Thread Zhiguo Niu
There is a corner scenario on a small-capacity partition with 64MB size:
1. The main area has a total of 24 segments, and there are no free
segments left shown from the free_segmap bitmap and free_secmap in
free_segmap_info.
-
bitmap value: 
-
2. When doing gc, an out-of-bounds segment with segno=24 is allocated.
Because CONFIG_F2FS_CHECK_FS is not enabled, f2fs_bug_on in get_new_segment
just print warning log but the subsequent process continues to run.
-
got_it:
/* set it as dirty segment in free segmap */
f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap));
__set_inuse(sbi, segno);
--
3. __set_inuse directly sets free_i->free_segments--,
As a result, free_i->free_segments=-1, as shown in the following
coredump information:
--
  crash_arm64> struct free_segmap_info 0xff8084d9a000 -x
  struct free_segmap_info {
  start_segno = 0x7,
  free_segments = 0x,
  free_sections = 0x0,
--
This is unreasonable and will cause free_segments and free_sections
counts mismatch if there are segments released as free.

So same counting methods like free_sections should be used to
free_segments.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 8129be7..f2847f1 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -463,8 +463,8 @@ static inline void __set_inuse(struct f2fs_sb_info *sbi,
struct free_segmap_info *free_i = FREE_I(sbi);
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
 
-   set_bit(segno, free_i->free_segmap);
-   free_i->free_segments--;
+   if (!test_and_set_bit(segno, free_i->free_segmap))
+   free_i->free_segments--;
if (!test_and_set_bit(secno, free_i->free_secmap))
free_i->free_sections--;
 }
-- 
1.9.1



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


[f2fs-dev] [PATCH v2 3/4] f2fs: enhance judgment conditions of GET_SEGNO

2024-02-06 Thread Zhiguo Niu
NULL_SEGNO should also be returned when the blk_addr value is
out-of-bound main area even __is_valid_data_blkaddr return true.

For example, a 64MB partition with total 24 main segments has no
any free segments left, then a new wrtie request use get_new_segment
may get a out-of-bound segno 24 if CONFIG_F2FS_CHECK_FS is not enabled.
GET_SEGNO should also return NULL_SEGNO in this case rather than treating
is as valid segment.

Besides, if the caller of GET_SEGNO does not ensure blk_addr pass to
GET_SEGNO is valid, it should do sanity check about return value of
GET_SEGNO, avoid causing some unexpected problems later.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/file.c| 7 ++-
 fs/f2fs/segment.c | 4 +++-
 fs/f2fs/segment.h | 3 ++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 23cd6a1..2cd3cd9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2985,9 +2985,14 @@ static int f2fs_ioc_flush_device(struct file *filp, 
unsigned long arg)
if (ret)
return ret;
 
-   if (range.dev_num != 0)
+   if (range.dev_num != 0) {
dev_start_segno = GET_SEGNO(sbi, FDEV(range.dev_num).start_blk);
+   if (dev_start_segno == NULL_SEGNO)
+   return -EINVAL;
+   }
dev_end_segno = GET_SEGNO(sbi, FDEV(range.dev_num).end_blk);
+   if (dev_end_segno == NULL_SEGNO)
+   return -EINVAL;
 
start_segno = sm->last_victim[FLUSH_DEVICE];
if (start_segno < dev_start_segno || start_segno >= dev_end_segno)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index f373ff7..6772ad4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2496,7 +2496,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, 
block_t addr)
struct sit_info *sit_i = SIT_I(sbi);
 
f2fs_bug_on(sbi, addr == NULL_ADDR);
-   if (addr == NEW_ADDR || addr == COMPRESS_ADDR)
+   if (segno == NULL_SEGNO)
return;
 
f2fs_invalidate_internal_cache(sbi, addr);
@@ -3708,6 +3708,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, 
struct f2fs_summary *sum,
unsigned char old_alloc_type;
 
segno = GET_SEGNO(sbi, new_blkaddr);
+   if (segno == NULL_SEGNO)
+   return;
se = get_seg_entry(sbi, segno);
type = se->type;
 
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index f2847f1..b0ea315 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -96,7 +96,8 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info 
*sbi,
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1))
 
 #define GET_SEGNO(sbi, blk_addr)   \
-   ((!__is_valid_data_blkaddr(blk_addr)) ? \
+   ((!__is_valid_data_blkaddr(blk_addr) || \
+   !f2fs_is_valid_blkaddr(sbi, blk_addr, DATA_GENERIC)) ?  \
NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \
GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
 #define BLKS_PER_SEC(sbi)  \
-- 
1.9.1



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


[f2fs-dev] [PATCH v2 4/4] f2fs: stop checkpoint when get a out-of-bounds segment

2024-02-06 Thread Zhiguo Niu
There is low probability that an out-of-bounds segment will be got
on a small-capacity device. In order to prevent subsequent write requests
allocating block address from this invalid segment, which may cause
unexpected issue, stop checkpoint should be performed.

Also introduce a new stop cp reason:  STOP_CP_REASON_OUTOF_RAGNE.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.c   | 12 ++--
 include/linux/f2fs_fs.h |  1 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6772ad4..6fe2baf 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2666,7 +2666,11 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
if (dir == ALLOC_RIGHT) {
secno = find_first_zero_bit(free_i->free_secmap,
MAIN_SECS(sbi));
-   f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi));
+   if (secno >= MAIN_SECS(sbi)) {
+   f2fs_stop_checkpoint(sbi, false,
+   STOP_CP_REASON_OUTOF_RAGNE);
+   f2fs_bug_on(sbi, 1);
+   }
} else {
go_left = 1;
left_start = hint - 1;
@@ -2682,7 +2686,11 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
}
left_start = find_first_zero_bit(free_i->free_secmap,
MAIN_SECS(sbi));
-   f2fs_bug_on(sbi, left_start >= MAIN_SECS(sbi));
+   if (left_start >= MAIN_SECS(sbi)) {
+   f2fs_stop_checkpoint(sbi, false,
+   STOP_CP_REASON_OUTOF_RAGNE);
+   f2fs_bug_on(sbi, 1);
+   }
break;
}
secno = left_start;
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 053137a0..72c6782 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -81,6 +81,7 @@ enum stop_cp_reason {
STOP_CP_REASON_CORRUPTED_SUMMARY,
STOP_CP_REASON_UPDATE_INODE,
STOP_CP_REASON_FLUSH_FAIL,
+   STOP_CP_REASON_OUTOF_RAGNE,
STOP_CP_REASON_MAX,
 };
 
-- 
1.9.1



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


[f2fs-dev] [PATCH v2 0/4] f2fs: fix panic issue in small capacity device

2024-02-06 Thread Zhiguo Niu
A panic issue happened in a reboot test in small capacity device
as following:
1.The device size is 64MB, and main area has 24 segments, and
CONFIG_F2FS_CHECK_FS is not enabled.
2.There is no any free segments left shown in free_segmap_info,
then another write request cause get_new_segment get a out-of-bound
segment with segno 24.
3.panic happen in update_sit_entry because access invalid bitmap
pointer.

More detail shown in following patch sets.
The three patches are splited here because the modifications are
relatively independent and more readable.

---
Changes of v2: stop checkpoint when get a out-of-bound segment
---

Zhiguo Niu (4):
  f2fs: correct counting methods of free_segments in __set_inuse
  f2fs: fix panic issue in update_sit_entry
  f2fs: enhance judgment conditions of GET_SEGNO
  f2fs: stop checkpoint when get a out-of-bounds segment

 fs/f2fs/file.c  |  7 ++-
 fs/f2fs/segment.c   | 21 -
 fs/f2fs/segment.h   |  7 ---
 include/linux/f2fs_fs.h |  1 +
 4 files changed, 27 insertions(+), 9 deletions(-)

-- 
1.9.1



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


Re: [f2fs-dev] [PATCH v7] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-02-06 Thread Zhiguo Niu
On Tue, Feb 6, 2024 at 11:36 AM Chao Yu  wrote:
>
> On 2024/2/6 11:32, Jaegeuk Kim wrote:
> > On 02/05, Chao Yu wrote:
> >> On 2024/2/5 11:30, Zhiguo Niu wrote:
> >>> There are some cases of f2fs_is_valid_blkaddr not handled as
> >>> ERROR_INVALID_BLKADDR,so unify the error handling about all of
> >>> f2fs_is_valid_blkaddr.
> >>>
> >>> Signed-off-by: Zhiguo Niu 
> >>> Signed-off-by: Chao Yu 
> >>> ---
> >>> changes of v7: update patch according to sync with Chao
> >>> -restore some code to original
> >>> -modify err handle of __is_bitmap_valid for covering all cases
> >>> changes of v6: improve patch according to Chao's suggestions
> >>> -restore dump_stack to original position
> >>> -adjuest code sequence of __is_bitmap_check_valid
> >>> changes of v5: improve patch according to Jaegeuk's suggestiongs
> >>> -restore return value of some f2fs_is_valid_blkaddr error case to 
> >>> original
> >>> -move cp_err checking to outermost for unified processing
> >>> -return true directly for case (type=DATA_GENERIC_ENHANCE_READ) in
> >>>  __is_bitmap_valid to avoid meaningless flow
> >>> -rename __is_bitmap_valid to __is_bitmap_check_valid for avoiding 
> >>> ambiguity
> >>>  and handling its return value in the caller uniformly, also cooperate
> >>>  switch checking true to false for error case of
> >>>  f2fs_is_valid_blkaddr(type=DATA_GENERIC_ENHANCE_UPDATE) in 
> >>> do_recover_data
> >>>  for more readable
> >>> changes of v4: update according to the latest code
> >>> changes of v3:
> >>> -rebase patch to dev-test
> >>> -correct return value for some f2fs_is_valid_blkaddr error case
> >>> changes of v2: improve patch according Chao's suggestions.
> >>> ---
> >>> ---
> >>>fs/f2fs/checkpoint.c   | 33 ++---
> >>>fs/f2fs/data.c | 22 +++---
> >>>fs/f2fs/extent_cache.c |  5 +
> >>>fs/f2fs/file.c | 16 +++-
> >>>fs/f2fs/gc.c   |  2 --
> >>>fs/f2fs/recovery.c |  4 
> >>>fs/f2fs/segment.c  |  2 --
> >>>7 files changed, 25 insertions(+), 59 deletions(-)
> >>>
> >>> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> >>> index b85820e..3335619 100644
> >>> --- a/fs/f2fs/checkpoint.c
> >>> +++ b/fs/f2fs/checkpoint.c
> >>> @@ -154,46 +154,43 @@ static bool __is_bitmap_valid(struct f2fs_sb_info 
> >>> *sbi, block_t blkaddr,
> >>> if (unlikely(f2fs_cp_error(sbi)))
> >>> return exist;
> >>> -   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> >>> -   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> >>> -blkaddr, exist);
> >>> -   set_sbi_flag(sbi, SBI_NEED_FSCK);
> >>> -   return exist;
> >>> -   }
> >>> -
> >>> -   if (!exist && type == DATA_GENERIC_ENHANCE) {
> >>> +   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> >>> +   (!exist && type == DATA_GENERIC_ENHANCE)) {
> >>> f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> >>>  blkaddr, exist);
> >>> set_sbi_flag(sbi, SBI_NEED_FSCK);
> >>> dump_stack();
> >>> }
> >>> +
> >>
> >> No need to add one blank line.
> >>
> >> Otherwise, it looks good to me.
> >>
> >> Reviewed-by: Chao Yu 
> >>
> >> Thanks,
> >>
> >>> return exist;
> >>>}
> >>>static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> >>> block_t blkaddr, int type)
> >>>{
> >>> +   bool valid = false;
> >>> +
> >>> switch (type) {
> >>> case META_NAT:
> >>> break;
> >>> case META_SIT:
> >>> if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> >>> -   return false;
> >>> +   goto err;
> >>> break;
> >>> case ME

Re: [f2fs-dev] [PATCH 0/3] f2fs: fix panic issue in small capacity device

2024-02-05 Thread Zhiguo Niu
On Tue, Feb 6, 2024 at 11:15 AM Jaegeuk Kim  wrote:
>
> On 01/29, Zhiguo Niu wrote:
> > A panic issue happened in a reboot test in small capacity device
> > as following:
> > 1.The device size is 64MB, and main area has 24 segments, and
> > CONFIG_F2FS_CHECK_FS is not enabled.
> > 2.There is no any free segments left shown in free_segmap_info,
> > then another write request cause get_new_segment get a out-of-bound
> > segment with segno 24.
> > 3.panic happen in update_sit_entry because access invalid bitmap
> > pointer.
>
> The goal here is to stop f2fs when it hits no space to write anymore?
Do not let the system crash now , and add some sanity check to avoid
accessing  illegal memory
> And, we need f2fs_stop_checkpoint() at the end?
I think it need indeed.
thanks!
>
> >
> > More detail shown in following three patches.
> > The three patches are splited here because the modifications are
> > relatively independent and more readable.
> >
> > Zhiguo Niu (3):
> >   f2fs: correct counting methods of free_segments in __set_inuse
> >   f2fs: fix panic issue in update_sit_entry
> >   f2fs: enhance judgment conditions of GET_SEGNO
> >
> >  fs/f2fs/file.c| 7 ++-
> >  fs/f2fs/segment.c | 9 ++---
> >  fs/f2fs/segment.h | 7 ---
> >  3 files changed, 16 insertions(+), 7 deletions(-)
> >
> > --
> > 1.9.1


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


[f2fs-dev] [PATCH v7] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-02-04 Thread Zhiguo Niu
There are some cases of f2fs_is_valid_blkaddr not handled as
ERROR_INVALID_BLKADDR,so unify the error handling about all of
f2fs_is_valid_blkaddr.

Signed-off-by: Zhiguo Niu 
Signed-off-by: Chao Yu 
---
changes of v7: update patch according to sync with Chao
  -restore some code to original
  -modify err handle of __is_bitmap_valid for covering all cases
changes of v6: improve patch according to Chao's suggestions
  -restore dump_stack to original position
  -adjuest code sequence of __is_bitmap_check_valid
changes of v5: improve patch according to Jaegeuk's suggestiongs
  -restore return value of some f2fs_is_valid_blkaddr error case to original
  -move cp_err checking to outermost for unified processing
  -return true directly for case (type=DATA_GENERIC_ENHANCE_READ) in
   __is_bitmap_valid to avoid meaningless flow
  -rename __is_bitmap_valid to __is_bitmap_check_valid for avoiding ambiguity
   and handling its return value in the caller uniformly, also cooperate
   switch checking true to false for error case of
   f2fs_is_valid_blkaddr(type=DATA_GENERIC_ENHANCE_UPDATE) in do_recover_data
   for more readable
changes of v4: update according to the latest code
changes of v3:
  -rebase patch to dev-test
  -correct return value for some f2fs_is_valid_blkaddr error case
changes of v2: improve patch according Chao's suggestions.
---
---
 fs/f2fs/checkpoint.c   | 33 ++---
 fs/f2fs/data.c | 22 +++---
 fs/f2fs/extent_cache.c |  5 +
 fs/f2fs/file.c | 16 +++-
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/recovery.c |  4 
 fs/f2fs/segment.c  |  2 --
 7 files changed, 25 insertions(+), 59 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b85820e..3335619 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -154,46 +154,43 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
if (unlikely(f2fs_cp_error(sbi)))
return exist;
 
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
-
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE)) {
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
 blkaddr, exist);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
}
+
return exist;
 }
 
 static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type)
 {
+   bool valid = false;
+
switch (type) {
case META_NAT:
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -210,21 +207,27 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
  blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
-   return false;
+   goto err;
} else {
-   return __is_bitmap_valid(sbi, blkaddr, type);
+   valid = __is_bitmap_valid(sbi, blkaddr, type);
+   if ((!valid && type != DATA_GENERIC_ENHANCE_UPDATE) ||
+   (valid && type == DATA_GENERIC_ENHANCE_UPDATE))
+   goto err;
}
break;
case META_GENERIC:
if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
blkaddr >= MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
default:
BUG();
}
 
retur

[f2fs-dev] [PATCH v6] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-02-01 Thread Zhiguo Niu
There are some cases of f2fs_is_valid_blkaddr not handled as
ERROR_INVALID_BLKADDR,so unify the error handling about all of
f2fs_is_valid_blkaddr.

Signed-off-by: Zhiguo Niu 
---
changes of v6: improve patch according to Chao's suggestions
  -restore dump_stack to original position
  -adjuest code sequence of __is_bitmap_check_valid
changes of v5: improve patch according to Jaegeuk's suggestiongs
  -restore return value of some f2fs_is_valid_blkaddr error case to original
  -move cp_err checking to outermost for unified processing
  -return true directly for case (type=DATA_GENERIC_ENHANCE_READ) in
   __is_bitmap_valid to avoid meaningless flow
  -rename __is_bitmap_valid to __is_bitmap_check_valid for avoiding ambiguity
   and handling its return value in the caller uniformly, also cooperate
   switch checking true to false for error case of
   f2fs_is_valid_blkaddr(type=DATA_GENERIC_ENHANCE_UPDATE) in do_recover_data
   for more readable
changes of v4: update according to the latest code
changes of v3:
  -rebase patch to dev-test
  -correct return value for some f2fs_is_valid_blkaddr error case
changes of v2: improve patch according Chao's suggestions.
---
---
 fs/f2fs/checkpoint.c   | 50 +-
 fs/f2fs/data.c | 22 +++---
 fs/f2fs/extent_cache.c |  5 +
 fs/f2fs/file.c | 16 +++-
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/recovery.c |  6 +-
 fs/f2fs/segment.c  |  2 --
 7 files changed, 29 insertions(+), 74 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b85820e..3e79e84 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -134,14 +134,15 @@ struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, 
pgoff_t index)
return __get_meta_page(sbi, index, false);
 }
 
-static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+static bool __is_bitmap_check_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
int type)
 {
struct seg_entry *se;
unsigned int segno, offset;
bool exist;
 
-   if (type == DATA_GENERIC)
+   if (type == DATA_GENERIC ||
+   type == DATA_GENERIC_ENHANCE_READ)
return true;
 
segno = GET_SEGNO(sbi, blkaddr);
@@ -149,25 +150,15 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
se = get_seg_entry(sbi, segno);
 
exist = f2fs_test_bit(offset, se->cur_valid_map);
-
-   /* skip data, if we already have an error in checkpoint. */
-   if (unlikely(f2fs_cp_error(sbi)))
-   return exist;
-
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
-
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE)) {
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
 blkaddr, exist);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
+   return false;
}
-   return exist;
+   return true;
 }
 
 static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
@@ -178,53 +169,54 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
case DATA_GENERIC_ENHANCE_READ:
case DATA_GENERIC_ENHANCE_UPDATE:
+   /* Skip to emit an error message. */
+   if (unlikely(f2fs_cp_error(sbi)))
+   return false;
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi))) {
-
-

Re: [f2fs-dev] [PATCH v5] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-02-01 Thread Zhiguo Niu
On Thu, Feb 1, 2024 at 6:04 PM Chao Yu  wrote:
>
> On 2024/1/31 10:43, Zhiguo Niu wrote:
> > There are some cases of f2fs_is_valid_blkaddr not handled as
> > ERROR_INVALID_BLKADDR,so unify the error handling about all of
> > f2fs_is_valid_blkaddr.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> > changes of v2: improve patch according Chao's suggestions.
> > changes of v3:
> >-rebase patch to dev-test
> >-correct return value for some f2fs_is_valid_blkaddr error case
> > changes of v4: update according to the latest code
> > changes of v5: improve patch according Jaegeuk's suggestiongs
> >-restore return value of some f2fs_is_valid_blkaddr error case to 
> > original
> >-remove cp_err checking in __is_bitmap_valid becasue it has done in
> > if case
> >-return true directly for case (type=DATA_GENERIC_ENHANCE_READ) in
> > __is_bitmap_valid to avoid meaningless flow
> >-rename __is_bitmap_valid to __is_bitmap_check_valid for avoiding 
> > ambiguity
> > and handling its return value in the caller uniformly, also cooperate
> > switch checking true to false in do_recover_data for error case of
> > f2fs_is_valid_blkaddr(type=DATA_GENERIC_ENHANCE_UPDATE) for more 
> > readable
> > ---
> > ---
> >   fs/f2fs/checkpoint.c   | 53 
> > +++---
> >   fs/f2fs/data.c | 22 +++--
> >   fs/f2fs/extent_cache.c |  5 +
> >   fs/f2fs/file.c | 16 +++
> >   fs/f2fs/gc.c   |  2 --
> >   fs/f2fs/recovery.c |  6 +-
> >   fs/f2fs/segment.c  |  2 --
> >   7 files changed, 32 insertions(+), 74 deletions(-)
> >
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index b85820e..e90fa46 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -134,14 +134,15 @@ struct page *f2fs_get_tmp_page(struct f2fs_sb_info 
> > *sbi, pgoff_t index)
> >   return __get_meta_page(sbi, index, false);
> >   }
> >
> > -static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
> > +static bool __is_bitmap_check_valid(struct f2fs_sb_info *sbi, block_t 
> > blkaddr,
> >   int type)
> >   {
> >   struct seg_entry *se;
> >   unsigned int segno, offset;
> >   bool exist;
> >
> > - if (type == DATA_GENERIC)
> > + if (type == DATA_GENERIC ||
> > + type == DATA_GENERIC_ENHANCE_READ)
> >   return true;
> >
> >   segno = GET_SEGNO(sbi, blkaddr);
> > @@ -149,25 +150,16 @@ static bool __is_bitmap_valid(struct f2fs_sb_info 
> > *sbi, block_t blkaddr,
> >   se = get_seg_entry(sbi, segno);
> >
> >   exist = f2fs_test_bit(offset, se->cur_valid_map);
> > + if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> > + (!exist && type == DATA_GENERIC_ENHANCE))
> > + goto err;
> >
> > - /* skip data, if we already have an error in checkpoint. */
> > - if (unlikely(f2fs_cp_error(sbi)))
> > - return exist;
> > -
> > - if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > -  blkaddr, exist);
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > - return exist;
> > - }
> > -
> > - if (!exist && type == DATA_GENERIC_ENHANCE) {
> > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > -  blkaddr, exist);
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > - dump_stack();
> > - }
> > - return exist;
> > + return true;
> > +err:
> > + f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > + blkaddr, exist);
> > + set_sbi_flag(sbi, SBI_NEED_FSCK);
> > + return false;
>
> if (unlikely((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> (!exist && type == DATA_GENERIC_ENHANCE))) {
> f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> blkaddr, exist);
> set_sbi_flag(sbi, SBI_NEED_FSCK);
> dump_stack();
> return false;
> }
> return exist;
>
> >   }
> >
> >   st

[f2fs-dev] [PATCH v5] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-01-30 Thread Zhiguo Niu
There are some cases of f2fs_is_valid_blkaddr not handled as
ERROR_INVALID_BLKADDR,so unify the error handling about all of
f2fs_is_valid_blkaddr.

Signed-off-by: Zhiguo Niu 
---
changes of v2: improve patch according Chao's suggestions.
changes of v3:
  -rebase patch to dev-test
  -correct return value for some f2fs_is_valid_blkaddr error case
changes of v4: update according to the latest code
changes of v5: improve patch according Jaegeuk's suggestiongs
  -restore return value of some f2fs_is_valid_blkaddr error case to original
  -remove cp_err checking in __is_bitmap_valid becasue it has done in
   if case
  -return true directly for case (type=DATA_GENERIC_ENHANCE_READ) in
   __is_bitmap_valid to avoid meaningless flow
  -rename __is_bitmap_valid to __is_bitmap_check_valid for avoiding ambiguity
   and handling its return value in the caller uniformly, also cooperate
   switch checking true to false in do_recover_data for error case of
   f2fs_is_valid_blkaddr(type=DATA_GENERIC_ENHANCE_UPDATE) for more readable
---
---
 fs/f2fs/checkpoint.c   | 53 +++---
 fs/f2fs/data.c | 22 +++--
 fs/f2fs/extent_cache.c |  5 +
 fs/f2fs/file.c | 16 +++
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/recovery.c |  6 +-
 fs/f2fs/segment.c  |  2 --
 7 files changed, 32 insertions(+), 74 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b85820e..e90fa46 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -134,14 +134,15 @@ struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, 
pgoff_t index)
return __get_meta_page(sbi, index, false);
 }
 
-static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+static bool __is_bitmap_check_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
int type)
 {
struct seg_entry *se;
unsigned int segno, offset;
bool exist;
 
-   if (type == DATA_GENERIC)
+   if (type == DATA_GENERIC ||
+   type == DATA_GENERIC_ENHANCE_READ)
return true;
 
segno = GET_SEGNO(sbi, blkaddr);
@@ -149,25 +150,16 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
se = get_seg_entry(sbi, segno);
 
exist = f2fs_test_bit(offset, se->cur_valid_map);
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE))
+   goto err;
 
-   /* skip data, if we already have an error in checkpoint. */
-   if (unlikely(f2fs_cp_error(sbi)))
-   return exist;
-
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
-
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   dump_stack();
-   }
-   return exist;
+   return true;
+err:
+   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+   blkaddr, exist);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   return false;
 }
 
 static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
@@ -178,22 +170,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -209,22 +201,25 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
f2fs_warn(sbi, "access invalid blkaddr:%u",
  blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
-   dump_stack();
-   retu

Re: [f2fs-dev] [PATCH v4] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-01-29 Thread Zhiguo Niu
On Tue, Jan 30, 2024 at 8:46 AM Zhiguo Niu  wrote:
>
> Hi Jaegeuk,
> Thanks for your suggestion,the following is my comment.
>
> On Tue, Jan 30, 2024 at 3:53 AM Jaegeuk Kim  wrote:
> >
> > On 01/23, Zhiguo Niu wrote:
> > > There are some cases of f2fs_is_valid_blkaddr not handled as
> > > ERROR_INVALID_BLKADDR,so unify the error handling about all of
> > > f2fs_is_valid_blkaddr.
> > >
> > > Signed-off-by: Zhiguo Niu 
> > > ---
> > > changes of v2: improve patch according Chao's suggestions.
> > > changes of v3:
> > >   -rebase patch to dev-test
> > >   -correct return value for some f2fs_is_valid_blkaddr error case
> > > changes of v4: update according to the latest code
> > > ---
> > > ---
> > >  fs/f2fs/checkpoint.c   | 37 +++--
> > >  fs/f2fs/data.c | 24 
> > >  fs/f2fs/extent_cache.c |  7 ++-
> > >  fs/f2fs/file.c | 16 +++-
> > >  fs/f2fs/gc.c   |  2 --
> > >  fs/f2fs/node.c |  2 +-
> > >  fs/f2fs/recovery.c |  4 
> > >  fs/f2fs/segment.c  |  2 --
> > >  8 files changed, 29 insertions(+), 65 deletions(-)
> > >
> > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > > index b85820e..b9bafd7 100644
> > > --- a/fs/f2fs/checkpoint.c
> > > +++ b/fs/f2fs/checkpoint.c
> > > @@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info 
> > > *sbi, block_t blkaddr,
> > >   if (unlikely(f2fs_cp_error(sbi)))
> > >   return exist;
> > > - if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> > > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit 
> > > bitmap:%d",
> > > -  blkaddr, exist);
> > > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > > - return exist;
> > > - }
> > > + if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> > > + (!exist && type == DATA_GENERIC_ENHANCE))
> > > + goto err;
> >
> > if (unlikely((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> > (!exist && type == DATA_GENERIC_ENHANCE))) {
> > f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit 
> > bitmap:%d",
> > blkaddr, exist);
> > set_sbi_flag(sbi, SBI_NEED_FSCK);
> > dump_stack();
> >
> > f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >  ^-- remove and done by caller below.
>
> The original logic of __is_bitmap_valid is to return the result
> directly , so f2fs_handle_error in
> its caller(__f2fs_is_valid_blkaddr) cannot be executed.
>
> > }
> > return exist;
> >
> > >
> > > - if (!exist && type == DATA_GENERIC_ENHANCE) {
> > > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit 
> > > bitmap:%d",
> > > -  blkaddr, exist);
> > > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > > - dump_stack();
> > > - }
> > > + return exist;
> > > +err:
> > > + f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > > + blkaddr, exist);
> > > + set_sbi_flag(sbi, SBI_NEED_FSCK);
> > > + dump_stack();
> > > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> > >   return exist;
> > >  }
> > >
> > > @@ -178,22 +176,22 @@ static bool __f2fs_is_valid_blkaddr(struct 
> > > f2fs_sb_info *sbi,
> > >   break;
> > >   case META_SIT:
> > >   if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> > > - return false;
> > > + goto err;
> > >   break;
> > >   case META_SSA:
> > >   if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
> > >   blkaddr < SM_I(sbi)->ssa_blkaddr))
> > > - return false;
> > > + goto err;
> > >   break;
> > >   case META_CP:
> > >   if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
> > >   blkaddr < __start_cp_addr(sbi))

Re: [f2fs-dev] [PATCH v4] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-01-29 Thread Zhiguo Niu
Hi Jaegeuk,
Thanks for your suggestion,the following is my comment.

On Tue, Jan 30, 2024 at 3:53 AM Jaegeuk Kim  wrote:
>
> On 01/23, Zhiguo Niu wrote:
> > There are some cases of f2fs_is_valid_blkaddr not handled as
> > ERROR_INVALID_BLKADDR,so unify the error handling about all of
> > f2fs_is_valid_blkaddr.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> > changes of v2: improve patch according Chao's suggestions.
> > changes of v3:
> >   -rebase patch to dev-test
> >   -correct return value for some f2fs_is_valid_blkaddr error case
> > changes of v4: update according to the latest code
> > ---
> > ---
> >  fs/f2fs/checkpoint.c   | 37 +++--
> >  fs/f2fs/data.c | 24 
> >  fs/f2fs/extent_cache.c |  7 ++-
> >  fs/f2fs/file.c | 16 +++-
> >  fs/f2fs/gc.c   |  2 --
> >  fs/f2fs/node.c |  2 +-
> >  fs/f2fs/recovery.c |  4 
> >  fs/f2fs/segment.c  |  2 --
> >  8 files changed, 29 insertions(+), 65 deletions(-)
> >
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index b85820e..b9bafd7 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info 
> > *sbi, block_t blkaddr,
> >   if (unlikely(f2fs_cp_error(sbi)))
> >   return exist;
> > - if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > -  blkaddr, exist);
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > - return exist;
> > - }
> > + if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> > + (!exist && type == DATA_GENERIC_ENHANCE))
> > + goto err;
>
> if (unlikely((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> (!exist && type == DATA_GENERIC_ENHANCE))) {
> f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> blkaddr, exist);
> set_sbi_flag(sbi, SBI_NEED_FSCK);
> dump_stack();
>
> f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
>  ^-- remove and done by caller below.

The original logic of __is_bitmap_valid is to return the result
directly , so f2fs_handle_error in
its caller(__f2fs_is_valid_blkaddr) cannot be executed.

> }
> return exist;
>
> >
> > - if (!exist && type == DATA_GENERIC_ENHANCE) {
> > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > -  blkaddr, exist);
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > - dump_stack();
> > - }
> > + return exist;
> > +err:
> > + f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > + blkaddr, exist);
> > + set_sbi_flag(sbi, SBI_NEED_FSCK);
> > + dump_stack();
> > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >   return exist;
> >  }
> >
> > @@ -178,22 +176,22 @@ static bool __f2fs_is_valid_blkaddr(struct 
> > f2fs_sb_info *sbi,
> >   break;
> >   case META_SIT:
> >   if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> > - return false;
> > + goto err;
> >   break;
> >   case META_SSA:
> >   if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
> >   blkaddr < SM_I(sbi)->ssa_blkaddr))
> > - return false;
> > + goto err;
> >   break;
> >   case META_CP:
> >   if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
> >   blkaddr < __start_cp_addr(sbi)))
> > - return false;
> > + goto err;
> >   break;
> >   case META_POR:
> >   if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
> >   blkaddr < MAIN_BLKADDR(sbi)))
> > - return false;
> > + goto err;
> >   break;
> >   case DATA_GENERIC:
> >   case DATA_GENERIC_ENHANCE:
> > @@ -210,7 +208,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
> > *s

[f2fs-dev] [PATCH 1/3] f2fs: correct counting methods of free_segments in __set_inuse

2024-01-29 Thread Zhiguo Niu
There is a corner scenario on a small-capacity partition with 64MB size:
1. The main area has a total of 24 segments, and there are no free
segments left shown from the free_segmap bitmap and free_secmap in
free_segmap_info.
-
bitmap value: 
-
2. When doing gc, an out-of-bounds segment with segno=24 is allocated.
Because CONFIG_F2FS_CHECK_FS is not enabled, f2fs_bug_on in get_new_segment
just print warning log but the subsequent process continues to run.
-
got_it:
/* set it as dirty segment in free segmap */
f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap));
__set_inuse(sbi, segno);
--
3. __set_inuse directly sets free_i->free_segments--,
As a result, free_i->free_segments=-1, as shown in the following
coredump information:
--
  crash_arm64> struct free_segmap_info 0xff8084d9a000 -x
  struct free_segmap_info {
  start_segno = 0x7,
  free_segments = 0x,
  free_sections = 0x0,
--
This is unreasonable and will cause free_segments and free_sections
counts mismatch if there are segments released as free.

So same counting methods like free_sections should be used to
free_segments.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 8129be7..f2847f1 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -463,8 +463,8 @@ static inline void __set_inuse(struct f2fs_sb_info *sbi,
struct free_segmap_info *free_i = FREE_I(sbi);
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
 
-   set_bit(segno, free_i->free_segmap);
-   free_i->free_segments--;
+   if (!test_and_set_bit(segno, free_i->free_segmap))
+   free_i->free_segments--;
if (!test_and_set_bit(secno, free_i->free_secmap))
free_i->free_sections--;
 }
-- 
1.9.1



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


[f2fs-dev] [PATCH 3/3] f2fs: enhance judgment conditions of GET_SEGNO

2024-01-29 Thread Zhiguo Niu
NULL_SEGNO should also be returned when the blk_addr value is
out-of-bound main area even __is_valid_data_blkaddr return true.

For example, a 64MB partition with total 24 main segments has no
any free segments left, then a new wrtie request use get_new_segment
may get a out-of-bound segno 24 if CONFIG_F2FS_CHECK_FS is not enabled.
GET_SEGNO should also return NULL_SEGNO in this case rather than treating
is as valid segment.

Besides, if the caller of GET_SEGNO does not ensure blk_addr pass to
GET_SEGNO is valid, it should do sanity check about return value of
GET_SEGNO, avoid causing some unexpected problems later.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/file.c| 7 ++-
 fs/f2fs/segment.c | 4 +++-
 fs/f2fs/segment.h | 3 ++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 23cd6a1..2cd3cd9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2985,9 +2985,14 @@ static int f2fs_ioc_flush_device(struct file *filp, 
unsigned long arg)
if (ret)
return ret;
 
-   if (range.dev_num != 0)
+   if (range.dev_num != 0) {
dev_start_segno = GET_SEGNO(sbi, FDEV(range.dev_num).start_blk);
+   if (dev_start_segno == NULL_SEGNO)
+   return -EINVAL;
+   }
dev_end_segno = GET_SEGNO(sbi, FDEV(range.dev_num).end_blk);
+   if (dev_end_segno == NULL_SEGNO)
+   return -EINVAL;
 
start_segno = sm->last_victim[FLUSH_DEVICE];
if (start_segno < dev_start_segno || start_segno >= dev_end_segno)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index f373ff7..6772ad4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2496,7 +2496,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, 
block_t addr)
struct sit_info *sit_i = SIT_I(sbi);
 
f2fs_bug_on(sbi, addr == NULL_ADDR);
-   if (addr == NEW_ADDR || addr == COMPRESS_ADDR)
+   if (segno == NULL_SEGNO)
return;
 
f2fs_invalidate_internal_cache(sbi, addr);
@@ -3708,6 +3708,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, 
struct f2fs_summary *sum,
unsigned char old_alloc_type;
 
segno = GET_SEGNO(sbi, new_blkaddr);
+   if (segno == NULL_SEGNO)
+   return;
se = get_seg_entry(sbi, segno);
type = se->type;
 
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index f2847f1..b0ea315 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -96,7 +96,8 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info 
*sbi,
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1))
 
 #define GET_SEGNO(sbi, blk_addr)   \
-   ((!__is_valid_data_blkaddr(blk_addr)) ? \
+   ((!__is_valid_data_blkaddr(blk_addr) || \
+   !f2fs_is_valid_blkaddr(sbi, blk_addr, DATA_GENERIC)) ?  \
NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \
GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
 #define BLKS_PER_SEC(sbi)  \
-- 
1.9.1



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


[f2fs-dev] [PATCH 2/3] f2fs: fix panic issue in update_sit_entry

2024-01-29 Thread Zhiguo Niu
When CONFIG_F2FS_CHECK_FS is not enabled, f2fs_bug_on just printing
warning, get_new_segment may get an out-of-bounds segment when there
is no free segments. Then a block is allocated from this invalid
segment, update_sit_entry will access the invalid bitmap address,
cause system panic. Just as below call stack:

f2fs_allocate_data_block get a block address with 0x4000 and
partition size is 64MB

[   13.401997] Unable to handle kernel NULL pointer dereference at virtual 
address 
[   13.402003] Mem abort info:
[   13.402006]   ESR = 0x9605
[   13.402009]   EC = 0x25: DABT (current EL), IL = 32 bits
[   13.402015]   SET = 0, FnV = 0
[   13.402018]   EA = 0, S1PTW = 0
[   13.402021]   FSC = 0x05: level 1 translation fault
[   13.402025] Data abort info:
[   13.402027]   ISV = 0, ISS = 0x0005
[   13.402030]   CM = 0, WnR = 0
[   13.402034] user pgtable: 4k pages, 39-bit VAs, pgdp=0001066ab000
[   13.402038] [] pgd=, p4d=, 
pud=
[   13.402052] Internal error: Oops: 9605 [#1] PREEMPT SMP
[   13.489854] pc : update_sit_entry+0x128/0x420
[   13.490497] lr : f2fs_allocate_data_block+0x6b0/0xc2c
[   13.491218] sp : ffc00e023440
[   13.501530] Call trace:
[   13.501930]  update_sit_entry+0x128/0x420
[   13.502523]  f2fs_allocate_data_block+0x6b0/0xc2c
[   13.503203]  do_write_page+0xf0/0x1d4
[   13.503752]  f2fs_outplace_write_data+0x68/0xfc
[   13.504408]  f2fs_do_write_data_page+0x3a8/0x65c
[   13.505076]  move_data_page+0x294/0x7a8
[   13.505647]  gc_data_segment+0x4b8/0x800
[   13.506229]  do_garbage_collect+0x354/0x674
[   13.506843]  f2fs_gc+0x280/0x68c
[   13.507340]  f2fs_balance_fs+0x104/0x144
[   13.507921]  f2fs_create+0x310/0x3d8
[   13.508458]  path_openat+0x53c/0xc28
[   13.508997]  do_filp_open+0xbc/0x16c
[   13.509535]  do_sys_openat2+0xa0/0x2a0

So sanity check should be add in update_sit_entry.
Also remove some redundant judgment code.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/segment.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index ad6511f..f373ff7 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2399,6 +2399,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, 
block_t blkaddr, int del)
 #endif
 
segno = GET_SEGNO(sbi, blkaddr);
+   if (segno == NULL_SEGNO)
+   return;
 
se = get_seg_entry(sbi, segno);
new_vblocks = se->valid_blocks + del;
@@ -3464,8 +3466,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, 
struct page *page,
 * since SSR needs latest valid block information.
 */
update_sit_entry(sbi, *new_blkaddr, 1);
-   if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
-   update_sit_entry(sbi, old_blkaddr, -1);
+   update_sit_entry(sbi, old_blkaddr, -1);
 
/*
 * If the current segment is full, flush it out and replace it with a
-- 
1.9.1



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


[f2fs-dev] [PATCH 0/3] f2fs: fix panic issue in small capacity device

2024-01-29 Thread Zhiguo Niu
A panic issue happened in a reboot test in small capacity device
as following:
1.The device size is 64MB, and main area has 24 segments, and
CONFIG_F2FS_CHECK_FS is not enabled.
2.There is no any free segments left shown in free_segmap_info,
then another write request cause get_new_segment get a out-of-bound
segment with segno 24.
3.panic happen in update_sit_entry because access invalid bitmap
pointer.

More detail shown in following three patches.
The three patches are splited here because the modifications are
relatively independent and more readable.

Zhiguo Niu (3):
  f2fs: correct counting methods of free_segments in __set_inuse
  f2fs: fix panic issue in update_sit_entry
  f2fs: enhance judgment conditions of GET_SEGNO

 fs/f2fs/file.c| 7 ++-
 fs/f2fs/segment.c | 9 ++---
 fs/f2fs/segment.h | 7 ---
 3 files changed, 16 insertions(+), 7 deletions(-)

-- 
1.9.1



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


Re: [f2fs-dev] [PATCH V1] f2fs: fix potentail deadloop issue in do_recover_data

2024-01-24 Thread Zhiguo Niu
Hi Chao,

On Wed, Jan 24, 2024 at 10:54 PM Chao Yu  wrote:
>
> Zhiguo,
>m
> Can you please check below version? Is it fine to you?
>
> https://lore.kernel.org/linux-f2fs-devel/20240124144915.19445-1-c...@kernel.org
it is ok to me and more reasonable than my  version
thanks~
>
> On 2024/1/22 13:46, Zhiguo Niu wrote:
> > Hi Chao
> >
> > On Mon, Jan 22, 2024 at 11:46 AM Chao Yu  wrote:
> >>
> >> On 2023/12/25 19:11, Zhiguo Niu wrote:
> >>> There is a potentail deadloop issue in the corner case of
> >>> CONFIG_F2FS_FAULT_INJECTION is enabled and the return value
> >>> of f2fs_reserve_new_block is error but not -ENOSPC, such as
> >>> this error case:
> >>> if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
> >>>return -EPERM;
> >>
> >> I don't see any path to trigger this error? am I missing something?
> >>
> >>> besides, the mainly error -ENOSPC has been handled as bug on,
> >>> so other error cases can be proecssed normally without looping.
> >>
> >> commit 975756c41332bc5e523e9f843271ed5ab6aa
> >> Author: Jaegeuk Kim 
> >> Date:   Thu May 19 11:57:21 2016 -0700
> >>
> >>   f2fs: avoid ENOSPC fault in the recovery process
> >>
> >>   This patch avoids impossible error injection, ENOSPC, during 
> >> recovery process.
> >>
> >> Please check above patch, I guess intention of adding such loop is
> >> to avoid mount failure due to fault injection was triggered in
> >> f2fs_reserve_new_block().
> >>
> >> What about change as blew?
> >> - keep the loop to avoid mount failure.
> >> - remove bug_on() to avoid panic due to fault injection error.
> >>
> >> #define DEFAULT_RETRY_COUNT 8
> >>
> >>  for (loops = DEFAULT_RETRY_COUNT; loops > 0; loops--) {
> >>  err = f2fs_reserve_new_block();
> >>  if (!err ||
> >>  !IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION))
> >>  break;
> >>  }
> >
> > Thanks for your detailed explanation and I understand.
> > It seems that the original process is also reasonable,
> > so it’s okay to keep it as it is.
> >>
> >> Thanks,
> >>
> >>>
> >>> Fixes: 956fa1ddc132 ("f2fs: fix to check return value of 
> >>> f2fs_reserve_new_block()")
> >>> Signed-off-by: Zhiguo Niu 
> >>> ---
> >>>fs/f2fs/recovery.c | 26 --
> >>>1 file changed, 8 insertions(+), 18 deletions(-)
> >>>
> >>> diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
> >>> index 21381b7..5d658f6 100644
> >>> --- a/fs/f2fs/recovery.c
> >>> +++ b/fs/f2fs/recovery.c
> >>> @@ -710,15 +710,10 @@ static int do_recover_data(struct f2fs_sb_info 
> >>> *sbi, struct inode *inode,
> >>> */
> >>>if (dest == NEW_ADDR) {
> >>>f2fs_truncate_data_blocks_range(, 1);
> >>> - do {
> >>> - err = f2fs_reserve_new_block();
> >>> - if (err == -ENOSPC) {
> >>> - f2fs_bug_on(sbi, 1);
> >>> - break;
> >>> - }
> >>> - } while (err &&
> >>> - IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
> >>> - if (err)
> >>> + err = f2fs_reserve_new_block();
> >>> + if (err == -ENOSPC)
> >>> + f2fs_bug_on(sbi, 1);
> >>> + else if (err)
> >>>goto err;
> >>>continue;
> >>>}
> >>> @@ -727,15 +722,10 @@ static int do_recover_data(struct f2fs_sb_info 
> >>> *sbi, struct inode *inode,
> >>>if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
> >>>
> >>>if (src == NULL_ADDR) {
> >>> - do {
> >>> - err = f2fs_reserve_new_block();
> >>> - if (err == -ENOSPC) {
> >>> - f2fs_bug_on(sbi, 1);
> >>> - break;
> >>> - }
> >>> - } while (err &&
> >>> - 
> >>> IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
> >>> - if (err)
> >>> + err = f2fs_reserve_new_block();
> >>> + if (err == -ENOSPC)
> >>> + f2fs_bug_on(sbi, 1);
> >>> + else if (err)
> >>>goto err;
> >>>}
> >>>retry_prev:


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


[f2fs-dev] [PATCH v4] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2024-01-23 Thread Zhiguo Niu
There are some cases of f2fs_is_valid_blkaddr not handled as
ERROR_INVALID_BLKADDR,so unify the error handling about all of
f2fs_is_valid_blkaddr.

Signed-off-by: Zhiguo Niu 
---
changes of v2: improve patch according Chao's suggestions.
changes of v3:
-rebase patch to dev-test
-correct return value for some f2fs_is_valid_blkaddr error case
changes of v4: update according to the latest code
---
---
 fs/f2fs/checkpoint.c   | 37 +++--
 fs/f2fs/data.c | 24 
 fs/f2fs/extent_cache.c |  7 ++-
 fs/f2fs/file.c | 16 +++-
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/node.c |  2 +-
 fs/f2fs/recovery.c |  4 
 fs/f2fs/segment.c  |  2 --
 8 files changed, 29 insertions(+), 65 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b85820e..b9bafd7 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
if (unlikely(f2fs_cp_error(sbi)))
return exist;
 
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE))
+   goto err;
 
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   dump_stack();
-   }
+   return exist;
+err:
+   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+   blkaddr, exist);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   dump_stack();
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
return exist;
 }
 
@@ -178,22 +176,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -210,7 +208,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
  blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
-   return false;
+   goto err;
} else {
return __is_bitmap_valid(sbi, blkaddr, type);
}
@@ -218,13 +216,16 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
case META_GENERIC:
if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
blkaddr >= MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
default:
BUG();
}
 
return true;
+err:
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+   return false;
 }
 
 bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 65fe48b..0f9a657 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -738,10 +738,8 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
 
if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
fio->is_por ? META_POR : (__is_meta_io(fio) ?
-   META_GENERIC : DATA_GENERIC_ENHANCE))) {
-   f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR);
+   META_GENERIC : DATA_GENERIC_ENHANCE)))
return -EFSCORRUPTED;
-   }
 
trace_f2fs_submit_page_bio(page, fio);
 
@@ -946,10 +944,8 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
fio->encrypted_page : fio->page;
 
if (!f2fs_is_

Re: [f2fs-dev] [PATCH V1] f2fs: fix potentail deadloop issue in do_recover_data

2024-01-21 Thread Zhiguo Niu
Hi Chao

On Mon, Jan 22, 2024 at 11:46 AM Chao Yu  wrote:
>
> On 2023/12/25 19:11, Zhiguo Niu wrote:
> > There is a potentail deadloop issue in the corner case of
> > CONFIG_F2FS_FAULT_INJECTION is enabled and the return value
> > of f2fs_reserve_new_block is error but not -ENOSPC, such as
> > this error case:
> > if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
> >   return -EPERM;
>
> I don't see any path to trigger this error? am I missing something?
>
> > besides, the mainly error -ENOSPC has been handled as bug on,
> > so other error cases can be proecssed normally without looping.
>
> commit 975756c41332bc5e523e9f843271ed5ab6aa
> Author: Jaegeuk Kim 
> Date:   Thu May 19 11:57:21 2016 -0700
>
>  f2fs: avoid ENOSPC fault in the recovery process
>
>  This patch avoids impossible error injection, ENOSPC, during recovery 
> process.
>
> Please check above patch, I guess intention of adding such loop is
> to avoid mount failure due to fault injection was triggered in
> f2fs_reserve_new_block().
>
> What about change as blew?
> - keep the loop to avoid mount failure.
> - remove bug_on() to avoid panic due to fault injection error.
>
> #define DEFAULT_RETRY_COUNT 8
>
> for (loops = DEFAULT_RETRY_COUNT; loops > 0; loops--) {
> err = f2fs_reserve_new_block();
> if (!err ||
> !IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION))
> break;
> }

Thanks for your detailed explanation and I understand.
It seems that the original process is also reasonable,
so it’s okay to keep it as it is.
>
> Thanks,
>
> >
> > Fixes: 956fa1ddc132 ("f2fs: fix to check return value of 
> > f2fs_reserve_new_block()")
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/recovery.c | 26 --
> >   1 file changed, 8 insertions(+), 18 deletions(-)
> >
> > diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
> > index 21381b7..5d658f6 100644
> > --- a/fs/f2fs/recovery.c
> > +++ b/fs/f2fs/recovery.c
> > @@ -710,15 +710,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, 
> > struct inode *inode,
> >*/
> >   if (dest == NEW_ADDR) {
> >   f2fs_truncate_data_blocks_range(, 1);
> > - do {
> > - err = f2fs_reserve_new_block();
> > - if (err == -ENOSPC) {
> > - f2fs_bug_on(sbi, 1);
> > - break;
> > - }
> > - } while (err &&
> > - IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
> > - if (err)
> > + err = f2fs_reserve_new_block();
> > + if (err == -ENOSPC)
> > + f2fs_bug_on(sbi, 1);
> > + else if (err)
> >   goto err;
> >   continue;
> >   }
> > @@ -727,15 +722,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, 
> > struct inode *inode,
> >   if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
> >
> >   if (src == NULL_ADDR) {
> > - do {
> > - err = f2fs_reserve_new_block();
> > - if (err == -ENOSPC) {
> > - f2fs_bug_on(sbi, 1);
> > - break;
> > - }
> > - } while (err &&
> > - 
> > IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
> > - if (err)
> > + err = f2fs_reserve_new_block();
> > + if (err == -ENOSPC)
> > + f2fs_bug_on(sbi, 1);
> > + else if (err)
> >   goto err;
> >   }
> >   retry_prev:


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


[f2fs-dev] [PATCH] f2fs: compress: remove some redundant codes in f2fs_cache_compressed_page

2024-01-17 Thread Zhiguo Niu
Just remove some redundant codes, no logic change.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/compress.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index ff26b49..624212d 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1889,12 +1889,8 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
*sbi, struct page *page,
 
set_page_private_data(cpage, ino);
 
-   if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ))
-   goto out;
-
memcpy(page_address(cpage), page_address(page), PAGE_SIZE);
SetPageUptodate(cpage);
-out:
f2fs_put_page(cpage, 1);
 }
 
-- 
1.9.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: use IS_INODE replace IS_DNODE in f2fs_flush_inline_data

2024-01-17 Thread Zhiguo Niu
Now IS_DNODE is used in f2fs_flush_inline_data and it has some problems:
1. Just only inodes may include inline data,not all direct nodes
2. When system IO is busy, it is inefficient to lock a direct node page
but not an inode page. Besides, if this direct node page is being
locked by others for IO, f2fs_flush_inline_data will be blocked here,
which will affects the checkpoint process, this is unreasonable.

So IS_INODE should be used in f2fs_flush_inline_data.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/node.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 541c4ad..a8fe49a3 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1919,7 +1919,7 @@ void f2fs_flush_inline_data(struct f2fs_sb_info *sbi)
for (i = 0; i < nr_folios; i++) {
struct page *page = [i]->page;
 
-   if (!IS_DNODE(page))
+   if (!IS_INODE(page))
continue;
 
lock_page(page);
-- 
1.9.1



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


[f2fs-dev] [PATCH V1] f2fs: fix potentail deadloop issue in do_recover_data

2023-12-25 Thread Zhiguo Niu
There is a potentail deadloop issue in the corner case of
CONFIG_F2FS_FAULT_INJECTION is enabled and the return value
of f2fs_reserve_new_block is error but not -ENOSPC, such as
this error case:
if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
return -EPERM;
besides, the mainly error -ENOSPC has been handled as bug on,
so other error cases can be proecssed normally without looping.

Fixes: 956fa1ddc132 ("f2fs: fix to check return value of 
f2fs_reserve_new_block()")
Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/recovery.c | 26 --
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 21381b7..5d658f6 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -710,15 +710,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, 
struct inode *inode,
 */
if (dest == NEW_ADDR) {
f2fs_truncate_data_blocks_range(, 1);
-   do {
-   err = f2fs_reserve_new_block();
-   if (err == -ENOSPC) {
-   f2fs_bug_on(sbi, 1);
-   break;
-   }
-   } while (err &&
-   IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
-   if (err)
+   err = f2fs_reserve_new_block();
+   if (err == -ENOSPC)
+   f2fs_bug_on(sbi, 1);
+   else if (err)
goto err;
continue;
}
@@ -727,15 +722,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, 
struct inode *inode,
if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
 
if (src == NULL_ADDR) {
-   do {
-   err = f2fs_reserve_new_block();
-   if (err == -ENOSPC) {
-   f2fs_bug_on(sbi, 1);
-   break;
-   }
-   } while (err &&
-   
IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
-   if (err)
+   err = f2fs_reserve_new_block();
+   if (err == -ENOSPC)
+   f2fs_bug_on(sbi, 1);
+   else if (err)
goto err;
}
 retry_prev:
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH V3] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2023-12-24 Thread Zhiguo Niu
Dear Chao,

Do you have any other suggestions about this patch version?
thanks!

On Tue, Dec 19, 2023 at 11:57 AM Zhiguo Niu  wrote:
>
> unify the error handling of ERROR_INVALID_BLKADDR in f2fs_is_valid_blkaddr
> and remove some redundant codes in f2fs_cache_compressed_page.
>
> Signed-off-by: Zhiguo Niu 
> ---
> changes of v2: improve patch according Chao's suggestions.
> changes of v3:
> -rebase patch to dev-test
> -correct return value for some f2fs_is_valid_blkaddr error case
> ---
> ---
>  fs/f2fs/checkpoint.c   | 39 ---
>  fs/f2fs/compress.c |  4 
>  fs/f2fs/data.c | 24 
>  fs/f2fs/extent_cache.c |  7 ++-
>  fs/f2fs/file.c | 12 ++--
>  fs/f2fs/gc.c   |  2 --
>  fs/f2fs/node.c |  2 +-
>  fs/f2fs/recovery.c |  4 
>  fs/f2fs/segment.c  |  2 --
>  9 files changed, 29 insertions(+), 67 deletions(-)
>
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index b0597a5..83119aa 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
> block_t blkaddr,
> if (unlikely(f2fs_cp_error(sbi)))
> return exist;
>
> -   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> -   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> -blkaddr, exist);
> -   set_sbi_flag(sbi, SBI_NEED_FSCK);
> -   return exist;
> -   }
> +   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> +   (!exist && type == DATA_GENERIC_ENHANCE))
> +   goto err;
>
> -   if (!exist && type == DATA_GENERIC_ENHANCE) {
> -   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> -blkaddr, exist);
> -   set_sbi_flag(sbi, SBI_NEED_FSCK);
> -   dump_stack();
> -   }
> +   return exist;
> +err:
> +   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> +   blkaddr, exist);
> +   set_sbi_flag(sbi, SBI_NEED_FSCK);
> +   dump_stack();
> +   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> return exist;
>  }
>
> @@ -174,29 +172,29 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> block_t blkaddr, int type)
>  {
> if (time_to_inject(sbi, FAULT_BLKADDR))
> -   return false;
> +   goto err;
>
> switch (type) {
> case META_NAT:
> break;
> case META_SIT:
> if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> -   return false;
> +   goto err;
> break;
> case META_SSA:
> if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
> blkaddr < SM_I(sbi)->ssa_blkaddr))
> -   return false;
> +   goto err;
> break;
> case META_CP:
> if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
> blkaddr < __start_cp_addr(sbi)))
> -   return false;
> +   goto err;
> break;
> case META_POR:
> if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
> blkaddr < MAIN_BLKADDR(sbi)))
> -   return false;
> +   goto err;
> break;
> case DATA_GENERIC:
> case DATA_GENERIC_ENHANCE:
> @@ -213,7 +211,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
>   blkaddr);
> set_sbi_flag(sbi, SBI_NEED_FSCK);
> dump_stack();
> -   return false;
> +   goto err;
> } else {
> return __is_bitmap_valid(sbi, blkaddr, type);
> }
> @@ -221,13 +219,16 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> case META_GENERIC:
> if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
> blkaddr >= MAIN_BLKADDR(sbi)))
> -   return false;
> +   goto err;
> break;
> default:
> BUG();
> }
>
> return true;
> +err:
> +   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> +   return false;
&g

[f2fs-dev] [PATCH V5] f2fs: show more discard status by sysfs

2023-12-19 Thread Zhiguo Niu
The current pending_discard attr just only shows the discard_cmd_cnt
information. More discard status can be shown so that we can check
them through sysfs when needed.

Signed-off-by: Zhiguo Niu 
---
changes of v2: Improve the patch according to Chao's suggestions.
changes of v3: Add a blank line for easy reading.
changes of v4: Split to three entries
changes of v5: move these entries from disk/xxx to disk/stat/xxx.
---
---
 Documentation/ABI/testing/sysfs-fs-f2fs | 15 +++
 fs/f2fs/sysfs.c | 34 +
 2 files changed, 49 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index 4f1d4e6..99fa87a 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -498,6 +498,21 @@ Description:   Show status of f2fs checkpoint in real 
time.
CP_RESIZEFS_FLAG0x4000
=== ==
 
+What:  /sys/fs/f2fs//stat/issued_discard
+Date:  December 2023
+Contact:   "Zhiguo Niu" 
+Description:   Shows the number of issued discard.
+
+What:  /sys/fs/f2fs//stat/queued_discard
+Date:  December 2023
+Contact:   "Zhiguo Niu" 
+Description:   Shows the number of queued discard.
+
+What:  /sys/fs/f2fs//stat/undiscard_blks
+Date:  December 2023
+Contact:   "Zhiguo Niu" 
+Description:   Shows the total number of undiscard blocks.
+
 What:  /sys/fs/f2fs//ckpt_thread_ioprio
 Date:  January 2021
 Contact:   "Daeho Jeong" 
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 7099ffa..c13eef0 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -143,6 +143,33 @@ static ssize_t pending_discard_show(struct f2fs_attr *a,
_I(sbi)->dcc_info->discard_cmd_cnt));
 }
 
+static ssize_t issued_discard_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   if (!SM_I(sbi)->dcc_info)
+   return -EINVAL;
+   return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
+   _I(sbi)->dcc_info->issued_discard));
+}
+
+static ssize_t queued_discard_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   if (!SM_I(sbi)->dcc_info)
+   return -EINVAL;
+   return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
+   _I(sbi)->dcc_info->queued_discard));
+}
+
+static ssize_t undiscard_blks_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   if (!SM_I(sbi)->dcc_info)
+   return -EINVAL;
+   return sysfs_emit(buf, "%u\n",
+   SM_I(sbi)->dcc_info->undiscard_blks);
+}
+
 static ssize_t gc_mode_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
 {
@@ -1206,9 +1233,16 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
 
 F2FS_GENERAL_RO_ATTR(sb_status);
 F2FS_GENERAL_RO_ATTR(cp_status);
+F2FS_GENERAL_RO_ATTR(issued_discard);
+F2FS_GENERAL_RO_ATTR(queued_discard);
+F2FS_GENERAL_RO_ATTR(undiscard_blks);
+
 static struct attribute *f2fs_stat_attrs[] = {
ATTR_LIST(sb_status),
ATTR_LIST(cp_status),
+   ATTR_LIST(issued_discard),
+   ATTR_LIST(queued_discard),
+   ATTR_LIST(undiscard_blks),
NULL,
 };
 ATTRIBUTE_GROUPS(f2fs_stat);
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH V4] f2fs: show more discard status by sysfs

2023-12-19 Thread Zhiguo Niu
On Tue, Dec 19, 2023 at 11:24 PM Chao Yu  wrote:
>
> On 2023/12/19 12:09, Zhiguo Niu wrote:
> > On Tue, Dec 19, 2023 at 12:00 PM Chao Yu  wrote:
> >>
> >> On 2023/12/19 10:21, Zhiguo Niu wrote:
> >>> The current pending_discard attr just only shows the discard_cmd_cnt
> >>> information. More discard status can be shown so that we can check
> >>> them through sysfs when needed.
> >>>
> >>> Signed-off-by: Zhiguo Niu 
> >>> ---
> >>> changes of v2: Improve the patch according to Chao's suggestions.
> >>> changes of v3: Add a blank line for easy reading.
> >>> changes of v4: Split to three entries
> >>> ---
> >>> ---
> >>>Documentation/ABI/testing/sysfs-fs-f2fs | 15 +++
> >>>fs/f2fs/sysfs.c | 33 
> >>> +
> >>>2 files changed, 48 insertions(+)
> >>>
> >>> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> >>> b/Documentation/ABI/testing/sysfs-fs-f2fs
> >>> index 4f1d4e6..606a298 100644
> >>> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> >>> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> >>> @@ -159,6 +159,21 @@ Date:November 2021
> >>>Contact:"Jaegeuk Kim" 
> >>>Description:Shows the number of pending discard commands in 
> >>> the queue.
> >>>
> >>> +What:   /sys/fs/f2fs//issued_discard
> >>
> >> Add them to /sys/fs/f2fs//stat/?
> > I just want to keep them consistent with the entry "pending_discard"
>
> There are too many entries in root directory of f2fs sysfs entry, so I
> created the 'stat' sub-directory for later all read-only stat-related
> entry. I think it's fine to create new discard stat entries there.
I got it  and will update the patch. thanks.
>
> Thanks,
>
> > if they are split to 3 entries.
> > they are all discard related infos.
> > Thanks
> >>
> >> Thanks,
> >>
> >>> +Date:   December 2023
> >>> +Contact:"Zhiguo Niu" 
> >>> +Description:Shows the number of issued discard.
> >>> +
> >>> +What:   /sys/fs/f2fs//queued_discard
> >>> +Date:   December 2023
> >>> +Contact:"Zhiguo Niu" 
> >>> +Description:Shows the number of queued discard.
> >>> +
> >>> +What:   /sys/fs/f2fs//undiscard_blks
> >>> +Date:   December 2023
> >>> +Contact:"Zhiguo Niu" 
> >>> +Description:Shows the total number of undiscard blocks.
> >>> +
> >>>What:   /sys/fs/f2fs//max_victim_search
> >>>Date:   January 2014
> >>>Contact:"Jaegeuk Kim" 
> >>> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> >>> index 7099ffa..666efdd 100644
> >>> --- a/fs/f2fs/sysfs.c
> >>> +++ b/fs/f2fs/sysfs.c
> >>> @@ -143,6 +143,33 @@ static ssize_t pending_discard_show(struct f2fs_attr 
> >>> *a,
> >>>_I(sbi)->dcc_info->discard_cmd_cnt));
> >>>}
> >>>
> >>> +static ssize_t issued_discard_show(struct f2fs_attr *a,
> >>> + struct f2fs_sb_info *sbi, char *buf)
> >>> +{
> >>> + if (!SM_I(sbi)->dcc_info)
> >>> + return -EINVAL;
> >>> + return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
> >>> + _I(sbi)->dcc_info->issued_discard));
> >>> +}
> >>> +
> >>> +static ssize_t queued_discard_show(struct f2fs_attr *a,
> >>> + struct f2fs_sb_info *sbi, char *buf)
> >>> +{
> >>> + if (!SM_I(sbi)->dcc_info)
> >>> + return -EINVAL;
> >>> + return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
> >>> + _I(sbi)->dcc_info->queued_discard));
> >>> +}
> >>> +
> >>> +static ssize_t undiscard_blks_show(struct f2fs_attr *a,
> >>> + struct f2fs_sb_info *sbi, char *buf)
> >>> +{
> >>> + if (!SM_I(sbi)->dcc_info)
> >>> + return -EINVAL;
> >>> + return sysfs_emit(buf, "%u\n",

Re: [f2fs-dev] [PATCH V4] f2fs: show more discard status by sysfs

2023-12-18 Thread Zhiguo Niu
On Tue, Dec 19, 2023 at 12:00 PM Chao Yu  wrote:
>
> On 2023/12/19 10:21, Zhiguo Niu wrote:
> > The current pending_discard attr just only shows the discard_cmd_cnt
> > information. More discard status can be shown so that we can check
> > them through sysfs when needed.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> > changes of v2: Improve the patch according to Chao's suggestions.
> > changes of v3: Add a blank line for easy reading.
> > changes of v4: Split to three entries
> > ---
> > ---
> >   Documentation/ABI/testing/sysfs-fs-f2fs | 15 +++
> >   fs/f2fs/sysfs.c | 33 
> > +
> >   2 files changed, 48 insertions(+)
> >
> > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > index 4f1d4e6..606a298 100644
> > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > @@ -159,6 +159,21 @@ Date:November 2021
> >   Contact:"Jaegeuk Kim" 
> >   Description:Shows the number of pending discard commands in the 
> > queue.
> >
> > +What:   /sys/fs/f2fs//issued_discard
>
> Add them to /sys/fs/f2fs//stat/?
I just want to keep them consistent with the entry "pending_discard"
if they are split to 3 entries.
they are all discard related infos.
Thanks
>
> Thanks,
>
> > +Date:   December 2023
> > +Contact:"Zhiguo Niu" 
> > +Description:Shows the number of issued discard.
> > +
> > +What:   /sys/fs/f2fs//queued_discard
> > +Date:   December 2023
> > +Contact:"Zhiguo Niu" 
> > +Description:Shows the number of queued discard.
> > +
> > +What:   /sys/fs/f2fs//undiscard_blks
> > +Date:   December 2023
> > +Contact:"Zhiguo Niu" 
> > +Description:Shows the total number of undiscard blocks.
> > +
> >   What:   /sys/fs/f2fs//max_victim_search
> >   Date:   January 2014
> >   Contact:"Jaegeuk Kim" 
> > diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> > index 7099ffa..666efdd 100644
> > --- a/fs/f2fs/sysfs.c
> > +++ b/fs/f2fs/sysfs.c
> > @@ -143,6 +143,33 @@ static ssize_t pending_discard_show(struct f2fs_attr 
> > *a,
> >   _I(sbi)->dcc_info->discard_cmd_cnt));
> >   }
> >
> > +static ssize_t issued_discard_show(struct f2fs_attr *a,
> > + struct f2fs_sb_info *sbi, char *buf)
> > +{
> > + if (!SM_I(sbi)->dcc_info)
> > + return -EINVAL;
> > + return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
> > + _I(sbi)->dcc_info->issued_discard));
> > +}
> > +
> > +static ssize_t queued_discard_show(struct f2fs_attr *a,
> > + struct f2fs_sb_info *sbi, char *buf)
> > +{
> > + if (!SM_I(sbi)->dcc_info)
> > + return -EINVAL;
> > + return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
> > + _I(sbi)->dcc_info->queued_discard));
> > +}
> > +
> > +static ssize_t undiscard_blks_show(struct f2fs_attr *a,
> > + struct f2fs_sb_info *sbi, char *buf)
> > +{
> > + if (!SM_I(sbi)->dcc_info)
> > + return -EINVAL;
> > + return sysfs_emit(buf, "%u\n",
> > + SM_I(sbi)->dcc_info->undiscard_blks);
> > +}
> > +
> >   static ssize_t gc_mode_show(struct f2fs_attr *a,
> >   struct f2fs_sb_info *sbi, char *buf)
> >   {
> > @@ -1025,6 +1052,9 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr 
> > *a,
> >   F2FS_GENERAL_RO_ATTR(mounted_time_sec);
> >   F2FS_GENERAL_RO_ATTR(main_blkaddr);
> >   F2FS_GENERAL_RO_ATTR(pending_discard);
> > +F2FS_GENERAL_RO_ATTR(issued_discard);
> > +F2FS_GENERAL_RO_ATTR(queued_discard);
> > +F2FS_GENERAL_RO_ATTR(undiscard_blks);
> >   F2FS_GENERAL_RO_ATTR(gc_mode);
> >   #ifdef CONFIG_F2FS_STAT_FS
> >   F2FS_GENERAL_RO_ATTR(moved_blocks_background);
> > @@ -1084,6 +1114,9 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr 
> > *a,
> >   ATTR_LIST(max_ordered_discard),
> >   ATTR_LIST(discard_io_aware),
> >   ATTR_LIST(pending_discard),
> > + ATTR_LIST(issued_discard),
> > + ATTR_LIST(queued_discard),
> > + ATTR_LIST(undiscard_blks),
> >   ATTR_LIST(gc_mode),
> >   ATTR_LIST(ipu_policy),
> >   ATTR_LIST(min_ipu_util),


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


[f2fs-dev] [PATCH V3] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2023-12-18 Thread Zhiguo Niu
unify the error handling of ERROR_INVALID_BLKADDR in f2fs_is_valid_blkaddr
and remove some redundant codes in f2fs_cache_compressed_page.

Signed-off-by: Zhiguo Niu 
---
changes of v2: improve patch according Chao's suggestions.
changes of v3:
-rebase patch to dev-test
-correct return value for some f2fs_is_valid_blkaddr error case
---
---
 fs/f2fs/checkpoint.c   | 39 ---
 fs/f2fs/compress.c |  4 
 fs/f2fs/data.c | 24 
 fs/f2fs/extent_cache.c |  7 ++-
 fs/f2fs/file.c | 12 ++--
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/node.c |  2 +-
 fs/f2fs/recovery.c |  4 
 fs/f2fs/segment.c  |  2 --
 9 files changed, 29 insertions(+), 67 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b0597a5..83119aa 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
if (unlikely(f2fs_cp_error(sbi)))
return exist;
 
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE))
+   goto err;
 
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   dump_stack();
-   }
+   return exist;
+err:
+   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+   blkaddr, exist);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   dump_stack();
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
return exist;
 }
 
@@ -174,29 +172,29 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type)
 {
if (time_to_inject(sbi, FAULT_BLKADDR))
-   return false;
+   goto err;
 
switch (type) {
case META_NAT:
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -213,7 +211,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
  blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
-   return false;
+   goto err;
} else {
return __is_bitmap_valid(sbi, blkaddr, type);
}
@@ -221,13 +219,16 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
case META_GENERIC:
if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
blkaddr >= MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
default:
BUG();
}
 
return true;
+err:
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+   return false;
 }
 
 /*
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index c5a4364..cf075ca 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1878,12 +1878,8 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
*sbi, struct page *page,
 
set_page_private_data(cpage, ino);
 
-   if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ))
-   goto out;
-
memcpy(page_address(cpage), page_address(page), PAGE_SIZE);
SetPageUptodate(cpage);
-out:
f2fs_put_page(cpage, 1);
 }
 
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index dce8def..61be01f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -740,10 +740,8 @@ int f2fs_submit_pag

[f2fs-dev] [PATCH V4] f2fs: show more discard status by sysfs

2023-12-18 Thread Zhiguo Niu
The current pending_discard attr just only shows the discard_cmd_cnt
information. More discard status can be shown so that we can check
them through sysfs when needed.

Signed-off-by: Zhiguo Niu 
---
changes of v2: Improve the patch according to Chao's suggestions.
changes of v3: Add a blank line for easy reading.
changes of v4: Split to three entries
---
---
 Documentation/ABI/testing/sysfs-fs-f2fs | 15 +++
 fs/f2fs/sysfs.c | 33 +
 2 files changed, 48 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index 4f1d4e6..606a298 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -159,6 +159,21 @@ Date:  November 2021
 Contact:   "Jaegeuk Kim" 
 Description:   Shows the number of pending discard commands in the queue.
 
+What:   /sys/fs/f2fs//issued_discard
+Date:   December 2023
+Contact:    "Zhiguo Niu" 
+Description:Shows the number of issued discard.
+
+What:   /sys/fs/f2fs//queued_discard
+Date:   December 2023
+Contact:"Zhiguo Niu" 
+Description:Shows the number of queued discard.
+
+What:   /sys/fs/f2fs//undiscard_blks
+Date:   December 2023
+Contact:"Zhiguo Niu" 
+Description:Shows the total number of undiscard blocks.
+
 What:  /sys/fs/f2fs//max_victim_search
 Date:  January 2014
 Contact:   "Jaegeuk Kim" 
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 7099ffa..666efdd 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -143,6 +143,33 @@ static ssize_t pending_discard_show(struct f2fs_attr *a,
_I(sbi)->dcc_info->discard_cmd_cnt));
 }
 
+static ssize_t issued_discard_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   if (!SM_I(sbi)->dcc_info)
+   return -EINVAL;
+   return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
+   _I(sbi)->dcc_info->issued_discard));
+}
+
+static ssize_t queued_discard_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   if (!SM_I(sbi)->dcc_info)
+   return -EINVAL;
+   return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
+   _I(sbi)->dcc_info->queued_discard));
+}
+
+static ssize_t undiscard_blks_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   if (!SM_I(sbi)->dcc_info)
+   return -EINVAL;
+   return sysfs_emit(buf, "%u\n",
+   SM_I(sbi)->dcc_info->undiscard_blks);
+}
+
 static ssize_t gc_mode_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
 {
@@ -1025,6 +1052,9 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
 F2FS_GENERAL_RO_ATTR(mounted_time_sec);
 F2FS_GENERAL_RO_ATTR(main_blkaddr);
 F2FS_GENERAL_RO_ATTR(pending_discard);
+F2FS_GENERAL_RO_ATTR(issued_discard);
+F2FS_GENERAL_RO_ATTR(queued_discard);
+F2FS_GENERAL_RO_ATTR(undiscard_blks);
 F2FS_GENERAL_RO_ATTR(gc_mode);
 #ifdef CONFIG_F2FS_STAT_FS
 F2FS_GENERAL_RO_ATTR(moved_blocks_background);
@@ -1084,6 +1114,9 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
ATTR_LIST(max_ordered_discard),
ATTR_LIST(discard_io_aware),
ATTR_LIST(pending_discard),
+   ATTR_LIST(issued_discard),
+   ATTR_LIST(queued_discard),
+   ATTR_LIST(undiscard_blks),
ATTR_LIST(gc_mode),
ATTR_LIST(ipu_policy),
ATTR_LIST(min_ipu_util),
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH V3] f2fs: show more discard status by sysfs

2023-12-18 Thread Zhiguo Niu
On Tue, Dec 19, 2023 at 1:45 AM Jaegeuk Kim  wrote:
>
> On 12/18, Zhiguo Niu wrote:
> > The current pending_discard attr just only shows the discard_cmd_cnt
> > information. More discard status can be shown so that we can check
> > them through sysfs when needed.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> > changes of v2: Improve the patch according to Chao's suggestions.
> > changes of v3: Add a blank line for easy reading.
> > ---
> > ---
> >  Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++
> >  fs/f2fs/sysfs.c | 19 +++
> >  2 files changed, 25 insertions(+)
> >
> > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > index 36c3cb5..c6970e5 100644
> > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > @@ -498,6 +498,12 @@ Description: Show status of f2fs checkpoint in 
> > real time.
> >   CP_RESIZEFS_FLAG0x4000
> >   === ==========
> >
> > +What:/sys/fs/f2fs//stat/discard_status
> > +Date:November 2023
> > +Contact: "Zhiguo Niu" 
> > +Description: Show status of f2fs discard in real time, including
> > + "issued discard","queued discard" and "undiscard blocks".
> > +
> >  What:/sys/fs/f2fs//ckpt_thread_ioprio
> >  Date:January 2021
> >  Contact: "Daeho Jeong" 
> > diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> > index 417fae96..312a4dc 100644
> > --- a/fs/f2fs/sysfs.c
> > +++ b/fs/f2fs/sysfs.c
> > @@ -134,6 +134,22 @@ static ssize_t cp_status_show(struct f2fs_attr *a,
> >   return sysfs_emit(buf, "%x\n", 
> > le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags));
> >  }
> >
> > +static ssize_t discard_status_show(struct f2fs_attr *a,
> > + struct f2fs_sb_info *sbi, char *buf)
> > +{
> > + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> > +
> > + if (!dcc)
> > + return -EINVAL;
> > +
> > + return sysfs_emit(buf, "%llu, %llu, %u\n",
> > + (unsigned long long)atomic_read(
> > + >issued_discard),
> > + (unsigned long long)atomic_read(
> > + >queued_discard),
> > + dcc->undiscard_blks);
>
> We cannot do this since it needs one value per one entry.
OK, I will split this into three entry. thanks
>
> > +}
> > +
> >  static ssize_t pending_discard_show(struct f2fs_attr *a,
> >   struct f2fs_sb_info *sbi, char *buf)
> >  {
> > @@ -1197,9 +1213,12 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr 
> > *a,
> >
> >  F2FS_GENERAL_RO_ATTR(sb_status);
> >  F2FS_GENERAL_RO_ATTR(cp_status);
> > +F2FS_GENERAL_RO_ATTR(discard_status);
> > +
> >  static struct attribute *f2fs_stat_attrs[] = {
> >   ATTR_LIST(sb_status),
> >   ATTR_LIST(cp_status),
> > + ATTR_LIST(discard_status),
> >   NULL,
> >  };
> >  ATTRIBUTE_GROUPS(f2fs_stat);
> > --
> > 1.9.1


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


[f2fs-dev] [PATCH V3] f2fs: show more discard status by sysfs

2023-12-18 Thread Zhiguo Niu
The current pending_discard attr just only shows the discard_cmd_cnt
information. More discard status can be shown so that we can check
them through sysfs when needed.

Signed-off-by: Zhiguo Niu 
---
changes of v2: Improve the patch according to Chao's suggestions.
changes of v3: Add a blank line for easy reading.
---
---
 Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++
 fs/f2fs/sysfs.c | 19 +++
 2 files changed, 25 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index 36c3cb5..c6970e5 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -498,6 +498,12 @@ Description:   Show status of f2fs checkpoint in real 
time.
CP_RESIZEFS_FLAG0x4000
=== ==
 
+What:  /sys/fs/f2fs//stat/discard_status
+Date:  November 2023
+Contact:   "Zhiguo Niu" 
+Description:   Show status of f2fs discard in real time, including
+   "issued discard","queued discard" and "undiscard blocks".
+
 What:  /sys/fs/f2fs//ckpt_thread_ioprio
 Date:  January 2021
 Contact:   "Daeho Jeong" 
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 417fae96..312a4dc 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -134,6 +134,22 @@ static ssize_t cp_status_show(struct f2fs_attr *a,
return sysfs_emit(buf, "%x\n", le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags));
 }
 
+static ssize_t discard_status_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+
+   if (!dcc)
+   return -EINVAL;
+
+   return sysfs_emit(buf, "%llu, %llu, %u\n",
+   (unsigned long long)atomic_read(
+   >issued_discard),
+   (unsigned long long)atomic_read(
+   >queued_discard),
+   dcc->undiscard_blks);
+}
+
 static ssize_t pending_discard_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
 {
@@ -1197,9 +1213,12 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
 
 F2FS_GENERAL_RO_ATTR(sb_status);
 F2FS_GENERAL_RO_ATTR(cp_status);
+F2FS_GENERAL_RO_ATTR(discard_status);
+
 static struct attribute *f2fs_stat_attrs[] = {
ATTR_LIST(sb_status),
ATTR_LIST(cp_status),
+   ATTR_LIST(discard_status),
NULL,
 };
 ATTRIBUTE_GROUPS(f2fs_stat);
-- 
1.9.1



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


Re: [f2fs-dev] [PATCH V2] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2023-12-17 Thread Zhiguo Niu
Dear Chao,
thanks for your feedback.

On Fri, Dec 15, 2023 at 10:28 AM Chao Yu  wrote:
>
> On 2023/12/12 13:23, Zhiguo Niu wrote:
> > unify the error handling of ERROR_INVALID_BLKADDR in f2fs_is_valid_blkaddr
> > and remove some redundant codes in f2fs_cache_compressed_page.
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> > changes of v2: improve patch according Chao's suggestions.
> > ---
> > ---
> >   fs/f2fs/checkpoint.c   | 43 +++
> >   fs/f2fs/compress.c |  4 
> >   fs/f2fs/data.c | 24 
> >   fs/f2fs/extent_cache.c |  7 ++-
> >   fs/f2fs/f2fs.h |  5 ++---
> >   fs/f2fs/file.c | 17 +
> >   fs/f2fs/gc.c   |  2 --
> >   fs/f2fs/inode.c|  5 ++---
> >   fs/f2fs/node.c |  2 +-
> >   fs/f2fs/recovery.c | 13 ++---
> >   fs/f2fs/segment.c  |  2 --
> >   11 files changed, 45 insertions(+), 79 deletions(-)
> >
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index b0597a5..d8ff056 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info 
> > *sbi, block_t blkaddr,
> >   if (unlikely(f2fs_cp_error(sbi)))
> >   return exist;
> >
> > - if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
> > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > -  blkaddr, exist);
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > - return exist;
> > - }
> > + if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
> > + (!exist && type == DATA_GENERIC_ENHANCE))
> > + goto err;
> >
> > - if (!exist && type == DATA_GENERIC_ENHANCE) {
> > - f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > -  blkaddr, exist);
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > - dump_stack();
> > - }
> > + return exist;
> > +err:
> > + f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> > + blkaddr, exist);
> > + set_sbi_flag(sbi, SBI_NEED_FSCK);
> > + dump_stack();
> > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >   return exist;
> >   }
> >
> > @@ -174,29 +172,29 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> >   block_t blkaddr, int type)
> >   {
> >   if (time_to_inject(sbi, FAULT_BLKADDR))
> > - return false;
> > + goto err;
> >
> >   switch (type) {
> >   case META_NAT:
> >   break;
> >   case META_SIT:
> >   if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> > - return false;
> > + goto err;
> >   break;
> >   case META_SSA:
> >   if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
> >   blkaddr < SM_I(sbi)->ssa_blkaddr))
> > - return false;
> > + goto err;
> >   break;
> >   case META_CP:
> >   if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
> >   blkaddr < __start_cp_addr(sbi)))
> > - return false;
> > + goto err;
> >   break;
> >   case META_POR:
> >   if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
> >   blkaddr < MAIN_BLKADDR(sbi)))
> > - return false;
> > + goto err;
> >   break;
> >   case DATA_GENERIC:
> >   case DATA_GENERIC_ENHANCE:
> > @@ -213,7 +211,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> > blkaddr);
> >   set_sbi_flag(sbi, SBI_NEED_FSCK);
> >   dump_stack();
> > - return false;
> > + goto err;
> >   } else {
> >   return __is_bitmap_valid(sbi, blkaddr, type);
> >   }
> > @@ -221,13 +219,16 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
> >   case META_GENERIC:
> >   if (unlikely(blkaddr < SEG0_BLKADDR(sb

[f2fs-dev] [PATCH V2] f2fs: unify the error handling of f2fs_is_valid_blkaddr

2023-12-11 Thread Zhiguo Niu
unify the error handling of ERROR_INVALID_BLKADDR in f2fs_is_valid_blkaddr
and remove some redundant codes in f2fs_cache_compressed_page.

Signed-off-by: Zhiguo Niu 
---
changes of v2: improve patch according Chao's suggestions.
---
---
 fs/f2fs/checkpoint.c   | 43 +++
 fs/f2fs/compress.c |  4 
 fs/f2fs/data.c | 24 
 fs/f2fs/extent_cache.c |  7 ++-
 fs/f2fs/f2fs.h |  5 ++---
 fs/f2fs/file.c | 17 +
 fs/f2fs/gc.c   |  2 --
 fs/f2fs/inode.c|  5 ++---
 fs/f2fs/node.c |  2 +-
 fs/f2fs/recovery.c | 13 ++---
 fs/f2fs/segment.c  |  2 --
 11 files changed, 45 insertions(+), 79 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b0597a5..d8ff056 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -154,19 +154,17 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
if (unlikely(f2fs_cp_error(sbi)))
return exist;
 
-   if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   return exist;
-   }
+   if ((exist && type == DATA_GENERIC_ENHANCE_UPDATE) ||
+   (!exist && type == DATA_GENERIC_ENHANCE))
+   goto err;
 
-   if (!exist && type == DATA_GENERIC_ENHANCE) {
-   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
-blkaddr, exist);
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   dump_stack();
-   }
+   return exist;
+err:
+   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+   blkaddr, exist);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   dump_stack();
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
return exist;
 }
 
@@ -174,29 +172,29 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type)
 {
if (time_to_inject(sbi, FAULT_BLKADDR))
-   return false;
+   goto err;
 
switch (type) {
case META_NAT:
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   return false;
+   goto err;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   return false;
+   goto err;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   return false;
+   goto err;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -213,7 +211,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
  blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
dump_stack();
-   return false;
+   goto err;
} else {
return __is_bitmap_valid(sbi, blkaddr, type);
}
@@ -221,13 +219,16 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
case META_GENERIC:
if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
blkaddr >= MAIN_BLKADDR(sbi)))
-   return false;
+   goto err;
break;
default:
BUG();
}
 
return true;
+err:
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+   return false;
 }
 
 /*
@@ -256,8 +257,10 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t 
start, int nrpages,
blk_start_plug();
for (; nrpages-- > 0; blkno++) {
 
-   if (!f2fs_is_valid_blkaddr(sbi, blkno, type))
+   if (!f2fs_is_valid_blkaddr(sbi, blkno, type)) {
+   err = -EFSCORRUPTED;
goto out;
+   }
 
switch (type) {
case META_NAT:
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 36e5dab..bd5acb5 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1878,12 +1878,8 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
*sbi, struct page *page,
 
set_page_priv

[f2fs-dev] [PATCH V2] f2fs: fix to check return value of f2fs_recover_xattr_data

2023-12-11 Thread Zhiguo Niu
Should check return value of f2fs_recover_xattr_data in
__f2fs_setxattr rather than doing invalid retry if error happen.

Also just do set_page_dirty in f2fs_recover_xattr_data when
page is changed really.

Fixes: 50a472bbc79f ("f2fs: do not return EFSCORRUPTED, but try to run online 
repair")
Signed-off-by: Zhiguo Niu 
---
changes of v2: move infor print to sutiable position according to Chao's 
suggestion.
---
---
 fs/f2fs/node.c  |  6 +++---
 fs/f2fs/xattr.c | 11 +++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index e50a093..93bf724 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2754,11 +2754,11 @@ int f2fs_recover_xattr_data(struct inode *inode, struct 
page *page)
f2fs_update_inode_page(inode);
 
/* 3: update and set xattr node page dirty */
-   if (page)
+   if (page) {
memcpy(F2FS_NODE(xpage), F2FS_NODE(page),
VALID_XATTR_BLOCK_SIZE);
-
-   set_page_dirty(xpage);
+   set_page_dirty(xpage);
+   }
f2fs_put_page(xpage, 1);
 
return 0;
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 47e88b4..b04b8fd 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -660,11 +660,14 @@ static int __f2fs_setxattr(struct inode *inode, int index,
here = __find_xattr(base_addr, last_base_addr, NULL, index, len, name);
if (!here) {
if (!F2FS_I(inode)->i_xattr_nid) {
+   error = f2fs_recover_xattr_data(inode, NULL);
f2fs_notice(F2FS_I_SB(inode),
-   "recover xattr in inode (%lu)", inode->i_ino);
-   f2fs_recover_xattr_data(inode, NULL);
-   kfree(base_addr);
-   goto retry;
+   "recover xattr in inode (%lu), error(%d)",
+   inode->i_ino, error);
+   if (!error) {
+   kfree(base_addr);
+   goto retry;
+   }
}
f2fs_err(F2FS_I_SB(inode), "set inode (%lu) has corrupted 
xattr",
inode->i_ino);
-- 
1.9.1



___
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: unify the error handling of f2fs_is_valid_blkaddr

2023-12-11 Thread Zhiguo Niu
Dear Chao

On Tue, Dec 12, 2023 at 9:32 AM Chao Yu  wrote:
>
> On 2023/12/1 13:42, Zhiguo Niu wrote:
> > unify the error handling of f2fs_is_valid_blkaddr and remove some
> > redundant codes in f2fs_cache_compressed_page.
>
> What about moving f2fs_handle_error(ERROR_INVALID_BLKADDR) into
> f2fs_is_valid_blkaddr() for cleanup?
Thanks  for your suggestion and I think it is a good opinion.  I will
update this patch.
>
> Thanks,
>
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/checkpoint.c   |  6 +-
> >   fs/f2fs/compress.c |  8 +++-
> >   fs/f2fs/data.c |  3 ++-
> >   fs/f2fs/extent_cache.c |  7 ---
> >   fs/f2fs/f2fs.h |  6 --
> >   fs/f2fs/file.c | 10 +++---
> >   fs/f2fs/node.c |  7 +--
> >   fs/f2fs/recovery.c | 15 +++
> >   8 files changed, 41 insertions(+), 21 deletions(-)
> >
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index b0597a5..47a1335 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -158,6 +158,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
> > block_t blkaddr,
> >   f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
> >blkaddr, exist);
> >   set_sbi_flag(sbi, SBI_NEED_FSCK);
> > + dump_stack();
> >   return exist;
> >   }
> >
> > @@ -256,8 +257,11 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, 
> > block_t start, int nrpages,
> >   blk_start_plug();
> >   for (; nrpages-- > 0; blkno++) {
> >
> > - if (!f2fs_is_valid_blkaddr(sbi, blkno, type))
> > + if (!f2fs_is_valid_blkaddr(sbi, blkno, type)) {
> > + err = -EFSCORRUPTED;
> > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >   goto out;
> > + }
> >
> >   switch (type) {
> >   case META_NAT:
> > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> > index 36e5dab..15d5035 100644
> > --- a/fs/f2fs/compress.c
> > +++ b/fs/f2fs/compress.c
> > @@ -1853,8 +1853,10 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
> > *sbi, struct page *page,
> >   if (!test_opt(sbi, COMPRESS_CACHE))
> >   return;
> >
> > - if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ))
> > + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) {
> > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >   return;
> > + }
> >
> >   if (!f2fs_available_free_memory(sbi, COMPRESS_PAGE))
> >   return;
> > @@ -1878,12 +1880,8 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
> > *sbi, struct page *page,
> >
> >   set_page_private_data(cpage, ino);
> >
> > - if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ))
> > - goto out;
> > -
> >   memcpy(page_address(cpage), page_address(page), PAGE_SIZE);
> >   SetPageUptodate(cpage);
> > -out:
> >   f2fs_put_page(cpage, 1);
> >   }
> >
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index 4e42b5f..e1a37ea 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -2309,7 +2309,8 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, 
> > struct bio **bio_ret,
> >   break;
> >
> >   if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
> > - ret = -EFAULT;
> > + ret = -EFSCORRUPTED;
> > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >   goto out_put_dnode;
> >   }
> >   cc->nr_cpages++;
> > diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
> > index ad8dfac7..33e5632 100644
> > --- a/fs/f2fs/extent_cache.c
> > +++ b/fs/f2fs/extent_cache.c
> > @@ -43,7 +43,7 @@ bool sanity_check_extent_cache(struct inode *inode)
> >   if (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE) ||
> >   !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
> >   DATA_GENERIC_ENHANCE)) {
> > - set_sbi_flag(sbi, SBI_NEED_FSCK);
> > + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> >   f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] 
> > 

[f2fs-dev] [PATCH] f2fs: fix to check return value of f2fs_recover_xattr_data

2023-12-08 Thread Zhiguo Niu
Should check return value of f2fs_recover_xattr_data in
__f2fs_setxattr rather than doing invalid retry if error happen.

Also just do set_page_dirty in f2fs_recover_xattr_data when
page is changed really.

Fixes: 50a472bbc79f ("f2fs: do not return EFSCORRUPTED, but try to run online 
repair")
Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/node.c  |  6 +++---
 fs/f2fs/xattr.c | 12 +++-
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index e50a093..93bf724 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2754,11 +2754,11 @@ int f2fs_recover_xattr_data(struct inode *inode, struct 
page *page)
f2fs_update_inode_page(inode);
 
/* 3: update and set xattr node page dirty */
-   if (page)
+   if (page) {
memcpy(F2FS_NODE(xpage), F2FS_NODE(page),
VALID_XATTR_BLOCK_SIZE);
-
-   set_page_dirty(xpage);
+   set_page_dirty(xpage);
+   }
f2fs_put_page(xpage, 1);
 
return 0;
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 47e88b4..de92891 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -660,11 +660,13 @@ static int __f2fs_setxattr(struct inode *inode, int index,
here = __find_xattr(base_addr, last_base_addr, NULL, index, len, name);
if (!here) {
if (!F2FS_I(inode)->i_xattr_nid) {
-   f2fs_notice(F2FS_I_SB(inode),
-   "recover xattr in inode (%lu)", inode->i_ino);
-   f2fs_recover_xattr_data(inode, NULL);
-   kfree(base_addr);
-   goto retry;
+   error = f2fs_recover_xattr_data(inode, NULL);
+   if (!error) {
+   f2fs_notice(F2FS_I_SB(inode),
+   "recover xattr in inode (%lu)", 
inode->i_ino);
+   kfree(base_addr);
+   goto retry;
+   }
}
f2fs_err(F2FS_I_SB(inode), "set inode (%lu) has corrupted 
xattr",
inode->i_ino);
-- 
1.9.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: unify the error handling of f2fs_is_valid_blkaddr

2023-11-30 Thread Zhiguo Niu
unify the error handling of f2fs_is_valid_blkaddr and remove some
redundant codes in f2fs_cache_compressed_page.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/checkpoint.c   |  6 +-
 fs/f2fs/compress.c |  8 +++-
 fs/f2fs/data.c |  3 ++-
 fs/f2fs/extent_cache.c |  7 ---
 fs/f2fs/f2fs.h |  6 --
 fs/f2fs/file.c | 10 +++---
 fs/f2fs/node.c |  7 +--
 fs/f2fs/recovery.c | 15 +++
 8 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b0597a5..47a1335 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -158,6 +158,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, 
block_t blkaddr,
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
 blkaddr, exist);
set_sbi_flag(sbi, SBI_NEED_FSCK);
+   dump_stack();
return exist;
}
 
@@ -256,8 +257,11 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t 
start, int nrpages,
blk_start_plug();
for (; nrpages-- > 0; blkno++) {
 
-   if (!f2fs_is_valid_blkaddr(sbi, blkno, type))
+   if (!f2fs_is_valid_blkaddr(sbi, blkno, type)) {
+   err = -EFSCORRUPTED;
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
goto out;
+   }
 
switch (type) {
case META_NAT:
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 36e5dab..15d5035 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1853,8 +1853,10 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
*sbi, struct page *page,
if (!test_opt(sbi, COMPRESS_CACHE))
return;
 
-   if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ))
+   if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) {
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
return;
+   }
 
if (!f2fs_available_free_memory(sbi, COMPRESS_PAGE))
return;
@@ -1878,12 +1880,8 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info 
*sbi, struct page *page,
 
set_page_private_data(cpage, ino);
 
-   if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ))
-   goto out;
-
memcpy(page_address(cpage), page_address(page), PAGE_SIZE);
SetPageUptodate(cpage);
-out:
f2fs_put_page(cpage, 1);
 }
 
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 4e42b5f..e1a37ea 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2309,7 +2309,8 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct 
bio **bio_ret,
break;
 
if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
-   ret = -EFAULT;
+   ret = -EFSCORRUPTED;
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
goto out_put_dnode;
}
cc->nr_cpages++;
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index ad8dfac7..33e5632 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -43,7 +43,7 @@ bool sanity_check_extent_cache(struct inode *inode)
if (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE) ||
!f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
DATA_GENERIC_ENHANCE)) {
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is 
incorrect, run fsck to fix",
  __func__, inode->i_ino,
  ei->blk, ei->fofs, ei->len);
@@ -857,8 +857,9 @@ static int __get_new_block_age(struct inode *inode, struct 
extent_info *ei,
 
if (__is_valid_data_blkaddr(blkaddr) &&
!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) {
-   f2fs_bug_on(sbi, 1);
-   return -EINVAL;
+   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+   return -EFSCORRUPTED;
+
}
 out:
/*
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9043ced..a4b8d86 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3454,13 +3454,16 @@ static inline int get_inline_xattr_addrs(struct inode 
*inode)
 
 bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type);
+void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error);
+
 static inline void verify_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type)
 {
if (!f2fs_is_valid_blkaddr(sbi, blkaddr, type)) {
f2fs_err(sbi, "invalid blkaddr: %u, type: %

[f2fs-dev] [PATCH V2] f2fs: show more discard status by sysfs

2023-11-27 Thread Zhiguo Niu
The current pending_discard attr just only shows the discard_cmd_cnt
information. More discard status can be shown so that we can check
them through sysfs when needed.

Signed-off-by: Zhiguo Niu 
---
changes of v2: Improve the patch according to Chao's suggestions.
---
---
 Documentation/ABI/testing/sysfs-fs-f2fs |  6 ++
 fs/f2fs/sysfs.c | 18 ++
 2 files changed, 24 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index 36c3cb5..c6970e5 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -498,6 +498,12 @@ Description:   Show status of f2fs checkpoint in real 
time.
CP_RESIZEFS_FLAG0x4000
=== ==
 
+What:  /sys/fs/f2fs//stat/discard_status
+Date:  November 2023
+Contact:   "Zhiguo Niu" 
+Description:   Show status of f2fs discard in real time, including
+   "issued discard","queued discard" and "undiscard blocks".
+
 What:  /sys/fs/f2fs//ckpt_thread_ioprio
 Date:  January 2021
 Contact:   "Daeho Jeong" 
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 417fae96..2b80116 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -134,6 +134,22 @@ static ssize_t cp_status_show(struct f2fs_attr *a,
return sysfs_emit(buf, "%x\n", le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags));
 }
 
+static ssize_t discard_status_show(struct f2fs_attr *a,
+   struct f2fs_sb_info *sbi, char *buf)
+{
+   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+
+   if (!dcc)
+   return -EINVAL;
+
+   return sysfs_emit(buf, "%llu, %llu, %u\n",
+   (unsigned long long)atomic_read(
+   >issued_discard),
+   (unsigned long long)atomic_read(
+   >queued_discard),
+   dcc->undiscard_blks);
+}
+
 static ssize_t pending_discard_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
 {
@@ -1197,9 +1213,11 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
 
 F2FS_GENERAL_RO_ATTR(sb_status);
 F2FS_GENERAL_RO_ATTR(cp_status);
+F2FS_GENERAL_RO_ATTR(discard_status);
 static struct attribute *f2fs_stat_attrs[] = {
ATTR_LIST(sb_status),
ATTR_LIST(cp_status),
+   ATTR_LIST(discard_status),
NULL,
 };
 ATTRIBUTE_GROUPS(f2fs_stat);
-- 
1.9.1



___
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: show more discard stat by sysfs

2023-11-27 Thread Zhiguo Niu
Dear Chao,

On Tue, Nov 28, 2023 at 10:13 AM Chao Yu  wrote:
>
> On 2023/11/24 9:08, Zhiguo Niu wrote:
> > The current pending_discard attr just only shows the discard_cmd_cnt
> > information, which is not very meaningful. More discard information
> > can be shown so that we can check them through sysfs when needed.
>
> What about adding this entry to /sys/fs/f2fs//stat/?
I think it is ok!
The purpose of this patch is to obtain f2fs discard related status
when necessary.
Because sys/kernel/debug/f2fs/status cannot be used on the user version,
I will change it according to your suggestion.
>
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/sysfs.c | 21 +++--
> >   1 file changed, 15 insertions(+), 6 deletions(-)
> >
> > diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> > index 417fae96..f98e680 100644
> > --- a/fs/f2fs/sysfs.c
> > +++ b/fs/f2fs/sysfs.c
> > @@ -134,13 +134,22 @@ static ssize_t cp_status_show(struct f2fs_attr *a,
> >   return sysfs_emit(buf, "%x\n", 
> > le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags));
> >   }
> >
> > -static ssize_t pending_discard_show(struct f2fs_attr *a,
> > +static ssize_t discard_stat_show(struct f2fs_attr *a,
> >   struct f2fs_sb_info *sbi, char *buf)
> >   {
> > - if (!SM_I(sbi)->dcc_info)
> > + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> > +
> > + if (!dcc)
> >   return -EINVAL;
> > - return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
> > - _I(sbi)->dcc_info->discard_cmd_cnt));
>
> It's better to keep the old one for any potential user.
>
> > +
> > + return sysfs_emit(buf, "%llu, %llu, %llu, %u\n",
> > + (unsigned long long)atomic_read(
> > + >discard_cmd_cnt),
> > + (unsigned long long)atomic_read(
> > + >issued_discard),
> > + (unsigned long long)atomic_read(
> > + >queued_discard),
> > + dcc->undiscard_blks);
> >   }
> >
> >   static ssize_t gc_mode_show(struct f2fs_attr *a,
> > @@ -1016,7 +1025,7 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr 
> > *a,
> >   F2FS_GENERAL_RO_ATTR(encoding);
> >   F2FS_GENERAL_RO_ATTR(mounted_time_sec);
> >   F2FS_GENERAL_RO_ATTR(main_blkaddr);
> > -F2FS_GENERAL_RO_ATTR(pending_discard);
> > +F2FS_GENERAL_RO_ATTR(discard_stat);
>
> It needs to adjust Documentation/ABI/testing/sysfs-fs-f2fs.
>
> Thanks,
>
> >   F2FS_GENERAL_RO_ATTR(gc_mode);
> >   #ifdef CONFIG_F2FS_STAT_FS
> >   F2FS_GENERAL_RO_ATTR(moved_blocks_background);
> > @@ -1074,7 +1083,7 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr 
> > *a,
> >   ATTR_LIST(discard_urgent_util),
> >   ATTR_LIST(discard_granularity),
> >   ATTR_LIST(max_ordered_discard),
> > - ATTR_LIST(pending_discard),
> > + ATTR_LIST(discard_stat),
> >   ATTR_LIST(gc_mode),
> >   ATTR_LIST(ipu_policy),
> >   ATTR_LIST(min_ipu_util),


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


[f2fs-dev] [PATCH] f2fs: show more discard stat by sysfs

2023-11-23 Thread Zhiguo Niu
The current pending_discard attr just only shows the discard_cmd_cnt
information, which is not very meaningful. More discard information
can be shown so that we can check them through sysfs when needed.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/sysfs.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 417fae96..f98e680 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -134,13 +134,22 @@ static ssize_t cp_status_show(struct f2fs_attr *a,
return sysfs_emit(buf, "%x\n", le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags));
 }
 
-static ssize_t pending_discard_show(struct f2fs_attr *a,
+static ssize_t discard_stat_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
 {
-   if (!SM_I(sbi)->dcc_info)
+   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+
+   if (!dcc)
return -EINVAL;
-   return sysfs_emit(buf, "%llu\n", (unsigned long long)atomic_read(
-   _I(sbi)->dcc_info->discard_cmd_cnt));
+
+   return sysfs_emit(buf, "%llu, %llu, %llu, %u\n",
+   (unsigned long long)atomic_read(
+   >discard_cmd_cnt),
+   (unsigned long long)atomic_read(
+   >issued_discard),
+   (unsigned long long)atomic_read(
+   >queued_discard),
+   dcc->undiscard_blks);
 }
 
 static ssize_t gc_mode_show(struct f2fs_attr *a,
@@ -1016,7 +1025,7 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
 F2FS_GENERAL_RO_ATTR(encoding);
 F2FS_GENERAL_RO_ATTR(mounted_time_sec);
 F2FS_GENERAL_RO_ATTR(main_blkaddr);
-F2FS_GENERAL_RO_ATTR(pending_discard);
+F2FS_GENERAL_RO_ATTR(discard_stat);
 F2FS_GENERAL_RO_ATTR(gc_mode);
 #ifdef CONFIG_F2FS_STAT_FS
 F2FS_GENERAL_RO_ATTR(moved_blocks_background);
@@ -1074,7 +1083,7 @@ static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a,
ATTR_LIST(discard_urgent_util),
ATTR_LIST(discard_granularity),
ATTR_LIST(max_ordered_discard),
-   ATTR_LIST(pending_discard),
+   ATTR_LIST(discard_stat),
ATTR_LIST(gc_mode),
ATTR_LIST(ipu_policy),
ATTR_LIST(min_ipu_util),
-- 
1.9.1



___
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 thread name cannot be fully displayed

2023-11-07 Thread Zhiguo Niu
Dear Chao,

On Tue, Nov 7, 2023 at 10:53 PM Chao Yu  wrote:
>
> On 2023/11/2 9:20, Zhiguo Niu wrote:
> > Because the length of task'name in task_struct can not exceed
> > 16 characters, f2fs some thread'name cannot be fully displayed,
> > including important device number information.
> > If there are more than one partition using the f2fs file system,
> > it is very inconvenient to match partitions and their threads.
> >
> > The following examples show that 4 partitions all use f2fs file system
> > PID: 400TASK: ff80f120c9c0  CPU: 2   COMMAND: "f2fs_discard-25"
> > PID: 392TASK: ff80f6b75880  CPU: 3   COMMAND: "f2fs_discard-25"
> > PID: 400TASK: ff80f120c9c0  CPU: 2   COMMAND: "f2fs_discard-25"
> > PID: 392TASK: ff80f6b75880  CPU: 3   COMMAND: "f2fs_discard-25"
> > PID: 510TASK: ff80dd62c9c0  CPU: 0   COMMAND: "f2fs_ckpt-254:4"
> > PID: 255TASK: ff80f2268000  CPU: 3   COMMAND: "f2fs_ckpt-259:4"
> > PID: 398TASK: ff80f120ac40  CPU: 2   COMMAND: "f2fs_ckpt-259:4"
> > PID: 390TASK: ff80f6b76740  CPU: 3   COMMAND: "f2fs_ckpt-259:4"
> > PID: 511TASK: ff80dd629d80  CPU: 3   COMMAND: "f2fs_flush-254:"
> > PID: 399TASK: ff80f120bb00  CPU: 2   COMMAND: "f2fs_flush-259:"
> > PID: 391TASK: ff80f6b7  CPU: 3   COMMAND: "f2fs_flush-259:"
> > PID: 256TASK: ff80f226d880  CPU: 6   COMMAND: "f2fs_flush-259:"
> >
> > We can use the name format such as f2fs_gc-xxx, as saw in device:
> > PID: 260TASK: ff80f8c2e740  CPU: 3   COMMAND: "f2fs_gc-259:44"
> > PID: 420TASK: ff80f6505880  CPU: 2   COMMAND: "f2fs_gc-259:41"
> > PID: 393TASK: ff80f6b72c40  CPU: 1   COMMAND: "f2fs_gc-259:40
> > PID: 513TASK: ff80dd62e740  CPU: 1   COMMAND: "f2fs_gc-254:40"
>
> Can you please check comments in below link?
>
> https://lore.kernel.org/linux-f2fs-devel/8eaad9d0-1d59-3ecb-bab4-904ed2238...@kernel.org/
>
Thanks for your share and I got it.
> Thanks,
>
> >
> > Signed-off-by: Zhiguo Niu 
> > ---
> >   fs/f2fs/checkpoint.c | 2 +-
> >   fs/f2fs/segment.c| 4 ++--
> >   2 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index b0597a5..f6a5424 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -1893,7 +1893,7 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
> >   return 0;
> >
> >   cprc->f2fs_issue_ckpt = kthread_run(issue_checkpoint_thread, sbi,
> > - "f2fs_ckpt-%u:%u", MAJOR(dev), MINOR(dev));
> > + "f2fs_cp-%u:%u", MAJOR(dev), MINOR(dev));
> >   if (IS_ERR(cprc->f2fs_issue_ckpt)) {
> >   int err = PTR_ERR(cprc->f2fs_issue_ckpt);
> >
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index d05b416..b290713 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -677,7 +677,7 @@ int f2fs_create_flush_cmd_control(struct f2fs_sb_info 
> > *sbi)
> >
> >   init_thread:
> >   fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi,
> > - "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev));
> > + "f2fs_fh-%u:%u", MAJOR(dev), MINOR(dev));
> >   if (IS_ERR(fcc->f2fs_issue_flush)) {
> >   int err = PTR_ERR(fcc->f2fs_issue_flush);
> >
> > @@ -2248,7 +2248,7 @@ int f2fs_start_discard_thread(struct f2fs_sb_info 
> > *sbi)
> >   return 0;
> >
> >   dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi,
> > - "f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev));
> > + "f2fs_dc-%u:%u", MAJOR(dev), MINOR(dev));
> >   if (IS_ERR(dcc->f2fs_issue_discard)) {
> >   err = PTR_ERR(dcc->f2fs_issue_discard);
> >   dcc->f2fs_issue_discard = NULL;


___
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 thread name cannot be fully displayed

2023-11-01 Thread Zhiguo Niu
Because the length of task'name in task_struct can not exceed
16 characters, f2fs some thread'name cannot be fully displayed,
including important device number information.
If there are more than one partition using the f2fs file system,
it is very inconvenient to match partitions and their threads.

The following examples show that 4 partitions all use f2fs file system
PID: 400TASK: ff80f120c9c0  CPU: 2   COMMAND: "f2fs_discard-25"
PID: 392TASK: ff80f6b75880  CPU: 3   COMMAND: "f2fs_discard-25"
PID: 400TASK: ff80f120c9c0  CPU: 2   COMMAND: "f2fs_discard-25"
PID: 392TASK: ff80f6b75880  CPU: 3   COMMAND: "f2fs_discard-25"
PID: 510TASK: ff80dd62c9c0  CPU: 0   COMMAND: "f2fs_ckpt-254:4"
PID: 255TASK: ff80f2268000  CPU: 3   COMMAND: "f2fs_ckpt-259:4"
PID: 398TASK: ff80f120ac40  CPU: 2   COMMAND: "f2fs_ckpt-259:4"
PID: 390TASK: ff80f6b76740  CPU: 3   COMMAND: "f2fs_ckpt-259:4"
PID: 511TASK: ff80dd629d80  CPU: 3   COMMAND: "f2fs_flush-254:"
PID: 399TASK: ff80f120bb00  CPU: 2   COMMAND: "f2fs_flush-259:"
PID: 391TASK: ff80f6b7  CPU: 3   COMMAND: "f2fs_flush-259:"
PID: 256TASK: ff80f226d880  CPU: 6   COMMAND: "f2fs_flush-259:"

We can use the name format such as f2fs_gc-xxx, as saw in device:
PID: 260TASK: ff80f8c2e740  CPU: 3   COMMAND: "f2fs_gc-259:44"
PID: 420TASK: ff80f6505880  CPU: 2   COMMAND: "f2fs_gc-259:41"
PID: 393TASK: ff80f6b72c40  CPU: 1   COMMAND: "f2fs_gc-259:40
PID: 513TASK: ff80dd62e740  CPU: 1   COMMAND: "f2fs_gc-254:40"

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/checkpoint.c | 2 +-
 fs/f2fs/segment.c| 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b0597a5..f6a5424 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1893,7 +1893,7 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
return 0;
 
cprc->f2fs_issue_ckpt = kthread_run(issue_checkpoint_thread, sbi,
-   "f2fs_ckpt-%u:%u", MAJOR(dev), MINOR(dev));
+   "f2fs_cp-%u:%u", MAJOR(dev), MINOR(dev));
if (IS_ERR(cprc->f2fs_issue_ckpt)) {
int err = PTR_ERR(cprc->f2fs_issue_ckpt);
 
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index d05b416..b290713 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -677,7 +677,7 @@ int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi)
 
 init_thread:
fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi,
-   "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev));
+   "f2fs_fh-%u:%u", MAJOR(dev), MINOR(dev));
if (IS_ERR(fcc->f2fs_issue_flush)) {
int err = PTR_ERR(fcc->f2fs_issue_flush);
 
@@ -2248,7 +2248,7 @@ int f2fs_start_discard_thread(struct f2fs_sb_info *sbi)
return 0;
 
dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi,
-   "f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev));
+   "f2fs_dc-%u:%u", MAJOR(dev), MINOR(dev));
if (IS_ERR(dcc->f2fs_issue_discard)) {
err = PTR_ERR(dcc->f2fs_issue_discard);
dcc->f2fs_issue_discard = NULL;
-- 
1.9.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 error handling of __get_node_page

2023-10-18 Thread Zhiguo Niu
Use f2fs_handle_error to record inconsistent node block error
and return -EFSCORRUPTED instead of -EINVAL.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/node.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 248764b..ed963c56 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1467,7 +1467,8 @@ static struct page *__get_node_page(struct f2fs_sb_info 
*sbi, pgoff_t nid,
  ofs_of_node(page), cpver_of_node(page),
  next_blkaddr_of_node(page));
set_sbi_flag(sbi, SBI_NEED_FSCK);
-   err = -EINVAL;
+   f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER);
+   err = -EFSCORRUPTED;
 out_err:
ClearPageUptodate(page);
 out_put_err:
-- 
1.9.1



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


[f2fs-dev] [PATCH V2] f2fs: fix error path of __f2fs_build_free_nids

2023-10-16 Thread Zhiguo Niu
If NAT is corrupted, let scan_nat_page() return EFSCORRUPTED, so that,
caller can set SBI_NEED_FSCK flag into checkpoint for later repair by
fsck.

Also, this patch introduces a new fscorrupted error flag, and in above
scenario, it will persist the error flag into superblock synchronously
to avoid it has no luck to trigger a checkpoint to record SBI_NEED_FSCK

Signed-off-by: Zhiguo Niu 
Signed-off-by: Chao Yu 
---
changes of v2: Improve the patch according to Chao's suggestions.
---
---
 fs/f2fs/node.c  | 11 +--
 include/linux/f2fs_fs.h |  1 +
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index ee2e1dd..248764b 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2389,7 +2389,7 @@ static int scan_nat_page(struct f2fs_sb_info *sbi,
blk_addr = le32_to_cpu(nat_blk->entries[i].block_addr);
 
if (blk_addr == NEW_ADDR)
-   return -EINVAL;
+   return -EFSCORRUPTED;
 
if (blk_addr == NULL_ADDR) {
add_free_nid(sbi, start_nid, true, true);
@@ -2504,7 +2504,14 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info 
*sbi,
 
if (ret) {
f2fs_up_read(_i->nat_tree_lock);
-   f2fs_err(sbi, "NAT is corrupt, run fsck to fix 
it");
+
+   if (ret == -EFSCORRUPTED) {
+   f2fs_err(sbi, "NAT is corrupt, run fsck 
to fix it");
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_handle_error(sbi,
+   ERROR_INCONSISTENT_NAT);
+   }
+
return ret;
}
}
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index a82a4bb..cf1adce 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -104,6 +104,7 @@ enum f2fs_error {
ERROR_CORRUPTED_VERITY_XATTR,
ERROR_CORRUPTED_XATTR,
ERROR_INVALID_NODE_REFERENCE,
+   ERROR_INCONSISTENT_NAT,
ERROR_MAX,
 };
 
-- 
1.9.1



___
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 error path of __f2fs_build_free_nids

2023-10-16 Thread Zhiguo Niu
Dear Chao,

On Mon, Oct 16, 2023 at 5:07 PM Chao Yu  wrote:
>
> Zhiguo,
>
> On 2023/10/16 17:02, Zhiguo Niu wrote:
> > Dear Chao,
> >
> > On Mon, Oct 16, 2023 at 3:37 PM Chao Yu  wrote:
> >>
> >> On 2023/10/13 18:58, Zhiguo Niu wrote:
> >>> SBI_NEED_FSCK should be set for fsck has a chance to
> >>> repair in case of scan_nat_page fail in run time.
> >>>
> >>> Signed-off-by: Zhiguo Niu 
> >>
> >> Hi Zhiguo,
> >>
> >> Can you please check below update?
> >>
> >>   From 9a3459d2d62a12f8708d72aa7808a1def9f9d92f Mon Sep 17 00:00:00 2001
> >> From: Zhiguo Niu 
> >> Date: Fri, 13 Oct 2023 18:58:23 +0800
> >> Subject: [PATCH] f2fs: fix error path of __f2fs_build_free_nids
> >>
> >> If NAT is corrupted, let scan_nat_page() return EFSCORRUPTED, so that,
> >> caller can set SBI_NEED_FSCK flag into checkpoint for later repair by
> >> fsck.
> >>
> >> Also, this patch introduces a new fscorrupted error flag, and in above
> >> scenario, it will persist the error flag into superblock synchronously
> >> to avoid it has no luck to trigger a checkpoint to record SBI_NEED_FSCK.
> >>
> >> Signed-off-by: Zhiguo Niu 
> >> Signed-off-by: Chao Yu 
> >> ---
> >>fs/f2fs/node.c  | 11 +--
> >>include/linux/f2fs_fs.h |  1 +
> >>2 files changed, 10 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> >> index a2b2c6c7f66d..57d9dd3a43bc 100644
> >> --- a/fs/f2fs/node.c
> >> +++ b/fs/f2fs/node.c
> >> @@ -2389,7 +2389,7 @@ static int scan_nat_page(struct f2fs_sb_info *sbi,
> >>  blk_addr = le32_to_cpu(nat_blk->entries[i].block_addr);
> >>
> >>  if (blk_addr == NEW_ADDR)
> >> -   return -EINVAL;
> >> +   return -EFSCORRUPTED;
> >>
> >>  if (blk_addr == NULL_ADDR) {
> >>  add_free_nid(sbi, start_nid, true, true);
> >> @@ -2504,7 +2504,14 @@ static int __f2fs_build_free_nids(struct 
> >> f2fs_sb_info *sbi,
> >>
> >>  if (ret) {
> >>  f2fs_up_read(_i->nat_tree_lock);
> >> -   f2fs_err(sbi, "NAT is corrupt, run fsck to 
> >> fix it");
> >> +
> >> +   if (ret == -EFSCORRUPTED) {
> >> +   f2fs_err(sbi, "NAT is corrupt, run 
> >> fsck to fix it");
> >> +   set_sbi_flag(sbi, SBI_NEED_FSCK);
> >> +   f2fs_handle_error(sbi,
> >> +   
> >> ERROR_INCONSISTENT_NAT);
> >> +   }
> >> +
> >>  return ret;
> >>  }
> >>  }
> >> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> >> index 07ed69c2840d..039fe0ce8d83 100644
> >> --- a/include/linux/f2fs_fs.h
> >> +++ b/include/linux/f2fs_fs.h
> >> @@ -104,6 +104,7 @@ enum f2fs_error {
> >>  ERROR_CORRUPTED_VERITY_XATTR,
> >>  ERROR_CORRUPTED_XATTR,
> >>  ERROR_INVALID_NODE_REFERENCE,
> >> +   ERROR_INCONSISTENT_NAT,
> >>  ERROR_MAX,
> >>};
> >>
> >> --
> >> 2.40.1
> >
> > Thank you for your updates and these updates are more reasonable based
> > on the latest code.
> > In addition,  I also modified the following code after I checked the
> > related flow of f2fs_handle_error.
> > ERROR_INCONSISTENT_FOOTER is reused here,   any suggestions for this?
> > diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> > index d9e6087..94f5c7f 100644
> > --- a/fs/f2fs/node.c
> > +++ b/fs/f2fs/node.c
> > @@ -1467,6 +1467,7 @@ static struct page *__get_node_page(struct
> > f2fs_sb_info *sbi, pgoff_t nid,
> >ofs_of_node(page), cpver_of_node(page),
> >next_blkaddr_of_node(page));
> >  set_sbi_flag(sbi, SBI_NEED_FSCK);
> > +   f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER);
> >  err = -EINVAL;
>
> err = -EFSCORRUPTED;
>
> >   out_err:
> >  ClearPageUptodate(page);
> >
> > If you have no other suggestions, I will update the "PATCH V2"
>
> How about changing above code in separated patch?
OK, I will do this as your suggestions.
Thanks!
>
> Thanks,
>
>  > Thanks!


___
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 error path of __f2fs_build_free_nids

2023-10-16 Thread Zhiguo Niu
Dear Chao,

On Mon, Oct 16, 2023 at 3:37 PM Chao Yu  wrote:
>
> On 2023/10/13 18:58, Zhiguo Niu wrote:
> > SBI_NEED_FSCK should be set for fsck has a chance to
> > repair in case of scan_nat_page fail in run time.
> >
> > Signed-off-by: Zhiguo Niu 
>
> Hi Zhiguo,
>
> Can you please check below update?
>
>  From 9a3459d2d62a12f8708d72aa7808a1def9f9d92f Mon Sep 17 00:00:00 2001
> From: Zhiguo Niu 
> Date: Fri, 13 Oct 2023 18:58:23 +0800
> Subject: [PATCH] f2fs: fix error path of __f2fs_build_free_nids
>
> If NAT is corrupted, let scan_nat_page() return EFSCORRUPTED, so that,
> caller can set SBI_NEED_FSCK flag into checkpoint for later repair by
> fsck.
>
> Also, this patch introduces a new fscorrupted error flag, and in above
> scenario, it will persist the error flag into superblock synchronously
> to avoid it has no luck to trigger a checkpoint to record SBI_NEED_FSCK.
>
> Signed-off-by: Zhiguo Niu 
> Signed-off-by: Chao Yu 
> ---
>   fs/f2fs/node.c  | 11 +--
>   include/linux/f2fs_fs.h |  1 +
>   2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index a2b2c6c7f66d..57d9dd3a43bc 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -2389,7 +2389,7 @@ static int scan_nat_page(struct f2fs_sb_info *sbi,
> blk_addr = le32_to_cpu(nat_blk->entries[i].block_addr);
>
> if (blk_addr == NEW_ADDR)
> -   return -EINVAL;
> +   return -EFSCORRUPTED;
>
> if (blk_addr == NULL_ADDR) {
> add_free_nid(sbi, start_nid, true, true);
> @@ -2504,7 +2504,14 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info 
> *sbi,
>
> if (ret) {
> f2fs_up_read(_i->nat_tree_lock);
> -   f2fs_err(sbi, "NAT is corrupt, run fsck to 
> fix it");
> +
> +   if (ret == -EFSCORRUPTED) {
> +   f2fs_err(sbi, "NAT is corrupt, run 
> fsck to fix it");
> +   set_sbi_flag(sbi, SBI_NEED_FSCK);
> +   f2fs_handle_error(sbi,
> +   
> ERROR_INCONSISTENT_NAT);
> +   }
> +
> return ret;
> }
> }
> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> index 07ed69c2840d..039fe0ce8d83 100644
> --- a/include/linux/f2fs_fs.h
> +++ b/include/linux/f2fs_fs.h
> @@ -104,6 +104,7 @@ enum f2fs_error {
> ERROR_CORRUPTED_VERITY_XATTR,
> ERROR_CORRUPTED_XATTR,
> ERROR_INVALID_NODE_REFERENCE,
> +   ERROR_INCONSISTENT_NAT,
> ERROR_MAX,
>   };
>
> --
> 2.40.1

Thank you for your updates and these updates are more reasonable based
on the latest code.
In addition,  I also modified the following code after I checked the
related flow of f2fs_handle_error.
ERROR_INCONSISTENT_FOOTER is reused here,   any suggestions for this?
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index d9e6087..94f5c7f 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1467,6 +1467,7 @@ static struct page *__get_node_page(struct
f2fs_sb_info *sbi, pgoff_t nid,
  ofs_of_node(page), cpver_of_node(page),
  next_blkaddr_of_node(page));
set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER);
err = -EINVAL;
 out_err:
ClearPageUptodate(page);

If you have no other suggestions, I will update the "PATCH V2"
Thanks!


___
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 error path of __f2fs_build_free_nids

2023-10-13 Thread Zhiguo Niu
SBI_NEED_FSCK should be set for fsck has a chance to
repair in case of scan_nat_page fail in run time.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/node.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index ee2e1dd..d9e6087 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2499,12 +2499,15 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info 
*sbi,
ret = PTR_ERR(page);
} else {
ret = scan_nat_page(sbi, page, nid);
+   if (ret && !mount) {
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_err(sbi, "NAT is corrupt, run fsck 
to fix it");
+   }
f2fs_put_page(page, 1);
}
 
if (ret) {
f2fs_up_read(_i->nat_tree_lock);
-   f2fs_err(sbi, "NAT is corrupt, run fsck to fix 
it");
return ret;
}
}
-- 
1.9.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: should update REQ_TIME for direct write

2023-08-10 Thread Zhiguo Niu
The sending interval of discard and GC should also
consider direct write requests; filesystem is not
idle if there is direct write.

Signed-off-by: Zhiguo Niu 
---
 fs/f2fs/file.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 5ac53d2627d2..713a2d98728a 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -4537,6 +4537,7 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, 
ssize_t size, int error,
dec_page_count(sbi, F2FS_DIO_WRITE);
if (error)
return error;
+   f2fs_update_time(sbi, REQ_TIME);
f2fs_update_iostat(sbi, NULL, APP_DIRECT_IO, size);
return 0;
 }
-- 
2.37.3



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