fsverity: stop using PG_error to track error status
Subsystems (5)
Eric Biggers
maintainerPATCH v4 1/1 fsverity: stop using PG_error to track error status
From: Eric Biggers <[email protected]>
As a step towards freeing the PG_error flag for other uses, change ext4 and f2fs to stop using PG_error to track verity errors. Instead, if a verity error occurs, just mark the whole bio as failed. The coarser granularity isn't really a problem since it isn't any worse than what the block layer provides, and errors from a multi-page readahead aren't reported to applications unless a single-page read fails too.
f2fs supports compression, which makes the f2fs changes a bit more complicated than desired, but the basic premise still works.
Note: there are still a few uses of PageError in f2fs, but they are on the write path, so they are unrelated and this patch doesn't touch them.
---
v4: Added a comment for decompression_attempted, added a paragraph to
the commit message, and added Chao's Reviewed-by.
v3: made a small simplification to the f2fs changes. Also dropped the
fscrypt patch since it is upstream now.
fs/ext4/readpage.c | 8 ++---- fs/f2fs/compress.c | 64 ++++++++++++++++++++++------------------------ fs/f2fs/data.c | 53 +++++++++++++++++++++++--------------- fs/verity/verify.c | 12 ++++----- 4 files changed, 72 insertions(+), 65 deletions(-)
fs/ext4/readpage.c +2 -6
@@ -75,14 +75,10 @@ static void __read_end_io(struct bio *bio)bio_for_each_segment_all (bv, bio, iter_all) { page = bv->bv_page; -/* PG_error was set if verity failed. */ -if (bio->bi_status ||PageError (page)) { +if (bio->bi_status)ClearPageUptodate (page); -/* will re-read again later */ -ClearPageError (page); - }else { +else SetPageUptodate (page); - }unlock_page (page); }if (bio->bi_private)
fs/f2fs/compress.c +31 -33
96 lines not on this page · raw message
fs/f2fs/data.c +33 -20
131 lines not on this page · raw message
fs/verity/verify.c +6 -6
@@ -200,9 +200,8 @@ EXPORT_SYMBOL_GPL(fsverity_verify_page);* @bio: the bio to verify * * Verify a set of pages that have just been read from a verity file. The pages -* must be pagecache pages that are still locked and not yet uptodate. Pages -* that fail verification are set to the Error state. Verification is skipped -* for pages already in the Error state, e.g. due to fscrypt decryption failure. +* must be pagecache pages that are still locked and not yet uptodate. If a +* page fails verification, then bio->bi_status is set to an error status. * * This is a helper function for use by the ->readahead() method of filesystems * that issue bios to read data directly into the page cache. Filesystems that
@@ -244,9 +243,10 @@ void fsverity_verify_bio(struct bio *bio)unsigned long level0_ra_pages =min (max_ra_pages, params->level0_blocks - level0_index); -if (!PageError (page) && - !verify_page (inode, vi, req, page, level0_ra_pages)) -SetPageError (page); +if (!verify_page (inode, vi, req, page, level0_ra_pages)) { + bio->bi_status =BLK_STS_IOERR ; +break ; + } }fsverity_free_hash_request (params->hash_alg, req);
base-commit: f0c4d9fc9cc9462659728d168387191387e903cc
Signature · 1 line
2.38.1
Quoted 9 lines · Eric Biggers
From: Eric Biggers <[email protected]>
As a step towards freeing the
PG_errorflag for other uses, change ext4 and f2fs to stop usingPG_errorto track verity errors. Instead, if a verity error occurs, just mark the whole bio as failed. The coarser granularity isn't really a problem since it isn't any worse than what the block layer provides, and errors from a multi-page readahead aren't reported to applications unless a single-page read fails too.
Quoted 7 lines
f2fs supports compression, which makes the f2fs changes a bit more complicated than desired, but the basic premise still works.
Note: there are still a few uses of PageError in f2fs, but they are on the write path, so they are unrelated and this patch doesn't touch them.
Reviewed-by Chao Yu <[email protected]>
Thanks,
Quoted 314 lines
Signed-off-by Eric Biggers <[email protected]>---
v4: Added a comment for
decompression_attempted, added a paragraph to
the commit message, and added Chao's Reviewed-by.v3: made a small simplification to the f2fs changes. Also dropped the
fscrypt patch since it is upstream now.fs/ext4/readpage.c | 8 ++---- fs/f2fs/compress.c | 64 ++++++++++++++++++++++------------------------ fs/f2fs/data.c | 53 +++++++++++++++++++++++--------------- fs/verity/verify.c | 12 ++++----- 4 files changed, 72 insertions(+), 65 deletions(-)fs/ext4/readpage.c +2
-6@@ -75,14 +75,10 @@ static void __read_end_io(struct bio *bio)bio_for_each_segment_all (bv, bio, iter_all) { page = bv->bv_page; -/* PG_error was set if verity failed. */ -if (bio->bi_status ||PageError (page)) { +if (bio->bi_status)ClearPageUptodate (page); -/* will re-read again later */ -ClearPageError (page); - }else { +else SetPageUptodate (page); - }unlock_page (page); }if (bio->bi_private)fs/f2fs/compress.c +31
-33@@ -1711,50 +1711,27 @@ static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task) } } -/* -* Update and unlock the cluster's pagecache pages, and release the reference to -* the decompress_io_ctx that was being held for I/O completion. -*/ -static void __f2fs_decompress_end_io (struct decompress_io_ctx *dic,bool failed, -bool in_task) +static void f2fs_verify_cluster (struct work_struct *work) { +struct decompress_io_ctx *dic = + container_of(work, struct decompress_io_ctx, verity_work);int i; +/* Verify, update, and unlock the decompressed pages. */ for (i =0 ; i < dic->cluster_size; i++) {struct page *rpage = dic->rpages[i];if (!rpage)continue ; -/* PG_error was set if verity failed. */ -if (failed ||PageError (rpage)) { -ClearPageUptodate (rpage); -/* will re-read again later */ -ClearPageError (rpage); - }else { +if (fsverity_verify_page (rpage))SetPageUptodate (rpage); - } +else +ClearPageUptodate (rpage);unlock_page (rpage); } -f2fs_put_dic (dic, in_task); -} - -static void f2fs_verify_cluster (struct work_struct *work) -{ -struct decompress_io_ctx *dic = - container_of(work, struct decompress_io_ctx, verity_work); -int i; - -/* Verify the cluster's decompressed pages with fs-verity. */ -for (i =0 ; i < dic->cluster_size; i++) { -struct page *rpage = dic->rpages[i]; - -if (rpage && !fsverity_verify_page (rpage)) -SetPageError (rpage); - } - -__f2fs_decompress_end_io (dic, false, true); +f2fs_put_dic (dic, true); }/* @@ -1764,6 +1741,8 @@ static void f2fs_verify_cluster(struct work_struct *work)void f2fs_decompress_end_io (struct decompress_io_ctx *dic,bool failed,bool in_task) { +int i; +if (!failed && dic->need_verity) {/* * Note that to avoid deadlocks, the verity work can't be done @@ -1773,9 +1752,28 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,*/ INIT_WORK (&dic->verity_work, f2fs_verify_cluster);fsverity_enqueue_verify_work (&dic->verity_work); - }else { -__f2fs_decompress_end_io (dic, failed, in_task); +return ; + } + +/* Update and unlock the cluster's pagecache pages. */ +for (i =0 ; i < dic->cluster_size; i++) { +struct page *rpage = dic->rpages[i]; + +if (!rpage) +continue ; + +if (failed) +ClearPageUptodate (rpage); +else +SetPageUptodate (rpage); +unlock_page (rpage); } + +/* +* Release the reference to the decompress_io_ctx that was being held +* for I/O completion. +*/ +f2fs_put_dic (dic, in_task); }/* fs/f2fs/data.c +33
-20@@ -116,43 +116,56 @@ struct bio_post_read_ctx {struct f2fs_sb_info *sbi;struct work_struct work;unsigned int enabled_steps; +/* +* decompression_attempted keeps track of whether +* f2fs_end_read_compressed_page() has been called on the pages in the +* bio that belong to a compressed cluster yet. +*/ +bool decompression_attempted;block_t fs_blkaddr; }; +/* +* Update and unlock a bio's pages, and free the bio. +* +* This marks pages up-to-date only if there was no error in the bio (I/O error, +* decryption error, or verity error), as indicated by bio->bi_status. +* +* "Compressed pages" (pagecache pages backed by a compressed cluster on-disk) +* aren't marked up-to-date here, as decompression is done on a per-compression- +* cluster basis rather than a per-bio basis. Instead, we only must do two +* things for each compressed page here: call f2fs_end_read_compressed_page() +* with failed=true if an error occurred before it would have normally gotten +* called (i.e., I/O error or decryption error, but *not* verity error), and +* release the bio's reference to the decompress_io_ctx of the page's cluster. +*/ static void f2fs_finish_read_bio (struct bio *bio,bool in_task) {struct bio_vec *bv;struct bvec_iter_all iter_all; +struct bio_post_read_ctx *ctx = bio->bi_private; -/* -* Update and unlock the bio's pagecache pages, and put the -* decompression context for any compressed pages. -*/ bio_for_each_segment_all (bv, bio, iter_all) {struct page *page = bv->bv_page;if (f2fs_is_compressed_page (page)) { -if (bio->bi_status) +if (!ctx->decompression_attempted)f2fs_end_read_compressed_page (page, true,0 , in_task);f2fs_put_page_dic (page, in_task);continue ; } -/* PG_error was set if verity failed. */ -if (bio->bi_status ||PageError (page)) { +if (bio->bi_status)ClearPageUptodate (page); -/* will re-read again later */ -ClearPageError (page); - }else { +else SetPageUptodate (page); - }dec_page_count (F2FS_P_SB (page),__read_io_type (page));unlock_page (page); } -if (bio->bi_private) -mempool_free (bio->bi_private, bio_post_read_ctx_pool); +if (ctx) +mempool_free (ctx, bio_post_read_ctx_pool);bio_put (bio); }@@ -185,8 +198,10 @@ static void f2fs_verify_bio(struct work_struct *work)struct page *page = bv->bv_page;if (!f2fs_is_compressed_page (page) && - !fsverity_verify_page (page)) -SetPageError (page); + !fsverity_verify_page (page)) { + bio->bi_status =BLK_STS_IOERR ; +break ; + } } }else {fsverity_verify_bio (bio);@@ -245,6 +260,8 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx, blkaddr++; } + ctx->decompression_attempted = true; +/* * Optimization: if all the bio's pages are compressed, then scheduling * the per-bio verity work is unnecessary, as verity will be fully @@ -1062,6 +1079,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, ctx->sbi = sbi; ctx->enabled_steps = post_read_steps; ctx->fs_blkaddr = blkaddr; + ctx->decompression_attempted = false; bio->bi_private = ctx; }iostat_alloc_and_bind_ctx (sbi, bio, ctx);@@ -1089,7 +1107,6 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,bio_put (bio);return -EFAULT ; } -ClearPageError (page);inc_page_count (sbi,F2FS_RD_DATA );f2fs_update_iostat (sbi,NULL ,FS_DATA_READ_IO ,F2FS_BLKSIZE );__submit_bio (sbi, bio,DATA );@@ -2141,7 +2158,6 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,inc_page_count (F2FS_I_SB (inode),F2FS_RD_DATA );f2fs_update_iostat (F2FS_I_SB (inode),NULL ,FS_DATA_READ_IO ,F2FS_BLKSIZE ); -ClearPageError (page); *last_block_in_bio = block_nr; goto out; out:@@ -2289,7 +2305,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,inc_page_count (sbi,F2FS_RD_DATA );f2fs_update_iostat (sbi, inode,FS_DATA_READ_IO ,F2FS_BLKSIZE ); -ClearPageError (page); *last_block_in_bio = blkaddr; }@@ -2306,7 +2321,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,for (i =0 ; i < cc->cluster_size; i++) {if (cc->rpages[i]) {ClearPageUptodate (cc->rpages[i]); -ClearPageError (cc->rpages[i]);unlock_page (cc->rpages[i]); } }@@ -2403,7 +2417,6 @@ static int f2fs_mpage_readpages(struct inode *inode,#ifdef CONFIG_F2FS_FS_COMPRESSION set_error_page:#endif -SetPageError (page);zero_user_segment (page,0 ,PAGE_SIZE );unlock_page (page); }fs/verity/verify.c +6
-6@@ -200,9 +200,8 @@ EXPORT_SYMBOL_GPL(fsverity_verify_page);* @bio: the bio to verify * * Verify a set of pages that have just been read from a verity file. The pages -* must be pagecache pages that are still locked and not yet uptodate. Pages -* that fail verification are set to the Error state. Verification is skipped -* for pages already in the Error state, e.g. due to fscrypt decryption failure. +* must be pagecache pages that are still locked and not yet uptodate. If a +* page fails verification, then bio->bi_status is set to an error status. * * This is a helper function for use by the ->readahead() method of filesystems * that issue bios to read data directly into the page cache. Filesystems that @@ -244,9 +243,10 @@ void fsverity_verify_bio(struct bio *bio)unsigned long level0_ra_pages =min (max_ra_pages, params->level0_blocks - level0_index); -if (!PageError (page) && - !verify_page (inode, vi, req, page, level0_ra_pages)) -SetPageError (page); +if (!verify_page (inode, vi, req, page, level0_ra_pages)) { + bio->bi_status =BLK_STS_IOERR ; +break ; + } }fsverity_free_hash_request (params->hash_alg, req);
Quoted 3 lines
base-commit:
f0c4d9fc9cc9462659728d168387191387e903ccSignature · 1 line
2.38.1
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Jaegeuk Kim
maintainerQuoted 192 lines · Eric Biggers
From: Eric Biggers <[email protected]>
As a step towards freeing the
PG_errorflag for other uses, change ext4 and f2fs to stop usingPG_errorto track verity errors. Instead, if a verity error occurs, just mark the whole bio as failed. The coarser granularity isn't really a problem since it isn't any worse than what the block layer provides, and errors from a multi-page readahead aren't reported to applications unless a single-page read fails too.f2fs supports compression, which makes the f2fs changes a bit more complicated than desired, but the basic premise still works.
Note: there are still a few uses of PageError in f2fs, but they are on the write path, so they are unrelated and this patch doesn't touch them.
Reviewed-by Chao Yu <[email protected]>Signed-off-by Eric Biggers <[email protected]>---
v4: Added a comment for
decompression_attempted, added a paragraph to
the commit message, and added Chao's Reviewed-by.v3: made a small simplification to the f2fs changes. Also dropped the
fscrypt patch since it is upstream now.fs/ext4/readpage.c | 8 ++---- fs/f2fs/compress.c | 64 ++++++++++++++++++++++------------------------ fs/f2fs/data.c | 53 +++++++++++++++++++++++--------------- fs/verity/verify.c | 12 ++++----- 4 files changed, 72 insertions(+), 65 deletions(-)fs/ext4/readpage.c +2
-6@@ -75,14 +75,10 @@ static void __read_end_io(struct bio *bio)bio_for_each_segment_all (bv, bio, iter_all) { page = bv->bv_page; -/* PG_error was set if verity failed. */ -if (bio->bi_status ||PageError (page)) { +if (bio->bi_status)ClearPageUptodate (page); -/* will re-read again later */ -ClearPageError (page); - }else { +else SetPageUptodate (page); - }unlock_page (page); }if (bio->bi_private)fs/f2fs/compress.c +31
-33@@ -1711,50 +1711,27 @@ static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task) } } -/* -* Update and unlock the cluster's pagecache pages, and release the reference to -* the decompress_io_ctx that was being held for I/O completion. -*/ -static void __f2fs_decompress_end_io (struct decompress_io_ctx *dic,bool failed, -bool in_task) +static void f2fs_verify_cluster (struct work_struct *work) { +struct decompress_io_ctx *dic = + container_of(work, struct decompress_io_ctx, verity_work);int i; +/* Verify, update, and unlock the decompressed pages. */ for (i =0 ; i < dic->cluster_size; i++) {struct page *rpage = dic->rpages[i];if (!rpage)continue ; -/* PG_error was set if verity failed. */ -if (failed ||PageError (rpage)) { -ClearPageUptodate (rpage); -/* will re-read again later */ -ClearPageError (rpage); - }else { +if (fsverity_verify_page (rpage))SetPageUptodate (rpage); - } +else +ClearPageUptodate (rpage);unlock_page (rpage); } -f2fs_put_dic (dic, in_task); -} - -static void f2fs_verify_cluster (struct work_struct *work) -{ -struct decompress_io_ctx *dic = - container_of(work, struct decompress_io_ctx, verity_work); -int i; - -/* Verify the cluster's decompressed pages with fs-verity. */ -for (i =0 ; i < dic->cluster_size; i++) { -struct page *rpage = dic->rpages[i]; - -if (rpage && !fsverity_verify_page (rpage)) -SetPageError (rpage); - } - -__f2fs_decompress_end_io (dic, false, true); +f2fs_put_dic (dic, true); }/* @@ -1764,6 +1741,8 @@ static void f2fs_verify_cluster(struct work_struct *work)void f2fs_decompress_end_io (struct decompress_io_ctx *dic,bool failed,bool in_task) { +int i; +if (!failed && dic->need_verity) {/* * Note that to avoid deadlocks, the verity work can't be done @@ -1773,9 +1752,28 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,*/ INIT_WORK (&dic->verity_work, f2fs_verify_cluster);fsverity_enqueue_verify_work (&dic->verity_work); - }else { -__f2fs_decompress_end_io (dic, failed, in_task); +return ; + } + +/* Update and unlock the cluster's pagecache pages. */ +for (i =0 ; i < dic->cluster_size; i++) { +struct page *rpage = dic->rpages[i]; + +if (!rpage) +continue ; + +if (failed) +ClearPageUptodate (rpage); +else +SetPageUptodate (rpage); +unlock_page (rpage); } + +/* +* Release the reference to the decompress_io_ctx that was being held +* for I/O completion. +*/ +f2fs_put_dic (dic, in_task); }/* fs/f2fs/data.c +21
-0@@ -116,43 +116,56 @@ struct bio_post_read_ctx {struct f2fs_sb_info *sbi;struct work_struct work;unsigned int enabled_steps; +/* +* decompression_attempted keeps track of whether +* f2fs_end_read_compressed_page() has been called on the pages in the +* bio that belong to a compressed cluster yet. +*/ +bool decompression_attempted;block_t fs_blkaddr; }; +/* +* Update and unlock a bio's pages, and free the bio. +* +* This marks pages up-to-date only if there was no error in the bio (I/O error, +* decryption error, or verity error), as indicated by bio->bi_status. +* +* "Compressed pages" (pagecache pages backed by a compressed cluster on-disk) +* aren't marked up-to-date here, as decompression is done on a per-compression- +* cluster basis rather than a per-bio basis. Instead, we only must do two +* things for each compressed page here: call f2fs_end_read_compressed_page() +* with failed=true if an error occurred before it would have normally gotten +* called (i.e., I/O error or decryption error, but *not* verity error), and +* release the bio's reference to the decompress_io_ctx of the page's cluster. +*/ static void f2fs_finish_read_bio (struct bio *bio,bool in_task) {struct bio_vec *bv;struct bvec_iter_all iter_all; +struct bio_post_read_ctx *ctx = bio->bi_private;
fs/f2fs/data.c struct bio_post_read_ctx { · line 152
Quoted 10 lines
fs/f2fs/data.c +1
-5-/* -* Update and unlock the bio's pagecache pages, and put the -* decompression context for any compressed pages. -*/ bio_for_each_segment_all (bv, bio, iter_all) {struct page *page = bv->bv_page;if (f2fs_is_compressed_page (page)) { -if (bio->bi_status) +if (!ctx->decompression_attempted)
If seems this causes a panic due to the ctx nullified by f2fs_verify_bio.
Quoted 128 lines
fs/f2fs/data.c +11
-15f2fs_end_read_compressed_page (page, true,0 , in_task);f2fs_put_page_dic (page, in_task);continue ; } -/* PG_error was set if verity failed. */ -if (bio->bi_status ||PageError (page)) { +if (bio->bi_status)ClearPageUptodate (page); -/* will re-read again later */ -ClearPageError (page); - }else { +else SetPageUptodate (page); - }dec_page_count (F2FS_P_SB (page),__read_io_type (page));unlock_page (page); } -if (bio->bi_private) -mempool_free (bio->bi_private, bio_post_read_ctx_pool); +if (ctx) +mempool_free (ctx, bio_post_read_ctx_pool);bio_put (bio); }@@ -185,8 +198,10 @@ static void f2fs_verify_bio(struct work_struct *work)struct page *page = bv->bv_page;if (!f2fs_is_compressed_page (page) && - !fsverity_verify_page (page)) -SetPageError (page); + !fsverity_verify_page (page)) { + bio->bi_status =BLK_STS_IOERR ; +break ; + } } }else {fsverity_verify_bio (bio);@@ -245,6 +260,8 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx, blkaddr++; } + ctx->decompression_attempted = true; +/* * Optimization: if all the bio's pages are compressed, then scheduling * the per-bio verity work is unnecessary, as verity will be fully @@ -1062,6 +1079,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, ctx->sbi = sbi; ctx->enabled_steps = post_read_steps; ctx->fs_blkaddr = blkaddr; + ctx->decompression_attempted = false; bio->bi_private = ctx; }iostat_alloc_and_bind_ctx (sbi, bio, ctx);@@ -1089,7 +1107,6 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,bio_put (bio);return -EFAULT ; } -ClearPageError (page);inc_page_count (sbi,F2FS_RD_DATA );f2fs_update_iostat (sbi,NULL ,FS_DATA_READ_IO ,F2FS_BLKSIZE );__submit_bio (sbi, bio,DATA );@@ -2141,7 +2158,6 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,inc_page_count (F2FS_I_SB (inode),F2FS_RD_DATA );f2fs_update_iostat (F2FS_I_SB (inode),NULL ,FS_DATA_READ_IO ,F2FS_BLKSIZE ); -ClearPageError (page); *last_block_in_bio = block_nr; goto out; out:@@ -2289,7 +2305,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,inc_page_count (sbi,F2FS_RD_DATA );f2fs_update_iostat (sbi, inode,FS_DATA_READ_IO ,F2FS_BLKSIZE ); -ClearPageError (page); *last_block_in_bio = blkaddr; }@@ -2306,7 +2321,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,for (i =0 ; i < cc->cluster_size; i++) {if (cc->rpages[i]) {ClearPageUptodate (cc->rpages[i]); -ClearPageError (cc->rpages[i]);unlock_page (cc->rpages[i]); } }@@ -2403,7 +2417,6 @@ static int f2fs_mpage_readpages(struct inode *inode,#ifdef CONFIG_F2FS_FS_COMPRESSION set_error_page:#endif -SetPageError (page);zero_user_segment (page,0 ,PAGE_SIZE );unlock_page (page); }fs/verity/verify.c +6
-6@@ -200,9 +200,8 @@ EXPORT_SYMBOL_GPL(fsverity_verify_page);* @bio: the bio to verify * * Verify a set of pages that have just been read from a verity file. The pages -* must be pagecache pages that are still locked and not yet uptodate. Pages -* that fail verification are set to the Error state. Verification is skipped -* for pages already in the Error state, e.g. due to fscrypt decryption failure. +* must be pagecache pages that are still locked and not yet uptodate. If a +* page fails verification, then bio->bi_status is set to an error status. * * This is a helper function for use by the ->readahead() method of filesystems * that issue bios to read data directly into the page cache. Filesystems that @@ -244,9 +243,10 @@ void fsverity_verify_bio(struct bio *bio)unsigned long level0_ra_pages =min (max_ra_pages, params->level0_blocks - level0_index); -if (!PageError (page) && - !verify_page (inode, vi, req, page, level0_ra_pages)) -SetPageError (page); +if (!verify_page (inode, vi, req, page, level0_ra_pages)) { + bio->bi_status =BLK_STS_IOERR ; +break ; + } }fsverity_free_hash_request (params->hash_alg, req);
Quoted 3 lines
base-commit:
f0c4d9fc9cc9462659728d168387191387e903ccSignature · 1 line
2.38.1
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Eric Biggers
maintainerQuoted 13 lines · Jaegeuk Kim
Quoted 13 lines
static void
f2fs_finish_read_bio(struct bio *bio, bool in_task){fs/f2fs/data.c +1
-4struct bio_vec *bv;struct bvec_iter_all iter_all; +struct bio_post_read_ctx *ctx = bio->bi_private; -/* -* Update and unlock the bio's pagecache pages, and put the -* decompression context for any compressed pages. -*/ bio_for_each_segment_all (bv, bio, iter_all) {struct page *page = bv->bv_page;
Quoted 6 lines
fs/f2fs/data.c struct bio_post_read_ctx { · line 152
Quoted 3 lines
fs/f2fs/data.c +1
-1if (f2fs_is_compressed_page (page)) { -if (bio->bi_status) +if (!ctx->decompression_attempted)If seems this causes a panic due to the ctx nullified by
f2fs_verify_bio.
Thanks for catching that! I've sent out v5 that checks for 'ctx && !ctx->decompression_attempted' here. That's the right thing to do, since if ctx is NULL then decompression must have been attempted.
I'd like to get rid of freeing the bio_post_read_ctx in f2fs_verify_bio(). But I believe it's still needed, at least in theory.
Do you have a suggestion for testing f2fs compression + verity with xfstests? I missed this because compression isn't covered by the "verity" group tests. Maybe there should be an "f2fs/compress" config in xfstests-bld that uses mkfs and mount options that cause all files to be automatically compressed, similar to how f2fs/encrypt automatically encrypts all files with test_dummy_encryption.
- Eric
Jaegeuk Kim
maintainerQuoted 25 lines · Eric Biggers
Quoted 13 lines · Jaegeuk Kim
Quoted 13 lines
static void
f2fs_finish_read_bio(struct bio *bio, bool in_task){fs/f2fs/data.c +1
-4struct bio_vec *bv;struct bvec_iter_all iter_all; +struct bio_post_read_ctx *ctx = bio->bi_private; -/* -* Update and unlock the bio's pagecache pages, and put the -* decompression context for any compressed pages. -*/ bio_for_each_segment_all (bv, bio, iter_all) {struct page *page = bv->bv_page;Quoted 6 lines
fs/f2fs/data.c struct bio_post_read_ctx { · line 152
Quoted 3 lines
fs/f2fs/data.c +1
-1if (f2fs_is_compressed_page (page)) { -if (bio->bi_status) +if (!ctx->decompression_attempted)If seems this causes a panic due to the ctx nullified by
f2fs_verify_bio.Thanks for catching that! I've sent out v5 that checks for 'ctx && !ctx->decompression_attempted' here. That's the right thing to do, since if ctx is NULL then decompression must have been attempted.
Quoted 8 lines
I'd like to get rid of freeing the
bio_post_read_ctxinf2fs_verify_bio(). But I believe it's still needed, at least in theory.Do you have a suggestion for testing f2fs compression + verity with xfstests? I missed this because compression isn't covered by the "verity" group tests. Maybe there should be an "f2fs/compress" config in xfstests-bld that uses mkfs and mount options that cause all files to be automatically compressed, similar to how f2fs/encrypt automatically encrypts all files with
test_dummy_encryption.
I used for fsstress+fault_injection+shutdown loop with compressed and non-compressed directories with:
# mkfs.f2fs -f -O extra_attr -O project_quota -O compression -g android /dev/$DEV # mount -t f2fs -o discard,fsync_mode=nobarrier,reserve_root=32768,checkpoint_merge,atgc,compress_cache /dev/$DEV $TESTDIR # mkdir $TESTDIR/comp # f2fs_io setflags compression $TESTDIR/comp # fsstress [options] -d $TESTDIR/comp
I think you can simply mount with "-o compress_extension=*" to compress everything.
Quoted 2 lines
- Eric
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel