mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-08 15:04:45 +00:00
f2fs-fix-6.2-rc3
This series fixes the below three bugs introduced in 6.2-rc1. - 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. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE00UqedjCtOrGVvQiQBSofoJIUNIFAmO1xyMACgkQQBSofoJI UNLivg//T7APr6AMyG59vmQv1Yzz0g1ZMCnkZ0cdBYBYgam0bwLtAgVFPfFfWc0q 1E5xqAIlxLjSZ/r9cZcOkTx9wq0De1Htgn5LhflsMrX0xyUYmldQH7uXx+m7nV2y kMZ1QyIc7IT7MNP/FdiZnGtnD+amKj0D/pF0rXUYIrr6uwpyDX/lJ2sEJlUQcFuM cJ2qAltRNaQumOYcCC1T+jS31fWUQw3DZYbaUi7pS7g7Y8js5xV1fGpPCvfLBcyf bBj48ynUSmH5nv4RI2wI0V12/naJNjvzhDCXHO0EM//ruHS86yspnyE2ywpZNKx0 MQ3aIwG0eKtCFX6Rdg+rVeqIg+eMoXCisIDuY0KY2TMPlwYWEsnMn1UqCp3uN8d0 yCR5BI7u4JeH11scuATz4lH9ffsIZbNUxQdpQnCOISO4eCYHQwfblYRvUddENLT7 J9vljgVJvX7aDw2V8ErRGw0OLa5HuWz+7tRkVmYWm/LHOquyt5ZXxDyWrEHrLGiq 6btAiHUrCa9ugT3jq2ub3CV7bkrUaw0G0LSsYYb5lCK62g6KMQzFpLQ+4MwrWla7 vIiidlzWmxg/lSpDeRpR1ybuGSPZ9/5iHNTaVHd4kgrWK2Zt3CDKj2fMPnCKPVZ8 diq1TuVKPbE/K4+zVQACRk2udkzSpwEVkum4awhKdIErlZ0kr04= =yV+N -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
2ac44821a8
@ -2183,7 +2183,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
|
||||
sector_t last_block_in_file;
|
||||
const unsigned blocksize = blks_to_bytes(inode, 1);
|
||||
struct decompress_io_ctx *dic = NULL;
|
||||
struct extent_info ei = {0, };
|
||||
struct extent_info ei = {};
|
||||
bool from_dnode = true;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
@ -546,7 +546,8 @@ static bool __lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
|
||||
struct extent_node *en;
|
||||
bool ret = false;
|
||||
|
||||
f2fs_bug_on(sbi, !et);
|
||||
if (!et)
|
||||
return false;
|
||||
|
||||
trace_f2fs_lookup_extent_tree_start(inode, pgofs, type);
|
||||
|
||||
@ -881,12 +882,14 @@ static unsigned long long __calculate_block_age(unsigned long long new,
|
||||
}
|
||||
|
||||
/* This returns a new age and allocated blocks in ei */
|
||||
static int __get_new_block_age(struct inode *inode, struct extent_info *ei)
|
||||
static int __get_new_block_age(struct inode *inode, struct extent_info *ei,
|
||||
block_t blkaddr)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
loff_t f_size = i_size_read(inode);
|
||||
unsigned long long cur_blocks =
|
||||
atomic64_read(&sbi->allocated_data_blocks);
|
||||
struct extent_info tei = *ei; /* only fofs and len are valid */
|
||||
|
||||
/*
|
||||
* When I/O is not aligned to a PAGE_SIZE, update will happen to the last
|
||||
@ -894,20 +897,20 @@ static int __get_new_block_age(struct inode *inode, struct extent_info *ei)
|
||||
* block here.
|
||||
*/
|
||||
if ((f_size >> PAGE_SHIFT) == ei->fofs && f_size & (PAGE_SIZE - 1) &&
|
||||
ei->blk == NEW_ADDR)
|
||||
blkaddr == NEW_ADDR)
|
||||
return -EINVAL;
|
||||
|
||||
if (__lookup_extent_tree(inode, ei->fofs, ei, EX_BLOCK_AGE)) {
|
||||
if (__lookup_extent_tree(inode, ei->fofs, &tei, EX_BLOCK_AGE)) {
|
||||
unsigned long long cur_age;
|
||||
|
||||
if (cur_blocks >= ei->last_blocks)
|
||||
cur_age = cur_blocks - ei->last_blocks;
|
||||
if (cur_blocks >= tei.last_blocks)
|
||||
cur_age = cur_blocks - tei.last_blocks;
|
||||
else
|
||||
/* allocated_data_blocks overflow */
|
||||
cur_age = ULLONG_MAX - ei->last_blocks + cur_blocks;
|
||||
cur_age = ULLONG_MAX - tei.last_blocks + cur_blocks;
|
||||
|
||||
if (ei->age)
|
||||
ei->age = __calculate_block_age(cur_age, ei->age);
|
||||
if (tei.age)
|
||||
ei->age = __calculate_block_age(cur_age, tei.age);
|
||||
else
|
||||
ei->age = cur_age;
|
||||
ei->last_blocks = cur_blocks;
|
||||
@ -915,14 +918,14 @@ static int __get_new_block_age(struct inode *inode, struct extent_info *ei)
|
||||
return 0;
|
||||
}
|
||||
|
||||
f2fs_bug_on(sbi, ei->blk == NULL_ADDR);
|
||||
f2fs_bug_on(sbi, blkaddr == NULL_ADDR);
|
||||
|
||||
/* the data block was allocated for the first time */
|
||||
if (ei->blk == NEW_ADDR)
|
||||
if (blkaddr == NEW_ADDR)
|
||||
goto out;
|
||||
|
||||
if (__is_valid_data_blkaddr(ei->blk) &&
|
||||
!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE)) {
|
||||
if (__is_valid_data_blkaddr(blkaddr) &&
|
||||
!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) {
|
||||
f2fs_bug_on(sbi, 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -938,7 +941,7 @@ static int __get_new_block_age(struct inode *inode, struct extent_info *ei)
|
||||
|
||||
static void __update_extent_cache(struct dnode_of_data *dn, enum extent_type type)
|
||||
{
|
||||
struct extent_info ei;
|
||||
struct extent_info ei = {};
|
||||
|
||||
if (!__may_extent_tree(dn->inode, type))
|
||||
return;
|
||||
@ -953,8 +956,7 @@ static void __update_extent_cache(struct dnode_of_data *dn, enum extent_type typ
|
||||
else
|
||||
ei.blk = dn->data_blkaddr;
|
||||
} else if (type == EX_BLOCK_AGE) {
|
||||
ei.blk = dn->data_blkaddr;
|
||||
if (__get_new_block_age(dn->inode, &ei))
|
||||
if (__get_new_block_age(dn->inode, &ei, dn->data_blkaddr))
|
||||
return;
|
||||
}
|
||||
__update_extent_tree_range(dn->inode, &ei, type);
|
||||
|
@ -2559,7 +2559,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
|
||||
struct f2fs_map_blocks map = { .m_next_extent = NULL,
|
||||
.m_seg_type = NO_CHECK_TYPE,
|
||||
.m_may_create = false };
|
||||
struct extent_info ei = {0, };
|
||||
struct extent_info ei = {};
|
||||
pgoff_t pg_start, pg_end, next_pgofs;
|
||||
unsigned int blk_per_seg = sbi->blocks_per_seg;
|
||||
unsigned int total = 0, sec_num;
|
||||
|
@ -663,8 +663,7 @@ int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi)
|
||||
if (IS_ERR(fcc->f2fs_issue_flush)) {
|
||||
int err = PTR_ERR(fcc->f2fs_issue_flush);
|
||||
|
||||
kfree(fcc);
|
||||
SM_I(sbi)->fcc_info = NULL;
|
||||
fcc->f2fs_issue_flush = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3161,7 +3160,7 @@ static int __get_segment_type_4(struct f2fs_io_info *fio)
|
||||
static int __get_age_segment_type(struct inode *inode, pgoff_t pgofs)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct extent_info ei;
|
||||
struct extent_info ei = {};
|
||||
|
||||
if (f2fs_lookup_age_extent_cache(inode, pgofs, &ei)) {
|
||||
if (!ei.age)
|
||||
@ -5138,11 +5137,9 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
|
||||
|
||||
init_f2fs_rwsem(&sm_info->curseg_lock);
|
||||
|
||||
if (!f2fs_readonly(sbi->sb)) {
|
||||
err = f2fs_create_flush_cmd_control(sbi);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
err = f2fs_create_flush_cmd_control(sbi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = create_discard_cmd_control(sbi);
|
||||
if (err)
|
||||
|
Loading…
Reference in New Issue
Block a user