From owner-svn-src-projects@freebsd.org Fri Apr 26 19:47:44 2019 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 86748159C8B5 for ; Fri, 26 Apr 2019 19:47:44 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2AC7182E4A; Fri, 26 Apr 2019 19:47:44 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E2B4618592; Fri, 26 Apr 2019 19:47:43 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x3QJlhfA087705; Fri, 26 Apr 2019 19:47:43 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x3QJlhn7087703; Fri, 26 Apr 2019 19:47:43 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201904261947.x3QJlhn7087703@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Fri, 26 Apr 2019 19:47:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r346763 - projects/fuse2/sys/fs/fuse X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: projects/fuse2/sys/fs/fuse X-SVN-Commit-Revision: 346763 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 2AC7182E4A X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.98 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.997,0]; NEURAL_HAM_SHORT(-0.98)[-0.981,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Apr 2019 19:47:44 -0000 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);