ext4, f2fs: stop using PG_error for fscrypt and fsverity
Subsystems (5)
Eric Biggers
maintainercover ext4, f2fs: stop using PG_error for fscrypt and fsverity
This series changes ext4 and f2fs to stop using PG_error to track decryption and verity errors. This is a step towards freeing up PG_error for other uses, as discussed at
https://lore.kernel.org/linux-fsdevel/[email protected]
Note: due to the interdependencies with fs/crypto/ and fs/verity/, I couldn't split this up into separate patches for each filesystem.
Eric Biggers (2):
fscrypt: stop using PG_error to track error status
fsverity: stop using PG_error to track error status
fs/crypto/bio.c | 16 +++++++---- fs/ext4/readpage.c | 16 +++++------ fs/f2fs/compress.c | 61 ++++++++++++++++++++--------------------- fs/f2fs/data.c | 60 +++++++++++++++++++++------------------- fs/verity/verify.c | 12 ++++---- include/linux/fscrypt.h | 5 ++-- 6 files changed, 88 insertions(+), 82 deletions(-)
base-commit: 0840a7914caa14315a3191178a9f72c742477860
Signature · 1 line
2.36.1
Eric Biggers
maintainerPATCH 1/2 fscrypt: 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 decryption errors. Instead, if a decryption 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.
--- fs/crypto/bio.c | 16 ++++++++++------ fs/ext4/readpage.c | 8 +++++--- fs/f2fs/data.c | 17 +++++++++-------- include/linux/fscrypt.h | 5 +++-- 4 files changed, 27 insertions(+), 19 deletions(-)
fs/crypto/bio.c +10 -6
@@ -25,21 +25,25 @@* then this function isn't applicable. This function may sleep, so it must be * called from a workqueue rather than from the bio's bi_end_io callback. * -* This function sets PG_error on any pages that contain any blocks that failed -* to be decrypted. The filesystem must not mark such pages uptodate. +* Return: %true on success; %false on failure. On failure, bio->bi_status is +* also set to an error status. */ -void fscrypt_decrypt_bio (struct bio *bio) +bool fscrypt_decrypt_bio (struct bio *bio) {struct bio_vec *bv;struct bvec_iter_all iter_all;bio_for_each_segment_all (bv, bio, iter_all) {struct page *page = bv->bv_page; -int ret =fscrypt_decrypt_pagecache_blocks (page, bv->bv_len, +int err =fscrypt_decrypt_pagecache_blocks (page, bv->bv_len, bv->bv_offset); -if (ret) -SetPageError (page); + +if (err) { + bio->bi_status =errno_to_blk_status (err); +return false; + } } +return true; }EXPORT_SYMBOL (fscrypt_decrypt_bio);
fs/ext4/readpage.c +5 -3
@@ -96,10 +96,12 @@ static void decrypt_work(struct work_struct *work) {struct bio_post_read_ctx *ctx = container_of(work, struct bio_post_read_ctx, work); +struct bio *bio = ctx->bio; -fscrypt_decrypt_bio (ctx->bio); - -bio_post_read_processing (ctx); +if (fscrypt_decrypt_bio (bio)) +bio_post_read_processing (ctx); +else +__read_end_io (bio); }static void verity_work (struct work_struct *work)
fs/f2fs/data.c +9 -8
@@ -138,7 +138,7 @@ static void f2fs_finish_read_bio(struct bio *bio)continue ; } -/* PG_error was set if decryption or verity failed. */ +/* PG_error was set if verity failed. */ if (bio->bi_status ||PageError (page)) {ClearPageUptodate (page);/* will re-read again later */
@@ -184,7 +184,7 @@ static void f2fs_verify_bio(struct work_struct *work)struct page *page = bv->bv_page;if (!f2fs_is_compressed_page (page) && - !PageError (page) && !fsverity_verify_page (page)) + !fsverity_verify_page (page))SetPageError (page); } }else {
@@ -234,10 +234,8 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx)bio_for_each_segment_all (bv, ctx->bio, iter_all) {struct page *page = bv->bv_page; -/* PG_error was set if decryption failed. */ if (f2fs_is_compressed_page (page)) -f2fs_end_read_compressed_page (page,PageError (page), - blkaddr); +f2fs_end_read_compressed_page (page, false, blkaddr);else all_compressed = false;
@@ -257,14 +255,17 @@ static void f2fs_post_read_work(struct work_struct *work) {struct bio_post_read_ctx *ctx = container_of(work, struct bio_post_read_ctx, work); +struct bio *bio = ctx->bio; -if (ctx->enabled_steps &STEP_DECRYPT ) -fscrypt_decrypt_bio (ctx->bio); +if ((ctx->enabled_steps &STEP_DECRYPT ) && !fscrypt_decrypt_bio (bio)) { +f2fs_finish_read_bio (bio); +return ; + }if (ctx->enabled_steps &STEP_DECOMPRESS )f2fs_handle_step_decompress (ctx); -f2fs_verify_and_finish_bio (ctx->bio); +f2fs_verify_and_finish_bio (bio); }static void f2fs_read_end_io (struct bio *bio)
include/linux/fscrypt.h +3 -2
@@ -348,7 +348,7 @@ u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name);int fscrypt_d_revalidate (struct dentry *dentry,unsigned int flags);/* bio.c */ -void fscrypt_decrypt_bio (struct bio *bio); +bool fscrypt_decrypt_bio (struct bio *bio);int fscrypt_zeroout_range (const struct inode *inode,pgoff_t lblk,sector_t pblk,unsigned int len);
@@ -641,8 +641,9 @@ static inline int fscrypt_d_revalidate(struct dentry *dentry, }/* bio.c */ -static inline void fscrypt_decrypt_bio (struct bio *bio) +static inline bool fscrypt_decrypt_bio (struct bio *bio) { +return true; } static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
Signature · 1 line
2.36.1
Eric Biggers
maintainerPATCH 2/2 fsverity: stop using PG_error to track error status
In reply to Eric BiggersFrom: 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.
--- fs/ext4/readpage.c | 8 ++---- fs/f2fs/compress.c | 61 +++++++++++++++++++++++----------------------- fs/f2fs/data.c | 49 ++++++++++++++++++++----------------- fs/verity/verify.c | 12 ++++----- 4 files changed, 64 insertions(+), 66 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 any post_read step 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 +30 -31
96 lines not on this page · raw message
fs/f2fs/data.c +26 -23
129 lines not on this page · raw message
fs/verity/verify.c +6 -6
@@ -210,9 +210,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
@@ -254,9 +253,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);
Signature · 1 line
2.36.1
Eric Biggers
maintainerQuoted 21 lines · Eric Biggers
This series changes ext4 and f2fs to stop using
PG_errorto track decryption and verity errors. This is a step towards freeing upPG_errorfor other uses, as discussed at
https://lore.kernel.org/linux-fsdevel/[email protected]Note: due to the interdependencies with
fs/crypto/andfs/verity/, I couldn't split this up into separate patches for each filesystem.Eric Biggers (2):
fscrypt: stop usingPG_errorto track error status
fsverity: stop usingPG_errorto track error statusfs/crypto/bio.c | 16 +++++++---- fs/ext4/readpage.c | 16 +++++------ fs/f2fs/compress.c | 61 ++++++++++++++++++++--------------------- fs/f2fs/data.c | 60 +++++++++++++++++++++------------------- fs/verity/verify.c | 12 ++++---- include/linux/fscrypt.h | 5 ++-- 6 files changed, 88 insertions(+), 82 deletions(-)
Quoted 1 line
base-commit:
0840a7914caa14315a3191178a9f72c742477860
Any thoughts on this patchset from anyone?
- Eric