Skip to content

Commit 1d1df41

Browse files
committed
Merge tag 'f2fs-for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "In this round, we've tried to address some performance issues in f2fs_checkpoint and direct IO flows. Also, there was a work to enhance the page cache management used for compression. Other than them, we've done typical work including sysfs, code clean-ups, tracepoint, sanity check, in addition to bug fixes on corner cases. Enhancements: - use iomap for direct IO - try to avoid lock contention to improve f2fs_ckpt speed - avoid unnecessary memory allocation in compression flow - POSIX_FADV_DONTNEED drops the page cache containing compression pages - add some sysfs entries (gc_urgent_high_remaining, pending_discard) Bug fixes: - try not to expose unwritten blocks to user by DIO (this was added to avoid merge conflict; another patch is coming to address other missing case) - relax minor error condition for file pinning feature used in Android OTA - fix potential deadlock case in compression flow - should not truncate any block on pinned file In addition, we've done some code clean-ups and tracepoint/sanity check improvement" * tag 'f2fs-for-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (29 commits) f2fs: do not allow partial truncation on pinned file f2fs: remove redunant invalidate compress pages f2fs: Simplify bool conversion f2fs: don't drop compressed page cache in .{invalidate,release}page f2fs: fix to reserve space for IO align feature f2fs: fix to check available space of CP area correctly in update_ckpt_flags() f2fs: support fault injection to f2fs_trylock_op() f2fs: clean up __find_inline_xattr() with __find_xattr() f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() f2fs: do not bother checkpoint by f2fs_get_node_info f2fs: avoid down_write on nat_tree_lock during checkpoint f2fs: compress: fix potential deadlock of compress file f2fs: avoid EINVAL by SBI_NEED_FSCK when pinning a file f2fs: add gc_urgent_high_remaining sysfs node f2fs: fix to do sanity check in is_alive() f2fs: fix to avoid panic in is_alive() if metadata is inconsistent f2fs: fix to do sanity check on inode type during garbage collection f2fs: avoid duplicate call of mark_inode_dirty f2fs: show number of pending discard commands f2fs: support POSIX_FADV_DONTNEED drop compressed page cache ...
2 parents e9f5cbc + 5fed0be commit 1d1df41

File tree

20 files changed

+759
-505
lines changed

20 files changed

+759
-505
lines changed

Documentation/ABI/testing/sysfs-fs-f2fs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ Contact: "Jaegeuk Kim" <[email protected]>
112112
Description: Set timeout to issue discard commands during umount.
113113
Default: 5 secs
114114

115+
What: /sys/fs/f2fs/<disk>/pending_discard
116+
Date: November 2021
117+
Contact: "Jaegeuk Kim" <[email protected]>
118+
Description: Shows the number of pending discard commands in the queue.
119+
115120
What: /sys/fs/f2fs/<disk>/max_victim_search
116121
Date: January 2014
117122
Contact: "Jaegeuk Kim" <[email protected]>
@@ -528,3 +533,10 @@ Description: With "mode=fragment:block" mount options, we can scatter block allo
528533
f2fs will allocate 1..<max_fragment_chunk> blocks in a chunk and make a hole
529534
in the length of 1..<max_fragment_hole> by turns. This value can be set
530535
between 1..512 and the default value is 4.
536+
537+
What: /sys/fs/f2fs/<disk>/gc_urgent_high_remaining
538+
Date: December 2021
539+
Contact: "Daeho Jeong" <[email protected]>
540+
Description: You can set the trial count limit for GC urgent high mode with this value.
541+
If GC thread gets to the limit, the mode will turn back to GC normal mode.
542+
By default, the value is zero, which means there is no limit like before.

Documentation/filesystems/f2fs.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ fault_type=%d Support configuring fault injection type, should be
198198
FAULT_WRITE_IO 0x000004000
199199
FAULT_SLAB_ALLOC 0x000008000
200200
FAULT_DQUOT_INIT 0x000010000
201+
FAULT_LOCK_OP 0x000020000
201202
=================== ===========
202203
mode=%s Control block allocation mode which supports "adaptive"
203204
and "lfs". In "lfs" mode, there should be no random

fs/f2fs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ config F2FS_FS
77
select CRYPTO_CRC32
88
select F2FS_FS_XATTR if FS_ENCRYPTION
99
select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
10+
select FS_IOMAP
1011
select LZ4_COMPRESS if F2FS_FS_LZ4
1112
select LZ4_DECOMPRESS if F2FS_FS_LZ4
1213
select LZ4HC_COMPRESS if F2FS_FS_LZ4HC

fs/f2fs/checkpoint.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
664664
/* truncate all the data during iput */
665665
iput(inode);
666666

667-
err = f2fs_get_node_info(sbi, ino, &ni);
667+
err = f2fs_get_node_info(sbi, ino, &ni, false);
668668
if (err)
669669
goto err_out;
670670

