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

fscrypt: replace get_ino_and_lblk_bits with just has_32bit_inodes

Now that fs/crypto/ computes the filesystem's lblk_bits from its maximum
file size, it is no longer necessary for filesystems to provide
lblk_bits via fscrypt_operations::get_ino_and_lblk_bits.

It is still necessary for fs/crypto/ to retrieve ino_bits from the
filesystem. However, this is used only to decide whether inode numbers
fit in 32 bits. Also, ino_bits is static for all relevant filesystems,
i.e. it doesn't depend on the filesystem instance.

Therefore, in the interest of keeping things as simple as possible,
replace 'get_ino_and_lblk_bits' with a flag 'has_32bit_inodes'. This
can always be changed back to a function if a filesystem needs it to be
dynamic, but for now a static flag is all that's needed.

Link: https://lore.kernel.org/r/20230925055451.59499-5-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>

+28 -49
+15 -18
fs/crypto/policy.c
··· 118 118 } 119 119 120 120 static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy, 121 - const struct inode *inode, 122 - const char *type, int max_ino_bits) 121 + const struct inode *inode) 123 122 { 123 + const char *type = (policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) 124 + ? "IV_INO_LBLK_64" : "IV_INO_LBLK_32"; 124 125 struct super_block *sb = inode->i_sb; 125 - int ino_bits = 64, lblk_bits = 64; 126 126 127 127 /* 128 128 * IV_INO_LBLK_* exist only because of hardware limitations, and ··· 149 149 type, sb->s_id); 150 150 return false; 151 151 } 152 - if (sb->s_cop->get_ino_and_lblk_bits) 153 - sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits); 154 - if (ino_bits > max_ino_bits) { 152 + 153 + /* 154 + * IV_INO_LBLK_64 and IV_INO_LBLK_32 both require that inode numbers fit 155 + * in 32 bits. In principle, IV_INO_LBLK_32 could support longer inode 156 + * numbers because it hashes the inode number; however, currently the 157 + * inode number is gotten from inode::i_ino which is 'unsigned long'. 158 + * So for now the implementation limit is 32 bits. 159 + */ 160 + if (!sb->s_cop->has_32bit_inodes) { 155 161 fscrypt_warn(inode, 156 162 "Can't use %s policy on filesystem '%s' because its inode numbers are too long", 157 163 type, sb->s_id); ··· 248 242 policy->filenames_encryption_mode)) 249 243 return false; 250 244 251 - if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) && 252 - !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_64", 32)) 253 - return false; 254 - 255 - /* 256 - * IV_INO_LBLK_32 hashes the inode number, so in principle it can 257 - * support any ino_bits. However, currently the inode number is gotten 258 - * from inode::i_ino which is 'unsigned long'. So for now the 259 - * implementation limit is 32 bits. 260 - */ 261 - if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && 262 - !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32", 32)) 245 + if ((policy->flags & (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 | 246 + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) && 247 + !supported_iv_ino_lblk_policy(policy, inode)) 263 248 return false; 264 249 265 250 if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) {
+1 -8
fs/ext4/crypto.c
··· 232 232 return ext4_has_feature_stable_inodes(sb); 233 233 } 234 234 235 - static void ext4_get_ino_and_lblk_bits(struct super_block *sb, 236 - int *ino_bits_ret, int *lblk_bits_ret) 237 - { 238 - *ino_bits_ret = 8 * sizeof(EXT4_SB(sb)->s_es->s_inodes_count); 239 - *lblk_bits_ret = 8 * sizeof(ext4_lblk_t); 240 - } 241 - 242 235 const struct fscrypt_operations ext4_cryptops = { 243 236 .needs_bounce_pages = 1, 237 + .has_32bit_inodes = 1, 244 238 .legacy_key_prefix = "ext4:", 245 239 .get_context = ext4_get_context, 246 240 .set_context = ext4_set_context, 247 241 .get_dummy_policy = ext4_get_dummy_policy, 248 242 .empty_dir = ext4_empty_dir, 249 243 .has_stable_inodes = ext4_has_stable_inodes, 250 - .get_ino_and_lblk_bits = ext4_get_ino_and_lblk_bits, 251 244 };
+1 -8
fs/f2fs/super.c
··· 3203 3203 return true; 3204 3204 } 3205 3205 3206 - static void f2fs_get_ino_and_lblk_bits(struct super_block *sb, 3207 - int *ino_bits_ret, int *lblk_bits_ret) 3208 - { 3209 - *ino_bits_ret = 8 * sizeof(nid_t); 3210 - *lblk_bits_ret = 8 * sizeof(block_t); 3211 - } 3212 - 3213 3206 static struct block_device **f2fs_get_devices(struct super_block *sb, 3214 3207 unsigned int *num_devs) 3215 3208 { ··· 3225 3232 3226 3233 static const struct fscrypt_operations f2fs_cryptops = { 3227 3234 .needs_bounce_pages = 1, 3235 + .has_32bit_inodes = 1, 3228 3236 .legacy_key_prefix = "f2fs:", 3229 3237 .get_context = f2fs_get_context, 3230 3238 .set_context = f2fs_set_context, 3231 3239 .get_dummy_policy = f2fs_get_dummy_policy, 3232 3240 .empty_dir = f2fs_empty_dir, 3233 3241 .has_stable_inodes = f2fs_has_stable_inodes, 3234 - .get_ino_and_lblk_bits = f2fs_get_ino_and_lblk_bits, 3235 3242 .get_devices = f2fs_get_devices, 3236 3243 }; 3237 3244 #endif
+11 -15
include/linux/fscrypt.h
··· 75 75 unsigned int needs_bounce_pages : 1; 76 76 77 77 /* 78 + * If set, then fs/crypto/ will allow the use of encryption settings 79 + * that assume inode numbers fit in 32 bits (i.e. 80 + * FSCRYPT_POLICY_FLAG_IV_INO_LBLK_{32,64}), provided that the other 81 + * prerequisites for these settings are also met. This is only useful 82 + * if the filesystem wants to support inline encryption hardware that is 83 + * limited to 32-bit or 64-bit data unit numbers and where programming 84 + * keyslots is very slow. 85 + */ 86 + unsigned int has_32bit_inodes : 1; 87 + 88 + /* 78 89 * This field exists only for backwards compatibility reasons and should 79 90 * only be set by the filesystems that are setting it already. It 80 91 * contains the filesystem-specific key description prefix that is ··· 161 150 * Leaving this NULL is equivalent to always returning false. 162 151 */ 163 152 bool (*has_stable_inodes)(struct super_block *sb); 164 - 165 - /* 166 - * Get the number of bits that the filesystem uses to represent inode 167 - * numbers and file logical block numbers. 168 - * 169 - * By default, both of these are assumed to be 64-bit. This function 170 - * can be implemented to declare that either or both of these numbers is 171 - * shorter, which may allow the use of the 172 - * FSCRYPT_POLICY_FLAG_IV_INO_LBLK_{32,64} flags and/or the use of 173 - * inline crypto hardware whose maximum DUN length is less than 64 bits 174 - * (e.g., eMMC v5.2 spec compliant hardware). This function only needs 175 - * to be implemented if support for one of these features is needed. 176 - */ 177 - void (*get_ino_and_lblk_bits)(struct super_block *sb, 178 - int *ino_bits_ret, int *lblk_bits_ret); 179 153 180 154 /* 181 155 * Return an array of pointers to the block devices to which the