Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+22 -13
+10
fs/crypto/fscrypt_private.h
··· 296 296 void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, 297 297 const struct fscrypt_info *ci); 298 298 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 + 299 309 /* fname.c */ 300 310 bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy, 301 311 u32 orig_len, u32 max_len,
+2 -5
fs/crypto/inline_crypt.c
··· 41 41 42 42 static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci) 43 43 { 44 - struct super_block *sb = ci->ci_inode->i_sb; 44 + const struct super_block *sb = ci->ci_inode->i_sb; 45 45 unsigned int flags = fscrypt_policy_flags(&ci->ci_policy); 46 - int ino_bits = 64, lblk_bits = 64; 47 46 48 47 if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) 49 48 return offsetofend(union fscrypt_iv, nonce); ··· 54 55 return sizeof(__le32); 55 56 56 57 /* Default case: IVs are just the file logical block number */ 57 - if (sb->s_cop->get_ino_and_lblk_bits) 58 - sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits); 59 - return DIV_ROUND_UP(lblk_bits, 8); 58 + return DIV_ROUND_UP(fscrypt_max_file_lblk_bits(sb), 8); 60 59 } 61 60 62 61 /*
+10 -8
fs/crypto/policy.c
··· 119 119 120 120 static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy, 121 121 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) 124 123 { 125 124 struct super_block *sb = inode->i_sb; 126 125 int ino_bits = 64, lblk_bits = 64; ··· 157 158 type, sb->s_id); 158 159 return false; 159 160 } 160 - if (lblk_bits > max_lblk_bits) { 161 + 162 + /* 163 + * IV_INO_LBLK_64 and IV_INO_LBLK_32 both require that file logical 164 + * block numbers fit in 32 bits. 165 + */ 166 + if (fscrypt_max_file_lblk_bits(sb) > 32) { 161 167 fscrypt_warn(inode, 162 - "Can't use %s policy on filesystem '%s' because its block numbers are too long", 168 + "Can't use %s policy on filesystem '%s' because its maximum file size is too large", 163 169 type, sb->s_id); 164 170 return false; 165 171 } ··· 243 239 return false; 244 240 245 241 if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) && 246 - !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_64", 247 - 32, 32)) 242 + !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_64", 32)) 248 243 return false; 249 244 250 245 /* ··· 253 250 * implementation limit is 32 bits. 254 251 */ 255 252 if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && 256 - !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32", 257 - 32, 32)) 253 + !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32", 32)) 258 254 return false; 259 255 260 256 if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) {