On Mon, Feb 12, 2024 at 09:13:14PM -0500, Gabriel Krisman Bertazi wrote: > Finally, we need to clean the dentry->flags even for unencrypted > dentries, so the ->d_lock might be acquired even for them. In order to might => must? > diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h > index 47567a6a4f9d..d1f17b90c30f 100644 > --- a/include/linux/fscrypt.h > +++ b/include/linux/fscrypt.h > @@ -951,10 +951,29 @@ static inline int fscrypt_prepare_rename(struct inode *old_dir, > static inline void fscrypt_prepare_dentry(struct dentry *dentry, > bool is_nokey_name) > { > + /* > + * This code tries to only take ->d_lock when necessary to write > + * to ->d_flags. We shouldn't be peeking on d_flags for > + * DCACHE_OP_REVALIDATE unlocked, but in the unlikely case > + * there is a race, the worst it can happen is that we fail to > + * unset DCACHE_OP_REVALIDATE and pay the cost of an extra > + * d_revalidate. > + */ > if (is_nokey_name) { > spin_lock(&dentry->d_lock); > dentry->d_flags |= DCACHE_NOKEY_NAME; > spin_unlock(&dentry->d_lock); > + } else if (dentry->d_flags & DCACHE_OP_REVALIDATE && > + dentry->d_op->d_revalidate == fscrypt_d_revalidate) { > + /* > + * Unencrypted dentries and encrypted dentries where the > + * key is available are always valid from fscrypt > + * perspective. Avoid the cost of calling > + * fscrypt_d_revalidate unnecessarily. > + */ > + spin_lock(&dentry->d_lock); > + dentry->d_flags &= ~DCACHE_OP_REVALIDATE; > + spin_unlock(&dentry->d_lock); > } > } Does this all get optimized out when !CONFIG_FS_ENCRYPTION? As-is, I don't think the d_revalidate part will be optimized out. You may need to create a !CONFIG_FS_ENCRYPTION stub explicitly. - Eric