Skip to content

Commit 2ac4482

Browse files
committed
Merge tag 'f2fs-fix-6.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs fixes from Jaegeuk Kim: - fix a null pointer dereference in f2fs_issue_flush, which occurs by the combination of mount/remount options. - fix a bug in per-block age-based extent_cache newly introduced in 6.2-rc1, which reported a wrong age information in extent_cache. - fix a kernel panic if extent_tree was not created, which was caught by a wrong BUG_ON * tag 'f2fs-fix-6.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: f2fs: let's avoid panic if extent_tree is not created f2fs: should use a temp extent_info for lookup f2fs: don't mix to use union values in extent_info f2fs: initialize extent_cache parameter f2fs: fix to avoid NULL pointer dereference in f2fs_issue_flush()
2 parents b61778f + df9d44b commit 2ac4482

4 files changed

Lines changed: 25 additions & 26 deletions

File tree

fs/f2fs/data.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
21832183
sector_t last_block_in_file;
21842184
const unsigned blocksize = blks_to_bytes(inode, 1);
21852185
struct decompress_io_ctx *dic = NULL;
2186-
struct extent_info ei = {0, };
2186+
struct extent_info ei = {};
21872187
bool from_dnode = true;
21882188
int i;
21892189
int ret = 0;

fs/f2fs/extent_cache.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,8 @@ static bool __lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
546546
struct extent_node *en;
547547
bool ret = false;
548548

549-
f2fs_bug_on(sbi, !et);
549+
if (!et)
550+
return false;
550551

551552
trace_f2fs_lookup_extent_tree_start(inode, pgofs, type);
552553

@@ -881,48 +882,50 @@ static unsigned long long __calculate_block_age(unsigned long long new,
881882
}
882883

883884
/* This returns a new age and allocated blocks in ei */
884-
static int __get_new_block_age(struct inode *inode, struct extent_info *ei)
885+
static int __get_new_block_age(struct inode *inode, struct extent_info *ei,
886+
block_t blkaddr)
885887
{
886888
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
887889
loff_t f_size = i_size_read(inode);
888890
unsigned long long cur_blocks =
889891
atomic64_read(&sbi->allocated_data_blocks);
892+
struct extent_info tei = *ei; /* only fofs and len are valid */
890893

891894
/*
892895
* When I/O is not aligned to a PAGE_SIZE, update will happen to the last
893896
* file block even in seq write. So don't record age for newly last file
894897
* block here.
895898
*/
896899
if ((f_size >> PAGE_SHIFT) == ei->fofs && f_size & (PAGE_SIZE - 1) &&
897-
ei->blk == NEW_ADDR)
900+
blkaddr == NEW_ADDR)
898901
return -EINVAL;
899902

900-
if (__lookup_extent_tree(inode, ei->fofs, ei, EX_BLOCK_AGE)) {
903+
if (__lookup_extent_tree(inode, ei->fofs, &tei, EX_BLOCK_AGE)) {
901904
unsigned long long cur_age;
902905

903-
if (cur_blocks >= ei->last_blocks)
904-
cur_age = cur_blocks - ei->last_blocks;
906+
if (cur_blocks >= tei.last_blocks)
907+
cur_age = cur_blocks - tei.last_blocks;
905908
else
906909
/* allocated_data_blocks overflow */
907-
cur_age = ULLONG_MAX - ei->last_blocks + cur_blocks;
910+
cur_age = ULLONG_MAX - tei.last_blocks + cur_blocks;
908911

909-
if (ei->age)
910-
ei->age = __calculate_block_age(cur_age, ei->age);
912+
if (tei.age)
913+
ei->age = __calculate_block_age(cur_age, tei.age);
911914
else
912915
ei->age = cur_age;
913916
ei->last_blocks = cur_blocks;
914917
WARN_ON(ei->age > cur_blocks);
915918
return 0;
916919
}
917920

918-
f2fs_bug_on(sbi, ei->blk == NULL_ADDR);
921+
f2fs_bug_on(sbi, blkaddr == NULL_ADDR);
919922

920923
/* the data block was allocated for the first time */
921-
if (ei->blk == NEW_ADDR)
924+
if (blkaddr == NEW_ADDR)
922925
goto out;
923926

924-
if (__is_valid_data_blkaddr(ei->blk) &&
925-
!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE)) {
927+
if (__is_valid_data_blkaddr(blkaddr) &&
928+
!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) {
926929
f2fs_bug_on(sbi, 1);
927930
return -EINVAL;
928931
}
@@ -938,7 +941,7 @@ static int __get_new_block_age(struct inode *inode, struct extent_info *ei)
938941

939942
static void __update_extent_cache(struct dnode_of_data *dn, enum extent_type type)
940943
{
941-
struct extent_info ei;
944+
struct extent_info ei = {};
942945

943946
if (!__may_extent_tree(dn->inode, type))
944947
return;
@@ -953,8 +956,7 @@ static void __update_extent_cache(struct dnode_of_data *dn, enum extent_type typ
953956
else
954957
ei.blk = dn->data_blkaddr;
955958
} else if (type == EX_BLOCK_AGE) {
956-
ei.blk = dn->data_blkaddr;
957-
if (__get_new_block_age(dn->inode, &ei))
959+
if (__get_new_block_age(dn->inode, &ei, dn->data_blkaddr))
958960
return;
959961
}
960962
__update_extent_tree_range(dn->inode, &ei, type);

fs/f2fs/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2559,7 +2559,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
25592559
struct f2fs_map_blocks map = { .m_next_extent = NULL,
25602560
.m_seg_type = NO_CHECK_TYPE,
25612561
.m_may_create = false };
2562-
struct extent_info ei = {0, };
2562+
struct extent_info ei = {};
25632563
pgoff_t pg_start, pg_end, next_pgofs;
25642564
unsigned int blk_per_seg = sbi->blocks_per_seg;
25652565
unsigned int total = 0, sec_num;

fs/f2fs/segment.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,7 @@ int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi)
663663
if (IS_ERR(fcc->f2fs_issue_flush)) {
664664
int err = PTR_ERR(fcc->f2fs_issue_flush);
665665

666-
kfree(fcc);
667-
SM_I(sbi)->fcc_info = NULL;
666+
fcc->f2fs_issue_flush = NULL;
668667
return err;
669668
}
670669

@@ -3161,7 +3160,7 @@ static int __get_segment_type_4(struct f2fs_io_info *fio)
31613160
static int __get_age_segment_type(struct inode *inode, pgoff_t pgofs)
31623161
{
31633162
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
3164-
struct extent_info ei;
3163+
struct extent_info ei = {};
31653164

31663165
if (f2fs_lookup_age_extent_cache(inode, pgofs, &ei)) {
31673166
if (!ei.age)
@@ -5138,11 +5137,9 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
51385137

51395138
init_f2fs_rwsem(&sm_info->curseg_lock);
51405139

5141-
if (!f2fs_readonly(sbi->sb)) {
5142-
err = f2fs_create_flush_cmd_control(sbi);
5143-
if (err)
5144-
return err;
5145-
}
5140+
err = f2fs_create_flush_cmd_control(sbi);
5141+
if (err)
5142+
return err;
51465143

51475144
err = create_discard_cmd_control(sbi);
51485145
if (err)

0 commit comments

Comments
 (0)