git: 2b4a45992a04 - stable/13 - fusefs: FUSE_NOTIFY_INVAL_* must busy the mountpoint
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 20 Jan 2025 22:33:10 UTC
The branch stable/13 has been updated by asomers:
URL: https://cgit.FreeBSD.org/src/commit/?id=2b4a45992a043459ab0d63410059822a2efb6045
commit 2b4a45992a043459ab0d63410059822a2efb6045
Author: Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2024-12-13 14:00:20 +0000
Commit: Alan Somers <asomers@FreeBSD.org>
CommitDate: 2025-01-20 22:31:29 +0000
fusefs: FUSE_NOTIFY_INVAL_* must busy the mountpoint
Unusually, the FUSE_NOTIFY_INVAL_INODE and FUSE_NOTIFY_INVAL_ENTRY
messages are fully asynchronous. The server sends them to the kernel
unsolicited. That means that unlike every other fuse message coming
from the server, these two arrive to a potentially unbusied mountpoint.
So they must explicitly busy it. Otherwise a page fault could result if
the mountpoint were being unmounted.
Reported by: JSML4ThWwBID69YC@protonmail.com
(cherry picked from commit 989998529387b4d98dfaa6c499ad88b006f78de8)
---
sys/fs/fuse/fuse_device.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c
index 88ebe702ec0a..7b163bc04bc2 100644
--- a/sys/fs/fuse/fuse_device.c
+++ b/sys/fs/fuse/fuse_device.c
@@ -440,7 +440,6 @@ fuse_device_write(struct cdev *dev, struct uio *uio, int ioflag)
err = devfs_get_cdevpriv((void **)&data);
if (err != 0)
return (err);
- mp = data->mp;
if (uio->uio_resid < sizeof(struct fuse_out_header)) {
SDT_PROBE2(fusefs, , device, trace, 1,
@@ -543,6 +542,13 @@ fuse_device_write(struct cdev *dev, struct uio *uio, int ioflag)
} else if (ohead.unique == 0){
/* unique == 0 means asynchronous notification */
SDT_PROBE1(fusefs, , device, fuse_device_write_notify, &ohead);
+ mp = data->mp;
+ vfs_ref(mp);
+ err = vfs_busy(mp, 0);
+ vfs_rel(mp);
+ if (err)
+ return (err);
+
switch (ohead.error) {
case FUSE_NOTIFY_INVAL_ENTRY:
err = fuse_internal_invalidate_entry(mp, uio);
@@ -567,6 +573,7 @@ fuse_device_write(struct cdev *dev, struct uio *uio, int ioflag)
/* Not implemented */
err = ENOSYS;
}
+ vfs_unbusy(mp);
} else {
/* no callback at all! */
SDT_PROBE1(fusefs, , device, fuse_device_write_missing_ticket,