Skip to content

Commit

Permalink
Merge tag 'f2fs-for-6.1-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 updates from Jaegeuk Kim:
 "This round looks fairly small comparing to the previous updates and
  includes mostly minor bug fixes. Nevertheless, as we've still
  interested in improving the stability, Chao added some debugging
  methods to diagnoze subtle runtime inconsistency problem.

  Enhancements:
   - store all the corruption or failure reasons in superblock
   - detect meta inode, summary info, and block address inconsistency
   - increase the limit for reserve_root for low-end devices
   - add the number of compressed IO in iostat

  Bug fixes:
   - DIO write fix for zoned devices
   - do out-of-place writes for cold files
   - fix some stat updates (FS_CP_DATA_IO, dirty page count)
   - fix race condition on setting FI_NO_EXTENT flag
   - fix data races when freezing super
   - fix wrong continue condition check in GC
   - do not allow ATGC for LFS mode

  In addition, there're some code enhancement and clean-ups as usual"

* tag 'f2fs-for-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (32 commits)
  f2fs: change to use atomic_t type form sbi.atomic_files
  f2fs: account swapfile inodes
  f2fs: allow direct read for zoned device
  f2fs: support recording errors into superblock
  f2fs: support recording stop_checkpoint reason into super_block
  f2fs: remove the unnecessary check in f2fs_xattr_fiemap
  f2fs: introduce cp_status sysfs entry
  f2fs: fix to detect corrupted meta ino
  f2fs: fix to account FS_CP_DATA_IO correctly
  f2fs: code clean and fix a type error
  f2fs: add "c_len" into trace_f2fs_update_extent_tree_range for compressed file
  f2fs: fix to do sanity check on summary info
  f2fs: port to vfs{g,u}id_t and associated helpers
  f2fs: fix to do sanity check on destination blkaddr during recovery
  f2fs: let FI_OPU_WRITE override FADVISE_COLD_BIT
  f2fs: fix race condition on setting FI_NO_EXTENT flag
  f2fs: remove redundant check in f2fs_sanity_check_cluster
  f2fs: add static init_idisk_time function to reduce the code
  f2fs: fix typo
  f2fs: fix wrong dirty page count when race between mmap and fallocate.
  ...
  • Loading branch information
Linus Torvalds committed Oct 11, 2022
2 parents 0083340 + b4dac12 commit 5d170fe
Show file tree
Hide file tree
Showing 25 changed files with 556 additions and 209 deletions.
24 changes: 24 additions & 0 deletions Documentation/ABI/testing/sysfs-fs-f2fs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,30 @@ Description: Show status of f2fs superblock in real time.
0x4000 SBI_IS_FREEZING freefs is in process
====== ===================== =================================

What: /sys/fs/f2fs/<disk>/stat/cp_status
Date: September 2022
Contact: "Chao Yu" <chao.yu@oppo.com>
Description: Show status of f2fs checkpoint in real time.

=============================== ==============================
cp flag value
CP_UMOUNT_FLAG 0x00000001
CP_ORPHAN_PRESENT_FLAG 0x00000002
CP_COMPACT_SUM_FLAG 0x00000004
CP_ERROR_FLAG 0x00000008
CP_FSCK_FLAG 0x00000010
CP_FASTBOOT_FLAG 0x00000020
CP_CRC_RECOVERY_FLAG 0x00000040
CP_NAT_BITS_FLAG 0x00000080
CP_TRIMMED_FLAG 0x00000100
CP_NOCRC_RECOVERY_FLAG 0x00000200
CP_LARGE_NAT_BITMAP_FLAG 0x00000400
CP_QUOTA_NEED_FSCK_FLAG 0x00000800
CP_DISABLED_FLAG 0x00001000
CP_DISABLED_QUICK_FLAG 0x00002000
CP_RESIZEFS_FLAG 0x00004000
=============================== ==============================

What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
Date: January 2021
Contact: "Daeho Jeong" <daehojeong@google.com>
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ static int f2fs_acl_update_mode(struct user_namespace *mnt_userns,
return error;
if (error == 0)
*acl = NULL;
if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) &&
if (!vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode)) &&
!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
mode &= ~S_ISGID;
*mode_p = mode;
Expand Down
65 changes: 47 additions & 18 deletions fs/f2fs/checkpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@
static struct kmem_cache *ino_entry_slab;
struct kmem_cache *f2fs_inode_entry_slab;

void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
unsigned char reason)
{
f2fs_build_fault_attr(sbi, 0, 0);
set_ckpt_flags(sbi, CP_ERROR_FLAG);
if (!end_io)
if (!end_io) {
f2fs_flush_merged_writes(sbi);

f2fs_handle_stop(sbi, reason);
}
}

