Skip to content

Commit aea6bf9

Browse files
committed
Merge tag 'f2fs-for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "In this cycle, we introduce a bigger page size support by changing the internal f2fs's block size aligned to the page size. We also continue to improve zoned block device support regarding the power off recovery. As usual, there are some bug fixes regarding the error handling routines in compression and ioctl. Enhancements: - Support Block Size == Page Size - let f2fs_precache_extents() traverses in file range - stop iterating f2fs_map_block if hole exists - preload extent_cache for POSIX_FADV_WILLNEED - compress: fix to avoid fragment w/ OPU during f2fs_ioc_compress_file() Bug fixes: - do not return EFSCORRUPTED, but try to run online repair - finish previous checkpoints before returning from remount - fix error handling of __get_node_page and __f2fs_build_free_nids - clean up zones when not successfully unmounted - fix to initialize map.m_pblk in f2fs_precache_extents() - fix to drop meta_inode's page cache in f2fs_put_super() - set the default compress_level on ioctl - fix to avoid use-after-free on dic - fix to avoid redundant compress extension - do sanity check on cluster when CONFIG_F2FS_CHECK_FS is on - fix deadloop in f2fs_write_cache_pages()" * tag 'f2fs-for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: f2fs: finish previous checkpoints before returning from remount f2fs: fix error handling of __get_node_page f2fs: do not return EFSCORRUPTED, but try to run online repair f2fs: fix error path of __f2fs_build_free_nids f2fs: Clean up errors in segment.h f2fs: clean up zones when not successfully unmounted f2fs: let f2fs_precache_extents() traverses in file range f2fs: avoid format-overflow warning f2fs: fix to initialize map.m_pblk in f2fs_precache_extents() f2fs: Support Block Size == Page Size f2fs: stop iterating f2fs_map_block if hole exists f2fs: preload extent_cache for POSIX_FADV_WILLNEED f2fs: set the default compress_level on ioctl f2fs: compress: fix to avoid fragment w/ OPU during f2fs_ioc_compress_file() f2fs: fix to drop meta_inode's page cache in f2fs_put_super() f2fs: split initial and dynamic conditions for extent_cache f2fs: compress: fix to avoid redundant compress extension f2fs: compress: do sanity check on cluster when CONFIG_F2FS_CHECK_FS is on f2fs: compress: fix to avoid use-after-free on dic f2fs: compress: fix deadloop in f2fs_write_cache_pages()
2 parents c9b93ca + 1e7bef5 commit aea6bf9

File tree

11 files changed

+296
-178
lines changed

11 files changed

+296
-178
lines changed

fs/f2fs/compress.c

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -893,14 +893,15 @@ static bool cluster_has_invalid_data(struct compress_ctx *cc)
893893

894894
bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
895895
{
896+
#ifdef CONFIG_F2FS_CHECK_FS
896897
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
897898
unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
898-
bool compressed = dn->data_blkaddr == COMPRESS_ADDR;
899899
int cluster_end = 0;
900+
unsigned int count;
900901
int i;
901902
char *reason = "";
902903

903-
if (!compressed)
904+
if (dn->data_blkaddr != COMPRESS_ADDR)
904905
return false;
905906

906907
/* [..., COMPR_ADDR, ...] */
@@ -909,7 +910,7 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
909910
goto out;
910911
}
911912

912-
for (i = 1; i < cluster_size; i++) {
913+
for (i = 1, count = 1; i < cluster_size; i++, count++) {
913914
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
914915
dn->ofs_in_node + i);
915916

@@ -929,19 +930,42 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
929930
goto out;
930931
}
931932
}
933+
934+
f2fs_bug_on(F2FS_I_SB(dn->inode), count != cluster_size &&
935+
!is_inode_flag_set(dn->inode, FI_COMPRESS_RELEASED));
936+
932937
return false;
933938
out:
934939
f2fs_warn(sbi, "access invalid cluster, ino:%lu, nid:%u, ofs_in_node:%u, reason:%s",
935940
dn->inode->i_ino, dn->nid, dn->ofs_in_node, reason);
936941
set_sbi_flag(sbi, SBI_NEED_FSCK);
937942
return true;
943+
#else
944+
return false;
945+
#endif
946+
}
947+
948+
static int __f2fs_get_cluster_blocks(struct inode *inode,
949+
struct dnode_of_data *dn)
950+
{
951+
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
952+
int count, i;
953+
954+
for (i = 1, count = 1; i < cluster_size; i++) {
955+
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
956+
dn->ofs_in_node + i);
957+
958+
if (__is_valid_data_blkaddr(blkaddr))
959+
count++;
960+
}
961+
962+
return count;
938963
}
939964

