Skip to content

Commit d615b54

Browse files
committed
Merge tag 'f2fs-fix-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs fixes from Jaegeuk Kim: "This includes major bug fixes introduced in 5.18-rc1 and 5.17+: - Remove obsolete whint_mode (5.18-rc1) - Fix IO split issue caused by op_flags change in f2fs (5.18-rc1) - Fix a wrong condition check to detect IO failure loop (5.18-rc1) - Fix wrong data truncation during roll-forward (5.17+)" * tag 'f2fs-fix-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: f2fs: should not truncate blocks during roll-forward recovery f2fs: fix wrong condition check when failing metapage read f2fs: keep io_flags to avoid IO split due to different op_flags in two fio holders f2fs: remove obsolete whint_mode
2 parents 0fc74d8 + 4d8ec91 commit d615b54

File tree

7 files changed

+27
-221
lines changed

7 files changed

+27
-221
lines changed

Documentation/filesystems/f2fs.rst

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,6 @@ offgrpjquota Turn off group journalled quota.
235235
offprjjquota Turn off project journalled quota.
236236
quota Enable plain user disk quota accounting.
237237
noquota Disable all plain disk quota option.
238-
whint_mode=%s Control which write hints are passed down to block
239-
layer. This supports "off", "user-based", and
240-
"fs-based". In "off" mode (default), f2fs does not pass
241-
down hints. In "user-based" mode, f2fs tries to pass
242-
down hints given by users. And in "fs-based" mode, f2fs
243-
passes down hints with its policy.
244238
alloc_mode=%s Adjust block allocation policy, which supports "reuse"
245239
and "default".
246240
fsync_mode=%s Control the policy of fsync. Currently supports "posix",
@@ -751,70 +745,6 @@ In order to identify whether the data in the victim segment are valid or not,
751745
F2FS manages a bitmap. Each bit represents the validity of a block, and the
752746
bitmap is composed of a bit stream covering whole blocks in main area.
753747

754-
Write-hint Policy
755-
-----------------
756-
757-
1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
758-
759-
2) whint_mode=user-based. F2FS tries to pass down hints given by
760-
users.
761-
762-
===================== ======================== ===================
763-
User F2FS Block
764-
===================== ======================== ===================
765-
N/A META WRITE_LIFE_NOT_SET
766-
N/A HOT_NODE "
767-
N/A WARM_NODE "
768-
N/A COLD_NODE "
769-
ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
770-
extension list " "
771-
772-
-- buffered io
773-
WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
774-
WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
775-
WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
776-
WRITE_LIFE_NONE " "
777-
WRITE_LIFE_MEDIUM " "
778-
WRITE_LIFE_LONG " "
779-
780-
-- direct io
781-
WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
782-
WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
783-
WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
784-
WRITE_LIFE_NONE " WRITE_LIFE_NONE
785-
WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
786-
WRITE_LIFE_LONG " WRITE_LIFE_LONG
787-
===================== ======================== ===================
788-
789-
3) whint_mode=fs-based. F2FS passes down hints with its policy.
790-
791-
===================== ======================== ===================
792-
User F2FS Block
793-
===================== ======================== ===================
794-
N/A META WRITE_LIFE_MEDIUM;
795-
N/A HOT_NODE WRITE_LIFE_NOT_SET
796-
N/A WARM_NODE "
797-
N/A COLD_NODE WRITE_LIFE_NONE
798-
ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
799-
extension list " "
800-
801-
-- buffered io
802-
WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
803-
WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
804-
WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_LONG
805-
WRITE_LIFE_NONE " "
806-
WRITE_LIFE_MEDIUM " "
807-
WRITE_LIFE_LONG " "
808-
809-
-- direct io
810-
WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
811-
WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
812-
WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
813-
WRITE_LIFE_NONE " WRITE_LIFE_NONE
814-
WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
815-
WRITE_LIFE_LONG " WRITE_LIFE_LONG
816-
===================== ======================== ===================
817-
818748
Fallocate(2) Policy
819749
-------------------
820750

