On Thu, Dec 21, 2023 at 07:39:40AM +0000, Al Viro wrote: > Hmm... Could we simply set ->s_d_op to &fscrypt_dentry_ops in non-ci case > *AND* have __fscrypt_prepare_lookup() clear DCACHE_OP_REVALIDATE in case > when it's not setting DCACHE_NOKEY_NAME and ->d_op->d_revalidate is > equal to fscrypt_d_revalidate? I mean, > > spin_lock(&dentry->d_lock); > if (fname->is_nokey_name) > dentry->d_flags |= DCACHE_NOKEY_NAME; > else if (dentry->d_flags & DCACHE_OP_REVALIDATE && > dentry->d_op->d_revalidate == fscrypt_d_revalidate) > dentry->d_flags &= ~DCACHE_OP_REVALIDATE; > spin_unlock(&dentry->d_lock); > > here + always set ->s_d_op for ext4 and friends (conditional upon > the CONFIG_UNICODE). > > No encryption - fine, you get ->is_nokey_name false from the very > beginning, DCACHE_OP_REVALIDATE is cleared and VFS won't ever call > ->d_revalidate(); not even the first time. > > Yes, you pay minimal price in dentry_unlink_inode() when we hit > if (dentry->d_op && dentry->d_op->d_iput) > and bugger off after the second fetch instead of the first one. > I would be quite surprised if it turns out to be measurable, > but if it is, we can always add DCACHE_OP_IPUT to flags. > Similar for ->d_op->d_release (called in the end of > __dentry_kill()). Again, that only makes sense if we get > a measurable overhead from that. fscrypt_prepare_lookup() handles unencrypted directories inline, without calling __fscrypt_prepare_lookup() which is only for encrypted directories. So the logic to clear DCACHE_OP_REVALIDATE would need to be there too. - Eric