Re: [f2fs-dev] [PATCH] f2fs: fix false alarm on invalid block address

2024-05-23 Thread Jaegeuk Kim
Fixed the stable mailing list.

On 05/23, Jaegeuk Kim wrote:
> Hi Greg,
> 
> Could you please consider to cherry-pick this patch in stable-6.9, since
> there are many users suffering from unnecessary fsck runs during boot?
> 
> You can get this from Linus's tree by
> (b864ddb57eb0 "f2fs: fix false alarm on invalid block address")
> 
> Thanks,
> 
> On 05/20, Jaegeuk Kim wrote:
> > f2fs_ra_meta_pages can try to read ahead on invalid block address which is
> > not the corruption case.
> > 
> > Cc:  # v6.9+
> > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218770
> > Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of 
> > f2fs_is_valid_blkaddr")
> > Reviewed-by: Chao Yu 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >  fs/f2fs/checkpoint.c | 9 +
> >  1 file changed, 5 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index 5d05a413f451..55d444bec5c0 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct 
> > f2fs_sb_info *sbi,
> > break;
> > case META_SIT:
> > if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case META_SSA:
> > if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
> > blkaddr < SM_I(sbi)->ssa_blkaddr))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case META_CP:
> > if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
> > blkaddr < __start_cp_addr(sbi)))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case META_POR:
> > if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
> > blkaddr < MAIN_BLKADDR(sbi)))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case DATA_GENERIC:
> > case DATA_GENERIC_ENHANCE:
> > @@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
> > *sbi,
> > return true;
> >  err:
> > f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> > +check_only:
> > return false;
> >  }
> >  
> > -- 
> > 2.45.0.rc1.225.g2a3ae87e7f-goog


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


Re: [f2fs-dev] [PATCH] f2fs: fix false alarm on invalid block address

2024-05-23 Thread Jaegeuk Kim
Hi Greg,

Could you please consider to cherry-pick this patch in stable-6.9, since
there are many users suffering from unnecessary fsck runs during boot?

You can get this from Linus's tree by
(b864ddb57eb0 "f2fs: fix false alarm on invalid block address")

Thanks,

On 05/20, Jaegeuk Kim wrote:
> f2fs_ra_meta_pages can try to read ahead on invalid block address which is
> not the corruption case.
> 
> Cc:  # v6.9+
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218770
> Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of 
> f2fs_is_valid_blkaddr")
> Reviewed-by: Chao Yu 
> Signed-off-by: Jaegeuk Kim 
> ---
>  fs/f2fs/checkpoint.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index 5d05a413f451..55d444bec5c0 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
> *sbi,
>   break;
>   case META_SIT:
>   if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> - goto err;
> + goto check_only;
>   break;
>   case META_SSA:
>   if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
>   blkaddr < SM_I(sbi)->ssa_blkaddr))
> - goto err;
> + goto check_only;
>   break;
>   case META_CP:
>   if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
>   blkaddr < __start_cp_addr(sbi)))
> - goto err;
> + goto check_only;
>   break;
>   case META_POR:
>   if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
>   blkaddr < MAIN_BLKADDR(sbi)))
> - goto err;
> + goto check_only;
>   break;
>   case DATA_GENERIC:
>   case DATA_GENERIC_ENHANCE:
> @@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
> *sbi,
>   return true;
>  err:
>   f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> +check_only:
>   return false;
>  }
>  
> -- 
> 2.45.0.rc1.225.g2a3ae87e7f-goog


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


[f2fs-dev] [PATCH] f2fs: fix false alarm on invalid block address

2024-05-20 Thread Jaegeuk Kim
f2fs_ra_meta_pages can try to read ahead on invalid block address which is
not the corruption case.

Cc:  # v6.9+
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218770
Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of f2fs_is_valid_blkaddr")
Reviewed-by: Chao Yu 
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5d05a413f451..55d444bec5c0 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   goto err;
+   goto check_only;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   goto err;
+   goto check_only;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   goto err;
+   goto check_only;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   goto err;
+   goto check_only;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
return true;
 err:
f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+check_only:
return false;
 }
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



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


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

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

>   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] [GIT PULL] f2fs update for 6.10-rc1

2024-05-20 Thread Jaegeuk Kim
Hi Linus,

Could you please consider this pull reuqest?

Thanks,

The following changes since commit 928a87efa42302a23bb9554be081a28058495f22:

  Merge tag 'gfs2-v6.8-fix' of 
git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2 (2024-03-25 
10:53:39 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git 
tags/f2fs-for-6.10.rc1

for you to fetch changes up to 16409fdbb8828d7ae829bc4ac4e09e7ff02f8878:

  f2fs: initialize last_block_in_bio variable (2024-05-15 04:18:40 +)


f2fs update for 6.10-rc1

In this round, we've tried to address some performance issues on zoned storage
such as direct IO and write_hints. In addition, we've migrated some IO paths
using folio. Meanwhile, there are multiple bug fixes in the compression paths,
sanity check conditions, and error handlers.

Enhancement:
 - allow direct io of pinned files for zoned storage
 - assign the write hint per stream by default
 - convert read paths and test_writeback to folio
 - avoid allocating WARM_DATA segment for direct IO

Bug fix:
 - fix false alarm on invalid block address
 - fix to add missing iput() in gc_data_segment()
 - fix to release node block count in error path of f2fs_new_node_page()
 - compress: don't allow unaligned truncation on released compress inode
 - compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem lock
 - compress: fix error path of inc_valid_block_count()
 - compress: fix to update i_compr_blocks correctly
 - fix block migration when section is not aligned to pow2
 - don't trigger OPU on pinfile for direct IO
 - fix to do sanity check on i_xattr_nid in sanity_check_inode()
 - write missing last sum blk of file pinning section
 - clear writeback when compression failed
 - fix to adjust appropirate defragment pg_end

As usual, there are several minor code clean-ups, and fixes to manage missing
corner cases in the error paths.


Chao Yu (30):
  f2fs: support .shutdown in f2fs_sops
  f2fs: fix to detect inconsistent nat entry during truncation
  f2fs: introduce map_is_mergeable() for cleanup
  f2fs: multidev: fix to recognize valid zero block address
  f2fs: support to map continuous holes or preallocated address
  f2fs: fix to wait on page writeback in __clone_blkaddrs()
  f2fs: compress: fix to relocate check condition in 
f2fs_{release,reserve}_compress_blocks()
  f2fs: compress: fix to relocate check condition in 
f2fs_ioc_{,de}compress_file()
  f2fs: fix to relocate check condition in f2fs_fallocate()
  f2fs: fix to check pinfile flag in f2fs_move_file_range()
  f2fs: convert f2fs_mpage_readpages() to use folio
  f2fs: convert f2fs_read_single_page() to use folio
  f2fs: convert f2fs_read_inline_data() to use folio
  f2fs: convert f2fs__page tracepoint class to use folio
  f2fs: fix comment in sanity_check_raw_super()
  f2fs: remove unnecessary block size check in init_f2fs_fs()
  f2fs: fix to avoid allocating WARM_DATA segment for direct IO
  f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode()
  f2fs: zone: fix to don't trigger OPU on pinfile for direct IO
  f2fs: use f2fs_{err,info}_ratelimited() for cleanup
  f2fs: remove unused GC_FAILURE_PIN
  f2fs: fix to limit gc_pin_file_threshold
  f2fs: check validation of fault attrs in f2fs_build_fault_attr()
  f2fs: compress: fix to update i_compr_blocks correctly
  f2fs: compress: fix typo in f2fs_reserve_compress_blocks()
  f2fs: compress: fix error path of inc_valid_block_count()
  f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ 
cp_rwsem lock
  f2fs: fix to release node block count in error path of 
f2fs_new_node_page()
  f2fs: compress: don't allow unaligned truncation on released compress 
inode
  f2fs: fix to add missing iput() in gc_data_segment()

Daeho Jeong (4):
  f2fs: write missing last sum blk of file pinning section
  f2fs: prevent writing without fallocate() for pinned files
  f2fs: allow direct io of pinned files for zoned storage
  f2fs: allow dirty sections with zero valid block for checkpoint disabled

Jaegeuk Kim (5):
  f2fs: don't set RO when shutting down f2fs
  f2fs: use folio_test_writeback
  f2fs: assign the write hint per stream by default
  f2fs: clear writeback when compression failed
  f2fs: fix false alarm on invalid block address

Nathan Chancellor (1):
  f2fs: Add inline to f2fs_build_fault_attr() stub

Wenjie Qi (1):
  f2fs: fix zoned block device information initialization

Wu Bo (3):
  f2fs: use helper to print zone condition
  f2fs: fix block migration when section is not aligned to pow2
  f2fs: initialize last_block_in_bio variable

Yeongjin Gil (1):
  f2fs: Prevent s_writer rw_sem count mismatch

Re: [f2fs-dev] [PATCH 3/3] f2fs: fix to do sanity check on i_nid for inline_data inode

2024-05-20 Thread Jaegeuk Kim
On 05/15, Chao Yu wrote:
> On 2024/5/15 12:39, Jaegeuk Kim wrote:
> > On 05/15, Chao Yu wrote:
> > > On 2024/5/15 0:07, Jaegeuk Kim wrote:
> > > > 外部邮件/External Mail
> > > > 
> > > > 
> > > > On 05/11, Chao Yu wrote:
> > > > > On 2024/5/11 8:38, Jaegeuk Kim wrote:
> > > > > > On 05/10, Chao Yu wrote:
> > > > > > > On 2024/5/10 11:36, Jaegeuk Kim wrote:
> > > > > > > > On 05/10, Chao Yu wrote:
> > > > > > > > > On 2024/5/9 23:52, Jaegeuk Kim wrote:
> > > > > > > > > > On 05/06, Chao Yu wrote:
> > > > > > > > > > > syzbot reports a f2fs bug as below:
> > > > > > > > > > > 
> > > > > > > > > > > [ cut here ]
> > > > > > > > > > > kernel BUG at fs/f2fs/inline.c:258!
> > > > > > > > > > > CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 
> > > > > > > > > > > 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
> > > > > > > > > > > RIP: 0010:f2fs_write_inline_data+0x781/0x790 
> > > > > > > > > > > fs/f2fs/inline.c:258
> > > > > > > > > > > Call Trace:
> > > > > > > > > > >   f2fs_write_single_data_page+0xb65/0x1d60 
> > > > > > > > > > > fs/f2fs/data.c:2834
> > > > > > > > > > >   f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
> > > > > > > > > > >   __f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
> > > > > > > > > > >   f2fs_write_data_pages+0x1efe/0x3a90 
> > > > > > > > > > > fs/f2fs/data.c:3315
> > > > > > > > > > >   do_writepages+0x35b/0x870 mm/page-writeback.c:2612
> > > > > > > > > > >   __writeback_single_inode+0x165/0x10b0 
> > > > > > > > > > > fs/fs-writeback.c:1650
> > > > > > > > > > >   writeback_sb_inodes+0x905/0x1260 
> > > > > > > > > > > fs/fs-writeback.c:1941
> > > > > > > > > > >   wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
> > > > > > > > > > >   wb_do_writeback fs/fs-writeback.c:2264 [inline]
> > > > > > > > > > >   wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
> > > > > > > > > > >   process_one_work kernel/workqueue.c:3254 [inline]
> > > > > > > > > > >   process_scheduled_works+0xa12/0x17c0 
> > > > > > > > > > > kernel/workqueue.c:3335
> > > > > > > > > > >   worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
> > > > > > > > > > >   kthread+0x2f2/0x390 kernel/kthread.c:388
> > > > > > > > > > >   ret_from_fork+0x4d/0x80 
> > > > > > > > > > > arch/x86/kernel/process.c:147
> > > > > > > > > > >   ret_from_fork_asm+0x1a/0x30 
> > > > > > > > > > > arch/x86/entry/entry_64.S:244
> > > > > > > > > > > 
> > > > > > > > > > > The root cause is: inline_data inode can be fuzzed, so 
> > > > > > > > > > > that there may
> > > > > > > > > > > be valid blkaddr in its direct node, once f2fs triggers 
> > > > > > > > > > > background GC
> > > > > > > > > > > to migrate the block, it will hit f2fs_bug_on() during 
> > > > > > > > > > > dirty page
> > > > > > > > > > > writeback.
> > > > > > > > > > > 
> > > > > > > > > > > Let's add sanity check on i_nid field for inline_data 
> > > > > > > > > > > inode, meanwhile,
> > > > > > > > > > > forbid to migrate inline_data inode's data block to fix 
> > > > > > > > > > > this issue.
> > > > > > > > > > > 
> > > > > > > > > > > Reported-by: 
> > > > > > > > > > > syzbot+848062ba19c8782ca...@syzkaller.appspotma

Re: [f2fs-dev] [PATCH v2] f2fs: fix to avoid racing in between read and OPU dio write

2024-05-14 Thread Jaegeuk Kim
On 05/15, Chao Yu wrote:
> On 2024/5/15 0:09, Jaegeuk Kim wrote:
> > On 05/10, Chao Yu wrote:
> > > If lfs mode is on, buffered read may race w/ OPU dio write as below,
> > > it may cause buffered read hits unwritten data unexpectly, and for
> > > dio read, the race condition exists as well.
> > > 
> > > Thread A  Thread B
> > > - f2fs_file_write_iter
> > >   - f2fs_dio_write_iter
> > >- __iomap_dio_rw
> > > - f2fs_iomap_begin
> > >  - f2fs_map_blocks
> > >   - __allocate_data_block
> > >- allocated blkaddr #x
> > > - iomap_dio_submit_bio
> > >- f2fs_file_read_iter
> > > - filemap_read
> > >  - f2fs_read_data_folio
> > >   - f2fs_mpage_readpages
> > >- f2fs_map_blocks
> > > : get blkaddr #x
> > >- f2fs_submit_read_bio
> > >IRQ
> > >- f2fs_read_end_io
> > > : read IO on blkaddr #x complete
> > > IRQ
> > > - iomap_dio_bio_end_io
> > >   : direct write IO on blkaddr #x complete
> > > 
> > > This patch introduces a new per-inode i_opu_rwsem lock to avoid
> > > such race condition.
> > 
> > Wasn't this supposed to be managed by user-land?
> 
> Actually, the test case is:
> 
> 1. mount w/ lfs mode
> 2. touch file;
> 3. initialize file w/ 4k zeroed data; fsync;
> 4. continue triggering dio write 4k zeroed data to file;
> 5. and meanwhile, continue triggering buf/dio 4k read in file,
> use md5sum to verify the 4k data;
> 
> It expects data is all zero, however it turned out it's not.

Can we check outstanding write bios instead of abusing locks?

> 
> Thanks,
> 
> > 
> > > 
> > > Fixes: f847c699cff3 ("f2fs: allow out-place-update for direct IO in LFS 
> > > mode")
> > > Signed-off-by: Chao Yu 
> > > ---
> > > v2:
> > > - fix to cover dio read path w/ i_opu_rwsem as well.
> > >   fs/f2fs/f2fs.h  |  1 +
> > >   fs/f2fs/file.c  | 28 ++--
> > >   fs/f2fs/super.c |  1 +
> > >   3 files changed, 28 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > > index 30058e16a5d0..91cf4b3d6bc6 100644
> > > --- a/fs/f2fs/f2fs.h
> > > +++ b/fs/f2fs/f2fs.h
> > > @@ -847,6 +847,7 @@ struct f2fs_inode_info {
> > >/* avoid racing between foreground op and gc */
> > >struct f2fs_rwsem i_gc_rwsem[2];
> > >struct f2fs_rwsem i_xattr_sem; /* avoid racing between reading and 
> > > changing EAs */
> > > + struct f2fs_rwsem i_opu_rwsem;  /* avoid racing between buf read 
> > > and opu dio write */
> > > 
> > >int i_extra_isize;  /* size of extra space located in 
> > > i_addr */
> > >kprojid_t i_projid; /* id for project quota */
> > > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > > index 72ce1a522fb2..4ec260af321f 100644
> > > --- a/fs/f2fs/file.c
> > > +++ b/fs/f2fs/file.c
> > > @@ -4445,6 +4445,7 @@ static ssize_t f2fs_dio_read_iter(struct kiocb 
> > > *iocb, struct iov_iter *to)
> > >const loff_t pos = iocb->ki_pos;
> > >const size_t count = iov_iter_count(to);
> > >struct iomap_dio *dio;
> > > + bool do_opu = f2fs_lfs_mode(sbi);
> > >ssize_t ret;
> > > 
> > >if (count == 0)
> > > @@ -4457,8 +4458,14 @@ static ssize_t f2fs_dio_read_iter(struct kiocb 
> > > *iocb, struct iov_iter *to)
> > >ret = -EAGAIN;
> > >goto out;
> > >}
> > > + if (do_opu && !f2fs_down_read_trylock(>i_opu_rwsem)) {
> > > + f2fs_up_read(>i_gc_rwsem[READ]);
> > > + ret = -EAGAIN;
> > > + goto out;
> > > + }
> > >} else {
> > >f2fs_down_read(>i_gc_rwsem[READ]);
> > > + f2fs_down_read(>i_opu_rwsem);
> > >}
> > > 
> > >/*
> > > @@ -4477,6 +4484,7 @@ static ssize_t

Re: [f2fs-dev] [PATCH 3/3] f2fs: fix to do sanity check on i_nid for inline_data inode

2024-05-14 Thread Jaegeuk Kim
On 05/15, Chao Yu wrote:
> On 2024/5/15 0:07, Jaegeuk Kim wrote:
> > 外部邮件/External Mail
> > 
> > 
> > On 05/11, Chao Yu wrote:
> > > On 2024/5/11 8:38, Jaegeuk Kim wrote:
> > > > On 05/10, Chao Yu wrote:
> > > > > On 2024/5/10 11:36, Jaegeuk Kim wrote:
> > > > > > On 05/10, Chao Yu wrote:
> > > > > > > On 2024/5/9 23:52, Jaegeuk Kim wrote:
> > > > > > > > On 05/06, Chao Yu wrote:
> > > > > > > > > syzbot reports a f2fs bug as below:
> > > > > > > > > 
> > > > > > > > > [ cut here ]
> > > > > > > > > kernel BUG at fs/f2fs/inline.c:258!
> > > > > > > > > CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 
> > > > > > > > > 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
> > > > > > > > > RIP: 0010:f2fs_write_inline_data+0x781/0x790 
> > > > > > > > > fs/f2fs/inline.c:258
> > > > > > > > > Call Trace:
> > > > > > > > >  f2fs_write_single_data_page+0xb65/0x1d60 
> > > > > > > > > fs/f2fs/data.c:2834
> > > > > > > > >  f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
> > > > > > > > >  __f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
> > > > > > > > >  f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3315
> > > > > > > > >  do_writepages+0x35b/0x870 mm/page-writeback.c:2612
> > > > > > > > >  __writeback_single_inode+0x165/0x10b0 
> > > > > > > > > fs/fs-writeback.c:1650
> > > > > > > > >  writeback_sb_inodes+0x905/0x1260 fs/fs-writeback.c:1941
> > > > > > > > >  wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
> > > > > > > > >  wb_do_writeback fs/fs-writeback.c:2264 [inline]
> > > > > > > > >  wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
> > > > > > > > >  process_one_work kernel/workqueue.c:3254 [inline]
> > > > > > > > >  process_scheduled_works+0xa12/0x17c0 
> > > > > > > > > kernel/workqueue.c:3335
> > > > > > > > >  worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
> > > > > > > > >  kthread+0x2f2/0x390 kernel/kthread.c:388
> > > > > > > > >  ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
> > > > > > > > >  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> > > > > > > > > 
> > > > > > > > > The root cause is: inline_data inode can be fuzzed, so that 
> > > > > > > > > there may
> > > > > > > > > be valid blkaddr in its direct node, once f2fs triggers 
> > > > > > > > > background GC
> > > > > > > > > to migrate the block, it will hit f2fs_bug_on() during dirty 
> > > > > > > > > page
> > > > > > > > > writeback.
> > > > > > > > > 
> > > > > > > > > Let's add sanity check on i_nid field for inline_data inode, 
> > > > > > > > > meanwhile,
> > > > > > > > > forbid to migrate inline_data inode's data block to fix this 
> > > > > > > > > issue.
> > > > > > > > > 
> > > > > > > > > Reported-by: 
> > > > > > > > > syzbot+848062ba19c8782ca...@syzkaller.appspotmail.com
> > > > > > > > > Closes: 
> > > > > > > > > https://lore.kernel.org/linux-f2fs-devel/d103ce06174d7...@google.com
> > > > > > > > > Signed-off-by: Chao Yu 
> > > > > > > > > ---
> > > > > > > > >  fs/f2fs/f2fs.h   |  2 +-
> > > > > > > > >  fs/f2fs/gc.c |  6 ++
> > > > > > > > >  fs/f2fs/inline.c | 17 -
> > > > > > > > >  fs/f2fs/inode.c  |  2 +-
> > > > > > > > >  4 files changed, 24 insertions(+), 3 deletions(-)
> > > > > > > > > 
> > > > > > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2

Re: [f2fs-dev] [PATCH v2] f2fs: fix to avoid racing in between read and OPU dio write

2024-05-14 Thread Jaegeuk Kim
On 05/10, Chao Yu wrote:
> If lfs mode is on, buffered read may race w/ OPU dio write as below,
> it may cause buffered read hits unwritten data unexpectly, and for
> dio read, the race condition exists as well.
> 
> Thread A  Thread B
> - f2fs_file_write_iter
>  - f2fs_dio_write_iter
>   - __iomap_dio_rw
>- f2fs_iomap_begin
> - f2fs_map_blocks
>  - __allocate_data_block
>   - allocated blkaddr #x
>- iomap_dio_submit_bio
>   - f2fs_file_read_iter
>- filemap_read
> - f2fs_read_data_folio
>  - f2fs_mpage_readpages
>   - f2fs_map_blocks
>: get blkaddr #x
>   - f2fs_submit_read_bio
>   IRQ
>   - f2fs_read_end_io
>: read IO on blkaddr #x complete
> IRQ
> - iomap_dio_bio_end_io
>  : direct write IO on blkaddr #x complete
> 
> This patch introduces a new per-inode i_opu_rwsem lock to avoid
> such race condition.

Wasn't this supposed to be managed by user-land?

> 
> Fixes: f847c699cff3 ("f2fs: allow out-place-update for direct IO in LFS mode")
> Signed-off-by: Chao Yu 
> ---
> v2:
> - fix to cover dio read path w/ i_opu_rwsem as well.
>  fs/f2fs/f2fs.h  |  1 +
>  fs/f2fs/file.c  | 28 ++--
>  fs/f2fs/super.c |  1 +
>  3 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 30058e16a5d0..91cf4b3d6bc6 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -847,6 +847,7 @@ struct f2fs_inode_info {
>   /* avoid racing between foreground op and gc */
>   struct f2fs_rwsem i_gc_rwsem[2];
>   struct f2fs_rwsem i_xattr_sem; /* avoid racing between reading and 
> changing EAs */
> + struct f2fs_rwsem i_opu_rwsem;  /* avoid racing between buf read and 
> opu dio write */
>  
>   int i_extra_isize;  /* size of extra space located in 
> i_addr */
>   kprojid_t i_projid; /* id for project quota */
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 72ce1a522fb2..4ec260af321f 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -4445,6 +4445,7 @@ static ssize_t f2fs_dio_read_iter(struct kiocb *iocb, 
> struct iov_iter *to)
>   const loff_t pos = iocb->ki_pos;
>   const size_t count = iov_iter_count(to);
>   struct iomap_dio *dio;
> + bool do_opu = f2fs_lfs_mode(sbi);
>   ssize_t ret;
>  
>   if (count == 0)
> @@ -4457,8 +4458,14 @@ static ssize_t f2fs_dio_read_iter(struct kiocb *iocb, 
> struct iov_iter *to)
>   ret = -EAGAIN;
>   goto out;
>   }
> + if (do_opu && !f2fs_down_read_trylock(>i_opu_rwsem)) {
> + f2fs_up_read(>i_gc_rwsem[READ]);
> + ret = -EAGAIN;
> + goto out;
> + }
>   } else {
>   f2fs_down_read(>i_gc_rwsem[READ]);
> + f2fs_down_read(>i_opu_rwsem);
>   }
>  
>   /*
> @@ -4477,6 +4484,7 @@ static ssize_t f2fs_dio_read_iter(struct kiocb *iocb, 
> struct iov_iter *to)
>   ret = iomap_dio_complete(dio);
>   }
>  
> + f2fs_up_read(>i_opu_rwsem);
>   f2fs_up_read(>i_gc_rwsem[READ]);
>  
>   file_accessed(file);
> @@ -4523,7 +4531,13 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, 
> struct iov_iter *to)
>   if (f2fs_should_use_dio(inode, iocb, to)) {
>   ret = f2fs_dio_read_iter(iocb, to);
>   } else {
> + bool do_opu = f2fs_lfs_mode(F2FS_I_SB(inode));
> +
> + if (do_opu)
> + f2fs_down_read(_I(inode)->i_opu_rwsem);
>   ret = filemap_read(iocb, to, 0);
> + if (do_opu)
> + f2fs_up_read(_I(inode)->i_opu_rwsem);
>   if (ret > 0)
>   f2fs_update_iostat(F2FS_I_SB(inode), inode,
>   APP_BUFFERED_READ_IO, ret);
> @@ -4748,14 +4762,22 @@ static ssize_t f2fs_dio_write_iter(struct kiocb 
> *iocb, struct iov_iter *from,
>   ret = -EAGAIN;
>   goto out;
>   }
> + if (do_opu && !f2fs_down_write_trylock(>i_opu_rwsem)) {
> + f2fs_up_read(>i_gc_rwsem[READ]);
> + f2fs_up_read(>i_gc_rwsem[WRITE]);
> + ret = -EAGAIN;
> + goto out;
> + }
>   } else {
>   ret = f2fs_convert_inline_inode(inode);
>   if (ret)
>   goto out;
>  
>   f2fs_down_read(>i_gc_rwsem[WRITE]);
> - if (do_opu)
> + if (do_opu) {
>   f2fs_down_read(>i_gc_rwsem[READ]);
> + f2fs_down_write(>i_opu_rwsem);
> 

Re: [f2fs-dev] [PATCH 3/3] f2fs: fix to do sanity check on i_nid for inline_data inode

2024-05-14 Thread Jaegeuk Kim
On 05/11, Chao Yu wrote:
> On 2024/5/11 8:38, Jaegeuk Kim wrote:
> > On 05/10, Chao Yu wrote:
> > > On 2024/5/10 11:36, Jaegeuk Kim wrote:
> > > > On 05/10, Chao Yu wrote:
> > > > > On 2024/5/9 23:52, Jaegeuk Kim wrote:
> > > > > > On 05/06, Chao Yu wrote:
> > > > > > > syzbot reports a f2fs bug as below:
> > > > > > > 
> > > > > > > [ cut here ]
> > > > > > > kernel BUG at fs/f2fs/inline.c:258!
> > > > > > > CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 
> > > > > > > 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
> > > > > > > RIP: 0010:f2fs_write_inline_data+0x781/0x790 fs/f2fs/inline.c:258
> > > > > > > Call Trace:
> > > > > > > f2fs_write_single_data_page+0xb65/0x1d60 fs/f2fs/data.c:2834
> > > > > > > f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
> > > > > > > __f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
> > > > > > > f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3315
> > > > > > > do_writepages+0x35b/0x870 mm/page-writeback.c:2612
> > > > > > > __writeback_single_inode+0x165/0x10b0 fs/fs-writeback.c:1650
> > > > > > > writeback_sb_inodes+0x905/0x1260 fs/fs-writeback.c:1941
> > > > > > > wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
> > > > > > > wb_do_writeback fs/fs-writeback.c:2264 [inline]
> > > > > > > wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
> > > > > > > process_one_work kernel/workqueue.c:3254 [inline]
> > > > > > > process_scheduled_works+0xa12/0x17c0 kernel/workqueue.c:3335
> > > > > > > worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
> > > > > > > kthread+0x2f2/0x390 kernel/kthread.c:388
> > > > > > > ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
> > > > > > > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> > > > > > > 
> > > > > > > The root cause is: inline_data inode can be fuzzed, so that there 
> > > > > > > may
> > > > > > > be valid blkaddr in its direct node, once f2fs triggers 
> > > > > > > background GC
> > > > > > > to migrate the block, it will hit f2fs_bug_on() during dirty page
> > > > > > > writeback.
> > > > > > > 
> > > > > > > Let's add sanity check on i_nid field for inline_data inode, 
> > > > > > > meanwhile,
> > > > > > > forbid to migrate inline_data inode's data block to fix this 
> > > > > > > issue.
> > > > > > > 
> > > > > > > Reported-by: syzbot+848062ba19c8782ca...@syzkaller.appspotmail.com
> > > > > > > Closes: 
> > > > > > > https://lore.kernel.org/linux-f2fs-devel/d103ce06174d7...@google.com
> > > > > > > Signed-off-by: Chao Yu 
> > > > > > > ---
> > > > > > > fs/f2fs/f2fs.h   |  2 +-
> > > > > > > fs/f2fs/gc.c |  6 ++
> > > > > > > fs/f2fs/inline.c | 17 -
> > > > > > > fs/f2fs/inode.c  |  2 +-
> > > > > > > 4 files changed, 24 insertions(+), 3 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > > > > > > index fced2b7652f4..c876813b5532 100644
> > > > > > > --- a/fs/f2fs/f2fs.h
> > > > > > > +++ b/fs/f2fs/f2fs.h
> > > > > > > @@ -4146,7 +4146,7 @@ extern struct kmem_cache 
> > > > > > > *f2fs_inode_entry_slab;
> > > > > > >  * inline.c
> > > > > > >  */
> > > > > > > bool f2fs_may_inline_data(struct inode *inode);
> > > > > > > -bool f2fs_sanity_check_inline_data(struct inode *inode);
> > > > > > > +bool f2fs_sanity_check_inline_data(struct inode *inode, struct 
> > > > > > > page *ipage);
> > > > > > > bool f2fs_may_inline_dentry(struct inode *inode);
> > > > > > > void f2fs_do_read_inline_data(struct page *page, struct page 
> > > > > > > *ipage);

Re: [f2fs-dev] [PATCH 3/3] f2fs: fix to do sanity check on i_nid for inline_data inode

