From: Baokun Li <libaokun@linux.alibaba.com>
To: linux-fscrypt@vger.kernel.org
Cc: ebiggers@kernel.org, jaegeuk@kernel.org, tytso@mit.edu,
linux-ext4@vger.kernel.org, adilger.kernel@dilger.ca,
jack@suse.cz, yi.zhang@huawei.com, ojaswin@linux.ibm.com,
ritesh.list@gmail.com, linux-kernel@vger.kernel.org
Subject: [PATCH 1/4] fscrypt: Cap data units at the page size
Date: Tue, 3 Nov 2026 23:31:29 +0800 [thread overview]
Message-ID: <20261103153132.4154855-2-libaokun@linux.alibaba.com> (raw)
In-Reply-To: <20261103153132.4154855-1-libaokun@linux.alibaba.com>
blk-crypto-fallback cannot handle a data unit larger than a page:
it walks the bio one page-sized segment at a time, so a data unit
that spans multiple pages never ends on a segment boundary and
the bio fails with BLK_STS_INVAL after the I/O was already
reported to userspace as successful, losing data.
Fix this in fscrypt_supported_v2_policy() by rejecting any v2 policy
that explicitly specifies a data unit size larger than the page size.
A v1 policy always uses the block size as its data unit size,
so fscrypt_supported_v1_policy() has to reject any v1 policy on
a filesystem with a block size larger than the page size (e.g. ext4).
A v2 policy with no data unit size specified uses the block size too,
but rejection is not necessary there: sub-block data units are
supported, so it is enough to cap the data unit bits at PAGE_SHIFT in
fscrypt_policy_v2_du_bits().
Note that a filesystem whose block size exceeds 4K then cannot be
made compatible across page sizes (e.g. 4K and 64K); this can be
avoided by explicitly specifying a data unit size of 4K or smaller.
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Link: https://lore.kernel.org/r/20261015185325.GG2170687@google.com
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
Documentation/filesystems/fscrypt.rst | 19 +++++++++++++++----
fs/crypto/fscrypt_private.h | 4 +++-
fs/crypto/policy.c | 11 ++++++++++-
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index 6e2e511a70bb..78251a9706ba 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -649,8 +649,9 @@ This structure must be initialized as follows:
Not all filesystems support setting ``log2_data_unit_size``. ext4
and f2fs support it since Linux v6.7. On filesystems that support
it, the supported nonzero values are 9 through the log2 of the
- filesystem block size, inclusively. The default value of 0 selects
- the filesystem block size.
+ filesystem block size, inclusively, but no greater than the log2 of
+ the page size. The default value of 0 selects the filesystem block
+ size, or the page size if the block size is larger.
The main use case for ``log2_data_unit_size`` is for selecting a
data unit size smaller than the filesystem block size for
@@ -659,8 +660,18 @@ This structure must be initialized as follows:
useful for checking which data unit sizes are supported by a
particular system's inline encryption hardware.
- Leave this field zeroed unless you are certain you need it. Using
- an unnecessarily small data unit size reduces performance.
+ A v1 policy has no ``log2_data_unit_size`` and always uses the
+ filesystem block size, so it cannot be used on a filesystem whose
+ block size is larger than the page size.
+
+ A v2 policy on such a filesystem falls back to the page size, so
+ the data unit size depends on the machine's page size and the data
+ becomes unreadable elsewhere. An image portable across page sizes
+ should explicitly specify a data unit size of 4096 or smaller.
+
+ Leave this field zeroed unless you are certain one of the reasons
+ above applies. Using an unnecessarily small data unit size reduces
+ performance.
- For v2 encryption policies, ``__reserved`` must be zeroed.
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index e602c31b3844..0dc158563e71 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -203,7 +203,9 @@ static inline int
fscrypt_policy_v2_du_bits(const struct fscrypt_policy_v2 *policy,
const struct inode *inode)
{
- return policy->log2_data_unit_size ?: inode->i_blkbits;
+ if (policy->log2_data_unit_size)
+ return policy->log2_data_unit_size;
+ return min_t(unsigned int, inode->i_blkbits, PAGE_SHIFT);
}
static inline int
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
index 6dd510f93e6d..84c496da248e 100644
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -228,6 +228,14 @@ static bool fscrypt_supported_v1_policy(const struct fscrypt_policy_v1 *policy,
return false;
}
+ if (inode->i_sb->s_cop->is_block_based &&
+ inode->i_blkbits > PAGE_SHIFT) {
+ /* v1 has no way to select a sub-block data unit size. */
+ fscrypt_warn(inode,
+ "v1 policies can't be used on fs with block size > page size");
+ return false;
+ }
+
return true;
}
@@ -270,7 +278,8 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
return false;
}
if (policy->log2_data_unit_size > inode->i_blkbits ||
- policy->log2_data_unit_size < SECTOR_SHIFT /* 9 */) {
+ policy->log2_data_unit_size < SECTOR_SHIFT /* 9 */ ||
+ policy->log2_data_unit_size > PAGE_SHIFT) {
fscrypt_warn(inode,
"Unsupported log2_data_unit_size in encryption policy: %d",
policy->log2_data_unit_size);
--
2.43.7
next prev parent reply other threads:[~2026-11-03 15:32 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 15:31 [PATCH 0/4] ext4: support encryption with block size larger than page size Baokun Li
2026-11-03 15:31 ` Baokun Li [this message]
2026-11-03 15:44 ` [PATCH 1/4] fscrypt: Cap data units at the " sashiko-bot
2026-11-03 22:40 ` Eric Biggers
2026-11-04 2:31 ` Baokun Li
2026-11-04 19:51 ` Eric Biggers
2026-11-05 16:37 ` Baokun Li
2026-11-03 15:31 ` [PATCH 2/4] fscrypt: Validate the test_dummy_encryption policy for new inodes Baokun Li
2026-11-03 15:45 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 3/4] ext4: don't put a DUN wraparound in the middle of a read bio Baokun Li
2026-11-03 15:40 ` sashiko-bot
2026-11-03 15:31 ` [PATCH 4/4] ext4: allow large folios and bs > ps encryption Baokun Li
2026-11-03 15:42 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103153132.4154855-2-libaokun@linux.alibaba.com \
--to=libaokun@linux.alibaba.com \
--cc=adilger.kernel@dilger.ca \
--cc=ebiggers@kernel.org \
--cc=jack@suse.cz \
--cc=jaegeuk@kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ojaswin@linux.ibm.com \
--cc=ritesh.list@gmail.com \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.