Skip to content

Commit f0904e8

Browse files
committed
fscrypt: compute max_lblk_bits from s_maxbytes and block size
For a given filesystem, the number of bits used by the maximum file logical block number is computable from the maximum file size and the block size. These values are always present in struct super_block. Therefore, compute it this way instead of using the value from fscrypt_operations::get_ino_and_lblk_bits. Since filesystems always have to set the super_block fields anyway, this avoids having to provide this information redundantly via fscrypt_operations. This change is in preparation for adding support for sub-block data units. For that, the value that is needed will become "the maximum file data unit index". A hardcoded value won't suffice for that; it will need to be computed anyway. Link: https://lore.kernel.org/r/20230925055451.59499-4-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@google.com>
1 parent 40e13e1 commit f0904e8

3 files changed

Lines changed: 22 additions & 13 deletions

File tree

fs/crypto/fscrypt_private.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ union fscrypt_iv {
296296
void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
297297
const struct fscrypt_info *ci);
298298

299+
/*
300+
* Return the number of bits used by the maximum file logical block number that
301+
* is possible on the given filesystem.
302+
*/
303+
static inline int
304+
fscrypt_max_file_lblk_bits(const struct super_block *sb)
305+
{
306+
return fls64(sb->s_maxbytes - 1) - sb->s_blocksize_bits;
307+
}
308+
299309
/* fname.c */
300310
bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
301311
u32 orig_len, u32 max_len,

fs/crypto/inline_crypt.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ static struct block_device **fscrypt_get_devices(struct super_block *sb,
4141

4242
static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
4343
{
44-
struct super_block *sb = ci->ci_inode->i_sb;
44+
const struct super_block *sb = ci->ci_inode->i_sb;
4545
unsigned int flags = fscrypt_policy_flags(&ci->ci_policy);
46-
int ino_bits = 64, lblk_bits = 64;
4746

4847
if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY)
4948
return offsetofend(union fscrypt_iv, nonce);
@@ -55,9 +54,7 @@ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
5554
return sizeof(__le32);
5655

5756
/* Default case: IVs are just the file logical block number */
58-
if (sb->s_cop->get_ino_and_lblk_bits)
59-
sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits);
60-
return DIV_ROUND_UP(lblk_bits, 8);
57+
return DIV_ROUND_UP(fscrypt_max_file_lblk_bits(sb), 8);
6158
}
6259

6360
/*

fs/crypto/policy.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ static bool supported_direct_key_modes(const struct inode *inode,
119119

120120
static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy,
121121
const struct inode *inode,
122-
const char *type,
123-
int max_ino_bits, int max_lblk_bits)
122+
const char *type, int max_ino_bits)
124123
{
125124
struct super_block *sb = inode->i_sb;
126125
int ino_bits = 64, lblk_bits = 64;
@@ -158,9 +157,14 @@ static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy,
158157
type, sb->s_id);
159158
return false;
160159
}
161-
if (lblk_bits > max_lblk_bits) {
160+
161+
/*
162+
* IV_INO_LBLK_64 and IV_INO_LBLK_32 both require that file logical
163+
* block numbers fit in 32 bits.
164+
*/
165+
if (fscrypt_max_file_lblk_bits(sb) > 32) {
162166
fscrypt_warn(inode,
163-
"Can't use %s policy on filesystem '%s' because its block numbers are too long",
167+
"Can't use %s policy on filesystem '%s' because its maximum file size is too large",
164168
type, sb->s_id);
165169
return false;
166170
}
@@ -239,8 +243,7 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
239243
return false;
240244

241245
if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) &&
242-
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_64",
243-
32, 32))
246+
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_64", 32))
244247
return false;
245248

246249
/*
@@ -250,8 +253,7 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
250253
* implementation limit is 32 bits.
251254
*/
252255
if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
253-
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32",
254-
32, 32))
256+
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32", 32))
255257
return false;
256258

257259
if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) {

0 commit comments

Comments
 (0)