2024-05-10 Thread Jaegeuk Kim
On 05/10, Chao Yu wrote:
> On 2024/5/10 11:36, Jaegeuk Kim wrote:
> > On 05/10, Chao Yu wrote:
> > > On 2024/5/9 23:52, Jaegeuk Kim wrote:
> > > > On 05/06, Chao Yu wrote:
> > > > > syzbot reports a f2fs bug as below:
> > > > > 
> > > > > [ cut here ]
> > > > > kernel BUG at fs/f2fs/inline.c:258!
> > > > > CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 
> > > > > 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
> > > > > RIP: 0010:f2fs_write_inline_data+0x781/0x790 fs/f2fs/inline.c:258
> > > > > Call Trace:
> > > > >f2fs_write_single_data_page+0xb65/0x1d60 fs/f2fs/data.c:2834
> > > > >f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
> > > > >__f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
> > > > >f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3315
> > > > >do_writepages+0x35b/0x870 mm/page-writeback.c:2612
> > > > >__writeback_single_inode+0x165/0x10b0 fs/fs-writeback.c:1650
> > > > >writeback_sb_inodes+0x905/0x1260 fs/fs-writeback.c:1941
> > > > >wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
> > > > >wb_do_writeback fs/fs-writeback.c:2264 [inline]
> > > > >wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
> > > > >process_one_work kernel/workqueue.c:3254 [inline]
> > > > >process_scheduled_works+0xa12/0x17c0 kernel/workqueue.c:3335
> > > > >worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
> > > > >kthread+0x2f2/0x390 kernel/kthread.c:388
> > > > >ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
> > > > >ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> > > > > 
> > > > > The root cause is: inline_data inode can be fuzzed, so that there may
> > > > > be valid blkaddr in its direct node, once f2fs triggers background GC
> > > > > to migrate the block, it will hit f2fs_bug_on() during dirty page
> > > > > writeback.
> > > > > 
> > > > > Let's add sanity check on i_nid field for inline_data inode, 
> > > > > meanwhile,
> > > > > forbid to migrate inline_data inode's data block to fix this issue.
> > > > > 
> > > > > Reported-by: syzbot+848062ba19c8782ca...@syzkaller.appspotmail.com
> > > > > Closes: 
> > > > > https://lore.kernel.org/linux-f2fs-devel/d103ce06174d7...@google.com
> > > > > Signed-off-by: Chao Yu 
> > > > > ---
> > > > >fs/f2fs/f2fs.h   |  2 +-
> > > > >fs/f2fs/gc.c |  6 ++
> > > > >fs/f2fs/inline.c | 17 -
> > > > >fs/f2fs/inode.c  |  2 +-
> > > > >4 files changed, 24 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > > > > index fced2b7652f4..c876813b5532 100644
> > > > > --- a/fs/f2fs/f2fs.h
> > > > > +++ b/fs/f2fs/f2fs.h
> > > > > @@ -4146,7 +4146,7 @@ extern struct kmem_cache *f2fs_inode_entry_slab;
> > > > > * inline.c
> > > > > */
> > > > >bool f2fs_may_inline_data(struct inode *inode);
> > > > > -bool f2fs_sanity_check_inline_data(struct inode *inode);
> > > > > +bool f2fs_sanity_check_inline_data(struct inode *inode, struct page 
> > > > > *ipage);
> > > > >bool f2fs_may_inline_dentry(struct inode *inode);
> > > > >void f2fs_do_read_inline_data(struct page *page, struct page 
> > > > > *ipage);
> > > > >void f2fs_truncate_inline_inode(struct inode *inode,
> > > > > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > > > > index e86c7f01539a..041957750478 100644
> > > > > --- a/fs/f2fs/gc.c
> > > > > +++ b/fs/f2fs/gc.c
> > > > > @@ -1563,6 +1563,12 @@ static int gc_data_segment(struct f2fs_sb_info 
> > > > > *sbi, struct f2fs_summary *sum,
> > > > >   continue;
> > > > >   }
> > > > > + if (f2fs_has_inline_data(inode)) {
> > > > > + iput(inode);
> > > > > + set_sbi_flag(sbi, SBI_NEED_FSCK);
> > > > > + continue;
> >

Re: [f2fs-dev] [PATCH 3/3] f2fs: fix to do sanity check on i_nid for inline_data inode

2024-05-09 Thread Jaegeuk Kim
On 05/10, Chao Yu wrote:
> On 2024/5/9 23:52, Jaegeuk Kim wrote:
> > On 05/06, Chao Yu wrote:
> > > syzbot reports a f2fs bug as below:
> > > 
> > > [ cut here ]
> > > kernel BUG at fs/f2fs/inline.c:258!
> > > CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 
> > > 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
> > > RIP: 0010:f2fs_write_inline_data+0x781/0x790 fs/f2fs/inline.c:258
> > > Call Trace:
> > >   f2fs_write_single_data_page+0xb65/0x1d60 fs/f2fs/data.c:2834
> > >   f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
> > >   __f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
> > >   f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3315
> > >   do_writepages+0x35b/0x870 mm/page-writeback.c:2612
> > >   __writeback_single_inode+0x165/0x10b0 fs/fs-writeback.c:1650
> > >   writeback_sb_inodes+0x905/0x1260 fs/fs-writeback.c:1941
> > >   wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
> > >   wb_do_writeback fs/fs-writeback.c:2264 [inline]
> > >   wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
> > >   process_one_work kernel/workqueue.c:3254 [inline]
> > >   process_scheduled_works+0xa12/0x17c0 kernel/workqueue.c:3335
> > >   worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
> > >   kthread+0x2f2/0x390 kernel/kthread.c:388
> > >   ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
> > >   ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> > > 
> > > The root cause is: inline_data inode can be fuzzed, so that there may
> > > be valid blkaddr in its direct node, once f2fs triggers background GC
> > > to migrate the block, it will hit f2fs_bug_on() during dirty page
> > > writeback.
> > > 
> > > Let's add sanity check on i_nid field for inline_data inode, meanwhile,
> > > forbid to migrate inline_data inode's data block to fix this issue.
> > > 
> > > Reported-by: syzbot+848062ba19c8782ca...@syzkaller.appspotmail.com
> > > Closes: 
> > > https://lore.kernel.org/linux-f2fs-devel/d103ce06174d7...@google.com
> > > Signed-off-by: Chao Yu 
> > > ---
> > >   fs/f2fs/f2fs.h   |  2 +-
> > >   fs/f2fs/gc.c |  6 ++
> > >   fs/f2fs/inline.c | 17 -
> > >   fs/f2fs/inode.c  |  2 +-
> > >   4 files changed, 24 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > > index fced2b7652f4..c876813b5532 100644
> > > --- a/fs/f2fs/f2fs.h
> > > +++ b/fs/f2fs/f2fs.h
> > > @@ -4146,7 +4146,7 @@ extern struct kmem_cache *f2fs_inode_entry_slab;
> > >* inline.c
> > >*/
> > >   bool f2fs_may_inline_data(struct inode *inode);
> > > -bool f2fs_sanity_check_inline_data(struct inode *inode);
> > > +bool f2fs_sanity_check_inline_data(struct inode *inode, struct page 
> > > *ipage);
> > >   bool f2fs_may_inline_dentry(struct inode *inode);
> > >   void f2fs_do_read_inline_data(struct page *page, struct page *ipage);
> > >   void f2fs_truncate_inline_inode(struct inode *inode,
> > > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > > index e86c7f01539a..041957750478 100644
> > > --- a/fs/f2fs/gc.c
> > > +++ b/fs/f2fs/gc.c
> > > @@ -1563,6 +1563,12 @@ static int gc_data_segment(struct f2fs_sb_info 
> > > *sbi, struct f2fs_summary *sum,
> > >   continue;
> > >   }
> > > + if (f2fs_has_inline_data(inode)) {
> > > + iput(inode);
> > > + set_sbi_flag(sbi, SBI_NEED_FSCK);
> > > + continue;
> > 
> > Any race condtion to get this as false alarm?
> 
> Since there is no reproducer for the bug, I doubt it was caused by metadata
> fuzzing, something like this:
> 
> - inline inode has one valid blkaddr in i_addr or in dnode reference by i_nid;
> - SIT/SSA entry of the block is valid;
> - background GC migrates the block;
> - kworker writeback it, and trigger the bug_on().

Wasn't detected by sanity_check_inode?

> 
> Thoughts?
> 
> Thanks,
> 
> > 
> > > + }
> > > +
> > >   err = f2fs_gc_pinned_control(inode, gc_type, 
> > > segno);
> > >   if (err == -EAGAIN) {
> > >   iput(inode);
> > > diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
> > > index ac0

Re: [f2fs-dev] [PATCH] f2fs: allow dirty sections with zero valid block for checkpoint disabled

2024-05-09 Thread Jaegeuk Kim
On 05/07, Daeho Jeong wrote:
> From: Daeho Jeong 
> 
> Following the semantic for dirty segments in checkpoint disabled mode,
> apply the same rule to dirty sections.
> 
> Signed-off-by: Daeho Jeong 
> ---
>  fs/f2fs/segment.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 6474b7338e81..2463398b243f 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -771,8 +771,11 @@ static void __locate_dirty_segment(struct f2fs_sb_info 
> *sbi, unsigned int segno,
>   block_t valid_blocks =
>   get_valid_blocks(sbi, segno, true);
>  
> - f2fs_bug_on(sbi, unlikely(!valid_blocks ||
> - valid_blocks == CAP_BLKS_PER_SEC(sbi)));
> + if (!is_sbi_flag_set(sbi, SBI_CP_DISABLED))
> + f2fs_bug_on(sbi, unlikely(!valid_blocks));
> +
> + f2fs_bug_on(sbi, unlikely(valid_blocks ==
> + CAP_BLKS_PER_SEC(sbi)));

What about:
f2fs_bug_on(sbi,
(!is_sbi_flag_set(sbi, SBI_CP_DISABLED) && !valid_blocks) ||
valid_blocks == CAP_BLKS_PER_SEC(sbi));

>  
>   if (!IS_CURSEC(sbi, secno))
>   set_bit(secno, dirty_i->dirty_secmap);
> -- 
> 2.45.0.rc1.225.g2a3ae87e7f-goog
> 
> 
> 
> ___
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


___
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/3] f2fs: fix to do sanity check on i_nid for inline_data inode

2024-05-09 Thread Jaegeuk Kim
On 05/06, Chao Yu wrote:
> syzbot reports a f2fs bug as below:
> 
> [ cut here ]
> kernel BUG at fs/f2fs/inline.c:258!
> CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 
> 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
> RIP: 0010:f2fs_write_inline_data+0x781/0x790 fs/f2fs/inline.c:258
> Call Trace:
>  f2fs_write_single_data_page+0xb65/0x1d60 fs/f2fs/data.c:2834
>  f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
>  __f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
>  f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3315
>  do_writepages+0x35b/0x870 mm/page-writeback.c:2612
>  __writeback_single_inode+0x165/0x10b0 fs/fs-writeback.c:1650
>  writeback_sb_inodes+0x905/0x1260 fs/fs-writeback.c:1941
>  wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
>  wb_do_writeback fs/fs-writeback.c:2264 [inline]
>  wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
>  process_one_work kernel/workqueue.c:3254 [inline]
>  process_scheduled_works+0xa12/0x17c0 kernel/workqueue.c:3335
>  worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
>  kthread+0x2f2/0x390 kernel/kthread.c:388
>  ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
>  ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
> 
> The root cause is: inline_data inode can be fuzzed, so that there may
> be valid blkaddr in its direct node, once f2fs triggers background GC
> to migrate the block, it will hit f2fs_bug_on() during dirty page
> writeback.
> 
> Let's add sanity check on i_nid field for inline_data inode, meanwhile,
> forbid to migrate inline_data inode's data block to fix this issue.
> 
> Reported-by: syzbot+848062ba19c8782ca...@syzkaller.appspotmail.com
> Closes: 
> https://lore.kernel.org/linux-f2fs-devel/d103ce06174d7...@google.com
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/f2fs.h   |  2 +-
>  fs/f2fs/gc.c |  6 ++
>  fs/f2fs/inline.c | 17 -
>  fs/f2fs/inode.c  |  2 +-
>  4 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index fced2b7652f4..c876813b5532 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -4146,7 +4146,7 @@ extern struct kmem_cache *f2fs_inode_entry_slab;
>   * inline.c
>   */
>  bool f2fs_may_inline_data(struct inode *inode);
> -bool f2fs_sanity_check_inline_data(struct inode *inode);
> +bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage);
>  bool f2fs_may_inline_dentry(struct inode *inode);
>  void f2fs_do_read_inline_data(struct page *page, struct page *ipage);
>  void f2fs_truncate_inline_inode(struct inode *inode,
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index e86c7f01539a..041957750478 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -1563,6 +1563,12 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, 
> struct f2fs_summary *sum,
>   continue;
>   }
>  
> + if (f2fs_has_inline_data(inode)) {
> + iput(inode);
> + set_sbi_flag(sbi, SBI_NEED_FSCK);
> + continue;

Any race condtion to get this as false alarm?

> + }
> +
>   err = f2fs_gc_pinned_control(inode, gc_type, segno);
>   if (err == -EAGAIN) {
>   iput(inode);
> diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
> index ac00423f117b..067600fed3d4 100644
> --- a/fs/f2fs/inline.c
> +++ b/fs/f2fs/inline.c
> @@ -33,11 +33,26 @@ bool f2fs_may_inline_data(struct inode *inode)
>   return !f2fs_post_read_required(inode);
>  }
>  
> -bool f2fs_sanity_check_inline_data(struct inode *inode)
> +static bool has_node_blocks(struct inode *inode, struct page *ipage)
> +{
> + struct f2fs_inode *ri = F2FS_INODE(ipage);
> + int i;
> +
> + for (i = 0; i < DEF_NIDS_PER_INODE; i++) {
> + if (ri->i_nid[i])
> + return true;
> + }
> + return false;
> +}
> +
> +bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage)
>  {
>   if (!f2fs_has_inline_data(inode))
>   return false;
>  
> + if (has_node_blocks(inode, ipage))
> + return false;
> +
>   if (!support_inline_data(inode))
>   return true;
>  
> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> index c26effdce9aa..1423cd27a477 100644
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -343,7 +343,7 @@ static bool sanity_check_inode(struct inode *inode, 
> struct page *node_page)
>   }
>   }
>  
> - if (f2fs_sanity_check_inline_data(inode)) {
> + if (f2fs_sanity_check_inline_data(inode, node_page)) {
>   f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have 
> inline_data, run fsck to fix",
> __func__, inode->i_ino, inode->i_mode);
>   return false;
> -- 
> 2.40.1


___
Linux-f2fs-devel mailing list

Re: [f2fs-dev] [PATCH 2/3] f2fs: fix to add missing iput() in gc_data_segment()

2024-05-09 Thread Jaegeuk Kim
On 05/09, Chao Yu wrote:
> On 2024/5/9 8:46, Jaegeuk Kim wrote:
> > On 05/06, Chao Yu wrote:
> > > During gc_data_segment(), if inode state is abnormal, it missed to call
> > > iput(), fix it.
> > > 
> > > Fixes: 132e3209789c ("f2fs: remove false alarm on iget failure during GC")
> > > Fixes: 9056d6489f5a ("f2fs: fix to do sanity check on inode type during 
> > > garbage collection")
> > > Signed-off-by: Chao Yu 
> > > ---
> > >   fs/f2fs/gc.c | 9 +++--
> > >   1 file changed, 7 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > > index 8852814dab7f..e86c7f01539a 100644
> > > --- a/fs/f2fs/gc.c
> > > +++ b/fs/f2fs/gc.c
> > > @@ -1554,10 +1554,15 @@ static int gc_data_segment(struct f2fs_sb_info 
> > > *sbi, struct f2fs_summary *sum,
> > >   int err;
> > >   inode = f2fs_iget(sb, dni.ino);
> > > - if (IS_ERR(inode) || is_bad_inode(inode) ||
> > > - special_file(inode->i_mode))
> > > + if (IS_ERR(inode))
> > >   continue;
> > > + if (is_bad_inode(inode) ||
> > > + special_file(inode->i_mode)) {
> > > + iput(inode);
> > 
> > iget_failed() called iput()?
> 
> It looks the bad inode was referenced in this context, it needs to be iput()ed
> here.
> 
> The bad inode was made in other thread, please check description in commit
> b73e52824c89 ("f2fs: reposition unlock_new_inode to prevent accessing invalid
> inode").

Ah, it's non-error case. Right.

> 
> Thanks,
> 
> > 
> > 
> > > + continue;
> > > + }
> > > +
> > >   err = f2fs_gc_pinned_control(inode, gc_type, 
> > > segno);
> > >   if (err == -EAGAIN) {
> > >   iput(inode);
> > > -- 
> > > 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 2/3] f2fs: fix to add missing iput() in gc_data_segment()

2024-05-08 Thread Jaegeuk Kim
On 05/06, Chao Yu wrote:
> During gc_data_segment(), if inode state is abnormal, it missed to call
> iput(), fix it.
> 
> Fixes: 132e3209789c ("f2fs: remove false alarm on iget failure during GC")
> Fixes: 9056d6489f5a ("f2fs: fix to do sanity check on inode type during 
> garbage collection")
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/gc.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 8852814dab7f..e86c7f01539a 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -1554,10 +1554,15 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, 
> struct f2fs_summary *sum,
>   int err;
>  
>   inode = f2fs_iget(sb, dni.ino);
> - if (IS_ERR(inode) || is_bad_inode(inode) ||
> - special_file(inode->i_mode))
> + if (IS_ERR(inode))
>   continue;
>  
> + if (is_bad_inode(inode) ||
> + special_file(inode->i_mode)) {
> + iput(inode);

iget_failed() called iput()?


> + continue;
> + }
> +
>   err = f2fs_gc_pinned_control(inode, gc_type, segno);
>   if (err == -EAGAIN) {
>   iput(inode);
> -- 
> 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] f2fs: fix block migration when section is not aligned to pow2

2024-04-29 Thread Jaegeuk Kim
On 04/29, Jaegeuk Kim wrote:
> On 04/26, Wu Bo wrote:
> > As for zoned-UFS, f2fs section size is forced to zone size. And zone
> > size may not aligned to pow2.
> > 
> > Fixes: 859fca6b706e ("f2fs: swap: support migrating swapfile in aligned 
> > write mode")
> > Signed-off-by: Liao Yuanhong 
> > Signed-off-by: Wu Bo 
> > ---
> >  fs/f2fs/data.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index d9494b5fc7c1..7ff5ad3fd5dc 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -3904,7 +3904,6 @@ static int check_swap_activate(struct 
> > swap_info_struct *sis,
> > int nr_extents = 0;
> > unsigned long nr_pblocks;
> > unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
> > -   unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
> > unsigned int not_aligned = 0;
> > int ret = 0;
> >  
> > @@ -3942,8 +3941,8 @@ static int check_swap_activate(struct 
> > swap_info_struct *sis,
> > pblock = map.m_pblk;
> > nr_pblocks = map.m_len;
> >  
> > -   if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
> > -   nr_pblocks & sec_blks_mask ||
> > +   if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
> > +   nr_pblocks % blks_per_sec ||
> 
> Modified a bit to address udiv issue like below. Let's see.

Ok, I took v2 instead of this.

> 
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -3923,8 +3923,8 @@ static int check_swap_activate(struct swap_info_struct 
> *sis,
> sector_t highest_pblock = 0;
> int nr_extents = 0;
> unsigned long nr_pblocks;
> +   u32 align;
> unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
> -   unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
> unsigned int not_aligned = 0;
> int ret = 0;
> 
> @@ -3961,10 +3961,10 @@ static int check_swap_activate(struct 
> swap_info_struct *sis,
> 
> pblock = map.m_pblk;
> nr_pblocks = map.m_len;
> +   div_u64_rem(nr_pblocks, blks_per_sec, );
> 
> -   if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
> -   nr_pblocks & sec_blks_mask ||
> -   !f2fs_valid_pinned_area(sbi, pblock)) {
> +   if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
> +   align || !f2fs_valid_pinned_area(sbi, 
> pblock)) {
> bool last_extent = false;
> 
> not_aligned++;
> 
> > !f2fs_valid_pinned_area(sbi, pblock)) {
> > bool last_extent = false;
> >  
> > -- 
> > 2.25.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 block migration when section is not aligned to pow2

2024-04-29 Thread Jaegeuk Kim
On 04/26, Wu Bo wrote:
> As for zoned-UFS, f2fs section size is forced to zone size. And zone
> size may not aligned to pow2.
> 
> Fixes: 859fca6b706e ("f2fs: swap: support migrating swapfile in aligned write 
> mode")
> Signed-off-by: Liao Yuanhong 
> Signed-off-by: Wu Bo 
> ---
>  fs/f2fs/data.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index d9494b5fc7c1..7ff5ad3fd5dc 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -3904,7 +3904,6 @@ static int check_swap_activate(struct swap_info_struct 
> *sis,
>   int nr_extents = 0;
>   unsigned long nr_pblocks;
>   unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
> - unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
>   unsigned int not_aligned = 0;
>   int ret = 0;
>  
> @@ -3942,8 +3941,8 @@ static int check_swap_activate(struct swap_info_struct 
> *sis,
>   pblock = map.m_pblk;
>   nr_pblocks = map.m_len;
>  
> - if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
> - nr_pblocks & sec_blks_mask ||
> + if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
> + nr_pblocks % blks_per_sec ||

Modified a bit to address udiv issue like below. Let's see.

--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3923,8 +3923,8 @@ static int check_swap_activate(struct swap_info_struct 
*sis,
sector_t highest_pblock = 0;
int nr_extents = 0;
unsigned long nr_pblocks;
+   u32 align;
unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
-   unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
unsigned int not_aligned = 0;
int ret = 0;

@@ -3961,10 +3961,10 @@ static int check_swap_activate(struct swap_info_struct 
*sis,

pblock = map.m_pblk;
nr_pblocks = map.m_len;
+   div_u64_rem(nr_pblocks, blks_per_sec, );

-   if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
-   nr_pblocks & sec_blks_mask ||
-   !f2fs_valid_pinned_area(sbi, pblock)) {
+   if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
+   align || !f2fs_valid_pinned_area(sbi, pblock)) {
bool last_extent = false;

not_aligned++;

>   !f2fs_valid_pinned_area(sbi, pblock)) {
>   bool last_extent = false;
>  
> -- 
> 2.25.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 false alarm on invalid block address

2024-04-24 Thread Jaegeuk Kim
f2fs_ra_meta_pages can try to read ahead on invalid block address which is
not the corruption case.

Cc:  # v6.9+
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218770
Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of f2fs_is_valid_blkaddr")
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5d05a413f451..55d444bec5c0 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   goto err;
+   goto check_only;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   goto err;
+   goto check_only;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   goto err;
+   goto check_only;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   goto err;
+   goto check_only;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
return true;
 err:
f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+check_only:
return false;
 }
 
-- 
2.44.0.769.g3c40516874-goog



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


Re: [f2fs-dev] [PATCH 3/3] f2fs: fix false alarm on invalid block address

2024-04-19 Thread Jaegeuk Kim
On 04/19, Juhyung Park wrote:
> On Sat, Apr 13, 2024 at 5:57 AM Jaegeuk Kim  wrote:
> >
> > On 04/11, Chao Yu wrote:
> > > On 2024/4/10 4:34, Jaegeuk Kim wrote:
> > > > f2fs_ra_meta_pages can try to read ahead on invalid block address which 
> > > > is
> > > > not the corruption case.
> > >
> > > In which case we will read ahead invalid meta pages? recovery w/ META_POR?
> 
> In my case, it seems like it's META_SIT, and it's triggered right after mount.
> fsck detects invalid_blkaddr, and when the kernel mounts it, it
> immediately flags invalid_blkaddr again:
> 
> [6.333498] init: [libfs_mgr] Running /system/bin/fsck.f2fs -a -c
> 1 --debug-cache /dev/block/sda13
> [6.337671] fsck.f2fs: Info: Fix the reported corruption.
> [6.337947] fsck.f2fs: Info: not exist /proc/version!
> [6.338010] fsck.f2fs: Info: can't find /sys, assuming normal block device
> [6.338294] fsck.f2fs: Info: MKFS version
> [6.338319] fsck.f2fs:   "5.10.160-android12-9-ge5cfec41c8e2"
> [6.338366] fsck.f2fs: Info: FSCK version
> [6.338380] fsck.f2fs:   from "5.10-arter97"
> [6.338393] fsck.f2fs: to "5.10-arter97"
> [6.338414] fsck.f2fs: Info: superblock features = 1499 :  encrypt
> verity extra_attr project_quota quota_ino casefold
> [6.338429] fsck.f2fs: Info: superblock encrypt level = 0, salt =
> 
> [6.338442] fsck.f2fs: Info: checkpoint stop reason: shutdown(180)
> [6.338455] fsck.f2fs: Info: fs errors: invalid_blkaddr
> [6.338468] fsck.f2fs: Info: Segments per section = 1
> [6.338480] fsck.f2fs: Info: Sections per zone = 1
> [6.338492] fsck.f2fs: Info: total FS sectors = 58971571 (230357 MB)
> [6.340599] fsck.f2fs: Info: CKPT version = 2b7e3b29
> [6.340620] fsck.f2fs: Info: version timestamp cur: 19789296, prev: 
> 18407008
> [6.677041] fsck.f2fs: Info: checkpoint state = 46 :  crc
> compacted_summary orphan_inodes sudden-power-off
> [6.677052] fsck.f2fs: [FSCK] Check node 1 / 712937 (0.00%)
> [8.997922] fsck.f2fs: [FSCK] Check node 71294 / 712937 (10.00%)
> [   10.629205] fsck.f2fs: [FSCK] Check node 142587 / 712937 (20.00%)
> [   12.278186] fsck.f2fs: [FSCK] Check node 213880 / 712937 (30.00%)
> [   13.768177] fsck.f2fs: [FSCK] Check node 285173 / 712937 (40.00%)
> [   17.446971] fsck.f2fs: [FSCK] Check node 356466 / 712937 (50.00%)
> [   19.891623] fsck.f2fs: [FSCK] Check node 427759 / 712937 (60.00%)
> [   23.251327] fsck.f2fs: [FSCK] Check node 499052 / 712937 (70.00%)
> [   28.493457] fsck.f2fs: [FSCK] Check node 570345 / 712937 (80.00%)
> [   29.640800] fsck.f2fs: [FSCK] Check node 641638 / 712937 (90.00%)
> [   30.718347] fsck.f2fs: [FSCK] Check node 712931 / 712937 (100.00%)
> [   30.724176] fsck.f2fs:
> [   30.737160] fsck.f2fs: [FSCK] Max image size: 167506 MB, Free space: 62850 
> MB
> [   30.737164] fsck.f2fs: [FSCK] Unreachable nat entries
>  [Ok..] [0x0]
> [   30.737638] fsck.f2fs: [FSCK] SIT valid block bitmap checking
>  [Ok..]
> [   30.737640] fsck.f2fs: [FSCK] Hard link checking for regular file
>  [Ok..] [0xd]
> [   30.737641] fsck.f2fs: [FSCK] valid_block_count matching with CP
>  [Ok..] [0x28b98e6]
> [   30.737644] fsck.f2fs: [FSCK] valid_node_count matching with CP (de
> lookup)  [Ok..] [0xae0e9]
> [   30.737646] fsck.f2fs: [FSCK] valid_node_count matching with CP
> (nat lookup) [Ok..] [0xae0e9]
> [   30.737647] fsck.f2fs: [FSCK] valid_inode_count matched with CP
>  [Ok..] [0xa74a3]
> [   30.737649] fsck.f2fs: [FSCK] free segment_count matched with CP
>  [Ok..] [0x7aa3]
> [   30.737662] fsck.f2fs: [FSCK] next block offset is free
>  [Ok..]
> [   30.737663] fsck.f2fs: [FSCK] fixing SIT types
> [   30.737867] fsck.f2fs: [FSCK] other corrupted bugs
>  [Ok..]
> [   30.737893] fsck.f2fs: [update_superblock: 765] Info: Done to
> update superblock
> [   30.960610] fsck.f2fs:
> [   30.960618] fsck.f2fs: Done: 24.622956 secs
> [   30.960620] fsck.f2fs:
> [   30.960622] fsck.f2fs: c, u, RA, CH, CM, Repl=
> [   30.960627] fsck.f2fs: 1 1 43600517 42605434 995083 985083
> [   30.963274] F2FS-fs (sda13): Using encoding defined by superblock:
> utf8-12.1.0 with flags 0x0
> [   30.995360] __f2fs_is_valid_blkaddr: type=2
> 
> (Manually added that print ^)
> 
> [   30.995369] [ cut here ]
> [   30.995375] WARNING: CPU: 7 PID: 1 at f2fs_handle_error+0x18/0x3c
> [   30.995378] CPU: 7 PID: 1 Comm: init Tainted: G S  W
> 5.10.209-arter97-r15-kernelsu-g0867d0e4f1d2 #6
> [   30.995379] Hardware name: Qualcomm Technologies, Inc. Cape QRD
> with PM8010 (DT)
&g

Re: [f2fs-dev] [PATCH] f2fs: assign the write hint per stream by default

2024-04-19 Thread Jaegeuk Kim
On 04/18, Chao Yu wrote:
> On 2024/4/18 5:12, Jaegeuk Kim wrote:
> > This reverts commit 930e2607638d ("f2fs: remove obsolete whint_mode"), as we
> > decide to pass write hints to the disk.
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >   Documentation/filesystems/f2fs.rst | 29 +++
> >   fs/f2fs/data.c |  2 +
> >   fs/f2fs/f2fs.h |  2 +
> >   fs/f2fs/segment.c  | 59 ++
> >   4 files changed, 92 insertions(+)
> > 
> > diff --git a/Documentation/filesystems/f2fs.rst 
> > b/Documentation/filesystems/f2fs.rst
> > index efc3493fd6f8..68a0885fb5e6 100644
> > --- a/Documentation/filesystems/f2fs.rst
> > +++ b/Documentation/filesystems/f2fs.rst
> > @@ -774,6 +774,35 @@ In order to identify whether the data in the victim 
> > segment are valid or not,
> >   F2FS manages a bitmap. Each bit represents the validity of a block, and 
> > the
> >   bitmap is composed of a bit stream covering whole blocks in main area.
> > +Write-hint Policy
> > +-
> > +
> > +F2FS sets the whint all the time with the below policy.
> 
> No user-based mode?

Not anymore, as there's no user.

> 
> Thanks,
> 
> > +
> > +=  ===
> > +User  F2FS Block
> > +=  ===
> > +N/A   META WRITE_LIFE_NONE|REQ_META
> > +N/A   HOT_NODE WRITE_LIFE_NONE
> > +N/A   WARM_NODEWRITE_LIFE_MEDIUM
> > +N/A   COLD_NODEWRITE_LIFE_LONG
> > +ioctl(COLD)   COLD_DATAWRITE_LIFE_EXTREME
> > +extension list""
> > +
> > +-- buffered io
> > +N/A   COLD_DATAWRITE_LIFE_EXTREME
> > +N/A   HOT_DATA WRITE_LIFE_SHORT
> > +N/A   WARM_DATAWRITE_LIFE_NOT_SET
> > +
> > +-- direct io
> > +WRITE_LIFE_EXTREMECOLD_DATAWRITE_LIFE_EXTREME
> > +WRITE_LIFE_SHORT  HOT_DATA WRITE_LIFE_SHORT
> > +WRITE_LIFE_NOT_SETWARM_DATAWRITE_LIFE_NOT_SET
> > +WRITE_LIFE_NONE   "WRITE_LIFE_NONE
> > +WRITE_LIFE_MEDIUM "WRITE_LIFE_MEDIUM
> > +WRITE_LIFE_LONG   "WRITE_LIFE_LONG
> > +=  ===
> > +
> >   Fallocate(2) Policy
> >   ---
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index 5d641fac02ba..ed7d08785fcf 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -465,6 +465,8 @@ static struct bio *__bio_alloc(struct f2fs_io_info 
> > *fio, int npages)
> > } else {
> > bio->bi_end_io = f2fs_write_end_io;
> > bio->bi_private = sbi;
> > +   bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi,
> > +   fio->type, fio->temp);
> > }
> > iostat_alloc_and_bind_ctx(sbi, bio, NULL);
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index dd530dc70005..b3b878acc86b 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -3745,6 +3745,8 @@ void f2fs_destroy_segment_manager(struct f2fs_sb_info 
> > *sbi);
> >   int __init f2fs_create_segment_manager_caches(void);
> >   void f2fs_destroy_segment_manager_caches(void);
> >   int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
> > +enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
> > +   enum page_type type, enum temp_type temp);
> >   unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
> > unsigned int segno);
> >   unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index f0da516ba8dc..daa94669f7ee 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -3364,6 +3364,65 @@ int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
> > }
> >   }
> > +/*
> > + * This returns write hints for each segment type. This hints will be
> > + * passed down to block layer as below by default.
> > + *
> > + * User  F2FS Block
> > + * --

Re: [f2fs-dev] [PATCH] f2fs: assign write hint in direct write IO path

2024-04-19 Thread Jaegeuk Kim
Thanks, Chao,

If you don't mind, can I merge this into my patch. Ok?

On 04/18, Chao Yu wrote:
> f2fs has its own write_hint policy, let's assign write hint for
> direct write bio.
> 
> Cc: Hyunchul Lee 
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/f2fs.h|  1 +
>  fs/f2fs/file.c| 15 ++-
>  fs/f2fs/segment.c | 17 +++--
>  3 files changed, 26 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index b3b878acc86b..3f7196122574 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -3722,6 +3722,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);
> +int f2fs_get_segment_temp(int seg_type);
>  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,
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index ac1ae85f3cc3..d382f8bc2fbe 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -4685,8 +4685,21 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, 
> ssize_t size, int error,
>   return 0;
>  }
>  
> +static void f2fs_dio_write_submit_io(const struct iomap_iter *iter,
> + struct bio *bio, loff_t file_offset)
> +{
> + struct inode *inode = iter->inode;
> + struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> + int seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint);
> + enum temp_type temp = f2fs_get_segment_temp(seg_type);
> +
> + bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, DATA, temp);
> + submit_bio(bio);
> +}
> +
>  static const struct iomap_dio_ops f2fs_iomap_dio_write_ops = {
> - .end_io = f2fs_dio_write_end_io,
> + .end_io = f2fs_dio_write_end_io,
> + .submit_io  = f2fs_dio_write_submit_io,
>  };
>  
>  static void f2fs_flush_buffered_write(struct address_space *mapping,
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index daa94669f7ee..2206199e8099 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3502,6 +3502,15 @@ static int __get_segment_type_6(struct f2fs_io_info 
> *fio)
>   }
>  }
>  
> +int f2fs_get_segment_temp(int seg_type)
> +{
> + if (IS_HOT(seg_type))
> + return HOT;
> + else if (IS_WARM(seg_type))
> + return WARM;
> + return COLD;
> +}
> +
>  static int __get_segment_type(struct f2fs_io_info *fio)
>  {
>   int type = 0;
> @@ -3520,12 +3529,8 @@ static int __get_segment_type(struct f2fs_io_info *fio)
>   f2fs_bug_on(fio->sbi, true);
>   }
>  
> - if (IS_HOT(type))
> - fio->temp = HOT;
> - else if (IS_WARM(type))
> - fio->temp = WARM;
> - else
> - fio->temp = COLD;
> + fio->temp = f2fs_get_segment_temp(type);
> +
>   return type;
>  }
>  
> -- 
> 2.40.1


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


[f2fs-dev] [PATCH] f2fs: assign the write hint per stream by default

2024-04-17 Thread Jaegeuk Kim
This reverts commit 930e2607638d ("f2fs: remove obsolete whint_mode"), as we
decide to pass write hints to the disk.

Signed-off-by: Jaegeuk Kim 
---
 Documentation/filesystems/f2fs.rst | 29 +++
 fs/f2fs/data.c |  2 +
 fs/f2fs/f2fs.h |  2 +
 fs/f2fs/segment.c  | 59 ++
 4 files changed, 92 insertions(+)

diff --git a/Documentation/filesystems/f2fs.rst 
b/Documentation/filesystems/f2fs.rst
index efc3493fd6f8..68a0885fb5e6 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -774,6 +774,35 @@ In order to identify whether the data in the victim 
segment are valid or not,
 F2FS manages a bitmap. Each bit represents the validity of a block, and the
 bitmap is composed of a bit stream covering whole blocks in main area.
 
+Write-hint Policy
+-
+
+F2FS sets the whint all the time with the below policy.
+
+=  ===
+User  F2FS Block
+=  ===
+N/A   META WRITE_LIFE_NONE|REQ_META
+N/A   HOT_NODE WRITE_LIFE_NONE
+N/A   WARM_NODEWRITE_LIFE_MEDIUM
+N/A   COLD_NODEWRITE_LIFE_LONG
+ioctl(COLD)   COLD_DATAWRITE_LIFE_EXTREME
+extension list""
+
+-- buffered io
+N/A   COLD_DATAWRITE_LIFE_EXTREME
+N/A   HOT_DATA WRITE_LIFE_SHORT
+N/A   WARM_DATAWRITE_LIFE_NOT_SET
+
+-- direct io
+WRITE_LIFE_EXTREMECOLD_DATAWRITE_LIFE_EXTREME
+WRITE_LIFE_SHORT  HOT_DATA WRITE_LIFE_SHORT
+WRITE_LIFE_NOT_SETWARM_DATAWRITE_LIFE_NOT_SET
+WRITE_LIFE_NONE   "WRITE_LIFE_NONE
+WRITE_LIFE_MEDIUM "WRITE_LIFE_MEDIUM
+WRITE_LIFE_LONG   "WRITE_LIFE_LONG
+=  ===
+
 Fallocate(2) Policy
 ---
 
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 5d641fac02ba..ed7d08785fcf 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -465,6 +465,8 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, 
int npages)
} else {
bio->bi_end_io = f2fs_write_end_io;
bio->bi_private = sbi;
+   bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi,
+   fio->type, fio->temp);
}
iostat_alloc_and_bind_ctx(sbi, bio, NULL);
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index dd530dc70005..b3b878acc86b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3745,6 +3745,8 @@ void f2fs_destroy_segment_manager(struct f2fs_sb_info 
*sbi);
 int __init f2fs_create_segment_manager_caches(void);
 void f2fs_destroy_segment_manager_caches(void);
 int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
+enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
+   enum page_type type, enum temp_type temp);
 unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
unsigned int segno);
 unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index f0da516ba8dc..daa94669f7ee 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3364,6 +3364,65 @@ int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
}
 }
 
+/*
+ * This returns write hints for each segment type. This hints will be
+ * passed down to block layer as below by default.
+ *
+ * User  F2FS Block
+ *    -
+ *   META WRITE_LIFE_NONE|REQ_META
+ *   HOT_NODE WRITE_LIFE_NONE
+ *   WARM_NODEWRITE_LIFE_MEDIUM
+ *   COLD_NODEWRITE_LIFE_LONG
+ * ioctl(COLD)   COLD_DATAWRITE_LIFE_EXTREME
+ * extension list""
+ *
+ * -- buffered io
+ *   COLD_DATAWRITE_LIFE_EXTREME
+ *   HOT_DATA WRITE_LIFE_SHORT
+ *   WARM_DATAWRITE_LIFE_NOT_SET
+ *
+ * -- direct io
+ * WRITE_LIFE_EXTREMECOLD_DATAWRITE_LIFE_EXTREME
+ * WRITE_LIFE_SHORT  HOT_DATA WRITE_LIFE_SHORT
+ * WRITE_LIFE_NOT_SETWARM_DATAWRITE_LIFE_NOT_SET
+ * WRITE_LIFE_NONE   "WRITE_LIFE_NONE
+ * WRITE_LIFE_MEDIUM  

Re: [f2fs-dev] [PATCH] f2fs:add zone device priority option to the mount options

2024-04-16 Thread Jaegeuk Kim
I don't see any point why we need this.

On 04/15, Liao Yuanhong wrote:
> Add a zone device priority option in the mount options. When enabled, the 
> file system will prioritize using zone devices free space instead of 
> conventional devices when writing to the end of the storage space.
> 
> Signed-off-by: Liao Yuanhong 
> ---
>  fs/f2fs/f2fs.h|  1 +
>  fs/f2fs/segment.c | 13 -
>  fs/f2fs/super.c   | 20 
>  3 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index fced2b7652f4..e2438f7d2e13 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -116,6 +116,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
>  #define  F2FS_MOUNT_GC_MERGE 0x0200
>  #define F2FS_MOUNT_COMPRESS_CACHE0x0400
>  #define F2FS_MOUNT_AGE_EXTENT_CACHE  0x0800
> +#define F2FS_MOUNT_PRIORITY_ZONED0x1000
>  
>  #define F2FS_OPTION(sbi) ((sbi)->mount_opt)
>  #define clear_opt(sbi, option)   (F2FS_OPTION(sbi).opt &= 
> ~F2FS_MOUNT_##option)
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 4fd76e867e0a..adbe68a11fa5 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -2697,7 +2697,18 @@ static int get_new_segment(struct f2fs_sb_info *sbi,
>  find_other_zone:
>   secno = find_next_zero_bit(free_i->free_secmap, MAIN_SECS(sbi), hint);
>   if (secno >= MAIN_SECS(sbi)) {
> - secno = find_first_zero_bit(free_i->free_secmap,
> + /* set hint to get section from zone device first */
> + if (test_opt(sbi, PRIORITY_ZONED)) {
> + hint = GET_SEC_FROM_SEG(sbi, first_zoned_segno(sbi));
> + secno = find_next_zero_bit(free_i->free_secmap,
> + MAIN_SECS(sbi), hint);
> +
> + /* get section from clu if exceeding the size limit */
> + if (secno >= MAIN_SECS(sbi))
> + secno = find_first_zero_bit(free_i->free_secmap,
> + MAIN_SECS(sbi));
> + } else
> + secno = find_first_zero_bit(free_i->free_secmap,
>   MAIN_SECS(sbi));
>   if (secno >= MAIN_SECS(sbi)) {
>   ret = -ENOSPC;
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index a4bc26dfdb1a..2742978a100a 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -126,6 +126,8 @@ enum {
>   Opt_inline_data,
>   Opt_inline_dentry,
>   Opt_noinline_dentry,
> + Opt_priority_zoned,
> + Opt_nopriority_zoned,
>   Opt_flush_merge,
>   Opt_noflush_merge,
>   Opt_barrier,
> @@ -204,6 +206,8 @@ static match_table_t f2fs_tokens = {
>   {Opt_inline_data, "inline_data"},
>   {Opt_inline_dentry, "inline_dentry"},
>   {Opt_noinline_dentry, "noinline_dentry"},
> + {Opt_priority_zoned, "priority_zoned"},
> + {Opt_nopriority_zoned, "nopriority_zoned"},
>   {Opt_flush_merge, "flush_merge"},
>   {Opt_noflush_merge, "noflush_merge"},
>   {Opt_barrier, "barrier"},
> @@ -805,6 +809,16 @@ static int parse_options(struct super_block *sb, char 
> *options, bool is_remount)
>   case Opt_noinline_dentry:
>   clear_opt(sbi, INLINE_DENTRY);
>   break;
> +#ifdef CONFIG_BLK_DEV_ZONED
> + case Opt_priority_zoned:
> + if (f2fs_sb_has_blkzoned(sbi))
> + set_opt(sbi, PRIORITY_ZONED);
> + break;
> + case Opt_nopriority_zoned:
> + if (f2fs_sb_has_blkzoned(sbi))
> + clear_opt(sbi, PRIORITY_ZONED);
> + break;
> +#endif
>   case Opt_flush_merge:
>   set_opt(sbi, FLUSH_MERGE);
>   break;
> @@ -1990,6 +2004,12 @@ static int f2fs_show_options(struct seq_file *seq, 
> struct dentry *root)
>   seq_puts(seq, ",inline_dentry");
>   else
>   seq_puts(seq, ",noinline_dentry");
> +#ifdef CONFIG_BLK_DEV_ZONED
> + if (test_opt(sbi, PRIORITY_ZONED))
> + seq_puts(seq, ",priority_zoned");
> + else
> + seq_puts(seq, ",nopriority_zoned");
> +#endif
>   if (test_opt(sbi, FLUSH_MERGE))
>   seq_puts(seq, ",flush_merge");
>   else
> -- 
> 2.25.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: zone: don't block IO if there is remained open zone

2024-04-16 Thread Jaegeuk Kim
On 04/16, Chao Yu wrote:
> On 2024/4/15 22:01, Chao Yu wrote:
> > On 2024/4/15 11:26, Chao Yu wrote:
> > > On 2024/4/14 23:19, Jaegeuk Kim wrote:
> > > > It seems this caused kernel hang. Chao, have you tested this patch 
> > > > enough?
> > > 
> > > Jaegeuk,
> > > 
> > > Oh, I've checked this patch w/ fsstress before submitting it, but missed
> > > the SPO testcase... do you encounter kernel hang w/ SPO testcase?
> > 
> > I did see any hang issue w/ por_fsstress testcase, which testcase do you 
> > use?
> 
> Sorry, I mean I haven't reproduced it yet...

I'd prefer to check this patch later. Have you tested on Zoned device with
nullblk?

> 
> Thanks,
> 
> > 
> > Thanks,
> > 
> > > 
> > > Anyway, let me test it more.
> > > 
> > > Thanks,
> > > 
> > > > 
> > > > On 04/13, Chao Yu wrote:
> > > > > On 2024/4/13 5:11, Jaegeuk Kim wrote:
> > > > > > On 04/07, Chao Yu wrote:
> > > > > > > max open zone may be larger than log header number of f2fs, for
> > > > > > > such case, it doesn't need to wait last IO in previous zone, let's
> > > > > > > introduce available_open_zone semaphore, and reduce it once we
> > > > > > > submit first write IO in a zone, and increase it after completion
> > > > > > > of last IO in the zone.
> > > > > > > 
> > > > > > > Cc: Daeho Jeong 
> > > > > > > Signed-off-by: Chao Yu 
> > > > > > > ---
> > > > > > > v3:
> > > > > > > - avoid race condition in between __submit_merged_bio()
> > > > > > > and __allocate_new_segment().
> > > > > > >    fs/f2fs/data.c    | 105 
> > > > > > > ++
> > > > > > >    fs/f2fs/f2fs.h    |  34 ---
> > > > > > >    fs/f2fs/iostat.c  |   7 
> > > > > > >    fs/f2fs/iostat.h  |   2 +
> > > > > > >    fs/f2fs/segment.c |  43 ---
> > > > > > >    fs/f2fs/segment.h |  12 +-
> > > > > > >    fs/f2fs/super.c   |   2 +
> > > > > > >    7 files changed, 156 insertions(+), 49 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > > > > > > index 0d88649c60a5..18a4ac0a06bc 100644
> > > > > > > --- a/fs/f2fs/data.c
> > > > > > > +++ b/fs/f2fs/data.c
> > > > > > > @@ -373,11 +373,10 @@ static void f2fs_write_end_io(struct bio 
> > > > > > > *bio)
> > > > > > >    #ifdef CONFIG_BLK_DEV_ZONED
> > > > > > >    static void f2fs_zone_write_end_io(struct bio *bio)
> > > > > > >    {
> > > > > > > -    struct f2fs_bio_info *io = (struct f2fs_bio_info 
> > > > > > > *)bio->bi_private;
> > > > > > > +    struct f2fs_sb_info *sbi = iostat_get_bio_private(bio);
> > > > > > > -    bio->bi_private = io->bi_private;
> > > > > > > -    complete(>zone_wait);
> > > > > > >    f2fs_write_end_io(bio);
> > > > > > > +    up(>available_open_zones);
> > > > > > >    }
> > > > > > >    #endif
> > > > > > > @@ -531,6 +530,24 @@ static void __submit_merged_bio(struct 
> > > > > > > f2fs_bio_info *io)
> > > > > > >    if (!io->bio)
> > > > > > >    return;
> > > > > > > +#ifdef CONFIG_BLK_DEV_ZONED
> > > > > > > +    if (io->open_zone) {
> > > > > > > +    /*
> > > > > > > + * if there is no open zone, it will wait for last IO in
> > > > > > > + * previous zone before submitting new IO.
> > > > > > > + */
> > > > > > > +    down(>sbi->available_open_zones);
> > > > > > > +    io->open_zone = false;
> > > > > > > +    io->zone_openned = true;
> > > > > > > +    }
> > > > > > > +
> > > > > > > +    if (io->close_zone) {
> > > > > > > +    io->bio->bi_end_io = f2fs_zo

Re: [f2fs-dev] [PATCH 2/3 v2] f2fs: clear writeback when compression failed

2024-04-16 Thread Jaegeuk Kim
Let's stop issuing compressed writes and clear their writeback flags.

Signed-off-by: Jaegeuk Kim 
---

 Now, I don't see any kernel hang for 24hours.

 Change log from v1:
  - fix bugs

 fs/f2fs/compress.c | 40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index d67c471ab5df..b12d3a49bfda 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1031,6 +1031,31 @@ static void set_cluster_writeback(struct compress_ctx 
*cc)
}
 }
 
+static void cancel_cluster_writeback(struct compress_ctx *cc,
+   struct compress_io_ctx *cic, int submitted)
+{
+   int i;
+
+   /* Wait for submitted IOs. */
+   if (submitted > 1) {
+   f2fs_submit_merged_write(F2FS_I_SB(cc->inode), DATA);
+   while (atomic_read(>pending_pages) !=
+   (cc->valid_nr_cpages - submitted + 1))
+   f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+   }
+
+   /* Cancel writeback and stay locked. */
+   for (i = 0; i < cc->cluster_size; i++) {
+   if (i < submitted) {
+   inode_inc_dirty_pages(cc->inode);
+   lock_page(cc->rpages[i]);
+   }
+   clear_page_private_gcing(cc->rpages[i]);
+   if (folio_test_writeback(page_folio(cc->rpages[i])))
+   end_page_writeback(cc->rpages[i]);
+   }
+}
+
 static void set_cluster_dirty(struct compress_ctx *cc)
 {
int i;
@@ -1232,7 +1257,6 @@ static int f2fs_write_compressed_pages(struct 
compress_ctx *cc,
.page = NULL,
.encrypted_page = NULL,
.compressed_page = NULL,
-   .submitted = 0,
.io_type = io_type,
.io_wbc = wbc,
.encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ?
@@ -1358,7 +1382,16 @@ static int f2fs_write_compressed_pages(struct 
compress_ctx *cc,
fio.compressed_page = cc->cpages[i - 1];
 
cc->cpages[i - 1] = NULL;
+   fio.submitted = 0;
f2fs_outplace_write_data(, );
+   if (unlikely(!fio.submitted)) {
+   cancel_cluster_writeback(cc, cic, i);
+
+   /* To call fscrypt_finalize_bounce_page */
+   i = cc->valid_nr_cpages;
+   *submitted = 0;
+   goto out_destroy_crypt;
+   }
(*submitted)++;
 unlock_continue:
inode_dec_dirty_pages(cc->inode);
@@ -1392,8 +1425,11 @@ static int f2fs_write_compressed_pages(struct 
compress_ctx *cc,
 out_destroy_crypt:
page_array_free(cc->inode, cic->rpages, cc->cluster_size);
 
-   for (--i; i >= 0; i--)
+   for (--i; i >= 0; i--) {
+   if (!cc->cpages[i])
+   continue;
fscrypt_finalize_bounce_page(>cpages[i]);
+   }
 out_put_cic:
kmem_cache_free(cic_entry_slab, cic);
 out_put_dnode:
-- 
2.44.0.683.g7961c838ac-goog



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


Re: [f2fs-dev] [PATCH v3] f2fs: zone: don't block IO if there is remained open zone

2024-04-14 Thread Jaegeuk Kim
It seems this caused kernel hang. Chao, have you tested this patch enough?

On 04/13, Chao Yu wrote:
> On 2024/4/13 5:11, Jaegeuk Kim wrote:
> > On 04/07, Chao Yu wrote:
> > > max open zone may be larger than log header number of f2fs, for
> > > such case, it doesn't need to wait last IO in previous zone, let's
> > > introduce available_open_zone semaphore, and reduce it once we
> > > submit first write IO in a zone, and increase it after completion
> > > of last IO in the zone.
> > > 
> > > Cc: Daeho Jeong 
> > > Signed-off-by: Chao Yu 
> > > ---
> > > v3:
> > > - avoid race condition in between __submit_merged_bio()
> > > and __allocate_new_segment().
> > >   fs/f2fs/data.c| 105 ++
> > >   fs/f2fs/f2fs.h|  34 ---
> > >   fs/f2fs/iostat.c  |   7 
> > >   fs/f2fs/iostat.h  |   2 +
> > >   fs/f2fs/segment.c |  43 ---
> > >   fs/f2fs/segment.h |  12 +-
> > >   fs/f2fs/super.c   |   2 +
> > >   7 files changed, 156 insertions(+), 49 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > > index 0d88649c60a5..18a4ac0a06bc 100644
> > > --- a/fs/f2fs/data.c
> > > +++ b/fs/f2fs/data.c
> > > @@ -373,11 +373,10 @@ static void f2fs_write_end_io(struct bio *bio)
> > >   #ifdef CONFIG_BLK_DEV_ZONED
> > >   static void f2fs_zone_write_end_io(struct bio *bio)
> > >   {
> > > - struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private;
> > > + struct f2fs_sb_info *sbi = iostat_get_bio_private(bio);
> > > - bio->bi_private = io->bi_private;
> > > - complete(>zone_wait);
> > >   f2fs_write_end_io(bio);
> > > + up(>available_open_zones);
> > >   }
> > >   #endif
> > > @@ -531,6 +530,24 @@ static void __submit_merged_bio(struct f2fs_bio_info 
> > > *io)
> > >   if (!io->bio)
> > >   return;
> > > +#ifdef CONFIG_BLK_DEV_ZONED
> > > + if (io->open_zone) {
> > > + /*
> > > +  * if there is no open zone, it will wait for last IO in
> > > +  * previous zone before submitting new IO.
> > > +  */
> > > + down(>sbi->available_open_zones);
> > > + io->open_zone = false;
> > > + io->zone_openned = true;
> > > + }
> > > +
> > > + if (io->close_zone) {
> > > + io->bio->bi_end_io = f2fs_zone_write_end_io;
> > > + io->zone_openned = false;
> > > + io->close_zone = false;
> > > + }
> > > +#endif
> > > +
> > >   if (is_read_io(fio->op)) {
> > >   trace_f2fs_prepare_read_bio(io->sbi->sb, fio->type, 
> > > io->bio);
> > >   f2fs_submit_read_bio(io->sbi, io->bio, fio->type);
> > > @@ -601,9 +618,9 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
> > >   INIT_LIST_HEAD(>write_io[i][j].bio_list);
> > >   
> > > init_f2fs_rwsem(>write_io[i][j].bio_list_lock);
> > >   #ifdef CONFIG_BLK_DEV_ZONED
> > > - init_completion(>write_io[i][j].zone_wait);
> > > - sbi->write_io[i][j].zone_pending_bio = NULL;
> > > - sbi->write_io[i][j].bi_private = NULL;
> > > + sbi->write_io[i][j].open_zone = false;
> > > + sbi->write_io[i][j].zone_openned = false;
> > > + sbi->write_io[i][j].close_zone = false;
> > >   #endif
> > >   }
> > >   }
> > > @@ -634,6 +651,31 @@ static void __f2fs_submit_merged_write(struct 
> > > f2fs_sb_info *sbi,
> > >   f2fs_up_write(>io_rwsem);
> > >   }
> > > +void f2fs_blkzoned_submit_merged_write(struct f2fs_sb_info *sbi, int 
> > > type)
> > > +{
> > > +#ifdef CONFIG_BLK_DEV_ZONED
> > > + struct f2fs_bio_info *io;
> > > +
> > > + if (!f2fs_sb_has_blkzoned(sbi))
> > > + return;
> > > +
> > > + io = sbi->write_io[PAGE_TYPE(type)] + type_to_temp(type);
> > > +
> > > + f2fs_down_write(>io_rwsem);
> > > + if (io->zone_openned) {
> > > + if (io->bio) {
> > > + io->close_zone = true;
> > >

Re: [f2fs-dev] [PATCH v3] f2fs: zone: don't block IO if there is remained open zone

2024-04-12 Thread Jaegeuk Kim
On 04/07, Chao Yu wrote:
> max open zone may be larger than log header number of f2fs, for
> such case, it doesn't need to wait last IO in previous zone, let's
> introduce available_open_zone semaphore, and reduce it once we
> submit first write IO in a zone, and increase it after completion
> of last IO in the zone.
> 
> Cc: Daeho Jeong 
> Signed-off-by: Chao Yu 
> ---
> v3:
> - avoid race condition in between __submit_merged_bio()
> and __allocate_new_segment().
>  fs/f2fs/data.c| 105 ++
>  fs/f2fs/f2fs.h|  34 ---
>  fs/f2fs/iostat.c  |   7 
>  fs/f2fs/iostat.h  |   2 +
>  fs/f2fs/segment.c |  43 ---
>  fs/f2fs/segment.h |  12 +-
>  fs/f2fs/super.c   |   2 +
>  7 files changed, 156 insertions(+), 49 deletions(-)
> 
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 0d88649c60a5..18a4ac0a06bc 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -373,11 +373,10 @@ static void f2fs_write_end_io(struct bio *bio)
>  #ifdef CONFIG_BLK_DEV_ZONED
>  static void f2fs_zone_write_end_io(struct bio *bio)
>  {
> - struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private;
> + struct f2fs_sb_info *sbi = iostat_get_bio_private(bio);
>  
> - bio->bi_private = io->bi_private;
> - complete(>zone_wait);
>   f2fs_write_end_io(bio);
> + up(>available_open_zones);
>  }
>  #endif
>  
> @@ -531,6 +530,24 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
>   if (!io->bio)
>   return;
>  
> +#ifdef CONFIG_BLK_DEV_ZONED
> + if (io->open_zone) {
> + /*
> +  * if there is no open zone, it will wait for last IO in
> +  * previous zone before submitting new IO.
> +  */
> + down(>sbi->available_open_zones);
> + io->open_zone = false;
> + io->zone_openned = true;
> + }
> +
> + if (io->close_zone) {
> + io->bio->bi_end_io = f2fs_zone_write_end_io;
> + io->zone_openned = false;
> + io->close_zone = false;
> + }
> +#endif
> +
>   if (is_read_io(fio->op)) {
>   trace_f2fs_prepare_read_bio(io->sbi->sb, fio->type, io->bio);
>   f2fs_submit_read_bio(io->sbi, io->bio, fio->type);
> @@ -601,9 +618,9 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
>   INIT_LIST_HEAD(>write_io[i][j].bio_list);
>   init_f2fs_rwsem(>write_io[i][j].bio_list_lock);
>  #ifdef CONFIG_BLK_DEV_ZONED
> - init_completion(>write_io[i][j].zone_wait);
> - sbi->write_io[i][j].zone_pending_bio = NULL;
> - sbi->write_io[i][j].bi_private = NULL;
> + sbi->write_io[i][j].open_zone = false;
> + sbi->write_io[i][j].zone_openned = false;
> + sbi->write_io[i][j].close_zone = false;
>  #endif
>   }
>   }
> @@ -634,6 +651,31 @@ static void __f2fs_submit_merged_write(struct 
> f2fs_sb_info *sbi,
>   f2fs_up_write(>io_rwsem);
>  }
>  
> +void f2fs_blkzoned_submit_merged_write(struct f2fs_sb_info *sbi, int type)
> +{
> +#ifdef CONFIG_BLK_DEV_ZONED
> + struct f2fs_bio_info *io;
> +
> + if (!f2fs_sb_has_blkzoned(sbi))
> + return;
> +
> + io = sbi->write_io[PAGE_TYPE(type)] + type_to_temp(type);
> +
> + f2fs_down_write(>io_rwsem);
> + if (io->zone_openned) {
> + if (io->bio) {
> + io->close_zone = true;
> + __submit_merged_bio(io);
> + } else if (io->zone_openned) {
> + up(>available_open_zones);
> + io->zone_openned = false;
> + }
> + }
> + f2fs_up_write(>io_rwsem);
> +#endif
> +
> +}
> +
>  static void __submit_merged_write_cond(struct f2fs_sb_info *sbi,
>   struct inode *inode, struct page *page,
>   nid_t ino, enum page_type type, bool force)
> @@ -918,22 +960,16 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
>  }
>  
>  #ifdef CONFIG_BLK_DEV_ZONED
> -static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
> +static bool is_blkaddr_zone_boundary(struct f2fs_sb_info *sbi,
> + block_t blkaddr, bool start)
>  {
> - int devi = 0;
> + if (!f2fs_blkaddr_in_seqzone(sbi, blkaddr))
> + return false;
> +
> + if (start)
> + return (blkaddr % sbi->blocks_per_blkz) == 0;
> + return (blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
>  
> - if (f2fs_is_multi_device(sbi)) {
> - devi = f2fs_target_device_index(sbi, blkaddr);
> - if (blkaddr < FDEV(devi).start_blk ||
> - blkaddr > FDEV(devi).end_blk) {
> - f2fs_err(sbi, "Invalid block %x", blkaddr);
> - return false;
> - }
> - 

Re: [f2fs-dev] [PATCH 2/3] f2fs: clear writeback when compression failed

2024-04-12 Thread Jaegeuk Kim
On 04/11, Chao Yu wrote:
> On 2024/4/10 4:34, Jaegeuk Kim wrote:
> > Let's stop issuing compressed writes and clear their writeback flags.
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >   fs/f2fs/compress.c | 33 +++--
> >   1 file changed, 31 insertions(+), 2 deletions(-)
> > 
> > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> > index d67c471ab5df..3a8ecc6aee84 100644
> > --- a/fs/f2fs/compress.c
> > +++ b/fs/f2fs/compress.c
> > @@ -1031,6 +1031,25 @@ static void set_cluster_writeback(struct 
> > compress_ctx *cc)
> > }
> >   }
> > +static void cancel_cluster_writeback(struct compress_ctx *cc, int 
> > submitted)
> > +{
> > +   int i;
> > +
> > +   for (i = 0; i < cc->cluster_size; i++) {
> > +   if (!cc->rpages[i])
> > +   continue;
> > +   if (i < submitted) {
> > +   if (i)
> > +   f2fs_wait_on_page_writeback(cc->rpages[i],
> > +   DATA, true, true);
> > +   inode_inc_dirty_pages(cc->inode);
> > +   lock_page(cc->rpages[i]);
> > +   }
> > +   clear_page_private_gcing(cc->rpages[i]);
> > +   end_page_writeback(cc->rpages[i]);
> > +   }
> > +}
> > +
> >   static void set_cluster_dirty(struct compress_ctx *cc)
> >   {
> > int i;
> > @@ -1232,7 +1251,6 @@ static int f2fs_write_compressed_pages(struct 
> > compress_ctx *cc,
> > .page = NULL,
> > .encrypted_page = NULL,
> > .compressed_page = NULL,
> > -   .submitted = 0,
> > .io_type = io_type,
> > .io_wbc = wbc,
> > .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ?
> > @@ -1358,7 +1376,15 @@ static int f2fs_write_compressed_pages(struct 
> > compress_ctx *cc,
> > fio.compressed_page = cc->cpages[i - 1];
> > cc->cpages[i - 1] = NULL;
> > +   fio.submitted = 0;
> > f2fs_outplace_write_data(, );
> > +   if (unlikely(!fio.submitted)) {
> > +   cancel_cluster_writeback(cc, i);
> > +
> > +   /* To call fscrypt_finalize_bounce_page */
> > +   i = cc->valid_nr_cpages;
> 
> *submitted = 0; ?

And, it seems this is not enough to address kernel hang on wait_on_writeback
while running fsstress + shutdown test. Stay tuned.

> 
> Thanks,
> 
> > +   goto out_destroy_crypt;
> > +   }
> > (*submitted)++;
> >   unlock_continue:
> > inode_dec_dirty_pages(cc->inode);
> > @@ -1392,8 +1418,11 @@ static int f2fs_write_compressed_pages(struct 
> > compress_ctx *cc,
> >   out_destroy_crypt:
> > page_array_free(cc->inode, cic->rpages, cc->cluster_size);
> > -   for (--i; i >= 0; i--)
> > +   for (--i; i >= 0; i--) {
> > +   if (!cc->cpages[i])
> > +   continue;
> > fscrypt_finalize_bounce_page(>cpages[i]);
> > +   }
> >   out_put_cic:
> > kmem_cache_free(cic_entry_slab, cic);
> >   out_put_dnode:


___
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/3] f2fs: fix false alarm on invalid block address

2024-04-12 Thread Jaegeuk Kim
On 04/11, Chao Yu wrote:
> On 2024/4/10 4:34, Jaegeuk Kim wrote:
> > f2fs_ra_meta_pages can try to read ahead on invalid block address which is
> > not the corruption case.
> 
> In which case we will read ahead invalid meta pages? recovery w/ META_POR?

I was trying to debug another issue, but found the root cause. Let me drop this
patch.

> 
> Thanks,
> 
> > 
> > Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of 
> > f2fs_is_valid_blkaddr")
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >   fs/f2fs/checkpoint.c | 9 +
> >   1 file changed, 5 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index eac698b8dd38..b01320502624 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct 
> > f2fs_sb_info *sbi,
> > break;
> > case META_SIT:
> > if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case META_SSA:
> > if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
> > blkaddr < SM_I(sbi)->ssa_blkaddr))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case META_CP:
> > if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
> > blkaddr < __start_cp_addr(sbi)))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case META_POR:
> > if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
> > blkaddr < MAIN_BLKADDR(sbi)))
> > -   goto err;
> > +   goto check_only;
> > break;
> > case DATA_GENERIC:
> > case DATA_GENERIC_ENHANCE:
> > @@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
> > *sbi,
> > return true;
> >   err:
> > f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
> > +check_only:
> > return false;
> >   }


___
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-12 Thread Jaegeuk Kim
On 04/10, Zhiguo Niu wrote:
> Hi Jaegeuk
> Any comments about this patch?

Thank you for heads up. Applied.

> 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


Re: [f2fs-dev] 回覆: 回覆: 回覆: [PATCH] f2fs: avoid the deadlock case when stopping discard thread

2024-04-12 Thread Jaegeuk Kim
On 04/12, Light Hsieh (謝明燈) wrote:
> I think 'readon' in this line may be typo of  'reason'

Was fixed as well. Thanks.

> 
> + f2fs_warn(sbi, "Stopped filesystem due to readon: %d", reason);
> 
> 
> 
> 寄件者: Jaegeuk Kim 
> 寄件日期: 2024年4月5日 上午 03:55
> 收件者: Light Hsieh (謝明燈) 
> 副本: Hillf Danton ; linux-ker...@vger.kernel.org 
> ; linux-f2fs-devel@lists.sourceforge.net 
> 
> 主旨: Re: 回覆: 回覆: [PATCH] f2fs: avoid the deadlock case when stopping discard 
> thread
>  
> 
> On 04/03, Light Hsieh (謝明燈) wrote:
> > Our log shows that thaw_super_locked() find that sb is readonly, so 
> > sb_freeze_unlock() is not invoked.
> > 
> > static int thaw_super_locked(struct super_block *sb, enum freeze_holder who)
> > {
> >   ...
> >   if (sb_rdonly(sb)) {
> > sb->s_writers.freeze_holders &= ~who;
> > sb->s_writers.frozen = SB_UNFROZEN;
> > wake_up_var(>s_writers.frozen);
> > goto out;
> >   }
> >                ...
> >   sb_freeze_unlock(sb, SB_FREEZE_FS);
> > out:
> >   deactivate_locked_super(sb);
> >   return 0;
> > }
> 
> Thank you. Could you please take a look at this patch?
> 
> https://lore.kernel.org/linux-f2fs-devel/20240404195254.556896-1-jaeg...@kernel.org/T/#u
> 
> > 
> > 寄件者: Jaegeuk Kim 
> > 寄件日期: 2024年3月27日 上午 12:52
> > 收件者: Light Hsieh (謝明燈) 
> > 副本: Hillf Danton ; linux-ker...@vger.kernel.org 
> > ; linux-f2fs-devel@lists.sourceforge.net 
> > 
> > 主旨: Re: 回覆: [PATCH] f2fs: avoid the deadlock case when stopping discard 
> > thread
> >  
> > 
> > External email : Please do not click links or open attachments until you 
> > have verified the sender or the content.
> > On 03/22, Jaegeuk Kim wrote:
> > > On 03/22, Light Hsieh (謝明燈) wrote:
> > > > I don't see my added log in sb_free_unlock() which will invoke 
> > > > percpu_up_write to release the write semaphore.
> > > 
> > > May I ask more details whether thaw_super() was called or not?
> > 
> > Ping?
> > 
> > > 
> > > > 
> > > > 
> > > > 
> > > > 寄件者: Jaegeuk Kim 
> > > > 寄件日期: 2024年3月22日 上午 08:29
> > > > 收件者: Hillf Danton 
> > > > 副本: linux-ker...@vger.kernel.org ; Light 
> > > > Hsieh (謝明燈) ; 
> > > > linux-f2fs-devel@lists.sourceforge.net 
> > > > 
> > > > 主旨: Re: [PATCH] f2fs: avoid the deadlock case when stopping discard 
> > > > thread
> > > > 
> > > > 
> > > > External email : Please do not click links or open attachments until 
> > > > you have verified the sender or the content.
> > > > 
> > > > On 03/22, Hillf Danton wrote:
> > > > > On Tue, 19 Mar 2024 17:14:42 -0700 Jaegeuk Kim 
> > > > > > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> > > > > >  - mnt_want_write_file()
> > > > > >    - sb_start_write(SB_FREEZE_WRITE)
> > > > >  __sb_start_write()
> > > > >    percpu_down_read()
> > > > > >                                              - 
> > > > > > sb_start_intwrite(SB_FREEZE_FS);
> > > > >    __sb_start_write()
> > > > >      percpu_down_read()
> > > > >
> > > > > Given lock acquirers for read on both sides, wtf deadlock are you 
> > > > > fixing?
> > > > 
> > > > Damn. I couldn't think _write uses _read sem.
> > > > 
> > > > >
> > > > > >  - f2fs_stop_checkpoint(sbi, false,            : waiting
> > > > > >     STOP_CP_REASON_SHUTDOWN);
> > > > > >  - f2fs_stop_discard_thread(sbi);
> > > > > >    - kthread_stop()
> > > > > >      : waiting
> > > > > >
> > > > > >  - mnt_drop_write_file(filp);
> > > > >
> > > > > More important, feel free to add in spin.
> > > > 
> > > > I posted this patch before Light reported.
> > > > 
> > > > And, in the report, I didn't get this:
> > > > 
> > > > f2fs_ioc_shutdown() --> freeze_bdev() --> freeze_super() --> 
> > > > sb_wait_write(sb, SB_FREEZE_FS) --> ... ->percpu_down_write().
> > > > 
> > > > because f2fs_ioc_shutdown() calls f2fs_stop_discard_thread() after 
> > > > thaw_bdev()
> > > > like this order.
> > > > 
> > > >  -> freeze_bdev()
> > > >  -> thaw_bdev()
> > > >  -> f2fs_stop_discard_thread()
> > > > 
> > > > Am I missing something?
> > > > 
> > > > >
> > > > > Reported-by: "Light Hsieh (謝明燈)" 
> > > > 


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


Re: [f2fs-dev] [PATCH] resize.f2fs: get value from new sb during rebuilding cp

2024-04-09 Thread Jaegeuk Kim
On 04/09, Sheng Yong wrote:
> 
> 
> On 2024/4/9 2:34, Jaegeuk Kim wrote:
> > On 04/08, Sheng Yong wrote:
> > > Althrough old and new sb have the same value for now, it would be better
> > > to build new checkpoint according to new sb.
> > 
> > May need to add assert, if they're different?
> > 
> We could add assert here, but I think it's not that necessary:
> 1. rebuild_checkpoint is only called by resize, and new_sb is copied directly
>from original sb without any changes of these basic attributes.
> 2. for now, new_sb has the same attributes/members with the original one. If
>those attributes are allowed to get changed in the future, the assert needs
>to be removed.
> So how about adding a new helper to check and show the difference between the
> new and original sb?

So, why do we need to change this?

> 
> many thanks,
> shengyong
> > > 
> > > Signed-off-by: Sheng Yong 
> > > ---
> > >   fsck/resize.c | 7 ---
> > >   1 file changed, 4 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/fsck/resize.c b/fsck/resize.c
> > > index 049ddd3..1b4ae85 100644
> > > --- a/fsck/resize.c
> > > +++ b/fsck/resize.c
> > > @@ -481,7 +481,7 @@ static void rebuild_checkpoint(struct f2fs_sb_info 
> > > *sbi,
> > >   set_cp(overprov_segment_count, 
> > > get_cp(rsvd_segment_count));
> > >   set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
> > > - 2 * get_sb(segs_per_sec));
> > > + 2 * get_newsb(segs_per_sec));
> > >   DBG(0, "Info: Overprovision ratio = %.3lf%%\n", 
> > > c.new_overprovision);
> > >   DBG(0, "Info: Overprovision segments = %u (GC reserved = %u)\n",
> > > @@ -551,11 +551,12 @@ static void rebuild_checkpoint(struct f2fs_sb_info 
> > > *sbi,
> > >   
> > > cpu_to_le32(crc);
> > >   /* Write a new checkpoint in the other set */
> > > - new_cp_blk_no = old_cp_blk_no = get_sb(cp_blkaddr);
> > > + old_cp_blk_no = get_sb(cp_blkaddr);
> > > + new_cp_blk_no = get_newsb(cp_blkaddr);
> > >   if (sbi->cur_cp == 2)
> > >   old_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
> > >   else
> > > - new_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
> > > + new_cp_blk_no += 1 << get_newsb(log_blocks_per_seg);
> > >   /* write first cp */
> > >   ret = dev_write_block(new_cp, new_cp_blk_no++);
> > > -- 
> > > 2.40.1


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


[f2fs-dev] [PATCH 3/3] f2fs: fix false alarm on invalid block address

2024-04-09 Thread Jaegeuk Kim
f2fs_ra_meta_pages can try to read ahead on invalid block address which is
not the corruption case.

Fixes: 31f85ccc84b8 ("f2fs: unify the error handling of f2fs_is_valid_blkaddr")
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index eac698b8dd38..b01320502624 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
break;
case META_SIT:
if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
-   goto err;
+   goto check_only;
break;
case META_SSA:
if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
blkaddr < SM_I(sbi)->ssa_blkaddr))
-   goto err;
+   goto check_only;
break;
case META_CP:
if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
blkaddr < __start_cp_addr(sbi)))
-   goto err;
+   goto check_only;
break;
case META_POR:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi)))
-   goto err;
+   goto check_only;
break;
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
@@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info 
*sbi,
return true;
 err:
f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+check_only:
return false;
 }
 
-- 
2.44.0.478.gd926399ef9-goog



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


[f2fs-dev] [PATCH 1/3] f2fs: use folio_test_writeback

2024-04-09 Thread Jaegeuk Kim
Let's convert PageWriteback to folio_test_writeback.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/compress.c |  2 +-
 fs/f2fs/data.c |  3 +--
 fs/f2fs/f2fs.h |  2 +-
 fs/f2fs/gc.c   |  2 +-
 fs/f2fs/inline.c   |  2 +-
 fs/f2fs/inode.c|  3 ++-
 fs/f2fs/node.c |  2 +-
 fs/f2fs/segment.c  | 10 +-
 8 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 8892c8262141..d67c471ab5df 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1484,7 +1484,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
if (!PageDirty(cc->rpages[i]))
goto continue_unlock;
 
-   if (PageWriteback(cc->rpages[i])) {
+   if (folio_test_writeback(page_folio(cc->rpages[i]))) {
if (wbc->sync_mode == WB_SYNC_NONE)
goto continue_unlock;
f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, 
true);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 60056b9a51be..19f1e573297d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2707,8 +2707,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
if (err) {
if (fscrypt_inode_uses_fs_layer_crypto(inode))

fscrypt_finalize_bounce_page(>encrypted_page);
-   if (PageWriteback(page))
-   end_page_writeback(page);
+   end_page_writeback(page);
} else {
set_inode_flag(inode, FI_UPDATE_WRITE);
}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index e9ef971f4dba..dd530dc70005 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4660,7 +4660,7 @@ static inline void f2fs_truncate_meta_inode_pages(struct 
f2fs_sb_info *sbi,
 
page = find_get_page(META_MAPPING(sbi), blkaddr + i);
if (page) {
-   if (PageWriteback(page))
+   if (folio_test_writeback(page_folio(page)))
need_submit = true;
f2fs_put_page(page, 0);
}
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 8852814dab7f..ac4cbbe50c2f 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1434,7 +1434,7 @@ static int move_data_page(struct inode *inode, block_t 
bidx, int gc_type,
goto out;
 
if (gc_type == BG_GC) {
-   if (PageWriteback(page)) {
+   if (folio_test_writeback(page_folio(page))) {
err = -EAGAIN;
goto out;
}
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index ac00423f117b..3d3218a4b29d 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -164,7 +164,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, 
struct page *page)
return -EFSCORRUPTED;
}
 
-   f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page));
+   f2fs_bug_on(F2FS_P_SB(page), folio_test_writeback(page_folio(page)));
 
f2fs_do_read_inline_data(page, dn->inode_page);
set_page_dirty(page);
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 12b1fef31f43..d7a5a88a1a5e 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -161,7 +161,8 @@ bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, 
struct page *page)
if (!f2fs_enable_inode_chksum(sbi, page))
 #else
if (!f2fs_enable_inode_chksum(sbi, page) ||
-   PageDirty(page) || PageWriteback(page))
+   PageDirty(page) ||
+   folio_test_writeback(page_folio(page)))
 #endif
return true;
 
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index bb57bbaff7b4..3b9eb5693683 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1743,7 +1743,7 @@ int f2fs_move_node_page(struct page *node_page, int 
gc_type)
goto release_page;
} else {
/* set page dirty and write it */
-   if (!PageWriteback(node_page))
+   if (!folio_test_writeback(page_folio(node_page)))
set_page_dirty(node_page);
}
 out_page:
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4fd76e867e0a..065fd5919b48 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3612,13 +3612,13 @@ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, 
struct page *page,
mutex_unlock(>curseg_mutex);
f2fs_up_read(_I(sbi)->curseg_lock);
return 0;
+
 out_err:
*new_blkaddr = NULL_ADDR;
up_write(_i->sentry_lock);
mutex_unlock(>curseg_mutex);
f2fs_up_read(_I(sbi)->curseg_lock);
return ret;
-
 }
 
 void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
@@ -3660,8 +3660,7 @@ static void do_write_page(struct f2fs_summary *sum, 
struct f2fs_io_info *fio)

[f2fs-dev] [PATCH 2/3] f2fs: clear writeback when compression failed

2024-04-09 Thread Jaegeuk Kim
Let's stop issuing compressed writes and clear their writeback flags.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/compress.c | 33 +++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index d67c471ab5df..3a8ecc6aee84 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1031,6 +1031,25 @@ static void set_cluster_writeback(struct compress_ctx 
*cc)
}
 }
 
