Skip to content

Commit 73a3fcd

Browse files
committed
Merge tag 'f2fs-for-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "In this cycle, we've mainly investigated the zoned block device support along with patches such as correcting write pointers between f2fs and storage, adding asynchronous zone reset flow, and managing the number of open zones. Other than them, f2fs adds another mount option, "errors=x" to specify how to handle when it detects an unexpected behavior at runtime. Enhancements: - support 'errors=remount-ro|continue|panic' mount option - enforce some inode flag policies - allow .tmp compression given extensions - add some ioctls to manage the f2fs compression - improve looped node chain flow - avoid issuing small-sized discard commands during checkpoint - implement an asynchronous zone reset Bug fixes: - fix deadlock in xattr and inode page lock - fix and add sanity check in some error paths - fix to avoid NULL pointer dereference f2fs_write_end_io() along with put_super - set proper flags to quota files - fix potential deadlock due to unpaired node_write lock use - fix over-estimating free section during FG GC - fix the wrong condition to determine atomic context As usual, also there are a number of patches with code refactoring and minor clean-ups" * tag 'f2fs-for-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (46 commits) f2fs: fix to do sanity check on direct node in truncate_dnode() f2fs: only set release for file that has compressed data f2fs: fix compile warning in f2fs_destroy_node_manager() f2fs: fix error path handling in truncate_dnode() f2fs: fix deadlock in i_xattr_sem and inode page lock f2fs: remove unneeded page uptodate check/set f2fs: update mtime and ctime in move file range method f2fs: compress tmp files given extension f2fs: refactor struct f2fs_attr macro f2fs: convert to use sbi directly f2fs: remove redundant assignment to variable err f2fs: do not issue small discard commands during checkpoint f2fs: check zone write pointer points to the end of zone f2fs: add f2fs_ioc_get_compress_blocks f2fs: cleanup MIN_INLINE_XATTR_SIZE f2fs: add helper to check compression level f2fs: set FMODE_CAN_ODIRECT instead of a dummy direct_IO method f2fs: do more sanity check on inode f2fs: compress: fix to check validity of i_compress_flag field f2fs: add sanity compress level check for compressed file ...
2 parents bb8e7e9 + a6ec837 commit 73a3fcd

File tree

21 files changed

+1069
-407
lines changed

21 files changed

+1069
-407
lines changed

Documentation/filesystems/f2fs.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,22 @@ age_extent_cache Enable an age extent cache based on rb-tree. It records
351351
data block update frequency of the extent per inode, in
352352
order to provide better temperature hints for data block
353353
allocation.
354+
errors=%s Specify f2fs behavior on critical errors. This supports modes:
355+
"panic", "continue" and "remount-ro", respectively, trigger
356+
panic immediately, continue without doing anything, and remount
357+
the partition in read-only mode. By default it uses "continue"
358+
mode.
359+
====================== =============== =============== ========
360+
mode continue remount-ro panic
361+
====================== =============== =============== ========
362+
access ops normal noraml N/A
363+
syscall errors -EIO -EROFS N/A
364+
mount option rw ro N/A
365+
pending dir write keep keep N/A
366+
pending non-dir write drop keep N/A
367+
pending node write drop keep N/A
368+
pending meta write keep keep N/A
369+
====================== =============== =============== ========
354370
======================== ============================================================
355371

356372
Debugfs Entries

fs/f2fs/checkpoint.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,9 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
3030
unsigned char reason)
3131
{
3232
f2fs_build_fault_attr(sbi, 0, 0);
33-
set_ckpt_flags(sbi, CP_ERROR_FLAG);
34-
if (!end_io) {
33+
if (!end_io)
3534
f2fs_flush_merged_writes(sbi);
36-
37-
f2fs_handle_stop(sbi, reason);
38-
}
35+
f2fs_handle_critical_error(sbi, reason, end_io);
3936
}
4037

