On Mon, May 02, 2022 at 03:55:21PM +0530, Dharmendra Singh wrote:
From: Dharmendra Singh <dsingh@xxxxxxx>
With atomic open + lookup implemented, it is possible
to avoid lookups in FUSE d_revalidate() for objects
other than directories.
If FUSE is mounted with default permissions then this
optimization is not possible as we need to fetch fresh
inode attributes for permission check. This lookup
skipped in d_revalidate() can be performed as part of
open call into libfuse which is made from fuse_file_open().
And when we return from USER SPACE with file opened and
fresh attributes, we can revalidate the inode.
Signed-off-by: Dharmendra Singh <dsingh@xxxxxxx>
Reported-by: kernel test robot <lkp@xxxxxxxxx>
---
fs/fuse/dir.c | 89 ++++++++++++++++++++++++++++++++++++++++++------
fs/fuse/file.c | 30 ++++++++++++++--
fs/fuse/fuse_i.h | 10 +++++-
fs/fuse/ioctl.c | 2 +-
4 files changed, 115 insertions(+), 16 deletions(-)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 6879d3a86796..1594fecc920f 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -196,6 +196,7 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
* the lookup once more. If the lookup results in the same inode,
* then refresh the attributes, timeouts and mark the dentry valid.
*/
+
static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
{
struct inode *inode;
@@ -224,6 +225,17 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
fm = get_fuse_mount(inode);
+ /* If atomic open is supported by FUSE then use this opportunity
+ * (only for non-dir) to avoid this lookup and combine
+ * lookup + open into single call.
+ */
+ if (!fm->fc->default_permissions && fm->fc->do_atomic_open &&
+ !(flags & (LOOKUP_EXCL | LOOKUP_REVAL)) &&
+ (flags & LOOKUP_OPEN) && !S_ISDIR(inode->i_mode)) {
+ ret = 1;
So basically we think that VFS is going to do OPEN and calling
->revalidate() before that. So we are returning "1" to vfs saying
dentry is valid (despite the fact that we have no idea at this
point of time).
And later when open comes we are opening and revalidating inode etc.
Seriously, IMHO, all this seems very fragile and hard to understand
and maintain code. Things can go easily wrong if even little bit
of assumptions change in VFS.
This sounds more like VFS should know about it and if VFS knows
that filesystem supports facility where it can open + revalidate
at the same time, it should probably call that. Something like
->open_revalidate() etc. That would be much more maintainable code but
this feels like very fragile to me, IMHO.