+static void cancel_cluster_writeback(struct compress_ctx *cc, int submitted)
+{
+   int i;
+
+   for (i = 0; i < cc->cluster_size; i++) {
+   if (!cc->rpages[i])
+   continue;
+   if (i < submitted) {
+   if (i)
+   f2fs_wait_on_page_writeback(cc->rpages[i],
+   DATA, true, true);
+   inode_inc_dirty_pages(cc->inode);
+   lock_page(cc->rpages[i]);
+   }
+   clear_page_private_gcing(cc->rpages[i]);
+   end_page_writeback(cc->rpages[i]);
+   }
+}
+
 static void set_cluster_dirty(struct compress_ctx *cc)
 {
int i;
@@ -1232,7 +1251,6 @@ static int f2fs_write_compressed_pages(struct 
compress_ctx *cc,
.page = NULL,
.encrypted_page = NULL,
.compressed_page = NULL,
-   .submitted = 0,
.io_type = io_type,
.io_wbc = wbc,
.encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ?
@@ -1358,7 +1376,15 @@ static int f2fs_write_compressed_pages(struct 
compress_ctx *cc,
fio.compressed_page = cc->cpages[i - 1];
 
cc->cpages[i - 1] = NULL;
+   fio.submitted = 0;
f2fs_outplace_write_data(, );
+   if (unlikely(!fio.submitted)) {
+   cancel_cluster_writeback(cc, i);
+
+   /* To call fscrypt_finalize_bounce_page */
+   i = cc->valid_nr_cpages;
+   goto out_destroy_crypt;
+   }
(*submitted)++;
 unlock_continue:
inode_dec_dirty_pages(cc->inode);
@@ -1392,8 +1418,11 @@ static int f2fs_write_compressed_pages(struct 
compress_ctx *cc,
 out_destroy_crypt:
page_array_free(cc->inode, cic->rpages, cc->cluster_size);
 
-   for (--i; i >= 0; i--)
+   for (--i; i >= 0; i--) {
+   if (!cc->cpages[i])
+   continue;
fscrypt_finalize_bounce_page(>cpages[i]);
+   }
 out_put_cic:
kmem_cache_free(cic_entry_slab, cic);
 out_put_dnode:
-- 
2.44.0.478.gd926399ef9-goog



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


Re: [f2fs-dev] [PATCH] f2fs: don't set RO when shutting down f2fs

2024-04-09 Thread Jaegeuk Kim
On 04/09, Chao Yu wrote:
> On 2024/4/5 3:52, Jaegeuk Kim wrote:
> > Shutdown does not check the error of thaw_super due to readonly, which
> > causes a deadlock like below.
> > 
> > f2fs_ioc_shutdown(F2FS_GOING_DOWN_FULLSYNC)issue_discard_thread
> >   - bdev_freeze
> >- freeze_super
> >   - f2fs_stop_checkpoint()
> >- f2fs_handle_critical_error - sb_start_write
> >  - set RO - waiting
> >   - bdev_thaw
> >- thaw_super_locked
> >  - return -EINVAL, if sb_rdonly()
> >   - f2fs_stop_discard_thread
> >-> wait for kthread_stop(discard_thread);
> > 
> > Reported-by: "Light Hsieh (謝明燈)" 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >   fs/f2fs/super.c | 11 +--
> >   1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index df9765b41dac..ba6288e870c5 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -4135,9 +4135,16 @@ void f2fs_handle_critical_error(struct f2fs_sb_info 
> > *sbi, unsigned char reason,
> > if (shutdown)
> > set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
> > -   /* continue filesystem operators if errors=continue */
> > -   if (continue_fs || f2fs_readonly(sb))
> > +   /*
> > +* Continue filesystem operators if errors=continue. Should not set
> > +* RO by shutdown, since RO bypasses thaw_super which can hang the
> > +* system.
> > +*/
> > +   if (continue_fs || f2fs_readonly(sb) ||
> > +   reason == STOP_CP_REASON_SHUTDOWN) {
> > +   f2fs_warn(sbi, "Stopped filesystem due to readon: %d", reason);
> > return;
> 
> Do we need to set RO after bdev_thaw() in f2fs_do_shutdown()?

IIRC, shutdown doesn't need to set RO as we stopped the checkpoint.
I'm more concerned on any side effect caused by this RO change.

> 
> Thanks,
> 
> > +   }
> > f2fs_warn(sbi, "Remounting filesystem read-only");
> > /*


___
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: don't set RO when shutting down f2fs

2024-04-09 Thread Jaegeuk Kim
Shutdown does not check the error of thaw_super due to readonly, which
causes a deadlock like below.

f2fs_ioc_shutdown(F2FS_GOING_DOWN_FULLSYNC)issue_discard_thread
 - bdev_freeze
  - freeze_super
 - f2fs_stop_checkpoint()
  - f2fs_handle_critical_error - sb_start_write
- set RO - waiting
 - bdev_thaw
  - thaw_super_locked
- return -EINVAL, if sb_rdonly()
 - f2fs_stop_discard_thread
  -> wait for kthread_stop(discard_thread);

Reported-by: "Light Hsieh (謝明燈)" 
Signed-off-by: Jaegeuk Kim 
---

 Change log from v1:
  - use better variable
  - fix typo

 fs/f2fs/super.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8ac4734c2df6..df32573d1f62 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4159,9 +4159,15 @@ void f2fs_handle_critical_error(struct f2fs_sb_info 
*sbi, unsigned char reason,
if (shutdown)
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
 
-   /* continue filesystem operators if errors=continue */
-   if (continue_fs || f2fs_readonly(sb))
+   /*
+* Continue filesystem operators if errors=continue. Should not set
+* RO by shutdown, since RO bypasses thaw_super which can hang the
+* system.
+*/
+   if (continue_fs || f2fs_readonly(sb) || shutdown) {
+   f2fs_warn(sbi, "Stopped filesystem due to reason: %d", reason);
return;
+   }
 
f2fs_warn(sbi, "Remounting filesystem read-only");
/*
-- 
2.44.0.478.gd926399ef9-goog



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


Re: [f2fs-dev] [PATCH] resize.f2fs: get value from new sb during rebuilding cp

2024-04-08 Thread Jaegeuk Kim
On 04/08, Sheng Yong wrote:
> Althrough old and new sb have the same value for now, it would be better
> to build new checkpoint according to new sb.

May need to add assert, if they're different?

> 
> Signed-off-by: Sheng Yong 
> ---
>  fsck/resize.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/fsck/resize.c b/fsck/resize.c
> index 049ddd3..1b4ae85 100644
> --- a/fsck/resize.c
> +++ b/fsck/resize.c
> @@ -481,7 +481,7 @@ static void rebuild_checkpoint(struct f2fs_sb_info *sbi,
>   set_cp(overprov_segment_count, get_cp(rsvd_segment_count));
>  
>   set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
> - 2 * get_sb(segs_per_sec));
> + 2 * get_newsb(segs_per_sec));
>  
>   DBG(0, "Info: Overprovision ratio = %.3lf%%\n", c.new_overprovision);
>   DBG(0, "Info: Overprovision segments = %u (GC reserved = %u)\n",
> @@ -551,11 +551,12 @@ static void rebuild_checkpoint(struct f2fs_sb_info *sbi,
>   cpu_to_le32(crc);
>  
>   /* Write a new checkpoint in the other set */
> - new_cp_blk_no = old_cp_blk_no = get_sb(cp_blkaddr);
> + old_cp_blk_no = get_sb(cp_blkaddr);
> + new_cp_blk_no = get_newsb(cp_blkaddr);
>   if (sbi->cur_cp == 2)
>   old_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
>   else
> - new_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
> + new_cp_blk_no += 1 << get_newsb(log_blocks_per_seg);
>  
>   /* write first cp */
>   ret = dev_write_block(new_cp, new_cp_blk_no++);
> -- 
> 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] f2fs: avoid the deadlock case when stopping discard thread

2024-04-04 Thread Jaegeuk Kim
On 04/03, Light Hsieh (謝明燈) wrote:
> Our log shows that thaw_super_locked() find that sb is readonly, so 
> sb_freeze_unlock() is not invoked.
> 
> static int thaw_super_locked(struct super_block *sb, enum freeze_holder who)
> {
>   ...
>   if (sb_rdonly(sb)) {
> sb->s_writers.freeze_holders &= ~who;
> sb->s_writers.frozen = SB_UNFROZEN;
> wake_up_var(>s_writers.frozen);
> goto out;
>   }
>                ...
>   sb_freeze_unlock(sb, SB_FREEZE_FS);
> out:
>   deactivate_locked_super(sb);
>   return 0;
> }

Thank you. Could you please take a look at this patch?

https://lore.kernel.org/linux-f2fs-devel/20240404195254.556896-1-jaeg...@kernel.org/T/#u

> 
> 寄件者: Jaegeuk Kim 
> 寄件日期: 2024年3月27日 上午 12:52
> 收件者: Light Hsieh (謝明燈) 
> 副本: Hillf Danton ; linux-ker...@vger.kernel.org 
> ; linux-f2fs-devel@lists.sourceforge.net 
> 
> 主旨: Re: 回覆: [PATCH] f2fs: avoid the deadlock case when stopping discard thread
>  
> 
> External email : Please do not click links or open attachments until you have 
> verified the sender or the content.
> On 03/22, Jaegeuk Kim wrote:
> > On 03/22, Light Hsieh (謝明燈) wrote:
> > > I don't see my added log in sb_free_unlock() which will invoke 
> > > percpu_up_write to release the write semaphore.
> > 
> > May I ask more details whether thaw_super() was called or not?
> 
> Ping?
> 
> > 
> > > 
> > > 
> > > 
> > > 寄件者: Jaegeuk Kim 
> > > 寄件日期: 2024年3月22日 上午 08:29
> > > 收件者: Hillf Danton 
> > > 副本: linux-ker...@vger.kernel.org ; Light 
> > > Hsieh (謝明燈) ; 
> > > linux-f2fs-devel@lists.sourceforge.net 
> > > 
> > > 主旨: Re: [PATCH] f2fs: avoid the deadlock case when stopping discard thread
> > > 
> > > 
> > > External email : Please do not click links or open attachments until you 
> > > have verified the sender or the content.
> > > 
> > > On 03/22, Hillf Danton wrote:
> > > > On Tue, 19 Mar 2024 17:14:42 -0700 Jaegeuk Kim 
> > > > > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> > > > >  - mnt_want_write_file()
> > > > >- sb_start_write(SB_FREEZE_WRITE)
> > > >  __sb_start_write()
> > > >percpu_down_read()
> > > > >  - 
> > > > > sb_start_intwrite(SB_FREEZE_FS);
> > > >__sb_start_write()
> > > >  percpu_down_read()
> > > >
> > > > Given lock acquirers for read on both sides, wtf deadlock are you 
> > > > fixing?
> > > 
> > > Damn. I couldn't think _write uses _read sem.
> > > 
> > > >
> > > > >  - f2fs_stop_checkpoint(sbi, false,: waiting
> > > > > STOP_CP_REASON_SHUTDOWN);
> > > > >  - f2fs_stop_discard_thread(sbi);
> > > > >- kthread_stop()
> > > > >  : waiting
> > > > >
> > > > >  - mnt_drop_write_file(filp);
> > > >
> > > > More important, feel free to add in spin.
> > > 
> > > I posted this patch before Light reported.
> > > 
> > > And, in the report, I didn't get this:
> > > 
> > > f2fs_ioc_shutdown() --> freeze_bdev() --> freeze_super() --> 
> > > sb_wait_write(sb, SB_FREEZE_FS) --> ... ->percpu_down_write().
> > > 
> > > because f2fs_ioc_shutdown() calls f2fs_stop_discard_thread() after 
> > > thaw_bdev()
> > > like this order.
> > > 
> > >  -> freeze_bdev()
> > >  -> thaw_bdev()
> > >  -> f2fs_stop_discard_thread()
> > > 
> > > Am I missing something?
> > > 
> > > >
> > > > Reported-by: "Light Hsieh (謝明燈)" 
> > > 


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


[f2fs-dev] [PATCH] f2fs: don't set RO when shutting down f2fs

2024-04-04 Thread Jaegeuk Kim
Shutdown does not check the error of thaw_super due to readonly, which
causes a deadlock like below.

f2fs_ioc_shutdown(F2FS_GOING_DOWN_FULLSYNC)issue_discard_thread
 - bdev_freeze
  - freeze_super
 - f2fs_stop_checkpoint()
  - f2fs_handle_critical_error - sb_start_write
- set RO - waiting
 - bdev_thaw
  - thaw_super_locked
- return -EINVAL, if sb_rdonly()
 - f2fs_stop_discard_thread
  -> wait for kthread_stop(discard_thread);

Reported-by: "Light Hsieh (謝明燈)" 
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/super.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index df9765b41dac..ba6288e870c5 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4135,9 +4135,16 @@ void f2fs_handle_critical_error(struct f2fs_sb_info 
*sbi, unsigned char reason,
if (shutdown)
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
 
-   /* continue filesystem operators if errors=continue */
-   if (continue_fs || f2fs_readonly(sb))
+   /*
+* Continue filesystem operators if errors=continue. Should not set
+* RO by shutdown, since RO bypasses thaw_super which can hang the
+* system.
+*/
+   if (continue_fs || f2fs_readonly(sb) ||
+   reason == STOP_CP_REASON_SHUTDOWN) {
+   f2fs_warn(sbi, "Stopped filesystem due to readon: %d", reason);
return;
+   }
 
f2fs_warn(sbi, "Remounting filesystem read-only");
/*
-- 
2.44.0.478.gd926399ef9-goog



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


[f2fs-dev] [PATCH] f2fs-tools: give 6 sections for overprovision buffer

2024-04-02 Thread Jaegeuk Kim
This addresses high GC cost at runtime.

Signed-off-by: Jaegeuk Kim 
---
 include/f2fs_fs.h  | 8 +++-
 mkfs/f2fs_format.c | 5 +++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index fc56396fa358..870a6e4823d2 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1775,6 +1775,12 @@ static inline uint32_t get_reserved(struct 
f2fs_super_block *sb, double ovp)
return round_up(reserved, segs_per_sec) * segs_per_sec;
 }
 
+static inline uint32_t overprovision_segment_buffer(struct f2fs_super_block 
*sb)
+{
+   /* Give 6 current sections to avoid huge GC overheads. */
+   return 6 * get_sb(segs_per_sec);
+}
+
 static inline double get_best_overprovision(struct f2fs_super_block *sb)
 {
double ovp, candidate, end, diff, space;
@@ -1798,7 +1804,7 @@ static inline double get_best_overprovision(struct 
f2fs_super_block *sb)
if (ovp < 0)
continue;
space = usable_main_segs - max((double)reserved, ovp) -
-   2 * get_sb(segs_per_sec);
+   overprovision_segment_buffer(sb);
if (max_space < space) {
max_space = space;
max_ovp = candidate;
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 8f632f8d74b4..e26a513ed80c 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -778,7 +778,8 @@ static int f2fs_write_check_point_pack(void)
 * In non configurable reserved section case, overprovision
 * segments are always bigger than two sections.
 */
-   if (get_cp(overprov_segment_count) < 2 * get_sb(segs_per_sec)) {
+   if (get_cp(overprov_segment_count) <
+   overprovision_segment_buffer(sb)) {
MSG(0, "\tError: Not enough overprovision segments 
(%u)\n",
get_cp(overprov_segment_count));
goto free_cp_payload;
@@ -787,7 +788,7 @@ static int f2fs_write_check_point_pack(void)
get_cp(rsvd_segment_count));
 } else {
set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
-   2 * get_sb(segs_per_sec));
+   overprovision_segment_buffer(sb));
 }
 
if (f2fs_get_usable_segments(sb) <= get_cp(overprov_segment_count)) {
-- 
2.44.0.478.gd926399ef9-goog



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


Re: [f2fs-dev] 回覆: [PATCH] f2fs: avoid the deadlock case when stopping discard thread

2024-03-26 Thread Jaegeuk Kim
On 03/22, Jaegeuk Kim wrote:
> On 03/22, Light Hsieh (謝明燈) wrote:
> > I don't see my added log in sb_free_unlock() which will invoke 
> > percpu_up_write to release the write semaphore.
> 
> May I ask more details whether thaw_super() was called or not?

Ping?

> 
> > 
> > 
> > ________
> > 寄件者: Jaegeuk Kim 
> > 寄件日期: 2024年3月22日 上午 08:29
> > 收件者: Hillf Danton 
> > 副本: linux-ker...@vger.kernel.org ; Light 
> > Hsieh (謝明燈) ; 
> > linux-f2fs-devel@lists.sourceforge.net 
> > 
> > 主旨: Re: [PATCH] f2fs: avoid the deadlock case when stopping discard thread
> > 
> > 
> > External email : Please do not click links or open attachments until you 
> > have verified the sender or the content.
> > 
> > On 03/22, Hillf Danton wrote:
> > > On Tue, 19 Mar 2024 17:14:42 -0700 Jaegeuk Kim 
> > > > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> > > >  - mnt_want_write_file()
> > > >- sb_start_write(SB_FREEZE_WRITE)
> > >  __sb_start_write()
> > >percpu_down_read()
> > > >  - 
> > > > sb_start_intwrite(SB_FREEZE_FS);
> > >__sb_start_write()
> > >  percpu_down_read()
> > >
> > > Given lock acquirers for read on both sides, wtf deadlock are you fixing?
> > 
> > Damn. I couldn't think _write uses _read sem.
> > 
> > >
> > > >  - f2fs_stop_checkpoint(sbi, false,: waiting
> > > > STOP_CP_REASON_SHUTDOWN);
> > > >  - f2fs_stop_discard_thread(sbi);
> > > >- kthread_stop()
> > > >  : waiting
> > > >
> > > >  - mnt_drop_write_file(filp);
> > >
> > > More important, feel free to add in spin.
> > 
> > I posted this patch before Light reported.
> > 
> > And, in the report, I didn't get this:
> > 
> > f2fs_ioc_shutdown() --> freeze_bdev() --> freeze_super() --> 
> > sb_wait_write(sb, SB_FREEZE_FS) --> ... ->percpu_down_write().
> > 
> > because f2fs_ioc_shutdown() calls f2fs_stop_discard_thread() after 
> > thaw_bdev()
> > like this order.
> > 
> >  -> freeze_bdev()
> >  -> thaw_bdev()
> >  -> f2fs_stop_discard_thread()
> > 
> > Am I missing something?
> > 
> > >
> > > Reported-by: "Light Hsieh (謝明燈)" 
> > 


___
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: avoid the deadlock case when stopping discard thread

2024-03-22 Thread Jaegeuk Kim
On 03/22, Light Hsieh (謝明燈) wrote:
> I don't see my added log in sb_free_unlock() which will invoke 
> percpu_up_write to release the write semaphore.

May I ask more details whether thaw_super() was called or not?

> 
> 
> ____
> 寄件者: Jaegeuk Kim 
> 寄件日期: 2024年3月22日 上午 08:29
> 收件者: Hillf Danton 
> 副本: linux-ker...@vger.kernel.org ; Light Hsieh 
> (謝明燈) ; linux-f2fs-devel@lists.sourceforge.net 
> 
> 主旨: Re: [PATCH] f2fs: avoid the deadlock case when stopping discard thread
> 
> 
> External email : Please do not click links or open attachments until you have 
> verified the sender or the content.
> 
> On 03/22, Hillf Danton wrote:
> > On Tue, 19 Mar 2024 17:14:42 -0700 Jaegeuk Kim 
> > > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> > >  - mnt_want_write_file()
> > >- sb_start_write(SB_FREEZE_WRITE)
> >  __sb_start_write()
> >percpu_down_read()
> > >  - 
> > > sb_start_intwrite(SB_FREEZE_FS);
> >__sb_start_write()
> >  percpu_down_read()
> >
> > Given lock acquirers for read on both sides, wtf deadlock are you fixing?
> 
> Damn. I couldn't think _write uses _read sem.
> 
> >
> > >  - f2fs_stop_checkpoint(sbi, false,: waiting
> > > STOP_CP_REASON_SHUTDOWN);
> > >  - f2fs_stop_discard_thread(sbi);
> > >- kthread_stop()
> > >  : waiting
> > >
> > >  - mnt_drop_write_file(filp);
> >
> > More important, feel free to add in spin.
> 
> I posted this patch before Light reported.
> 
> And, in the report, I didn't get this:
> 
> f2fs_ioc_shutdown() --> freeze_bdev() --> freeze_super() --> 
> sb_wait_write(sb, SB_FREEZE_FS) --> ... ->percpu_down_write().
> 
> because f2fs_ioc_shutdown() calls f2fs_stop_discard_thread() after thaw_bdev()
> like this order.
> 
>  -> freeze_bdev()
>  -> thaw_bdev()
>  -> f2fs_stop_discard_thread()
> 
> Am I missing something?
> 
> >
> > Reported-by: "Light Hsieh (謝明燈)" 
> 


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


Re: [f2fs-dev] 回覆: 回覆: f2fs F2FS_IOC_SHUTDOWN hang issue

2024-03-21 Thread Jaegeuk Kim
On 03/21, Light Hsieh (謝明燈) wrote:
> Do you mean:
> 
> +   /* Avoid the deadlock from F2FS_GOING_DOWN_NOSYNC. */
> +   if (!sb_start_intwrite_trylock(sbi->sb))
> + continue;
> 
> After failure of trylock,  the 'continue'  make code flow goto the line:
>   } while (!kthread_should_stop());
> Since  kthrad_should_stop() is true now, so the issue_discard_thread will end?

Yes, but now I'm confused who is taking write_sem. :(

> 
> Light
> ________
> 寄件者: Jaegeuk Kim 
> 寄件日期: 2024年3月21日 上午 08:39
> 收件者: Light Hsieh (謝明燈) 
> 副本: Ed Tsai (蔡宗軒) ; linux-ker...@vger.kernel.org 
> ; linux-f2fs-devel@lists.sourceforge.net 
> ; linux-fsde...@vger.kernel.org 
> ; Chun-Hung Wu (巫駿宏) 
> 
> 主旨: Re: 回覆: f2fs F2FS_IOC_SHUTDOWN hang issue
> 
> 
> External email : Please do not click links or open attachments until you have 
> verified the sender or the content.
> 
> 
> On 03/20, Light Hsieh (謝明燈) wrote:
> > On 2024/3/20 8:14, Jaegeuk Kim wrote:
> > > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> > >   - mnt_want_write_file()
> > > - sb_start_write(SB_FREEZE_WRITE)
> > >   - 
> > > sb_start_intwrite(SB_FREEZE_FS);
> > >   - f2fs_stop_checkpoint(sbi, false,: waiting
> > >  STOP_CP_REASON_SHUTDOWN);
> > >   - f2fs_stop_discard_thread(sbi);
> > > - kthread_stop()
> > >   : waiting
> > >
> > >   - mnt_drop_write_file(filp);
> > >
> > > Signed-off-by: Jaegeuk Kim 
> >
> > The case I encounter is f2fs_ic_shutdown with arg  
> > F2FS_GOING_DOWN_FULLSYNC, not  F2FS_GOING_DOWN_NOSYNC.
> >
> > Or you are meaning that: besides the kernel patch, I need to change the 
> > invoked F2FS_IOC_SHUTDOWN to use arg F2FS_GOING_DOWN_NOSYNC?
> 
> I think this patch also addresses your case by using trylock.
> 
> >
> >
> >
> 


___
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: avoid the deadlock case when stopping discard thread

2024-03-21 Thread Jaegeuk Kim
On 03/22, Hillf Danton wrote:
> On Tue, 19 Mar 2024 17:14:42 -0700 Jaegeuk Kim 
> > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> >  - mnt_want_write_file()
> >- sb_start_write(SB_FREEZE_WRITE)
>__sb_start_write()
>  percpu_down_read()
> >  - 
> > sb_start_intwrite(SB_FREEZE_FS);
>  __sb_start_write()
>percpu_down_read()
> 
> Given lock acquirers for read on both sides, wtf deadlock are you fixing?

Damn. I couldn't think _write uses _read sem.

> 
> >  - f2fs_stop_checkpoint(sbi, false,: waiting
> > STOP_CP_REASON_SHUTDOWN);
> >  - f2fs_stop_discard_thread(sbi);
> >- kthread_stop()
> >  : waiting
> > 
> >  - mnt_drop_write_file(filp);
> 
> More important, feel free to add in spin.

I posted this patch before Light reported.

And, in the report, I didn't get this:

f2fs_ioc_shutdown() --> freeze_bdev() --> freeze_super() --> sb_wait_write(sb, 
SB_FREEZE_FS) --> ... ->percpu_down_write().

because f2fs_ioc_shutdown() calls f2fs_stop_discard_thread() after thaw_bdev()
like this order.

 -> freeze_bdev()
 -> thaw_bdev()
 -> f2fs_stop_discard_thread()

Am I missing something?

> 
>   Reported-by: "Light Hsieh (謝明燈)" 


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


Re: [f2fs-dev] 回覆: f2fs F2FS_IOC_SHUTDOWN hang issue

2024-03-20 Thread Jaegeuk Kim
On 03/20, Light Hsieh (謝明燈) wrote:
> On 2024/3/20 8:14, Jaegeuk Kim wrote:
> > f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
> >   - mnt_want_write_file()
> >     - sb_start_write(SB_FREEZE_WRITE)
> >                                               - 
> > sb_start_intwrite(SB_FREEZE_FS);
> >   - f2fs_stop_checkpoint(sbi, false,            : waiting
> >      STOP_CP_REASON_SHUTDOWN);
> >   - f2fs_stop_discard_thread(sbi);
> >     - kthread_stop()
> >       : waiting
> > 
> >   - mnt_drop_write_file(filp);
> > 
> > Signed-off-by: Jaegeuk Kim 
> 
> The case I encounter is f2fs_ic_shutdown with arg  F2FS_GOING_DOWN_FULLSYNC, 
> not  F2FS_GOING_DOWN_NOSYNC.
> 
> Or you are meaning that: besides the kernel patch, I need to change the 
> invoked F2FS_IOC_SHUTDOWN to use arg F2FS_GOING_DOWN_NOSYNC?

I think this patch also addresses your case by using trylock.

> 
> 
> 


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


Re: [f2fs-dev] f2fs F2FS_IOC_SHUTDOWN hang issue

2024-03-20 Thread Jaegeuk Kim
Can you try this?

https://patchwork.kernel.org/project/f2fs/patch/20240320001442.497813-1-jaeg...@kernel.org/

On 03/20, Light Hsieh (謝明燈) wrote:
> Hi Jaegeuk:
> 
> We encounter a deadlock issue when Android is going to poweroff.
> Please help check.
> 
> When unmounting of  f2fs partition fail in Android poweroff procedure, init 
> thread (pid = 1) invoke F2FS_IOC_SHUTDOWN  ioctl with arg 
> F2FS_GOING_DOWN_FULLSYNC.
> This ioctl cause down_write of a semaphore in the following call sequence:
> f2fs_ioc_shutdown() --> freeze_bdev() --> freeze_super() --> 
> sb_wait_write(sb, SB_FREEZE_FS) --> ... ->percpu_down_write().
> 
> f2fs_ioc_shutdown() will later invoke f2fs_stop_discard_thread() and wait for 
> stopping of f2fs_discard thread in the following call sequence:
> f2fs_ioc_shutdown() -->f2fs_stop_discard_thread() 
> -->kthread_stop(discard_thread) --> wait_for_completion().
> That is, init thread go sleep with a write semaphore.
> 
> f2fs_discard thread is then waken up to process f2fs discard.
> However, f2fs_discard threshold may then hang because failing to get the 
> semaphore aleady obtained by the slept init thread:
> issue_discard_thread() --> sb_start_intwrite() -->sb_start_write(sb, 
> SB_FREEZE_FS) --> percpu_down_read()
> 
> Light


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


[f2fs-dev] [PATCH] f2fs: avoid the deadlock case when stopping discard thread

2024-03-19 Thread Jaegeuk Kim
f2fs_ioc_shutdown(F2FS_GOING_DOWN_NOSYNC)  issue_discard_thread
 - mnt_want_write_file()
   - sb_start_write(SB_FREEZE_WRITE)
 - sb_start_intwrite(SB_FREEZE_FS);
 - f2fs_stop_checkpoint(sbi, false,: waiting
STOP_CP_REASON_SHUTDOWN);
 - f2fs_stop_discard_thread(sbi);
   - kthread_stop()
 : waiting

 - mnt_drop_write_file(filp);

Signed-off-by: Jaegeuk Kim 
---
 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 4fd76e867e0a..088b8c48cffa 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1923,7 +1923,9 @@ static int issue_discard_thread(void *data)
continue;
}
 
-   sb_start_intwrite(sbi->sb);
+   /* Avoid the deadlock from F2FS_GOING_DOWN_NOSYNC. */
+   if (!sb_start_intwrite_trylock(sbi->sb))
+   continue;
 
issued = __issue_discard_cmd(sbi, );
if (issued > 0) {
-- 
2.44.0.291.gc1ea87d7ee-goog



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


[f2fs-dev] [GIT PULL] f2fs update for 6.9-rc1

2024-03-18 Thread Jaegeuk Kim
Hi Linus,

Could you please consider this pull request?

Thanks,

The following changes since commit 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478:

  Linux 6.8-rc3 (2024-02-04 12:20:36 +)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git 
tags/f2fs-for-6.9-rc1

for you to fetch changes up to eb70d5a6c932d9d23f4bb3e7b83782c21ac4b064:

  f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault (2024-03-14 
09:14:53 -0700)


f2fs update for 6.9-rc1

In this round, there are a number of updates on mainly two areas: Zoned block
device support and Per-file compression. For example, we've found several issues
to support Zoned block device especially having large sections regarding to GC
and file pinning used for Android devices. In compression side, we've fixed many
corner race conditions that had broken the design assumption.

Enhancement:
 - Support file pinning for Zoned block device having large section
 - Enhance the data recovery after sudden power cut on Zoned block device
 - Add more error injection cases to easily detect the kernel panics
 - add a proc entry show the entire disk layout
 - Improve various error paths paniced by BUG_ON in block allocation and GC
 - support SEEK_DATA and SEEK_HOLE for compression files

Bug fix:
 - fix to avoid use-after-free issue in f2fs_filemap_fault
 - fix some race conditions to break the atomic write design assumption
 - fix to truncate meta inode pages forcely
 - resolve various per-file compression issues wrt the space management and
   compression policies
 - fix some swap-related bugs

In addition, we removed deprecated codes such as io_bits and heap_allocation,
and also fixed minor error handling routines with neat debugging messages.


Chao Yu (29):
  f2fs: compress: fix to guarantee persisting compressed blocks by CP
  f2fs: compress: fix to cover normal cluster write with cp_rwsem
  f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode
  f2fs: fix to remove unnecessary f2fs_bug_on() to avoid panic
  f2fs: introduce FAULT_BLKADDR_CONSISTENCE
  f2fs: zone: fix to wait completion of last bio in zone correctly
  f2fs: support printk_ratelimited() in f2fs_printk()
  f2fs: use f2fs_err_ratelimited() to avoid redundant logs
  f2fs: compress: fix to cover f2fs_disable_compressed_file() w/ i_sem
  f2fs: fix to avoid potential panic during recovery
  f2fs: fix to create selinux label during whiteout initialization
  f2fs: compress: fix to check zstd compress level correctly in mount option
  f2fs: introduce get_available_block_count() for cleanup
  f2fs: delete f2fs_get_new_segment() declaration
  f2fs: fix to handle segment allocation failure correctly
  f2fs: compress: fix to check compress flag w/ .i_sem lock
  f2fs: introduce FAULT_NO_SEGMENT
  f2fs: fix to use correct segment type in f2fs_allocate_data_block()
  f2fs: fix to check return value in f2fs_insert_range()
  f2fs: ro: compress: fix to avoid caching unaligned extent
  f2fs: ro: don't start discard thread for readonly image
  f2fs: fix blkofs_end correctly in f2fs_migrate_blocks()
  f2fs: relocate f2fs_precache_extents() in f2fs_swap_activate()
  f2fs: clean up new_curseg()
  f2fs: fix to reset fields for unloaded curseg
  f2fs: introduce SEGS_TO_BLKS/BLKS_TO_SEGS for cleanup
  f2fs: fix to truncate meta inode pages forcely
  f2fs: zone: fix to remove pow2 check condition for zoned block device
  f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault

Daeho Jeong (4):
  f2fs: separate f2fs_gc_range() to use GC for a range
  f2fs: support SEEK_DATA and SEEK_HOLE for compression files
  f2fs: support file pinning for zoned devices
  f2fs: prevent atomic write on pinned file

HuangXiaojia (1):
  f2fs: Use folio in f2fs_read_merkle_tree_page

Jaegeuk Kim (10):
  f2fs: remove unnecessary f2fs_put_page in f2fs_rename
  f2fs: deprecate io_bits
  f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC
  f2fs: kill heap-based allocation
  f2fs: prevent an f2fs_gc loop during disable_checkpoint
  f2fs: check number of blocks in a current section
  f2fs: fix write pointers all the time
  f2fs: print zone status in string and some log
  f2fs: allow to mount if cap is 100
  f2fs: add a proc entry show disk layout

Jeffrey Hugo (1):
  f2fs: doc: Fix bouncing email address for Sahitya Tummala

Sheng Yong (1):
  f2fs: compress: fix to check unreleased compressed cluster

Sunmin Jeong (2):
  f2fs: mark inode dirty for FI_ATOMIC_COMMITTED flag
  f2fs: truncate page cache before clearing flags when aborting atomic write

Wenjie Qi (1):
  f2fs: fix NULL pointer dereference in f2fs_submit_page_write()

Wu Bo (1):
  f2fs

Re: [f2fs-dev] [PATCH] f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault

2024-03-14 Thread Jaegeuk Kim
On 03/14, Chao Yu wrote:
> syzbot reports a f2fs bug as below:
> 
> BUG: KASAN: slab-use-after-free in f2fs_filemap_fault+0xd1/0x2c0 
> fs/f2fs/file.c:49
> Read of size 8 at addr 88807bb22680 by task syz-executor184/5058
> 
> CPU: 0 PID: 5058 Comm: syz-executor184 Not tainted 
> 6.7.0-syzkaller-09928-g052d534373b7 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS 
> Google 11/17/2023
> Call Trace:
>  
>  __dump_stack lib/dump_stack.c:88 [inline]
>  dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106
>  print_address_description mm/kasan/report.c:377 [inline]
>  print_report+0x163/0x540 mm/kasan/report.c:488
>  kasan_report+0x142/0x170 mm/kasan/report.c:601
>  f2fs_filemap_fault+0xd1/0x2c0 fs/f2fs/file.c:49
>  __do_fault+0x131/0x450 mm/memory.c:4376
>  do_shared_fault mm/memory.c:4798 [inline]
>  do_fault mm/memory.c:4872 [inline]
>  do_pte_missing mm/memory.c:3745 [inline]
>  handle_pte_fault mm/memory.c:5144 [inline]
>  __handle_mm_fault+0x23b7/0x72b0 mm/memory.c:5285
>  handle_mm_fault+0x27e/0x770 mm/memory.c:5450
>  do_user_addr_fault arch/x86/mm/fault.c:1364 [inline]
>  handle_page_fault arch/x86/mm/fault.c:1507 [inline]
>  exc_page_fault+0x456/0x870 arch/x86/mm/fault.c:1563
>  asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:570
> 
> The root cause is: in f2fs_filemap_fault(), vmf->vma may be not alive after
> filemap_fault(), so it may cause use-after-free issue when accessing
> vmf->vma->vm_flags in trace_f2fs_filemap_fault(). So it needs to keep vm_flags
> in separated temporary variable for tracepoint use.
> 
> Fixes: 87f3afd366f7 ("f2fs: add tracepoint for f2fs_vm_page_mkwrite()")
> Reported-and-tested-by: syzbot+763afad57075d3f86...@syzkaller.appspotmail.com
> Closes: https://lore.kernel.org/lkml/e8222b060f00d...@google.com
> Cc: Ed Tsai 
> Cc: Hillf Danton 

Suggested-by: Hillf Danton 

I modified to "Suggested-by". Please let me know if this doesn't work.

> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/file.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index a47c57e813bb..c19e55a3e50e 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -39,6 +39,7 @@
>  static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
>  {
>   struct inode *inode = file_inode(vmf->vma->vm_file);
> + vm_flags_t flags = vmf->vma->vm_flags;
>   vm_fault_t ret;
>  
>   ret = filemap_fault(vmf);
> @@ -46,7 +47,7 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
>   f2fs_update_iostat(F2FS_I_SB(inode), inode,
>   APP_MAPPED_READ_IO, F2FS_BLKSIZE);
>  
> - trace_f2fs_filemap_fault(inode, vmf->pgoff, vmf->vma->vm_flags, ret);
> + trace_f2fs_filemap_fault(inode, vmf->pgoff, flags, ret);
>  
>   return ret;
>  }
> -- 
> 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] f2fs: fix to return EIO when reading after device removal

2024-03-12 Thread Jaegeuk Kim
So, I was wondering we can give data even in cp_error case.

On 03/12, Chao Yu wrote:
> Ping,
> 
> Jaegeuk, do you have any comments on this patch?
> 
> Thanks,
> 
> On 2024/2/26 16:00, Chao Yu wrote:
> > Any comments?
> > 
> > Thanks,
> > 
> > On 2024/2/19 11:13, Chao Yu wrote:
> > > On 2024/2/8 8:18, Jaegeuk Kim wrote:
> > > > On 02/06, Chao Yu wrote:
> > > > > generic/730 2s ... - output mismatch (see 
> > > > > /media/fstests/results//generic/730.out.bad)
> > > > >  --- tests/generic/730.out    2023-08-07 01:39:51.055568499 +
> > > > >  +++ /media/fstests/results//generic/730.out.bad    2024-02-06 
> > > > > 02:26:43.0 +
> > > > >  @@ -1,2 +1 @@
> > > > >   QA output created by 730
> > > > >  -cat: -: Input/output error
> > > > >  ...
> > > > >  (Run 'diff -u /media/fstests/tests/generic/730.out 
> > > > > /media/fstests/results//generic/730.out.bad'  to see the entire diff)
> > > > > Ran: generic/730
> > > > > Failures: generic/730
> > > > > Failed 1 of 1 tests
> > > > > 
> > > > > This patch adds a check condition in f2fs_file_read_iter() to
> > > > > detect cp_error status after device removal, and retrurn -EIO
> > > > > for such case.
> > > > 
> > > > Can we check device removal?
> > > 
> > > We can use blk_queue_dying() to detect device removal, but, IMO, device
> > > removal can almost not happen in Android, not sure for distros or server,
> > > do you want to add this check condition into f2fs_cp_error()?
> > > 
> > > Thanks,
> > > 
> > > > 
> > > > > 
> > > > > Signed-off-by: Chao Yu 
> > > > > ---
> > > > >   fs/f2fs/file.c | 3 +++
> > > > >   1 file changed, 3 insertions(+)
> > > > > 
> > > > > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > > > > index 45b7e3610b0f..9e4386d4144c 100644
> > > > > --- a/fs/f2fs/file.c
> > > > > +++ b/fs/f2fs/file.c
> > > > > @@ -4462,6 +4462,9 @@ static ssize_t f2fs_file_read_iter(struct kiocb 
> > > > > *iocb, struct iov_iter *to)
> > > > >   const loff_t pos = iocb->ki_pos;
> > > > >   ssize_t ret;
> > > > > +    if (unlikely(f2fs_cp_error(F2FS_I_SB(inode
> > > > > +    return -EIO;
> > > > > +
> > > > >   if (!f2fs_is_compress_backend_ready(inode))
> > > > >   return -EOPNOTSUPP;
> > > > > -- 
> > > > > 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


___
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: support .shutdown in f2fs_sops

2024-03-12 Thread Jaegeuk Kim
Will check this after merge window.

On 03/12, Chao Yu wrote:
> Ping,
> 
> On 2024/2/29 22:38, Chao Yu wrote:
> > Support .shutdown callback in f2fs_sops, then, it can be called to
> > shut down the file system when underlying block device is marked dead.
> > 
> > Signed-off-by: Chao Yu 
> > ---
> >   fs/f2fs/f2fs.h  |  2 ++
> >   fs/f2fs/file.c  | 70 ++---
> >   fs/f2fs/super.c |  6 +
> >   3 files changed, 51 insertions(+), 27 deletions(-)
> > 
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index 85eb9a8a5ed3..80789255bf68 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -3506,6 +3506,8 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct 
> > dentry *dentry,
> >  struct iattr *attr);
> >   int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t 
> > pg_end);
> >   void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
> > +int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,
> > +   bool readonly);
> >   int f2fs_precache_extents(struct inode *inode);
> >   int f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
> >   int f2fs_fileattr_set(struct mnt_idmap *idmap,
> > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > index 4ca6c693b33a..d223175b3d5c 100644
> > --- a/fs/f2fs/file.c
> > +++ b/fs/f2fs/file.c
> > @@ -2226,34 +2226,13 @@ static int f2fs_ioc_abort_atomic_write(struct file 
> > *filp)
> > return ret;
> >   }
> > -static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
> > +int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,
> > +   bool readonly)
> >   {
> > -   struct inode *inode = file_inode(filp);
> > -   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> > struct super_block *sb = sbi->sb;
> > -   __u32 in;
> > int ret = 0;
> > -   if (!capable(CAP_SYS_ADMIN))
> > -   return -EPERM;
> > -
> > -   if (get_user(in, (__u32 __user *)arg))
> > -   return -EFAULT;
> > -
> > -   if (in != F2FS_GOING_DOWN_FULLSYNC) {
> > -   ret = mnt_want_write_file(filp);
> > -   if (ret) {
> > -   if (ret == -EROFS) {
> > -   ret = 0;
> > -   f2fs_stop_checkpoint(sbi, false,
> > -   STOP_CP_REASON_SHUTDOWN);
> > -   trace_f2fs_shutdown(sbi, in, ret);
> > -   }
> > -   return ret;
> > -   }
> > -   }
> > -
> > -   switch (in) {
> > +   switch (flag) {
> > case F2FS_GOING_DOWN_FULLSYNC:
> > ret = bdev_freeze(sb->s_bdev);
> > if (ret)
> > @@ -2292,6 +2271,9 @@ static int f2fs_ioc_shutdown(struct file *filp, 
> > unsigned long arg)
> > goto out;
> > }
> > +   if (readonly)
> > +   goto out;
> > +
> > f2fs_stop_gc_thread(sbi);
> > f2fs_stop_discard_thread(sbi);
> > @@ -2300,10 +2282,44 @@ static int f2fs_ioc_shutdown(struct file *filp, 
> > unsigned long arg)
> > f2fs_update_time(sbi, REQ_TIME);
> >   out:
> > -   if (in != F2FS_GOING_DOWN_FULLSYNC)
> > -   mnt_drop_write_file(filp);
> > -   trace_f2fs_shutdown(sbi, in, ret);
> > +   trace_f2fs_shutdown(sbi, flag, ret);
> > +
> > +   return ret;
> > +}
> > +
> > +static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
> > +{
> > +   struct inode *inode = file_inode(filp);
> > +   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> > +   __u32 in;
> > +   int ret;
> > +   bool need_drop = false, readonly = false;
> > +
> > +   if (!capable(CAP_SYS_ADMIN))
> > +   return -EPERM;
> > +
> > +   if (get_user(in, (__u32 __user *)arg))
> > +   return -EFAULT;
> > +
> > +   if (in != F2FS_GOING_DOWN_FULLSYNC) {
> > +   ret = mnt_want_write_file(filp);
> > +   if (ret) {
> > +   if (ret != -EROFS)
> > +   return ret;
> > +
> > +   /* fallback to nosync shutdown for readonly fs */
> > +   in = F2FS_GOING_DOWN_NOSYNC;
> > +   readonly = true;
> > +   } else {
> > +   need_drop = true;
> > +   }
> > +   }
> > +
> > +   ret = f2fs_do_shutdown(sbi, in, readonly);
> > +
> > +   if (need_drop)
> > +   mnt_drop_write_file(filp);
> > return ret;
> >   }
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index 78a76583a4aa..0676c2dcbbf7 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -2547,6 +2547,11 @@ static int f2fs_remount(struct super_block *sb, int 
> > *flags, char *data)
> > return err;
> >   }
> > +static void f2fs_shutdown(struct super_block *sb)
> > +{
> > +   f2fs_do_shutdown(F2FS_SB(sb), F2FS_GOING_DOWN_NOSYNC, false);
> > +}
> > +
> >   #ifdef CONFIG_QUOTA
> >   static bool f2fs_need_recovery(struct f2fs_sb_info *sbi)
> >   {
> > @@ -3146,6 +3151,7 

Re: [f2fs-dev] [syzbot] [f2fs?] KASAN: slab-use-after-free Read in f2fs_filemap_fault

2024-03-12 Thread Jaegeuk Kim
On 03/12, Ed Tsai (蔡宗軒) wrote:
> On Mon, 2024-01-15 at 20:05 +0800, Hillf Danton wrote:
> > 
> > ...
> > 
> > --- x/fs/f2fs/file.c
> > +++ y/fs/f2fs/file.c
> > @@ -39,6 +39,7 @@
> >  static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
> >  {
> > struct inode *inode = file_inode(vmf->vma->vm_file);
> > +   vm_flags_t flags = vmf->vma->vm_flags;
> > vm_fault_t ret;
> >  
> > ret = filemap_fault(vmf);
> > @@ -46,7 +47,7 @@ static vm_fault_t f2fs_filemap_fault(str
> > f2fs_update_iostat(F2FS_I_SB(inode), inode,
> > APP_MAPPED_READ_IO,
> > F2FS_BLKSIZE);
> >  
> > -   trace_f2fs_filemap_fault(inode, vmf->pgoff, vmf->vma-
> > >vm_flags, ret);
> > +   trace_f2fs_filemap_fault(inode, vmf->pgoff, flags, ret);
> >  
> > return ret;
> >  }
> > --
> 
> Hi Jaegeuk,
> 
> We recently encountered this slabe-use-after-free issue in KASAN as
> well. Could you please review the patch above and merge it into f2fs?

Where is the patch?

> 
> Best,
> Ed
> 
> ==
> [29195.369964][T31720] BUG: KASAN: slab-use-after-free in
> f2fs_filemap_fault+0x50/0xe0
> [29195.370971][T31720] Read at addr f780454ebde0 by task AsyncTask
> #11/31720
> [29195.371881][T31720] Pointer tag: [f7], memory tag: [f1]
> [29195.372549][T31720] 
> [29195.372838][T31720] CPU: 2 PID: 31720 Comm: AsyncTask #11 Tainted:
> GW  OE  6.6.17-android15-0-gcb5ba718a525 #1
> [29195.374862][T31720] Call trace:
> [29195.375268][T31720]  dump_backtrace+0xec/0x138
> [29195.375848][T31720]  show_stack+0x18/0x24
> [29195.376365][T31720]  dump_stack_lvl+0x50/0x6c
> [29195.376943][T31720]  print_report+0x1b0/0x714
> [29195.377520][T31720]  kasan_report+0xc4/0x124
> [29195.378076][T31720]  __do_kernel_fault+0xb8/0x26c
> [29195.378694][T31720]  do_bad_area+0x30/0xdc
> [29195.379226][T31720]  do_tag_check_fault+0x20/0x34
> [29195.379834][T31720]  do_mem_abort+0x58/0x104
> [29195.380388][T31720]  el1_abort+0x3c/0x5c
> [29195.380899][T31720]  el1h_64_sync_handler+0x54/0x90
> [29195.381529][T31720]  el1h_64_sync+0x68/0x6c
> [29195.382069][T31720]  f2fs_filemap_fault+0x50/0xe0
> [29195.382678][T31720]  __do_fault+0xc8/0xfc
> [29195.383209][T31720]  handle_mm_fault+0xb44/0x10c4
> [29195.383816][T31720]  do_page_fault+0x294/0x48c
> [29195.384395][T31720]  do_translation_fault+0x38/0x54
> [29195.385023][T31720]  do_mem_abort+0x58/0x104
> [29195.385577][T31720]  el0_da+0x44/0x78
> [29195.386057][T31720]  el0t_64_sync_handler+0x98/0xbc
> [29195.386688][T31720]  el0t_64_sync+0x1a8/0x1ac
> [29195.387249][T31720] 
> [29195.387534][T31720] Allocated by task 14784:
> [29195.388085][T31720]  kasan_save_stack+0x40/0x70
> [29195.388672][T31720]  save_stack_info+0x34/0x128
> [29195.389259][T31720]  kasan_save_alloc_info+0x14/0x20
> [29195.389901][T31720]  __kasan_slab_alloc+0x168/0x174
> [29195.390530][T31720]  slab_post_alloc_hook+0x88/0x3a4
> [29195.391168][T31720]  kmem_cache_alloc+0x18c/0x2c8
> [29195.391771][T31720]  vm_area_alloc+0x2c/0xe8
> [29195.392327][T31720]  mmap_region+0x440/0xa94
> [29195.392888][T31720]  do_mmap+0x3d0/0x524
> [29195.393399][T31720]  vm_mmap_pgoff+0x1a0/0x1f8
> [29195.393980][T31720]  ksys_mmap_pgoff+0x78/0xf4
> [29195.394557][T31720]  __arm64_sys_mmap+0x34/0x44
> [29195.395138][T31720]  invoke_syscall+0x58/0x114
> [29195.395727][T31720]  el0_svc_common+0x80/0xe0
> [29195.396292][T31720]  do_el0_svc+0x1c/0x28
> [29195.396812][T31720]  el0_svc+0x38/0x68
> [29195.397302][T31720]  el0t_64_sync_handler+0x68/0xbc
> [29195.397932][T31720]  el0t_64_sync+0x1a8/0x1ac
> [29195.398492][T31720] 
> [29195.398778][T31720] Freed by task 0:
> [29195.399240][T31720]  kasan_save_stack+0x40/0x70
> [29195.399825][T31720]  save_stack_info+0x34/0x128
> [29195.400412][T31720]  kasan_save_free_info+0x18/0x28
> [29195.401043][T31720]  kasan_slab_free+0x254/0x25c
> [29195.401682][T31720]  __kasan_slab_free+0x10/0x20
> [29195.402278][T31720]  slab_free_freelist_hook+0x174/0x1e0
> [29195.402961][T31720]  kmem_cache_free+0xc4/0x348
> [29195.403544][T31720]  __vm_area_free+0x84/0xa4
> [29195.404103][T31720]  vm_area_free_rcu_cb+0x10/0x20
> [29195.404719][T31720]  rcu_do_batch+0x214/0x720
> [29195.405284][T31720]  rcu_core+0x1b0/0x408
> [29195.405800][T31720]  rcu_core_si+0x10/0x20
> [29195.406348][T31720]  __do_softirq+0x120/0x3f4
> [29195.406907][T31720] 
> [29195.407191][T31720] The buggy address belongs to the object at
> ff80454ebdc0
> [29195.407191][T31720]  which belongs to the cache vm_area_struct of
> size 176
> [29195.408978][T31720] The buggy address is located 32 bytes inside of
> [29195.408978][T31720]  176-byte region [ff80454ebdc0,
> ff80454ebe70)
> [29195.410625][T31720] 
> [29195.410911][T31720] The buggy address belongs to the physical page:
> [29195.411709][T31720] page:58f0f2f1 refcount:1 mapcount:0
> mapping: index:0x0 pfn:0xc54eb
> 

Re: [f2fs-dev] [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()

2024-03-11 Thread Jaegeuk Kim
On 03/10, David Laight wrote:
> From: Roman Smirnov
> > Sent: 05 March 2024 08:10
> > 
> > Cast expression type to unsigned long in __count_extent_cache()
> > to prevent integer overflow.
> > 
> > Found by Linux Verification Center (linuxtesting.org) with Svace.
> 
> Another broken analysis tool :-)
> 
> > Signed-off-by: Roman Smirnov 
> > Reviewed-by: Sergey Shtylyov 
> > ---
> >  fs/f2fs/shrinker.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
> > index 83d6fb97dcae..bb86a06c5d5e 100644
> > --- a/fs/f2fs/shrinker.c
> > +++ b/fs/f2fs/shrinker.c
> > @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct 
> > f2fs_sb_info *sbi,
> >  {
> > struct extent_tree_info *eti = >extent_tree[type];
> > 
> > -   return atomic_read(>total_zombie_tree) +
> > +   return (unsigned long)atomic_read(>total_zombie_tree) +
> > atomic_read(>total_ext_node);
> 
> Makes diddly-squit difference.
> 
> Both total_zombie_tree and totat_ext_node are 'int'.
> If they are large enough that their sum wraps then the values
> can individually wrap (to negative values).
> 
> You really don't want to cast 'int' to 'unsigned long' here
> at all - implicitly or explicitly.
> The cast will first promote 'int' to 'signed long'.
> So a negative value will get sign extended to a very big value.

I thought, since total_zombie_tree won't get overflowed theoritically, the first
cast to (unsigned long) could expand the space to cover the following
total_ext_node.

> 
> The best you can hope for is a 33bit result from wrapped 32bit
> signed counters.
> To get that you need to convert 'int' => 'unsigned int' => 'unsigned long'.
> One way would be:
>   return (atomic_read(>total_zombie_tree) + 0u + 0ul) +
>   (atomic_read(>total_ext_node) + 0u);
> 
> Although changing the return type to 'unsigned int' would probably
> be better.
> I don't know what the values are, but if they are stats counters
> then that would give a value that nicely wraps at 2^32 rather
> that the strange wrap that the sum of two wrapping 32bit counters
> has.
> 
> OTOH it may be that they are counts - and just can't get any where
> near that big.
> 
>   David
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 
> 1PT, UK
> Registration No: 1397386 (Wales)


___
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 truncate meta inode pages forcely

2024-03-07 Thread Jaegeuk Kim
On 03/07, Chao Yu wrote:
> Below race case can cause data corruption:
> 
> Thread A  GC thread
> - f2fs_inplace_write_data
>   - gc_data_segment
>- ra_data_block
> - locked meta_inode page
>  - invalidate_mapping_pages
>  : fail to invalidate meta_inode page
>due to lock failure or dirty|writeback
>status

Wasn't the original data page locked in both cases?

>  - f2fs_submit_page_bio
>  : write last dirty data to old blkaddr
>- move_data_block
> - load old data from meta_inode page
> - f2fs_submit_page_write
> : write old data to new blkaddr
> 
> Because invalidate_mapping_pages() will skip invalidating page when the
> page has unclear status including locked, dirty, writeback and so on, so
> we need to use truncate_inode_pages_range() instead of
> invalidate_mapping_pages() to make sure meta_inode page will be dropped.
> 
> Fixes: 6aa58d8ad20a ("f2fs: readahead encrypted block during GC")
> Fixes: e3b49ea36802 ("f2fs: invalidate META_MAPPING before IPU/DIO write")
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/checkpoint.c|  5 +++--
>  fs/f2fs/f2fs.h  | 28 +++-
>  fs/f2fs/segment.c   |  5 ++---
>  include/linux/f2fs_fs.h |  1 +
>  4 files changed, 33 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index a09a9609e228..55b7d2cf030f 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -1598,8 +1598,9 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, 
> struct cp_control *cpc)
>*/
>   if (f2fs_sb_has_encrypt(sbi) || f2fs_sb_has_verity(sbi) ||
>   f2fs_sb_has_compression(sbi))
> - invalidate_mapping_pages(META_MAPPING(sbi),
> - MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1);
> + f2fs_bug_on(sbi,
> + invalidate_inode_pages2_range(META_MAPPING(sbi),
> + MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1));
>  
>   f2fs_release_ino_entry(sbi, false);
>  
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 4836e7cb0efe..9814e5981a6a 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -4655,10 +4655,36 @@ static inline bool f2fs_is_readonly(struct 
> f2fs_sb_info *sbi)
>   return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
>  }
>  
> +static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi,
> + block_t blkaddr, unsigned int cnt)
> +{
> + bool need_submit = false;
> + int i = 0;
> +
> + do {
> + struct page *page;
> +
> + page = find_get_page(META_MAPPING(sbi), blkaddr + i);
> + if (page) {
> + if (PageWriteback(page))
> + need_submit = true;
> + f2fs_put_page(page, 0);
> + }
> + } while (++i < cnt && !need_submit);
> +
> + if (need_submit)
> + f2fs_submit_merged_write_cond(sbi, sbi->meta_inode,
> + NULL, 0, DATA);
> +
> + truncate_inode_pages_range(META_MAPPING(sbi),
> + F2FS_BLK_TO_BYTES((loff_t)blkaddr),
> + F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1)));
> +}
> +
>  static inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi,
>   block_t blkaddr)
>  {
> - invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr);
> + f2fs_truncate_meta_inode_pages(sbi, blkaddr, 1);
>   f2fs_invalidate_compress_page(sbi, blkaddr);
>  }
>  
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 4ff3b2d14ddf..20af48d7f784 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3741,8 +3741,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
>   }
>  
>   if (fio->post_read)
> - invalidate_mapping_pages(META_MAPPING(sbi),
> - fio->new_blkaddr, fio->new_blkaddr);
> + f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1);
>  
>   stat_inc_inplace_blocks(fio->sbi);
>  
> @@ -3932,7 +3931,7 @@ void f2fs_wait_on_block_writeback_range(struct inode 
> *inode, block_t blkaddr,
>   for (i = 0; i < len; i++)
>   f2fs_wait_on_block_writeback(inode, blkaddr + i);
>  
> - invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr + len - 1);
> + f2fs_truncate_meta_inode_pages(sbi, blkaddr, len);
>  }
>  
>  static int read_compacted_summaries(struct f2fs_sb_info *sbi)
> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> index 755e9a41b196..a357287eac1e 100644
> --- a/include/linux/f2fs_fs.h
> +++ 

