Message ID | 20200708091237.3922153-5-drosen@google.com |
---|---|
State | Superseded |
Headers | show |
Series | Prepare for upcoming Casefolding/Encryption patches | expand |
Daniel Rosenberg <drosen@google.com> writes: > This switches ext4 over to the generic support provided in > the previous patch. > > Since casefolded dentries behave the same in ext4 and f2fs, we decrease > the maintenance burden by unifying them, and any optimizations will > immediately apply to both. > > Signed-off-by: Daniel Rosenberg <drosen@google.com> > Reviewed-by: Eric Biggers <ebiggers@google.com> > > #ifdef CONFIG_UNICODE > - if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent)) { > + if (parent->i_sb->s_encoding && IS_CASEFOLDED(parent)) { > if (fname->cf_name.name) { > struct qstr cf = {.name = fname->cf_name.name, > .len = fname->cf_name.len}; > @@ -2171,9 +2171,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, > struct buffer_head *bh = NULL; > struct ext4_dir_entry_2 *de; > struct super_block *sb; > -#ifdef CONFIG_UNICODE > - struct ext4_sb_info *sbi; > -#endif > struct ext4_filename fname; > int retval; > int dx_fallback=0; > @@ -2190,9 +2187,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, > return -EINVAL; > > #ifdef CONFIG_UNICODE > - sbi = EXT4_SB(sb); > - if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) && > - sbi->s_encoding && utf8_validate(sbi->s_encoding, &dentry->d_name)) > + if (sb_has_strict_encoding(sb) && IS_CASEFOLDED(dir) && > + sb->s_encoding && utf8_validate(sb->s_encoding, &dentry->d_name)) > return -EINVAL; hm, just noticed the sb->s_encoding check here is superfluous, since the has_strict_mode() cannot be true if !s_encoding. Not related to this patch though. Daniel, are you still working on getting this upstream? The fscrypt support would be very useful for us. :) In the hope this will get upstream, as its been flying for a while and looks correct. Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.com>
On Sun, Sep 20, 2020 at 09:10:57PM -0400, Gabriel Krisman Bertazi wrote: > Daniel Rosenberg <drosen@google.com> writes: > > > This switches ext4 over to the generic support provided in > > the previous patch. > > > > Since casefolded dentries behave the same in ext4 and f2fs, we decrease > > the maintenance burden by unifying them, and any optimizations will > > immediately apply to both. > > > > Signed-off-by: Daniel Rosenberg <drosen@google.com> > > Reviewed-by: Eric Biggers <ebiggers@google.com> > > > > #ifdef CONFIG_UNICODE > > - if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent)) { > > + if (parent->i_sb->s_encoding && IS_CASEFOLDED(parent)) { > > if (fname->cf_name.name) { > > struct qstr cf = {.name = fname->cf_name.name, > > .len = fname->cf_name.len}; > > @@ -2171,9 +2171,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, > > struct buffer_head *bh = NULL; > > struct ext4_dir_entry_2 *de; > > struct super_block *sb; > > -#ifdef CONFIG_UNICODE > > - struct ext4_sb_info *sbi; > > -#endif > > struct ext4_filename fname; > > int retval; > > int dx_fallback=0; > > @@ -2190,9 +2187,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, > > return -EINVAL; > > > > #ifdef CONFIG_UNICODE > > - sbi = EXT4_SB(sb); > > - if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) && > > - sbi->s_encoding && utf8_validate(sbi->s_encoding, &dentry->d_name)) > > + if (sb_has_strict_encoding(sb) && IS_CASEFOLDED(dir) && > > + sb->s_encoding && utf8_validate(sb->s_encoding, &dentry->d_name)) > > return -EINVAL; > > hm, just noticed the sb->s_encoding check here is superfluous, since the > has_strict_mode() cannot be true if !s_encoding. Not related to this > patch though. > > Daniel, are you still working on getting this upstream? The fscrypt > support would be very useful for us. :) > > In the hope this will get upstream, as its been flying for a while and > looks correct. > > Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.com> We couldn't get a response from Ted, so instead Jaegeuk has applied patches 1-3 to f2fs/dev for 5.10. Hopefully Ted will take the ext4 patch for 5.11. I believe that Daniel is planning to resend the actual encryption+casefolding support soon, but initially only for f2fs since that will be ready first. - Eric
On Mon, Sep 21, 2020 at 11:29 AM Eric Biggers <ebiggers@kernel.org> wrote: > > On Sun, Sep 20, 2020 at 09:10:57PM -0400, Gabriel Krisman Bertazi wrote: > > Daniel Rosenberg <drosen@google.com> writes: > > > > > This switches ext4 over to the generic support provided in > > > the previous patch. > > > > > > Since casefolded dentries behave the same in ext4 and f2fs, we decrease > > > the maintenance burden by unifying them, and any optimizations will > > > immediately apply to both. > > > > > > Signed-off-by: Daniel Rosenberg <drosen@google.com> > > > Reviewed-by: Eric Biggers <ebiggers@google.com> > > > > > > #ifdef CONFIG_UNICODE > > > - if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent)) { > > > + if (parent->i_sb->s_encoding && IS_CASEFOLDED(parent)) { > > > if (fname->cf_name.name) { > > > struct qstr cf = {.name = fname->cf_name.name, > > > .len = fname->cf_name.len}; > > > @@ -2171,9 +2171,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, > > > struct buffer_head *bh = NULL; > > > struct ext4_dir_entry_2 *de; > > > struct super_block *sb; > > > -#ifdef CONFIG_UNICODE > > > - struct ext4_sb_info *sbi; > > > -#endif > > > struct ext4_filename fname; > > > int retval; > > > int dx_fallback=0; > > > @@ -2190,9 +2187,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, > > > return -EINVAL; > > > > > > #ifdef CONFIG_UNICODE > > > - sbi = EXT4_SB(sb); > > > - if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) && > > > - sbi->s_encoding && utf8_validate(sbi->s_encoding, &dentry->d_name)) > > > + if (sb_has_strict_encoding(sb) && IS_CASEFOLDED(dir) && > > > + sb->s_encoding && utf8_validate(sb->s_encoding, &dentry->d_name)) > > > return -EINVAL; > > > > hm, just noticed the sb->s_encoding check here is superfluous, since the > > has_strict_mode() cannot be true if !s_encoding. Not related to this > > patch though. > > > > Daniel, are you still working on getting this upstream? The fscrypt > > support would be very useful for us. :) > > > > In the hope this will get upstream, as its been flying for a while and > > looks correct. > > > > Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.com> > > We couldn't get a response from Ted, so instead Jaegeuk has applied patches 1-3 > to f2fs/dev for 5.10. Hopefully Ted will take the ext4 patch for 5.11. > > I believe that Daniel is planning to resend the actual encryption+casefolding > support soon, but initially only for f2fs since that will be ready first. > > - Eric Yes, planning to send them shortly. Just checking that I've not missed anything. For the sb_has_strict_encoding, I don't think that's actually checking s_encoding, though it does check s_encoding_flags. I'm planning to resend this one with that set, since it's not queued in the f2fs tree. -Daniel
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 1d82336b1cd4..b437120f0b3f 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -669,68 +669,8 @@ const struct file_operations ext4_dir_operations = { }; #ifdef CONFIG_UNICODE -static int ext4_d_compare(const struct dentry *dentry, unsigned int len, - const char *str, const struct qstr *name) -{ - struct qstr qstr = {.name = str, .len = len }; - const struct dentry *parent = READ_ONCE(dentry->d_parent); - const struct inode *inode = READ_ONCE(parent->d_inode); - char strbuf[DNAME_INLINE_LEN]; - - if (!inode || !IS_CASEFOLDED(inode) || - !EXT4_SB(inode->i_sb)->s_encoding) { - if (len != name->len) - return -1; - return memcmp(str, name->name, len); - } - - /* - * If the dentry name is stored in-line, then it may be concurrently - * modified by a rename. If this happens, the VFS will eventually retry - * the lookup, so it doesn't matter what ->d_compare() returns. - * However, it's unsafe to call utf8_strncasecmp() with an unstable - * string. Therefore, we have to copy the name into a temporary buffer. - */ - if (len <= DNAME_INLINE_LEN - 1) { - memcpy(strbuf, str, len); - strbuf[len] = 0; - qstr.name = strbuf; - /* prevent compiler from optimizing out the temporary buffer */ - barrier(); - } - - return ext4_ci_compare(inode, name, &qstr, false); -} - -static int ext4_d_hash(const struct dentry *dentry, struct qstr *str) -{ - const struct ext4_sb_info *sbi = EXT4_SB(dentry->d_sb); - const struct unicode_map *um = sbi->s_encoding; - const struct inode *inode = READ_ONCE(dentry->d_inode); - unsigned char *norm; - int len, ret = 0; - - if (!inode || !IS_CASEFOLDED(inode) || !um) - return 0; - - norm = kmalloc(PATH_MAX, GFP_ATOMIC); - if (!norm) - return -ENOMEM; - - len = utf8_casefold(um, str, norm, PATH_MAX); - if (len < 0) { - if (ext4_has_strict_mode(sbi)) - ret = -EINVAL; - goto out; - } - str->hash = full_name_hash(dentry, norm, len); -out: - kfree(norm); - return ret; -} - const struct dentry_operations ext4_dentry_ops = { - .d_hash = ext4_d_hash, - .d_compare = ext4_d_compare, + .d_hash = generic_ci_d_hash, + .d_compare = generic_ci_d_compare, }; #endif diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 42f5060f3cdf..5cd8be24a4fd 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1393,14 +1393,6 @@ struct ext4_super_block { #define EXT4_ENC_UTF8_12_1 1 -/* - * Flags for ext4_sb_info.s_encoding_flags. - */ -#define EXT4_ENC_STRICT_MODE_FL (1 << 0) - -#define ext4_has_strict_mode(sbi) \ - (sbi->s_encoding_flags & EXT4_ENC_STRICT_MODE_FL) - /* * fourth extended-fs super-block data in memory */ @@ -1450,10 +1442,6 @@ struct ext4_sb_info { struct kobject s_kobj; struct completion s_kobj_unregister; struct super_block *s_sb; -#ifdef CONFIG_UNICODE - struct unicode_map *s_encoding; - __u16 s_encoding_flags; -#endif /* Journaling */ struct journal_s *s_journal; diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c index 3e133793a5a3..143b0073b3f4 100644 --- a/fs/ext4/hash.c +++ b/fs/ext4/hash.c @@ -275,7 +275,7 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len, struct dx_hash_info *hinfo) { #ifdef CONFIG_UNICODE - const struct unicode_map *um = EXT4_SB(dir->i_sb)->s_encoding; + const struct unicode_map *um = dir->i_sb->s_encoding; int r, dlen; unsigned char *buff; struct qstr qstr = {.name = name, .len = len }; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 56738b538ddf..6ffd53e6455e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1286,8 +1286,8 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block) int ext4_ci_compare(const struct inode *parent, const struct qstr *name, const struct qstr *entry, bool quick) { - const struct ext4_sb_info *sbi = EXT4_SB(parent->i_sb); - const struct unicode_map *um = sbi->s_encoding; + const struct super_block *sb = parent->i_sb; + const struct unicode_map *um = sb->s_encoding; int ret; if (quick) @@ -1299,7 +1299,7 @@ int ext4_ci_compare(const struct inode *parent, const struct qstr *name, /* Handle invalid character sequence as either an error * or as an opaque byte sequence. */ - if (ext4_has_strict_mode(sbi)) + if (sb_has_strict_encoding(sb)) return -EINVAL; if (name->len != entry->len) @@ -1316,7 +1316,7 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname, { int len; - if (!IS_CASEFOLDED(dir) || !EXT4_SB(dir->i_sb)->s_encoding) { + if (!IS_CASEFOLDED(dir) || !dir->i_sb->s_encoding) { cf_name->name = NULL; return; } @@ -1325,7 +1325,7 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname, if (!cf_name->name) return; - len = utf8_casefold(EXT4_SB(dir->i_sb)->s_encoding, + len = utf8_casefold(dir->i_sb->s_encoding, iname, cf_name->name, EXT4_NAME_LEN); if (len <= 0) { @@ -1362,7 +1362,7 @@ static inline bool ext4_match(const struct inode *parent, #endif #ifdef CONFIG_UNICODE - if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent)) { + if (parent->i_sb->s_encoding && IS_CASEFOLDED(parent)) { if (fname->cf_name.name) { struct qstr cf = {.name = fname->cf_name.name, .len = fname->cf_name.len}; @@ -2171,9 +2171,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, struct buffer_head *bh = NULL; struct ext4_dir_entry_2 *de; struct super_block *sb; -#ifdef CONFIG_UNICODE - struct ext4_sb_info *sbi; -#endif struct ext4_filename fname; int retval; int dx_fallback=0; @@ -2190,9 +2187,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, return -EINVAL; #ifdef CONFIG_UNICODE - sbi = EXT4_SB(sb); - if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) && - sbi->s_encoding && utf8_validate(sbi->s_encoding, &dentry->d_name)) + if (sb_has_strict_encoding(sb) && IS_CASEFOLDED(dir) && + sb->s_encoding && utf8_validate(sb->s_encoding, &dentry->d_name)) return -EINVAL; #endif diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 330957ed1f05..d097771a374f 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1102,7 +1102,7 @@ static void ext4_put_super(struct super_block *sb) fs_put_dax(sbi->s_daxdev); fscrypt_free_dummy_context(&sbi->s_dummy_enc_ctx); #ifdef CONFIG_UNICODE - utf8_unload(sbi->s_encoding); + utf8_unload(sb->s_encoding); #endif kfree(sbi); } @@ -4035,7 +4035,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount; #ifdef CONFIG_UNICODE - if (ext4_has_feature_casefold(sb) && !sbi->s_encoding) { + if (ext4_has_feature_casefold(sb) && !sb->s_encoding) { const struct ext4_sb_encodings *encoding_info; struct unicode_map *encoding; __u16 encoding_flags; @@ -4066,8 +4066,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) "%s-%s with flags 0x%hx", encoding_info->name, encoding_info->version?:"\b", encoding_flags); - sbi->s_encoding = encoding; - sbi->s_encoding_flags = encoding_flags; + sb->s_encoding = encoding; + sb->s_encoding_flags = encoding_flags; } #endif @@ -4678,7 +4678,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } #ifdef CONFIG_UNICODE - if (sbi->s_encoding) + if (sb->s_encoding) sb->s_d_op = &ext4_dentry_ops; #endif @@ -4873,7 +4873,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) crypto_free_shash(sbi->s_chksum_driver); #ifdef CONFIG_UNICODE - utf8_unload(sbi->s_encoding); + utf8_unload(sb->s_encoding); #endif #ifdef CONFIG_QUOTA