Message ID | d0957b6aa0847fed100765d9268e4919265fabe9.1662420176.git.sweettea-kernel@dorminy.me (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: add fscrypt integration | expand |
On Mon, Sep 05, 2022 at 08:35:32PM -0400, Sweet Tea Dorminy wrote: > From: Omar Sandoval <osandov@osandov.com> > > For encrypted fscrypt_names, we can reuse fscrypt's precomputed hash of > the encrypted name to generate our own hash, instead of rehashing the > unencrypted name (which may not be possible if it's a nokey name). Can you please describe how this works when the key is not available? > Signed-off-by: Omar Sandoval <osandov@osandov.com> > Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> > --- > fs/btrfs/ctree.h | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h > index e8d000fcc85d..aa599518c057 100644 > --- a/fs/btrfs/ctree.h > +++ b/fs/btrfs/ctree.h > @@ -2842,7 +2842,10 @@ static inline void btrfs_crc32c_final(u32 crc, u8 *result) > > static inline u64 btrfs_name_hash(const struct fscrypt_name *name) > { > - return crc32c((u32)~1, fname_name(name), fname_len(name)); > + if (fname_name(name)) > + return crc32c((u32)~1, fname_name(name), fname_len(name)); > + else > + return name->hash | ((u64)name->minor_hash << 32); So this is another on-disk format change. > } > > /* > @@ -2851,8 +2854,20 @@ static inline u64 btrfs_name_hash(const struct fscrypt_name *name) > static inline u64 btrfs_extref_hash(u64 parent_objectid, > const struct fscrypt_name *name) > { > - return (u64) crc32c(parent_objectid, fname_name(name), > - fname_len(name)); > + /* > + * If the name is encrypted and we don't have the key, we can use the > + * fscrypt-provided hash instead of the normal name, and do the steps > + * of crc32c() manually. Else, just hash the name, parent objectid, > + * and name length. > + */ > + if (fname_name(name)) > + return (u64) crc32c(parent_objectid, fname_name(name), > + fname_len(name)); > + else > + return (__crc32c_le_combine(parent_objectid, > + name->hash, > + fname_len(name)) ^ > + __crc32c_le_shift(~1, fname_len(name))); How stable is the __crc32c_le_* API? > } > > static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping) > -- > 2.35.1
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e8d000fcc85d..aa599518c057 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2842,7 +2842,10 @@ static inline void btrfs_crc32c_final(u32 crc, u8 *result) static inline u64 btrfs_name_hash(const struct fscrypt_name *name) { - return crc32c((u32)~1, fname_name(name), fname_len(name)); + if (fname_name(name)) + return crc32c((u32)~1, fname_name(name), fname_len(name)); + else + return name->hash | ((u64)name->minor_hash << 32); } /* @@ -2851,8 +2854,20 @@ static inline u64 btrfs_name_hash(const struct fscrypt_name *name) static inline u64 btrfs_extref_hash(u64 parent_objectid, const struct fscrypt_name *name) { - return (u64) crc32c(parent_objectid, fname_name(name), - fname_len(name)); + /* + * If the name is encrypted and we don't have the key, we can use the + * fscrypt-provided hash instead of the normal name, and do the steps + * of crc32c() manually. Else, just hash the name, parent objectid, + * and name length. + */ + if (fname_name(name)) + return (u64) crc32c(parent_objectid, fname_name(name), + fname_len(name)); + else + return (__crc32c_le_combine(parent_objectid, + name->hash, + fname_len(name)) ^ + __crc32c_le_shift(~1, fname_len(name))); } static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping)