From owner-svn-src-projects@freebsd.org Thu Apr 4 20:30:16 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 CF3631556A74 for ; Thu, 4 Apr 2019 20:30:16 +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 780708B69C; Thu, 4 Apr 2019 20:30:16 +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 460F028D3; Thu, 4 Apr 2019 20:30:16 +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 x34KUGMb030143; Thu, 4 Apr 2019 20:30:16 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x34KUFSw030138; Thu, 4 Apr 2019 20:30:15 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201904042030.x34KUFSw030138@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Thu, 4 Apr 2019 20:30:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r345892 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs X-SVN-Commit-Revision: 345892 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 780708B69C X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.97)[-0.965,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] 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: Thu, 04 Apr 2019 20:30:17 -0000 Author: asomers Date: Thu Apr 4 20:30:14 2019 New Revision: 345892 URL: https://svnweb.freebsd.org/changeset/base/345892 Log: fusefs: properly handle FOPEN_KEEP_CACHE If a fuse file system returne FOPEN_KEEP_CACHE in the open or create response, then the client is supposed to _not_ clear its caches for that file. I don't know why clearing the caches would be the default given that there's a separate flag to bypass the cache altogether, but that's the way it is. fusefs(5) will now honor this flag. Our behavior is slightly different than Linux's because we reuse file handles. That means that open(2) wont't clear the cache if there's a reusable file handle, even if the file server wouldn't have sent FOPEN_KEEP_CACHE had we opened a new file handle like Linux does. PR: 236560 Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_file.c projects/fuse2/sys/fs/fuse/fuse_file.h projects/fuse2/sys/fs/fuse/fuse_node.c projects/fuse2/sys/fs/fuse/fuse_vnops.c projects/fuse2/tests/sys/fs/fusefs/read.cc Modified: projects/fuse2/sys/fs/fuse/fuse_file.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.c Thu Apr 4 20:27:13 2019 (r345891) +++ projects/fuse2/sys/fs/fuse/fuse_file.c Thu Apr 4 20:30:14 2019 (r345892) @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include "fuse.h" #include "fuse_file.h" #include "fuse_internal.h" +#include "fuse_io.h" #include "fuse_ipc.h" #include "fuse_node.h" @@ -188,9 +189,7 @@ fuse_filehandle_open(struct vnode *vp, int a_mode, } foo = fdi.answ; - fuse_filehandle_init(vp, fufh_type, fufhp, td->td_proc->p_pid, cred, - foo); - + fuse_filehandle_init(vp, fufh_type, fufhp, td, cred, foo); fuse_vnode_open(vp, foo->open_flags, td); out: @@ -322,7 +321,7 @@ fuse_filehandle_getrw(struct vnode *vp, int fflag, void fuse_filehandle_init(struct vnode *vp, fufh_type_t fufh_type, - struct fuse_filehandle **fufhp, pid_t pid, struct ucred *cred, + struct fuse_filehandle **fufhp, struct thread *td, struct ucred *cred, struct fuse_open_out *foo) { struct fuse_vnode_data *fvdat = VTOFUD(vp); @@ -335,7 +334,7 @@ fuse_filehandle_init(struct vnode *vp, fufh_type_t fuf fufh->fufh_type = fufh_type; fufh->gid = cred->cr_rgid; fufh->uid = cred->cr_uid; - fufh->pid = pid; + fufh->pid = td->td_proc->p_pid; fufh->fuse_open_flags = foo->open_flags; if (!FUFH_IS_VALID(fufh)) { panic("FUSE: init: invalid filehandle id (type=%d)", fufh_type); @@ -345,4 +344,15 @@ fuse_filehandle_init(struct vnode *vp, fufh_type_t fuf *fufhp = fufh; atomic_add_acq_int(&fuse_fh_count, 1); + + if (foo->open_flags & FOPEN_DIRECT_IO) { + ASSERT_VOP_ELOCKED(vp, __func__); + VTOFUD(vp)->flag |= FN_DIRECTIO; + fuse_io_invalbuf(vp, td); + } else { + if ((foo->open_flags & FOPEN_KEEP_CACHE) == 0) + fuse_io_invalbuf(vp, td); + VTOFUD(vp)->flag &= ~FN_DIRECTIO; + } + } Modified: projects/fuse2/sys/fs/fuse/fuse_file.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.h Thu Apr 4 20:27:13 2019 (r345891) +++ projects/fuse2/sys/fs/fuse/fuse_file.h Thu Apr 4 20:30:14 2019 (r345892) @@ -158,7 +158,7 @@ int fuse_filehandle_getrw(struct vnode *vp, int fflag, pid_t pid); void fuse_filehandle_init(struct vnode *vp, fufh_type_t fufh_type, - struct fuse_filehandle **fufhp, pid_t pid, + struct fuse_filehandle **fufhp, struct thread *td, struct ucred *cred, struct fuse_open_out *foo); int fuse_filehandle_open(struct vnode *vp, int mode, struct fuse_filehandle **fufhp, struct thread *td, Modified: projects/fuse2/sys/fs/fuse/fuse_node.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_node.c Thu Apr 4 20:27:13 2019 (r345891) +++ projects/fuse2/sys/fs/fuse/fuse_node.c Thu Apr 4 20:30:14 2019 (r345892) @@ -329,16 +329,6 @@ fuse_vnode_open(struct vnode *vp, int32_t fuse_open_fl * * XXXIP: Handle fd based DIRECT_IO */ - if (fuse_open_flags & FOPEN_DIRECT_IO) { - ASSERT_VOP_ELOCKED(vp, __func__); - VTOFUD(vp)->flag |= FN_DIRECTIO; - fuse_io_invalbuf(vp, td); - } else { - if ((fuse_open_flags & FOPEN_KEEP_CACHE) == 0) - fuse_io_invalbuf(vp, td); - VTOFUD(vp)->flag &= ~FN_DIRECTIO; - } - if (vnode_vtype(vp) == VREG) { /* XXXIP prevent getattr, by using cached node size */ vnode_create_vobject(vp, 0, td); Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vnops.c Thu Apr 4 20:27:13 2019 (r345891) +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Thu Apr 4 20:30:14 2019 (r345892) @@ -479,8 +479,7 @@ fuse_vnop_create(struct vop_create_args *ap) } ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create"); - fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, td->td_proc->p_pid, cred, - foo); + fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, td, cred, foo); fuse_vnode_open(*vpp, foo->open_flags, td); cache_purge_negative(dvp); Modified: projects/fuse2/tests/sys/fs/fusefs/read.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/read.cc Thu Apr 4 20:27:13 2019 (r345891) +++ projects/fuse2/tests/sys/fs/fusefs/read.cc Thu Apr 4 20:30:14 2019 (r345892) @@ -398,8 +398,7 @@ TEST_F(Read, eio) * With the keep_cache option, the kernel may keep its read cache across * multiple open(2)s. */ -/* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236560 */ -TEST_F(Read, DISABLED_keep_cache) +TEST_F(Read, keep_cache) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -410,7 +409,7 @@ TEST_F(Read, DISABLED_keep_cache) char buf[bufsize]; FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2); - expect_open(ino, FOPEN_KEEP_CACHE, 1); + expect_open(ino, FOPEN_KEEP_CACHE, 2); expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); @@ -418,7 +417,7 @@ TEST_F(Read, DISABLED_keep_cache) ASSERT_LE(0, fd0) << strerror(errno); ASSERT_EQ(bufsize, read(fd0, buf, bufsize)) << strerror(errno); - fd1 = open(FULLPATH, O_RDONLY); + fd1 = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd1) << strerror(errno); /* @@ -445,7 +444,7 @@ TEST_F(Read, keep_cache_disabled) char buf[bufsize]; FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, bufsize, 2); - expect_open(ino, FOPEN_KEEP_CACHE, 1); + expect_open(ino, 0, 2); expect_getattr(ino, bufsize); expect_read(ino, 0, bufsize, bufsize, CONTENTS); @@ -453,7 +452,7 @@ TEST_F(Read, keep_cache_disabled) ASSERT_LE(0, fd0) << strerror(errno); ASSERT_EQ(bufsize, read(fd0, buf, bufsize)) << strerror(errno); - fd1 = open(FULLPATH, O_RDONLY); + fd1 = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd1) << strerror(errno); /*