| From 085aa9f46f24a83208a039bb164f124d6a398bbf Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 10 May 2021 17:30:32 +0800 |
| Subject: f2fs: compress: fix to assign cc.cluster_idx correctly |
| |
| From: Chao Yu <yuchao0@huawei.com> |
| |
| [ Upstream commit 8bfbfb0ddd706b1ce2e89259ecc45f192c0ec2bf ] |
| |
| In f2fs_destroy_compress_ctx(), after f2fs_destroy_compress_ctx(), |
| cc.cluster_idx will be cleared w/ NULL_CLUSTER, f2fs_cluster_blocks() |
| may check wrong cluster metadata, fix it. |
| |
| Fixes: 4c8ff7095bef ("f2fs: support data compression") |
| Signed-off-by: Chao Yu <yuchao0@huawei.com> |
| Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/f2fs/compress.c | 17 +++++++++-------- |
| fs/f2fs/data.c | 6 +++--- |
| fs/f2fs/f2fs.h | 2 +- |
| 3 files changed, 13 insertions(+), 12 deletions(-) |
| |
| diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c |
| index 58eb5eefe268..f94b13075ea4 100644 |
| --- a/fs/f2fs/compress.c |
| +++ b/fs/f2fs/compress.c |
| @@ -151,13 +151,14 @@ int f2fs_init_compress_ctx(struct compress_ctx *cc) |
| return cc->rpages ? 0 : -ENOMEM; |
| } |
| |
| -void f2fs_destroy_compress_ctx(struct compress_ctx *cc) |
| +void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse) |
| { |
| page_array_free(cc->inode, cc->rpages, cc->cluster_size); |
| cc->rpages = NULL; |
| cc->nr_rpages = 0; |
| cc->nr_cpages = 0; |
| - cc->cluster_idx = NULL_CLUSTER; |
| + if (!reuse) |
| + cc->cluster_idx = NULL_CLUSTER; |
| } |
| |
| void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page) |
| @@ -984,7 +985,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, |
| ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size, |
| &last_block_in_bio, false, true); |
| f2fs_put_rpages(cc); |
| - f2fs_destroy_compress_ctx(cc); |
| + f2fs_destroy_compress_ctx(cc, true); |
| if (ret) |
| goto out; |
| if (bio) |
| @@ -1011,7 +1012,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, |
| release_and_retry: |
| f2fs_put_rpages(cc); |
| f2fs_unlock_rpages(cc, i + 1); |
| - f2fs_destroy_compress_ctx(cc); |
| + f2fs_destroy_compress_ctx(cc, true); |
| goto retry; |
| } |
| } |
| @@ -1044,7 +1045,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, |
| unlock_pages: |
| f2fs_put_rpages(cc); |
| f2fs_unlock_rpages(cc, i); |
| - f2fs_destroy_compress_ctx(cc); |
| + f2fs_destroy_compress_ctx(cc, true); |
| out: |
| return ret; |
| } |
| @@ -1080,7 +1081,7 @@ bool f2fs_compress_write_end(struct inode *inode, void *fsdata, |
| set_cluster_dirty(&cc); |
| |
| f2fs_put_rpages_wbc(&cc, NULL, false, 1); |
| - f2fs_destroy_compress_ctx(&cc); |
| + f2fs_destroy_compress_ctx(&cc, false); |
| |
| return first_index; |
| } |
| @@ -1299,7 +1300,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, |
| f2fs_put_rpages(cc); |
| page_array_free(cc->inode, cc->cpages, cc->nr_cpages); |
| cc->cpages = NULL; |
| - f2fs_destroy_compress_ctx(cc); |
| + f2fs_destroy_compress_ctx(cc, false); |
| return 0; |
| |
| out_destroy_crypt: |
| @@ -1461,7 +1462,7 @@ int f2fs_write_multi_pages(struct compress_ctx *cc, |
| err = f2fs_write_raw_pages(cc, submitted, wbc, io_type); |
| f2fs_put_rpages_wbc(cc, wbc, false, 0); |
| destroy_out: |
| - f2fs_destroy_compress_ctx(cc); |
| + f2fs_destroy_compress_ctx(cc, false); |
| return err; |
| } |
| |
| diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c |
| index 901bd1d963ee..bdc0f3b2d7ab 100644 |
| --- a/fs/f2fs/data.c |
| +++ b/fs/f2fs/data.c |
| @@ -2419,7 +2419,7 @@ static int f2fs_mpage_readpages(struct inode *inode, |
| max_nr_pages, |
| &last_block_in_bio, |
| rac != NULL, false); |
| - f2fs_destroy_compress_ctx(&cc); |
| + f2fs_destroy_compress_ctx(&cc, false); |
| if (ret) |
| goto set_error_page; |
| } |
| @@ -2464,7 +2464,7 @@ static int f2fs_mpage_readpages(struct inode *inode, |
| max_nr_pages, |
| &last_block_in_bio, |
| rac != NULL, false); |
| - f2fs_destroy_compress_ctx(&cc); |
| + f2fs_destroy_compress_ctx(&cc, false); |
| } |
| } |
| #endif |
| @@ -3168,7 +3168,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, |
| } |
| } |
| if (f2fs_compressed_file(inode)) |
| - f2fs_destroy_compress_ctx(&cc); |
| + f2fs_destroy_compress_ctx(&cc, false); |
| #endif |
| if (retry) { |
| index = 0; |
| diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h |
| index 036d2a3a2f41..69a390c6064c 100644 |
| --- a/fs/f2fs/f2fs.h |
| +++ b/fs/f2fs/f2fs.h |
| @@ -3856,7 +3856,7 @@ void f2fs_free_dic(struct decompress_io_ctx *dic); |
| void f2fs_decompress_end_io(struct page **rpages, |
| unsigned int cluster_size, bool err, bool verity); |
| int f2fs_init_compress_ctx(struct compress_ctx *cc); |
| -void f2fs_destroy_compress_ctx(struct compress_ctx *cc); |
| +void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); |
| void f2fs_init_compress_info(struct f2fs_sb_info *sbi); |
| int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi); |
| void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi); |
| -- |
| 2.30.2 |
| |