Re: [f2fs-dev] [PATCH v2] f2fs: add a proc entry show disk map

2024-03-05 Thread Jaegeuk Kim
This patch adds the disk map of block address ranges configured by multiple
partitions.

Signed-off-by: Jaegeuk Kim 
---

 from v1:
  - add more layout information

 fs/f2fs/sysfs.c | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 10f308b3128f..a568ce96cf56 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -1492,6 +1492,50 @@ static int __maybe_unused discard_plist_seq_show(struct 
seq_file *seq,
return 0;
 }
 
+static int __maybe_unused disk_map_seq_show(struct seq_file *seq,
+   void *offset)
+{
+   struct super_block *sb = seq->private;
+   struct f2fs_sb_info *sbi = F2FS_SB(sb);
+   int i;
+
+   seq_printf(seq, "Address Layout   : %5luB Block address (# of 
Segments)\n",
+   F2FS_BLKSIZE);
+   seq_printf(seq, " SB: %12s\n", "0/1024B");
+   seq_printf(seq, " seg0_blkaddr  : 0x%010x\n", SEG0_BLKADDR(sbi));
+   seq_printf(seq, " Checkpoint: 0x%010x (%10d)\n",
+   le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr), 2);
+   seq_printf(seq, " SIT   : 0x%010x (%10d)\n",
+   SIT_I(sbi)->sit_base_addr,
+   le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_sit));
+   seq_printf(seq, " NAT   : 0x%010x (%10d)\n",
+   NM_I(sbi)->nat_blkaddr,
+   le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_nat));
+   seq_printf(seq, " SSA   : 0x%010x (%10d)\n",
+   SM_I(sbi)->ssa_blkaddr,
+   le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_ssa));
+   seq_printf(seq, " Main  : 0x%010x (%10d)\n",
+   SM_I(sbi)->main_blkaddr,
+   le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_main));
+   seq_printf(seq, " # of Sections : %12d\n",
+   le32_to_cpu(F2FS_RAW_SUPER(sbi)->section_count));
+   seq_printf(seq, " Segs/Sections : %12d\n",
+   SEGS_PER_SEC(sbi));
+   seq_printf(seq, " Section size  : %12d MB\n",
+   SEGS_PER_SEC(sbi) << 1);
+
+   if (!f2fs_is_multi_device(sbi))
+   return 0;
+
+   seq_puts(seq, "\nDisk Map for multi devices:\n");
+   for (i = 0; i < sbi->s_ndevs; i++)
+   seq_printf(seq, "Disk:%2d (zoned=%d): 0x%010x - 0x%010x on 
%s\n",
+   i, bdev_is_zoned(FDEV(i).bdev),
+   FDEV(i).start_blk, FDEV(i).end_blk,
+   FDEV(i).path);
+   return 0;
+}
+
 int __init f2fs_init_sysfs(void)
 {
int ret;
@@ -1573,6 +1617,8 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
victim_bits_seq_show, sb);
proc_create_single_data("discard_plist_info", 0444, sbi->s_proc,
discard_plist_seq_show, sb);
+   proc_create_single_data("disk_map", 0444, sbi->s_proc,
+   disk_map_seq_show, sb);
return 0;
 put_feature_list_kobj:
