Skip to content

Commit

Permalink
Merge tag 'f2fs-for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/jaegeuk/f2fs

Pull f2fs update from Jaegeuk Kim:
 "In this round, we've mainly modified to support non-power-of-two zone
  size, which is not required for f2fs by design. In order to avoid arch
  dependency, we refactored the messy rb_entry structure shared across
  different extent_cache. In addition to the improvement, we've also
  fixed several subtle bugs and error cases.

  Enhancements:
   - support non-power-of-two zone size for zoned device
   - remove sharing the rb_entry structure in extent cache
   - refactor f2fs_gc to call checkpoint in urgent condition
   - support iopoll

  Bug fixes:
   - fix potential corruption when moving a directory
   - fix to avoid use-after-free for cached IPU bio
   - fix the folio private usage
   - avoid kernel warnings or panics in the cp_error case
   - fix to recover quota data correctly
   - fix some bugs in atomic operations
   - fix system crash due to lack of free space in LFS
   - fix null pointer panic in tracepoint in __replace_atomic_write_block
   - fix iostat lock protection
   - fix scheduling while atomic in decompression path
   - preserve direct write semantics when buffering is forced
   - fix to call f2fs_wait_on_page_writeback() in f2fs_write_raw_pages()"

* tag 'f2fs-for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (52 commits)
  f2fs: remove unnessary comment in __may_age_extent_tree
  f2fs: allocate node blocks for atomic write block replacement
  f2fs: use cow inode data when updating atomic write
  f2fs: remove power-of-two limitation of zoned device
  f2fs: allocate trace path buffer from names_cache
  f2fs: add has_enough_free_secs()
  f2fs: relax sanity check if checkpoint is corrupted
  f2fs: refactor f2fs_gc to call checkpoint in urgent condition
  f2fs: remove folio_detach_private() in .invalidate_folio and .release_folio
  f2fs: remove bulk remove_proc_entry() and unnecessary kobject_del()
  f2fs: support iopoll method
  f2fs: remove batched_trim_sections node description
  f2fs: fix to check return value of inc_valid_block_count()
  f2fs: fix to check return value of f2fs_do_truncate_blocks()
  f2fs: fix passing relative address when discard zones
  f2fs: fix potential corruption when moving a directory
  f2fs: add radix_tree_preload_end in error case
  f2fs: fix to recover quota data correctly
  f2fs: fix to check readonly condition correctly
  docs: f2fs: Correct instruction to disable checkpoint
  ...
  • Loading branch information
torvalds committed Apr 26, 2023
2 parents fbfaf03 + 8375be2 commit 5c7ecad
Show file tree
Hide file tree
Showing 22 changed files with 899 additions and 897 deletions.
23 changes: 17 additions & 6 deletions Documentation/ABI/testing/sysfs-fs-f2fs
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,6 @@ Description: Controls the memory footprint used by free nids and cached
nat entries. By default, 1 is set, which indicates
10 MB / 1 GB RAM.

What: /sys/fs/f2fs/<disk>/batched_trim_sections
Date: February 2015
Contact: "Jaegeuk Kim" <[email protected]>
Description: Controls the trimming rate in batch mode.
<deprecated>

What: /sys/fs/f2fs/<disk>/cp_interval
Date: October 2015
Contact: "Jaegeuk Kim" <[email protected]>
Expand Down Expand Up @@ -729,3 +723,20 @@ What: /sys/fs/f2fs/<disk>/last_age_weight
Date: January 2023
Contact: "Ping Xiong" <[email protected]>
Description: When DATA SEPARATION is on, it controls the weight of last data block age.

What: /sys/fs/f2fs/<disk>/compress_watermark
Date: February 2023
Contact: "Yangtao Li" <[email protected]>
Description: When compress cache is on, it controls free memory watermark
in order to limit caching compress page. If free memory is lower
than watermark, then deny caching compress page. The value should be in
range of (0, 100], by default it was initialized as 20(%).

What: /sys/fs/f2fs/<disk>/compress_percent
Date: February 2023
Contact: "Yangtao Li" <[email protected]>
Description: When compress cache is on, it controls cached page
percent(compress pages / free_ram) in order to limit caching compress page.
If cached page percent exceed threshold, then deny caching compress page.
The value should be in range of (0, 100], by default it was initialized
as 20(%).
2 changes: 1 addition & 1 deletion Documentation/filesystems/f2fs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "enabl
disabled, any unmounting or unexpected shutdowns will cause
the filesystem contents to appear as they did when the
filesystem was mounted with that option.
While mounting with checkpoint=disabled, the filesystem must
While mounting with checkpoint=disable, the filesystem must
run garbage collection to ensure that all available space can
be used. If this takes too much time, the mount may return
EAGAIN. You may optionally add a value to indicate how much
Expand Down
52 changes: 25 additions & 27 deletions fs/f2fs/checkpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
se = get_seg_entry(sbi, segno);

exist = f2fs_test_bit(offset, se->cur_valid_map);

/* skip data, if we already have an error in checkpoint. */
if (unlikely(f2fs_cp_error(sbi)))
return exist;