4138
/*

fs/f2fs/compress.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct f2fs_compress_ops {
5555
int (*init_decompress_ctx)(struct decompress_io_ctx *dic);
5656
void (*destroy_decompress_ctx)(struct decompress_io_ctx *dic);
5757
int (*decompress_pages)(struct decompress_io_ctx *dic);
58+
bool (*is_level_valid)(int level);
5859
};
5960

6061
static unsigned int offset_in_cluster(struct compress_ctx *cc, pgoff_t index)
@@ -308,17 +309,25 @@ static int lz4_decompress_pages(struct decompress_io_ctx *dic)
308309
return 0;
309310
}
310311

312+
static bool lz4_is_level_valid(int lvl)
313+
{
314+
#ifdef CONFIG_F2FS_FS_LZ4HC
315+
return !lvl || (lvl >= LZ4HC_MIN_CLEVEL && lvl <= LZ4HC_MAX_CLEVEL);
316+
#else
317+
return lvl == 0;
318+
#endif
319+
}
320+
311321
static const struct f2fs_compress_ops f2fs_lz4_ops = {
312322
.init_compress_ctx = lz4_init_compress_ctx,
313323
.destroy_compress_ctx = lz4_destroy_compress_ctx,
314324
.compress_pages = lz4_compress_pages,
315325
.decompress_pages = lz4_decompress_pages,
326+
.is_level_valid = lz4_is_level_valid,
316327
};
317328
#endif
318329

319330
#ifdef CONFIG_F2FS_FS_ZSTD
320-
#define F2FS_ZSTD_DEFAULT_CLEVEL 1
321-
322331
static int zstd_init_compress_ctx(struct compress_ctx *cc)
323332
{
324333
zstd_parameters params;
@@ -327,6 +336,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
327336
unsigned int workspace_size;
328337
unsigned char level = F2FS_I(cc->inode)->i_compress_level;
329338

339+
/* Need to remain this for backward compatibility */
330340
if (!level)
331341
level = F2FS_ZSTD_DEFAULT_CLEVEL;
332342

@@ -477,13 +487,19 @@ static int zstd_decompress_pages(struct decompress_io_ctx *dic)
477487
return 0;
478488
}
479489

490+
static bool zstd_is_level_valid(int lvl)
491+
{
492+
return lvl >= zstd_min_clevel() && lvl <= zstd_max_clevel();
493+
}
494+
480495
static const struct f2fs_compress_ops f2fs_zstd_ops = {
481496
.init_compress_ctx = zstd_init_compress_ctx,
482497
.destroy_compress_ctx = zstd_destroy_compress_ctx,
483498
.compress_pages = zstd_compress_pages,
484499
.init_decompress_ctx = zstd_init_decompress_ctx,
485500
.destroy_decompress_ctx = zstd_destroy_decompress_ctx,
486501
.decompress_pages = zstd_decompress_pages,
502+
.is_level_valid = zstd_is_level_valid,
487503
};
488504
#endif
489505

@@ -542,6 +558,16 @@ bool f2fs_is_compress_backend_ready(struct inode *inode)
542558
return f2fs_cops[F2FS_I(inode)->i_compress_algorithm];
543559
}
544560

561+
bool f2fs_is_compress_level_valid(int alg, int lvl)
562+
{
563+
const struct f2fs_compress_ops *cops = f2fs_cops[alg];
564+
565+
if (cops->is_level_valid)
566+
return cops->is_level_valid(lvl);
567+
568+
return lvl == 0;
569+
}
570+
545571
static mempool_t *compress_page_pool;
546572
static int num_compress_pages = 512;
547573
module_param(num_compress_pages, uint, 0444);
@@ -743,8 +769,8 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
743769
ret = -EFSCORRUPTED;
744770

745771
/* Avoid f2fs_commit_super in irq context */
746-
if (in_task)
747-
f2fs_save_errors(sbi, ERROR_FAIL_DECOMPRESSION);
772+
if (!in_task)
773+
f2fs_handle_error_async(sbi, ERROR_FAIL_DECOMPRESSION);
748774
else
749775
f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION);
750776
goto out_release;
@@ -1215,14 +1241,15 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
12151241
unsigned int last_index = cc->cluster_size - 1;
12161242
loff_t psize;
12171243
int i, err;
1244+
bool quota_inode = IS_NOQUOTA(inode);
12181245