@@ -1302,8 +1302,8 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
13021302
unsigned long flags;
13031303

13041304
if (cpc->reason & CP_UMOUNT) {
1305-
if (le32_to_cpu(ckpt->cp_pack_total_block_count) >
1306-
sbi->blocks_per_seg - NM_I(sbi)->nat_bits_blocks) {
1305+
if (le32_to_cpu(ckpt->cp_pack_total_block_count) +
1306+
NM_I(sbi)->nat_bits_blocks > sbi->blocks_per_seg) {
13071307
clear_ckpt_flags(sbi, CP_NAT_BITS_FLAG);
13081308
f2fs_notice(sbi, "Disable nat_bits due to no space");
13091309
} else if (!is_set_ckpt_flags(sbi, CP_NAT_BITS_FLAG) &&

fs/f2fs/compress.c

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse)
154154
cc->rpages = NULL;
155155
cc->nr_rpages = 0;
156156
cc->nr_cpages = 0;
157+
cc->valid_nr_cpages = 0;
157158
if (!reuse)
158159
cc->cluster_idx = NULL_CLUSTER;
159160
}
@@ -620,7 +621,6 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
620621
const struct f2fs_compress_ops *cops =
621622
f2fs_cops[fi->i_compress_algorithm];
622623
unsigned int max_len, new_nr_cpages;
623-
struct page **new_cpages;
624624
u32 chksum = 0;
625625
int i, ret;
626626

@@ -635,6 +635,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
635635

636636
max_len = COMPRESS_HEADER_SIZE + cc->clen;
637637
cc->nr_cpages = DIV_ROUND_UP(max_len, PAGE_SIZE);
638+
cc->valid_nr_cpages = cc->nr_cpages;
638639

639640
cc->cpages = page_array_alloc(cc->inode, cc->nr_cpages);
640641
if (!cc->cpages) {
@@ -685,13 +686,6 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
685686

686687
new_nr_cpages = DIV_ROUND_UP(cc->clen + COMPRESS_HEADER_SIZE, PAGE_SIZE);
687688

688-
/* Now we're going to cut unnecessary tail pages */
689-
new_cpages = page_array_alloc(cc->inode, new_nr_cpages);
690-
if (!new_cpages) {
691-
ret = -ENOMEM;
692-
goto out_vunmap_cbuf;
693-
}
694-
695689
/* zero out any unused part of the last page */
696690
memset(&cc->cbuf->cdata[cc->clen], 0,
697691
(new_nr_cpages * PAGE_SIZE) -
@@ -701,20 +695,16 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
701695
vm_unmap_ram(cc->rbuf, cc->cluster_size);
702696

703697
for (i = 0; i < cc->nr_cpages; i++) {
704-
if (i < new_nr_cpages) {
705-
new_cpages[i] = cc->cpages[i];
698+
if (i < new_nr_cpages)
706699
continue;
707-
}
708700
f2fs_compress_free_page(cc->cpages[i]);
709701
cc->cpages[i] = NULL;
710702
}
711703

712704
if (cops->destroy_compress_ctx)
713705
cops->destroy_compress_ctx(cc);
714706

715-
page_array_free(cc->inode, cc->cpages, cc->nr_cpages);
716-
cc->cpages = new_cpages;
717-
cc->nr_cpages = new_nr_cpages;
707+
cc->valid_nr_cpages = new_nr_cpages;
718708

719709
trace_f2fs_compress_pages_end(cc->inode, cc->cluster_idx,
720710
cc->clen, ret);
@@ -1296,7 +1286,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
12961286

12971287
psize = (loff_t)(cc->rpages[last_index]->index + 1) << PAGE_SHIFT;
12981288

1299-
err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
1289+
err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false);
13001290
if (err)
13011291
goto out_put_dnode;
13021292

@@ -1308,14 +1298,14 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
13081298

13091299
cic->magic = F2FS_COMPRESSED_PAGE_MAGIC;
13101300
cic->inode = inode;
1311-
atomic_set(&cic->pending_pages, cc->nr_cpages);
1301+
atomic_set(&cic->pending_pages, cc->valid_nr_cpages);
13121302
cic->rpages = page_array_alloc(cc->inode, cc->cluster_size);
13131303
if (!cic->rpages)
13141304
goto out_put_cic;
13151305

13161306
cic->nr_rpages = cc->cluster_size;
13171307

1318-
for (i = 0; i < cc->nr_cpages; i++) {
1308+
for (i = 0; i < cc->valid_nr_cpages; i++) {
13191309
f2fs_set_compressed_page(cc->cpages[i], inode,
13201310
cc->rpages[i + 1]->index, cic);
13211311
fio.compressed_page = cc->cpages[i];
@@ -1360,7 +1350,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
13601350
if (fio.compr_blocks && __is_valid_data_blkaddr(blkaddr))
13611351
fio.compr_blocks++;
13621352

1363-
if (i > cc->nr_cpages) {
1353+
if (i > cc->valid_nr_cpages) {
13641354
if (__is_valid_data_blkaddr(blkaddr)) {
13651355
f2fs_invalidate_blocks(sbi, blkaddr);
13661356
f2fs_update_data_blkaddr(&dn, NEW_ADDR);
@@ -1385,8 +1375,8 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
13851375

13861376
if (fio.compr_blocks)
13871377
f2fs_i_compr_blocks_update(inode, fio.compr_blocks - 1, false);
1388-
f2fs_i_compr_blocks_update(inode, cc->nr_cpages, true);
1389-
add_compr_block_stat(inode, cc->nr_cpages);
1378+
f2fs_i_compr_blocks_update(inode, cc->valid_nr_cpages, true);
1379+
add_compr_block_stat(inode, cc->valid_nr_cpages);
13901380

13911381
set_inode_flag(cc->inode, FI_APPEND_WRITE);
13921382
if (cc->cluster_idx == 0)
@@ -1424,9 +1414,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
14241414
else
14251415
f2fs_unlock_op(sbi);
14261416
out_free:
1427-
for (i = 0; i < cc->nr_cpages; i++) {
1428-
if (!cc->cpages[i])
1429-
continue;
1417+
for (i = 0; i < cc->valid_nr_cpages; i++) {
14301418
f2fs_compress_free_page(cc->cpages[i]);
14311419
cc->cpages[i] = NULL;
14321420
}
@@ -1468,25 +1456,38 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
14681456
enum iostat_type io_type)
14691457
{
14701458
struct address_space *mapping = cc->inode->i_mapping;
1471-
int _submitted, compr_blocks, ret;
1472-
int i = -1, err = 0;
1459+
int _submitted, compr_blocks, ret, i;
14731460

14741461
compr_blocks = f2fs_compressed_blocks(cc);
1475-
if (compr_blocks < 0) {
1476-
err = compr_blocks;
1477-
goto out_err;
1462+
1463+
for (i = 0; i < cc->cluster_size; i++) {
1464+
if (!cc->rpages[i])
1465+
continue;
1466+
1467+
redirty_page_for_writepage(wbc, cc->rpages[i]);
1468+
unlock_page(cc->rpages[i]);
14781469
}
14791470

1471+
if (compr_blocks < 0)
1472+
return compr_blocks;
1473+
14801474
for (i = 0; i < cc->cluster_size; i++) {
14811475
if (!cc->rpages[i])
14821476
continue;
14831477
retry_write:
1478+
lock_page(cc->rpages[i]);
1479+
14841480
if (cc->rpages[i]->mapping != mapping) {
1481+
continue_unlock:
14851482
unlock_page(cc->rpages[i]);
14861483
continue;
14871484
}
14881485

1489-
BUG_ON(!PageLocked(cc->rpages[i]));
1486+
if (!PageDirty(cc->rpages[i]))
1487+
goto continue_unlock;
1488+
1489+
if (!clear_page_dirty_for_io(cc->rpages[i]))
1490+
goto continue_unlock;
14901491

14911492
ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted,
14921493
NULL, NULL, wbc, io_type,
@@ -1501,26 +1502,15 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
15011502
* avoid deadlock caused by cluster update race
15021503
* from foreground operation.
15031504
*/
1504-
if (IS_NOQUOTA(cc->inode)) {
1505-
err = 0;
1506-
goto out_err;
1507-
}
1505+
if (IS_NOQUOTA(cc->inode))
1506+
return 0;
15081507
ret = 0;
15091508
cond_resched();
15101509
congestion_wait(BLK_RW_ASYNC,
15111510
DEFAULT_IO_TIMEOUT);
1512-
lock_page(cc->rpages[i]);
1513-
1514-
if (!PageDirty(cc->rpages[i])) {
1515-
unlock_page(cc->rpages[i]);
1516-
continue;
1517-
}
1518-
1519-
clear_page_dirty_for_io(cc->rpages[i]);
15201511
goto retry_write;
15211512
}
1522-
err = ret;
1523-
goto out_err;
1513+
return ret;
15241514
}
15251515

15261516
*submitted += _submitted;
@@ -1529,14 +1519,6 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
15291519
f2fs_balance_fs(F2FS_M_SB(mapping), true);
15301520

15311521
return 0;
1532-
out_err:
1533-
for (++i; i < cc->cluster_size; i++) {
1534-
if (!cc->rpages[i])
1535-
continue;
1536-
redirty_page_for_writepage(wbc, cc->rpages[i]);
1537-
unlock_page(cc->rpages[i]);
1538-
}
1539-
return err;
15401522
}
15411523

15421524
int f2fs_write_multi_pages(struct compress_ctx *cc,

0 commit comments

Comments
 (0)