kobject_put(>s_feature_list_kobj);
-- 
2.44.0.278.ge034bb2e1d-goog



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


Re: [f2fs-dev] [External Mail]Re: [PATCH v3] f2fs-tools: fix to check loop device for non-root users

2024-03-05 Thread Jaegeuk Kim
On 03/01, 黄佳男 wrote:
> On 2024/3/1 16:39, Juhyung Park wrote:
> > [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给mi...@xiaomi.com进行反馈
> >
> > Hi Huang and Chao.
> >
> > I feel like this special loopback handling alongside Chao's
> > 14197d546b93 on f2fs-tools is just unnecessarily complicating the code
> > flow.
> > We're now doing what, lookup to /sys, parse original backing file,
> > remove trailing newline char, stat()'ing it to make sure it exists?
> 
> Indeed this is not a good approach.
> 
> > What if the stat()'ed file is a new file after the original backing
> > file has been deleted?
> >
> > Being able to overwrite an active loopback backing file is a semantic
> > that Linux provides willingly.
> > O_EXCL only works on block devices and it's a POSIX guarantee that
> > multiple writers can work on a regular file.
> >
> > IMHO we should honor that, but if we really want to prevent this akin
> > to e2fsprogs, we should be using mntent like e2fsprogs.
> 
> e2fsprogs will continue to check if opening the loop device fails, 
> rather than
> 
> exiting. This way non-root users can use mkfs/fsck normally, although there
> 
> may be overwrite issues.

I think we need to fix this first and try to find a better way.

https://lore.kernel.org/linux-f2fs-devel/20240305204834.101697-1-jaeg...@kernel.org/T/#u

> 
> 
> Thanks,
> 
> Jianan
> 
> > On Fri, Mar 1, 2024 at 4:15 PM Huang Jianan via Linux-f2fs-devel
> >  wrote:
> >> Currently mkfs/fsck gets the following error when executed by
> >> non-root users:
> >>
> >> Info: open /dev/loop0 failed errno:13
> >>  Error: Not available on mounted device!
> >>
> >> Let's fix it by reading the backing file from sysfs.
> >>
> >> Fixes: 14197d546b93 ("f2fs-tools: fix to check loop device")
> >> Signed-off-by: Huang Jianan 
> >> ---
> >> v3:
> >> - Skip deleted backing file.
> >>   lib/libf2fs.c | 40 +++-
> >>   1 file changed, 27 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/lib/libf2fs.c b/lib/libf2fs.c
> >> index d51e485..fad3fd4 100644
> >> --- a/lib/libf2fs.c
> >> +++ b/lib/libf2fs.c
> >> @@ -832,7 +832,7 @@ int f2fs_dev_is_umounted(char *path)
> >>  }
> >>  } else if (S_ISREG(st_buf.st_mode)) {
> >>  /* check whether regular is backfile of loop device */
> >> -#if defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H)
> >> +#if defined(HAVE_LINUX_MAJOR_H)
> >>  struct mntent *mnt;
> >>  struct stat st_loop;
> >>  FILE *f;
> >> @@ -840,8 +840,9 @@ int f2fs_dev_is_umounted(char *path)
> >>  f = setmntent("/proc/mounts", "r");
> >>
> >>  while ((mnt = getmntent(f)) != NULL) {
> >> -   struct loop_info64 loopinfo = {0, };
> >> -   int loop_fd, err;
> >> +   struct stat st_back;
> >> +   int sysfs_fd, rc;
> >> +   char buf[PATH_MAX + 1];
> >>
> >>  if (mnt->mnt_fsname[0] != '/')
> >>  continue;
> >> @@ -852,23 +853,36 @@ int f2fs_dev_is_umounted(char *path)
> >>  if (major(st_loop.st_rdev) != LOOP_MAJOR)
> >>  continue;
> >>
> >> -   loop_fd = open(mnt->mnt_fsname, O_RDONLY);
> >> -   if (loop_fd < 0) {
> >> +   snprintf(buf, PATH_MAX,
> >> +"/sys/dev/block/%d:%d/loop/backing_file",
> >> +major(st_loop.st_rdev), 
> >> minor(st_loop.st_rdev));
> >> +
> >> +   sysfs_fd = open(buf, O_RDONLY);
> >> +   if (sysfs_fd < 0) {
> >>  MSG(0, "Info: open %s failed errno:%d\n",
> >> -   mnt->mnt_fsname, errno);
> >> +   buf, errno);
> >>  return -1;
> >>  }
> >>
> >> -   err = ioctl(loop_fd, LOOP_GET_STATUS64, );
> >> -   close(loop_fd);
> >> -   if (err < 0) {
> >> -   MSG(0, "\tError: ioctl LOOP_GET_STATUS64 
> >> failed errno:%d!\n",
> >> -   errno);
> >> +   memset(buf, 0, PATH_MAX + 1);
> >> +   rc = read(sysfs_fd, buf, PATH_MAX);
> >> +   if (rc < 0) {
> >> +   MSG(0, "Info: read %s failed errno:%d\n",
> >> +   buf, errno);
> >>  return -1;
> >>  }
> >>
> >> -   if (st_buf.st_dev == loopinfo.lo_device &&
> >> -   st_buf.st_ino == loopinfo.lo_inode) {
> >> +   /* Remove trailing newline */
> >> +   if 

[f2fs-dev] [PATCH] f2fs-tools: deal with permission denial on non-root user

2024-03-05 Thread Jaegeuk Kim
This fixes some android build failures due to the missing permission when
checking the loop device. Until we get a better solution, let's ignore
the error with warnings.

Signed-off-by: Jaegeuk Kim 
---
 lib/libf2fs.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index d51e485361ee..1cfbf31a9c85 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -854,9 +854,15 @@ int f2fs_dev_is_umounted(char *path)
 
loop_fd = open(mnt->mnt_fsname, O_RDONLY);
if (loop_fd < 0) {
+   /* non-root users have no permission */
+   if (errno == EPERM || errno == EACCES) {
+   MSG(0, "Info: open %s failed errno:%d - 
be careful to overwrite a mounted loopback file.\n",
+   mnt->mnt_fsname, errno);
+   return 0;
+   }
MSG(0, "Info: open %s failed errno:%d\n",
-   mnt->mnt_fsname, errno);
-   return -1;
+   mnt->mnt_fsname, errno);
+   return -errno;
}
 
err = ioctl(loop_fd, LOOP_GET_STATUS64, );
@@ -864,7 +870,7 @@ int f2fs_dev_is_umounted(char *path)
if (err < 0) {
MSG(0, "\tError: ioctl LOOP_GET_STATUS64 failed 
errno:%d!\n",
errno);
-   return -1;
+   return -errno;
}
 
if (st_buf.st_dev == loopinfo.lo_device &&
-- 
2.44.0.278.ge034bb2e1d-goog



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


[f2fs-dev] [PATCH] f2fs: add a proc entry show disk map

2024-03-04 Thread Jaegeuk Kim
This patch adds the disk map of block address ranges configured by multiple
partitions.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/sysfs.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 10f308b3128f..e81af6adb85b 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -1492,6 +1492,27 @@ static int __maybe_unused discard_plist_seq_show(struct 
seq_file *seq,
return 0;
 }
 
+static int __maybe_unused disk_map_seq_show(struct seq_file *seq,
+   void *offset)
+{
+   struct super_block *sb = seq->private;
+   struct f2fs_sb_info *sbi = F2FS_SB(sb);
+   int i;
+
+   seq_puts(seq, "Disk Map for multi devices:\n");
+   if (!f2fs_is_multi_device(sbi))
+   return 0;
+
+   for (i = 0; i < sbi->s_ndevs; i++) {
+   seq_printf(seq, "%2d (zoned=%d): %20x - %20x",
+   i, bdev_is_zoned(FDEV(i).bdev),
+   FDEV(i).start_blk, FDEV(i).end_blk);
+   seq_putc(seq, '\n');
+   }
+   return 0;
+}
+
+
 int __init f2fs_init_sysfs(void)
 {
int ret;
@@ -1573,6 +1594,8 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
victim_bits_seq_show, sb);
proc_create_single_data("discard_plist_info", 0444, sbi->s_proc,
discard_plist_seq_show, sb);
+   proc_create_single_data("disk_map", 0444, sbi->s_proc,
+   disk_map_seq_show, sb);
return 0;
 put_feature_list_kobj:
kobject_put(>s_feature_list_kobj);
-- 
2.44.0.278.ge034bb2e1d-goog



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


Re: [f2fs-dev] [PATCH 3/5] f2fs: print zone status in string and some log

2024-03-04 Thread Jaegeuk Kim
On 02/23, Jaegeuk Kim wrote:
> No functional change, but add some more logs.
> 
> Signed-off-by: Jaegeuk Kim 
> ---
>  fs/f2fs/segment.c | 34 --
>  fs/f2fs/super.c   |  1 +
>  2 files changed, 25 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index d4f228e6f771..6d586ae8b55f 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -4912,6 +4912,16 @@ static int sanity_check_curseg(struct f2fs_sb_info 
> *sbi)
>  }
>  
>  #ifdef CONFIG_BLK_DEV_ZONED
> +const char *f2fs_zone_status[BLK_ZONE_COND_OFFLINE + 1] = {

Added static.

> + [BLK_ZONE_COND_NOT_WP]  = "NOT_WP",
> + [BLK_ZONE_COND_EMPTY]   = "EMPTY",
> + [BLK_ZONE_COND_IMP_OPEN]= "IMPLICITE_OPEN",
> + [BLK_ZONE_COND_EXP_OPEN]= "EXPLICITE_OPEN",
> + [BLK_ZONE_COND_CLOSED]  = "CLOSED",
> + [BLK_ZONE_COND_READONLY]= "READONLY",
> + [BLK_ZONE_COND_FULL]= "FULL",
> + [BLK_ZONE_COND_OFFLINE] = "OFFLINE",
> +};
>  
>  static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
>   struct f2fs_dev_info *fdev,
> @@ -4928,18 +4938,22 @@ static int check_zone_write_pointer(struct 
> f2fs_sb_info *sbi,
>   zone_block = fdev->start_blk + (zone->start >> log_sectors_per_block);
>   zone_segno = GET_SEGNO(sbi, zone_block);
>  
> + /*
> +  * Get # of valid block of the zone.
> +  */
> + valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
> +
>   /*
>* Skip check of zones cursegs point to, since
>* fix_curseg_write_pointer() checks them.
>*/
>   if (zone_segno >= MAIN_SEGS(sbi) ||
> - IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno)))
> + IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno))) {
> + f2fs_notice(sbi, "Open zones: valid block[0x%x,0x%x] cond[%s]",
> + zone_segno, valid_block_cnt,
> + f2fs_zone_status[zone->cond]);
>   return 0;
> -
> - /*
> -  * Get # of valid block of the zone.
> -  */
> - valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
> + }
>  
>   if ((!valid_block_cnt && zone->cond == BLK_ZONE_COND_EMPTY) ||
>   (valid_block_cnt && zone->cond == BLK_ZONE_COND_FULL))
> @@ -4947,8 +4961,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
> *sbi,
>  
>   if (!valid_block_cnt) {
>   f2fs_notice(sbi, "Zone without valid block has non-zero write "
> - "pointer. Reset the write pointer: cond[0x%x]",
> - zone->cond);
> + "pointer. Reset the write pointer: cond[%s]",
> + f2fs_zone_status[zone->cond]);
>   ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
>   zone->len >> log_sectors_per_block);
>   if (ret)
> @@ -4965,8 +4979,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
> *sbi,
>* selected for write operation until it get discarded.
>*/
>   f2fs_notice(sbi, "Valid blocks are not aligned with write "
> - "pointer: valid block[0x%x,0x%x] cond[0x%x]",
> - zone_segno, valid_block_cnt, zone->cond);
> + "pointer: valid block[0x%x,0x%x] cond[%s]",
> + zone_segno, valid_block_cnt, f2fs_zone_status[zone->cond]);
>  
>   ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH,
>   zone->start, zone->len, GFP_NOFS);
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 4d03ce1109ad..fc7f1a9fbbda 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4674,6 +4674,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
> *data, int silent)
>* check zoned block devices' write pointer consistency.
>*/
>   if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
> + f2fs_notice(sbi, "Checking entire write pointers");
>   err = f2fs_check_write_pointer(sbi);
>   if (err)
>   goto free_meta;
> -- 
> 2.44.0.rc0.258.g7320e95886-goog


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