fs/f2fs/checkpoint.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
9898
}
9999

100100
if (unlikely(!PageUptodate(page))) {
101-
if (page->index == sbi->metapage_eio_ofs &&
102-
sbi->metapage_eio_cnt++ == MAX_RETRY_META_PAGE_EIO) {
103-
set_ckpt_flags(sbi, CP_ERROR_FLAG);
101+
if (page->index == sbi->metapage_eio_ofs) {
102+
if (sbi->metapage_eio_cnt++ == MAX_RETRY_META_PAGE_EIO)
103+
set_ckpt_flags(sbi, CP_ERROR_FLAG);
104104
} else {
105105
sbi->metapage_eio_ofs = page->index;
106106
sbi->metapage_eio_cnt = 0;

fs/f2fs/data.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -388,11 +388,23 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr)
388388
return 0;
389389
}
390390

391-
static void __attach_io_flag(struct f2fs_io_info *fio, unsigned int io_flag)
391+
static unsigned int f2fs_io_flags(struct f2fs_io_info *fio)
392392
{
393393
unsigned int temp_mask = (1 << NR_TEMP_TYPE) - 1;
394-
unsigned int fua_flag = io_flag & temp_mask;
395-
unsigned int meta_flag = (io_flag >> NR_TEMP_TYPE) & temp_mask;
394+
unsigned int fua_flag, meta_flag, io_flag;
395+
unsigned int op_flags = 0;
396+
397+
if (fio->op != REQ_OP_WRITE)
398+
return 0;
399+
if (fio->type == DATA)
400+
io_flag = fio->sbi->data_io_flag;
401+
else if (fio->type == NODE)
402+
io_flag = fio->sbi->node_io_flag;
403+
else
404+
return 0;
405+
406+
fua_flag = io_flag & temp_mask;
407+
meta_flag = (io_flag >> NR_TEMP_TYPE) & temp_mask;
396408

397409
/*
398410
* data/node io flag bits per temp:
@@ -401,9 +413,10 @@ static void __attach_io_flag(struct f2fs_io_info *fio, unsigned int io_flag)
401413
* Cold | Warm | Hot | Cold | Warm | Hot |
402414
*/
403415
if ((1 << fio->temp) & meta_flag)
404-
fio->op_flags |= REQ_META;
416+
op_flags |= REQ_META;
405417
if ((1 << fio->temp) & fua_flag)
406-
fio->op_flags |= REQ_FUA;
418+
op_flags |= REQ_FUA;
419+
return op_flags;
407420
}
408421

409422
static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
@@ -413,14 +426,10 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
413426
sector_t sector;
414427
struct bio *bio;
415428

416-
if (fio->type == DATA)
417-
__attach_io_flag(fio, sbi->data_io_flag);
418-
else if (fio->type == NODE)
419-
__attach_io_flag(fio, sbi->node_io_flag);
420-
421429
bdev = f2fs_target_device(sbi, fio->new_blkaddr, &sector);
422-
bio = bio_alloc_bioset(bdev, npages, fio->op | fio->op_flags, GFP_NOIO,
423-
&f2fs_bioset);
430+
bio = bio_alloc_bioset(bdev, npages,
431+
fio->op | fio->op_flags | f2fs_io_flags(fio),
432+
GFP_NOIO, &f2fs_bioset);
424433
bio->bi_iter.bi_sector = sector;
425434
if (is_read_io(fio->op)) {
426435
bio->bi_end_io = f2fs_read_end_io;

fs/f2fs/f2fs.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ struct f2fs_mount_info {
154154
int s_jquota_fmt; /* Format of quota to use */
155155
#endif
156156
/* For which write hints are passed down to block layer */
157-
int whint_mode;
158157
int alloc_mode; /* segment allocation policy */
159158
int fsync_mode; /* fsync policy */
160159
int fs_mode; /* fs mode: LFS or ADAPTIVE */
@@ -1333,12 +1332,6 @@ enum {
13331332
FS_MODE_FRAGMENT_BLK, /* block fragmentation mode */
13341333
};
13351334

1336-
enum {
1337-
WHINT_MODE_OFF, /* not pass down write hints */
1338-
WHINT_MODE_USER, /* try to pass down hints given by users */
1339-
WHINT_MODE_FS, /* pass down hints with F2FS policy */
1340-
};
1341-
13421335
enum {
13431336
ALLOC_MODE_DEFAULT, /* stay default */
13441337
ALLOC_MODE_REUSE, /* reuse segments as much as possible */
@@ -3657,8 +3650,6 @@ void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
36573650
int __init f2fs_create_segment_manager_caches(void);
36583651
void f2fs_destroy_segment_manager_caches(void);
36593652
int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
3660-
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
3661-
enum page_type type, enum temp_type temp);
36623653
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
36633654
unsigned int segno);
36643655
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,

fs/f2fs/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
550550
}
551551
f2fs_set_inode_flags(inode);
552552

553-
if (file_should_truncate(inode)) {
553+
if (file_should_truncate(inode) &&
554+
!is_sbi_flag_set(sbi, SBI_POR_DOING)) {
554555
ret = f2fs_truncate(inode);
555556
if (ret)
556557
goto bad_inode;

fs/f2fs/segment.c

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,101 +3243,6 @@ int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
32433243
}
32443244
}
32453245

3246-
/* This returns write hints for each segment type. This hints will be
3247-
* passed down to block layer. There are mapping tables which depend on
3248-
* the mount option 'whint_mode'.
3249-
*
3250-
* 1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
3251-
*
3252-
* 2) whint_mode=user-based. F2FS tries to pass down hints given by users.
3253-
*
3254-
* User F2FS Block
3255-
* ---- ---- -----
3256-
* META WRITE_LIFE_NOT_SET
3257-
* HOT_NODE "
3258-
* WARM_NODE "
3259-
* COLD_NODE "
3260-
* ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
3261-
* extension list " "
3262-
*
3263-
* -- buffered io
3264-
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
3265-
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
3266-
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
3267-
* WRITE_LIFE_NONE " "
3268-
* WRITE_LIFE_MEDIUM " "
3269-
* WRITE_LIFE_LONG " "
3270-
*
3271-
* -- direct io
3272-
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
3273-
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
3274-
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
3275-
* WRITE_LIFE_NONE " WRITE_LIFE_NONE
3276-
* WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
3277-
* WRITE_LIFE_LONG " WRITE_LIFE_LONG
3278-
*
3279-
* 3) whint_mode=fs-based. F2FS passes down hints with its policy.
3280-
*
3281-
* User F2FS Block
3282-
* ---- ---- -----
3283-
* META WRITE_LIFE_MEDIUM;
3284-
* HOT_NODE WRITE_LIFE_NOT_SET
3285-
* WARM_NODE "
3286-
* COLD_NODE WRITE_LIFE_NONE
3287-
* ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
3288-
* extension list " "
3289-
*
3290-
* -- buffered io
3291-
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
3292-
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
3293-
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_LONG
3294-
* WRITE_LIFE_NONE " "
3295-
* WRITE_LIFE_MEDIUM " "
3296-
* WRITE_LIFE_LONG " "
3297-
*
3298-
* -- direct io
3299-
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
3300-
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
3301-
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
3302-
* WRITE_LIFE_NONE " WRITE_LIFE_NONE
3303-
* WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
3304-
* WRITE_LIFE_LONG " WRITE_LIFE_LONG
3305-
*/
3306-
3307-
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
3308-
enum page_type type, enum temp_type temp)
3309-
{
3310-
if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER) {
3311-
if (type == DATA) {
3312-
if (temp == WARM)
3313-
return WRITE_LIFE_NOT_SET;
3314-
else if (temp == HOT)
3315-
return WRITE_LIFE_SHORT;
3316-
else if (temp == COLD)
3317-
return WRITE_LIFE_EXTREME;
3318-
} else {
3319-
return WRITE_LIFE_NOT_SET;
3320-
}
3321-
} else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS) {
3322-
if (type == DATA) {
3323-
if (temp == WARM)
3324-
return WRITE_LIFE_LONG;
3325-
else if (temp == HOT)
3326-
return WRITE_LIFE_SHORT;
3327-
else if (temp == COLD)
3328-
return WRITE_LIFE_EXTREME;
3329-
} else if (type == NODE) {
3330-
if (temp == WARM || temp == HOT)
3331-
return WRITE_LIFE_NOT_SET;
3332-
else if (temp == COLD)
3333-
return WRITE_LIFE_NONE;
3334-
} else if (type == META) {
3335-
return WRITE_LIFE_MEDIUM;
3336-
}
3337-
}
3338-
return WRITE_LIFE_NOT_SET;
3339-
}
3340-
33413246
static int __get_segment_type_2(struct f2fs_io_info *fio)
33423247
{
33433248
if (fio->type == DATA)

fs/f2fs/super.c

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ enum {
138138
Opt_jqfmt_vfsold,
139139
Opt_jqfmt_vfsv0,
140140
Opt_jqfmt_vfsv1,
141-
Opt_whint,
142141
Opt_alloc,
143142
Opt_fsync,
144143
Opt_test_dummy_encryption,
@@ -214,7 +213,6 @@ static match_table_t f2fs_tokens = {
214213
{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
215214
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
216215
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
217-
{Opt_whint, "whint_mode=%s"},
218216
{Opt_alloc, "alloc_mode=%s"},
219217
{Opt_fsync, "fsync_mode=%s"},
220218
{Opt_test_dummy_encryption, "test_dummy_encryption=%s"},
@@ -975,22 +973,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
975973
f2fs_info(sbi, "quota operations not supported");
976974
break;
977975
#endif
978-
case Opt_whint:
979-
name = match_strdup(&args[0]);
980-
if (!name)
981-
return -ENOMEM;
982-
if (!strcmp(name, "user-based")) {
983-
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_USER;
984-
} else if (!strcmp(name, "off")) {
985-
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
986-
} else if (!strcmp(name, "fs-based")) {
987-
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_FS;
988-
} else {
989-
kfree(name);
990-
return -EINVAL;
991-
}
992-
kfree(name);
993-
break;
994976
case Opt_alloc:
995977
name = match_strdup(&args[0]);
996978
if (!name)
@@ -1328,12 +1310,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
13281310
return -EINVAL;
13291311
}
13301312

1331-
/* Not pass down write hints if the number of active logs is lesser
1332-
* than NR_CURSEG_PERSIST_TYPE.
1333-
*/
1334-
if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_PERSIST_TYPE)
1335-
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
1336-
13371313
if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) {
13381314
f2fs_err(sbi, "Allow to mount readonly mode only");
13391315
return -EROFS;
@@ -1978,10 +1954,6 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
19781954
seq_puts(seq, ",prjquota");
19791955
#endif
19801956
f2fs_show_quota_options(seq, sbi->sb);
1981-
if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER)
1982-
seq_printf(seq, ",whint_mode=%s", "user-based");
1983-
else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
1984-
seq_printf(seq, ",whint_mode=%s", "fs-based");
19851957

19861958
fscrypt_show_test_dummy_encryption(seq, ',', sbi->sb);
19871959

@@ -2033,7 +2005,6 @@ static void default_options(struct f2fs_sb_info *sbi)
20332005
F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE;
20342006

20352007
F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
2036-
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
20372008
F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
20382009
F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX;
20392010
F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
@@ -2314,8 +2285,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
23142285
need_stop_gc = true;
23152286
}
23162287

2317-
if (*flags & SB_RDONLY ||
2318-
F2FS_OPTION(sbi).whint_mode != org_mount_opt.whint_mode) {
2288+
if (*flags & SB_RDONLY) {
23192289
sync_inodes_sb(sb);
23202290

23212291
set_sbi_flag(sbi, SBI_IS_DIRTY);

0 commit comments

Comments
 (0)