From owner-svn-src-projects@freebsd.org Fri Jun 14 19:47:50 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 15AFF15AFD35 for ; Fri, 14 Jun 2019 19:47:50 +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 AF14D76777; Fri, 14 Jun 2019 19:47:49 +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 7B15C1C648; Fri, 14 Jun 2019 19:47:49 +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 x5EJlnAW060275; Fri, 14 Jun 2019 19:47:49 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x5EJlnqu060274; Fri, 14 Jun 2019 19:47:49 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201906141947.x5EJlnqu060274@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Fri, 14 Jun 2019 19:47:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r349038 - 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: 349038 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: AF14D76777 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_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.96)[-0.960,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: Fri, 14 Jun 2019 19:47:50 -0000 Author: asomers Date: Fri Jun 14 19:47:48 2019 New Revision: 349038 URL: https://svnweb.freebsd.org/changeset/base/349038 Log: fusefs: fix the "write-through" of write-through cacheing Our fusefs(5) module supports three cache modes: uncached, write-through, and write-back. However, the write-through mode (which is the default) has never actually worked as its name suggests. Rather, it's always been more like "write-around". It wrote directly, bypassing the cache. The cache would only be populated by a subsequent read of the same data. This commit fixes that problem. Now the write-through mode works as one would expect: write(2) immediately adds data to the cache and then blocks while the daemon processes the write operation. A side effect of this change is that non-cache-block-aligned writes will now incur a read-modify-write cycle of the cache block. The old behavior (bypassing write cache entirely) can still be achieved by opening a file with O_DIRECT. PR: 237588 Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_io.c projects/fuse2/tests/sys/fs/fusefs/write.cc Modified: projects/fuse2/sys/fs/fuse/fuse_io.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_io.c Fri Jun 14 18:33:41 2019 (r349037) +++ projects/fuse2/sys/fs/fuse/fuse_io.c Fri Jun 14 19:47:48 2019 (r349038) @@ -219,13 +219,7 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, in } break; case UIO_WRITE: - /* - * Kludge: simulate write-through caching via write-around - * caching. Same effect, as far as never caching dirty data, - * but slightly pessimal in that newly written data is not - * cached. - */ - if (directio || fuse_data_cache_mode == FUSE_CACHE_WT) { + if (directio) { const int iosize = fuse_iosize(vp); off_t start, end, filesize; @@ -250,6 +244,8 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, in } else { SDT_PROBE2(fusefs, , io, trace, 1, "buffered write of vnode"); + if (fuse_data_cache_mode == FUSE_CACHE_WT) + ioflag |= IO_SYNC; err = fuse_write_biobackend(vp, uio, cred, fufh, ioflag, pid); } Modified: projects/fuse2/tests/sys/fs/fusefs/write.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/write.cc Fri Jun 14 18:33:41 2019 (r349037) +++ projects/fuse2/tests/sys/fs/fusefs/write.cc Fri Jun 14 19:47:48 2019 (r349038) @@ -531,60 +531,13 @@ TEST_F(Write, mmap) free(zeros); } -/* In WriteThrough mode, a write should evict overlapping cached data */ -TEST_F(WriteThrough, evicts_read_cache) -{ - const char FULLPATH[] = "mountpoint/some_file.txt"; - const char RELPATH[] = "some_file.txt"; - ssize_t bufsize = 65536; - /* End the write in the middle of a page */ - ssize_t wrsize = bufsize - 1000; - char *contents0, *contents1, *readbuf, *expected; - uint64_t ino = 42; - int fd; - - contents0 = (char*)malloc(bufsize); - memset(contents0, 'X', bufsize); - contents0[bufsize - 1] = '\0'; // Null-terminate - contents1 = (char*)malloc(wrsize); - memset(contents1, 'Y', wrsize); - readbuf = (char*)calloc(bufsize, 1); - expected = (char*)malloc(bufsize); - memset(expected, 'Y', wrsize); - memset(expected + wrsize, 'X', bufsize - wrsize); - expected[bufsize - 1] = '\0'; // Null-terminate - - expect_lookup(RELPATH, ino, bufsize); - expect_open(ino, 0, 1); - expect_read(ino, 0, bufsize, bufsize, contents0); - expect_write(ino, 0, wrsize, wrsize, contents1); - - fd = open(FULLPATH, O_RDWR); - EXPECT_LE(0, fd) << strerror(errno); - - // Prime cache - ASSERT_EQ(bufsize, read(fd, readbuf, bufsize)) << strerror(errno); - - // Write directly, evicting cache - ASSERT_EQ(0, lseek(fd, 0, SEEK_SET)) << strerror(errno); - ASSERT_EQ(wrsize, write(fd, contents1, wrsize)) << strerror(errno); - - // Read again. Cache should be bypassed - expect_read(ino, 0, bufsize, bufsize, expected); - ASSERT_EQ(0, lseek(fd, 0, SEEK_SET)) << strerror(errno); - ASSERT_EQ(bufsize, read(fd, readbuf, bufsize)) << strerror(errno); - ASSERT_STREQ(readbuf, expected); - - /* Deliberately leak fd. close(2) will be tested in release.cc */ -} - TEST_F(WriteThrough, pwrite) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; const char *CONTENTS = "abcdefgh"; uint64_t ino = 42; - uint64_t offset = 4096; + uint64_t offset = 65536; int fd; ssize_t bufsize = strlen(CONTENTS); @@ -901,11 +854,7 @@ TEST_F(WriteBack, o_direct) /* * Without direct_io, writes should be committed to cache */ -/* - * Disabled because we don't yet implement write-through caching. No bugzilla - * entry, because that's a feature request, not a bug. - */ -TEST_F(WriteThrough, DISABLED_writethrough) +TEST_F(WriteThrough, writethrough) { const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; @@ -927,6 +876,7 @@ TEST_F(WriteThrough, DISABLED_writethrough) * A subsequent read should be serviced by cache, without querying the * filesystem daemon */ + ASSERT_EQ(0, lseek(fd, 0, SEEK_SET)) << strerror(errno); ASSERT_EQ(bufsize, read(fd, readbuf, bufsize)) << strerror(errno); /* Deliberately leak fd. close(2) will be tested in release.cc */ }