Re: [f2fs-dev] [PATCH 1/4] f2fs: fix blkofs_end correctly in f2fs_migrate_blocks()

2024-02-29 Thread Jaegeuk Kim
On 03/01, Chao Yu wrote:
> On 2024/3/1 1:41, Daeho Jeong wrote:
> > On Thu, Feb 29, 2024 at 2:11 AM Chao Yu  wrote:
> > > 
> > > Jaegeuk, Daeho,
> > > 
> > > Any comments on this serials?
> > > 
> > > Thanks,
> > 
> > No functional difference here, since start_blk is always aligned with
> > the section address.
> 
> You're right.
> 
> > However, this is more clear in itself.
> 
> Thanks for the review!
> 
> One more thing is, I found that fallocate() on pinned file will preallocate
> aligned w/ section-size which is about several hundred megabyte for ZUFS case,
> since commit e1175f022911 ("f2fs: fix to align to section for fallocate() on
> pinned file").
> 
> It looks not make sense, especially for logcat case which actually want to
> preallocate 2MB space, so, what about reverting commit e1175f022911 and
> looking for other solution to avoid GCing on fragmented pinned file.

I remember we removed the logcat case.

> 
> What do you think?
> 
> Thanks,
> 
> > 
> > Reviewed-by: Daeho Jeong 
> > 
> > Thanks,
> > 
> > > 
> > > On 2024/2/26 9:32, Chao Yu wrote:
> > > > In f2fs_migrate_blocks(), when traversing blocks in last section,
> > > > blkofs_end should be (start_blk + blkcnt - 1) % blk_per_sec, fix it.
> > > > 
> > > > Signed-off-by: Chao Yu 
> > > > ---
> > > >fs/f2fs/data.c | 5 +++--
> > > >1 file changed, 3 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > > > index c21b92f18463..0c728e82d936 100644
> > > > --- a/fs/f2fs/data.c
> > > > +++ b/fs/f2fs/data.c
> > > > @@ -3841,13 +3841,14 @@ static int f2fs_migrate_blocks(struct inode 
> > > > *inode, block_t start_blk,
> > > >struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> > > >unsigned int blkofs;
> > > >unsigned int blk_per_sec = BLKS_PER_SEC(sbi);
> > > > + unsigned int end_blk = start_blk + blkcnt - 1;
> > > >unsigned int secidx = start_blk / blk_per_sec;
> > > >unsigned int end_sec;
> > > >int ret = 0;
> > > > 
> > > >if (!blkcnt)
> > > >return 0;
> > > > - end_sec = secidx + (blkcnt - 1) / blk_per_sec;
> > > > + end_sec = end_blk / blk_per_sec;
> > > > 
> > > >f2fs_down_write(_I(inode)->i_gc_rwsem[WRITE]);
> > > >filemap_invalidate_lock(inode->i_mapping);
> > > > @@ -3857,7 +3858,7 @@ static int f2fs_migrate_blocks(struct inode 
> > > > *inode, block_t start_blk,
> > > > 
> > > >for (; secidx <= end_sec; secidx++) {
> > > >unsigned int blkofs_end = secidx == end_sec ?
> > > > - (blkcnt - 1) % blk_per_sec : blk_per_sec - 1;
> > > > + end_blk % blk_per_sec : blk_per_sec - 1;
> > > > 
> > > >f2fs_down_write(>pin_sem);
> > > > 
> > > 
> > > 
> > > ___
> > > 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] f2fs: introduce SEGS_TO_BLKS/BLKS_TO_SEGS for cleanup

2024-02-29 Thread Jaegeuk Kim
On 03/01, Chao Yu wrote:
> On 2024/3/1 0:35, Jaegeuk Kim wrote:
> > On 02/29, Chao Yu wrote:
> > > On 2024/2/28 1:47, Jaegeuk Kim wrote:
> > > > On 02/21, Chao Yu wrote:
> > > > > Just cleanup, no functional change.
> > > > > 
> > > > > Signed-off-by: Chao Yu 
> > > > > ---
> > > > >fs/f2fs/debug.c   |  7 +++
> > > > >fs/f2fs/f2fs.h| 14 --
> > > > >fs/f2fs/gc.c  | 10 +-
> > > > >fs/f2fs/gc.h  |  4 ++--
> > > > >fs/f2fs/segment.c | 12 ++--
> > > > >fs/f2fs/segment.h |  8 
> > > > >fs/f2fs/super.c   | 16 
> > > > >fs/f2fs/sysfs.c   |  4 ++--
> > > > >8 files changed, 38 insertions(+), 37 deletions(-)
> > > > > 
> > > > > diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> > > > > index 6617195bd27e..12893477f2e4 100644
> > > > > --- a/fs/f2fs/debug.c
> > > > > +++ b/fs/f2fs/debug.c
> > > > > @@ -134,7 +134,7 @@ static void update_general_status(struct 
> > > > > f2fs_sb_info *sbi)
> > > > >   si->cur_ckpt_time = sbi->cprc_info.cur_time;
> > > > >   si->peak_ckpt_time = sbi->cprc_info.peak_time;
> > > > >   spin_unlock(>cprc_info.stat_lock);
> > > > > - si->total_count = (int)sbi->user_block_count / 
> > > > > BLKS_PER_SEG(sbi);
> > > > > + si->total_count = BLKS_TO_SEGS(sbi, (int)sbi->user_block_count);
> > > > >   si->rsvd_segs = reserved_segments(sbi);
> > > > >   si->overp_segs = overprovision_segments(sbi);
> > > > >   si->valid_count = valid_user_blocks(sbi);
> > > > > @@ -175,11 +175,10 @@ static void update_general_status(struct 
> > > > > f2fs_sb_info *sbi)
> > > > >   si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
> > > > >   si->io_skip_bggc = sbi->io_skip_bggc;
> > > > >   si->other_skip_bggc = sbi->other_skip_bggc;
> > > > > - si->util_free = (int)(free_user_blocks(sbi) >> 
> > > > > sbi->log_blocks_per_seg)
> > > > > + si->util_free = (int)(BLKS_TO_SEGS(sbi, free_user_blocks(sbi)))
> > > > >   * 100 / (int)(sbi->user_block_count >> 
> > > > > sbi->log_blocks_per_seg)
> > > > >   / 2;
> > > > > - si->util_valid = (int)(written_block_count(sbi) >>
> > > > > - sbi->log_blocks_per_seg)
> > > > > + si->util_valid = (int)(BLKS_TO_SEGS(sbi, 
> > > > > written_block_count(sbi)))
> > > > >   * 100 / (int)(sbi->user_block_count >> 
> > > > > sbi->log_blocks_per_seg)
> > > > >   / 2;
> > > > >   si->util_invalid = 50 - si->util_free - si->util_valid;
> > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > > > > index dad2774ca72f..8a6fd4352a0e 100644
> > > > > --- a/fs/f2fs/f2fs.h
> > > > > +++ b/fs/f2fs/f2fs.h
> > > > > @@ -1813,12 +1813,14 @@ struct f2fs_sb_info {
> > > > >};
> > > > >/* Definitions to access f2fs_sb_info */
> > > > > -#define BLKS_PER_SEG(sbi)\
> > > > > - ((sbi)->blocks_per_seg)
> > > > > -#define BLKS_PER_SEC(sbi)\
> > > > > - ((sbi)->segs_per_sec << (sbi)->log_blocks_per_seg)
> > > > > -#define SEGS_PER_SEC(sbi)\
> > > > > - ((sbi)->segs_per_sec)
> > > > > +#define SEGS_TO_BLKS(sbi, segs)  
> > > > > \
> > > > > + ((segs) << (sbi)->log_blocks_per_seg)
> > > > 
> > > > 
> > > > I also applied this.
> > > > 
> > > >/* Definitions to access f2fs_sb_info */
> > > >#define SEGS_TO_BLKS(sbi, segs)  
> > > >   \
> > > > -   ((segs) << (sbi)->log_blocks_per_seg)
> > > > +   (((long long)segs) << (sbi)->log_blocks_per_seg)
> > > 
> > > Ja

Re: [f2fs-dev] [PATCH][next] f2fs: Fix two spelling mistakes in f2fs_zone_status array

2024-02-29 Thread Jaegeuk Kim
On 02/29, Colin King (gmail) wrote:
> On 29/02/2024 17:12, Jaegeuk Kim wrote:
> > Hi Colin,
> > 
> > Thank you for the fix. If you don't mind, can I integrate this fix
> > into the original patch?
> 
> Sure. No problem.

Thank you so much!

> 
> Colin
> > 
> > Thanks,
> > 
> > On 02/29, Colin Ian King wrote:
> > > The array f2fs_zone_status contains two spelling mistakes in
> > > literal strings. Fix them.
> > > 
> > > Signed-off-by: Colin Ian King 
> > > ---
> > >   fs/f2fs/segment.c | 4 ++--
> > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > > index bdb27e4a604b..072c4355d3d3 100644
> > > --- a/fs/f2fs/segment.c
> > > +++ b/fs/f2fs/segment.c
> > > @@ -4921,8 +4921,8 @@ static int sanity_check_curseg(struct f2fs_sb_info 
> > > *sbi)
> > >   const char *f2fs_zone_status[BLK_ZONE_COND_OFFLINE + 1] = {
> > >   [BLK_ZONE_COND_NOT_WP]  = "NOT_WP",
> > >   [BLK_ZONE_COND_EMPTY]   = "EMPTY",
> > > - [BLK_ZONE_COND_IMP_OPEN]= "IMPLICITE_OPEN",
> > > - [BLK_ZONE_COND_EXP_OPEN]= "EXPLICITE_OPEN",
> > > + [BLK_ZONE_COND_IMP_OPEN]= "IMPLICIT_OPEN",
> > > + [BLK_ZONE_COND_EXP_OPEN]= "EXPLICIT_OPEN",
> > >   [BLK_ZONE_COND_CLOSED]  = "CLOSED",
> > >   [BLK_ZONE_COND_READONLY]= "READONLY",
> > >   [BLK_ZONE_COND_FULL]= "FULL",
> > > -- 
> > > 2.39.2


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


Re: [f2fs-dev] [PATCH][next] f2fs: Fix two spelling mistakes in f2fs_zone_status array

2024-02-29 Thread Jaegeuk Kim
Hi Colin,

Thank you for the fix. If you don't mind, can I integrate this fix
into the original patch?

Thanks,

On 02/29, Colin Ian King wrote:
> The array f2fs_zone_status contains two spelling mistakes in
> literal strings. Fix them.
> 
> Signed-off-by: Colin Ian King 
> ---
>  fs/f2fs/segment.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index bdb27e4a604b..072c4355d3d3 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -4921,8 +4921,8 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi)
>  const char *f2fs_zone_status[BLK_ZONE_COND_OFFLINE + 1] = {
>   [BLK_ZONE_COND_NOT_WP]  = "NOT_WP",
>   [BLK_ZONE_COND_EMPTY]   = "EMPTY",
> - [BLK_ZONE_COND_IMP_OPEN]= "IMPLICITE_OPEN",
> - [BLK_ZONE_COND_EXP_OPEN]= "EXPLICITE_OPEN",
> + [BLK_ZONE_COND_IMP_OPEN]= "IMPLICIT_OPEN",
> + [BLK_ZONE_COND_EXP_OPEN]= "EXPLICIT_OPEN",
>   [BLK_ZONE_COND_CLOSED]  = "CLOSED",
>   [BLK_ZONE_COND_READONLY]= "READONLY",
>   [BLK_ZONE_COND_FULL]= "FULL",
> -- 
> 2.39.2


___
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: introduce SEGS_TO_BLKS/BLKS_TO_SEGS for cleanup

2024-02-29 Thread Jaegeuk Kim
On 02/29, Chao Yu wrote:
> On 2024/2/28 1:47, Jaegeuk Kim wrote:
> > On 02/21, Chao Yu wrote:
> > > Just cleanup, no functional change.
> > > 
> > > Signed-off-by: Chao Yu 
> > > ---
> > >   fs/f2fs/debug.c   |  7 +++
> > >   fs/f2fs/f2fs.h| 14 --
> > >   fs/f2fs/gc.c  | 10 +-
> > >   fs/f2fs/gc.h  |  4 ++--
> > >   fs/f2fs/segment.c | 12 ++--
> > >   fs/f2fs/segment.h |  8 
> > >   fs/f2fs/super.c   | 16 
> > >   fs/f2fs/sysfs.c   |  4 ++--
> > >   8 files changed, 38 insertions(+), 37 deletions(-)
> > > 
> > > diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> > > index 6617195bd27e..12893477f2e4 100644
> > > --- a/fs/f2fs/debug.c
> > > +++ b/fs/f2fs/debug.c
> > > @@ -134,7 +134,7 @@ static void update_general_status(struct f2fs_sb_info 
> > > *sbi)
> > >   si->cur_ckpt_time = sbi->cprc_info.cur_time;
> > >   si->peak_ckpt_time = sbi->cprc_info.peak_time;
> > >   spin_unlock(>cprc_info.stat_lock);
> > > - si->total_count = (int)sbi->user_block_count / BLKS_PER_SEG(sbi);
> > > + si->total_count = BLKS_TO_SEGS(sbi, (int)sbi->user_block_count);
> > >   si->rsvd_segs = reserved_segments(sbi);
> > >   si->overp_segs = overprovision_segments(sbi);
> > >   si->valid_count = valid_user_blocks(sbi);
> > > @@ -175,11 +175,10 @@ static void update_general_status(struct 
> > > f2fs_sb_info *sbi)
> > >   si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
> > >   si->io_skip_bggc = sbi->io_skip_bggc;
> > >   si->other_skip_bggc = sbi->other_skip_bggc;
> > > - si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
> > > + si->util_free = (int)(BLKS_TO_SEGS(sbi, free_user_blocks(sbi)))
> > >   * 100 / (int)(sbi->user_block_count >> 
> > > sbi->log_blocks_per_seg)
> > >   / 2;
> > > - si->util_valid = (int)(written_block_count(sbi) >>
> > > - sbi->log_blocks_per_seg)
> > > + si->util_valid = (int)(BLKS_TO_SEGS(sbi, written_block_count(sbi)))
> > >   * 100 / (int)(sbi->user_block_count >> 
> > > sbi->log_blocks_per_seg)
> > >   / 2;
> > >   si->util_invalid = 50 - si->util_free - si->util_valid;
> > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > > index dad2774ca72f..8a6fd4352a0e 100644
> > > --- a/fs/f2fs/f2fs.h
> > > +++ b/fs/f2fs/f2fs.h
> > > @@ -1813,12 +1813,14 @@ struct f2fs_sb_info {
> > >   };
> > >   /* Definitions to access f2fs_sb_info */
> > > -#define BLKS_PER_SEG(sbi)\
> > > - ((sbi)->blocks_per_seg)
> > > -#define BLKS_PER_SEC(sbi)\
> > > - ((sbi)->segs_per_sec << (sbi)->log_blocks_per_seg)
> > > -#define SEGS_PER_SEC(sbi)\
> > > - ((sbi)->segs_per_sec)
> > > +#define SEGS_TO_BLKS(sbi, segs)  \
> > > + ((segs) << (sbi)->log_blocks_per_seg)
> > 
> > 
> > I also applied this.
> > 
> >   /* Definitions to access f2fs_sb_info */
> >   #define SEGS_TO_BLKS(sbi, segs)\
> > -   ((segs) << (sbi)->log_blocks_per_seg)
> > +   (((long long)segs) << (sbi)->log_blocks_per_seg)
> 
> Jaegeuk,
> 
> This may cause compile failure reported as below, can we revert this?
> 
> https://lore.kernel.org/linux-f2fs-devel/camuhmdxruiv8pee6azkylp+z_sa8cbl8849bzu59j1_xxty...@mail.gmail.com/T/#t

Yeah, it seems so. I removed it in -dev.

> 
> Thanks,
> 
> >   #define BLKS_TO_SEGS(sbi, blks)\
> >  ((blks) >> (sbi)->log_blocks_per_seg)
> > 
> > > +#define BLKS_TO_SEGS(sbi, blks)  \
> > > + ((blks) >> (sbi)->log_blocks_per_seg)
> > > +
> > > +#define BLKS_PER_SEG(sbi)((sbi)->blocks_per_seg)
> > > +#define BLKS_PER_SEC(sbi)(SEGS_TO_BLKS(sbi, (sbi)->segs_per_sec))
> > > +#define SEGS_PER_SEC(sbi)((sbi)->segs_per_sec)
> > >   __printf(3, 4)
> > > 

Re: [f2fs-dev] [PATCH 2/4] f2fs: fix to don't call f2fs_stop_checkpoint in spinlock coverage

2024-02-27 Thread Jaegeuk Kim
On 02/22, Chao Yu wrote:
> f2fs_stop_checkpoint(, false) is complex and it may sleep, so we should
> move it outside segmap_lock spinlock coverage in get_new_segment().

Chao, I merged this patch into

https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test=f3b576d209983b5d6e1cb130bfc8ca1f0bbcad6d

> 
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/segment.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index d0209ea77dd2..8edc42071e6f 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -2646,6 +2646,7 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
>   unsigned int old_zoneno = GET_ZONE_FROM_SEG(sbi, *newseg);
>   bool init = true;
>   int i;
> + int ret = 0;
>  
>   spin_lock(_i->segmap_lock);
>  
> @@ -2671,9 +2672,8 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
>   secno = find_first_zero_bit(free_i->free_secmap,
>   MAIN_SECS(sbi));
>   if (secno >= MAIN_SECS(sbi)) {
> - f2fs_stop_checkpoint(sbi, false,
> - STOP_CP_REASON_NO_SEGMENT);
> - f2fs_bug_on(sbi, 1);
> + ret = -ENOSPC;
> + goto out_unlock;
>   }
>   }
>   segno = GET_SEG_FROM_SEC(sbi, secno);
> @@ -2704,7 +2704,13 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
>   f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap));
>   __set_inuse(sbi, segno);
>   *newseg = segno;
> +out_unlock:
>   spin_unlock(_i->segmap_lock);
> +
> + if (ret) {
> + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_NO_SEGMENT);
> + f2fs_bug_on(sbi, 1);
> + }
>  }
>  
>  static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
> -- 
> 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] f2fs: introduce SEGS_TO_BLKS/BLKS_TO_SEGS for cleanup

2024-02-27 Thread Jaegeuk Kim
On 02/21, Chao Yu wrote:
> Just cleanup, no functional change.
> 
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/debug.c   |  7 +++
>  fs/f2fs/f2fs.h| 14 --
>  fs/f2fs/gc.c  | 10 +-
>  fs/f2fs/gc.h  |  4 ++--
>  fs/f2fs/segment.c | 12 ++--
>  fs/f2fs/segment.h |  8 
>  fs/f2fs/super.c   | 16 
>  fs/f2fs/sysfs.c   |  4 ++--
>  8 files changed, 38 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> index 6617195bd27e..12893477f2e4 100644
> --- a/fs/f2fs/debug.c
> +++ b/fs/f2fs/debug.c
> @@ -134,7 +134,7 @@ static void update_general_status(struct f2fs_sb_info 
> *sbi)
>   si->cur_ckpt_time = sbi->cprc_info.cur_time;
>   si->peak_ckpt_time = sbi->cprc_info.peak_time;
>   spin_unlock(>cprc_info.stat_lock);
> - si->total_count = (int)sbi->user_block_count / BLKS_PER_SEG(sbi);
> + si->total_count = BLKS_TO_SEGS(sbi, (int)sbi->user_block_count);
>   si->rsvd_segs = reserved_segments(sbi);
>   si->overp_segs = overprovision_segments(sbi);
>   si->valid_count = valid_user_blocks(sbi);
> @@ -175,11 +175,10 @@ static void update_general_status(struct f2fs_sb_info 
> *sbi)
>   si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
>   si->io_skip_bggc = sbi->io_skip_bggc;
>   si->other_skip_bggc = sbi->other_skip_bggc;
> - si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
> + si->util_free = (int)(BLKS_TO_SEGS(sbi, free_user_blocks(sbi)))
>   * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
>   / 2;
> - si->util_valid = (int)(written_block_count(sbi) >>
> - sbi->log_blocks_per_seg)
> + si->util_valid = (int)(BLKS_TO_SEGS(sbi, written_block_count(sbi)))
>   * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
>   / 2;
>   si->util_invalid = 50 - si->util_free - si->util_valid;
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index dad2774ca72f..8a6fd4352a0e 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1813,12 +1813,14 @@ struct f2fs_sb_info {
>  };
>  
>  /* Definitions to access f2fs_sb_info */
> -#define BLKS_PER_SEG(sbi)\
> - ((sbi)->blocks_per_seg)
> -#define BLKS_PER_SEC(sbi)\
> - ((sbi)->segs_per_sec << (sbi)->log_blocks_per_seg)
> -#define SEGS_PER_SEC(sbi)\
> - ((sbi)->segs_per_sec)
> +#define SEGS_TO_BLKS(sbi, segs)  \
> + ((segs) << (sbi)->log_blocks_per_seg)


I also applied this.

 /* Definitions to access f2fs_sb_info */
 #define SEGS_TO_BLKS(sbi, segs)\
-   ((segs) << (sbi)->log_blocks_per_seg)
+   (((long long)segs) << (sbi)->log_blocks_per_seg)
 #define BLKS_TO_SEGS(sbi, blks)\
((blks) >> (sbi)->log_blocks_per_seg)

> +#define BLKS_TO_SEGS(sbi, blks)  \
> + ((blks) >> (sbi)->log_blocks_per_seg)
> +
> +#define BLKS_PER_SEG(sbi)((sbi)->blocks_per_seg)
> +#define BLKS_PER_SEC(sbi)(SEGS_TO_BLKS(sbi, (sbi)->segs_per_sec))
> +#define SEGS_PER_SEC(sbi)((sbi)->segs_per_sec)
>  
>  __printf(3, 4)
>  void f2fs_printk(struct f2fs_sb_info *sbi, bool limit_rate, const char *fmt, 
> ...);
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 3ff126316d42..6d160d50e14e 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -301,7 +301,7 @@ static unsigned int get_max_cost(struct f2fs_sb_info *sbi,
>  
>   /* LFS */
>   if (p->gc_mode == GC_GREEDY)
> - return 2 * BLKS_PER_SEG(sbi) * p->ofs_unit;
> + return SEGS_TO_BLKS(sbi, 2 * p->ofs_unit);
>   else if (p->gc_mode == GC_CB)
>   return UINT_MAX;
>   else if (p->gc_mode == GC_AT)
> @@ -347,7 +347,7 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, 
> unsigned int segno)
>   mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
>   vblocks = div_u64(vblocks, SEGS_PER_SEC(sbi));
>  
> - u = (vblocks * 100) >> sbi->log_blocks_per_seg;
> + u = BLKS_TO_SEGS(sbi, vblocks * 100);
>  
>   /* Handle if the system time has changed by the user */
>   if (mtime < sit_i->min_mtime)
> @@ -2060,7 +2060,7 @@ static void update_sb_metadata(struct f2fs_sb_info 
> *sbi, int secs)
>   raw_sb->segment_count = cpu_to_le32(segment_count + segs);
>   raw_sb->segment_count_main = cpu_to_le32(segment_count_main + segs);
>   raw_sb->block_count = cpu_to_le64(block_count +
> - (long long)(segs << sbi->log_blocks_per_seg));
> + (long long)SEGS_TO_BLKS(sbi, segs));
>   if (f2fs_is_multi_device(sbi)) {
>   int last_dev = sbi->s_ndevs - 1;
>   int dev_segs =
> @@ -2076,7 +2076,7 @@ static void 

Re: [f2fs-dev] [bug report] f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC

2024-02-27 Thread Jaegeuk Kim
On 02/27, Dan Carpenter wrote:
> Hello Jaegeuk Kim,
> 
> The patch 9c1d3cd4ff8c: "f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and
> SEGS_PER_SEC" from Feb 6, 2024 (linux-next), leads to the following
> Smatch static checker warning:
> 
>   fs/f2fs/gc.c:2092 update_fs_metadata()
>   warn: cast after binop
> 
> fs/f2fs/gc.c
> 2089 static void update_fs_metadata(struct f2fs_sb_info *sbi, int secs)
> 2090 {
> 2091 int segs = secs * SEGS_PER_SEC(sbi);
> --> 2092 long long blks = (long long)(segs << 
> sbi->log_blocks_per_seg);
>  
> ^^
> Originally this was something like:
> 
>   long long blks = (long long)segs << sbi->log_blocks_per_seg;

Thanks. I just reverted this line back to the original cast one.

> 
> So the cast seemed necessary to avoid an integer overflow.
> 
> 2093 long long user_block_count =
> 2094 
> le64_to_cpu(F2FS_CKPT(sbi)->user_block_count);
> 2095 
> 2096 SM_I(sbi)->segment_count = (int)SM_I(sbi)->segment_count + 
> segs;
> 2097 MAIN_SEGS(sbi) = (int)MAIN_SEGS(sbi) + segs;
> 
> regards,
> dan carpenter


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


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

2024-02-27 Thread Jaegeuk Kim
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 Jaegeuk Kim
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?

> 
> 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.

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

2024-02-26 Thread Jaegeuk Kim
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  > > > 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
> > >  
> > > 
> > >
> > > 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!

Hey, do you guys please point out which patches were tested without what?
IOWs, which patches should I remove and keep Chao's patch?

> 
> >
> > 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
> > >  
> > > 
> >
> > 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 2/5] f2fs: fix write pointers all the time

2024-02-26 Thread Jaegeuk Kim
On 02/26, Chao Yu wrote:
> On 2024/2/24 4:55, Jaegeuk Kim wrote:
> > Even if the roll forward recovery stopped due to any error, we have to fix
> > the write pointers in order to mount the disk from the previous checkpoint.
> 
> Jaegeuk,
> 
> IIUC, we may lost warm node chain once we allocate new section for all logs,
> should we give some notification in log to indicate such condition that
> filesystem doesn't process a full recovery flow?

How about v2 to preserve the error which gives a warnings on roll-forward
recovery?

> 
> Thanks,
> 
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >   fs/f2fs/recovery.c | 2 +-
> >   fs/f2fs/super.c| 2 +-
> >   2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
> > index b3baec666afe..8bbecb5f9323 100644
> > --- a/fs/f2fs/recovery.c
> > +++ b/fs/f2fs/recovery.c
> > @@ -913,7 +913,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, 
> > bool check_only)
> >  * and the f2fs is not read only, check and fix zoned block devices'
> >  * write pointer consistency.
> >  */
> > -   if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
> > +   if (fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
> > f2fs_sb_has_blkzoned(sbi)) {
> > err = f2fs_fix_curseg_write_pointer(sbi);
> > if (!err)
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index 2e41142d07c0..4d03ce1109ad 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -4673,7 +4673,7 @@ static int f2fs_fill_super(struct super_block *sb, 
> > void *data, int silent)
> >  * If the f2fs is not readonly and fsync data recovery succeeds,
> >  * check zoned block devices' write pointer consistency.
> >  */
> > -   if (!err && !f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
> > +   if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
> > err = f2fs_check_write_pointer(sbi);
> > if (err)
> > goto free_meta;


___
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/5 v2] f2fs: fix write pointers all the time

2024-02-26 Thread Jaegeuk Kim
Even if the roll forward recovery stopped due to any error, we have to fix
the write pointers in order to mount the disk from the previous checkpoint.

Signed-off-by: Jaegeuk Kim 
---

 from v1:
  - preserve error

 fs/f2fs/recovery.c | 15 +++
 fs/f2fs/super.c| 11 +++
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index b3baec666afe..3078d5613748 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -863,7 +863,6 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool 
check_only)
int ret = 0;
unsigned long s_flags = sbi->sb->s_flags;
bool need_writecp = false;
-   bool fix_curseg_write_pointer = false;
 
if (is_sbi_flag_set(sbi, SBI_IS_WRITABLE))
f2fs_info(sbi, "recover fsync data on readonly fs");
@@ -894,8 +893,6 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool 
check_only)
else
f2fs_bug_on(sbi, sbi->sb->s_flags & SB_ACTIVE);
 skip:
-   fix_curseg_write_pointer = !check_only || list_empty(_list);
-
destroy_fsync_dnodes(_list, err);
destroy_fsync_dnodes(_inode_list, err);
 
@@ -913,11 +910,13 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, 
bool check_only)
 * and the f2fs is not read only, check and fix zoned block devices'
 * write pointer consistency.
 */
-   if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
-   f2fs_sb_has_blkzoned(sbi)) {
-   err = f2fs_fix_curseg_write_pointer(sbi);
-   if (!err)
-   err = f2fs_check_write_pointer(sbi);
+   if (f2fs_sb_has_blkzoned(sbi) && !f2fs_readonly(sbi->sb)) {
+   int err2 = f2fs_fix_curseg_write_pointer(sbi);
+
+   if (!err2)
+   err2 = f2fs_check_write_pointer(sbi);
+   if (err2)
+   err = err2;
ret = err;
}
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d91e57ca6110..77348fd0a42b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4674,11 +4674,14 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
 * If the f2fs is not readonly and fsync data recovery succeeds,
 * check zoned block devices' write pointer consistency.
 */
-   if (!err && !f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
-   err = f2fs_check_write_pointer(sbi);
-   if (err)
-   goto free_meta;
+   if (f2fs_sb_has_blkzoned(sbi) && !f2fs_readonly(sb)) {
+   int err2 = f2fs_check_write_pointer(sbi);
+
+   if (err2)
+   err = err2;
}
+   if (err)
+   goto free_meta;
 
f2fs_init_inmem_curseg(sbi);
 
-- 
2.44.0.rc1.240.g4c46232300-goog



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


Re: [f2fs-dev] [PATCH 1/5 v2] f2fs: check number of blocks in a current section

2024-02-26 Thread Jaegeuk Kim
In cfd66bb715fd ("f2fs: fix deadloop in foreground GC"), we needed to check
the number of blocks in a section instead of the segment.

Fixes: cfd66bb715fd ("f2fs: fix deadloop in foreground GC")
Signed-off-by: Jaegeuk Kim 
---

 from v1:
  - check current node block space to deal with the worst case
  - TODO: need to fine tuning on node temperature

 fs/f2fs/segment.h | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 3edd3809b6b5..335fc6285fa5 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -561,23 +561,22 @@ static inline bool has_curseg_enough_space(struct 
f2fs_sb_info *sbi,
unsigned int node_blocks, unsigned int dent_blocks)
 {
 
-   unsigned int segno, left_blocks;
+   unsigned segno, left_blocks;
int i;
 
-   /* check current node segment */
+   /* check current node sections in the worst case. */
for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
segno = CURSEG_I(sbi, i)->segno;
-   left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks;
-
+   left_blocks = CAP_BLKS_PER_SEC(sbi) -
+   get_ckpt_valid_blocks(sbi, segno, true);
if (node_blocks > left_blocks)
return false;
}
 
-   /* check current data segment */
+   /* check current data section for dentry blocks. */
segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
-   left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+   left_blocks = CAP_BLKS_PER_SEC(sbi) -
+   get_ckpt_valid_blocks(sbi, segno, true);
if (dent_blocks > left_blocks)
return false;
return true;
@@ -626,7 +625,7 @@ static inline bool has_not_enough_free_secs(struct 
f2fs_sb_info *sbi,
 
if (free_secs > upper_secs)
return false;
-   else if (free_secs <= lower_secs)
+   if (free_secs <= lower_secs)
return true;
return !curseg_space;
 }
-- 
2.44.0.rc1.240.g4c46232300-goog



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


Re: [f2fs-dev] [PATCH 3/5 v2] f2fs: print zone status in string and some log

2024-02-26 Thread Jaegeuk Kim
No functional change, but add some more logs.

Reviewed-by: Chao Yu 
Signed-off-by: Jaegeuk Kim 
---

 from v1:
  - avoid unnecessary log per Daeho's comment

 fs/f2fs/segment.c | 27 +--
 fs/f2fs/super.c   |  1 +
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index d4f228e6f771..31a9e7db19e3 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4912,6 +4912,16 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi)
 }
 
 #ifdef CONFIG_BLK_DEV_ZONED
