Skip to content

Commit 5d170fe

Browse files
committed
Merge tag 'f2fs-for-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/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. ...
2 parents 0083340 + b4dac12 commit 5d170fe

File tree

25 files changed

+556
-209
lines changed

25 files changed

+556
-209
lines changed

Documentation/ABI/testing/sysfs-fs-f2fs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,30 @@ Description: Show status of f2fs superblock in real time.
466466
0x4000 SBI_IS_FREEZING freefs is in process
467467
====== ===================== =================================
468468

469+
What: /sys/fs/f2fs/<disk>/stat/cp_status
470+
Date: September 2022
471+
Contact: "Chao Yu" <chao.yu@oppo.com>
472+
Description: Show status of f2fs checkpoint in real time.
473+
474+
=============================== ==============================
475+
cp flag value
476+
CP_UMOUNT_FLAG 0x00000001
477+
CP_ORPHAN_PRESENT_FLAG 0x00000002
478+
CP_COMPACT_SUM_FLAG 0x00000004
479+
CP_ERROR_FLAG 0x00000008
480+
CP_FSCK_FLAG 0x00000010
481+
CP_FASTBOOT_FLAG 0x00000020
482+
CP_CRC_RECOVERY_FLAG 0x00000040
483+
CP_NAT_BITS_FLAG 0x00000080
484+
CP_TRIMMED_FLAG 0x00000100
485+
CP_NOCRC_RECOVERY_FLAG 0x00000200
486+
CP_LARGE_NAT_BITMAP_FLAG 0x00000400
487+
CP_QUOTA_NEED_FSCK_FLAG 0x00000800
488+
CP_DISABLED_FLAG 0x00001000
489+
CP_DISABLED_QUICK_FLAG 0x00002000
490+
CP_RESIZEFS_FLAG 0x00004000
491+
=============================== ==============================
492+
469493
What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
470494
Date: January 2021
471495
Contact: "Daeho Jeong" <daehojeong@google.com>

fs/f2fs/acl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ static int f2fs_acl_update_mode(struct user_namespace *mnt_userns,
219219
return error;
220220
if (error == 0)
221221
*acl = NULL;
222-
if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) &&
222+
if (!vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode)) &&
223223
!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
224224
mode &= ~S_ISGID;
225225
*mode_p = mode;

fs/f2fs/checkpoint.c

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@
2626
static struct kmem_cache *ino_entry_slab;
2727
struct kmem_cache *f2fs_inode_entry_slab;
2828

29-
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
29+
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
30+
unsigned char reason)
3031
{
3132
f2fs_build_fault_attr(sbi, 0, 0);
3233
set_ckpt_flags(sbi, CP_ERROR_FLAG);
33-
if (!end_io)
34+
if (!end_io) {
3435
f2fs_flush_merged_writes(sbi);
36+
37+
f2fs_handle_stop(sbi, reason);
38+
}
3539
}
3640

