This patchset is still a bit of a work in progress, and I've not tested the performance impact. It currently uses strncmp to compare paths but this might be able to be optimized into a hash comparison first. It should also normally only need to do it for one pair of filenames, as the test is only done if qid.path matches in the first place. Also, currently the inode is not reused in cached mode if mtime changed AND the dentry was evicted -- I considered removing the qid.version test in v9fs_test_inode_dotl but I think perhaps care needs to be taken to ensure we can refresh an inode that potentially has data cached? This is a TODO for this patchset. Another TODO is to maybe add support for case-insensitive matching? For this patch series I've tested modifying files on both host and guest, changing a file from regular file to dir then back while preserving ino, keeping a file open in the guest with a fd, and using Landlock (which results in an ihold but does not keep the dentry) then trying to access the file from both inside and outside the Landlocked shell. Let me know what's your thought on this -- if this is a viable approach I'm happy to work on it more and do more testing. The main motivation behind this is getting Landlock to work "out of the box" on 9pfs. This patch series was based on, and tested on v6.14 + [5] Kind regards, Tingmao [1]: https://github.com/landlock-lsm/linux/issues/45 [2]: https://lore.kernel.org/all/20241024-revert_iget-v1-4-4cac63d25f72@xxxxxxxxxxxxx/ [3]: https://lore.kernel.org/all/20240923100508.GA32066@willie-the-truck/ [4]: https://wiki.qemu.org/Documentation/9p#Protocol_Plans [5]: https://lore.kernel.org/all/cover.1743956147.git.m@xxxxxxxxxx/ fanotify-basic-open.c: #define _GNU_SOURCE /* Needed to get O_LARGEFILE definition */ #include <errno.h> #include <fcntl.h> #include <limits.h> #include <poll.h> #include <stdio.h> #include <stdlib.h> #include <sys/fanotify.h> #include <unistd.h> /* Read all available fanotify events from the file descriptor 'fd'. */ static void handle_events(int fd) { const struct fanotify_event_metadata *metadata; struct fanotify_event_metadata buf[200]; ssize_t size; char path[PATH_MAX]; ssize_t path_len; char procfd_path[PATH_MAX]; struct fanotify_response response; for (;;) { size = read(fd, buf, sizeof(buf)); if (size == -1 && errno != EAGAIN) { perror("read"); exit(EXIT_FAILURE); } /* Check if end of available data reached. */ if (size <= 0) break; /* Point to the first event in the buffer. */ metadata = buf; /* Loop over all events in the buffer. */ while (FAN_EVENT_OK(metadata, size)) { if (metadata->fd >= 0) { if (metadata->mask & FAN_OPEN) { printf("FAN_OPEN: "); } /* Retrieve and print pathname of the accessed file. */ snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d", metadata->fd); path_len = readlink(procfd_path, path, sizeof(path) - 1); if (path_len == -1) { perror("readlink"); exit(EXIT_FAILURE); } path[path_len] = '\0'; printf("File %s\n", path); /* Close the file descriptor of the event. */ close(metadata->fd); } /* Advance to next event. */ metadata = FAN_EVENT_NEXT(metadata, size); } } } int main(int argc, char *argv[]) { char buf; int fd, poll_num; nfds_t nfds; struct pollfd fds[2]; /* Check mount point is supplied. */ if (argc != 2) { fprintf(stderr, "Usage: %s FILE\n", argv[0]); exit(EXIT_FAILURE); } fd = fanotify_init(0, O_RDONLY | O_LARGEFILE); if (fd == -1) { perror("fanotify_init"); exit(EXIT_FAILURE); } if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_INODE, FAN_OPEN, AT_FDCWD, argv[1]) == -1) { perror("fanotify_mark"); exit(EXIT_FAILURE); } while (1) { handle_events(fd); } } Tingmao Wang (6): fs/9p: Add ability to identify inode by path for .L fs/9p: add default option for path-based inodes fs/9p: Hide inodeident=path from show_options as it is the default fs/9p: Add ability to identify inode by path for non-.L fs/9p: .L: Refresh stale inodes on reuse fs/9p: non-.L: Refresh stale inodes on reuse fs/9p/Makefile | 3 +- fs/9p/ino_path.c | 114 ++++++++++++++++++++++++++++++++++++++ fs/9p/v9fs.c | 33 ++++++++++- fs/9p/v9fs.h | 63 +++++++++++++++------ fs/9p/vfs_inode.c | 122 +++++++++++++++++++++++++++++++++++------ fs/9p/vfs_inode_dotl.c | 108 +++++++++++++++++++++++++++++++++--- fs/9p/vfs_super.c | 10 +++- 7 files changed, 406 insertions(+), 47 deletions(-) create mode 100644 fs/9p/ino_path.c base-commit: 38fec10eb60d687e30c8c6b5420d86e8149f7557 prerequisite-patch-id: 12dc6676db52ff32eed082b1e5d273f297737f61 prerequisite-patch-id: 93ab54c52a41fa44b8d0baf55df949d0ad27e99a prerequisite-patch-id: 5f558bf969e6eaa3d011c98de0806ca8ad369efe -- 2.39.5