if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
blkaddr, exist);
Expand Down Expand Up @@ -202,6 +207,11 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
case DATA_GENERIC_ENHANCE_UPDATE:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi))) {

/* Skip to emit an error message. */
if (unlikely(f2fs_cp_error(sbi)))
return false;

f2fs_warn(sbi, "access invalid blkaddr:%u",
blkaddr);
set_sbi_flag(sbi, SBI_NEED_FSCK);
Expand Down Expand Up @@ -325,8 +335,15 @@ static int __f2fs_write_meta_page(struct page *page,

trace_f2fs_writepage(page, META);

if (unlikely(f2fs_cp_error(sbi)))
if (unlikely(f2fs_cp_error(sbi))) {
if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) {
ClearPageUptodate(page);
dec_page_count(sbi, F2FS_DIRTY_META);
unlock_page(page);
return 0;
}
goto redirty_out;
}
if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
goto redirty_out;
if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
Expand Down Expand Up @@ -508,6 +525,7 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
if (!e) {
if (!new) {
spin_unlock(&im->ino_lock);
radix_tree_preload_end();
goto retry;
}
e = new;
Expand Down Expand Up @@ -706,32 +724,18 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
{
block_t start_blk, orphan_blocks, i, j;
unsigned int s_flags = sbi->sb->s_flags;
int err = 0;
#ifdef CONFIG_QUOTA
int quota_enabled;
#endif

if (!is_set_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG))
return 0;

if (bdev_read_only(sbi->sb->s_bdev)) {
if (f2fs_hw_is_readonly(sbi)) {
f2fs_info(sbi, "write access unavailable, skipping orphan cleanup");
return 0;
}

if (s_flags & SB_RDONLY) {
if (is_sbi_flag_set(sbi, SBI_IS_WRITABLE))
f2fs_info(sbi, "orphan cleanup on readonly fs");
sbi->sb->s_flags &= ~SB_RDONLY;
}

#ifdef CONFIG_QUOTA
/*
* Turn on quotas which were not enabled for read-only mounts if
* filesystem has quota feature, so that they are updated correctly.
*/
quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
#endif

start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi);
orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi);
Expand Down Expand Up @@ -765,13 +769,6 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
out:
set_sbi_flag(sbi, SBI_IS_RECOVERED);

#ifdef CONFIG_QUOTA
/* Turn quotas off */
if (quota_enabled)
f2fs_quota_off_umount(sbi->sb);
#endif
sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */

return err;
}

Expand Down Expand Up @@ -982,7 +979,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)

cp_blk_no = le32_to_cpu(fsb->cp_blkaddr);
if (cur_page == cp2)
cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg);
cp_blk_no += BIT(le32_to_cpu(fsb->log_blocks_per_seg));

for (i = 1; i < cp_blks; i++) {
void *sit_bitmap_ptr;
Expand Down Expand Up @@ -1133,7 +1130,7 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
goto retry;
}

int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi)
static int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi)
{
struct list_head *head = &sbi->inode_list[DIRTY_META];
struct inode *inode;
Expand Down Expand Up @@ -1306,7 +1303,8 @@ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type)
if (!get_pages(sbi, type))
break;

if (unlikely(f2fs_cp_error(sbi)))
if (unlikely(f2fs_cp_error(sbi) &&
!is_sbi_flag_set(sbi, SBI_IS_CLOSE)))
break;

if (type == F2FS_DIRTY_META)
Expand Down
47 changes: 22 additions & 25 deletions fs/f2fs/compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,35 +264,21 @@ static void lz4_destroy_compress_ctx(struct compress_ctx *cc)
cc->private = NULL;
}

#ifdef CONFIG_F2FS_FS_LZ4HC
static int lz4hc_compress_pages(struct compress_ctx *cc)
static int lz4_compress_pages(struct compress_ctx *cc)
{
int len = -EINVAL;
unsigned char level = F2FS_I(cc->inode)->i_compress_level;
int len;

if (level)
len = LZ4_compress_HC(cc->rbuf, cc->cbuf->cdata, cc->rlen,
cc->clen, level, cc->private);
else
if (!level)
len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen,
cc->clen, cc->private);
if (!len)
return -EAGAIN;

cc->clen = len;
return 0;
}
#endif

static int lz4_compress_pages(struct compress_ctx *cc)
{
int len;

#ifdef CONFIG_F2FS_FS_LZ4HC
return lz4hc_compress_pages(cc);
else
len = LZ4_compress_HC(cc->rbuf, cc->cbuf->cdata, cc->rlen,
cc->clen, level, cc->private);
#endif
len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen,
cc->clen, cc->private);
if (len < 0)
return len;
if (!len)
return -EAGAIN;

Expand Down Expand Up @@ -670,7 +656,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)

cc->cbuf->clen = cpu_to_le32(cc->clen);

if (fi->i_compress_flag & 1 << COMPRESS_CHKSUM)
if (fi->i_compress_flag & BIT(COMPRESS_CHKSUM))
chksum = f2fs_crc32(F2FS_I_SB(cc->inode),
cc->cbuf->cdata, cc->clen);
cc->cbuf->chksum = cpu_to_le32(chksum);
Expand Down Expand Up @@ -755,13 +741,18 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)

if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) {
ret = -EFSCORRUPTED;
f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION);

/* Avoid f2fs_commit_super in irq context */
if (in_task)
f2fs_save_errors(sbi, ERROR_FAIL_DECOMPRESSION);
else
f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION);
goto out_release;
}

ret = cops->decompress_pages(dic);

if (!ret && (fi->i_compress_flag & 1 << COMPRESS_CHKSUM)) {
if (!ret && (fi->i_compress_flag & BIT(COMPRESS_CHKSUM))) {
u32 provided = le32_to_cpu(dic->cbuf->chksum);
u32 calculated = f2fs_crc32(sbi, dic->cbuf->cdata, dic->clen);

Expand Down Expand Up @@ -1456,6 +1447,12 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
if (!PageDirty(cc->rpages[i]))
goto continue_unlock;

if (PageWriteback(cc->rpages[i])) {
if (wbc->sync_mode == WB_SYNC_NONE)
goto continue_unlock;
f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, true);
}

if (!clear_page_dirty_for_io(cc->rpages[i]))
goto continue_unlock;

Expand Down
Loading

0 comments on commit 5c7ecad

Please sign in to comment.