From 1ba8834cfaccea071971847977ebe6f3bcd0817c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Tue, 19 Dec 2023 22:53:40 -0500 Subject: [PATCH] document-portal: Don't invalidate directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes issue #1234. This is a followup from #1190. fuse_lowlevel_notify_inval_entry() will invalidate directories too, which is a problem as it invalidate the current workdir directory. So now we don't invalidate them and will let the kernel deal with it. This is consistent with the passthrough_hp example from fuse. Signed-off-by: Hubert Figuière --- document-portal/document-portal-fuse.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/document-portal/document-portal-fuse.c b/document-portal/document-portal-fuse.c index 8d2e107d6..f8a95abd7 100644 --- a/document-portal/document-portal-fuse.c +++ b/document-portal/document-portal-fuse.c @@ -109,7 +109,7 @@ * referenced by the dcache (Directory Entry Cache) (even though we * will not really use the dcache info due to the 0 valid time). This * is unfortunate, because it means we will keep a lot of file - * descriptor open. But, we can not know if the kernel needs the inode + * descriptors open. But, we can not know if the kernel needs the inode * for some non-dcache use so we can't close the file descriptors. * * To work around this we regularly emit entry invalidation calls @@ -947,7 +947,7 @@ verify_doc_dir_devino (int dirfd, XdpDomain *doc_domain) return -ENOENT; return 0; - } +} /* Only for toplevel dirs, not this is a bit weird for toplevel dir inodes as it returns the dir itself which isn't really the dirfd @@ -1659,7 +1659,7 @@ ensure_docdir_inode (XdpInode *parent, inode->domain_root_inode = xdp_inode_ref (parent->domain_root_inode); else inode->domain_root_inode = xdp_inode_ref (parent); - g_hash_table_insert (domain->inodes, physical, inode); + g_hash_table_insert (domain->inodes, physical, inode); } G_UNLOCK(domain_inodes); @@ -1847,17 +1847,21 @@ xdp_fuse_lookup (fuse_req_t req, } else { + g_autoptr(XdpInode) inode = NULL; + struct stat buf; + g_assert (parent_domain->type == XDP_DOMAIN_DOCUMENT); fd = xdp_document_inode_open_child_fd (parent, name, open_flags, 0); if (fd < 0) return xdp_reply_err (op, req, -fd); - res = ensure_docdir_inode (parent, fd, &e, NULL); /* Takes ownership of fd */ + res = ensure_docdir_inode (parent, fd, &e, &inode); /* Takes ownership of fd */ if (res != 0) return xdp_reply_err (op, req, -res); - queue_invalidate_dentry (parent, name); + if (fstat (inode->physical->fd, &buf) != 0 || !S_ISDIR(buf.st_mode)) + queue_invalidate_dentry (parent, name); } g_debug ("LOOKUP %lx:%s => %lx", parent_ino, name, e.ino); @@ -2360,7 +2364,7 @@ xdp_fuse_opendir (fuse_req_t req, } } - fi->fh = (gsize)d; + fi->fh = (gsize)d; if (fuse_reply_open (req, fi) == -ENOENT) {