3741
/*
@@ -89,7 +93,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
8993
return ERR_PTR(err);
9094
}
9195

92-
f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
96+
f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, F2FS_BLKSIZE);
9397

9498
lock_page(page);
9599
if (unlikely(page->mapping != mapping)) {
@@ -122,7 +126,7 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index)
122126
if (PTR_ERR(page) == -EIO &&
123127
++count <= DEFAULT_RETRY_IO_COUNT)
124128
goto retry;
125-
f2fs_stop_checkpoint(sbi, false);
129+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
126130
}
127131
return page;
128132
}
@@ -140,14 +144,21 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
140144
unsigned int segno, offset;
141145
bool exist;
142146

143-
if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ)
147+
if (type == DATA_GENERIC)
144148
return true;
145149

146150
segno = GET_SEGNO(sbi, blkaddr);
147151
offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
148152
se = get_seg_entry(sbi, segno);
149153

150154
exist = f2fs_test_bit(offset, se->cur_valid_map);
155+
if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
156+
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
157+
blkaddr, exist);
158+
set_sbi_flag(sbi, SBI_NEED_FSCK);
159+
return exist;
160+
}
161+
151162
if (!exist && type == DATA_GENERIC_ENHANCE) {
152163
f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
153164
blkaddr, exist);
@@ -185,6 +196,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
185196
case DATA_GENERIC:
186197
case DATA_GENERIC_ENHANCE:
187198
case DATA_GENERIC_ENHANCE_READ:
199+
case DATA_GENERIC_ENHANCE_UPDATE:
188200
if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
189201
blkaddr < MAIN_BLKADDR(sbi))) {
190202
f2fs_warn(sbi, "access invalid blkaddr:%u",
@@ -276,7 +288,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
276288
f2fs_put_page(page, err ? 1 : 0);
277289

278290
if (!err)
279-
f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE);
291+
f2fs_update_iostat(sbi, NULL, FS_META_READ_IO,
292+
F2FS_BLKSIZE);
280293
}
281294
out:
282295
blk_finish_plug(&plug);
@@ -448,8 +461,7 @@ static bool f2fs_dirty_meta_folio(struct address_space *mapping,
448461

449462
if (!folio_test_uptodate(folio))
450463
folio_mark_uptodate(folio);
451-
if (!folio_test_dirty(folio)) {
452-
filemap_dirty_folio(mapping, folio);
464+
if (filemap_dirty_folio(mapping, folio)) {
453465
inc_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_META);
454466
set_page_private_reference(&folio->page);
455467
return true;
@@ -1053,7 +1065,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)
10531065
spin_unlock(&sbi->inode_lock[type]);
10541066
}
10551067

1056-
int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
1068+
int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
1069+
bool from_cp)
10571070
{
10581071
struct list_head *head;
10591072
struct inode *inode;
@@ -1088,11 +1101,15 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
10881101
if (inode) {
10891102
unsigned long cur_ino = inode->i_ino;
10901103

1091-
F2FS_I(inode)->cp_task = current;
1104+
if (from_cp)
1105+
F2FS_I(inode)->cp_task = current;
1106+
F2FS_I(inode)->wb_task = current;
10921107

10931108
filemap_fdatawrite(inode->i_mapping);
10941109

1095-
F2FS_I(inode)->cp_task = NULL;
1110+
F2FS_I(inode)->wb_task = NULL;
1111+
if (from_cp)
1112+
F2FS_I(inode)->cp_task = NULL;
10961113

10971114
iput(inode);
10981115
/* We need to give cpu to another writers. */
@@ -1221,7 +1238,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
12211238
/* write all the dirty dentry pages */
12221239
if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
12231240
f2fs_unlock_all(sbi);
1224-
err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
1241+
err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true);
12251242
if (err)
12261243
return err;
12271244
cond_resched();
@@ -1892,15 +1909,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
18921909
void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi)
18931910
{
18941911
struct ckpt_req_control *cprc = &sbi->cprc_info;
1912+
struct task_struct *ckpt_task;
1913+
1914+
if (!cprc->f2fs_issue_ckpt)
1915+
return;
18951916

1896-
if (cprc->f2fs_issue_ckpt) {
1897-
struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt;
1917+
ckpt_task = cprc->f2fs_issue_ckpt;
1918+
cprc->f2fs_issue_ckpt = NULL;
1919+
kthread_stop(ckpt_task);
18981920

1899-
cprc->f2fs_issue_ckpt = NULL;
1900-
kthread_stop(ckpt_task);
1921+
f2fs_flush_ckpt_thread(sbi);
1922+
}
19011923

1902-
flush_remained_ckpt_reqs(sbi, NULL);
1903-
}
1924+
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi)
1925+
{
1926+
struct ckpt_req_control *cprc = &sbi->cprc_info;
1927+
1928+
flush_remained_ckpt_reqs(sbi, NULL);
1929+
1930+
/* Let's wait for the previous dispatched checkpoint. */
1931+
while (atomic_read(&cprc->queued_ckpt))
1932+
io_schedule_timeout(DEFAULT_IO_TIMEOUT);
19041933
}
19051934

19061935
void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)

fs/f2fs/compress.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
762762

763763
if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) {
764764
ret = -EFSCORRUPTED;
765+
f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION);
765766
goto out_release;
766767
}
767768

@@ -912,17 +913,15 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
912913
reason = "[C|*|C|*]";
913914
goto out;
914915
}
915-
if (compressed) {
916-
if (!__is_valid_data_blkaddr(blkaddr)) {
917-
if (!cluster_end)
918-
cluster_end = i;
919-
continue;
920-
}
921-
/* [COMPR_ADDR, NULL_ADDR or NEW_ADDR, valid_blkaddr] */
922-
if (cluster_end) {
923-
reason = "[C|N|N|V]";
924-
goto out;
925-
}
916+
if (!__is_valid_data_blkaddr(blkaddr)) {
917+
if (!cluster_end)
918+
cluster_end = i;
919+
continue;
920+
}
921+
/* [COMPR_ADDR, NULL_ADDR or NEW_ADDR, valid_blkaddr] */
922+
if (cluster_end) {
923+
reason = "[C|N|N|V]";
924+
goto out;
926925
}
927926
}
928927
return false;
@@ -952,6 +951,7 @@ static int __f2fs_cluster_blocks(struct inode *inode,
952951

953952
if (f2fs_sanity_check_cluster(&dn)) {
954953
ret = -EFSCORRUPTED;
954+
f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER);
955955
goto fail;
956956
}
957957

@@ -1568,12 +1568,8 @@ static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
15681568
if (!dic->cbuf)
15691569
return -ENOMEM;
15701570

1571-
if (cops->init_decompress_ctx) {
1572-
int ret = cops->init_decompress_ctx(dic);
1573-
1574-
if (ret)
1575-
return ret;
1576-
}
1571+
if (cops->init_decompress_ctx)
1572+
return cops->init_decompress_ctx(dic);
15771573

15781574
return 0;
15791575
}
@@ -1905,7 +1901,7 @@ bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
19051901

19061902
void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino)
19071903
{
1908-
struct address_space *mapping = sbi->compress_inode->i_mapping;
1904+
struct address_space *mapping = COMPRESS_MAPPING(sbi);
19091905
struct folio_batch fbatch;
19101906
pgoff_t index = 0;
19111907
pgoff_t end = MAX_BLKADDR(sbi);

0 commit comments

Comments
 (0)