Chao Yu (3): f2fs: fix to stop filesystem update once CP failed f2fs: reduce stack memory cost by using bitfield in struct f2fs_io_info f2fs: compress: fix to cover normal cluster write with cp_rwsem
NeilBrown (1): f2fs: replace congestion_wait() calls with io_schedule_timeout()
fs/f2fs/f2fs.h | 26 ++++++++++++++++---------- fs/f2fs/checkpoint.c | 18 ++++++++++++------ fs/f2fs/compress.c | 36 ++++++++++++++++++++++-------------- fs/f2fs/data.c | 16 ++++++++-------- fs/f2fs/gc.c | 8 ++++---- fs/f2fs/node.c | 2 +- fs/f2fs/segment.c | 25 +++++++++++++++++-------- fs/f2fs/super.c | 6 ++---- 8 files changed, 82 insertions(+), 55 deletions(-)
From: Chao Yu chao@kernel.org
mainline inclusion from mainline-v5.15-rc1 commit 91803392c732c43b5cf440e885ea89be7f5fecef category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9NO CVE: CVE-2024-27034
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
During f2fs_write_checkpoint(), once we failed in f2fs_flush_nat_entries() or do_checkpoint(), metadata of filesystem such as prefree bitmap, nat/sit version bitmap won't be recovered, it may cause f2fs image to be inconsistent, let's just set CP error flag to avoid further updates until we figure out a scheme to rollback all metadatas in such condition.
Reported-by: Yangtao Li frank.li@vivo.com Signed-off-by: Yangtao Li frank.li@vivo.com Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/f2fs/f2fs.h | 2 +- fs/f2fs/checkpoint.c | 12 +++++++++--- fs/f2fs/segment.c | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 154d6fa2f4c0..26f12d9f7776 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -518,7 +518,7 @@ enum { */ };
-#define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO count */ +#define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO or flush count */
/* congestion wait timeout value, default: 20ms */ #define DEFAULT_IO_TIMEOUT (msecs_to_jiffies(20)) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 8a94bf3611d3..19484d6a0acc 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1645,8 +1645,11 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
/* write cached NAT/SIT entries to NAT/SIT area */ err = f2fs_flush_nat_entries(sbi, cpc); - if (err) + if (err) { + f2fs_err(sbi, "f2fs_flush_nat_entries failed err:%d, stop checkpoint", err); + f2fs_bug_on(sbi, !f2fs_cp_error(sbi)); goto stop; + }
f2fs_flush_sit_entries(sbi, cpc);
@@ -1654,10 +1657,13 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_save_inmem_curseg(sbi);
err = do_checkpoint(sbi, cpc); - if (err) + if (err) { + f2fs_err(sbi, "do_checkpoint failed err:%d, stop checkpoint", err); + f2fs_bug_on(sbi, !f2fs_cp_error(sbi)); f2fs_release_discard_addrs(sbi); - else + } else { f2fs_clear_prefree_segments(sbi, cpc); + }
f2fs_restore_inmem_curseg(sbi); stop: diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index b87de275a357..c5c011ee0429 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -777,11 +777,22 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) return 0;
for (i = 1; i < sbi->s_ndevs; i++) { + int count = DEFAULT_RETRY_IO_COUNT; + if (!f2fs_test_bit(i, (char *)&sbi->dirty_device)) continue; - ret = __submit_flush_wait(sbi, FDEV(i).bdev); - if (ret) + + do { + ret = __submit_flush_wait(sbi, FDEV(i).bdev); + if (ret) + congestion_wait(BLK_RW_ASYNC, + DEFAULT_IO_TIMEOUT); + } while (ret && --count); + + if (ret) { + f2fs_stop_checkpoint(sbi, false); break; + }
spin_lock(&sbi->dev_lock); f2fs_clear_bit(i, (char *)&sbi->dirty_device);
From: NeilBrown neilb@suse.de
mainline inclusion from mainline-v5.18-rc1 commit a64239d0ef345208d8c15d7841a028a43a34c068 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9NO CVE: CVE-2024-27034
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
As congestion is no longer tracked, congestion_wait() is effectively equivalent to io_schedule_timeout().
So introduce f2fs_io_schedule_timeout() which sets TASK_UNINTERRUPTIBLE and call that instead.
Link: https://lkml.kernel.org/r/164549983744.9187.6425865370954230902.stgit@noble.... Signed-off-by: NeilBrown neilb@suse.de Cc: Anna Schumaker Anna.Schumaker@Netapp.com Cc: Chao Yu chao@kernel.org Cc: Darrick J. Wong djwong@kernel.org Cc: Ilya Dryomov idryomov@gmail.com Cc: Jaegeuk Kim jaegeuk@kernel.org Cc: Jan Kara jack@suse.cz Cc: Jeff Layton jlayton@kernel.org Cc: Jens Axboe axboe@kernel.dk Cc: Lars Ellenberg lars.ellenberg@linbit.com Cc: Miklos Szeredi miklos@szeredi.hu Cc: Paolo Valente paolo.valente@linaro.org Cc: Philipp Reisner philipp.reisner@linbit.com Cc: Ryusuke Konishi konishi.ryusuke@gmail.com Cc: Trond Myklebust trond.myklebust@hammerspace.com Cc: Wu Fengguang fengguang.wu@intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/f2fs/f2fs.h | 6 ++++++ fs/f2fs/compress.c | 4 +--- fs/f2fs/data.c | 3 +-- fs/f2fs/segment.c | 8 +++----- fs/f2fs/super.c | 6 ++---- 5 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 26f12d9f7776..fdfb13285291 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4155,6 +4155,12 @@ static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi, F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1))); }
+static inline void f2fs_io_schedule_timeout(long timeout) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + io_schedule_timeout(timeout); +} + #define EFSBADCRC EBADMSG /* Bad CRC detected */ #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index c99f1cc5c449..17223e75bd64 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1418,9 +1418,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, if (IS_NOQUOTA(cc->inode)) return 0; ret = 0; - cond_resched(); - congestion_wait(BLK_RW_ASYNC, - DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto retry_write; } return ret; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index c0c30a32fd59..38efd3237463 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3152,8 +3152,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, } else if (ret == -EAGAIN) { ret = 0; if (wbc->sync_mode == WB_SYNC_ALL) { - cond_resched(); - congestion_wait(BLK_RW_ASYNC, + f2fs_io_schedule_timeout( DEFAULT_IO_TIMEOUT); goto retry_write; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c5c011ee0429..428ad5b718c8 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -313,8 +313,7 @@ void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure) skip: iput(inode); } - congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); - cond_resched(); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); if (gc_failure) { if (++looped >= count) return; @@ -785,8 +784,7 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) do { ret = __submit_flush_wait(sbi, FDEV(i).bdev); if (ret) - congestion_wait(BLK_RW_ASYNC, - DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); } while (ret && --count);
if (ret) { @@ -3068,7 +3066,7 @@ static unsigned int __issue_discard_cmd_range(struct f2fs_sb_info *sbi, blk_finish_plug(&plug); mutex_unlock(&dcc->cmd_lock); trimmed += __wait_all_discard_cmd(sbi, NULL); - congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto next; } skip: diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 9a74d60f61db..6a214366970c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1808,8 +1808,7 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) /* we should flush all the data to keep data consistency */ do { sync_inodes_sb(sbi->sb); - cond_resched(); - congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); } while (get_pages(sbi, F2FS_DIRTY_DATA) && retry--);
if (unlikely(retry < 0)) @@ -2099,8 +2098,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, &page, &fsdata); if (unlikely(err)) { if (err == -ENOMEM) { - congestion_wait(BLK_RW_ASYNC, - DEFAULT_IO_TIMEOUT); + f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto retry; } set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR);
From: Chao Yu chao@kernel.org
mainline inclusion from mainline-v6.3-rc1 commit 2eae077e6e46f9046d383631145750e043820dce category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9NO CVE: CVE-2024-27034
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
This patch tries to use bitfield in struct f2fs_io_info to improve memory usage.
struct f2fs_io_info { ... unsigned int need_lock:8; /* indicate we need to lock cp_rwsem */ unsigned int version:8; /* version of the node */ unsigned int submitted:1; /* indicate IO submission */ unsigned int in_list:1; /* indicate fio is in io_list */ unsigned int is_por:1; /* indicate IO is from recovery or not */ unsigned int retry:1; /* need to reallocate block address */ unsigned int encrypted:1; /* indicate file is encrypted */ unsigned int post_read:1; /* require post read */ ... };
After this patch, size of struct f2fs_io_info reduces from 136 to 120.
[Nathan: fix a compile warning (single-bit-bitfield-constant-conversion)] Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/f2fs/f2fs.h | 18 +++++++++--------- fs/f2fs/checkpoint.c | 6 +++--- fs/f2fs/compress.c | 5 +++-- fs/f2fs/data.c | 10 +++++----- fs/f2fs/gc.c | 8 ++++---- fs/f2fs/node.c | 2 +- fs/f2fs/segment.c | 6 +++--- 7 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index fdfb13285291..42f8b336eb57 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1111,19 +1111,19 @@ struct f2fs_io_info { struct page *encrypted_page; /* encrypted page */ struct page *compressed_page; /* compressed page */ struct list_head list; /* serialize IOs */ - bool submitted; /* indicate IO submission */ - int need_lock; /* indicate we need to lock cp_rwsem */ - bool in_list; /* indicate fio is in io_list */ - bool is_por; /* indicate IO is from recovery or not */ - bool retry; /* need to reallocate block address */ - int compr_blocks; /* # of compressed block addresses */ - bool encrypted; /* indicate file is encrypted */ - bool post_read; /* require post read */ + unsigned int compr_blocks; /* # of compressed block addresses */ + unsigned int need_lock:8; /* indicate we need to lock cp_rwsem */ + unsigned int version:8; /* version of the node */ + unsigned int submitted:1; /* indicate IO submission */ + unsigned int in_list:1; /* indicate fio is in io_list */ + unsigned int is_por:1; /* indicate IO is from recovery or not */ + unsigned int retry:1; /* need to reallocate block address */ + unsigned int encrypted:1; /* indicate file is encrypted */ + unsigned int post_read:1; /* require post read */ enum iostat_type io_type; /* io type */ struct writeback_control *io_wbc; /* writeback control */ struct bio **bio; /* bio for ipu */ sector_t *last_block; /* last block number in bio */ - unsigned char version; /* version of the node */ };
struct bio_entry { diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 19484d6a0acc..c41f72a141b9 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -63,7 +63,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, .old_blkaddr = index, .new_blkaddr = index, .encrypted_page = NULL, - .is_por = !is_meta, + .is_por = !is_meta ? 1 : 0, }; int err;
@@ -226,8 +226,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, .op = REQ_OP_READ, .op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD, .encrypted_page = NULL, - .in_list = false, - .is_por = (type == META_POR), + .in_list = 0, + .is_por = (type == META_POR) ? 1 : 0, }; struct blk_plug plug; int err; diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 17223e75bd64..2bb556a3c00b 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1152,10 +1152,11 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, .page = NULL, .encrypted_page = NULL, .compressed_page = NULL, - .submitted = false, + .submitted = 0, .io_type = io_type, .io_wbc = wbc, - .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode), + .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ? + 1 : 0, }; struct dnode_of_data dn; struct node_info ni; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 38efd3237463..8d0a45489d4c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -972,7 +972,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) bio_page = fio->page;
/* set submitted = true as a return value */ - fio->submitted = true; + fio->submitted = 1;
type = WB_DATA_TYPE(bio_page, fio->compressed_page); inc_page_count(sbi, type); @@ -990,7 +990,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) { dec_page_count(sbi, WB_DATA_TYPE(bio_page, fio->compressed_page)); - fio->retry = true; + fio->retry = 1; goto skip; } io->bio = __bio_alloc(fio, BIO_MAX_PAGES); @@ -2795,10 +2795,10 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, .old_blkaddr = NULL_ADDR, .page = page, .encrypted_page = NULL, - .submitted = false, + .submitted = 0, .compr_blocks = compr_blocks, .need_lock = LOCK_RETRY, - .post_read = f2fs_post_read_required(inode), + .post_read = f2fs_post_read_required(inode) ? 1 : 0, .io_type = io_type, .io_wbc = wbc, .bio = bio, @@ -2926,7 +2926,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, }
if (submitted) - *submitted = fio.submitted ? 1 : 0; + *submitted = fio.submitted;
return 0;
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 65f1363b3608..1a6122628ec3 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1056,8 +1056,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index) .op = REQ_OP_READ, .op_flags = 0, .encrypted_page = NULL, - .in_list = false, - .retry = false, + .in_list = 0, + .retry = 0, }; int err;
@@ -1143,8 +1143,8 @@ static int move_data_block(struct inode *inode, block_t bidx, .op = REQ_OP_READ, .op_flags = 0, .encrypted_page = NULL, - .in_list = false, - .retry = false, + .in_list = 0, + .retry = 0, }; struct dnode_of_data dn; struct f2fs_summary sum; diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 02cb1c806c3e..62af4c40eae2 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1525,7 +1525,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, .op_flags = wbc_to_write_flags(wbc), .page = page, .encrypted_page = NULL, - .submitted = false, + .submitted = 0, .io_type = io_type, .io_wbc = wbc, }; diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 428ad5b718c8..707ffdb5e48e 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3430,10 +3430,10 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, struct f2fs_bio_info *io;
if (F2FS_IO_ALIGNED(sbi)) - fio->retry = false; + fio->retry = 0;
INIT_LIST_HEAD(&fio->list); - fio->in_list = true; + fio->in_list = 1; io = sbi->write_io[fio->type] + fio->temp; spin_lock(&io->io_lock); list_add_tail(&fio->list, &io->io_list); @@ -3505,7 +3505,7 @@ void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page, .new_blkaddr = page->index, .page = page, .encrypted_page = NULL, - .in_list = false, + .in_list = 0, };
if (unlikely(page->index >= MAIN_BLKADDR(sbi)))
From: Chao Yu chao@kernel.org
stable inclusion from stable-v6.8.2 commit 52982edfcefd475cc34af663d5c47c0cddaa5739 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9NO CVE: CVE-2024-27034
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit fd244524c2cf07b5f4c3fe8abd6a99225c76544b ]
When we overwrite compressed cluster w/ normal cluster, we should not unlock cp_rwsem during f2fs_write_raw_pages(), otherwise data will be corrupted if partial blocks were persisted before CP & SPOR, due to cluster metadata wasn't updated atomically.
Fixes: 4c8ff7095bef ("f2fs: support data compression") Reviewed-by: Daeho Jeong daehojeong@google.com Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/f2fs/compress.c | 27 ++++++++++++++++++--------- fs/f2fs/data.c | 3 ++- 2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 2bb556a3c00b..200843f1f44c 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1359,12 +1359,14 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page) }
static int f2fs_write_raw_pages(struct compress_ctx *cc, - int *submitted, + int *submitted_p, struct writeback_control *wbc, enum iostat_type io_type) { struct address_space *mapping = cc->inode->i_mapping; - int _submitted, compr_blocks, ret, i; + struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); + int submitted, compr_blocks, i; + int ret = 0;
compr_blocks = f2fs_compressed_blocks(cc);
@@ -1379,6 +1381,10 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, if (compr_blocks < 0) return compr_blocks;
+ /* overwrite compressed cluster w/ normal cluster */ + if (compr_blocks > 0) + f2fs_lock_op(sbi); + for (i = 0; i < cc->cluster_size; i++) { if (!cc->rpages[i]) continue; @@ -1403,7 +1409,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, if (!clear_page_dirty_for_io(cc->rpages[i])) goto continue_unlock;
- ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted, + ret = f2fs_write_single_data_page(cc->rpages[i], &submitted, NULL, NULL, wbc, io_type, compr_blocks, false); if (ret) { @@ -1411,26 +1417,29 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, unlock_page(cc->rpages[i]); ret = 0; } else if (ret == -EAGAIN) { + ret = 0; /* * for quota file, just redirty left pages to * avoid deadlock caused by cluster update race * from foreground operation. */ if (IS_NOQUOTA(cc->inode)) - return 0; - ret = 0; + goto out; f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); goto retry_write; } - return ret; + goto out; }
- *submitted += _submitted; + *submitted_p += submitted; }
- f2fs_balance_fs(F2FS_M_SB(mapping), true); +out: + if (compr_blocks > 0) + f2fs_unlock_op(sbi);
- return 0; + f2fs_balance_fs(sbi, true); + return ret; }
int f2fs_write_multi_pages(struct compress_ctx *cc, diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8d0a45489d4c..18c031a0bf56 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2797,7 +2797,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, .encrypted_page = NULL, .submitted = 0, .compr_blocks = compr_blocks, - .need_lock = LOCK_RETRY, + .need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY, .post_read = f2fs_post_read_required(inode) ? 1 : 0, .io_type = io_type, .io_wbc = wbc, @@ -2882,6 +2882,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, if (err == -EAGAIN) { err = f2fs_do_write_data_page(&fio); if (err == -EAGAIN) { + f2fs_bug_on(sbi, compr_blocks); fio.need_lock = LOCK_REQ; err = f2fs_do_write_data_page(&fio); }
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/7040 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/X...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/7040 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/X...