12191246
/* we should bypass data pages to proceed the kworker jobs */
12201247
if (unlikely(f2fs_cp_error(sbi))) {
12211248
mapping_set_error(cc->rpages[0]->mapping, -EIO);
12221249
goto out_free;
12231250
}
12241251

1225-
if (IS_NOQUOTA(inode)) {
1252+
if (quota_inode) {
12261253
/*
12271254
* We need to wait for node_write to avoid block allocation during
12281255
* checkpoint. This can only happen to quota writes which can cause
@@ -1344,7 +1371,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
13441371
set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
13451372

13461373
f2fs_put_dnode(&dn);
1347-
if (IS_NOQUOTA(inode))
1374+
if (quota_inode)
13481375
f2fs_up_read(&sbi->node_write);
13491376
else
13501377
f2fs_unlock_op(sbi);
@@ -1370,7 +1397,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
13701397
out_put_dnode:
13711398
f2fs_put_dnode(&dn);
13721399
out_unlock_op:
1373-
if (IS_NOQUOTA(inode))
1400+
if (quota_inode)
13741401
f2fs_up_read(&sbi->node_write);
13751402
else
13761403
f2fs_unlock_op(sbi);

fs/f2fs/data.c

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,17 @@ static void f2fs_write_end_io(struct bio *bio)
383383
bio_put(bio);
384384
}
385385

386+
#ifdef CONFIG_BLK_DEV_ZONED
387+
static void f2fs_zone_write_end_io(struct bio *bio)
388+
{
389+
struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private;
390+
391+
bio->bi_private = io->bi_private;
392+
complete(&io->zone_wait);
393+
f2fs_write_end_io(bio);
394+
}
395+
#endif
396+
386397
struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
387398
block_t blk_addr, sector_t *sector)
388399
{
@@ -639,6 +650,11 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
639650
INIT_LIST_HEAD(&sbi->write_io[i][j].io_list);
640651
INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list);
641652
init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock);
653+
#ifdef CONFIG_BLK_DEV_ZONED
654+
init_completion(&sbi->write_io[i][j].zone_wait);
655+
sbi->write_io[i][j].zone_pending_bio = NULL;
656+
sbi->write_io[i][j].bi_private = NULL;
657+
#endif
642658
}
643659
}
644660

@@ -965,6 +981,26 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
965981
return 0;
966982
}
967983

984+
#ifdef CONFIG_BLK_DEV_ZONED
985+
static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
986+
{
987+
int devi = 0;
988+
989+
if (f2fs_is_multi_device(sbi)) {
990+
devi = f2fs_target_device_index(sbi, blkaddr);
991+
if (blkaddr < FDEV(devi).start_blk ||
992+
blkaddr > FDEV(devi).end_blk) {
993+
f2fs_err(sbi, "Invalid block %x", blkaddr);
994+
return false;
995+
}
996+
blkaddr -= FDEV(devi).start_blk;
997+
}
998+
return bdev_zoned_model(FDEV(devi).bdev) == BLK_ZONED_HM &&
999+
f2fs_blkz_is_seq(sbi, devi, blkaddr) &&
1000+
(blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
1001+
}
1002+
#endif
1003+
9681004
void f2fs_submit_page_write(struct f2fs_io_info *fio)
9691005
{
9701006
struct f2fs_sb_info *sbi = fio->sbi;
@@ -975,6 +1011,16 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
9751011
f2fs_bug_on(sbi, is_read_io(fio->op));
9761012

9771013
f2fs_down_write(&io->io_rwsem);
1014+
1015+
#ifdef CONFIG_BLK_DEV_ZONED
1016+
if (f2fs_sb_has_blkzoned(sbi) && btype < META && io->zone_pending_bio) {
1017+
wait_for_completion_io(&io->zone_wait);
1018+
bio_put(io->zone_pending_bio);
1019+
io->zone_pending_bio = NULL;
1020+
io->bi_private = NULL;
1021+
}
1022+
#endif
1023+
9781024
next:
9791025
if (fio->in_list) {
9801026
spin_lock(&io->io_lock);
@@ -1038,6 +1084,18 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
10381084
if (fio->in_list)
10391085
goto next;
10401086
out:
1087+
#ifdef CONFIG_BLK_DEV_ZONED
1088+
if (f2fs_sb_has_blkzoned(sbi) && btype < META &&
1089+
is_end_zone_blkaddr(sbi, fio->new_blkaddr)) {
1090+
bio_get(io->bio);
1091+
reinit_completion(&io->zone_wait);
1092+
io->bi_private = io->bio->bi_private;
1093+
io->bio->bi_private = io;
1094+
io->bio->bi_end_io = f2fs_zone_write_end_io;
1095+
io->zone_pending_bio = io->bio;
1096+
__submit_merged_bio(io);
1097+
}
1098+
#endif
10411099
if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) ||
10421100
!f2fs_is_checkpoint_ready(sbi))
10431101
__submit_merged_bio(io);
@@ -2173,7 +2231,6 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
21732231
f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO,
21742232
F2FS_BLKSIZE);
21752233
*last_block_in_bio = block_nr;
2176-
goto out;
21772234
out:
21782235
*bio_ret = bio;
21792236
return ret;
@@ -2775,6 +2832,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
27752832
loff_t psize = (loff_t)(page->index + 1) << PAGE_SHIFT;
27762833
unsigned offset = 0;
27772834
bool need_balance_fs = false;
2835+
bool quota_inode = IS_NOQUOTA(inode);
27782836
int err = 0;
27792837
struct f2fs_io_info fio = {
27802838
.sbi = sbi,
@@ -2807,6 +2865,10 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
28072865
if (S_ISDIR(inode->i_mode) &&
28082866
!is_sbi_flag_set(sbi, SBI_IS_CLOSE))
28092867
goto redirty_out;
2868+
2869+
/* keep data pages in remount-ro mode */
2870+
if (F2FS_OPTION(sbi).errors == MOUNT_ERRORS_READONLY)
2871+
goto redirty_out;
28102872
goto out;
28112873
}
28122874

@@ -2832,19 +2894,19 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
28322894
goto out;
28332895

28342896
/* Dentry/quota blocks are controlled by checkpoint */
2835-
if (S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) {
2897+
if (S_ISDIR(inode->i_mode) || quota_inode) {
28362898
/*
28372899
* We need to wait for node_write to avoid block allocation during
28382900
* checkpoint. This can only happen to quota writes which can cause
28392901
* the below discard race condition.
28402902
*/
2841-
if (IS_NOQUOTA(inode))
2903+
if (quota_inode)
28422904
f2fs_down_read(&sbi->node_write);
28432905

28442906
fio.need_lock = LOCK_DONE;
28452907
err = f2fs_do_write_data_page(&fio);
28462908

2847-
if (IS_NOQUOTA(inode))
2909+
if (quota_inode)
28482910
f2fs_up_read(&sbi->node_write);
28492911

28502912
goto done;
@@ -4067,7 +4129,6 @@ const struct address_space_operations f2fs_dblock_aops = {
40674129
.migrate_folio = filemap_migrate_folio,
40684130
.invalidate_folio = f2fs_invalidate_folio,
40694131
.release_folio = f2fs_release_folio,
4070-
.direct_IO = noop_direct_IO,
40714132
.bmap = f2fs_bmap,
40724133
.swap_activate = f2fs_swap_activate,
40734134
.swap_deactivate = f2fs_swap_deactivate,

fs/f2fs/dir.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,15 @@ int f2fs_add_dentry(struct inode *dir, const struct f2fs_filename *fname,
775775
{
776776
int err = -EAGAIN;
777777

778-
if (f2fs_has_inline_dentry(dir))
778+
if (f2fs_has_inline_dentry(dir)) {
779+
/*
780+
* Should get i_xattr_sem to keep the lock order:
781+
* i_xattr_sem -> inode_page lock used by f2fs_setxattr.
782+
*/
783+
f2fs_down_read(&F2FS_I(dir)->i_xattr_sem);
779784
err = f2fs_add_inline_entry(dir, fname, inode, ino, mode);
785+
f2fs_up_read(&F2FS_I(dir)->i_xattr_sem);
786+
}
780787
if (err == -EAGAIN)
781788
err = f2fs_add_regular_entry(dir, fname, inode, ino, mode);
782789

0 commit comments

Comments
 (0)