svn commit: r346763 - projects/fuse2/sys/fs/fuse
Alan Somers
asomers at FreeBSD.org
Fri Apr 26 19:47:44 UTC 2019
Author: asomers
Date: Fri Apr 26 19:47:43 2019
New Revision: 346763
URL: https://svnweb.freebsd.org/changeset/base/346763
Log:
fusefs: fix a deadlock in VOP_PUTPAGES
As of r346162 fuse now invalidates the cache during writes. But it can't do
that when writing from VOP_PUTPAGES, because the write is coming _from_ the
cache. Trying to invalidate the cache in that situation causes a deadlock
in vm_object_page_remove, because the pages in question have already been
busied by the same thread.
PR: 235774
Sponsored by: The FreeBSD Foundation
Modified:
projects/fuse2/sys/fs/fuse/fuse_io.c
projects/fuse2/sys/fs/fuse/fuse_io.h
projects/fuse2/sys/fs/fuse/fuse_vnops.c
Modified: projects/fuse2/sys/fs/fuse/fuse_io.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_io.c Fri Apr 26 19:02:21 2019 (r346762)
+++ projects/fuse2/sys/fs/fuse/fuse_io.c Fri Apr 26 19:47:43 2019 (r346763)
@@ -122,7 +122,7 @@ fuse_write_biobackend(struct vnode *vp, struct uio *ui
SDT_PROBE_DEFINE5(fusefs, , io, io_dispatch, "struct vnode*", "struct uio*",
"int", "struct ucred*", "struct fuse_filehandle*");
int
-fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
+fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag, bool pages,
struct ucred *cred, pid_t pid)
{
struct fuse_filehandle *fufh;
@@ -172,13 +172,20 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, in
* cached.
*/
if (directio || fuse_data_cache_mode == FUSE_CACHE_WT) {
+ const int iosize = fuse_iosize(vp);
off_t start, end;
SDT_PROBE2(fusefs, , io, trace, 1,
"direct write of vnode");
start = uio->uio_offset;
end = start + uio->uio_resid;
- v_inval_buf_range(vp, start, end, fuse_iosize(vp));
+ /*
+ * Invalidate the write cache unless we're coming from
+ * VOP_PUTPAGES, in which case we're writing _from_ the
+ * write cache
+ */
+ if (!pages )
+ v_inval_buf_range(vp, start, end, iosize);
err = fuse_write_directbackend(vp, uio, cred, fufh,
ioflag);
} else {
Modified: projects/fuse2/sys/fs/fuse/fuse_io.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_io.h Fri Apr 26 19:02:21 2019 (r346762)
+++ projects/fuse2/sys/fs/fuse/fuse_io.h Fri Apr 26 19:47:43 2019 (r346763)
@@ -60,7 +60,7 @@
#ifndef _FUSE_IO_H_
#define _FUSE_IO_H_
-int fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
+int fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag, bool pages,
struct ucred *cred, pid_t pid);
int fuse_io_strategy(struct vnode *vp, struct buf *bp);
int fuse_io_flushbuf(struct vnode *vp, int waitfor, struct thread *td);
Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c Fri Apr 26 19:02:21 2019 (r346762)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Fri Apr 26 19:47:43 2019 (r346763)
@@ -1222,7 +1222,7 @@ fuse_vnop_read(struct vop_read_args *ap)
ioflag |= IO_DIRECT;
}
- return fuse_io_dispatch(vp, uio, ioflag, cred, pid);
+ return fuse_io_dispatch(vp, uio, ioflag, false, cred, pid);
}
/*
@@ -1729,7 +1729,7 @@ fuse_vnop_write(struct vop_write_args *ap)
ioflag |= IO_DIRECT;
}
- return fuse_io_dispatch(vp, uio, ioflag, cred, pid);
+ return fuse_io_dispatch(vp, uio, ioflag, false, cred, pid);
}
SDT_PROBE_DEFINE1(fusefs, , vnops, vnop_getpages_error, "int");
@@ -1803,7 +1803,7 @@ fuse_vnop_getpages(struct vop_getpages_args *ap)
uio.uio_rw = UIO_READ;
uio.uio_td = td;
- error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred, pid);
+ error = fuse_io_dispatch(vp, &uio, IO_DIRECT, true, cred, pid);
pmap_qremove(kva, npages);
uma_zfree(fuse_pbuf_zone, bp);
@@ -1936,7 +1936,7 @@ fuse_vnop_putpages(struct vop_putpages_args *ap)
uio.uio_rw = UIO_WRITE;
uio.uio_td = td;
- error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred, pid);
+ error = fuse_io_dispatch(vp, &uio, IO_DIRECT, true, cred, pid);
pmap_qremove(kva, npages);
uma_zfree(fuse_pbuf_zone, bp);
More information about the svn-src-projects
mailing list