+const char *f2fs_zone_status[BLK_ZONE_COND_OFFLINE + 1] = {
+   [BLK_ZONE_COND_NOT_WP]  = "NOT_WP",
+   [BLK_ZONE_COND_EMPTY]   = "EMPTY",
+   [BLK_ZONE_COND_IMP_OPEN]= "IMPLICITE_OPEN",
+   [BLK_ZONE_COND_EXP_OPEN]= "EXPLICITE_OPEN",
+   [BLK_ZONE_COND_CLOSED]  = "CLOSED",
+   [BLK_ZONE_COND_READONLY]= "READONLY",
+   [BLK_ZONE_COND_FULL]= "FULL",
+   [BLK_ZONE_COND_OFFLINE] = "OFFLINE",
+};
 
 static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
struct f2fs_dev_info *fdev,
@@ -4932,14 +4942,19 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
*sbi,
 * Skip check of zones cursegs point to, since
 * fix_curseg_write_pointer() checks them.
 */
-   if (zone_segno >= MAIN_SEGS(sbi) ||
-   IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno)))
+   if (zone_segno >= MAIN_SEGS(sbi))
return 0;
 
/*
 * Get # of valid block of the zone.
 */
valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
+   if (IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno))) {
+   f2fs_notice(sbi, "Open zones: valid block[0x%x,0x%x] cond[%s]",
+   zone_segno, valid_block_cnt,
+   f2fs_zone_status[zone->cond]);
+   return 0;
+   }
 
if ((!valid_block_cnt && zone->cond == BLK_ZONE_COND_EMPTY) ||
(valid_block_cnt && zone->cond == BLK_ZONE_COND_FULL))
@@ -4947,8 +4962,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
*sbi,
 
if (!valid_block_cnt) {
f2fs_notice(sbi, "Zone without valid block has non-zero write "
-   "pointer. Reset the write pointer: cond[0x%x]",
-   zone->cond);
+   "pointer. Reset the write pointer: cond[%s]",
+   f2fs_zone_status[zone->cond]);
ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
zone->len >> log_sectors_per_block);
if (ret)
@@ -4965,8 +4980,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
*sbi,
 * selected for write operation until it get discarded.
 */
f2fs_notice(sbi, "Valid blocks are not aligned with write "
-   "pointer: valid block[0x%x,0x%x] cond[0x%x]",
-   zone_segno, valid_block_cnt, zone->cond);
+   "pointer: valid block[0x%x,0x%x] cond[%s]",
+   zone_segno, valid_block_cnt, f2fs_zone_status[zone->cond]);
 
ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH,
zone->start, zone->len, GFP_NOFS);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4d03ce1109ad..fc7f1a9fbbda 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4674,6 +4674,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
 * check zoned block devices' write pointer consistency.
 */
if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
+   f2fs_notice(sbi, "Checking entire write pointers");
err = f2fs_check_write_pointer(sbi);
if (err)
goto free_meta;
-- 
2.44.0.rc1.240.g4c46232300-goog



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


Re: [f2fs-dev] [PATCH 5/5] f2fs: allow to mount if cap is 100

2024-02-26 Thread Jaegeuk Kim
On 02/26, Daeho Jeong wrote:
> On Fri, Feb 23, 2024 at 12:56 PM Jaegeuk Kim  wrote:
> >
> > Don't block mounting the partition, if cap is 100%.
> >
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >  fs/f2fs/segment.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index 6d586ae8b55f..f11361152d2a 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -904,6 +904,9 @@ int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, 
> > block_t unusable)
> >  {
> > int ovp_hole_segs =
> > (overprovision_segments(sbi) - reserved_segments(sbi));
> > +
> > +   if (F2FS_OPTION(sbi).unusable_cap_perc == 100)
> > +   return 0;
> 
> With this, f2fs will not execute GC. What is this 100
> unusable_cap_perc used for?

Theoritically, it won't, but I was hitting a GC loop, and I suspected a wrong
section/segment layout. So, I posted the below, and guess we need this patch
as workaround.

https://patchwork.kernel.org/project/f2fs/patch/20240224011411.3820719-1-jaeg...@kernel.org/

> 
> > if (unusable > F2FS_OPTION(sbi).unusable_cap)
> > return -EAGAIN;
> > if (is_sbi_flag_set(sbi, SBI_CP_DISABLED_QUICK) &&
> > --
> > 2.44.0.rc0.258.g7320e95886-goog
> >
> >
> >
> > ___
> > 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] mkfs.f2fs: should give section-aligned reserved segments

2024-02-23 Thread Jaegeuk Kim
The reserved segments should be aligned to the section boundary.

Signed-off-by: Jaegeuk Kim 
---

  v2:
  - fix bug

 include/f2fs_fs.h | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 9056e02acd29..fc56396fa358 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1760,25 +1760,27 @@ extern uint32_t f2fs_get_usable_segments(struct 
f2fs_super_block *sb);
 #define ZONE_ALIGN(blks)   SIZE_ALIGN(blks, c.blks_per_seg * \
c.segs_per_zone)
 
-static inline double get_reserved(struct f2fs_super_block *sb, double ovp)
+static inline uint32_t get_reserved(struct f2fs_super_block *sb, double ovp)
 {
-   double reserved;
uint32_t usable_main_segs = f2fs_get_usable_segments(sb);
uint32_t segs_per_sec = round_up(usable_main_segs, 
get_sb(section_count));
+   uint32_t reserved;
 
if (c.conf_reserved_sections)
reserved = c.conf_reserved_sections * segs_per_sec;
else
reserved = (100 / ovp + 1 + NR_CURSEG_TYPE) * segs_per_sec;
 
-   return reserved;
+   /* Let's keep the section alignment */
+   return round_up(reserved, segs_per_sec) * segs_per_sec;
 }
 
 static inline double get_best_overprovision(struct f2fs_super_block *sb)
 {
-   double reserved, ovp, candidate, end, diff, space;
+   double ovp, candidate, end, diff, space;
double max_ovp = 0, max_space = 0;
uint32_t usable_main_segs = f2fs_get_usable_segments(sb);
+   uint32_t reserved;
 
if (get_sb(segment_count_main) < 256) {
candidate = 10;
@@ -1795,7 +1797,7 @@ static inline double get_best_overprovision(struct 
f2fs_super_block *sb)
ovp = (usable_main_segs - reserved) * candidate / 100;
if (ovp < 0)
continue;
-   space = usable_main_segs - max(reserved, ovp) -
+   space = usable_main_segs - max((double)reserved, ovp) -
2 * get_sb(segs_per_sec);
if (max_space < space) {
max_space = space;
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH] mkfs.f2fs: should give section-aligned reserved segments

2024-02-23 Thread Jaegeuk Kim
The reserved segments should be aligned to the section boundary.

Signed-off-by: Jaegeuk Kim 
---
 include/f2fs_fs.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 9056e02acd29..2e93503cada9 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1771,7 +1771,8 @@ static inline double get_reserved(struct f2fs_super_block 
*sb, double ovp)
else
reserved = (100 / ovp + 1 + NR_CURSEG_TYPE) * segs_per_sec;
 
-   return reserved;
+   /* Let's keep the section alignment */
+   return round_up(reserved, segs_per_sec);
 }
 
 static inline double get_best_overprovision(struct f2fs_super_block *sb)
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH 5/5] f2fs: allow to mount if cap is 100

2024-02-23 Thread Jaegeuk Kim
Don't block mounting the partition, if cap is 100%.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/segment.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6d586ae8b55f..f11361152d2a 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -904,6 +904,9 @@ int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t 
unusable)
 {
int ovp_hole_segs =
(overprovision_segments(sbi) - reserved_segments(sbi));
+
+   if (F2FS_OPTION(sbi).unusable_cap_perc == 100)
+   return 0;
if (unusable > F2FS_OPTION(sbi).unusable_cap)
return -EAGAIN;
if (is_sbi_flag_set(sbi, SBI_CP_DISABLED_QUICK) &&
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH 4/5] f2fs: prevent an f2fs_gc loop during disable_checkpoint

2024-02-23 Thread Jaegeuk Kim
Don't get stuck in the f2fs_gc loop while disabling checkpoint. Instead, we have
a time-based management.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index fc7f1a9fbbda..7d9b92978709 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2191,6 +2191,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info 
*sbi)
.init_gc_type = FG_GC,
.should_migrate_blocks = false,
.err_gc_skipped = true,
+   .no_bg_gc = true,
.nr_free_secs = 1 };
 
f2fs_down_write(>gc_lock);
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH 2/5] f2fs: fix write pointers all the time

2024-02-23 Thread Jaegeuk Kim
Even if the roll forward recovery stopped due to any error, we have to fix
the write pointers in order to mount the disk from the previous checkpoint.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/recovery.c | 2 +-
 fs/f2fs/super.c| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index b3baec666afe..8bbecb5f9323 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -913,7 +913,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool 
check_only)
 * and the f2fs is not read only, check and fix zoned block devices'
 * write pointer consistency.
 */
-   if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
+   if (fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
f2fs_sb_has_blkzoned(sbi)) {
err = f2fs_fix_curseg_write_pointer(sbi);
if (!err)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 2e41142d07c0..4d03ce1109ad 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4673,7 +4673,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
 * If the f2fs is not readonly and fsync data recovery succeeds,
 * check zoned block devices' write pointer consistency.
 */
-   if (!err && !f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
+   if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
err = f2fs_check_write_pointer(sbi);
if (err)
goto free_meta;
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH 3/5] f2fs: print zone status in string and some log

2024-02-23 Thread Jaegeuk Kim
No functional change, but add some more logs.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/segment.c | 34 --
 fs/f2fs/super.c   |  1 +
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index d4f228e6f771..6d586ae8b55f 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4912,6 +4912,16 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi)
 }
 
 #ifdef CONFIG_BLK_DEV_ZONED
+const char *f2fs_zone_status[BLK_ZONE_COND_OFFLINE + 1] = {
+   [BLK_ZONE_COND_NOT_WP]  = "NOT_WP",
+   [BLK_ZONE_COND_EMPTY]   = "EMPTY",
+   [BLK_ZONE_COND_IMP_OPEN]= "IMPLICITE_OPEN",
+   [BLK_ZONE_COND_EXP_OPEN]= "EXPLICITE_OPEN",
+   [BLK_ZONE_COND_CLOSED]  = "CLOSED",
+   [BLK_ZONE_COND_READONLY]= "READONLY",
+   [BLK_ZONE_COND_FULL]= "FULL",
+   [BLK_ZONE_COND_OFFLINE] = "OFFLINE",
+};
 
 static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
struct f2fs_dev_info *fdev,
@@ -4928,18 +4938,22 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
*sbi,
zone_block = fdev->start_blk + (zone->start >> log_sectors_per_block);
zone_segno = GET_SEGNO(sbi, zone_block);
 
+   /*
+* Get # of valid block of the zone.
+*/
+   valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
+
/*
 * Skip check of zones cursegs point to, since
 * fix_curseg_write_pointer() checks them.
 */
if (zone_segno >= MAIN_SEGS(sbi) ||
-   IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno)))
+   IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno))) {
+   f2fs_notice(sbi, "Open zones: valid block[0x%x,0x%x] cond[%s]",
+   zone_segno, valid_block_cnt,
+   f2fs_zone_status[zone->cond]);
return 0;
-
-   /*
-* Get # of valid block of the zone.
-*/
-   valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
+   }
 
if ((!valid_block_cnt && zone->cond == BLK_ZONE_COND_EMPTY) ||
(valid_block_cnt && zone->cond == BLK_ZONE_COND_FULL))
@@ -4947,8 +4961,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
*sbi,
 
if (!valid_block_cnt) {
f2fs_notice(sbi, "Zone without valid block has non-zero write "
-   "pointer. Reset the write pointer: cond[0x%x]",
-   zone->cond);
+   "pointer. Reset the write pointer: cond[%s]",
+   f2fs_zone_status[zone->cond]);
ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
zone->len >> log_sectors_per_block);
if (ret)
@@ -4965,8 +4979,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info 
*sbi,
 * selected for write operation until it get discarded.
 */
f2fs_notice(sbi, "Valid blocks are not aligned with write "
-   "pointer: valid block[0x%x,0x%x] cond[0x%x]",
-   zone_segno, valid_block_cnt, zone->cond);
+   "pointer: valid block[0x%x,0x%x] cond[%s]",
+   zone_segno, valid_block_cnt, f2fs_zone_status[zone->cond]);
 
ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH,
zone->start, zone->len, GFP_NOFS);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4d03ce1109ad..fc7f1a9fbbda 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4674,6 +4674,7 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
 * check zoned block devices' write pointer consistency.
 */
if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
+   f2fs_notice(sbi, "Checking entire write pointers");
err = f2fs_check_write_pointer(sbi);
if (err)
goto free_meta;
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH 1/5] f2fs: check number of blocks in a current section

2024-02-23 Thread Jaegeuk Kim
In cfd66bb715fd ("f2fs: fix deadloop in foreground GC"), we needed to check
the number of blocks in a section instead of the segment.

In addtion, let's check the entire node sections when checking the avaiable
node block space. It does not match one to one per temperature, but currently
we don't have exact dirty page count per temperature. Hence, use a rough
estimation.

Fixes: cfd66bb715fd ("f2fs: fix deadloop in foreground GC")
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/segment.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 3edd3809b6b5..15bf5edd9b3c 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -561,23 +561,23 @@ static inline bool has_curseg_enough_space(struct 
f2fs_sb_info *sbi,
unsigned int node_blocks, unsigned int dent_blocks)
 {
 
-   unsigned int segno, left_blocks;
+   unsigned segno, left_blocks;
int i;
 
-   /* check current node segment */
+   /* check current node sections, which counts very roughly */
+   left_blocks = 0;
for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
segno = CURSEG_I(sbi, i)->segno;
-   left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks;
-
-   if (node_blocks > left_blocks)
-   return false;
+   left_blocks += CAP_BLKS_PER_SEC(sbi) -
+   get_ckpt_valid_blocks(sbi, segno, true);
}
+   if (node_blocks > left_blocks)
+   return false;
 
