Skip to content

Commit 7a0263d

Browse files
committed
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>
1 parent f0904e8 commit 7a0263d

4 files changed

Lines changed: 28 additions & 49 deletions

File tree

fs/crypto/policy.c

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ static bool supported_direct_key_modes(const struct inode *inode,
118118
}
119119

120120
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)
123122
{
123+
const char *type = (policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64)
124+
? "IV_INO_LBLK_64" : "IV_INO_LBLK_32";
124125
struct super_block *sb = inode->i_sb;
125-
int ino_bits = 64, lblk_bits = 64;
126126

127127
/*
128128
* IV_INO_LBLK_* exist only because of hardware limitations, and
@@ -149,9 +149,15 @@ static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy,
149149
type, sb->s_id);
150150
return false;
151151
}
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) {
155161
fscrypt_warn(inode,
156162
"Can't use %s policy on filesystem '%s' because its inode numbers are too long",
157163
type, sb->s_id);
@@ -242,18 +248,9 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
242248
policy->filenames_encryption_mode))
243249
return false;
244250

245-
if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) &&
246-
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_64", 32))
247-
return false;
248-
249-
/*
250-
* IV_INO_LBLK_32 hashes the inode number, so in principle it can
251-
* support any ino_bits. However, currently the inode number is gotten
252-
* from inode::i_ino which is 'unsigned long'. So for now the
253-
* implementation limit is 32 bits.
254-
*/
255-
if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
256-
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32", 32))
251+
if ((policy->flags & (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 |
252+
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) &&
253+
!supported_iv_ino_lblk_policy(policy, inode))
257254
return false;
258255

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

fs/ext4/crypto.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,13 @@ static bool ext4_has_stable_inodes(struct super_block *sb)
232232
return ext4_has_feature_stable_inodes(sb);
233233
}
234234

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-
242235
const struct fscrypt_operations ext4_cryptops = {
243236
.needs_bounce_pages = 1,
237+
.has_32bit_inodes = 1,
244238
.legacy_key_prefix = "ext4:",
245239
.get_context = ext4_get_context,
246240
.set_context = ext4_set_context,
247241
.get_dummy_policy = ext4_get_dummy_policy,
248242
.empty_dir = ext4_empty_dir,
249243
.has_stable_inodes = ext4_has_stable_inodes,
250-
.get_ino_and_lblk_bits = ext4_get_ino_and_lblk_bits,
251244
};

fs/f2fs/super.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,13 +3203,6 @@ static bool f2fs_has_stable_inodes(struct super_block *sb)
32033203
return true;
32043204
}
32053205

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-
32133206
static struct block_device **f2fs_get_devices(struct super_block *sb,
32143207
unsigned int *num_devs)
32153208
{
@@ -3232,13 +3225,13 @@ static struct block_device **f2fs_get_devices(struct super_block *sb,
32323225

32333226
static const struct fscrypt_operations f2fs_cryptops = {
32343227
.needs_bounce_pages = 1,
3228+
.has_32bit_inodes = 1,
32353229
.legacy_key_prefix = "f2fs:",
32363230
.get_context = f2fs_get_context,
32373231
.set_context = f2fs_set_context,
32383232
.get_dummy_policy = f2fs_get_dummy_policy,
32393233
.empty_dir = f2fs_empty_dir,
32403234
.has_stable_inodes = f2fs_has_stable_inodes,
3241-
.get_ino_and_lblk_bits = f2fs_get_ino_and_lblk_bits,
32423235
.get_devices = f2fs_get_devices,
32433236
};
32443237
#endif

include/linux/fscrypt.h

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ struct fscrypt_operations {
7474
*/
7575
unsigned int needs_bounce_pages : 1;
7676

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+
7788
/*
7889
* This field exists only for backwards compatibility reasons and should
7990
* only be set by the filesystems that are setting it already. It
@@ -151,21 +162,6 @@ struct fscrypt_operations {
151162
*/
152163
bool (*has_stable_inodes)(struct super_block *sb);
153164

154-
/*
155-
* Get the number of bits that the filesystem uses to represent inode
156-
* numbers and file logical block numbers.
157-
*
158-
* By default, both of these are assumed to be 64-bit. This function
159-
* can be implemented to declare that either or both of these numbers is
160-
* shorter, which may allow the use of the
161-
* FSCRYPT_POLICY_FLAG_IV_INO_LBLK_{32,64} flags and/or the use of
162-
* inline crypto hardware whose maximum DUN length is less than 64 bits
163-
* (e.g., eMMC v5.2 spec compliant hardware). This function only needs
164-
* to be implemented if support for one of these features is needed.
165-
*/
166-
void (*get_ino_and_lblk_bits)(struct super_block *sb,
167-
int *ino_bits_ret, int *lblk_bits_ret);
168-
169165
/*
170166
* Return an array of pointers to the block devices to which the
171167
* filesystem may write encrypted file contents, NULL if the filesystem

0 commit comments

Comments
 (0)