/*
Expand Down Expand Up @@ -89,7 +93,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
return ERR_PTR(err);
}

f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, F2FS_BLKSIZE);

lock_page(page);
if (unlikely(page->mapping != mapping)) {
Expand Down Expand Up @@ -122,7 +126,7 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index)
if (PTR_ERR(page) == -EIO &&
++count <= DEFAULT_RETRY_IO_COUNT)
goto retry;
f2fs_stop_checkpoint(sbi, false);
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
}
return page;
}
Expand All @@ -140,14 +144,21 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
unsigned int segno, offset;
bool exist;

if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ)
if (type == DATA_GENERIC)
return true;

segno = GET_SEGNO(sbi, blkaddr);
offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
se = get_seg_entry(sbi, segno);

exist = f2fs_test_bit(offset, se->cur_valid_map);
if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
blkaddr, exist);
set_sbi_flag(sbi, SBI_NEED_FSCK);
return exist;
}

if (!exist && type == DATA_GENERIC_ENHANCE) {
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
blkaddr, exist);
Expand Down Expand Up @@ -185,6 +196,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
case DATA_GENERIC:
case DATA_GENERIC_ENHANCE:
case DATA_GENERIC_ENHANCE_READ:
case DATA_GENERIC_ENHANCE_UPDATE:
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
blkaddr < MAIN_BLKADDR(sbi))) {
f2fs_warn(sbi, "access invalid blkaddr:%u",
Expand Down Expand Up @@ -276,7 +288,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
f2fs_put_page(page, err ? 1 : 0);

if (!err)
f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
f2fs_update_iostat(sbi, NULL, FS_META_READ_IO,
F2FS_BLKSIZE);
}
out:
blk_finish_plug(&plug);
Expand Down Expand Up @@ -448,8 +461,7 @@ static bool f2fs_dirty_meta_folio(struct address_space *mapping,

if (!folio_test_uptodate(folio))
folio_mark_uptodate(folio);
if (!folio_test_dirty(folio)) {
filemap_dirty_folio(mapping, folio);
if (filemap_dirty_folio(mapping, folio)) {
inc_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_META);
set_page_private_reference(&folio->page);
return true;
Expand Down Expand Up @@ -1053,7 +1065,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)
spin_unlock(&sbi->inode_lock[type]);
}

int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
bool from_cp)
{
struct list_head *head;
struct inode *inode;
Expand Down Expand Up @@ -1088,11 +1101,15 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
if (inode) {
unsigned long cur_ino = inode->i_ino;

F2FS_I(inode)->cp_task = current;
if (from_cp)
F2FS_I(inode)->cp_task = current;
F2FS_I(inode)->wb_task = current;

filemap_fdatawrite(inode->i_mapping);

F2FS_I(inode)->cp_task = NULL;
F2FS_I(inode)->wb_task = NULL;
if (from_cp)
F2FS_I(inode)->cp_task = NULL;

iput(inode);
/* We need to give cpu to another writers. */
Expand Down Expand Up @@ -1221,7 +1238,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
/* write all the dirty dentry pages */
if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
f2fs_unlock_all(sbi);
err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true);
if (err)
return err;
cond_resched();
Expand Down Expand Up @@ -1892,15 +1909,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi)
{
struct ckpt_req_control *cprc = &sbi->cprc_info;
struct task_struct *ckpt_task;

if (!cprc->f2fs_issue_ckpt)
return;

if (cprc->f2fs_issue_ckpt) {
struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt;
ckpt_task = cprc->f2fs_issue_ckpt;
cprc->f2fs_issue_ckpt = NULL;
kthread_stop(ckpt_task);

cprc->f2fs_issue_ckpt = NULL;
kthread_stop(ckpt_task);
f2fs_flush_ckpt_thread(sbi);
}

flush_remained_ckpt_reqs(sbi, NULL);
}
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi)
{
struct ckpt_req_control *cprc = &sbi->cprc_info;

flush_remained_ckpt_reqs(sbi, NULL);

/* Let's wait for the previous dispatched checkpoint. */
while (atomic_read(&cprc->queued_ckpt))
io_schedule_timeout(DEFAULT_IO_TIMEOUT);
}

void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)
Expand Down
32 changes: 14 additions & 18 deletions fs/f2fs/compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@ 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);
goto out_release;
}

Expand Down Expand Up @@ -912,17 +913,15 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
reason = "[C|*|C|*]";
goto out;
}
if (compressed) {
if (!__is_valid_data_blkaddr(blkaddr)) {
if (!cluster_end)
cluster_end = i;
continue;
}
/* [COMPR_ADDR, NULL_ADDR or NEW_ADDR, valid_blkaddr] */
if (cluster_end) {
reason = "[C|N|N|V]";
goto out;
}
if (!__is_valid_data_blkaddr(blkaddr)) {
if (!cluster_end)
cluster_end = i;
continue;
}
/* [COMPR_ADDR, NULL_ADDR or NEW_ADDR, valid_blkaddr] */
if (cluster_end) {
reason = "[C|N|N|V]";
goto out;
}
}
return false;
Expand Down Expand Up @@ -952,6 +951,7 @@ static int __f2fs_cluster_blocks(struct inode *inode,

if (f2fs_sanity_check_cluster(&dn)) {
ret = -EFSCORRUPTED;
f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER);
goto fail;
}

Expand Down Expand Up @@ -1568,12 +1568,8 @@ static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
if (!dic->cbuf)
return -ENOMEM;

if (cops->init_decompress_ctx) {
int ret = cops->init_decompress_ctx(dic);

if (ret)
return ret;
}
if (cops->init_decompress_ctx)
return cops->init_decompress_ctx(dic);

return 0;
}
Expand Down Expand Up @@ -1905,7 +1901,7 @@ bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page,

void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino)
{
struct address_space *mapping = sbi->compress_inode->i_mapping;
struct address_space *mapping = COMPRESS_MAPPING(sbi);
struct folio_batch fbatch;
pgoff_t index = 0;
pgoff_t end = MAX_BLKADDR(sbi);
Expand Down
Loading

0 comments on commit 5d170fe

Please sign in to comment.