-   /* check current data segment */
+   /* check current data section for dentry blocks. */
segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
-   left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+   left_blocks = CAP_BLKS_PER_SEC(sbi) -
+   get_ckpt_valid_blocks(sbi, segno, true);
if (dent_blocks > left_blocks)
return false;
return true;
@@ -626,7 +626,7 @@ static inline bool has_not_enough_free_secs(struct 
f2fs_sb_info *sbi,
 
if (free_secs > upper_secs)
return false;
-   else if (free_secs <= lower_secs)
+   if (free_secs <= lower_secs)
return true;
return !curseg_space;
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



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


Re: [f2fs-dev] [PATCH] f2fs: fix to use correct segment type in f2fs_allocate_data_block()

2024-02-23 Thread Jaegeuk Kim
On 02/23, Chao Yu wrote:
> @type in f2fs_allocate_data_block() indicates log header's type, it
> can be CURSEG_COLD_DATA_PINNED or CURSEG_ALL_DATA_ATGC, rather than
> type of data/node, however IS_DATASEG()/IS_NODESEG() only accept later
> one, fix it.
> 
> Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/segment.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index d0209ea77dd2..76422f50e6cc 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3505,12 +3505,12 @@ void f2fs_allocate_data_block(struct f2fs_sb_info 
> *sbi, struct page *page,
>   locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
>   locate_dirty_segment(sbi, GET_SEGNO(sbi, *new_blkaddr));
>  
> - if (IS_DATASEG(type))
> + if (IS_DATASEG(se->type))

We have se only when type is CURSEG_ALL_DATA_ATGC. We may need to change
IS_DATASEG()?

>   atomic64_inc(>allocated_data_blocks);
>  
>   up_write(_i->sentry_lock);
>  
> - if (page && IS_NODESEG(type)) {
> + if (page && IS_NODESEG(se->type)) {
>   fill_node_footer_blkaddr(page, NEXT_FREE_BLKADDR(sbi, curseg));
>  
>   f2fs_inode_chksum_set(sbi, page);
> -- 
> 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] f2fs: introduce SEGS_TO_BLKS/BLKS_TO_SEGS for cleanup

2024-02-23 Thread Jaegeuk Kim
Chao,

I applied the below as well in order to keep zone capacity back.

--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -101,11 +101,10 @@ static inline void sanity_check_seg_type(struct 
f2fs_sb_info *sbi,
NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \
GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
 #define CAP_BLKS_PER_SEC(sbi)  \
-   (SEGS_PER_SEC(sbi) * BLKS_PER_SEG(sbi) -\
-(sbi)->unusable_blocks_per_sec)
+   (BLKS_PER_SEC(sbi) - (sbi)->unusable_blocks_per_sec)
 #define CAP_SEGS_PER_SEC(sbi)  \
-   (SEGS_PER_SEC(sbi) - ((sbi)->unusable_blocks_per_sec >> \
-   (sbi)->log_blocks_per_seg))
+   (SEGS_PER_SEC(sbi) -\
+   BLKS_TO_SEGS(sbi, (sbi)->unusable_blocks_per_sec)
 #define GET_SEC_FROM_SEG(sbi, segno)   \
(((segno) == -1) ? -1 : (segno) / SEGS_PER_SEC(sbi))
 #define GET_SEG_FROM_SEC(sbi, secno)   \


On 02/21, Chao Yu wrote:
> Just cleanup, no functional change.
> 
> Signed-off-by: Chao Yu 
> ---
>  fs/f2fs/debug.c   |  7 +++
>  fs/f2fs/f2fs.h| 14 --
>  fs/f2fs/gc.c  | 10 +-
>  fs/f2fs/gc.h  |  4 ++--
>  fs/f2fs/segment.c | 12 ++--
>  fs/f2fs/segment.h |  8 
>  fs/f2fs/super.c   | 16 
>  fs/f2fs/sysfs.c   |  4 ++--
>  8 files changed, 38 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> index 6617195bd27e..12893477f2e4 100644
> --- a/fs/f2fs/debug.c
> +++ b/fs/f2fs/debug.c
> @@ -134,7 +134,7 @@ static void update_general_status(struct f2fs_sb_info 
> *sbi)
>   si->cur_ckpt_time = sbi->cprc_info.cur_time;
>   si->peak_ckpt_time = sbi->cprc_info.peak_time;
>   spin_unlock(>cprc_info.stat_lock);
> - si->total_count = (int)sbi->user_block_count / BLKS_PER_SEG(sbi);
> + si->total_count = BLKS_TO_SEGS(sbi, (int)sbi->user_block_count);
>   si->rsvd_segs = reserved_segments(sbi);
>   si->overp_segs = overprovision_segments(sbi);
>   si->valid_count = valid_user_blocks(sbi);
> @@ -175,11 +175,10 @@ static void update_general_status(struct f2fs_sb_info 
> *sbi)
>   si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
>   si->io_skip_bggc = sbi->io_skip_bggc;
>   si->other_skip_bggc = sbi->other_skip_bggc;
> - si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
> + si->util_free = (int)(BLKS_TO_SEGS(sbi, free_user_blocks(sbi)))
>   * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
>   / 2;
> - si->util_valid = (int)(written_block_count(sbi) >>
> - sbi->log_blocks_per_seg)
> + si->util_valid = (int)(BLKS_TO_SEGS(sbi, written_block_count(sbi)))
>   * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
>   / 2;
>   si->util_invalid = 50 - si->util_free - si->util_valid;
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index dad2774ca72f..8a6fd4352a0e 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1813,12 +1813,14 @@ struct f2fs_sb_info {
>  };
>  
>  /* Definitions to access f2fs_sb_info */
> -#define BLKS_PER_SEG(sbi)\
> - ((sbi)->blocks_per_seg)
> -#define BLKS_PER_SEC(sbi)\
> - ((sbi)->segs_per_sec << (sbi)->log_blocks_per_seg)
> -#define SEGS_PER_SEC(sbi)\
> - ((sbi)->segs_per_sec)
> +#define SEGS_TO_BLKS(sbi, segs)  \
> + ((segs) << (sbi)->log_blocks_per_seg)
> +#define BLKS_TO_SEGS(sbi, blks)  \
> + ((blks) >> (sbi)->log_blocks_per_seg)
> +
> +#define BLKS_PER_SEG(sbi)((sbi)->blocks_per_seg)
> +#define BLKS_PER_SEC(sbi)(SEGS_TO_BLKS(sbi, (sbi)->segs_per_sec))
> +#define SEGS_PER_SEC(sbi)((sbi)->segs_per_sec)
>  
>  __printf(3, 4)
>  void f2fs_printk(struct f2fs_sb_info *sbi, bool limit_rate, const char *fmt, 
> ...);
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 3ff126316d42..6d160d50e14e 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -301,7 +301,7 @@ static unsigned int get_max_cost(struct f2fs_sb_info *sbi,
>  
>   /* LFS */
>   if (p->gc_mode == GC_GREEDY)
> - return 2 * BLKS_PER_SEG(sbi) * p->ofs_unit;
> + return SEGS_TO_BLKS(sbi, 2 * p->ofs_unit);
>   else if (p->gc_mode == GC_CB)
>   return UINT_MAX;
>   else if (p->gc_mode == GC_AT)
> @@ -347,7 +347,7 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, 
> unsigned int segno)
>   mtime = div_u64(mtime, SEGS_PER_SEC(sbi));
>   vblocks = div_u64(vblocks, SEGS_PER_SEC(sbi));
>  
> - u = (vblocks * 100) >> sbi->log_blocks_per_seg;
> + u = BLKS_TO_SEGS(sbi, vblocks * 100);
>  
>   /* Handle if the system 

Re: [f2fs-dev] [PATCH 3/3 v2] f2fs: kill zone-capacity support

2024-02-23 Thread Jaegeuk Kim
On 02/22, Matias Bjørling wrote:
> On 21-02-2024 18:27, Jaegeuk Kim wrote:
> 
> > > Doesn't this break practically all ZNS NVMe devices?
> > 
> > Yes, so here I'm in questioning who is really using w/ zone capacity. If 
> > there's
> > no user complaining, I'd like to deprecate this, since this adds code 
> > complexity
> > and unnecessary checks.
> > 
> 
> Hi Jaegeuk,
> 
> I like to make a couple of points to hopefully keep the support in a little
> while longer.
> 
> - NVMe-based zone devices continue to be developed with the pow2 zone size
> and zone size != zone cap features. There was some divergence in the
> first-gen drives. However, all the second-gen drives I know of are
> implemented with those features in mind.
> 
> - A very active community is doing work using f2fs, and many of those
> members are working with the ZN540s device (which exposes a pow2 zone size).
> 
> - For drives with a capacity of less than 16TiB, f2fs is an excellent file
> system to use and is really useful for various use cases. We're using the
> f2fs daily for a couple of our workloads.
> 
> Work is ongoing on btrfs and XFS to support zoned storage devices, but they
> have yet to be through the trenches as much as f2fs has been with its zone
> support. So it would be great to have f2fs continue to support the pow2 zone
> sizes, as it is a valuable feature for the currently used and second-gen
> drives that have been released or are soon becoming available.
> 
> If there is a performance concern with the feature re: ZUFS, maybe the pow2
> implementation could be slightly more computationally expensive, as the
> feature, anyway, typically is used on more beefy systems.

Thanks, Matias for the background. It seems to be fair for keeping this for a
while tho, IMO, non-pow2 could address both parties.

> 
> Regards,
> Matias


___
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 2/2] f2fs: support file pinning for zoned devices

2024-02-23 Thread Jaegeuk Kim
Hi Chao,

I've tested the patch and queued in -dev, so can you take a look at it and
propose any change on top of it? Then, we can discuss further on it.

On 02/23, Chao Yu wrote:
> On 2024/2/14 1:38, Daeho Jeong wrote:
> > From: Daeho Jeong 
> > 
> > Support file pinning with conventional storage area for zoned devices
> > 
> > Signed-off-by: Daeho Jeong 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> > v3: check the hole when migrating blocks for swap.
> >  do not use the remainder of cold pin section.
> > v2: flush previous dirty pages before swapon.
> >  do not re-check for the last extent of swap area.
> >  merge this patch with swap file pinning support patch.
> > ---
> >   fs/f2fs/data.c| 58 ++-
> >   fs/f2fs/f2fs.h| 17 +++-
> >   fs/f2fs/file.c| 24 -
> >   fs/f2fs/gc.c  | 14 +++---
> >   fs/f2fs/segment.c | 69 +--
> >   fs/f2fs/segment.h | 10 +++
> >   6 files changed, 154 insertions(+), 38 deletions(-)
> > 
> > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > index 828c797cd47c..0c9aa3082fcf 100644
> > --- a/fs/f2fs/data.c
> > +++ b/fs/f2fs/data.c
> > @@ -3839,25 +3839,34 @@ static int f2fs_migrate_blocks(struct inode *inode, 
> > block_t start_blk,
> > unsigned int blkofs;
> > unsigned int blk_per_sec = BLKS_PER_SEC(sbi);
> > unsigned int secidx = start_blk / blk_per_sec;
> > -   unsigned int end_sec = secidx + blkcnt / blk_per_sec;
> > +   unsigned int end_sec;
> > int ret = 0;
> > +   if (!blkcnt)
> > +   return 0;
> > +   end_sec = secidx + (blkcnt - 1) / blk_per_sec;
> > +
> > f2fs_down_write(_I(inode)->i_gc_rwsem[WRITE]);
> > filemap_invalidate_lock(inode->i_mapping);
> > set_inode_flag(inode, FI_ALIGNED_WRITE);
> > set_inode_flag(inode, FI_OPU_WRITE);
> > -   for (; secidx < end_sec; secidx++) {
> > +   for (; secidx <= end_sec; secidx++) {
> > +   unsigned int blkofs_end = secidx == end_sec ?
> > +   (blkcnt - 1) % blk_per_sec : blk_per_sec - 1;
> > +
> > f2fs_down_write(>pin_sem);
> > -   f2fs_lock_op(sbi);
> > -   f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false);
> > -   f2fs_unlock_op(sbi);
> > +   ret = f2fs_allocate_pinning_section(sbi);
> > +   if (ret) {
> > +   f2fs_up_write(>pin_sem);
> > +   break;
> > +   }
> > set_inode_flag(inode, FI_SKIP_WRITES);
> > -   for (blkofs = 0; blkofs < blk_per_sec; blkofs++) {
> > +   for (blkofs = 0; blkofs <= blkofs_end; blkofs++) {
> > struct page *page;
> > unsigned int blkidx = secidx * blk_per_sec + blkofs;
> > @@ -3946,27 +3955,34 @@ static int check_swap_activate(struct 
> > swap_info_struct *sis,
> > nr_pblocks = map.m_len;
> > if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
> > -   nr_pblocks & sec_blks_mask) {
> > +   nr_pblocks & sec_blks_mask ||
> > +   !f2fs_valid_pinned_area(sbi, pblock)) {
> > +   bool last_extent = false;
> > +
> > not_aligned++;
> > nr_pblocks = roundup(nr_pblocks, blks_per_sec);
> > if (cur_lblock + nr_pblocks > sis->max)
> > nr_pblocks -= blks_per_sec;
> > +   /* this extent is last one */
> > if (!nr_pblocks) {
> > -   /* this extent is last one */
> > -   nr_pblocks = map.m_len;
> > -   f2fs_warn(sbi, "Swapfile: last extent is not 
> > aligned to section");
> > -   goto next;
> > +   nr_pblocks = last_lblock - cur_lblock;
> > +   last_extent = true;
> > }
> > ret = f2fs_migrate_blocks(inode, cur_lblock,
> > nr_pblocks);
> > -   if (ret)
> > +   if (ret) {
> > +   if (ret == -ENOENT)
> > +   ret = -EINVAL;
> > goto out;
> > - 

Re: [f2fs-dev] [PATCH 3/3 v2] f2fs: kill zone-capacity support

2024-02-21 Thread Jaegeuk Kim
On 02/21, Juhyung Park wrote:
> On Wed, Feb 21, 2024 at 4:03 AM Jaegeuk Kim  wrote:
> >
> > On 02/20, Chao Yu wrote:
> > > Jaegeuk, Daeho,
> > >
> > > Do we need Cc WD guys? Not sure whether they need this feature...
> >
> > CC'ed WDC folks.
> >
> > >
> > > For ZUFS: 1) will it only exports 2MB-aligned zone size, and 2) its zone
> > > capacity equals zone size?
> >
> > Yeah, I think f2fs just needs to check 2MB alignment only.
> >
> 
> Doesn't this break practically all ZNS NVMe devices?

Yes, so here I'm in questioning who is really using w/ zone capacity. If there's
no user complaining, I'd like to deprecate this, since this adds code complexity
and unnecessary checks.

> 
> dm-po2zoned isn't merged yet, and PO2 is still enforced on NVMe's
> side, and afaik vendors are doing capacity != size to comply with PO2
> requirements on the ZNS-side.
> 
> > >
> > > Thanks,
> > >
> > > On 2024/2/8 7:29, Jaegeuk Kim wrote:
> > > > Since we don't see any user, let's kill.
> > > >
> > > > Signed-off-by: Jaegeuk Kim 
> > > > ---
> > > >
> > > >   from v1:
> > > >- keep setting the seq bit
> > > >
> > > >   Documentation/ABI/testing/sysfs-fs-f2fs |  6 --
> > > >   fs/f2fs/debug.c |  7 +-
> > > >   fs/f2fs/f2fs.h  |  5 --
> > > >   fs/f2fs/file.c  |  6 +-
> > > >   fs/f2fs/gc.c| 33 +++--
> > > >   fs/f2fs/gc.h| 26 ---
> > > >   fs/f2fs/segment.c   | 93 +++--
> > > >   fs/f2fs/segment.h   | 41 ---
> > > >   fs/f2fs/super.c | 16 ++---
> > > >   fs/f2fs/sysfs.c |  6 --
> > > >   10 files changed, 44 insertions(+), 195 deletions(-)
> > > >
> > > > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> > > > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > > > index 48c135e24eb5..dff8c87d87dd 100644
> > > > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > > > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > > > @@ -628,12 +628,6 @@ Contact:   "Jaegeuk Kim" 
> > > >   Description:  Controls max # of node block writes to be used for 
> > > > roll forward
> > > > recovery. This can limit the roll forward recovery time.
> > > > -What:  /sys/fs/f2fs//unusable_blocks_per_sec
> > > > -Date:  June 2022
> > > > -Contact:   "Jaegeuk Kim" 
> > > > -Description:   Shows the number of unusable blocks in a section 
> > > > which was defined by
> > > > -   the zone capacity reported by underlying zoned device.
> > > > -
> > > >   What: /sys/fs/f2fs//current_atomic_write
> > > >   Date: July 2022
> > > >   Contact:  "Daeho Jeong" 
> > > > diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> > > > index 0d02224b99b7..6617195bd27e 100644
> > > > --- a/fs/f2fs/debug.c
> > > > +++ b/fs/f2fs/debug.c
> > > > @@ -32,21 +32,20 @@ static struct dentry *f2fs_debugfs_root;
> > > >   void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
> > > >   {
> > > > struct f2fs_stat_info *si = F2FS_STAT(sbi);
> > > > -   unsigned long long blks_per_sec, hblks_per_sec, total_vblocks;
> > > > +   unsigned long long hblks_per_sec, total_vblocks;
> > > > unsigned long long bimodal, dist;
> > > > unsigned int segno, vblocks;
> > > > int ndirty = 0;
> > > > bimodal = 0;
> > > > total_vblocks = 0;
> > > > -   blks_per_sec = CAP_BLKS_PER_SEC(sbi);
> > > > -   hblks_per_sec = blks_per_sec / 2;
> > > > +   hblks_per_sec = BLKS_PER_SEC(sbi) / 2;
> > > > for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) 
> > > > {
> > > > vblocks = get_valid_blocks(sbi, segno, true);
> > > > dist = abs(vblocks - hblks_per_sec);
> > > > bimodal += dist * dist;
> > > > -   if (vblocks > 0 && vblocks < blks_per_sec) {
> > > > +   if (vblocks > 0 && vblocks < BLKS_PER_SEC(sbi)) {
> > > >

Re: [f2fs-dev] [PATCH] f2fs: support compress extension update via sysfs interface

2024-02-20 Thread Jaegeuk Kim
On 02/21, Chao Yu wrote:
> On 2024/2/21 3:28, Jaegeuk Kim wrote:
> > On 02/19, Chao Yu wrote:
> > > On 2024/2/8 8:07, Jaegeuk Kim wrote:
> > > > On 02/07, Chao Yu wrote:
> > > > > Introduce /sys/fs/f2fs//compress_extension to support
> > > > > adding/deleting compress extension via sysfs interface, in
> > > > > comparison to mount option, it's more easy to use and less
> > > > > authority issue for applications.
> > > > > 
> > > > > Usage:
> > > > > - Query: cat /sys/fs/f2fs//compress_extension
> > > > > - Add: echo '[c|n]extension' > /sys/fs/f2fs//compress_extension
> > > > > - Del: echo '[c|n]!extension' > /sys/fs/f2fs//compress_extension
> > > > > - [c] means add/del compress extension
> > > > > - [n] means add/del nocompress extension
> > > > > 
> > > > > Signed-off-by: Sheng Yong 
> > > > > Signed-off-by: Chao Yu 
> > > > > ---
> > > > >Documentation/ABI/testing/sysfs-fs-f2fs | 10 
> > > > >Documentation/filesystems/f2fs.rst  |  6 ++-
> > > > >fs/f2fs/compress.c  | 61 
> > > > > +++
> > > > >fs/f2fs/f2fs.h  |  4 +-
> > > > >fs/f2fs/sysfs.c | 65 
> > > > > +++--
> > > > >5 files changed, 139 insertions(+), 7 deletions(-)
> > > > > 
> > > > > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> > > > > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > > > > index 48c135e24eb5..1f2cc0913e45 100644
> > > > > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > > > > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > > > > @@ -762,3 +762,13 @@ Date:November 2023
> > > > >Contact:   "Chao Yu" 
> > > > >Description:   It controls to enable/disable IO aware feature 
> > > > > for background discard.
> > > > >   By default, the value is 1 which indicates IO aware is 
> > > > > on.
> > > > > +
> > > > > +What:/sys/fs/f2fs//compress_extension
> > > > > +Date:October 2023
> > > > > +Contact: "Chao Yu" 
> > > > > +Description: Used to control configure [|no]compress_extension list:
> > > > > + - Query: cat /sys/fs/f2fs//compress_extension
> > > > > + - Add: echo '[c|n]extension' > 
> > > > > /sys/fs/f2fs//compress_extension
> > > > > + - Del: echo '[c|n]!extension' > 
> > > > > /sys/fs/f2fs//compress_extension
> > > > > + - [c] means add/del compress extension
> > > > > + - [n] means add/del nocompress extension
> > > > > diff --git a/Documentation/filesystems/f2fs.rst 
> > > > > b/Documentation/filesystems/f2fs.rst
> > > > > index 32cbfa864f38..c82a8fd7316b 100644
> > > > > --- a/Documentation/filesystems/f2fs.rst
> > > > > +++ b/Documentation/filesystems/f2fs.rst
> > > > > @@ -821,17 +821,19 @@ Compression implementation
> > > > >  all logical blocks in cluster contain valid data and compress 
> > > > > ratio of
> > > > >  cluster data is lower than specified threshold.
> > > > > -- To enable compression on regular inode, there are four ways:
> > > > > +- To enable compression on regular inode, there are five ways:
> > > > >  * chattr +c file
> > > > >  * chattr +c dir; touch dir/file
> > > > >  * mount w/ -o compress_extension=ext; touch file.ext
> > > > >  * mount w/ -o compress_extension=*; touch any_file
> > > > > +  * echo '[c]ext' > /sys/fs/f2fs//compress_extension; touch 
> > > > > file.ext
> > > > > -- To disable compression on regular inode, there are two ways:
> > > > > +- To disable compression on regular inode, there are three ways:
> > > > >  * chattr -c file
> > > > >  * mount w/ -o nocompress_extension=ext; touch file.ext
> > > > > +  * echo '[n]ext' > /sys/fs/f2fs//compress_extension; touch 
> > > > > file.ext
> > > > >- Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions

Re: [f2fs-dev] [PATCH v2] f2fs: kill heap-based allocation

2024-02-20 Thread Jaegeuk Kim
On 02/21, Chao Yu wrote:
> On 2024/2/21 4:51, Jaegeuk Kim wrote:
> > No one uses this feature. Let's kill it.
> > 
> > Reviewed-by: Daeho Jeong 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> > 
> >   Change log from v1:
> >- keep mount options but give warnings instead
> > 
> >   Documentation/filesystems/f2fs.rst |  4 +--
> >   fs/f2fs/gc.c   |  5 ++-
> >   fs/f2fs/segment.c  | 54 --
> >   fs/f2fs/segment.h  | 10 --
> >   fs/f2fs/super.c|  9 +
> >   5 files changed, 11 insertions(+), 71 deletions(-)
> > 
> > diff --git a/Documentation/filesystems/f2fs.rst 
> > b/Documentation/filesystems/f2fs.rst
> > index 9ac5083dae8e..c30a800604fd 100644
> > --- a/Documentation/filesystems/f2fs.rst
> > +++ b/Documentation/filesystems/f2fs.rst
> > @@ -126,9 +126,7 @@ norecovery   Disable the roll-forward 
> > recovery routine, mounted read-
> >   discard/nodiscard  Enable/disable real-time discard in f2fs, if discard is
> >  enabled, f2fs will issue discard/TRIM commands when a
> >  segment is cleaned.
> > -no_heap Disable heap-style segment allocation which 
> > finds free
> > -segments for data from the beginning of main area, 
> > while
> > -for node from the end of main area.
> > +no_heap Deprecated.
> 
> heap/no_heap  Deprecated
> 
> Otherwise, it looks good to me.
> 
> Reviewed-by: Chao Yu 
> 
> BTW, do we need to kill heap-based allocation in mkfs.f2fs as well?

I was about to work on it after kernel change tho. Can you write one? :)

> 
> Thanks,
> 
> >   nouser_xattr   Disable Extended User Attributes. Note: xattr 
> > is enabled
> >  by default if CONFIG_F2FS_FS_XATTR is selected.
> >   noacl  Disable POSIX Access Control List. Note: acl 
> > is enabled
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index 501b93b45b6c..a089a938355b 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -280,12 +280,11 @@ static void select_policy(struct f2fs_sb_info *sbi, 
> > int gc_type,
> > p->max_search > sbi->max_victim_search)
> > p->max_search = sbi->max_victim_search;
> > -   /* let's select beginning hot/small space first in no_heap mode*/
> > +   /* let's select beginning hot/small space first. */
> > if (f2fs_need_rand_seg(sbi))
> > p->offset = get_random_u32_below(MAIN_SECS(sbi) *
> > SEGS_PER_SEC(sbi));
> > -   else if (test_opt(sbi, NOHEAP) &&
> > -   (type == CURSEG_HOT_DATA || IS_NODESEG(type)))
> > +   else if (type == CURSEG_HOT_DATA || IS_NODESEG(type))
> > p->offset = 0;
> > else
> > p->offset = SIT_I(sbi)->last_victim[p->gc_mode];
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index 94c4f7b16c19..09af17af4e7a 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -2634,16 +2634,14 @@ static int is_next_segment_free(struct f2fs_sb_info 
> > *sbi,
> >* This function should be returned with success, otherwise BUG
> >*/
> >   static void get_new_segment(struct f2fs_sb_info *sbi,
> > -   unsigned int *newseg, bool new_sec, int dir)
> > +   unsigned int *newseg, bool new_sec)
> >   {
> > struct free_segmap_info *free_i = FREE_I(sbi);
> > unsigned int segno, secno, zoneno;
> > unsigned int total_zones = MAIN_SECS(sbi) / sbi->secs_per_zone;
> > unsigned int hint = GET_SEC_FROM_SEG(sbi, *newseg);
> > unsigned int old_zoneno = GET_ZONE_FROM_SEG(sbi, *newseg);
> > -   unsigned int left_start = hint;
> > bool init = true;
> > -   int go_left = 0;
> > int i;
> > spin_lock(_i->segmap_lock);
> > @@ -2657,30 +2655,10 @@ static void get_new_segment(struct f2fs_sb_info 
> > *sbi,
> >   find_other_zone:
> > secno = find_next_zero_bit(free_i->free_secmap, MAIN_SECS(sbi), hint);
> > if (secno >= MAIN_SECS(sbi)) {
> > -   if (dir == ALLOC_RIGHT) {
> > -   secno = find_first_zero_bit(free_i->free_secmap,
> > +   secno = find_first_zero_bit(free_i->free_secmap,
> > MAIN_SECS(sbi));
> > - 

Re: [f2fs-dev] [PATCH 2/3 v3] f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC

2024-02-20 Thread Jaegeuk Kim
On 02/21, Chao Yu wrote:
> On 2024/2/21 4:39, Jaegeuk Kim wrote:
> > No functional change.
> > 
> > Reviewed-by: Daeho Jeong 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >Change log from v2:
> > - cover more cases
> >Change log from v1:
> > - use div_u64
> >   fs/f2fs/checkpoint.c |  10 ++--
> >   fs/f2fs/debug.c  |   6 +--
> >   fs/f2fs/f2fs.h   |  21 +
> >   fs/f2fs/file.c   |  16 +++
> >   fs/f2fs/gc.c |  40 
> >   fs/f2fs/node.c   |   4 +-
> >   fs/f2fs/node.h   |   4 +-
> >   fs/f2fs/recovery.c   |   2 +-
> >   fs/f2fs/segment.c| 110 +--
> >   fs/f2fs/segment.h|  44 +
> >   fs/f2fs/super.c  |   8 ++--
> >   fs/f2fs/sysfs.c  |   6 +--
> >   12 files changed, 135 insertions(+), 136 deletions(-)
> > 
> > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> > index b85820e70f5e..a09a9609e228 100644
> > --- a/fs/f2fs/checkpoint.c
> > +++ b/fs/f2fs/checkpoint.c
> > @@ -900,7 +900,7 @@ static struct page *validate_checkpoint(struct 
> > f2fs_sb_info *sbi,
> > cp_blocks = le32_to_cpu(cp_block->cp_pack_total_block_count);
> > -   if (cp_blocks > sbi->blocks_per_seg || cp_blocks <= F2FS_CP_PACKS) {
> > +   if (cp_blocks > BLKS_PER_SEG(sbi) || cp_blocks <= F2FS_CP_PACKS) {
> > f2fs_warn(sbi, "invalid cp_pack_total_block_count:%u",
> >   le32_to_cpu(cp_block->cp_pack_total_block_count));
> > goto invalid_cp;
> > @@ -1335,7 +1335,7 @@ static void update_ckpt_flags(struct f2fs_sb_info 
> > *sbi, struct cp_control *cpc)
> > if (cpc->reason & CP_UMOUNT) {
> > if (le32_to_cpu(ckpt->cp_pack_total_block_count) +
> > -   NM_I(sbi)->nat_bits_blocks > sbi->blocks_per_seg) {
> > +   NM_I(sbi)->nat_bits_blocks > BLKS_PER_SEG(sbi)) {
> > clear_ckpt_flags(sbi, CP_NAT_BITS_FLAG);
> > f2fs_notice(sbi, "Disable nat_bits due to no space");
> > } else if (!is_set_ckpt_flags(sbi, CP_NAT_BITS_FLAG) &&
> > @@ -1538,7 +1538,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, 
> > struct cp_control *cpc)
> > cp_ver |= ((__u64)crc32 << 32);
> > *(__le64 *)nm_i->nat_bits = cpu_to_le64(cp_ver);
> > -   blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks;
> > +   blk = start_blk + BLKS_PER_SEG(sbi) - nm_i->nat_bits_blocks;
> > for (i = 0; i < nm_i->nat_bits_blocks; i++)
> > f2fs_update_meta_page(sbi, nm_i->nat_bits +
> > (i << F2FS_BLKSIZE_BITS), blk + i);
> > @@ -1741,9 +1741,9 @@ void f2fs_init_ino_entry_info(struct f2fs_sb_info 
> > *sbi)
> > im->ino_num = 0;
> > }
> > -   sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS -
> > +   sbi->max_orphans = (BLKS_PER_SEG(sbi) - F2FS_CP_PACKS -
> > NR_CURSEG_PERSIST_TYPE - __cp_payload(sbi)) *
> > -   F2FS_ORPHANS_PER_BLOCK;
> > +   F2FS_ORPHANS_PER_BLOCK;
> >   }
> >   int __init f2fs_create_checkpoint_caches(void)
> > diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> > index fdbf994f1271..0d02224b99b7 100644
> > --- a/fs/f2fs/debug.c
> > +++ b/fs/f2fs/debug.c
> > @@ -41,7 +41,7 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
> > total_vblocks = 0;
> > blks_per_sec = CAP_BLKS_PER_SEC(sbi);
> > hblks_per_sec = blks_per_sec / 2;
> > -   for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
> > +   for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
> > vblocks = get_valid_blocks(sbi, segno, true);
> > dist = abs(vblocks - hblks_per_sec);
> > bimodal += dist * dist;
> > @@ -135,7 +135,7 @@ static void update_general_status(struct f2fs_sb_info 
> > *sbi)
> > si->cur_ckpt_time = sbi->cprc_info.cur_time;
> > si->peak_ckpt_time = sbi->cprc_info.peak_time;
> > spin_unlock(>cprc_info.stat_lock);
> > -   si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg;
> > +   si->total_count = (int)sbi->user_block_count / BLKS_PER_SEG(sbi);
> > si->rsvd_segs = reserved_segments(sbi);
> > si->overp_segs = overprovision_segments(sbi);

[f2fs-dev] [PATCH 2/3] f2fs: prevent an f2fs_gc loop during disable_checkpoint

2024-02-20 Thread Jaegeuk Kim
Don't get stuck in the f2fs_gc loop while disabling checkpoint. Instead, we have
a time-based management.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/super.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ad80cd38f3a4..9de467a28fd3 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2190,6 +2190,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info 
*sbi)
.init_gc_type = FG_GC,
.should_migrate_blocks = false,
.err_gc_skipped = true,
+   .no_bg_gc = true,
.nr_free_secs = 1 };
 
f2fs_down_write(>gc_lock);
-- 
2.44.0.rc0.258.g7320e95886-goog



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


[f2fs-dev] [PATCH 1/3] f2fs: check number of blocks in a current section

2024-02-20 Thread Jaegeuk Kim
In cfd66bb715fd ("f2fs: fix deadloop in foreground GC"), we needed to check
the number of blocks in a section instead of the segment.

Fixes: cfd66bb715fd ("f2fs: fix deadloop in foreground GC")
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/segment.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 63f278210654..9fe5ec619456 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -560,16 +560,16 @@ static inline bool has_curseg_enough_space(struct 
f2fs_sb_info *sbi,
/* check current node segment */
for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
segno = CURSEG_I(sbi, i)->segno;
-   left_blocks = BLKS_PER_SEG(sbi) -
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+   left_blocks = BLKS_PER_SEC(sbi) -
+   get_ckpt_valid_blocks(sbi, segno, true);
if (node_blocks > left_blocks)
return false;
}
 
/* check current data segment */
segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
-   left_blocks = BLKS_PER_SEG(sbi) -
-   get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+   left_blocks = BLKS_PER_SEC(sbi) -
+   get_ckpt_valid_blocks(sbi, segno, true);
if (dent_blocks > left_blocks)
return false;
return true;
-- 
2.44.0.rc0.258.g7320e95886-goog



___
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: allow to mount if cap is 100

2024-02-20 Thread Jaegeuk Kim
Don't block mounting the partition, if cap is 100%.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/segment.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 160ee550cbfe..56927b097e30 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -894,6 +894,9 @@ int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t 
unusable)
 {
int ovp_hole_segs =
(overprovision_segments(sbi) - reserved_segments(sbi));
+
+   if (F2FS_OPTION(sbi).unusable_cap_perc == 100)
+   return 0;
if (unusable > F2FS_OPTION(sbi).unusable_cap)
return -EAGAIN;
if (is_sbi_flag_set(sbi, SBI_CP_DISABLED_QUICK) &&
-- 
2.44.0.rc0.258.g7320e95886-goog



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


Re: [f2fs-dev] [PATCH v2] f2fs: kill heap-based allocation

2024-02-20 Thread Jaegeuk Kim
No one uses this feature. Let's kill it.

Reviewed-by: Daeho Jeong 
Signed-off-by: Jaegeuk Kim 
---

 Change log from v1:
  - keep mount options but give warnings instead

 Documentation/filesystems/f2fs.rst |  4 +--
 fs/f2fs/gc.c   |  5 ++-
 fs/f2fs/segment.c  | 54 --
 fs/f2fs/segment.h  | 10 --
 fs/f2fs/super.c|  9 +
 5 files changed, 11 insertions(+), 71 deletions(-)

diff --git a/Documentation/filesystems/f2fs.rst 
b/Documentation/filesystems/f2fs.rst
index 9ac5083dae8e..c30a800604fd 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -126,9 +126,7 @@ norecovery   Disable the roll-forward recovery 
routine, mounted read-
 discard/nodiscard   Enable/disable real-time discard in f2fs, if discard is
 enabled, f2fs will issue discard/TRIM commands when a
 segment is cleaned.
-no_heap Disable heap-style segment allocation which 
finds free
-segments for data from the beginning of main area, 
while
-for node from the end of main area.
+no_heap Deprecated.
 nouser_xattrDisable Extended User Attributes. Note: xattr is 
enabled
 by default if CONFIG_F2FS_FS_XATTR is selected.
 noacl   Disable POSIX Access Control List. Note: acl is enabled
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 501b93b45b6c..a089a938355b 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -280,12 +280,11 @@ static void select_policy(struct f2fs_sb_info *sbi, int 
gc_type,
p->max_search > sbi->max_victim_search)
p->max_search = sbi->max_victim_search;
 
-   /* let's select beginning hot/small space first in no_heap mode*/
+   /* let's select beginning hot/small space first. */
if (f2fs_need_rand_seg(sbi))
p->offset = get_random_u32_below(MAIN_SECS(sbi) *
SEGS_PER_SEC(sbi));
-   else if (test_opt(sbi, NOHEAP) &&
-   (type == CURSEG_HOT_DATA || IS_NODESEG(type)))
+   else if (type == CURSEG_HOT_DATA || IS_NODESEG(type))
p->offset = 0;
else
p->offset = SIT_I(sbi)->last_victim[p->gc_mode];
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 94c4f7b16c19..09af17af4e7a 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2634,16 +2634,14 @@ static int is_next_segment_free(struct f2fs_sb_info 
*sbi,
  * This function should be returned with success, otherwise BUG
  */
 static void get_new_segment(struct f2fs_sb_info *sbi,
-   unsigned int *newseg, bool new_sec, int dir)
+   unsigned int *newseg, bool new_sec)
 {
struct free_segmap_info *free_i = FREE_I(sbi);
unsigned int segno, secno, zoneno;
unsigned int total_zones = MAIN_SECS(sbi) / sbi->secs_per_zone;
unsigned int hint = GET_SEC_FROM_SEG(sbi, *newseg);
unsigned int old_zoneno = GET_ZONE_FROM_SEG(sbi, *newseg);
-   unsigned int left_start = hint;
bool init = true;
-   int go_left = 0;
int i;
 
spin_lock(_i->segmap_lock);
@@ -2657,30 +2655,10 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
 find_other_zone:
secno = find_next_zero_bit(free_i->free_secmap, MAIN_SECS(sbi), hint);
if (secno >= MAIN_SECS(sbi)) {
-   if (dir == ALLOC_RIGHT) {
-   secno = find_first_zero_bit(free_i->free_secmap,
+   secno = find_first_zero_bit(free_i->free_secmap,
MAIN_SECS(sbi));
-   f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi));
-   } else {
-   go_left = 1;
-   left_start = hint - 1;
-   }
-   }
-   if (go_left == 0)
-   goto skip_left;
-
-   while (test_bit(left_start, free_i->free_secmap)) {
-   if (left_start > 0) {
-   left_start--;
-   continue;
-   }
-   left_start = find_first_zero_bit(free_i->free_secmap,
-   MAIN_SECS(sbi));
-   f2fs_bug_on(sbi, left_start >= MAIN_SECS(sbi));
-   break;
+   f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi));
}
-   secno = left_start;
-skip_left:
segno = GET_SEG_FROM_SEC(sbi, secno);
zoneno = GET_ZONE_FROM_SEC(sbi, secno);
 
@@ -2691,21 +2669,13 @@ static void get_new_segment(struct f2fs_sb_info *sbi,
goto got_it;
if (zoneno == old_zoneno)
goto got_it;
-   if (dir == ALLOC_LEFT) {
-   if (

Re: [f2fs-dev] [PATCH 2/3 v3] f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC

2024-02-20 Thread Jaegeuk Kim
No functional change.

Reviewed-by: Daeho Jeong 
Signed-off-by: Jaegeuk Kim 
---
  Change log from v2:
   - cover more cases
 
  Change log from v1:
   - use div_u64
 
 fs/f2fs/checkpoint.c |  10 ++--
 fs/f2fs/debug.c  |   6 +--
 fs/f2fs/f2fs.h   |  21 +
 fs/f2fs/file.c   |  16 +++
 fs/f2fs/gc.c |  40 
 fs/f2fs/node.c   |   4 +-
 fs/f2fs/node.h   |   4 +-
 fs/f2fs/recovery.c   |   2 +-
 fs/f2fs/segment.c| 110 +--
 fs/f2fs/segment.h|  44 +
 fs/f2fs/super.c  |   8 ++--
 fs/f2fs/sysfs.c  |   6 +--
 12 files changed, 135 insertions(+), 136 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b85820e70f5e..a09a9609e228 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -900,7 +900,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info 
*sbi,
 
cp_blocks = le32_to_cpu(cp_block->cp_pack_total_block_count);
 
-   if (cp_blocks > sbi->blocks_per_seg || cp_blocks <= F2FS_CP_PACKS) {
+   if (cp_blocks > BLKS_PER_SEG(sbi) || cp_blocks <= F2FS_CP_PACKS) {
f2fs_warn(sbi, "invalid cp_pack_total_block_count:%u",
  le32_to_cpu(cp_block->cp_pack_total_block_count));
goto invalid_cp;
@@ -1335,7 +1335,7 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, 
struct cp_control *cpc)
 
if (cpc->reason & CP_UMOUNT) {
if (le32_to_cpu(ckpt->cp_pack_total_block_count) +
-   NM_I(sbi)->nat_bits_blocks > sbi->blocks_per_seg) {
+   NM_I(sbi)->nat_bits_blocks > BLKS_PER_SEG(sbi)) {
clear_ckpt_flags(sbi, CP_NAT_BITS_FLAG);
f2fs_notice(sbi, "Disable nat_bits due to no space");
} else if (!is_set_ckpt_flags(sbi, CP_NAT_BITS_FLAG) &&
@@ -1538,7 +1538,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct 
cp_control *cpc)
cp_ver |= ((__u64)crc32 << 32);
*(__le64 *)nm_i->nat_bits = cpu_to_le64(cp_ver);
 
-   blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks;
+   blk = start_blk + BLKS_PER_SEG(sbi) - nm_i->nat_bits_blocks;
for (i = 0; i < nm_i->nat_bits_blocks; i++)
f2fs_update_meta_page(sbi, nm_i->nat_bits +
(i << F2FS_BLKSIZE_BITS), blk + i);
@@ -1741,9 +1741,9 @@ void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi)
im->ino_num = 0;
}
 
-   sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS -
+   sbi->max_orphans = (BLKS_PER_SEG(sbi) - F2FS_CP_PACKS -
NR_CURSEG_PERSIST_TYPE - __cp_payload(sbi)) *
-   F2FS_ORPHANS_PER_BLOCK;
+   F2FS_ORPHANS_PER_BLOCK;
 }
 
 int __init f2fs_create_checkpoint_caches(void)
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index fdbf994f1271..0d02224b99b7 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -41,7 +41,7 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
total_vblocks = 0;
blks_per_sec = CAP_BLKS_PER_SEC(sbi);
hblks_per_sec = blks_per_sec / 2;
-   for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
+   for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
vblocks = get_valid_blocks(sbi, segno, true);
dist = abs(vblocks - hblks_per_sec);
bimodal += dist * dist;
@@ -135,7 +135,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
si->cur_ckpt_time = sbi->cprc_info.cur_time;
si->peak_ckpt_time = sbi->cprc_info.peak_time;
spin_unlock(>cprc_info.stat_lock);
-   si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg;
+   si->total_count = (int)sbi->user_block_count / BLKS_PER_SEG(sbi);
si->rsvd_segs = reserved_segments(sbi);
si->overp_segs = overprovision_segments(sbi);
si->valid_count = valid_user_blocks(sbi);
@@ -208,7 +208,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
if (!blks)
continue;
 
-   if (blks == sbi->blocks_per_seg)
+   if (blks == BLKS_PER_SEG(sbi))
si->full_seg[type]++;
else
si->dirty_seg[type]++;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4c52136cbc10..50e7890cc6a5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1813,6 +1813,14 @@ struct f2fs_sb_info {
 #endif
 };
 
+/* Definitions to access f2fs_sb_info */
+#define BLKS_PER_SEG(sbi)  \
+ 

Re: [f2fs-dev] [PATCH 2/3 v2] f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC

2024-02-20 Thread Jaegeuk Kim
Hi Chao,

I applied more tho, some are new and some are missing in your patch.
Please see v2.

Thanks,

On 02/20, Chao Yu wrote:
> On 2024/2/13 2:10, Jaegeuk Kim wrote:
> 
> How do you think of appending below diff which cleans up missing
> parts?
> 
> ---
>  fs/f2fs/f2fs.h|  2 +-
>  fs/f2fs/file.c|  4 ++--
>  fs/f2fs/segment.c |  4 ++--
>  fs/f2fs/segment.h | 22 +++---
>  fs/f2fs/super.c   |  2 +-
>  5 files changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index c4488e12c56e..fc9328655de8 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -3491,7 +3491,7 @@ static inline __le32 *get_dnode_addr(struct inode 
> *inode,
>   sizeof((f2fs_inode)->field))\
>   <= (F2FS_OLD_ATTRIBUTE_SIZE + (extra_isize)))   \
> 
> -#define __is_large_section(sbi)  ((sbi)->segs_per_sec > 1)
> +#define __is_large_section(sbi)  (SEGS_PER_SEC(sbi) > 1)
> 
>  #define __is_meta_io(fio) (PAGE_TYPE_OF_BIO((fio)->type) == META)
> 
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 20a26bb5b889..ef43d33278ea 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -2997,8 +2997,8 @@ static int f2fs_ioc_flush_device(struct file *filp, 
> unsigned long arg)
> 
>   if (!f2fs_is_multi_device(sbi) || sbi->s_ndevs - 1 <= range.dev_num ||
>   __is_large_section(sbi)) {
> - f2fs_warn(sbi, "Can't flush %u in %d for segs_per_sec %u != 1",
> -   range.dev_num, sbi->s_ndevs, sbi->segs_per_sec);
> + f2fs_warn(sbi, "Can't flush %u in %d for SEGS_PER_SEC %u != 1",
> +   range.dev_num, sbi->s_ndevs, SEGS_PER_SEC(sbi));
>   return -EINVAL;
>   }
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 97ac733ceffe..b59e29608ae7 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -2750,7 +2750,7 @@ static unsigned int __get_next_segno(struct 
> f2fs_sb_info *sbi, int type)
>   if (f2fs_need_rand_seg(sbi))
>   return get_random_u32_below(MAIN_SECS(sbi) * SEGS_PER_SEC(sbi));
> 
> - /* if segs_per_sec is large than 1, we need to keep original policy. */
> + /* if SEGS_PER_SEC() is large than 1, we need to keep original policy. 
> */
>   if (__is_large_section(sbi))
>   return curseg->segno;
> 
> @@ -3498,7 +3498,7 @@ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, 
> struct page *page,
>*/
>   if (segment_full) {
>   if (type == CURSEG_COLD_DATA_PINNED &&
> - !((curseg->segno + 1) % sbi->segs_per_sec))
> + !((curseg->segno + 1) % SEGS_PER_SEC(sbi)))
>   goto skip_new_segment;
> 
>   if (from_gc) {
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index cb982af765c3..63f278210654 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -48,21 +48,21 @@ static inline void sanity_check_seg_type(struct 
> f2fs_sb_info *sbi,
> 
>  #define IS_CURSEC(sbi, secno)
> \
>   (((secno) == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno /\
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_WARM_DATA)->segno /   \
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_COLD_DATA)->segno /   \
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_HOT_NODE)->segno /\
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno /   \
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno /   \
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_COLD_DATA_PINNED)->segno /\
> -   (sbi)->segs_per_sec) ||   \
> +   SEGS_PER_SEC(sbi)) || \
>((secno) == CURSEG_I(sbi, CURSEG_ALL_DATA_ATGC)->segno /   \
> -   (sbi)->segs_per_sec))
> +   SEGS_PER_SEC(sbi)))
> 
>  #define MAIN_BLKADDR(sbi)\
>   (SM_I(sbi) ? SM_I(sbi)->main_blkaddr :  \
> @@ -93,7 +93,7 @@ static inline void sanity_check_seg_typ

Re: [f2fs-dev] [PATCH] f2fs: support compress extension update via sysfs interface

2024-02-20 Thread Jaegeuk Kim
On 02/19, Chao Yu wrote:
> On 2024/2/8 8:07, Jaegeuk Kim wrote:
> > On 02/07, Chao Yu wrote:
> > > Introduce /sys/fs/f2fs//compress_extension to support
> > > adding/deleting compress extension via sysfs interface, in
> > > comparison to mount option, it's more easy to use and less
> > > authority issue for applications.
> > > 
> > > Usage:
> > > - Query: cat /sys/fs/f2fs//compress_extension
> > > - Add: echo '[c|n]extension' > /sys/fs/f2fs//compress_extension
> > > - Del: echo '[c|n]!extension' > /sys/fs/f2fs//compress_extension
> > > - [c] means add/del compress extension
> > > - [n] means add/del nocompress extension
> > > 
> > > Signed-off-by: Sheng Yong 
> > > Signed-off-by: Chao Yu 
> > > ---
> > >   Documentation/ABI/testing/sysfs-fs-f2fs | 10 
> > >   Documentation/filesystems/f2fs.rst  |  6 ++-
> > >   fs/f2fs/compress.c  | 61 +++
> > >   fs/f2fs/f2fs.h  |  4 +-
> > >   fs/f2fs/sysfs.c | 65 +++--
> > >   5 files changed, 139 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> > > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > > index 48c135e24eb5..1f2cc0913e45 100644
> > > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > > @@ -762,3 +762,13 @@ Date:November 2023
> > >   Contact:"Chao Yu" 
> > >   Description:It controls to enable/disable IO aware feature for 
> > > background discard.
> > >   By default, the value is 1 which indicates IO aware is 
> > > on.
> > > +
> > > +What:/sys/fs/f2fs//compress_extension
> > > +Date:October 2023
> > > +Contact: "Chao Yu" 
> > > +Description: Used to control configure [|no]compress_extension list:
> > > + - Query: cat /sys/fs/f2fs//compress_extension
> > > + - Add: echo '[c|n]extension' > 
> > > /sys/fs/f2fs//compress_extension
> > > + - Del: echo '[c|n]!extension' > 
> > > /sys/fs/f2fs//compress_extension
> > > + - [c] means add/del compress extension
> > > + - [n] means add/del nocompress extension
> > > diff --git a/Documentation/filesystems/f2fs.rst 
> > > b/Documentation/filesystems/f2fs.rst
> > > index 32cbfa864f38..c82a8fd7316b 100644
> > > --- a/Documentation/filesystems/f2fs.rst
> > > +++ b/Documentation/filesystems/f2fs.rst
> > > @@ -821,17 +821,19 @@ Compression implementation
> > > all logical blocks in cluster contain valid data and compress ratio of
> > > cluster data is lower than specified threshold.
> > > -- To enable compression on regular inode, there are four ways:
> > > +- To enable compression on regular inode, there are five ways:
> > > * chattr +c file
> > > * chattr +c dir; touch dir/file
> > > * mount w/ -o compress_extension=ext; touch file.ext
> > > * mount w/ -o compress_extension=*; touch any_file
> > > +  * echo '[c]ext' > /sys/fs/f2fs//compress_extension; touch 
> > > file.ext
> > > -- To disable compression on regular inode, there are two ways:
> > > +- To disable compression on regular inode, there are three ways:
> > > * chattr -c file
> > > * mount w/ -o nocompress_extension=ext; touch file.ext
> > > +  * echo '[n]ext' > /sys/fs/f2fs//compress_extension; touch 
> > > file.ext
> > >   - Priority in between FS_COMPR_FL, FS_NOCOMP_FS, extensions:
> > > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> > > index 3dc488ce882b..a5257882c772 100644
> > > --- a/fs/f2fs/compress.c
> > > +++ b/fs/f2fs/compress.c
> > > @@ -20,6 +20,67 @@
> > >   #include "segment.h"
> > >   #include 
> > > +static int is_compress_extension_exist(struct f2fs_sb_info *sbi,
> > > + unsigned char (*ext)[F2FS_EXTENSION_LEN],
> > > + int ext_cnt, unsigned char *new_ext)
> > > +{
> > > + int i;
> > > +
> > > + for (i = 0; i < ext_cnt; i++) {
> > > + if (!strcasecmp(new_ext, ext[i]))
> > > + return i;
> > > + }
> > > + return -1;
> > > +}
> > > +
> > > +int f2fs_update_compre

Re: [f2fs-dev] [PATCH 3/3 v2] f2fs: kill zone-capacity support

2024-02-20 Thread Jaegeuk Kim
On 02/20, Chao Yu wrote:
> Jaegeuk, Daeho,
> 
> Do we need Cc WD guys? Not sure whether they need this feature...

CC'ed WDC folks.

> 
> For ZUFS: 1) will it only exports 2MB-aligned zone size, and 2) its zone
> capacity equals zone size?

Yeah, I think f2fs just needs to check 2MB alignment only.

> 
> Thanks,
> 
> On 2024/2/8 7:29, Jaegeuk Kim wrote:
> > Since we don't see any user, let's kill.
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> > 
> >   from v1:
> >- keep setting the seq bit
> > 
> >   Documentation/ABI/testing/sysfs-fs-f2fs |  6 --
> >   fs/f2fs/debug.c |  7 +-
> >   fs/f2fs/f2fs.h  |  5 --
> >   fs/f2fs/file.c  |  6 +-
> >   fs/f2fs/gc.c| 33 +++--
> >   fs/f2fs/gc.h| 26 ---
> >   fs/f2fs/segment.c   | 93 +++--
> >   fs/f2fs/segment.h   | 41 ---
> >   fs/f2fs/super.c | 16 ++---
> >   fs/f2fs/sysfs.c |  6 --
> >   10 files changed, 44 insertions(+), 195 deletions(-)
> > 
> > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> > b/Documentation/ABI/testing/sysfs-fs-f2fs
> > index 48c135e24eb5..dff8c87d87dd 100644
> > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > @@ -628,12 +628,6 @@ Contact:   "Jaegeuk Kim" 
> >   Description:  Controls max # of node block writes to be used for roll 
> > forward
> > recovery. This can limit the roll forward recovery time.
> > -What:  /sys/fs/f2fs//unusable_blocks_per_sec
> > -Date:  June 2022
> > -Contact:   "Jaegeuk Kim" 
> > -Description:   Shows the number of unusable blocks in a section which 
> > was defined by
> > -   the zone capacity reported by underlying zoned device.
> > -
> >   What: /sys/fs/f2fs//current_atomic_write
> >   Date: July 2022
> >   Contact:  "Daeho Jeong" 
> > diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> > index 0d02224b99b7..6617195bd27e 100644
> > --- a/fs/f2fs/debug.c
> > +++ b/fs/f2fs/debug.c
> > @@ -32,21 +32,20 @@ static struct dentry *f2fs_debugfs_root;
> >   void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
> >   {
> > struct f2fs_stat_info *si = F2FS_STAT(sbi);
> > -   unsigned long long blks_per_sec, hblks_per_sec, total_vblocks;
> > +   unsigned long long hblks_per_sec, total_vblocks;
> > unsigned long long bimodal, dist;
> > unsigned int segno, vblocks;
> > int ndirty = 0;
> > bimodal = 0;
> > total_vblocks = 0;
> > -   blks_per_sec = CAP_BLKS_PER_SEC(sbi);
> > -   hblks_per_sec = blks_per_sec / 2;
> > +   hblks_per_sec = BLKS_PER_SEC(sbi) / 2;
> > for (segno = 0; segno < MAIN_SEGS(sbi); segno += SEGS_PER_SEC(sbi)) {
> > vblocks = get_valid_blocks(sbi, segno, true);
> > dist = abs(vblocks - hblks_per_sec);
> > bimodal += dist * dist;
> > -   if (vblocks > 0 && vblocks < blks_per_sec) {
> > +   if (vblocks > 0 && vblocks < BLKS_PER_SEC(sbi)) {
> > total_vblocks += vblocks;
> > ndirty++;
> > }
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index 9a9e858083af..34d718301392 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -1618,7 +1618,6 @@ struct f2fs_sb_info {
> > unsigned int meta_ino_num;  /* meta inode number*/
> > unsigned int log_blocks_per_seg;/* log2 blocks per segment */
> > unsigned int blocks_per_seg;/* blocks per segment */
> > -   unsigned int unusable_blocks_per_sec;   /* unusable blocks per section 
> > */
> > unsigned int segs_per_sec;  /* segments per section */
> > unsigned int secs_per_zone; /* sections per zone */
> > unsigned int total_sections;/* total section count */
> > @@ -3743,10 +3742,6 @@ void f2fs_destroy_segment_manager(struct 
> > f2fs_sb_info *sbi);
> >   int __init f2fs_create_segment_manager_caches(void);
> >   void f2fs_destroy_segment_manager_caches(void);
> >   int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
> > -unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
> > -   unsigned int segno);
> > -unsigned int f2fs_

  1   2   3   4   5   6   7   8   9   10   >