940965
static int __f2fs_cluster_blocks(struct inode *inode,
941-
unsigned int cluster_idx, bool compr)
966+
unsigned int cluster_idx, bool compr_blks)
942967
{
943968
struct dnode_of_data dn;
944-
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
945969
unsigned int start_idx = cluster_idx <<
946970
F2FS_I(inode)->i_log_cluster_size;
947971
int ret;
@@ -956,31 +980,14 @@ static int __f2fs_cluster_blocks(struct inode *inode,
956980

957981
if (f2fs_sanity_check_cluster(&dn)) {
958982
ret = -EFSCORRUPTED;
959-
f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER);
960983
goto fail;
961984
}
962985

963986
if (dn.data_blkaddr == COMPRESS_ADDR) {
964-
int i;
965-
966-
ret = 1;
967-
for (i = 1; i < cluster_size; i++) {
968-
block_t blkaddr;
969-
970-
blkaddr = data_blkaddr(dn.inode,
971-
dn.node_page, dn.ofs_in_node + i);
972-
if (compr) {
973-
if (__is_valid_data_blkaddr(blkaddr))
974-
ret++;
975-
} else {
976-
if (blkaddr != NULL_ADDR)
977-
ret++;
978-
}
979-
}
980-
981-
f2fs_bug_on(F2FS_I_SB(inode),
982-
!compr && ret != cluster_size &&
983-
!is_inode_flag_set(inode, FI_COMPRESS_RELEASED));
987+
if (compr_blks)
988+
ret = __f2fs_get_cluster_blocks(inode, &dn);
989+
else
990+
ret = 1;
984991
}
985992
fail:
986993
f2fs_put_dnode(&dn);
@@ -993,7 +1000,7 @@ static int f2fs_compressed_blocks(struct compress_ctx *cc)
9931000
return __f2fs_cluster_blocks(cc->inode, cc->cluster_idx, true);
9941001
}
9951002

996-
/* return # of valid blocks in compressed cluster */
1003+
/* return whether cluster is compressed one or not */
9971004
int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
9981005
{
9991006
return __f2fs_cluster_blocks(inode,
@@ -1976,7 +1983,7 @@ void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi)
19761983
int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi)
19771984
{
19781985
dev_t dev = sbi->sb->s_bdev->bd_dev;
1979-
char slab_name[32];
1986+
char slab_name[35];
19801987

19811988
if (!f2fs_sb_has_compression(sbi))
19821989
return 0;

fs/f2fs/data.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,9 +1690,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
16901690
map->m_flags |= F2FS_MAP_NEW;
16911691
} else if (is_hole) {
16921692
if (f2fs_compressed_file(inode) &&
1693-
f2fs_sanity_check_cluster(&dn) &&
1694-
(flag != F2FS_GET_BLOCK_FIEMAP ||
1695-
IS_ENABLED(CONFIG_F2FS_CHECK_FS))) {
1693+
f2fs_sanity_check_cluster(&dn)) {
16961694
err = -EFSCORRUPTED;
16971695
f2fs_handle_error(sbi,
16981696
ERROR_CORRUPTED_CLUSTER);
@@ -2344,8 +2342,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
23442342
f2fs_wait_on_block_writeback(inode, blkaddr);
23452343

23462344
if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
2347-
if (atomic_dec_and_test(&dic->remaining_pages))
2345+
if (atomic_dec_and_test(&dic->remaining_pages)) {
23482346
f2fs_decompress_cluster(dic, true);
2347+
break;
2348+
}
23492349
continue;
23502350
}
23512351

@@ -2665,6 +2665,11 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
26652665
return true;
26662666
if (f2fs_is_atomic_file(inode))
26672667
return true;
2668+
/* rewrite low ratio compress data w/ OPU mode to avoid fragmentation */
2669+
if (f2fs_compressed_file(inode) &&
2670+
F2FS_OPTION(sbi).compress_mode == COMPR_MODE_USER &&
2671+
is_inode_flag_set(inode, FI_ENABLE_COMPRESS))
2672+
return true;
26682673

26692674
/* swap file is migrating in aligned write mode */
26702675
if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
@@ -3023,7 +3028,8 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
30233028
{
30243029
int ret = 0;
30253030
int done = 0, retry = 0;
3026-
struct page *pages[F2FS_ONSTACK_PAGES];
3031+
struct page *pages_local[F2FS_ONSTACK_PAGES];
3032+
struct page **pages = pages_local;
30273033
struct folio_batch fbatch;
30283034
struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
30293035
struct bio *bio = NULL;
@@ -3047,6 +3053,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
30473053
#endif
30483054
int nr_folios, p, idx;
30493055
int nr_pages;
3056+
unsigned int max_pages = F2FS_ONSTACK_PAGES;
30503057
pgoff_t index;
30513058
pgoff_t end; /* Inclusive */
30523059
pgoff_t done_index;
@@ -3056,6 +3063,15 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
30563063
int submitted = 0;
30573064
int i;
30583065

3066+
#ifdef CONFIG_F2FS_FS_COMPRESSION
3067+
if (f2fs_compressed_file(inode) &&
3068+
1 << cc.log_cluster_size > F2FS_ONSTACK_PAGES) {
3069+
pages = f2fs_kzalloc(sbi, sizeof(struct page *) <<
3070+
cc.log_cluster_size, GFP_NOFS | __GFP_NOFAIL);
3071+
max_pages = 1 << cc.log_cluster_size;
3072+
}
3073+
#endif
3074+
30593075
folio_batch_init(&fbatch);
30603076

30613077
if (get_dirty_pages(mapping->host) <=
@@ -3101,7 +3117,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
31013117
add_more:
31023118
pages[nr_pages] = folio_page(folio, idx);
31033119
folio_get(folio);
3104-
if (++nr_pages == F2FS_ONSTACK_PAGES) {
3120+
if (++nr_pages == max_pages) {
31053121
index = folio->index + idx + 1;
31063122
folio_batch_release(&fbatch);
31073123
goto write;
@@ -3283,6 +3299,11 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
32833299
if (bio)
32843300
f2fs_submit_merged_ipu_write(sbi, &bio, NULL);
32853301

3302+
#ifdef CONFIG_F2FS_FS_COMPRESSION
3303+
if (pages != pages_local)
3304+
kfree(pages);
3305+
#endif
3306+
32863307
return ret;
32873308
}
32883309

@@ -4055,7 +4076,7 @@ static int check_swap_activate(struct swap_info_struct *sis,
40554076
sis->highest_bit = cur_lblock - 1;
40564077
out:
40574078
if (not_aligned)
4058-
f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(%u * N)",
4079+
f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(%lu * N)",
40594080
not_aligned, blks_per_sec * F2FS_BLKSIZE);
40604081
return ret;
40614082
}

fs/f2fs/extent_cache.c

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -74,40 +74,14 @@ static void __set_extent_info(struct extent_info *ei,
7474
}
7575
}
7676

77-
static bool __may_read_extent_tree(struct inode *inode)
78-
{
79-
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
80-
81-
if (!test_opt(sbi, READ_EXTENT_CACHE))
82-
return false;
83-
if (is_inode_flag_set(inode, FI_NO_EXTENT))
84-
return false;
85-
if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
86-
!f2fs_sb_has_readonly(sbi))
87-
return false;
88-
return S_ISREG(inode->i_mode);
89-
}
90-
91-
static bool __may_age_extent_tree(struct inode *inode)
92-
{
93-
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
94-
95-
if (!test_opt(sbi, AGE_EXTENT_CACHE))
96-
return false;
97-
if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
98-
return false;
99-
if (file_is_cold(inode))
100-
return false;
101-
102-
return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode);
103-
}
104-
10577
static bool __init_may_extent_tree(struct inode *inode, enum extent_type type)
10678
{
10779
if (type == EX_READ)
108-
return __may_read_extent_tree(inode);
109-
else if (type == EX_BLOCK_AGE)
110-
return __may_age_extent_tree(inode);
80+
return test_opt(F2FS_I_SB(inode), READ_EXTENT_CACHE) &&
81+
S_ISREG(inode->i_mode);
82+
if (type == EX_BLOCK_AGE)
83+
return test_opt(F2FS_I_SB(inode), AGE_EXTENT_CACHE) &&
84+
(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode));
11185
return false;
11286
}
11387

@@ -120,7 +94,22 @@ static bool __may_extent_tree(struct inode *inode, enum extent_type type)
12094
if (list_empty(&F2FS_I_SB(inode)->s_list))
12195
return false;
12296

123-
return __init_may_extent_tree(inode, type);
97+
if (!__init_may_extent_tree(inode, type))
98+
return false;
99+
100+
if (type == EX_READ) {
101+
if (is_inode_flag_set(inode, FI_NO_EXTENT))
102+
return false;
103+
if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
104+
!f2fs_sb_has_readonly(F2FS_I_SB(inode)))
105+
return false;
106+
} else if (type == EX_BLOCK_AGE) {
107+
if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
108+
return false;
109+
if (file_is_cold(inode))
110+
return false;
111+
}
112+
return true;
124113
}
125114

126115
static void __try_update_largest_extent(struct extent_tree *et,

fs/f2fs/file.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3258,19 +3258,20 @@ int f2fs_precache_extents(struct inode *inode)
32583258
return -EOPNOTSUPP;
32593259

32603260
map.m_lblk = 0;
3261+
map.m_pblk = 0;
32613262
map.m_next_pgofs = NULL;
32623263
map.m_next_extent = &m_next_extent;
32633264
map.m_seg_type = NO_CHECK_TYPE;
32643265
map.m_may_create = false;
3265-
end = max_file_blocks(inode);
3266+
end = F2FS_BLK_ALIGN(i_size_read(inode));
32663267

32673268
while (map.m_lblk < end) {
32683269
map.m_len = end - map.m_lblk;
32693270

32703271
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
32713272
err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_PRECACHE);
32723273
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
3273-
if (err)
3274+
if (err || !map.m_len)
32743275
return err;
32753276

32763277
map.m_lblk = m_next_extent;
@@ -4005,6 +4006,15 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
40054006
F2FS_I(inode)->i_compress_algorithm = option.algorithm;
40064007
F2FS_I(inode)->i_log_cluster_size = option.log_cluster_size;
40074008
F2FS_I(inode)->i_cluster_size = BIT(option.log_cluster_size);
4009+
/* Set default level */
4010+
if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD)
4011+
F2FS_I(inode)->i_compress_level = F2FS_ZSTD_DEFAULT_CLEVEL;
4012+
else
4013+
F2FS_I(inode)->i_compress_level = 0;
4014+
/* Adjust mount option level */
4015+
if (option.algorithm == F2FS_OPTION(sbi).compress_algorithm &&
4016+
F2FS_OPTION(sbi).compress_level)
4017+
F2FS_I(inode)->i_compress_level = F2FS_OPTION(sbi).compress_level;
40084018
f2fs_mark_inode_dirty_sync(inode, true);
40094019

40104020
if (!f2fs_is_compress_backend_ready(inode))
@@ -4849,6 +4859,9 @@ static int f2fs_file_fadvise(struct file *filp, loff_t offset, loff_t len,
48494859
filp->f_mode &= ~FMODE_RANDOM;
48504860
spin_unlock(&filp->f_lock);
48514861
return 0;
4862+
} else if (advice == POSIX_FADV_WILLNEED && offset == 0) {
4863+
/* Load extent cache at the first readahead. */
4864+
f2fs_precache_extents(inode);
48524865
}
48534866

48544867
err = generic_fadvise(filp, offset, len, advice);

fs/f2fs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
315315
f2fs_has_inline_xattr(inode) &&
316316
(!fi->i_inline_xattr_size ||
317317
fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) {
318-
f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu",
318+
f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %lu",
319319
__func__, inode->i_ino, fi->i_inline_xattr_size,
320320
MAX_INLINE_XATTR_SIZE);
321321
return false;

0 commit comments

Comments
 (0)