From owner-svn-src-projects@freebsd.org Sun May 26 03:52:37 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 DE21C15BE96E for ; Sun, 26 May 2019 03:52:36 +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 83DF16FBD3; Sun, 26 May 2019 03:52:36 +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 6EF62E404; Sun, 26 May 2019 03:52:36 +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 x4Q3qaEs010756; Sun, 26 May 2019 03:52:36 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4Q3qZBT010750; Sun, 26 May 2019 03:52:35 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905260352.x4Q3qZBT010750@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Sun, 26 May 2019 03:52:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348285 - projects/fuse2/tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: projects/fuse2/tests/sys/fs/fusefs X-SVN-Commit-Revision: 348285 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 83DF16FBD3 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.95 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.95)[-0.951,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: Sun, 26 May 2019 03:52:37 -0000 Author: asomers Date: Sun May 26 03:52:35 2019 New Revision: 348285 URL: https://svnweb.freebsd.org/changeset/base/348285 Log: fusefs: more build fixes * Fix printf format strings on 32-bit OSes * Fix -Wclass-memaccess violation on GCC-8 caused by using memset on an object of non-trivial type. * Fix memory leak in MockFS::init * Fix -Wcast-align error on i386 in expect_readdir * Fix some heterogenous comparison errors on 32-bit OSes. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.hh projects/fuse2/tests/sys/fs/fusefs/read.cc projects/fuse2/tests/sys/fs/fusefs/setattr.cc projects/fuse2/tests/sys/fs/fusefs/utils.cc Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sat May 25 23:58:09 2019 (r348284) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sun May 26 03:52:35 2019 (r348285) @@ -48,6 +48,8 @@ extern "C" { #include "mntopts.h" // for build_iovec } +#include + #include #include "mockfs.hh" @@ -153,10 +155,10 @@ void sigint_handler(int __unused sig) { void debug_fuseop(const mockfs_buf_in *in) { - printf("%-11s ino=%2lu", opcode2opname(in->header.opcode), + printf("%-11s ino=%2" PRIu64, opcode2opname(in->header.opcode), in->header.nodeid); if (verbosity > 1) { - printf(" uid=%5u gid=%5u pid=%5u unique=%lu len=%u", + printf(" uid=%5u gid=%5u pid=%5u unique=%" PRIu64 " len=%u", in->header.uid, in->header.gid, in->header.pid, in->header.unique, in->header.len); } @@ -173,11 +175,12 @@ void debug_fuseop(const mockfs_buf_in *in) in->body.open.flags, name); break; case FUSE_FLUSH: - printf(" fh=%#lx lock_owner=%lu", in->body.flush.fh, + printf(" fh=%#" PRIx64 " lock_owner=%" PRIu64, + in->body.flush.fh, in->body.flush.lock_owner); break; case FUSE_FORGET: - printf(" nlookup=%lu", in->body.forget.nlookup); + printf(" nlookup=%" PRIu64, in->body.forget.nlookup); break; case FUSE_FSYNC: printf(" flags=%#x", in->body.fsync.fsync_flags); @@ -186,10 +189,10 @@ void debug_fuseop(const mockfs_buf_in *in) printf(" flags=%#x", in->body.fsyncdir.fsync_flags); break; case FUSE_INTERRUPT: - printf(" unique=%lu", in->body.interrupt.unique); + printf(" unique=%" PRIu64, in->body.interrupt.unique); break; case FUSE_LINK: - printf(" oldnodeid=%lu", in->body.link.oldnodeid); + printf(" oldnodeid=%" PRIu64, in->body.link.oldnodeid); break; case FUSE_LOOKUP: printf(" %s", in->body.lookup); @@ -212,16 +215,17 @@ void debug_fuseop(const mockfs_buf_in *in) in->body.opendir.flags, in->body.opendir.mode); break; case FUSE_READ: - printf(" offset=%lu size=%u", in->body.read.offset, + printf(" offset=%" PRIu64 " size=%u", + in->body.read.offset, in->body.read.size); break; case FUSE_READDIR: - printf(" fh=%#lx offset=%lu size=%u", + printf(" fh=%#" PRIx64 " offset=%" PRIu64 " size=%u", in->body.readdir.fh, in->body.readdir.offset, in->body.readdir.size); break; case FUSE_RELEASE: - printf(" fh=%#lx flags=%#x lock_owner=%lu", + printf(" fh=%#" PRIx64 " flags=%#x lock_owner=%" PRIu64, in->body.release.fh, in->body.release.flags, in->body.release.lock_owner); @@ -238,25 +242,26 @@ void debug_fuseop(const mockfs_buf_in *in) if (in->body.setattr.valid & FATTR_GID) printf(" gid=%u", in->body.setattr.gid); if (in->body.setattr.valid & FATTR_SIZE) - printf(" size=%zu", in->body.setattr.size); + printf(" size=%" PRIu64, in->body.setattr.size); if (in->body.setattr.valid & FATTR_ATIME) - printf(" atime=%zu.%u", + printf(" atime=%" PRIu64 ".%u", in->body.setattr.atime, in->body.setattr.atimensec); if (in->body.setattr.valid & FATTR_MTIME) - printf(" mtime=%zu.%u", + printf(" mtime=%" PRIu64 ".%u", in->body.setattr.mtime, in->body.setattr.mtimensec); if (in->body.setattr.valid & FATTR_FH) - printf(" fh=%zu", in->body.setattr.fh); + printf(" fh=%" PRIu64 "", in->body.setattr.fh); break; case FUSE_SETLK: - printf(" fh=%#lx owner=%lu type=%u pid=%u", + printf(" fh=%#" PRIx64 " owner=%" PRIu64 + " type=%u pid=%u", in->body.setlk.fh, in->body.setlk.owner, in->body.setlk.lk.type, in->body.setlk.lk.pid); if (verbosity >= 2) { - printf(" range=[%lu-%lu]", + printf(" range=[%" PRIu64 "-%" PRIu64 "]", in->body.setlk.lk.start, in->body.setlk.lk.end); } @@ -272,7 +277,8 @@ void debug_fuseop(const mockfs_buf_in *in) printf(" %s=%s", name, value); break; case FUSE_WRITE: - printf(" fh=%#lx offset=%lu size=%u flags=%u", + printf(" fh=%#" PRIx64 " offset=%" PRIu64 + " size=%u flags=%u", in->body.write.fh, in->body.write.offset, in->body.write.size, in->body.write.write_flags); @@ -389,15 +395,14 @@ void MockFS::init(uint32_t flags) { mockfs_buf_in *in; mockfs_buf_out *out; - in = (mockfs_buf_in*) malloc(sizeof(*in)); + in = new mockfs_buf_in; ASSERT_TRUE(in != NULL); - out = (mockfs_buf_out*) malloc(sizeof(*out)); + out = new mockfs_buf_out; ASSERT_TRUE(out != NULL); read_request(in); ASSERT_EQ(FUSE_INIT, in->header.opcode); - memset(out, 0, sizeof(*out)); out->header.unique = in->header.unique; out->header.error = 0; out->body.init.major = FUSE_KERNEL_VERSION; @@ -418,7 +423,8 @@ void MockFS::init(uint32_t flags) { SET_OUT_HEADER_LEN(out, init); write(m_fuse_fd, out, out->header.len); - free(in); + delete out; + delete in; } void MockFS::kill_daemon() { Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sat May 25 23:58:09 2019 (r348284) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sun May 26 03:52:35 2019 (r348285) @@ -166,7 +166,7 @@ union fuse_payloads_out { fuse_create_out create; fuse_create_out_7_8 create_7_8; /* The protocol places no limits on the size of bytes */ - uint8_t bytes[0x20000]; + uint8_t bytes[0x20000]; fuse_entry_out entry; fuse_entry_out_7_8 entry_7_8; fuse_lk_out getlk; Modified: projects/fuse2/tests/sys/fs/fusefs/read.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/read.cc Sat May 25 23:58:09 2019 (r348284) +++ projects/fuse2/tests/sys/fs/fusefs/read.cc Sun May 26 03:52:35 2019 (r348285) @@ -486,9 +486,8 @@ TEST_F(ReadCacheable, mmap) uint64_t ino = 42; int fd; ssize_t len; - ssize_t bufsize = strlen(CONTENTS); + size_t bufsize = strlen(CONTENTS); void *p; - //char buf[bufsize]; len = getpagesize(); @@ -674,7 +673,7 @@ TEST_F(ReadCacheable, sendfile) const char *CONTENTS = "abcdefgh"; uint64_t ino = 42; int fd; - ssize_t bufsize = strlen(CONTENTS); + size_t bufsize = strlen(CONTENTS); char buf[bufsize]; int sp[2]; off_t sbytes; @@ -703,7 +702,8 @@ TEST_F(ReadCacheable, sendfile) ASSERT_EQ(0, sendfile(fd, sp[1], 0, bufsize, NULL, &sbytes, 0)) << strerror(errno); - ASSERT_EQ(bufsize, read(sp[0], buf, bufsize)) << strerror(errno); + ASSERT_EQ((ssize_t)bufsize, read(sp[0], buf, bufsize)) + << strerror(errno); ASSERT_EQ(0, memcmp(buf, CONTENTS, bufsize)); close(sp[1]); Modified: projects/fuse2/tests/sys/fs/fusefs/setattr.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/setattr.cc Sat May 25 23:58:09 2019 (r348284) +++ projects/fuse2/tests/sys/fs/fusefs/setattr.cc Sun May 26 03:52:35 2019 (r348285) @@ -495,7 +495,7 @@ TEST_F(Setattr, truncate_discards_cached_data) { SET_OUT_HEADER_LEN(out, write); out->body.attr.attr.ino = ino; out->body.write.size = in->body.write.size; - cur_size = std::max(cur_size, + cur_size = std::max((uint64_t)cur_size, in->body.write.size + in->body.write.offset); }))); @@ -522,8 +522,8 @@ TEST_F(Setattr, truncate_discards_cached_data) { }, Eq(true)), _) ).WillRepeatedly(Invoke(ReturnImmediate([&](auto in, auto out) { - auto osize = std::min(cur_size - in->body.read.offset, - (size_t)in->body.read.size); + auto osize = std::min((uint64_t)cur_size - in->body.read.offset, + (uint64_t)in->body.read.size); out->header.len = sizeof(struct fuse_out_header) + osize; if (should_have_data) memset(out->body.bytes, 'X', osize); Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.cc Sat May 25 23:58:09 2019 (r348284) +++ projects/fuse2/tests/sys/fs/fusefs/utils.cc Sun May 26 03:52:35 2019 (r348285) @@ -298,7 +298,7 @@ void FuseTest::expect_readdir(uint64_t ino, uint64_t o }, Eq(true)), _) ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in, auto out) { - struct fuse_dirent *fde = (struct fuse_dirent*)out->body.bytes; + struct fuse_dirent *fde = (struct fuse_dirent*)&(out->body); int i = 0; out->header.error = 0; From owner-svn-src-projects@freebsd.org Sun May 26 14:02:56 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 AFBCB15A731F for ; Sun, 26 May 2019 14:02:56 +0000 (UTC) (envelope-from yaneurabeya@gmail.com) Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 1E7BF8860E; Sun, 26 May 2019 14:02:56 +0000 (UTC) (envelope-from yaneurabeya@gmail.com) Received: by mail-pf1-x435.google.com with SMTP id c6so8019228pfa.10; Sun, 26 May 2019 07:02:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=XmHr3muuUY+kGCgH/kzIyjG+Fewv3eycxy42LwcBHfo=; b=RlJXIn9Fyed/RVOpJvvliyQsQSR194yMPG8HzAVTDIdMwlQvQN+pE+2H0ajzNwsEq6 DvtRHKP7iLDLidTAZg3WO1DxVLyFvwZ/XzN1IW693Kf6fsznpQcc0N/TowjRuaSWMFix tqFWNjwcxUUDFtyBtDZ97ZHpCJWXVbfo4WGyx8WEDJZ4fQGcmSCvt0XK8bbxFoPMvTxM M96Hej9TZykEgN/RwMVPolnq5XDeBeT+M6CbpCWl37dgRHgNv8vfPQV5nMVeNJerbxpV Gn5mVz/adL15FfS1lwk3ekPSj464nRxxq3lNCVAMRmgOm9LI58k5EjHpqzD3g5SBOjh6 evJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=XmHr3muuUY+kGCgH/kzIyjG+Fewv3eycxy42LwcBHfo=; b=bhq6X9Ar0pBqwWZr2S7RRPeAbS1EubpEQody0+CqF60rJoTD+KABVeXSbXGGLXMk+j AZkFAudxEShf71V+/yGXV84vIwfQYebDuotujiQp1gpgQvaSux5CeAgKFGoqVuht8SQC vz58PmQBeqf4dbnQRYzuxxoPZWq0smrAbHUsfM0q1WsewPePRcHEXzFMEUxavFQW6iLd mqfLxYABap/UApnQD9ekVjbl6uPzJtvMyBbVUssRch/x7tcRwpUc5qyZet/mnnI+g1KT 5PvR11uxqOkwHjUOpZbrbg6e8mwN9/qxkGcYaKnj4HXyxUNdZ3vRa85pdniL399xUsdW 0v8A== X-Gm-Message-State: APjAAAUSjS52Ksqag8cEUeeVG0LsuH/vVWM0/Fn86mxGnnZ62mTkIs1u xd1CG8xDk0vP1255ZviwCL5lNNkrG48= X-Google-Smtp-Source: APXvYqxgG3E4dLwVhwCuNpoIGDEruwgJCfxAf540dPXbA2gJpqx9sJti1nderzcDF4noPcYd111apw== X-Received: by 2002:a63:c94f:: with SMTP id y15mr56277548pgg.159.1558879373952; Sun, 26 May 2019 07:02:53 -0700 (PDT) Received: from [192.168.20.22] (c-73-19-52-228.hsd1.wa.comcast.net. [73.19.52.228]) by smtp.gmail.com with ESMTPSA id p64sm9663278pfp.72.2019.05.26.07.02.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 May 2019 07:02:53 -0700 (PDT) Mime-Version: 1.0 (1.0) Subject: Re: svn commit: r348285 - projects/fuse2/tests/sys/fs/fusefs From: Enji Cooper X-Mailer: iPhone Mail (16F156) In-Reply-To: <201905260352.x4Q3qZBT010750@repo.freebsd.org> Date: Sun, 26 May 2019 07:02:52 -0700 Cc: src-committers@freebsd.org, svn-src-projects@freebsd.org Message-Id: <276AB18D-F1C7-47FF-B070-A019352FB615@gmail.com> References: <201905260352.x4Q3qZBT010750@repo.freebsd.org> To: Alan Somers X-Rspamd-Queue-Id: 1E7BF8860E X-Spamd-Bar: ------ Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-6.98 / 15.00]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; REPLY(-4.00)[]; NEURAL_HAM_SHORT(-0.98)[-0.980,0] Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 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: Sun, 26 May 2019 14:02:56 -0000 > On May 25, 2019, at 20:52, Alan Somers wrote: >=20 > Author: asomers > Date: Sun May 26 03:52:35 2019 > New Revision: 348285 > URL: https://svnweb.freebsd.org/changeset/base/348285 >=20 > Log: > fusefs: more build fixes >=20 > * Fix printf format strings on 32-bit OSes > * Fix -Wclass-memaccess violation on GCC-8 caused by using memset on an o= bject > of non-trivial type. > * Fix memory leak in MockFS::init > * Fix -Wcast-align error on i386 in expect_readdir > * Fix some heterogenous comparison errors on 32-bit OSes. >=20 > Sponsored by: The FreeBSD Foundation >=20 > Modified: > projects/fuse2/tests/sys/fs/fusefs/mockfs.cc > projects/fuse2/tests/sys/fs/fusefs/mockfs.hh > projects/fuse2/tests/sys/fs/fusefs/read.cc > projects/fuse2/tests/sys/fs/fusefs/setattr.cc > projects/fuse2/tests/sys/fs/fusefs/utils.cc >=20 > Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D > --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sat May 25 23:58:09 20= 19 (r348284) > +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sun May 26 03:52:35 20= 19 (r348285) ... > - in =3D (mockfs_buf_in*) malloc(sizeof(*in)); > + in =3D new mockfs_buf_in; > ASSERT_TRUE(in !=3D NULL); > - out =3D (mockfs_buf_out*) malloc(sizeof(*out)); > + out =3D new mockfs_buf_out; > ASSERT_TRUE(out !=3D NULL); >=20 > read_request(in); > ASSERT_EQ(FUSE_INIT, in->header.opcode); >=20 > - memset(out, 0, sizeof(*out)); > out->header.unique =3D in->header.unique; > out->header.error =3D 0; > out->body.init.major =3D FUSE_KERNEL_VERSION; > @@ -418,7 +423,8 @@ void MockFS::init(uint32_t flags) { > SET_OUT_HEADER_LEN(out, init); > write(m_fuse_fd, out, out->header.len); >=20 > - free(in); > + delete out; > + delete in; Given that the tests are currently using C++14, it seems like it would make s= ense to use smart pointers here to manage the scope/lifetime of the objects,= as this could leak if someone added an early return or an exception was thr= own. Ref: https://en.cppreference.com/book/intro/smart_pointers. > } >=20 > void MockFS::kill_daemon() { >=20 > Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D > --- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sat May 25 23:58:09 20= 19 (r348284) > +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sun May 26 03:52:35 20= 19 (r348285) > @@ -166,7 +166,7 @@ union fuse_payloads_out { > fuse_create_out create; > fuse_create_out_7_8 create_7_8; > /* The protocol places no limits on the size of bytes */ > - uint8_t bytes[0x20000]; > + uint8_t bytes[0x20000]; What does this hex value represent? Could it be made into a constant? ... > - cur_size =3D std::max(cur_size, > + cur_size =3D std::max((uint64_t)cur_size, > in->body.write.size + in->body.write.offset); > }))); Casting like this is legal, but this is the C way of doing casting. C++11 an= d newer recommends using static_cast for all compile time casting and dynami= c_cast for all runtime casting. Thanks :)! -Enji= From owner-svn-src-projects@freebsd.org Mon May 27 17:08:19 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 47E5015A5E9B for ; Mon, 27 May 2019 17:08:19 +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 BB0EE7574F; Mon, 27 May 2019 17:08:18 +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 723805F38; Mon, 27 May 2019 17:08:18 +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 x4RH8Ia0089951; Mon, 27 May 2019 17:08:18 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4RH8G2m089942; Mon, 27 May 2019 17:08:16 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905271708.x4RH8G2m089942@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Mon, 27 May 2019 17:08:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348307 - projects/fuse2/tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: projects/fuse2/tests/sys/fs/fusefs X-SVN-Commit-Revision: 348307 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: BB0EE7574F X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.975,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: Mon, 27 May 2019 17:08:19 -0000 Author: asomers Date: Mon May 27 17:08:16 2019 New Revision: 348307 URL: https://svnweb.freebsd.org/changeset/base/348307 Log: fusefs: make the tests more cplusplusy * Prefer std::unique_ptr to raw pointers * Prefer pass-by-reference to pass-by-pointer * Prefer static_cast to C-style cast, unless it's too much typing Reported by: ngie Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc projects/fuse2/tests/sys/fs/fusefs/create.cc projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc projects/fuse2/tests/sys/fs/fusefs/default_permissions_privileged.cc projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc projects/fuse2/tests/sys/fs/fusefs/fifo.cc projects/fuse2/tests/sys/fs/fusefs/flush.cc projects/fuse2/tests/sys/fs/fusefs/fsync.cc projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc projects/fuse2/tests/sys/fs/fusefs/getattr.cc projects/fuse2/tests/sys/fs/fusefs/interrupt.cc projects/fuse2/tests/sys/fs/fusefs/link.cc projects/fuse2/tests/sys/fs/fusefs/locks.cc projects/fuse2/tests/sys/fs/fusefs/lookup.cc projects/fuse2/tests/sys/fs/fusefs/mkdir.cc projects/fuse2/tests/sys/fs/fusefs/mknod.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.hh projects/fuse2/tests/sys/fs/fusefs/mount.cc projects/fuse2/tests/sys/fs/fusefs/nfs.cc projects/fuse2/tests/sys/fs/fusefs/open.cc projects/fuse2/tests/sys/fs/fusefs/opendir.cc projects/fuse2/tests/sys/fs/fusefs/read.cc projects/fuse2/tests/sys/fs/fusefs/readdir.cc projects/fuse2/tests/sys/fs/fusefs/readlink.cc projects/fuse2/tests/sys/fs/fusefs/release.cc projects/fuse2/tests/sys/fs/fusefs/releasedir.cc projects/fuse2/tests/sys/fs/fusefs/rename.cc projects/fuse2/tests/sys/fs/fusefs/rmdir.cc projects/fuse2/tests/sys/fs/fusefs/setattr.cc projects/fuse2/tests/sys/fs/fusefs/statfs.cc projects/fuse2/tests/sys/fs/fusefs/symlink.cc projects/fuse2/tests/sys/fs/fusefs/unlink.cc projects/fuse2/tests/sys/fs/fusefs/utils.cc projects/fuse2/tests/sys/fs/fusefs/write.cc projects/fuse2/tests/sys/fs/fusefs/xattr.cc Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/allow_other.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/allow_other.cc Mon May 27 17:08:16 2019 (r348307) @@ -108,9 +108,9 @@ TEST_F(AllowOther, creds) get_unprivileged_id(&uid, &gid); fork(true, &status, [=] { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_LOOKUP && - in->header.uid == uid && - in->header.gid == gid); + return (in.header.opcode == FUSE_LOOKUP && + in.header.uid == uid && + in.header.gid == gid); }, Eq(true)), _) ).Times(1) @@ -143,25 +143,25 @@ TEST_F(AllowOther, privilege_escalation) expect_lookup(RELPATH, ino, S_IFREG | 0600, 0, 2); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_OPEN && - in->header.pid == (uint32_t)getpid() && - in->header.uid == (uint32_t)geteuid() && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_OPEN && + in.header.pid == (uint32_t)getpid() && + in.header.uid == (uint32_t)geteuid() && + in.header.nodeid == ino); }, Eq(true)), _) ).WillOnce(Invoke( - ReturnImmediate([](auto in __unused, auto out) { - out->body.open.fh = fh; - out->header.len = sizeof(out->header); + ReturnImmediate([](auto in __unused, auto& out) { + out.body.open.fh = fh; + out.header.len = sizeof(out.header); SET_OUT_HEADER_LEN(out, open); }))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_OPEN && - in->header.pid != (uint32_t)getpid() && - in->header.uid != (uint32_t)geteuid() && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_OPEN && + in.header.pid != (uint32_t)getpid() && + in.header.uid != (uint32_t)geteuid() && + in.header.nodeid == ino); }, Eq(true)), _) ).Times(AnyNumber()) @@ -228,12 +228,12 @@ TEST_F(NoAllowOther, disallowed_beneath_root) expect_lookup(RELPATH, ino, S_IFDIR | 0755, 0, 1); EXPECT_LOOKUP(ino, RELPATH2) - .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = ino2; - out->body.entry.attr.nlink = 1; - out->body.entry.attr_valid = UINT64_MAX; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = ino2; + out.body.entry.attr.nlink = 1; + out.body.entry.attr_valid = UINT64_MAX; }))); expect_opendir(ino); dfd = open(FULLPATH, O_DIRECTORY); @@ -269,12 +269,12 @@ TEST_F(NoAllowOther, setextattr) fork(true, &status, [&] { EXPECT_LOOKUP(1, RELPATH) .WillOnce(Invoke( - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr_valid = UINT64_MAX; - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = ino; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = ino; }))); /* Modified: projects/fuse2/tests/sys/fs/fusefs/create.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/create.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/create.cc Mon May 27 17:08:16 2019 (r348307) @@ -44,10 +44,10 @@ void expect_create(const char *relpath, mode_t mode, P { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - const char *name = (const char*)in->body.bytes + + const char *name = (const char*)in.body.bytes + sizeof(fuse_open_in); - return (in->header.opcode == FUSE_CREATE && - in->body.open.mode == mode && + return (in.header.opcode == FUSE_CREATE && + in.body.open.mode == mode && (0 == strcmp(relpath, name))); }, Eq(true)), _) @@ -80,18 +80,18 @@ TEST_F(Create, attr_cache) EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; })); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == ino); }, Eq(true)), _) ).Times(0); @@ -114,25 +114,25 @@ TEST_F(Create, clear_attr_cache) EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == 1); + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == 1); }, Eq(true)), _) ).Times(2) - .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { + .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = 1; - out->body.attr.attr.mode = S_IFDIR | 0755; - out->body.attr.attr_valid = UINT64_MAX; + out.body.attr.attr.ino = 1; + out.body.attr.attr.mode = S_IFDIR | 0755; + out.body.attr.attr_valid = UINT64_MAX; }))); expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; })); EXPECT_EQ(0, stat("mountpoint", &sb)) << strerror(errno); @@ -177,30 +177,30 @@ TEST_F(Create, Enosys) EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - const char *name = (const char*)in->body.bytes + + const char *name = (const char*)in.body.bytes + sizeof(fuse_mknod_in); - return (in->header.opcode == FUSE_MKNOD && - in->body.mknod.mode == (S_IFREG | mode) && - in->body.mknod.rdev == 0 && + return (in.header.opcode == FUSE_MKNOD && + in.body.mknod.mode == (S_IFREG | mode) && + in.body.mknod.rdev == 0 && (0 == strcmp(RELPATH, name))); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr.mode = mode; - out->body.entry.nodeid = ino; - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr_valid = UINT64_MAX; + out.body.entry.attr.mode = mode; + out.body.entry.nodeid = ino; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr_valid = UINT64_MAX; }))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_OPEN && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_OPEN && + in.header.nodeid == ino); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto out) { - out->header.len = sizeof(out->header); + ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto& out) { + out.header.len = sizeof(out.header); SET_OUT_HEADER_LEN(out, open); }))); @@ -229,12 +229,12 @@ TEST_F(Create, entry_cache_negative) /* create will first do a LOOKUP, adding a negative cache entry */ EXPECT_LOOKUP(1, RELPATH).WillOnce(ReturnNegativeCache(&entry_valid)); expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; })); fd = open(FULLPATH, O_CREAT | O_EXCL, mode); @@ -261,11 +261,11 @@ TEST_F(Create, entry_cache_negative_purge) /* Then the CREATE should purge the negative cache entry */ expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.attr_valid = UINT64_MAX; })); fd = open(FULLPATH, O_CREAT | O_EXCL, mode); @@ -305,12 +305,12 @@ TEST_F(Create, ok) EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; })); fd = open(FULLPATH, O_CREAT | O_EXCL, mode); @@ -336,12 +336,12 @@ TEST_F(Create, wronly_0444) EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; })); fd = open(FULLPATH, O_CREAT | O_WRONLY, mode); @@ -359,12 +359,12 @@ TEST_F(Create_7_8, ok) EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, - ReturnImmediate([=](auto in __unused, auto out) { + ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create_7_8); - out->body.create.entry.attr.mode = mode; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; })); fd = open(FULLPATH, O_CREAT | O_EXCL, mode); Modified: projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Mon May 27 17:08:16 2019 (r348307) @@ -61,7 +61,7 @@ virtual void SetUp() { /* With -o default_permissions, FUSE_ACCESS should never be called */ EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_ACCESS); + return (in.header.opcode == FUSE_ACCESS); }, Eq(true)), _) ).Times(0); @@ -72,18 +72,18 @@ void expect_chmod(uint64_t ino, mode_t mode, uint64_t { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino && - in->body.setattr.valid == FATTR_MODE && - in->body.setattr.mode == mode); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino && + in.body.setattr.valid == FATTR_MODE && + in.body.setattr.mode == mode); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | mode; - out->body.attr.attr.size = size; - out->body.attr.attr_valid = UINT64_MAX; + out.body.attr.attr.ino = ino; // Must match nodeid + out.body.attr.attr.mode = S_IFREG | mode; + out.body.attr.attr.size = size; + out.body.attr.attr_valid = UINT64_MAX; }))); } @@ -91,18 +91,18 @@ void expect_create(const char *relpath, uint64_t ino) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - const char *name = (const char*)in->body.bytes + + const char *name = (const char*)in.body.bytes + sizeof(fuse_open_in); - return (in->header.opcode == FUSE_CREATE && + return (in.header.opcode == FUSE_CREATE && (0 == strcmp(relpath, name))); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); - out->body.create.entry.attr.mode = S_IFREG | 0644; - out->body.create.entry.nodeid = ino; - out->body.create.entry.entry_valid = UINT64_MAX; - out->body.create.entry.attr_valid = UINT64_MAX; + out.body.create.entry.attr.mode = S_IFREG | 0644; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; }))); } @@ -111,19 +111,19 @@ void expect_getattr(uint64_t ino, mode_t mode, uint64_ { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == ino); }, Eq(true)), _) ).Times(times) - .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { + .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = mode; - out->body.attr.attr.size = 0; - out->body.attr.attr.uid = uid; - out->body.attr.attr.uid = gid; - out->body.attr.attr_valid = attr_valid; + out.body.attr.attr.ino = ino; // Must match nodeid + out.body.attr.attr.mode = mode; + out.body.attr.attr.size = 0; + out.body.attr.attr.uid = uid; + out.body.attr.attr.uid = gid; + out.body.attr.attr_valid = attr_valid; }))); } @@ -158,7 +158,7 @@ void expect_removexattr() { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_REMOVEXATTR); + return (in.header.opcode == FUSE_REMOVEXATTR); }, Eq(true)), _) ).WillOnce(Invoke(ReturnErrno(0))); @@ -171,7 +171,7 @@ void expect_getxattr(ProcessMockerT r) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETXATTR); + return (in.header.opcode == FUSE_GETXATTR); }, Eq(true)), _) ).WillOnce(Invoke(r)); @@ -184,11 +184,11 @@ void expect_listxattr() { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_LISTXATTR); + return (in.header.opcode == FUSE_LISTXATTR); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([](auto i __unused, auto out) { - out->body.listxattr.size = 0; + ).WillOnce(Invoke(ReturnImmediate([](auto i __unused, auto& out) { + out.body.listxattr.size = 0; SET_OUT_HEADER_LEN(out, listxattr); }))); } @@ -204,7 +204,7 @@ class Rename: public DefaultPermissions { (public) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_RENAME); + return (in.header.opcode == FUSE_RENAME); }, Eq(true)), _) ).WillOnce(Invoke(ReturnErrno(error))); @@ -217,7 +217,7 @@ void expect_setxattr(int error) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_SETXATTR); + return (in.header.opcode == FUSE_SETXATTR); }, Eq(true)), _) ).WillOnce(Invoke(ReturnErrno(error))); @@ -312,13 +312,13 @@ TEST_F(Chown, chown_to_self) /* The OS may optimize chown by omitting the redundant setattr */ EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out){ + ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out){ SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.mode = S_IFREG | mode; - out->body.attr.attr.uid = uid; + out.body.attr.attr.mode = S_IFREG | mode; + out.body.attr.attr.uid = uid; }))); EXPECT_EQ(0, chown(FULLPATH, uid, -1)) << strerror(errno); @@ -342,17 +342,17 @@ TEST_F(Chown, clear_suid) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, uid); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino && - in->body.setattr.valid == valid && - in->body.setattr.mode == newmode); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino && + in.body.setattr.valid == valid && + in.body.setattr.mode == newmode); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | newmode; - out->body.attr.attr_valid = UINT64_MAX; + out.body.attr.attr.ino = ino; // Must match nodeid + out.body.attr.attr.mode = S_IFREG | newmode; + out.body.attr.attr_valid = UINT64_MAX; }))); EXPECT_EQ(0, chown(FULLPATH, uid, -1)) << strerror(errno); @@ -371,7 +371,7 @@ TEST_F(Chown, eperm) expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) ).Times(0); @@ -399,17 +399,17 @@ TEST_F(Chgrp, clear_suid) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, uid, gid); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino && - in->body.setattr.valid == valid && - in->body.setattr.mode == newmode); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino && + in.body.setattr.valid == valid && + in.body.setattr.mode == newmode); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = S_IFREG | newmode; - out->body.attr.attr_valid = UINT64_MAX; + out.body.attr.attr.ino = ino; // Must match nodeid + out.body.attr.attr.mode = S_IFREG | newmode; + out.body.attr.attr_valid = UINT64_MAX; }))); EXPECT_EQ(0, chown(FULLPATH, -1, gid)) << strerror(errno); @@ -433,7 +433,7 @@ TEST_F(Chgrp, eperm) expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, uid, gid); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) ).Times(0); @@ -460,15 +460,15 @@ TEST_F(Chgrp, ok) /* The OS may optimize chgrp by omitting the redundant setattr */ EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino); }, Eq(true)), _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out){ + ).WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out){ SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.mode = S_IFREG | mode; - out->body.attr.attr.uid = uid; - out->body.attr.attr.gid = newgid; + out.body.attr.attr.mode = S_IFREG | mode; + out.body.attr.attr.uid = uid; + out.body.attr.attr.gid = newgid; }))); EXPECT_EQ(0, chown(FULLPATH, -1, newgid)) << strerror(errno); @@ -564,15 +564,15 @@ TEST_F(Utimensat, utime_now) expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, owner); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino && - in->body.setattr.valid & FATTR_ATIME && - in->body.setattr.valid & FATTR_MTIME); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino && + in.body.setattr.valid & FATTR_ATIME && + in.body.setattr.valid & FATTR_MTIME); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.mode = S_IFREG | mode; + out.body.attr.attr.mode = S_IFREG | mode; }))); ASSERT_EQ(0, utimensat(AT_FDCWD, FULLPATH, ×[0], 0)) @@ -647,9 +647,9 @@ TEST_F(Getextattr, ok) /* Getting user attributes only requires read access */ expect_lookup(RELPATH, ino, S_IFREG | 0444, UINT64_MAX, 0); expect_getxattr( - ReturnImmediate([&](auto in __unused, auto out) { - memcpy((void*)out->body.bytes, value, value_len); - out->header.len = sizeof(out->header) + value_len; + ReturnImmediate([&](auto in __unused, auto& out) { + memcpy((void*)out.body.bytes, value, value_len); + out.header.len = sizeof(out.header) + value_len; }) ); @@ -892,13 +892,13 @@ TEST_F(Rename, eperm_on_sticky_dstdir) expect_lookup(RELSRC, src_ino, S_IFREG | 0644, UINT64_MAX); expect_lookup(RELDSTDIR, dstdir_ino, S_IFDIR | 01777, UINT64_MAX); EXPECT_LOOKUP(dstdir_ino, RELDST) - .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = dst_ino; - out->body.entry.attr_valid = UINT64_MAX; - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr.uid = 0; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = dst_ino; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.uid = 0; }))); ASSERT_EQ(-1, rename(FULLSRC, FULLDST)); @@ -952,14 +952,14 @@ TEST_F(Setattr, ok) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino && - in->body.setattr.mode == newmode); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino && + in.body.setattr.mode == newmode); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.mode = S_IFREG | newmode; + out.body.attr.attr.mode = S_IFREG | newmode; }))); EXPECT_EQ(0, chmod(FULLPATH, newmode)) << strerror(errno); @@ -977,7 +977,7 @@ TEST_F(Setattr, eacces) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, 0); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) ).Times(0); @@ -1004,16 +1004,16 @@ TEST_F(Setattr, ftruncate_of_newly_created_file) expect_create(RELPATH, ino); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR && - in->header.nodeid == ino && - (in->body.setattr.valid & FATTR_SIZE)); + return (in.header.opcode == FUSE_SETATTR && + in.header.nodeid == ino && + (in.body.setattr.valid & FATTR_SIZE)); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; - out->body.attr.attr.mode = S_IFREG | mode; - out->body.attr.attr_valid = UINT64_MAX; + out.body.attr.attr.ino = ino; + out.body.attr.attr.mode = S_IFREG | mode; + out.body.attr.attr_valid = UINT64_MAX; }))); fd = open(FULLPATH, O_CREAT | O_RDWR, 0); @@ -1040,7 +1040,7 @@ TEST_F(Setattr, sgid_by_non_group_member) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, uid, gid); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) ).Times(0); @@ -1062,7 +1062,7 @@ TEST_F(Setattr, sticky_regular_file) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) ).Times(0); @@ -1173,11 +1173,11 @@ TEST_F(Unlink, cached_unwritable_directory) EXPECT_LOOKUP(1, RELPATH) .Times(AnyNumber()) .WillRepeatedly(Invoke( - ReturnImmediate([=](auto i __unused, auto out) { + ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = ino; - out->body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = ino; + out.body.entry.entry_valid = UINT64_MAX; })) ); Modified: projects/fuse2/tests/sys/fs/fusefs/default_permissions_privileged.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/default_permissions_privileged.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/default_permissions_privileged.cc Mon May 27 17:08:16 2019 (r348307) @@ -60,7 +60,7 @@ virtual void SetUp() { /* With -o default_permissions, FUSE_ACCESS should never be called */ EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_ACCESS); + return (in.header.opcode == FUSE_ACCESS); }, Eq(true)), _) ).Times(0); @@ -72,19 +72,19 @@ void expect_getattr(uint64_t ino, mode_t mode, uint64_ { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == ino); + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == ino); }, Eq(true)), _) ).Times(times) - .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { + .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid - out->body.attr.attr.mode = mode; - out->body.attr.attr.size = 0; - out->body.attr.attr.uid = uid; - out->body.attr.attr.uid = gid; - out->body.attr.attr_valid = attr_valid; + out.body.attr.attr.ino = ino; // Must match nodeid + out.body.attr.attr.mode = mode; + out.body.attr.attr.size = 0; + out.body.attr.attr.uid = uid; + out.body.attr.attr.uid = gid; + out.body.attr.attr_valid = attr_valid; }))); } @@ -110,12 +110,12 @@ TEST_F(Setattr, sticky_regular_file) expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) - ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto out) { + ).WillOnce(Invoke(ReturnImmediate([](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.mode = S_IFREG | newmode; + out.body.attr.attr.mode = S_IFREG | newmode; }))); EXPECT_EQ(0, chmod(FULLPATH, newmode)) << strerror(errno); Modified: projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc Mon May 27 17:08:16 2019 (r348307) @@ -127,73 +127,73 @@ TEST_F(Kqueue, data) ASSERT_EQ(0, sem_init(&sem1, 0, 0)) << strerror(errno); EXPECT_LOOKUP(1, "foo") - .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = foo_ino; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = foo_ino; }))); EXPECT_LOOKUP(1, "bar") - .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = bar_ino; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = bar_ino; }))); EXPECT_LOOKUP(1, "baz") - .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr.mode = S_IFREG | 0644; - out->body.entry.nodeid = baz_ino; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = baz_ino; }))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - in->header.nodeid == foo_ino); + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == foo_ino); }, Eq(true)), _) ) - .WillOnce(Invoke(ReturnImmediate([&](auto in, auto out) { + .WillOnce(Invoke(ReturnImmediate([&](auto in, auto& out) { nready0 = m_mock->m_nready; sem_post(&sem0); // Block the daemon so we can accumulate a few more ops sem_wait(&sem1); - out->header.unique = in->header.unique; - out->header.error = -EIO; - out->header.len = sizeof(out->header); + out.header.unique = in.header.unique; + out.header.error = -EIO; + out.header.len = sizeof(out.header); }))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - (in->header.nodeid == bar_ino || - in->header.nodeid == baz_ino)); + return (in.header.opcode == FUSE_GETATTR && + (in.header.nodeid == bar_ino || + in.header.nodeid == baz_ino)); }, Eq(true)), _) ).InSequence(seq) - .WillOnce(Invoke(ReturnImmediate([&](auto in, auto out) { + .WillOnce(Invoke(ReturnImmediate([&](auto in, auto& out) { nready1 = m_mock->m_nready; - out->header.unique = in->header.unique; - out->header.error = -EIO; - out->header.len = sizeof(out->header); + out.header.unique = in.header.unique; + out.header.error = -EIO; + out.header.len = sizeof(out.header); }))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_GETATTR && - (in->header.nodeid == bar_ino || - in->header.nodeid == baz_ino)); + return (in.header.opcode == FUSE_GETATTR && + (in.header.nodeid == bar_ino || + in.header.nodeid == baz_ino)); }, Eq(true)), _) ).InSequence(seq) - .WillOnce(Invoke(ReturnImmediate([&](auto in, auto out) { + .WillOnce(Invoke(ReturnImmediate([&](auto in, auto& out) { nready2 = m_mock->m_nready; - out->header.unique = in->header.unique; - out->header.error = -EIO; - out->header.len = sizeof(out->header); + out.header.unique = in.header.unique; + out.header.error = -EIO; + out.header.len = sizeof(out.header); }))); /* Modified: projects/fuse2/tests/sys/fs/fusefs/fifo.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/fifo.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/fifo.cc Mon May 27 17:08:16 2019 (r348307) @@ -159,27 +159,27 @@ TEST_F(Socket, read_write) EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_MKNOD); + return (in.header.opcode == FUSE_MKNOD); }, Eq(true)), _) ).InSequence(seq) - .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr.mode = mode; - out->body.entry.nodeid = ino; - out->body.entry.entry_valid = UINT64_MAX; - out->body.entry.attr_valid = UINT64_MAX; + out.body.entry.attr.mode = mode; + out.body.entry.nodeid = ino; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr_valid = UINT64_MAX; }))); EXPECT_LOOKUP(1, RELPATH) .InSequence(seq) - .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) { + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); - out->body.entry.attr.mode = mode; - out->body.entry.nodeid = ino; - out->body.entry.attr.nlink = 1; - out->body.entry.attr_valid = UINT64_MAX; - out->body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr.mode = mode; + out.body.entry.nodeid = ino; + out.body.entry.attr.nlink = 1; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = UINT64_MAX; }))); fd = socket(AF_UNIX, SOCK_STREAM, 0); Modified: projects/fuse2/tests/sys/fs/fusefs/flush.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/flush.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/flush.cc Mon May 27 17:08:16 2019 (r348307) @@ -46,10 +46,10 @@ expect_flush(uint64_t ino, int times, pid_t lo, Proces { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_FLUSH && - in->header.nodeid == ino && - in->body.flush.lock_owner == (uint64_t)lo && - in->body.flush.fh == FH); + return (in.header.opcode == FUSE_FLUSH && + in.header.nodeid == ino && + in.body.flush.lock_owner == (uint64_t)lo && + in.body.flush.fh == FH); }, Eq(true)), _) ).Times(times) @@ -69,7 +69,7 @@ void expect_release() { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_RELEASE); + return (in.header.opcode == FUSE_RELEASE); }, Eq(true)), _) ).WillRepeatedly(Invoke(ReturnErrno(0))); @@ -206,9 +206,9 @@ TEST_F(FlushWithLocks, unlock_on_close) expect_open(ino, 0, 1); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_SETLK && - in->header.nodeid == ino && - in->body.setlk.fh == FH); + return (in.header.opcode == FUSE_SETLK && + in.header.nodeid == ino && + in.body.setlk.fh == FH); }, Eq(true)), _) ).WillOnce(Invoke(ReturnErrno(0))); Modified: projects/fuse2/tests/sys/fs/fusefs/fsync.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/fsync.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/fsync.cc Mon May 27 17:08:16 2019 (r348307) @@ -54,15 +54,15 @@ void expect_fsync(uint64_t ino, uint32_t flags, int er { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_FSYNC && - in->header.nodeid == ino && + return (in.header.opcode == FUSE_FSYNC && + in.header.nodeid == ino && /* * TODO: reenable pid check after fixing * bug 236379 */ - //(pid_t)in->header.pid == getpid() && - in->body.fsync.fh == FH && - in->body.fsync.fsync_flags == flags); + //(pid_t)in.header.pid == getpid() && + in.body.fsync.fh == FH && + in.body.fsync.fsync_flags == flags); }, Eq(true)), _) ).WillOnce(Invoke(ReturnErrno(error))); @@ -129,16 +129,16 @@ TEST_F(Fsync, close) expect_write(ino, bufsize, CONTENTS); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_SETATTR); + return (in.header.opcode == FUSE_SETATTR); }, Eq(true)), _) - ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto out) { + ).WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out->body.attr.attr.ino = ino; // Must match nodeid + out.body.attr.attr.ino = ino; // Must match nodeid }))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_FSYNC); + return (in.header.opcode == FUSE_FSYNC); }, Eq(true)), _) ).Times(0); Modified: projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc Mon May 27 15:21:26 2019 (r348306) +++ projects/fuse2/tests/sys/fs/fusefs/fsyncdir.cc Mon May 27 17:08:16 2019 (r348307) @@ -54,15 +54,15 @@ void expect_fsyncdir(uint64_t ino, uint32_t flags, int { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { - return (in->header.opcode == FUSE_FSYNCDIR && - in->header.nodeid == ino && + return (in.header.opcode == FUSE_FSYNCDIR && + in.header.nodeid == ino && /* * TODO: reenable pid check after fixing * bug 236379 */ - //(pid_t)in->header.pid == getpid() && *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-projects@freebsd.org Mon May 27 17:14:47 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 85B6A15A60B4 for ; Mon, 27 May 2019 17:14:47 +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 1B72A75AEF; Mon, 27 May 2019 17:14:47 +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 08E3C60D8; Mon, 27 May 2019 17:14:47 +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 x4RHEkUV095313; Mon, 27 May 2019 17:14:46 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4RHEkUr095311; Mon, 27 May 2019 17:14:46 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905271714.x4RHEkUr095311@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Mon, 27 May 2019 17:14:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348308 - projects/fuse2/tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: projects/fuse2/tests/sys/fs/fusefs X-SVN-Commit-Revision: 348308 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 1B72A75AEF X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_SHORT(-0.97)[-0.972,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; 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: Mon, 27 May 2019 17:14:47 -0000 Author: asomers Date: Mon May 27 17:14:46 2019 New Revision: 348308 URL: https://svnweb.freebsd.org/changeset/base/348308 Log: fusefs: remove obsolete comments in the tests Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/tests/sys/fs/fusefs/lookup.cc projects/fuse2/tests/sys/fs/fusefs/utils.hh Modified: projects/fuse2/tests/sys/fs/fusefs/lookup.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/lookup.cc Mon May 27 17:08:16 2019 (r348307) +++ projects/fuse2/tests/sys/fs/fusefs/lookup.cc Mon May 27 17:14:46 2019 (r348308) @@ -291,12 +291,6 @@ TEST_F(Lookup, entry_cache_timeout) ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno); } -// TODO: export_support -// After upgrading the protocol to 7.10, check that the kernel will only -// attempt to lookup "." and ".." if the filesystem sets FUSE_EXPORT_SUPPORT in -// the init flags. If not, then all lookups for those entries will return -// ESTALE. - TEST_F(Lookup, ok) { const char FULLPATH[] = "mountpoint/some_file.txt"; Modified: projects/fuse2/tests/sys/fs/fusefs/utils.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.hh Mon May 27 17:08:16 2019 (r348307) +++ projects/fuse2/tests/sys/fs/fusefs/utils.hh Mon May 27 17:14:46 2019 (r348308) @@ -28,15 +28,6 @@ * SUCH DAMAGE. */ -/* - * TODO: remove FUSE_WRITE_CACHE definition when upgrading to protocol 7.9. - * This bit was actually part of kernel protocol version 7.2, but never - * documented until 7.9 - */ -#ifndef FUSE_WRITE_CACHE -#define FUSE_WRITE_CACHE 1 -#endif - /* Nanoseconds to sleep, for tests that must */ #define NAP_NS (100'000'000) From owner-svn-src-projects@freebsd.org Mon May 27 21:36:30 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 3101A15AB914 for ; Mon, 27 May 2019 21:36:30 +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 D4D1B87660; Mon, 27 May 2019 21:36:29 +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 9203E8CC6; Mon, 27 May 2019 21:36:29 +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 x4RLaTO1035367; Mon, 27 May 2019 21:36:29 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4RLaSKY035361; Mon, 27 May 2019 21:36:28 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905272136.x4RLaSKY035361@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Mon, 27 May 2019 21:36:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348313 - 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: 348313 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: D4D1B87660 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)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.984,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: Mon, 27 May 2019 21:36:30 -0000 Author: asomers Date: Mon May 27 21:36:28 2019 New Revision: 348313 URL: https://svnweb.freebsd.org/changeset/base/348313 Log: fusefs: set FUSE_WRITE_CACHE when writing from cache This bit tells the server that we're not sure which uid, gid, and/or pid originated the write. I don't know of a single file system that cares, but it's part of the protocol. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_io.c projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc projects/fuse2/tests/sys/fs/fusefs/fsync.cc projects/fuse2/tests/sys/fs/fusefs/utils.cc projects/fuse2/tests/sys/fs/fusefs/utils.hh 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 Mon May 27 20:22:54 2019 (r348312) +++ projects/fuse2/sys/fs/fuse/fuse_io.c Mon May 27 21:36:28 2019 (r348313) @@ -119,7 +119,7 @@ fuse_read_biobackend(struct vnode *vp, struct uio *uio static int fuse_write_directbackend(struct vnode *vp, struct uio *uio, struct ucred *cred, struct fuse_filehandle *fufh, off_t filesize, - int ioflag); + int ioflag, bool pages); static int fuse_write_biobackend(struct vnode *vp, struct uio *uio, struct ucred *cred, struct fuse_filehandle *fufh, int ioflag, pid_t pid); @@ -245,7 +245,7 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, in if (!pages ) v_inval_buf_range(vp, start, end, iosize); err = fuse_write_directbackend(vp, uio, cred, fufh, - filesize, ioflag); + filesize, ioflag, pages); } else { SDT_PROBE2(fusefs, , io, trace, 1, "buffered write of vnode"); @@ -405,7 +405,7 @@ out: static int fuse_write_directbackend(struct vnode *vp, struct uio *uio, struct ucred *cred, struct fuse_filehandle *fufh, off_t filesize, - int ioflag) + int ioflag, bool pages) { struct fuse_vnode_data *fvdat = VTOFUD(vp); struct fuse_data *data; @@ -418,9 +418,29 @@ fuse_write_directbackend(struct vnode *vp, struct uio int diff; int err = 0; bool direct_io = fufh->fuse_open_flags & FOPEN_DIRECT_IO; + uint32_t write_flags; data = fuse_get_mpdata(vp->v_mount); + /* + * Don't set FUSE_WRITE_LOCKOWNER in write_flags. It can't be set + * accurately when using POSIX AIO, libfuse doesn't use it, and I'm not + * aware of any file systems that do. It was an attempt to add + * Linux-style mandatory locking to the FUSE protocol, but mandatory + * locking is deprecated even on Linux. See Linux commit + * f33321141b273d60cbb3a8f56a5489baad82ba5e . + */ + /* + * Set FUSE_WRITE_CACHE whenever we don't know the uid, gid, and/or pid + * that originated a write. For example when writing from the + * writeback cache. I don't know of a single file system that cares, + * but the protocol says we're supposed to do this. + */ + write_flags = !pages && ( + (ioflag & IO_DIRECT) || + !fsess_opt_datacache(vnode_mount(vp)) || + fuse_data_cache_mode != FUSE_CACHE_WB) ? 0 : FUSE_WRITE_CACHE; + if (uio->uio_resid == 0) return (0); @@ -439,17 +459,8 @@ fuse_write_directbackend(struct vnode *vp, struct uio fwi->fh = fufh->fh_id; fwi->offset = uio->uio_offset; fwi->size = chunksize; + fwi->write_flags = write_flags; if (fuse_libabi_geq(data, 7, 9)) { - /* - * Don't set FUSE_WRITE_LOCKOWNER. It can't be set - * accurately when using POSIX AIO, libfuse doesn't use - * it, and I'm not aware of any file systems that do. - * It was an attempt to add Linux-style mandatory - * locking to the FUSE protocol, but mandatory locking - * is deprecated even on Linux. See Linux commit - * f33321141b273d60cbb3a8f56a5489baad82ba5e . - */ - fwi->write_flags = 0; fwi->flags = 0; /* TODO */ fwi_data = (char *)fdi.indata + sizeof(*fwi); } else { @@ -525,6 +536,7 @@ retry: fwi->fh = fufh->fh_id; fwi->offset = as_written_offset; fwi->size = diff; + fwi->write_flags = write_flags; goto retry; } } @@ -884,7 +896,7 @@ fuse_io_strategy(struct vnode *vp, struct buf *bp) uiop->uio_rw = UIO_WRITE; error = fuse_write_directbackend(vp, uiop, cred, fufh, - filesize, 0); + filesize, 0, false); if (error == EINTR || error == ETIMEDOUT || (!error && (bp->b_flags & B_NEEDCOMMIT))) { Modified: projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Mon May 27 20:22:54 2019 (r348312) +++ projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Mon May 27 21:36:28 2019 (r348313) @@ -1229,7 +1229,7 @@ TEST_F(Write, clear_suid) expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX); expect_open(ino, 0, 1); - expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, wbuf); + expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf); expect_chmod(ino, newmode, sizeof(wbuf)); fd = open(FULLPATH, O_WRONLY); @@ -1255,7 +1255,7 @@ TEST_F(Write, clear_sgid) expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX); expect_open(ino, 0, 1); - expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, wbuf); + expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf); expect_chmod(ino, newmode, sizeof(wbuf)); fd = open(FULLPATH, O_WRONLY); @@ -1285,7 +1285,7 @@ TEST_F(Write, recursion_panic_while_clearing_suid) expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX); expect_open(ino, 0, 1); - expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, wbuf); + expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf); /* XXX Return a smaller file size than what we just wrote! */ expect_chmod(ino, newmode, 0); Modified: projects/fuse2/tests/sys/fs/fusefs/fsync.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/fsync.cc Mon May 27 20:22:54 2019 (r348312) +++ projects/fuse2/tests/sys/fs/fusefs/fsync.cc Mon May 27 21:36:28 2019 (r348313) @@ -75,7 +75,7 @@ void expect_lookup(const char *relpath, uint64_t ino) void expect_write(uint64_t ino, uint64_t size, const void *contents) { - FuseTest::expect_write(ino, 0, size, size, 0, contents); + FuseTest::expect_write(ino, 0, size, size, 0, 0, contents); } }; Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.cc Mon May 27 20:22:54 2019 (r348312) +++ projects/fuse2/tests/sys/fs/fusefs/utils.cc Mon May 27 21:36:28 2019 (r348313) @@ -377,15 +377,17 @@ void FuseTest::expect_unlink(uint64_t parent, const ch } void FuseTest::expect_write(uint64_t ino, uint64_t offset, uint64_t isize, - uint64_t osize, uint32_t flags, const void *contents) + uint64_t osize, uint32_t flags_set, uint32_t flags_unset, + const void *contents) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { const char *buf = (const char*)in.body.bytes + sizeof(struct fuse_write_in); bool pid_ok; + uint32_t wf = in.body.write.write_flags; - if (in.body.write.write_flags & FUSE_WRITE_CACHE) + if (wf & FUSE_WRITE_CACHE) pid_ok = true; else pid_ok = (pid_t)in.header.pid == getpid(); @@ -396,7 +398,8 @@ void FuseTest::expect_write(uint64_t ino, uint64_t off in.body.write.offset == offset && in.body.write.size == isize && pid_ok && - in.body.write.write_flags == flags && + (wf & flags_set) == flags_set && + (wf & flags_unset) == 0 && 0 == bcmp(buf, contents, isize)); }, Eq(true)), _) @@ -407,7 +410,7 @@ void FuseTest::expect_write(uint64_t ino, uint64_t off } void FuseTest::expect_write_7_8(uint64_t ino, uint64_t offset, uint64_t isize, - uint64_t osize, uint32_t flags, const void *contents) + uint64_t osize, const void *contents) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -420,7 +423,6 @@ void FuseTest::expect_write_7_8(uint64_t ino, uint64_t in.body.write.offset == offset && in.body.write.size == isize && pid_ok && - in.body.write.write_flags == flags && 0 == bcmp(buf, contents, isize)); }, Eq(true)), _) Modified: projects/fuse2/tests/sys/fs/fusefs/utils.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.hh Mon May 27 20:22:54 2019 (r348312) +++ projects/fuse2/tests/sys/fs/fusefs/utils.hh Mon May 27 21:36:28 2019 (r348313) @@ -169,15 +169,18 @@ class FuseTest : public ::testing::Test { /* * Create an expectation that FUSE_WRITE will be called exactly once - * for the given inode, at offset offset, with write_flags flags, - * size isize and buffer contents. It will return osize + * for the given inode, at offset offset, with size isize and buffer + * contents. Any flags present in flags_set must be set, and any + * present in flags_unset must not be set. Other flags are don't care. + * It will return osize. */ void expect_write(uint64_t ino, uint64_t offset, uint64_t isize, - uint64_t osize, uint32_t flags, const void *contents); + uint64_t osize, uint32_t flags_set, uint32_t flags_unset, + const void *contents); /* Protocol 7.8 version of expect_write */ void expect_write_7_8(uint64_t ino, uint64_t offset, uint64_t isize, - uint64_t osize, uint32_t flags, const void *contents); + uint64_t osize, const void *contents); /* * Helper that runs code in a child process. Modified: projects/fuse2/tests/sys/fs/fusefs/write.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/write.cc Mon May 27 20:22:54 2019 (r348312) +++ projects/fuse2/tests/sys/fs/fusefs/write.cc Mon May 27 21:36:28 2019 (r348313) @@ -65,6 +65,12 @@ void expect_release(uint64_t ino, ProcessMockerT r) ).WillRepeatedly(Invoke(r)); } +void expect_write(uint64_t ino, uint64_t offset, uint64_t isize, + uint64_t osize, const void *contents) +{ + FuseTest::expect_write(ino, offset, isize, osize, 0, 0, contents); +} + }; class Write_7_8: public FuseTest { @@ -100,7 +106,7 @@ virtual void SetUp() { /* Tests for the write-through cache mode */ class WriteThrough: public Write { - +public: virtual void SetUp() { const char *cache_mode_node = "vfs.fusefs.data_cache_mode"; int val = 0; @@ -117,11 +123,17 @@ virtual void SetUp() { "(writethrough) for this test"; } +void expect_write(uint64_t ino, uint64_t offset, uint64_t isize, + uint64_t osize, const void *contents) +{ + FuseTest::expect_write(ino, offset, isize, osize, 0, FUSE_WRITE_CACHE, + contents); +} }; /* Tests for the writeback cache mode */ class WriteBack: public Write { - +public: virtual void SetUp() { const char *node = "vfs.fusefs.data_cache_mode"; int val = 0; @@ -138,6 +150,12 @@ virtual void SetUp() { "(writeback) for this test"; } +void expect_write(uint64_t ino, uint64_t offset, uint64_t isize, + uint64_t osize, const void *contents) +{ + FuseTest::expect_write(ino, offset, isize, osize, FUSE_WRITE_CACHE, 0, + contents); +} }; /* AIO writes need to set the header's pid field correctly */ @@ -155,7 +173,7 @@ TEST_F(AioWrite, DISABLED_aio_write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, offset, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -196,7 +214,7 @@ TEST_F(Write, append) expect_lookup(RELPATH, ino, initial_offset); expect_open(ino, 0, 1); - expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS); + expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, CONTENTS); /* Must open O_RDWR or fuse(4) implicitly sets direct_io */ fd = open(FULLPATH, O_RDWR | O_APPEND); @@ -218,7 +236,7 @@ TEST_F(Write, append_direct_io) expect_lookup(RELPATH, ino, initial_offset); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, 0, CONTENTS); + expect_write(ino, initial_offset, BUFSIZE, BUFSIZE, CONTENTS); fd = open(FULLPATH, O_WRONLY | O_APPEND); EXPECT_LE(0, fd) << strerror(errno); @@ -242,7 +260,7 @@ TEST_F(Write, direct_io_evicts_cache) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_read(ino, 0, bufsize, bufsize, CONTENTS0); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS1); + expect_write(ino, 0, bufsize, bufsize, CONTENTS1); fd = open(FULLPATH, O_RDWR); EXPECT_LE(0, fd) << strerror(errno); @@ -285,9 +303,8 @@ TEST_F(Write, indirect_io_short_write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize0, 0, CONTENTS); - expect_write(ino, bufsize0, bufsize1, bufsize1, 0, - contents1); + expect_write(ino, 0, bufsize, bufsize0, CONTENTS); + expect_write(ino, bufsize0, bufsize1, bufsize1, contents1); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -312,7 +329,7 @@ TEST_F(Write, direct_io_short_write) expect_lookup(RELPATH, ino, 0); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_write(ino, 0, bufsize, halfbufsize, 0, CONTENTS); + expect_write(ino, 0, bufsize, halfbufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -342,7 +359,7 @@ TEST_F(Write, direct_io_short_write_iov) expect_lookup(RELPATH, ino, 0); expect_open(ino, FOPEN_DIRECT_IO, 1); - expect_write(ino, 0, totalsize, size0, 0, EXPECTED0); + expect_write(ino, 0, totalsize, size0, EXPECTED0); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -388,9 +405,8 @@ TEST_F(Write, mmap) /* * Writes from the pager may or may not be associated with the correct * pid, so they must set FUSE_WRITE_CACHE. - * TODO: expect FUSE_WRITE_CACHE after upgrading to protocol 7.9 */ - expect_write(ino, 0, len, len, 0, expected); + FuseTest::expect_write(ino, 0, len, len, FUSE_WRITE_CACHE, 0, expected); expect_flush(ino, 1, ReturnErrno(0)); expect_release(ino, ReturnErrno(0)); @@ -435,7 +451,7 @@ TEST_F(WriteThrough, evicts_read_cache) expect_lookup(RELPATH, ino, bufsize); expect_open(ino, 0, 1); expect_read(ino, 0, bufsize, bufsize, contents0); - expect_write(ino, 0, wrsize, wrsize, 0, contents1); + expect_write(ino, 0, wrsize, wrsize, contents1); fd = open(FULLPATH, O_RDWR); EXPECT_LE(0, fd) << strerror(errno); @@ -468,7 +484,7 @@ TEST_F(WriteThrough, pwrite) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, offset, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -489,7 +505,7 @@ TEST_F(Write, write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -518,8 +534,8 @@ TEST_F(Write, write_large) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, halfbufsize, halfbufsize, 0, contents); - expect_write(ino, halfbufsize, halfbufsize, halfbufsize, 0, + expect_write(ino, 0, halfbufsize, halfbufsize, contents); + expect_write(ino, halfbufsize, halfbufsize, halfbufsize, &contents[halfbufsize / sizeof(int)]); fd = open(FULLPATH, O_WRONLY); @@ -561,7 +577,7 @@ TEST_F(Write_7_8, write) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write_7_8(ino, 0, bufsize, bufsize, 0, CONTENTS); + expect_write_7_8(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -582,7 +598,7 @@ TEST_F(WriteBack, close) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, 0, bufsize, bufsize, CONTENTS); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in.header.opcode == FUSE_SETATTR); @@ -621,7 +637,7 @@ TEST_F(WriteBack, rmw) FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, fsize, 1); expect_open(ino, 0, 1); expect_read(ino, 0, fsize, fsize, INITIAL); - expect_write(ino, offset, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, offset, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); EXPECT_LE(0, fd) << strerror(errno); @@ -646,7 +662,7 @@ TEST_F(WriteBack, writeback) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDWR); EXPECT_LE(0, fd) << strerror(errno); @@ -678,7 +694,8 @@ TEST_F(WriteBack, o_direct) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); + FuseTest::expect_write(ino, 0, bufsize, bufsize, 0, FUSE_WRITE_CACHE, + CONTENTS); expect_read(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDWR | O_DIRECT); @@ -711,7 +728,7 @@ TEST_F(WriteThrough, DISABLED_writethrough) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDWR); EXPECT_LE(0, fd) << strerror(errno); @@ -738,7 +755,7 @@ TEST_F(WriteThrough, update_file_size) expect_lookup(RELPATH, ino, 0); expect_open(ino, 0, 1); - expect_write(ino, 0, bufsize, bufsize, 0, CONTENTS); + expect_write(ino, 0, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_RDWR); EXPECT_LE(0, fd) << strerror(errno); From owner-svn-src-projects@freebsd.org Mon May 27 21:51: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 2AEBD15AC257 for ; Mon, 27 May 2019 21:51: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 C4C2F87FE6; Mon, 27 May 2019 21:51:43 +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 9A76C8FDF; Mon, 27 May 2019 21:51: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 x4RLphit041464; Mon, 27 May 2019 21:51:43 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4RLphvM041463; Mon, 27 May 2019 21:51:43 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905272151.x4RLphvM041463@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Mon, 27 May 2019 21:51:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348314 - projects/fuse2/tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: projects/fuse2/tests/sys/fs/fusefs X-SVN-Commit-Revision: 348314 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: C4C2F87FE6 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)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.982,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: Mon, 27 May 2019 21:51:44 -0000 Author: asomers Date: Mon May 27 21:51:43 2019 New Revision: 348314 URL: https://svnweb.freebsd.org/changeset/base/348314 Log: fusefs: fix an alignment issue in the tests on arm Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.cc Mon May 27 21:36:28 2019 (r348313) +++ projects/fuse2/tests/sys/fs/fusefs/utils.cc Mon May 27 21:51:43 2019 (r348314) @@ -333,7 +333,7 @@ void FuseTest::expect_readdir(uint64_t ino, uint64_t o } out.header.len += entsize; fde = (struct fuse_dirent*) - ((long*)fde + entsize / sizeof(long)); + ((intmax_t*)fde + entsize / sizeof(intmax_t)); i++; } out.header.len += sizeof(out.header); From owner-svn-src-projects@freebsd.org Mon May 27 22:25:40 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 B7B0315ACD99 for ; Mon, 27 May 2019 22:25:40 +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 57752895AB; Mon, 27 May 2019 22:25:40 +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 264D49527; Mon, 27 May 2019 22:25:40 +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 x4RMPd5r061514; Mon, 27 May 2019 22:25:39 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4RMPdvq061513; Mon, 27 May 2019 22:25:39 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905272225.x4RMPdvq061513@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Mon, 27 May 2019 22:25:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348315 - 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: 348315 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 57752895AB 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)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.96)[-0.959,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: Mon, 27 May 2019 22:25:40 -0000 Author: asomers Date: Mon May 27 22:25:39 2019 New Revision: 348315 URL: https://svnweb.freebsd.org/changeset/base/348315 Log: fusefs: clear fuse_getattr_in.getattr_flags Protocol 7.9 adds this field. We could use it to store the file handle of the file whose attributes we're requesting. However, that requires extra work at runtime to look up a file handle, and I'm not aware of any file systems that care. So it's easiest just to clear it. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.c Mon May 27 21:51:43 2019 (r348314) +++ projects/fuse2/sys/fs/fuse/fuse_internal.c Mon May 27 22:25:39 2019 (r348315) @@ -680,12 +680,21 @@ fuse_internal_do_getattr(struct vnode *vp, struct vatt { struct fuse_dispatcher fdi; struct fuse_vnode_data *fvdat = VTOFUD(vp); + struct fuse_getattr_in *fgai; struct fuse_attr_out *fao; off_t old_filesize = fvdat->cached_attrs.va_size; enum vtype vtyp; int err; fdisp_init(&fdi, 0); + fdisp_make_vp(&fdi, FUSE_GETATTR, vp, td, cred); + fgai = fdi.indata; + /* + * We could look up a file handle and set it in fgai->fh, but that + * involves extra runtime work and I'm unaware of any file systems that + * care. + */ + fgai->getattr_flags = 0; if ((err = fdisp_simple_putget_vp(&fdi, FUSE_GETATTR, vp, td, cred))) { if (err == ENOENT) fuse_internal_vnode_disappear(vp); From owner-svn-src-projects@freebsd.org Mon May 27 22:34:52 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 3999D15ACFB6 for ; Mon, 27 May 2019 22:34:52 +0000 (UTC) (envelope-from asomers@gmail.com) Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2547689BAE; Mon, 27 May 2019 22:34:50 +0000 (UTC) (envelope-from asomers@gmail.com) Received: by mail-lj1-f175.google.com with SMTP id r76so5048973lja.12; Mon, 27 May 2019 15:34:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=83+yuguPuEx5uq0bSyuVCIo7byt5C3QhpTXT0bNC0IQ=; b=eJiWzPvyEdqTtKdUAwoHQ83SgzCn9NaI0QvIfN6ItDHcJhxZF4/YCEVO0Hq3UI1syb wuuEOoCDPDcvFf1pvYHO3MpUDDqhAa5pktRznodfsXi+2FsRAWJRvx59CsceIO/MD14I y0SO8DQ5VCy9F4CZCpL8idfUxra4LdPva0WPTmU0qB0R/MG2D2iFRHV4iU7VU2KlfTKF 2WAX3tbotAk+9XQh2ardG7fXBl/tsD3mbooVZ6Z8JfGcThTjp6evGDHuifQxJCvONDGV LYkPj98Cr9iHj716MZawHxvWeG6YtkETSEHYHMqo6ExtO790fx4mBcWw7xQBL9E73xuZ R3fg== X-Gm-Message-State: APjAAAVXC/iVnLK4oZJ3EAhSuCgv7ZCqScf2sCBRF6q1t4bqSCXXIwgE xV0Tpj3uaA8UTm0rJP0Baq8X9gymj1Z4hxulG98= X-Google-Smtp-Source: APXvYqxaI6riiflAu53vObwQuKDBRxAAG6AY67fMydvsyYnWfqkv6VErr+YVCxTnyx0XIgIQMxQ76N4awoZTxmbF7g0= X-Received: by 2002:a2e:1284:: with SMTP id 4mr31482965ljs.138.1558994987650; Mon, 27 May 2019 15:09:47 -0700 (PDT) MIME-Version: 1.0 References: <201905260352.x4Q3qZBT010750@repo.freebsd.org> <276AB18D-F1C7-47FF-B070-A019352FB615@gmail.com> In-Reply-To: <276AB18D-F1C7-47FF-B070-A019352FB615@gmail.com> From: Alan Somers Date: Mon, 27 May 2019 16:09:35 -0600 Message-ID: Subject: Re: svn commit: r348285 - projects/fuse2/tests/sys/fs/fusefs To: Enji Cooper Cc: src-committers , svn-src-projects@freebsd.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 2547689BAE X-Spamd-Bar: --- Authentication-Results: mx1.freebsd.org; spf=pass (mx1.freebsd.org: domain of asomers@gmail.com designates 209.85.208.175 as permitted sender) smtp.mailfrom=asomers@gmail.com X-Spamd-Result: default: False [-4.00 / 15.00]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; R_SPF_ALLOW(-0.20)[+ip4:209.85.128.0/17]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[text/plain]; MIME_TRACE(0.00)[0:+]; DMARC_NA(0.00)[freebsd.org]; TO_DN_SOME(0.00)[]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[cached: alt3.gmail-smtp-in.l.google.com]; NEURAL_HAM_SHORT(-0.74)[-0.736,0]; RCVD_IN_DNSWL_NONE(0.00)[175.208.85.209.list.dnswl.org : 127.0.5.0]; RCVD_TLS_LAST(0.00)[]; FORGED_SENDER(0.30)[asomers@freebsd.org,asomers@gmail.com]; FREEMAIL_TO(0.00)[gmail.com]; R_DKIM_NA(0.00)[]; FREEMAIL_ENVFROM(0.00)[gmail.com]; ASN(0.00)[asn:15169, ipnet:209.85.128.0/17, country:US]; FROM_NEQ_ENVFROM(0.00)[asomers@freebsd.org,asomers@gmail.com]; IP_SCORE(-1.25)[ip: (-0.54), ipnet: 209.85.128.0/17(-3.39), asn: 15169(-2.28), country: US(-0.06)]; RCVD_COUNT_TWO(0.00)[2] 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: Mon, 27 May 2019 22:34:52 -0000 On Sun, May 26, 2019 at 8:02 AM Enji Cooper wrote: > > > On May 25, 2019, at 20:52, Alan Somers wrote: > > Author: asomers > Date: Sun May 26 03:52:35 2019 > New Revision: 348285 > URL: https://svnweb.freebsd.org/changeset/base/348285 > > Log: > fusefs: more build fixes > > * Fix printf format strings on 32-bit OSes > * Fix -Wclass-memaccess violation on GCC-8 caused by using memset on an = object > of non-trivial type. > * Fix memory leak in MockFS::init > * Fix -Wcast-align error on i386 in expect_readdir > * Fix some heterogenous comparison errors on 32-bit OSes. > > Sponsored by: The FreeBSD Foundation > > Modified: > projects/fuse2/tests/sys/fs/fusefs/mockfs.cc > projects/fuse2/tests/sys/fs/fusefs/mockfs.hh > projects/fuse2/tests/sys/fs/fusefs/read.cc > projects/fuse2/tests/sys/fs/fusefs/setattr.cc > projects/fuse2/tests/sys/fs/fusefs/utils.cc > > Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sat May 25 23:58:09 2= 019 (r348284) > +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sun May 26 03:52:35 2= 019 (r348285) > > > ... > > - in =3D (mockfs_buf_in*) malloc(sizeof(*in)); > + in =3D new mockfs_buf_in; > ASSERT_TRUE(in !=3D NULL); > - out =3D (mockfs_buf_out*) malloc(sizeof(*out)); > + out =3D new mockfs_buf_out; > ASSERT_TRUE(out !=3D NULL); > > read_request(in); > ASSERT_EQ(FUSE_INIT, in->header.opcode); > > - memset(out, 0, sizeof(*out)); > out->header.unique =3D in->header.unique; > out->header.error =3D 0; > out->body.init.major =3D FUSE_KERNEL_VERSION; > @@ -418,7 +423,8 @@ void MockFS::init(uint32_t flags) { > SET_OUT_HEADER_LEN(out, init); > write(m_fuse_fd, out, out->header.len); > > - free(in); > + delete out; > + delete in; > > > Given that the tests are currently using C++14, it seems like it would ma= ke sense to use smart pointers here to manage the scope/lifetime of the obj= ects, as this could leak if someone added an early return or an exception w= as thrown. Ref: https://en.cppreference.com/book/intro/smart_pointers. Done! Nothing like using C++ smart pointers to make me miss Rust. > > } > > void MockFS::kill_daemon() { > > Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sat May 25 23:58:09 2= 019 (r348284) > +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sun May 26 03:52:35 2= 019 (r348285) > @@ -166,7 +166,7 @@ union fuse_payloads_out { > fuse_create_out create; > fuse_create_out_7_8 create_7_8; > /* The protocol places no limits on the size of bytes */ > - uint8_t bytes[0x20000]; > + uint8_t bytes[0x20000]; > > > What does this hex value represent? Could it be made into a constant? It's just "a big buffer" used for different purposes by different tests. The size is arbitrary. I've tried to make that more clear in the comment. > > ... > > - cur_size =3D std::max(cur_size, > + cur_size =3D std::max((uint64_t)cur_size, > in->body.write.size + in->body.write.offset); > }))); > > > Casting like this is legal, but this is the C way of doing casting. C++11= and newer recommends using static_cast for all compile time casting and dy= namic_cast for all runtime casting. Done! Here, at least. In some other locations I've stuck with C-style casting because it involves significantly fewer characters, so I find it more readable. > > Thanks :)! > -Enji Since you're interested in C++ issues, would you mind taking a look at a painful compiler error I'm getting? This only happens with GCC-8, not Clang, so I'm only seeing it in the riscv.riscv64 buildworld. In file included from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/algorithm:645, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/__string:57, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/string_view:176, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/string:505, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/__locale:15, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/ios:216, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/ostream:138, from /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/private/gtest/gtest.h:56, from /home/asomers/freebsd/base/projects/fuse2/tests/sys/fs/fusefs/mockfs.cc:53: /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/functional: In instantiation of 'std::__1::__function::__value_func<_Rp(_ArgTypes ...)>::__value_func(_Fp&&, _Alloc) [with _Fp =3D ReturnImmediate(std::__1::function)::; _Alloc =3D std::__1::allocator):: >; _Rp =3D void; _ArgTypes =3D {const mockfs_buf_in&, std::__1::vector >, std::__1::allocator > > >&}]': /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/functional:2290:46: required from 'std::__1::function<_Rp(_ArgTypes ...)>::function(_Fp) [with _Fp =3D ReturnImmediate(std::__1::function)::; =3D void; _Rp =3D void; _ArgTypes =3D {const mockfs_buf_in&, std::__1::vector >, std::__1::allocator > > >&}]' /home/asomers/freebsd/base/projects/fuse2/tests/sys/fs/fusefs/mockfs.cc:149= :3: required from here /scratch/tmp/asomers/obj/home/asomers/freebsd/base/projects/fuse2/riscv.ris= cv64/tmp/usr/include/c++/v1/functional:1711:36: error: placement new constructing an object of type '_Fun' {aka 'std::__1::__function::__func)::, std::__1::allocator):: >, void(const mockfs_buf_in&, std::__1::vector >&)>'} and size '64' in a region of type 'std::__1::aligned_storage<24>::type' and size '32' [-Werror=3Dplacement-new=3D] ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); ^~~~~~ Do you have any idea how to fix that? -Alan From owner-svn-src-projects@freebsd.org Tue May 28 00:03:47 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 6988015AF09F for ; Tue, 28 May 2019 00:03:47 +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 08A8A8C64A; Tue, 28 May 2019 00:03:47 +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 D15DBA5C6; Tue, 28 May 2019 00:03:46 +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 x4S03k77014683; Tue, 28 May 2019 00:03:46 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4S03kcv014681; Tue, 28 May 2019 00:03:46 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905280003.x4S03kcv014681@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Tue, 28 May 2019 00:03:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348317 - 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: 348317 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 08A8A8C64A 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)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.984,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: Tue, 28 May 2019 00:03:47 -0000 Author: asomers Date: Tue May 28 00:03:46 2019 New Revision: 348317 URL: https://svnweb.freebsd.org/changeset/base/348317 Log: fusefs: flock(2) locks must be implemented in-kernel If a FUSE file system sets the FUSE_POSIX_LOCKS flag then it can support fcntl(2)-style locks directly. However, the protocol does not adequately support flock(2)-style locks until revision 7.17. They must be implemented locally in-kernel instead. This unfortunately breaks the interoperability of fcntl(2) and flock(2) locks for file systems that support the former. C'est la vie. Prior to this commit flock(2) would get sent to the server as a fcntl(2)-style lock with the lock owner field set to stack garbage. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c projects/fuse2/tests/sys/fs/fusefs/locks.cc Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vnops.c Mon May 27 23:25:19 2019 (r348316) +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Tue May 28 00:03:46 2019 (r348317) @@ -389,6 +389,7 @@ fuse_vnop_advlock(struct vop_advlock_args *ap) struct fuse_lk_out *flo; enum fuse_opcode op; int dataflags, err; + int flags = ap->a_flags; dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags; @@ -397,6 +398,9 @@ fuse_vnop_advlock(struct vop_advlock_args *ap) } if (!(dataflags & FSESS_POSIX_LOCKS)) + return vop_stdadvlock(ap); + /* FUSE doesn't properly support flock until protocol 7.17 */ + if (flags & F_FLOCK) return vop_stdadvlock(ap); err = fuse_filehandle_get_anyflags(vp, &fufh, cred, pid); Modified: projects/fuse2/tests/sys/fs/fusefs/locks.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/locks.cc Mon May 27 23:25:19 2019 (r348316) +++ projects/fuse2/tests/sys/fs/fusefs/locks.cc Tue May 28 00:03:46 2019 (r348317) @@ -29,6 +29,7 @@ */ extern "C" { +#include #include } @@ -59,14 +60,137 @@ class Locks: public Fallback { } }; +class Fcntl: public Locks { +public: +void expect_setlk(uint64_t ino, pid_t pid, uint64_t start, uint64_t end, + uint32_t type, int err) +{ + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_SETLK && + in.header.nodeid == ino && + in.body.setlk.fh == FH && + in.body.setlkw.owner == (uint32_t)pid && + in.body.setlkw.lk.start == start && + in.body.setlkw.lk.end == end && + in.body.setlkw.lk.type == type && + in.body.setlkw.lk.pid == (uint64_t)pid); + }, Eq(true)), + _) + ).WillOnce(Invoke(ReturnErrno(err))); +} +}; + +class Flock: public Locks { +public: +void expect_setlk(uint64_t ino, uint32_t type, int err) +{ + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_SETLK && + in.header.nodeid == ino && + in.body.setlk.fh == FH && + /* + * The owner should be set to the address of + * the vnode. That's hard to verify. + */ + /* in.body.setlk.owner == ??? && */ + in.body.setlk.lk.type == type); + }, Eq(true)), + _) + ).WillOnce(Invoke(ReturnErrno(err))); +} +}; + +class FlockFallback: public Fallback {}; class GetlkFallback: public Fallback {}; -class Getlk: public Locks {}; +class Getlk: public Fcntl {}; class SetlkFallback: public Fallback {}; -class Setlk: public Locks {}; +class Setlk: public Fcntl {}; class SetlkwFallback: public Fallback {}; -class Setlkw: public Locks {}; +class Setlkw: public Fcntl {}; /* + * If the fuse filesystem does not support flock locks, then the kernel should + * fall back to local locks. + */ +TEST_F(FlockFallback, local) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int fd; + + expect_lookup(RELPATH, ino); + expect_open(ino, 0, 1); + + fd = open(FULLPATH, O_RDWR); + ASSERT_LE(0, fd) << strerror(errno); + ASSERT_EQ(0, flock(fd, LOCK_EX)) << strerror(errno); + /* Deliberately leak fd. close(2) will be tested in release.cc */ +} + +/* + * Even if the fuse file system supports POSIX locks, we must implement flock + * locks locally until protocol 7.17. Protocol 7.9 added partial buggy support + * but we won't implement that. + */ +TEST_F(Flock, local) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int fd; + + expect_lookup(RELPATH, ino); + expect_open(ino, 0, 1); + + fd = open(FULLPATH, O_RDWR); + ASSERT_LE(0, fd) << strerror(errno); + ASSERT_EQ(0, flock(fd, LOCK_EX)) << strerror(errno); + /* Deliberately leak fd. close(2) will be tested in release.cc */ +} + +/* Set a new flock lock with FUSE_SETLK */ +/* TODO: enable after upgrading to protocol 7.17 */ +TEST_F(Flock, DISABLED_set) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int fd; + + expect_lookup(RELPATH, ino); + expect_open(ino, 0, 1); + expect_setlk(ino, F_WRLCK, 0); + + fd = open(FULLPATH, O_RDWR); + ASSERT_LE(0, fd) << strerror(errno); + ASSERT_EQ(0, flock(fd, LOCK_EX)) << strerror(errno); + /* Deliberately leak fd. close(2) will be tested in release.cc */ +} + +/* Fail to set a flock lock in non-blocking mode */ +/* TODO: enable after upgrading to protocol 7.17 */ +TEST_F(Flock, DISABLED_eagain) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + uint64_t ino = 42; + int fd; + + expect_lookup(RELPATH, ino); + expect_open(ino, 0, 1); + expect_setlk(ino, F_WRLCK, EAGAIN); + + fd = open(FULLPATH, O_RDWR); + ASSERT_LE(0, fd) << strerror(errno); + ASSERT_NE(0, flock(fd, LOCK_EX | LOCK_NB)); + ASSERT_EQ(EAGAIN, errno); + /* Deliberately leak fd. close(2) will be tested in release.cc */ +} + +/* * If the fuse filesystem does not support posix file locks, then the kernel * should fall back to local locks. */ @@ -229,19 +353,7 @@ TEST_F(Setlk, set) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in.header.opcode == FUSE_SETLK && - in.header.nodeid == ino && - in.body.setlk.fh == FH && - in.body.setlk.owner == (uint32_t)pid && - in.body.setlk.lk.start == 10 && - in.body.setlk.lk.end == 1009 && - in.body.setlk.lk.type == F_RDLCK && - in.body.setlk.lk.pid == (uint64_t)pid); - }, Eq(true)), - _) - ).WillOnce(Invoke(ReturnErrno(0))); + expect_setlk(ino, pid, 10, 1009, F_RDLCK, 0); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); @@ -267,19 +379,7 @@ TEST_F(Setlk, set_eof) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in.header.opcode == FUSE_SETLK && - in.header.nodeid == ino && - in.body.setlk.fh == FH && - in.body.setlk.owner == (uint32_t)pid && - in.body.setlk.lk.start == 10 && - in.body.setlk.lk.end == OFFSET_MAX && - in.body.setlk.lk.type == F_RDLCK && - in.body.setlk.lk.pid == (uint64_t)pid); - }, Eq(true)), - _) - ).WillOnce(Invoke(ReturnErrno(0))); + expect_setlk(ino, pid, 10, OFFSET_MAX, F_RDLCK, 0); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); @@ -305,19 +405,7 @@ TEST_F(Setlk, eagain) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in.header.opcode == FUSE_SETLK && - in.header.nodeid == ino && - in.body.setlk.fh == FH && - in.body.setlk.owner == (uint32_t)pid && - in.body.setlk.lk.start == 10 && - in.body.setlk.lk.end == 1009 && - in.body.setlk.lk.type == F_RDLCK && - in.body.setlk.lk.pid == (uint64_t)pid); - }, Eq(true)), - _) - ).WillOnce(Invoke(ReturnErrno(EAGAIN))); + expect_setlk(ino, pid, 10, 1009, F_RDLCK, EAGAIN); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); @@ -375,19 +463,7 @@ TEST_F(Setlkw, set) expect_lookup(RELPATH, ino); expect_open(ino, 0, 1); - EXPECT_CALL(*m_mock, process( - ResultOf([=](auto in) { - return (in.header.opcode == FUSE_SETLK && - in.header.nodeid == ino && - in.body.setlkw.fh == FH && - in.body.setlkw.owner == (uint32_t)pid && - in.body.setlkw.lk.start == 10 && - in.body.setlkw.lk.end == 1009 && - in.body.setlkw.lk.type == F_RDLCK && - in.body.setlkw.lk.pid == (uint64_t)pid); - }, Eq(true)), - _) - ).WillOnce(Invoke(ReturnErrno(0))); + expect_setlk(ino, pid, 10, 1009, F_RDLCK, 0); fd = open(FULLPATH, O_RDWR); ASSERT_LE(0, fd) << strerror(errno); From owner-svn-src-projects@freebsd.org Tue May 28 01:09:22 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 4A98E15B056D for ; Tue, 28 May 2019 01:09:22 +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 DEA3B8E918; Tue, 28 May 2019 01:09:21 +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 B5906AFB1; Tue, 28 May 2019 01:09:21 +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 x4S19L9T046724; Tue, 28 May 2019 01:09:21 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4S19KcA046717; Tue, 28 May 2019 01:09:20 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905280109.x4S19KcA046717@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Tue, 28 May 2019 01:09:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348319 - 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: 348319 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: DEA3B8E918 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)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.979,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: Tue, 28 May 2019 01:09:22 -0000 Author: asomers Date: Tue May 28 01:09:19 2019 New Revision: 348319 URL: https://svnweb.freebsd.org/changeset/base/348319 Log: fusefs: set the flags fields of fuse_write_in and fuse_read_in These fields are supposed to contain the file descriptor flags as supplied to open(2) or set by fcntl(2). The feature is kindof useless on FreeBSD since we don't supply all of these flags to fuse (because of the weak relationship between struct file and struct vnode). But we should at least set the access mode flags (O_RDONLY, etc). This is the last fusefs change needed to get full protocol 7.9 support. There are still a few options we don't support for good reason (mandatory file locking is dumb, flock support is broken in the protocol until 7.17, etc), but there's nothing else to do at this protocol level. 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_internal.c projects/fuse2/sys/fs/fuse/fuse_io.c projects/fuse2/tests/sys/fs/fusefs/mockfs.cc projects/fuse2/tests/sys/fs/fusefs/utils.cc projects/fuse2/tests/sys/fs/fusefs/utils.hh projects/fuse2/tests/sys/fs/fusefs/write.cc Modified: projects/fuse2/sys/fs/fuse/fuse_file.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.c Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/sys/fs/fuse/fuse_file.c Tue May 28 01:09:19 2019 (r348319) @@ -114,44 +114,6 @@ fflags_2_fufh_type(int fflags) panic("FUSE: What kind of a flag is this (%x)?", fflags); } -/* - * Get the flags to use for FUSE_CREATE, FUSE_OPEN and FUSE_RELEASE - * - * These are supposed to be the same as the flags argument to open(2). - * However, since we can't reliably associate a fuse_filehandle with a specific - * file descriptor it would would be dangerous to include anything more than - * the access mode flags. For example, suppose we open a file twice, once with - * O_APPEND and once without. Then the user pwrite(2)s to offset using the - * second file descriptor. If fusefs uses the first file handle, then the - * server may append the write to the end of the file rather than at offset 0. - * To prevent problems like this, we only ever send the portion of flags - * related to access mode. - * - * It's essential to send that portion, because FUSE uses it for server-side - * authorization. - * - * TODO: consider sending O_APPEND after upgrading to protocol 7.9, which - * includes flags in fuse_write_in. - */ -static inline int -fufh_type_2_fflags(fufh_type_t type) -{ - int oflags = -1; - - switch (type) { - case FUFH_RDONLY: - case FUFH_WRONLY: - case FUFH_RDWR: - case FUFH_EXEC: - oflags = type; - break; - default: - break; - } - - return oflags; -} - int fuse_filehandle_open(struct vnode *vp, int a_mode, struct fuse_filehandle **fufhp, struct thread *td, struct ucred *cred) Modified: projects/fuse2/sys/fs/fuse/fuse_file.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.h Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/sys/fs/fuse/fuse_file.h Tue May 28 01:09:19 2019 (r348319) @@ -148,6 +148,41 @@ struct fuse_filehandle { #define FUFH_IS_VALID(f) ((f)->fufh_type != FUFH_INVALID) +/* + * Get the flags to use for FUSE_CREATE, FUSE_OPEN and FUSE_RELEASE + * + * These are supposed to be the same as the flags argument to open(2). + * However, since we can't reliably associate a fuse_filehandle with a specific + * file descriptor it would would be dangerous to include anything more than + * the access mode flags. For example, suppose we open a file twice, once with + * O_APPEND and once without. Then the user pwrite(2)s to offset using the + * second file descriptor. If fusefs uses the first file handle, then the + * server may append the write to the end of the file rather than at offset 0. + * To prevent problems like this, we only ever send the portion of flags + * related to access mode. + * + * It's essential to send that portion, because FUSE uses it for server-side + * authorization. + */ +static inline int +fufh_type_2_fflags(fufh_type_t type) +{ + int oflags = -1; + + switch (type) { + case FUFH_RDONLY: + case FUFH_WRONLY: + case FUFH_RDWR: + case FUFH_EXEC: + oflags = type; + break; + default: + break; + } + + return oflags; +} + bool fuse_filehandle_validrw(struct vnode *vp, int mode, struct ucred *cred, pid_t pid); int fuse_filehandle_get(struct vnode *vp, int fflag, Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.c Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/sys/fs/fuse/fuse_internal.c Tue May 28 01:09:19 2019 (r348319) @@ -779,6 +779,10 @@ fuse_internal_init_callback(struct fuse_ticket *tick, data->dataflags |= FSESS_POSIX_LOCKS; if (fiio->flags & FUSE_EXPORT_SUPPORT) data->dataflags |= FSESS_EXPORT_SUPPORT; + /* + * Don't bother to check FUSE_BIG_WRITES, because it's + * redundant with max_write + */ } else { err = EINVAL; } @@ -816,7 +820,13 @@ fuse_internal_send_init(struct fuse_data *data, struct * the size of a buffer cache block. */ fiii->max_readahead = maxbcachebuf; - fiii->flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_EXPORT_SUPPORT ; + /* + * Unsupported features: + * FUSE_FILE_OPS: No known FUSE server or client supports it + * FUSE_ATOMIC_O_TRUNC: our VFS cannot support it + */ + fiii->flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_EXPORT_SUPPORT + | FUSE_BIG_WRITES; fuse_insert_callback(fdi.tick, fuse_internal_init_callback); fuse_insert_message(fdi.tick, false); Modified: projects/fuse2/sys/fs/fuse/fuse_io.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_io.c Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/sys/fs/fuse/fuse_io.c Tue May 28 01:09:19 2019 (r348319) @@ -380,7 +380,7 @@ fuse_read_directbackend(struct vnode *vp, struct uio * if (fuse_libabi_geq(data, 7, 9)) { /* See comment regarding FUSE_WRITE_LOCKOWNER */ fri->read_flags = 0; - fri->flags = 0; /* TODO */ + fri->flags = fufh_type_2_fflags(fufh->fufh_type); } SDT_PROBE1(fusefs, , io, read_directbackend_start, fri); @@ -461,7 +461,7 @@ fuse_write_directbackend(struct vnode *vp, struct uio fwi->size = chunksize; fwi->write_flags = write_flags; if (fuse_libabi_geq(data, 7, 9)) { - fwi->flags = 0; /* TODO */ + fwi->flags = fufh_type_2_fflags(fufh->fufh_type); fwi_data = (char *)fdi.indata + sizeof(*fwi); } else { fwi_data = (char *)fdi.indata + Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Tue May 28 01:09:19 2019 (r348319) @@ -218,6 +218,8 @@ void debug_fuseop(const mockfs_buf_in &in) printf(" offset=%" PRIu64 " size=%u", in.body.read.offset, in.body.read.size); + if (verbosity > 1) + printf(" flags=%#x", in.body.read.flags); break; case FUSE_READDIR: printf(" fh=%#" PRIx64 " offset=%" PRIu64 " size=%u", @@ -278,10 +280,12 @@ void debug_fuseop(const mockfs_buf_in &in) break; case FUSE_WRITE: printf(" fh=%#" PRIx64 " offset=%" PRIu64 - " size=%u flags=%u", + " size=%u write_flags=%u", in.body.write.fh, in.body.write.offset, in.body.write.size, in.body.write.write_flags); + if (verbosity > 1) + printf(" flags=%#x", in.body.write.flags); break; default: break; Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.cc Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/tests/sys/fs/fusefs/utils.cc Tue May 28 01:09:19 2019 (r348319) @@ -36,6 +36,7 @@ extern "C" { #include #include +#include #include #include #include @@ -273,7 +274,7 @@ void FuseTest::expect_opendir(uint64_t ino) } void FuseTest::expect_read(uint64_t ino, uint64_t offset, uint64_t isize, - uint64_t osize, const void *contents) + uint64_t osize, const void *contents, int flags) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -281,7 +282,11 @@ void FuseTest::expect_read(uint64_t ino, uint64_t offs in.header.nodeid == ino && in.body.read.fh == FH && in.body.read.offset == offset && - in.body.read.size == isize); + in.body.read.size == isize && + flags == -1 ? + (in.body.read.flags == O_RDONLY || + in.body.read.flags == O_RDWR) + : in.body.read.flags == (uint32_t)flags); }, Eq(true)), _) ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { @@ -400,6 +405,8 @@ void FuseTest::expect_write(uint64_t ino, uint64_t off pid_ok && (wf & flags_set) == flags_set && (wf & flags_unset) == 0 && + (in.body.write.flags == O_WRONLY || + in.body.write.flags == O_RDWR) && 0 == bcmp(buf, contents, isize)); }, Eq(true)), _) Modified: projects/fuse2/tests/sys/fs/fusefs/utils.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/utils.hh Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/tests/sys/fs/fusefs/utils.hh Tue May 28 01:09:19 2019 (r348319) @@ -139,7 +139,7 @@ class FuseTest : public ::testing::Test { * nothing currently validates the size of the fuse_read_in struct. */ void expect_read(uint64_t ino, uint64_t offset, uint64_t isize, - uint64_t osize, const void *contents); + uint64_t osize, const void *contents, int flags = -1); /* * Create an expectation that FUSE_READIR will be called any number of Modified: projects/fuse2/tests/sys/fs/fusefs/write.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/write.cc Tue May 28 00:51:23 2019 (r348318) +++ projects/fuse2/tests/sys/fs/fusefs/write.cc Tue May 28 01:09:19 2019 (r348319) @@ -636,7 +636,7 @@ TEST_F(WriteBack, rmw) FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, fsize, 1); expect_open(ino, 0, 1); - expect_read(ino, 0, fsize, fsize, INITIAL); + expect_read(ino, 0, fsize, fsize, INITIAL, O_WRONLY); expect_write(ino, offset, bufsize, bufsize, CONTENTS); fd = open(FULLPATH, O_WRONLY); From owner-svn-src-projects@freebsd.org Wed May 29 00:01:38 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 F38F115B09DF for ; Wed, 29 May 2019 00:01:37 +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 8716470AC0; Wed, 29 May 2019 00:01:37 +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 0608621B0D; Wed, 29 May 2019 00:01:37 +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 x4T01aPh082613; Wed, 29 May 2019 00:01:36 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4T01akA082610; Wed, 29 May 2019 00:01:36 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905290001.x4T01akA082610@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Wed, 29 May 2019 00:01:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348344 - 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: 348344 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 8716470AC0 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.96)[-0.961,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: Wed, 29 May 2019 00:01:38 -0000 Author: asomers Date: Wed May 29 00:01:36 2019 New Revision: 348344 URL: https://svnweb.freebsd.org/changeset/base/348344 Log: fusefs: raise protocol level to 7.10 Protocol version 7.10 has only one new feature, and I'm choosing not to implement it, so this commit is basically a noop. The sole new feature is the FOPEN_NONSEEKABLE flag, which a fuse file system can return to indicate that a certain file handle cannot be seeked. However, I'm unaware of any file system in ports that uses this flag. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_file.h projects/fuse2/sys/fs/fuse/fuse_kernel.h projects/fuse2/sys/fs/fuse/fuse_node.c Modified: projects/fuse2/sys/fs/fuse/fuse_file.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_file.h Wed May 29 00:00:52 2019 (r348343) +++ projects/fuse2/sys/fs/fuse/fuse_file.h Wed May 29 00:01:36 2019 (r348344) @@ -134,7 +134,16 @@ struct fuse_filehandle { /* The filehandle returned by FUSE_OPEN */ uint64_t fh_id; - /* flags returned by FUSE_OPEN */ + /* + * flags returned by FUSE_OPEN + * Supported flags: FOPEN_DIRECT_IO, FOPEN_KEEP_CACHE + * Unsupported: + * FOPEN_NONSEEKABLE: Adding support would require a new per-file + * or per-vnode attribute, which would have to be checked by + * kern_lseek (and others) for every file system. The benefit is + * dubious, since I'm unaware of any file systems in ports that use + * this flag. + */ uint32_t fuse_open_flags; /* The access mode of the file handle */ Modified: projects/fuse2/sys/fs/fuse/fuse_kernel.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_kernel.h Wed May 29 00:00:52 2019 (r348343) +++ projects/fuse2/sys/fs/fuse/fuse_kernel.h Wed May 29 00:01:36 2019 (r348344) @@ -45,6 +45,9 @@ * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in * - add blksize field to fuse_attr * - add file flags field to fuse_read_in and fuse_write_in + * + * 7.10 + * - add nonseekable open flag */ #ifndef _FUSE_FUSE_KERNEL_H @@ -64,7 +67,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 9 +#define FUSE_KERNEL_MINOR_VERSION 10 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -72,9 +75,6 @@ /** The major number of the fuse character device */ #define FUSE_MAJOR MISC_MAJOR -/** The minor number of the fuse character device */ -#define FUSE_MINOR 229 - /* Make sure all structures are padded to 64bit boundary, so 32bit userspace works under 64bit kernels */ @@ -136,9 +136,11 @@ struct fuse_file_lock { * * FOPEN_DIRECT_IO: bypass page cache for this open file * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + * FOPEN_NONSEEKABLE: the file is not seekable */ #define FOPEN_DIRECT_IO (1 << 0) #define FOPEN_KEEP_CACHE (1 << 1) +#define FOPEN_NONSEEKABLE (1 << 2) /** * INIT request/reply flags Modified: projects/fuse2/sys/fs/fuse/fuse_node.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_node.c Wed May 29 00:00:52 2019 (r348343) +++ projects/fuse2/sys/fs/fuse/fuse_node.c Wed May 29 00:01:36 2019 (r348344) @@ -312,30 +312,15 @@ fuse_vnode_get(struct mount *mp, return 0; } +/* + * Called for every fusefs vnode open to initialize the vnode (not + * fuse_filehandle) for use + */ void fuse_vnode_open(struct vnode *vp, int32_t fuse_open_flags, struct thread *td) { - /* - * Function is called for every vnode open. - * Merge fuse_open_flags it may be 0 - */ - /* - * Ideally speaking, direct io should be enabled on - * fd's but do not see of any way of providing that - * this implementation. - * - * Also cannot think of a reason why would two - * different fd's on same vnode would like - * have DIRECT_IO turned on and off. But linux - * based implementation works on an fd not an - * inode and provides such a feature. - * - * XXXIP: Handle fd based DIRECT_IO - */ - if (vnode_vtype(vp) == VREG) { - /* XXXIP prevent getattr, by using cached node size */ + if (vnode_vtype(vp) == VREG) vnode_create_vobject(vp, 0, td); - } } int From owner-svn-src-projects@freebsd.org Wed May 29 00:54: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 6EE4C15B1A85 for ; Wed, 29 May 2019 00:54: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 102AE72331; Wed, 29 May 2019 00:54:50 +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 D1C5F22424; Wed, 29 May 2019 00:54: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 x4T0snEK009534; Wed, 29 May 2019 00:54:49 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4T0snGA009533; Wed, 29 May 2019 00:54:49 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905290054.x4T0snGA009533@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Wed, 29 May 2019 00:54:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348345 - 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: 348345 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 102AE72331 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.96)[-0.965,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: Wed, 29 May 2019 00:54:50 -0000 Author: asomers Date: Wed May 29 00:54:49 2019 New Revision: 348345 URL: https://svnweb.freebsd.org/changeset/base/348345 Log: fusefs: raise protocol level to 7.11 This commit adds the definitions for protocol 7.11 but doesn't yet implement the new features. The new features are optional, so they can come later. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_kernel.h Modified: projects/fuse2/sys/fs/fuse/fuse_kernel.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_kernel.h Wed May 29 00:01:36 2019 (r348344) +++ projects/fuse2/sys/fs/fuse/fuse_kernel.h Wed May 29 00:54:49 2019 (r348345) @@ -1,6 +1,6 @@ /*-- * This file defines the kernel interface of FUSE - * Copyright (C) 2001-2007 Miklos Szeredi + * Copyright (C) 2001-2008 Miklos Szeredi * * This program can be distributed under the terms of the GNU GPL. * See the file COPYING. @@ -48,6 +48,10 @@ * * 7.10 * - add nonseekable open flag + * + * 7.11 + * - add IOCTL message + * - add unsolicited notification support */ #ifndef _FUSE_FUSE_KERNEL_H @@ -59,22 +63,18 @@ #define __u32 uint32_t #define __s32 int32_t #else -#include -#include +#include #endif /** Version number of this interface */ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 10 +#define FUSE_KERNEL_MINOR_VERSION 11 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 -/** The major number of the fuse character device */ -#define FUSE_MAJOR MISC_MAJOR - /* Make sure all structures are padded to 64bit boundary, so 32bit userspace works under 64bit kernels */ @@ -154,7 +154,16 @@ struct fuse_file_lock { #define FUSE_EXPORT_SUPPORT (1 << 4) #define FUSE_BIG_WRITES (1 << 5) +#ifdef linux /** + * CUSE INIT request/reply flags + * + * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl + */ +#define CUSE_UNRESTRICTED_IOCTL (1 << 0) +#endif /* linux */ + +/** * Release flags */ #define FUSE_RELEASE_FLUSH (1 << 0) @@ -183,6 +192,28 @@ struct fuse_file_lock { */ #define FUSE_READ_LOCKOWNER (1 << 1) +/** + * Ioctl flags + * + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed + * FUSE_IOCTL_RETRY: retry with new iovecs + * + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs + */ +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) + +#define FUSE_IOCTL_MAX_IOV 256 + +/** + * Poll flags + * + * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify + */ +#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ @@ -220,8 +251,20 @@ enum fuse_opcode { FUSE_INTERRUPT = 36, FUSE_BMAP = 37, FUSE_DESTROY = 38, + FUSE_IOCTL = 39, + FUSE_POLL = 40, + +#ifdef linux + /* CUSE specific operations */ + CUSE_INIT = 4096, +#endif /* linux */ }; +enum fuse_notify_code { + FUSE_NOTIFY_POLL = 1, + FUSE_NOTIFY_CODE_MAX, +}; + /* The read buffer is required to be at least 8k, but may be much larger */ #define FUSE_MIN_READ_BUFFER 8192 @@ -416,6 +459,29 @@ struct fuse_init_out { __u32 max_write; }; +#ifdef linux +#define CUSE_INIT_INFO_MAX 4096 + +struct cuse_init_in { + __u32 major; + __u32 minor; + __u32 unused; + __u32 flags; +}; + +struct cuse_init_out { + __u32 major; + __u32 minor; + __u32 unused; + __u32 flags; + __u32 max_read; + __u32 max_write; + __u32 dev_major; /* chardev major */ + __u32 dev_minor; /* chardev minor */ + __u32 spare[10]; +}; +#endif /* linux */ + struct fuse_interrupt_in { __u64 unique; }; @@ -428,6 +494,38 @@ struct fuse_bmap_in { struct fuse_bmap_out { __u64 block; +}; + +struct fuse_ioctl_in { + __u64 fh; + __u32 flags; + __u32 cmd; + __u64 arg; + __u32 in_size; + __u32 out_size; +}; + +struct fuse_ioctl_out { + __s32 result; + __u32 flags; + __u32 in_iovs; + __u32 out_iovs; +}; + +struct fuse_poll_in { + __u64 fh; + __u64 kh; + __u32 flags; + __u32 padding; +}; + +struct fuse_poll_out { + __u32 revents; + __u32 padding; +}; + +struct fuse_notify_poll_wakeup_out { + __u64 kh; }; struct fuse_in_header { From owner-svn-src-projects@freebsd.org Wed May 29 02:03:09 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 BFA2415B304F for ; Wed, 29 May 2019 02:03:09 +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 58D40747FE; Wed, 29 May 2019 02:03:09 +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 31DB922FD9; Wed, 29 May 2019 02:03:09 +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 x4T239xc045620; Wed, 29 May 2019 02:03:09 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4T239Bs045619; Wed, 29 May 2019 02:03:09 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905290203.x4T239Bs045619@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Wed, 29 May 2019 02:03:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348348 - 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: 348348 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 58D40747FE 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.96)[-0.960,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: Wed, 29 May 2019 02:03:10 -0000 Author: asomers Date: Wed May 29 02:03:08 2019 New Revision: 348348 URL: https://svnweb.freebsd.org/changeset/base/348348 Log: fusefs: add comments explaining why 7.11 features aren't implemented Protocol 7.11 adds two new features, but neither of them were defined correctly. FUSE_IOCTL messages don't work for 32-bit daemons on a 64-bit host (fixed in protocol 7.16). FUSE_POLL is basically unusable until 7.21. Before 7.21, the client can't choose which events to register for; the client registers for "something" and the server replies to say which events the client is registered for. Also, before 7.21 there was no way for a client to deregister a file handle. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vnops.c Wed May 29 02:02:56 2019 (r348347) +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Wed May 29 02:03:08 2019 (r348348) @@ -182,6 +182,11 @@ struct vop_vector fuse_vnops = { .vop_getattr = fuse_vnop_getattr, .vop_getextattr = fuse_vnop_getextattr, .vop_inactive = fuse_vnop_inactive, + /* + * TODO: implement vop_ioctl after upgrading to protocol 7.16. + * FUSE_IOCTL was added in 7.11, but 32-bit compat is broken until + * 7.16. + */ .vop_link = fuse_vnop_link, .vop_listextattr = fuse_vnop_listextattr, .vop_lookup = fuse_vnop_lookup, @@ -189,6 +194,12 @@ struct vop_vector fuse_vnops = { .vop_mknod = fuse_vnop_mknod, .vop_open = fuse_vnop_open, .vop_pathconf = fuse_vnop_pathconf, + /* + * TODO: implement vop_poll after upgrading to protocol 7.21. + * FUSE_POLL was added in protocol 7.11, but it's kind of broken until + * 7.21, which adds the ability for the client to choose which poll + * events it wants, and for a client to deregister a file handle + */ .vop_read = fuse_vnop_read, .vop_readdir = fuse_vnop_readdir, .vop_readlink = fuse_vnop_readlink, From owner-svn-src-projects@freebsd.org Wed May 29 16:39:55 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 4F49A15A7308 for ; Wed, 29 May 2019 16:39:55 +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 ED7A974A57; Wed, 29 May 2019 16:39:54 +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 C401E46EB; Wed, 29 May 2019 16:39:54 +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 x4TGdsHn003129; Wed, 29 May 2019 16:39:54 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4TGdrO0003120; Wed, 29 May 2019 16:39:53 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905291639.x4TGdrO0003120@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Wed, 29 May 2019 16:39:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348365 - 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: 348365 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: ED7A974A57 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)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.981,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: Wed, 29 May 2019 16:39:55 -0000 Author: asomers Date: Wed May 29 16:39:52 2019 New Revision: 348365 URL: https://svnweb.freebsd.org/changeset/base/348365 Log: fusefs: raise protocol level to 7.12 This commit raises the protocol level and adds backwards-compatibility code to handle structure size changes. It doesn't implement any new features. The new features added in protocol 7.12 are: * server-side umask processing (which FreeBSD won't do) * asynchronous inode and directory entry invalidation (which I'll do next) Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c projects/fuse2/sys/fs/fuse/fuse_kernel.h projects/fuse2/sys/fs/fuse/fuse_vnops.c projects/fuse2/tests/sys/fs/fusefs/create.cc projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc projects/fuse2/tests/sys/fs/fusefs/mkdir.cc projects/fuse2/tests/sys/fs/fusefs/mknod.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.c Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/sys/fs/fuse/fuse_internal.c Wed May 29 16:39:52 2019 (r348365) @@ -331,12 +331,22 @@ int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct vattr *vap) { + struct fuse_data *data; struct fuse_mknod_in fmni; + size_t insize; + data = fuse_get_mpdata(dvp->v_mount); + fmni.mode = MAKEIMODE(vap->va_type, vap->va_mode); fmni.rdev = vap->va_rdev; + if (fuse_libabi_geq(data, 7, 12)) { + insize = sizeof(fmni); + fmni.umask = curthread->td_proc->p_fd->fd_cmask; + } else { + insize = FUSE_COMPAT_MKNOD_IN_SIZE; + } return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKNOD, &fmni, - sizeof(fmni), vap->va_type)); + insize, vap->va_type)); } /* readdir */ @@ -824,6 +834,8 @@ fuse_internal_send_init(struct fuse_data *data, struct * Unsupported features: * FUSE_FILE_OPS: No known FUSE server or client supports it * FUSE_ATOMIC_O_TRUNC: our VFS cannot support it + * FUSE_DONT_MASK: unlike Linux, FreeBSD always applies the umask, even + * when default ACLs are in use. */ fiii->flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES; Modified: projects/fuse2/sys/fs/fuse/fuse_kernel.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_kernel.h Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/sys/fs/fuse/fuse_kernel.h Wed May 29 16:39:52 2019 (r348365) @@ -52,6 +52,11 @@ * 7.11 * - add IOCTL message * - add unsolicited notification support + * + * 7.12 + * - add umask flag to input argument of open, mknod and mkdir + * - add notification messages for invalidation of inodes and + * directory entries */ #ifndef _FUSE_FUSE_KERNEL_H @@ -60,6 +65,7 @@ #ifndef linux #include #define __u64 uint64_t +#define __s64 int64_t #define __u32 uint32_t #define __s32 int32_t #else @@ -70,7 +76,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 11 +#define FUSE_KERNEL_MINOR_VERSION 12 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -146,6 +152,7 @@ struct fuse_file_lock { * INIT request/reply flags * * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." + * FUSE_DONT_MASK: don't apply umask to file mode on create operations */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -153,6 +160,7 @@ struct fuse_file_lock { #define FUSE_ATOMIC_O_TRUNC (1 << 3) #define FUSE_EXPORT_SUPPORT (1 << 4) #define FUSE_BIG_WRITES (1 << 5) +#define FUSE_DONT_MASK (1 << 6) #ifdef linux /** @@ -262,6 +270,8 @@ enum fuse_opcode { enum fuse_notify_code { FUSE_NOTIFY_POLL = 1, + FUSE_NOTIFY_INVAL_INODE = 2, + FUSE_NOTIFY_INVAL_ENTRY = 3, FUSE_NOTIFY_CODE_MAX, }; @@ -300,14 +310,18 @@ struct fuse_attr_out { struct fuse_attr attr; }; +#define FUSE_COMPAT_MKNOD_IN_SIZE 8 + struct fuse_mknod_in { __u32 mode; __u32 rdev; + __u32 umask; + __u32 padding; }; struct fuse_mkdir_in { __u32 mode; - __u32 padding; + __u32 umask; }; struct fuse_rename_in { @@ -339,7 +353,14 @@ struct fuse_setattr_in { struct fuse_open_in { __u32 flags; + __u32 unused; +}; + +struct fuse_create_in { + __u32 flags; __u32 mode; + __u32 umask; + __u32 padding; }; struct fuse_open_out { @@ -557,5 +578,17 @@ struct fuse_dirent { #define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) #define FUSE_DIRENT_SIZE(d) \ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) + +struct fuse_notify_inval_inode_out { + __u64 ino; + __s64 off; + __s64 len; +}; + +struct fuse_notify_inval_entry_out { + __u64 parent; + __u32 namelen; + __u32 padding; +}; #endif /* _FUSE_FUSE_KERNEL_H */ Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vnops.c Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Wed May 29 16:39:52 2019 (r348365) @@ -540,7 +540,8 @@ fuse_vnop_create(struct vop_create_args *ap) struct thread *td = cnp->cn_thread; struct ucred *cred = cnp->cn_cred; - struct fuse_open_in *foi; + struct fuse_data *data; + struct fuse_create_in *fci; struct fuse_entry_out *feo; struct fuse_open_out *foo; struct fuse_dispatcher fdi, fdi2; @@ -550,6 +551,7 @@ fuse_vnop_create(struct vop_create_args *ap) int err; struct mount *mp = vnode_mount(dvp); + data = fuse_get_mpdata(mp); uint64_t parentnid = VTOFUD(dvp)->nid; mode_t mode = MAKEIMODE(vap->va_type, vap->va_mode); enum fuse_opcode op; @@ -580,15 +582,24 @@ fuse_vnop_create(struct vop_create_args *ap) cred, mode, &op); } else { /* Use FUSE_CREATE */ + size_t insize; + op = FUSE_CREATE; - fdisp_init(fdip, sizeof(*foi) + cnp->cn_namelen + 1); + fdisp_init(fdip, sizeof(*fci) + cnp->cn_namelen + 1); fdisp_make(fdip, op, vnode_mount(dvp), parentnid, td, cred); - foi = fdip->indata; - foi->mode = mode; - foi->flags = O_CREAT | flags; - memcpy((char *)fdip->indata + sizeof(*foi), cnp->cn_nameptr, + fci = fdip->indata; + fci->mode = mode; + fci->flags = O_CREAT | flags; + if (fuse_libabi_geq(data, 7, 12)) { + insize = sizeof(*fci); + fci->umask = td->td_proc->p_fd->fd_cmask; + } else { + insize = sizeof(struct fuse_open_in); + } + + memcpy((char *)fdip->indata + insize, cnp->cn_nameptr, cnp->cn_namelen); - ((char *)fdip->indata)[sizeof(*foi) + cnp->cn_namelen] = '\0'; + ((char *)fdip->indata)[insize + cnp->cn_namelen] = '\0'; } err = fdisp_wait_answ(fdip); @@ -614,12 +625,13 @@ fuse_vnop_create(struct vop_create_args *ap) foo = (struct fuse_open_out*)(feo + 1); } else { /* Issue a separate FUSE_OPEN */ + struct fuse_open_in *foi; + fdip2 = &fdi2; fdisp_init(fdip2, sizeof(*foi)); fdisp_make(fdip2, FUSE_OPEN, vnode_mount(dvp), feo->nodeid, td, cred); foi = fdip2->indata; - foi->mode = mode; foi->flags = flags; err = fdisp_wait_answ(fdip2); if (err) @@ -1162,6 +1174,7 @@ fuse_vnop_mkdir(struct vop_mkdir_args *ap) return ENXIO; } fmdi.mode = MAKEIMODE(vap->va_type, vap->va_mode); + fmdi.umask = curthread->td_proc->p_fd->fd_cmask; return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi, sizeof(fmdi), VDIR)); Modified: projects/fuse2/tests/sys/fs/fusefs/create.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/create.cc Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/tests/sys/fs/fusefs/create.cc Wed May 29 16:39:52 2019 (r348365) @@ -42,12 +42,16 @@ class Create: public FuseTest { (public) void expect_create(const char *relpath, mode_t mode, ProcessMockerT r) { + mode_t mask = umask(0); + (void)umask(mask); + EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { const char *name = (const char*)in.body.bytes + - sizeof(fuse_open_in); + sizeof(fuse_create_in); return (in.header.opcode == FUSE_CREATE && - in.body.open.mode == mode && + in.body.create.mode == mode && + in.body.create.umask == mask && (0 == strcmp(relpath, name))); }, Eq(true)), _) @@ -63,9 +67,48 @@ virtual void SetUp() { m_kernel_minor_version = 8; Create::SetUp(); } + +void expect_create(const char *relpath, mode_t mode, ProcessMockerT r) +{ + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + const char *name = (const char*)in.body.bytes + + sizeof(fuse_open_in); + return (in.header.opcode == FUSE_CREATE && + in.body.create.mode == mode && + (0 == strcmp(relpath, name))); + }, Eq(true)), + _) + ).WillOnce(Invoke(r)); +} + }; +/* FUSE_CREATE operations for a server built at protocol <= 7.11 */ +class Create_7_11: public FuseTest { +public: +virtual void SetUp() { + m_kernel_minor_version = 11; + FuseTest::SetUp(); +} +void expect_create(const char *relpath, mode_t mode, ProcessMockerT r) +{ + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + const char *name = (const char*)in.body.bytes + + sizeof(fuse_open_in); + return (in.header.opcode == FUSE_CREATE && + in.body.create.mode == mode && + (0 == strcmp(relpath, name))); + }, Eq(true)), + _) + ).WillOnce(Invoke(r)); +} + +}; + + /* * If FUSE_CREATE sets attr_valid, then subsequent GETATTRs should use the * attribute cache @@ -372,4 +415,25 @@ TEST_F(Create_7_8, ok) /* Deliberately leak fd. close(2) will be tested in release.cc */ } +TEST_F(Create_7_11, ok) +{ + const char FULLPATH[] = "mountpoint/some_file.txt"; + const char RELPATH[] = "some_file.txt"; + mode_t mode = S_IFREG | 0755; + uint64_t ino = 42; + int fd; + EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + expect_create(RELPATH, mode, + ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, create); + out.body.create.entry.attr.mode = mode; + out.body.create.entry.nodeid = ino; + out.body.create.entry.entry_valid = UINT64_MAX; + out.body.create.entry.attr_valid = UINT64_MAX; + })); + + fd = open(FULLPATH, O_CREAT | O_EXCL, mode); + EXPECT_LE(0, fd) << strerror(errno); + /* Deliberately leak fd. close(2) will be tested in release.cc */ +} Modified: projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Wed May 29 16:39:52 2019 (r348365) @@ -92,7 +92,7 @@ void expect_create(const char *relpath, uint64_t ino) EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { const char *name = (const char*)in.body.bytes + - sizeof(fuse_open_in); + sizeof(fuse_create_in); return (in.header.opcode == FUSE_CREATE && (0 == strcmp(relpath, name))); }, Eq(true)), Modified: projects/fuse2/tests/sys/fs/fusefs/mkdir.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mkdir.cc Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/tests/sys/fs/fusefs/mkdir.cc Wed May 29 16:39:52 2019 (r348365) @@ -159,7 +159,11 @@ TEST_F(Mkdir, ok) const char RELPATH[] = "some_dir"; mode_t mode = 0755; uint64_t ino = 42; + mode_t mask; + mask = umask(0); + (void)umask(mask); + EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( @@ -168,6 +172,7 @@ TEST_F(Mkdir, ok) sizeof(fuse_mkdir_in); return (in.header.opcode == FUSE_MKDIR && in.body.mkdir.mode == (S_IFDIR | mode) && + in.body.mkdir.umask == mask && (0 == strcmp(RELPATH, name))); }, Eq(true)), _) Modified: projects/fuse2/tests/sys/fs/fusefs/mknod.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mknod.cc Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/tests/sys/fs/fusefs/mknod.cc Wed May 29 16:39:52 2019 (r348365) @@ -48,16 +48,69 @@ const char RELPATH[] = "some_file.txt"; class Mknod: public FuseTest { +mode_t m_oldmask; +const static mode_t c_umask = 022; + public: virtual void SetUp() { + m_oldmask = umask(c_umask); + printf("m_oldmask=%#o\n", m_oldmask); + if (geteuid() != 0) { + GTEST_SKIP() << "Only root may use most mknod(2) variations"; + } FuseTest::SetUp(); +} +virtual void TearDown() { + FuseTest::TearDown(); + (void)umask(m_oldmask); +} + +/* Test an OK creation of a file with the given mode and device number */ +void expect_mknod(mode_t mode, dev_t dev) { + uint64_t ino = 42; + + EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + const char *name = (const char*)in.body.bytes + + sizeof(fuse_mknod_in); + return (in.header.opcode == FUSE_MKNOD && + in.body.mknod.mode == mode && + in.body.mknod.rdev == (uint32_t)dev && + in.body.mknod.umask == c_umask && + (0 == strcmp(RELPATH, name))); + }, Eq(true)), + _) + ).WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, entry); + out.body.entry.attr.mode = mode; + out.body.entry.nodeid = ino; + out.body.entry.entry_valid = UINT64_MAX; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.attr.rdev = dev; + }))); +} + +}; + +class Mknod_7_11: public FuseTest { +public: +virtual void SetUp() { + m_kernel_minor_version = 11; if (geteuid() != 0) { GTEST_SKIP() << "Only root may use most mknod(2) variations"; } + FuseTest::SetUp(); } +void expect_lookup(const char *relpath, uint64_t ino, uint64_t size) +{ + FuseTest::expect_lookup_7_8(relpath, ino, S_IFREG | 0644, size, 1); +} + /* Test an OK creation of a file with the given mode and device number */ void expect_mknod(mode_t mode, dev_t dev) { uint64_t ino = 42; @@ -67,7 +120,7 @@ void expect_mknod(mode_t mode, dev_t dev) { EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { const char *name = (const char*)in.body.bytes + - sizeof(fuse_mknod_in); + FUSE_COMPAT_MKNOD_IN_SIZE; return (in.header.opcode == FUSE_MKNOD && in.body.mknod.mode == mode && in.body.mknod.rdev == (uint32_t)dev && @@ -171,4 +224,13 @@ TEST_F(Mknod, DISABLED_whiteout) dev_t rdev = VNOVAL; /* whiteouts don't have device numbers */ expect_mknod(mode, rdev); EXPECT_EQ(0, mknod(FULLPATH, mode, 0)) << strerror(errno); +} + +/* A server built at protocol version 7.11 or earlier can still use mknod */ +TEST_F(Mknod_7_11, fifo) +{ + mode_t mode = S_IFIFO | 0755; + dev_t rdev = VNOVAL; + expect_mknod(mode, rdev); + EXPECT_EQ(0, mkfifo(FULLPATH, mode)) << strerror(errno); } Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Wed May 29 16:39:52 2019 (r348365) @@ -153,7 +153,7 @@ void sigint_handler(int __unused sig) { // Don't do anything except interrupt the daemon's read(2) call } -void debug_fuseop(const mockfs_buf_in &in) +void MockFS::debug_fuseop(const mockfs_buf_in &in) { printf("%-11s ino=%2" PRIu64, opcode2opname(in.header.opcode), in.header.nodeid); @@ -169,8 +169,12 @@ void debug_fuseop(const mockfs_buf_in &in) printf(" mask=%#x", in.body.access.mask); break; case FUSE_CREATE: - name = (const char*)in.body.bytes + - sizeof(fuse_open_in); + if (m_kernel_minor_version >= 12) + name = (const char*)in.body.bytes + + sizeof(fuse_create_in); + else + name = (const char*)in.body.bytes + + sizeof(fuse_open_in); printf(" flags=%#x name=%s", in.body.open.flags, name); break; @@ -200,19 +204,25 @@ void debug_fuseop(const mockfs_buf_in &in) case FUSE_MKDIR: name = (const char*)in.body.bytes + sizeof(fuse_mkdir_in); - printf(" name=%s mode=%#o", name, in.body.mkdir.mode); + printf(" name=%s mode=%#o umask=%#o", name, + in.body.mkdir.mode, in.body.mkdir.umask); break; case FUSE_MKNOD: - printf(" mode=%#o rdev=%x", in.body.mknod.mode, - in.body.mknod.rdev); + if (m_kernel_minor_version >= 12) + name = (const char*)in.body.bytes + + sizeof(fuse_mknod_in); + else + name = (const char*)in.body.bytes + + FUSE_COMPAT_MKNOD_IN_SIZE; + printf(" mode=%#o rdev=%x umask=%#o name=%s", + in.body.mknod.mode, in.body.mknod.rdev, + in.body.mknod.umask, name); break; case FUSE_OPEN: - printf(" flags=%#x mode=%#o", - in.body.open.flags, in.body.open.mode); + printf(" flags=%#x", in.body.open.flags); break; case FUSE_OPENDIR: - printf(" flags=%#x mode=%#o", - in.body.opendir.flags, in.body.opendir.mode); + printf(" flags=%#x", in.body.opendir.flags); break; case FUSE_READ: printf(" offset=%" PRIu64 " size=%u", Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Wed May 29 16:01:34 2019 (r348364) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Wed May 29 16:39:52 2019 (r348365) @@ -126,6 +126,7 @@ union fuse_payloads_in { fuse_access_in access; /* value is from fuse_kern_chan.c in fusefs-libs */ uint8_t bytes[0x21000 - sizeof(struct fuse_in_header)]; + fuse_create_in create; fuse_flush_in flush; fuse_fsync_in fsync; fuse_fsync_in fsyncdir; @@ -256,6 +257,8 @@ class MockFS { /* Method the daemon should use for I/O to and from /dev/fuse */ enum poll_method m_pm; + + void debug_fuseop(const mockfs_buf_in&); /* Initialize a session after mounting */ void init(uint32_t flags); From owner-svn-src-projects@freebsd.org Fri May 31 17:02:41 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 858A315C1B0C for ; Fri, 31 May 2019 17:02:40 +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 2F3DA74C6F; Fri, 31 May 2019 17:02:40 +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 E49F63320; Fri, 31 May 2019 17:02:39 +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 x4VH2daC045094; Fri, 31 May 2019 17:02:39 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4VH2b4i045080; Fri, 31 May 2019 17:02:37 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905311702.x4VH2b4i045080@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Fri, 31 May 2019 17:02:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348469 - projects/fuse2/tests/sys/fs/fusefs X-SVN-Group: projects X-SVN-Commit-Author: asomers X-SVN-Commit-Paths: projects/fuse2/tests/sys/fs/fusefs X-SVN-Commit-Revision: 348469 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 2F3DA74C6F X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.97)[-0.966,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, 31 May 2019 17:02:41 -0000 Author: asomers Date: Fri May 31 17:02:37 2019 New Revision: 348469 URL: https://svnweb.freebsd.org/changeset/base/348469 Log: fusefs: prefer FUSE_ROOT_ID to literal 1 in the tests Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/tests/sys/fs/fusefs/access.cc projects/fuse2/tests/sys/fs/fusefs/allow_other.cc projects/fuse2/tests/sys/fs/fusefs/create.cc projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc projects/fuse2/tests/sys/fs/fusefs/destroy.cc projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc projects/fuse2/tests/sys/fs/fusefs/fifo.cc projects/fuse2/tests/sys/fs/fusefs/getattr.cc projects/fuse2/tests/sys/fs/fusefs/interrupt.cc projects/fuse2/tests/sys/fs/fusefs/link.cc projects/fuse2/tests/sys/fs/fusefs/lookup.cc projects/fuse2/tests/sys/fs/fusefs/mkdir.cc projects/fuse2/tests/sys/fs/fusefs/mknod.cc projects/fuse2/tests/sys/fs/fusefs/nfs.cc projects/fuse2/tests/sys/fs/fusefs/open.cc projects/fuse2/tests/sys/fs/fusefs/rename.cc projects/fuse2/tests/sys/fs/fusefs/rmdir.cc projects/fuse2/tests/sys/fs/fusefs/setattr.cc projects/fuse2/tests/sys/fs/fusefs/symlink.cc projects/fuse2/tests/sys/fs/fusefs/unlink.cc projects/fuse2/tests/sys/fs/fusefs/utils.cc Modified: projects/fuse2/tests/sys/fs/fusefs/access.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/access.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/access.cc Fri May 31 17:02:37 2019 (r348469) @@ -62,7 +62,7 @@ TEST_F(Access, eaccess) uint64_t ino = 42; mode_t access_mode = X_OK; - expect_access(1, X_OK, 0); + expect_access(FUSE_ROOT_ID, X_OK, 0); expect_lookup(RELPATH, ino); expect_access(ino, access_mode, EACCES); @@ -82,7 +82,7 @@ TEST_F(Access, enosys) uint64_t ino = 42; mode_t access_mode = R_OK; - expect_access(1, X_OK, ENOSYS); + expect_access(FUSE_ROOT_ID, X_OK, ENOSYS); FuseTest::expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2); ASSERT_EQ(0, access(FULLPATH, access_mode)) << strerror(errno); @@ -96,7 +96,7 @@ TEST_F(RofsAccess, erofs) uint64_t ino = 42; mode_t access_mode = W_OK; - expect_access(1, X_OK, 0); + expect_access(FUSE_ROOT_ID, X_OK, 0); expect_lookup(RELPATH, ino); ASSERT_NE(0, access(FULLPATH, access_mode)); @@ -111,7 +111,7 @@ TEST_F(Access, ok) uint64_t ino = 42; mode_t access_mode = R_OK; - expect_access(1, X_OK, 0); + expect_access(FUSE_ROOT_ID, X_OK, 0); expect_lookup(RELPATH, ino); expect_access(ino, access_mode, 0); Modified: projects/fuse2/tests/sys/fs/fusefs/allow_other.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/allow_other.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/allow_other.cc Fri May 31 17:02:37 2019 (r348469) @@ -267,7 +267,7 @@ TEST_F(NoAllowOther, setextattr) int ino = 42, status; fork(true, &status, [&] { - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .WillOnce(Invoke( ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); Modified: projects/fuse2/tests/sys/fs/fusefs/create.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/create.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/create.cc Fri May 31 17:02:37 2019 (r348469) @@ -121,7 +121,8 @@ TEST_F(Create, attr_cache) uint64_t ino = 42; int fd; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); @@ -154,17 +155,18 @@ TEST_F(Create, clear_attr_cache) int fd; struct stat sb; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in.header.opcode == FUSE_GETATTR && - in.header.nodeid == 1); + in.header.nodeid == FUSE_ROOT_ID); }, Eq(true)), _) ).Times(2) .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out.body.attr.attr.ino = 1; + out.body.attr.attr.ino = FUSE_ROOT_ID; out.body.attr.attr.mode = S_IFDIR | 0755; out.body.attr.attr_valid = UINT64_MAX; }))); @@ -197,7 +199,8 @@ TEST_F(Create, eexist) const char RELPATH[] = "some_file.txt"; mode_t mode = S_IFREG | 0755; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnErrno(EEXIST)); EXPECT_NE(0, open(FULLPATH, O_CREAT | O_EXCL, mode)); EXPECT_EQ(EEXIST, errno); @@ -215,7 +218,8 @@ TEST_F(Create, Enosys) uint64_t ino = 42; int fd; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnErrno(ENOSYS)); EXPECT_CALL(*m_mock, process( @@ -270,7 +274,8 @@ TEST_F(Create, entry_cache_negative) struct timespec entry_valid = {.tv_sec = 0, .tv_nsec = 0}; /* create will first do a LOOKUP, adding a negative cache entry */ - EXPECT_LOOKUP(1, RELPATH).WillOnce(ReturnNegativeCache(&entry_valid)); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(ReturnNegativeCache(&entry_valid)); expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); @@ -298,8 +303,8 @@ TEST_F(Create, entry_cache_negative_purge) struct timespec entry_valid = {.tv_sec = TIME_T_MAX, .tv_nsec = 0}; /* create will first do a LOOKUP, adding a negative cache entry */ - EXPECT_LOOKUP(1, RELPATH).Times(1) - .WillOnce(Invoke(ReturnNegativeCache(&entry_valid))) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH).Times(1) + .WillOnce(Invoke(ReturnNegativeCache(&entry_valid))) .RetiresOnSaturation(); /* Then the CREATE should purge the negative cache entry */ @@ -331,7 +336,8 @@ TEST_F(Create, eperm) const char RELPATH[] = "some_file.txt"; mode_t mode = S_IFREG | 0755; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnErrno(EPERM)); EXPECT_NE(0, open(FULLPATH, O_CREAT | O_EXCL, mode)); @@ -346,7 +352,8 @@ TEST_F(Create, ok) uint64_t ino = 42; int fd; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); @@ -377,7 +384,8 @@ TEST_F(Create, wronly_0444) uint64_t ino = 42; int fd; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); @@ -400,7 +408,8 @@ TEST_F(Create_7_8, ok) uint64_t ino = 42; int fd; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create_7_8); @@ -423,7 +432,8 @@ TEST_F(Create_7_11, ok) uint64_t ino = 42; int fd; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, mode, ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, create); Modified: projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/default_permissions.cc Fri May 31 17:02:37 2019 (r348469) @@ -252,7 +252,7 @@ TEST_F(Access, eacces) uint64_t ino = 42; mode_t access_mode = X_OK; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX); ASSERT_NE(0, access(FULLPATH, access_mode)); @@ -266,7 +266,7 @@ TEST_F(Access, eacces_no_cached_attrs) uint64_t ino = 42; mode_t access_mode = X_OK; - expect_getattr(1, S_IFDIR | 0755, 0, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, 0, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, 0); expect_getattr(ino, S_IFREG | 0644, 0, 1); /* @@ -286,7 +286,7 @@ TEST_F(Access, ok) uint64_t ino = 42; mode_t access_mode = R_OK; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX); /* * Once default_permissions is properly implemented, there might be @@ -307,7 +307,7 @@ TEST_F(Chown, chown_to_self) uid = geteuid(); - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, uid); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, uid); expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, uid); /* The OS may optimize chown by omitting the redundant setattr */ EXPECT_CALL(*m_mock, process( @@ -338,7 +338,7 @@ TEST_F(Chown, clear_suid) uid_t uid = geteuid(); uint32_t valid = FATTR_UID | FATTR_MODE; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, uid); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, uid); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, uid); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -367,7 +367,7 @@ TEST_F(Chown, eperm) const uint64_t ino = 42; const mode_t mode = 0755; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, geteuid()); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, geteuid()); expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -395,7 +395,7 @@ TEST_F(Chgrp, clear_suid) gid_t gid = getegid(); uint32_t valid = FATTR_GID | FATTR_MODE; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, uid); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, uid); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, uid, gid); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { @@ -429,7 +429,7 @@ TEST_F(Chgrp, eperm) gid = getegid(); newgid = excluded_group(); - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, uid, gid); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, uid, gid); expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, uid, gid); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -455,7 +455,7 @@ TEST_F(Chgrp, ok) gid = 0; newgid = getegid(); - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, uid, gid); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, uid, gid); expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, uid, gid); /* The OS may optimize chgrp by omitting the redundant setattr */ EXPECT_CALL(*m_mock, process( @@ -481,8 +481,9 @@ TEST_F(Create, ok) uint64_t ino = 42; int fd; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1); - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, ino); fd = open(FULLPATH, O_CREAT | O_EXCL, 0644); @@ -495,8 +496,9 @@ TEST_F(Create, eacces) const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_EQ(-1, open(FULLPATH, O_CREAT | O_EXCL, 0644)); EXPECT_EQ(EACCES, errno); @@ -509,7 +511,7 @@ TEST_F(Deleteextattr, eacces) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, 0); ASSERT_EQ(-1, extattr_delete_file(FULLPATH, ns, "foo")); @@ -523,7 +525,7 @@ TEST_F(Deleteextattr, ok) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, geteuid()); expect_removexattr(); @@ -539,7 +541,7 @@ TEST_F(Deleteextattr, system) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_SYSTEM; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0666, UINT64_MAX, geteuid()); ASSERT_EQ(-1, extattr_delete_file(FULLPATH, ns, "foo")); @@ -560,7 +562,7 @@ TEST_F(Utimensat, utime_now) {.tv_sec = 0, .tv_nsec = UTIME_NOW}, }; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, owner); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -593,7 +595,7 @@ TEST_F(Utimensat, utime_omit) {.tv_sec = 0, .tv_nsec = UTIME_OMIT}, }; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | mode, UINT64_MAX, owner); ASSERT_EQ(0, utimensat(AT_FDCWD, FULLPATH, ×[0], 0)) @@ -608,7 +610,7 @@ TEST_F(Deleteextattr, user) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0666, UINT64_MAX, 0); expect_removexattr(); @@ -624,7 +626,7 @@ TEST_F(Getextattr, eacces) char data[80]; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0600, UINT64_MAX, 0); ASSERT_EQ(-1, @@ -643,7 +645,7 @@ TEST_F(Getextattr, ok) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); /* Getting user attributes only requires read access */ expect_lookup(RELPATH, ino, S_IFREG | 0444, UINT64_MAX, 0); expect_getxattr( @@ -667,7 +669,7 @@ TEST_F(Getextattr, system) char data[80]; int ns = EXTATTR_NAMESPACE_SYSTEM; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0666, UINT64_MAX, geteuid()); ASSERT_EQ(-1, @@ -682,7 +684,7 @@ TEST_F(Listextattr, eacces) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0600, UINT64_MAX, 0); ASSERT_EQ(-1, extattr_list_file(FULLPATH, ns, NULL, 0)); @@ -696,7 +698,7 @@ TEST_F(Listextattr, ok) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1); /* Listing user extended attributes merely requires read access */ expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, 0); expect_listxattr(); @@ -713,7 +715,7 @@ TEST_F(Listextattr, system) uint64_t ino = 42; int ns = EXTATTR_NAMESPACE_SYSTEM; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1); /* Listing user extended attributes merely requires read access */ expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, geteuid()); @@ -728,7 +730,7 @@ TEST_F(Lookup, eacces) const char RELDIRPATH[] = "some_dir"; uint64_t dir_ino = 42; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELDIRPATH, dir_ino, S_IFDIR | 0700, UINT64_MAX, 0); EXPECT_EQ(-1, access(FULLPATH, F_OK)); @@ -741,7 +743,7 @@ TEST_F(Open, eacces) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX); EXPECT_NE(0, open(FULLPATH, O_RDWR)); @@ -755,7 +757,7 @@ TEST_F(Open, ok) uint64_t ino = 42; int fd; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX); expect_open(ino, 0, 1); @@ -772,9 +774,9 @@ TEST_F(Rename, eacces_on_srcdir) const char RELSRC[] = "src"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1, 0); expect_lookup(RELSRC, ino, S_IFREG | 0644, UINT64_MAX); - EXPECT_LOOKUP(1, RELDST) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST) .Times(AnyNumber()) .WillRepeatedly(Invoke(ReturnErrno(ENOENT))); @@ -792,7 +794,7 @@ TEST_F(Rename, eacces_on_dstdir_for_creating) uint64_t src_ino = 42; uint64_t dstdir_ino = 43; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, src_ino, S_IFREG | 0644, UINT64_MAX); expect_lookup(RELDSTDIR, dstdir_ino, S_IFDIR | 0755, UINT64_MAX); EXPECT_LOOKUP(dstdir_ino, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); @@ -811,7 +813,7 @@ TEST_F(Rename, eacces_on_dstdir_for_removing) uint64_t src_ino = 42; uint64_t dstdir_ino = 43; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, src_ino, S_IFREG | 0644, UINT64_MAX); expect_lookup(RELDSTDIR, dstdir_ino, S_IFDIR | 0755, UINT64_MAX); EXPECT_LOOKUP(dstdir_ino, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); @@ -827,7 +829,7 @@ TEST_F(Rename, eperm_on_sticky_srcdir) const char RELSRC[] = "src"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 01777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 01777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, ino, S_IFREG | 0644, UINT64_MAX); ASSERT_EQ(-1, rename(FULLSRC, FULLDST)); @@ -848,7 +850,7 @@ TEST_F(Rename, eperm_for_subdirectory) uint64_t ino = 42; uint64_t dstdir_ino = 43; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, ino, S_IFDIR | 0755, UINT64_MAX, 0); expect_lookup(RELDSTDIR, dstdir_ino, S_IFDIR | 0777, UINT64_MAX, 0); EXPECT_LOOKUP(dstdir_ino, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); @@ -869,9 +871,10 @@ TEST_F(Rename, subdirectory_to_same_dir) const char RELSRC[] = "src"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, ino, S_IFDIR | 0755, UINT64_MAX, 0); - EXPECT_LOOKUP(1, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_rename(0); ASSERT_EQ(0, rename(FULLSRC, FULLDST)) << strerror(errno); @@ -888,7 +891,7 @@ TEST_F(Rename, eperm_on_sticky_dstdir) uint64_t dstdir_ino = 43; uint64_t dst_ino = 44; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, src_ino, S_IFREG | 0644, UINT64_MAX); expect_lookup(RELDSTDIR, dstdir_ino, S_IFDIR | 01777, UINT64_MAX); EXPECT_LOOKUP(dstdir_ino, RELDST) @@ -916,7 +919,7 @@ TEST_F(Rename, ok) uint64_t dst_ino = 2; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1, geteuid()); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1, geteuid()); expect_lookup(RELSRC, ino, S_IFREG | 0644, UINT64_MAX); expect_lookup(RELDST, dst_ino, S_IFREG | 0644, UINT64_MAX); expect_rename(0); @@ -932,9 +935,10 @@ TEST_F(Rename, ok_to_remove_src_because_of_stickiness) const char RELSRC[] = "src"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 01777, UINT64_MAX, 1, 0); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 01777, UINT64_MAX, 1, 0); expect_lookup(RELSRC, ino, S_IFREG | 0644, UINT64_MAX, geteuid()); - EXPECT_LOOKUP(1, RELDST).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_rename(0); ASSERT_EQ(0, rename(FULLSRC, FULLDST)) << strerror(errno); @@ -948,7 +952,7 @@ TEST_F(Setattr, ok) const mode_t oldmode = 0755; const mode_t newmode = 0644; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -973,7 +977,7 @@ TEST_F(Setattr, eacces) const mode_t oldmode = 0755; const mode_t newmode = 0644; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, 0); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -999,8 +1003,9 @@ TEST_F(Setattr, ftruncate_of_newly_created_file) const mode_t mode = 0000; int fd; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1); - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_create(RELPATH, ino); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -1036,7 +1041,7 @@ TEST_F(Setattr, sgid_by_non_group_member) uid_t uid = geteuid(); gid_t gid = excluded_group(); - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, uid, gid); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -1058,7 +1063,7 @@ TEST_F(Setattr, sticky_regular_file) const mode_t oldmode = 0644; const mode_t newmode = 01644; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX, geteuid()); EXPECT_CALL(*m_mock, process( ResultOf([](auto in) { @@ -1081,7 +1086,7 @@ TEST_F(Setextattr, ok) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, geteuid()); expect_setxattr(0); @@ -1098,7 +1103,7 @@ TEST_F(Setextattr, eacces) ssize_t value_len = strlen(value) + 1; int ns = EXTATTR_NAMESPACE_USER; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, 0); ASSERT_EQ(-1, @@ -1116,7 +1121,7 @@ TEST_F(Setextattr, system) ssize_t value_len = strlen(value) + 1; int ns = EXTATTR_NAMESPACE_SYSTEM; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0666, UINT64_MAX, geteuid()); ASSERT_EQ(-1, @@ -1135,7 +1140,7 @@ TEST_F(Setextattr, user) int ns = EXTATTR_NAMESPACE_USER; ssize_t r; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0666, UINT64_MAX, 0); expect_setxattr(0); @@ -1149,9 +1154,9 @@ TEST_F(Unlink, ok) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0777, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0777, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, geteuid()); - expect_unlink(1, RELPATH, 0); + expect_unlink(FUSE_ROOT_ID, RELPATH, 0); ASSERT_EQ(0, unlink(FULLPATH)) << strerror(errno); } @@ -1169,8 +1174,8 @@ TEST_F(Unlink, cached_unwritable_directory) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); - EXPECT_LOOKUP(1, RELPATH) + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .Times(AnyNumber()) .WillRepeatedly(Invoke( ReturnImmediate([=](auto i __unused, auto& out) { @@ -1194,7 +1199,7 @@ TEST_F(Unlink, unwritable_directory) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, geteuid()); ASSERT_EQ(-1, unlink(FULLPATH)); @@ -1207,7 +1212,7 @@ TEST_F(Unlink, sticky_directory) const char RELPATH[] = "some_file.txt"; uint64_t ino = 42; - expect_getattr(1, S_IFDIR | 01777, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 01777, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | 0644, UINT64_MAX, 0); ASSERT_EQ(-1, unlink(FULLPATH)); @@ -1226,7 +1231,7 @@ TEST_F(Write, clear_suid) char wbuf[1] = {'x'}; int fd; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX); expect_open(ino, 0, 1); expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf); @@ -1252,7 +1257,7 @@ TEST_F(Write, clear_sgid) char wbuf[1] = {'x'}; int fd; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX); expect_open(ino, 0, 1); expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf); @@ -1282,7 +1287,7 @@ TEST_F(Write, recursion_panic_while_clearing_suid) char wbuf[1] = {'x'}; int fd; - expect_getattr(1, S_IFDIR | 0755, UINT64_MAX, 1); + expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755, UINT64_MAX, 1); expect_lookup(RELPATH, ino, S_IFREG | oldmode, UINT64_MAX); expect_open(ino, 0, 1); expect_write(ino, 0, sizeof(wbuf), sizeof(wbuf), 0, 0, wbuf); Modified: projects/fuse2/tests/sys/fs/fusefs/destroy.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/destroy.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/destroy.cc Fri May 31 17:02:37 2019 (r348469) @@ -48,7 +48,7 @@ TEST_F(Destroy, ok) uint64_t ino = 42; expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 2); - expect_forget(1, 1); + expect_forget(FUSE_ROOT_ID, 1); expect_forget(ino, 2); expect_destroy(0); Modified: projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/dev_fuse_poll.cc Fri May 31 17:02:37 2019 (r348469) @@ -81,7 +81,7 @@ class Kqueue: public FuseTest { TEST_P(DevFusePoll, access) { - expect_access(1, X_OK, 0); + expect_access(FUSE_ROOT_ID, X_OK, 0); expect_lookup(RELPATH, ino, S_IFREG | 0644, 0, 1); expect_access(ino, access_mode, 0); @@ -91,7 +91,7 @@ TEST_P(DevFusePoll, access) /* Ensure that we wake up pollers during unmount */ TEST_P(DevFusePoll, destroy) { - expect_forget(1, 1); + expect_forget(FUSE_ROOT_ID, 1); expect_destroy(0); m_mock->unmount(); @@ -126,21 +126,21 @@ TEST_F(Kqueue, data) ASSERT_EQ(0, sem_init(&sem0, 0, 0)) << strerror(errno); ASSERT_EQ(0, sem_init(&sem1, 0, 0)) << strerror(errno); - EXPECT_LOOKUP(1, "foo") + EXPECT_LOOKUP(FUSE_ROOT_ID, "foo") .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.entry_valid = UINT64_MAX; out.body.entry.attr.mode = S_IFREG | 0644; out.body.entry.nodeid = foo_ino; }))); - EXPECT_LOOKUP(1, "bar") + EXPECT_LOOKUP(FUSE_ROOT_ID, "bar") .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.entry_valid = UINT64_MAX; out.body.entry.attr.mode = S_IFREG | 0644; out.body.entry.nodeid = bar_ino; }))); - EXPECT_LOOKUP(1, "baz") + EXPECT_LOOKUP(FUSE_ROOT_ID, "baz") .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.entry_valid = UINT64_MAX; Modified: projects/fuse2/tests/sys/fs/fusefs/fifo.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/fifo.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/fifo.cc Fri May 31 17:02:37 2019 (r348469) @@ -156,7 +156,8 @@ TEST_F(Socket, read_write) int fd, connected; Sequence seq; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in.header.opcode == FUSE_MKNOD); @@ -171,7 +172,7 @@ TEST_F(Socket, read_write) out.body.entry.attr_valid = UINT64_MAX; }))); - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .InSequence(seq) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); Modified: projects/fuse2/tests/sys/fs/fusefs/getattr.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/getattr.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/getattr.cc Fri May 31 17:02:37 2019 (r348469) @@ -42,7 +42,7 @@ class Getattr : public FuseTest { (public) void expect_lookup(const char *relpath, uint64_t ino, mode_t mode, uint64_t size, int times, uint64_t attr_valid, uint32_t attr_valid_nsec) { - EXPECT_LOOKUP(1, relpath) + EXPECT_LOOKUP(FUSE_ROOT_ID, relpath) .Times(times) .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); @@ -76,7 +76,7 @@ TEST_F(Getattr, attr_cache) const uint64_t ino = 42; struct stat sb; - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.attr.mode = S_IFREG | 0644; @@ -247,7 +247,7 @@ TEST_F(Getattr_7_8, ok) const uint64_t ino = 42; struct stat sb; - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry_7_8); out.body.entry.attr.mode = S_IFREG | 0644; Modified: projects/fuse2/tests/sys/fs/fusefs/interrupt.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/interrupt.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/interrupt.cc Fri May 31 17:02:37 2019 (r348469) @@ -222,7 +222,7 @@ TEST_F(Interrupt, already_complete) self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) .InSequence(seq) .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_mkdir(&mkdir_unique); @@ -248,7 +248,7 @@ TEST_F(Interrupt, already_complete) out1->header.len = sizeof(out1->header); out.push_back(std::move(out1)); })); - EXPECT_LOOKUP(1, RELDIRPATH0) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) .InSequence(seq) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); @@ -284,8 +284,10 @@ TEST_F(Interrupt, enosys) ASSERT_EQ(0, sem_init(&sem0, 0, 0)) << strerror(errno); ASSERT_EQ(0, sem_init(&sem1, 0, 0)) << strerror(errno); - EXPECT_LOOKUP(1, RELDIRPATH1).WillOnce(Invoke(ReturnErrno(ENOENT))); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH1) + .WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_mkdir(&mkdir_unique); EXPECT_CALL(*m_mock, process( ResultOf([&](auto in) { @@ -363,7 +365,8 @@ TEST_F(Interrupt, fatal_signal) ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno); self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_mkdir(&mkdir_unique); EXPECT_CALL(*m_mock, process( ResultOf([&](auto in) { @@ -420,7 +423,8 @@ TEST_F(Interrupt, ignore) self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_mkdir(&mkdir_unique); EXPECT_CALL(*m_mock, process( ResultOf([&](auto in) { @@ -461,7 +465,8 @@ TEST_F(Interrupt, in_kernel_restartable) ASSERT_EQ(0, sem_init(&sem1, 0, 0)) << strerror(errno); self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_lookup(RELPATH1, ino1); expect_open(ino1, 0, 1); EXPECT_CALL(*m_mock, process( @@ -534,7 +539,8 @@ TEST_F(Interrupt, in_kernel_nonrestartable) ASSERT_EQ(0, sem_init(&sem1, 0, 0)) << strerror(errno); self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_lookup(RELPATH1, ino1); expect_open(ino1, 0, 1); EXPECT_CALL(*m_mock, process( @@ -593,7 +599,8 @@ TEST_F(Interrupt, in_progress) self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_mkdir(&mkdir_unique); EXPECT_CALL(*m_mock, process( ResultOf([&](auto in) { @@ -666,8 +673,10 @@ TEST_F(Interrupt, priority) ASSERT_EQ(0, sem_init(&sem1, 0, 0)) << strerror(errno); self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); - EXPECT_LOOKUP(1, RELDIRPATH1).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH1) + .WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in.header.opcode == FUSE_MKDIR); @@ -746,7 +755,8 @@ TEST_F(Interrupt, too_soon) self = pthread_self(); - EXPECT_LOOKUP(1, RELDIRPATH0).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH0) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_mkdir(&mkdir_unique); EXPECT_CALL(*m_mock, process( Modified: projects/fuse2/tests/sys/fs/fusefs/link.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/link.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/link.cc Fri May 31 17:02:37 2019 (r348469) @@ -114,22 +114,24 @@ TEST_F(Link, clear_attr_cache) mode_t mode = S_IFREG | 0644; struct stat sb; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_CALL(*m_mock, process( ResultOf([=](auto in) { return (in.header.opcode == FUSE_GETATTR && - in.header.nodeid == 1); + in.header.nodeid == FUSE_ROOT_ID); }, Eq(true)), _) ).Times(2) .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { SET_OUT_HEADER_LEN(out, attr); - out.body.attr.attr.ino = 1; + out.body.attr.attr.ino = FUSE_ROOT_ID; out.body.attr.attr.mode = S_IFDIR | 0755; out.body.attr.attr_valid = UINT64_MAX; }))); - EXPECT_LOOKUP(1, RELDST) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST) + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.attr.mode = mode; @@ -153,7 +155,8 @@ TEST_F(Link, emlink) const char RELDST[] = "dst"; uint64_t dst_ino = 42; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); expect_lookup(RELDST, dst_ino); EXPECT_CALL(*m_mock, process( @@ -181,8 +184,9 @@ TEST_F(Link, ok) mode_t mode = S_IFREG | 0644; struct stat sb; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); - EXPECT_LOOKUP(1, RELDST) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.attr.mode = mode; @@ -209,8 +213,9 @@ TEST_F(Link_7_8, ok) mode_t mode = S_IFREG | 0644; struct stat sb; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); - EXPECT_LOOKUP(1, RELDST) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDST) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry_7_8); out.body.entry.attr.mode = mode; Modified: projects/fuse2/tests/sys/fs/fusefs/lookup.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/lookup.cc Fri May 31 16:25:16 2019 (r348468) +++ projects/fuse2/tests/sys/fs/fusefs/lookup.cc Fri May 31 17:02:37 2019 (r348469) @@ -58,7 +58,7 @@ TEST_F(Lookup, attr_cache) const uint64_t generation = 13; struct stat sb; - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.nodeid = ino; @@ -118,7 +118,7 @@ TEST_F(Lookup, attr_cache_timeout) const uint64_t ino = 42; struct stat sb; - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .Times(2) .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); @@ -142,7 +142,7 @@ TEST_F(Lookup, dot) const char RELDIRPATH[] = "some_dir"; uint64_t ino = 42; - EXPECT_LOOKUP(1, RELDIRPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.attr.mode = S_IFDIR | 0755; @@ -163,7 +163,7 @@ TEST_F(Lookup, dotdot) const char FULLPATH[] = "mountpoint/some_dir/.."; const char RELDIRPATH[] = "some_dir"; - EXPECT_LOOKUP(1, RELDIRPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.attr.mode = S_IFDIR | 0755; @@ -184,7 +184,8 @@ TEST_F(Lookup, enoent) const char FULLPATH[] = "mountpoint/does_not_exist"; const char RELPATH[] = "does_not_exist"; - EXPECT_LOOKUP(1, RELPATH).WillOnce(Invoke(ReturnErrno(ENOENT))); + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) + .WillOnce(Invoke(ReturnErrno(ENOENT))); EXPECT_NE(0, access(FULLPATH, F_OK)); EXPECT_EQ(ENOENT, errno); } @@ -194,7 +195,7 @@ TEST_F(Lookup, enotdir) const char FULLPATH[] = "mountpoint/not_a_dir/some_file.txt"; const char RELPATH[] = "not_a_dir"; - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); out.body.entry.entry_valid = UINT64_MAX; @@ -215,7 +216,7 @@ TEST_F(Lookup, entry_cache) const char FULLPATH[] = "mountpoint/some_file.txt"; const char RELPATH[] = "some_file.txt"; - EXPECT_LOOKUP(1, RELPATH) + EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-projects@freebsd.org Fri May 31 21:23:01 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 104EB15C614F for ; Fri, 31 May 2019 21:23:01 +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 A8D2285153; Fri, 31 May 2019 21:23:00 +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 84E7F61A4; Fri, 31 May 2019 21:23:00 +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 x4VLN0Ie082250; Fri, 31 May 2019 21:23:00 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4VLMxWl082240; Fri, 31 May 2019 21:22:59 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201905312122.x4VLMxWl082240@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Fri, 31 May 2019 21:22:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348485 - 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: 348485 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: A8D2285153 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_SHORT(-0.97)[-0.968,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; 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, 31 May 2019 21:23:01 -0000 Author: asomers Date: Fri May 31 21:22:58 2019 New Revision: 348485 URL: https://svnweb.freebsd.org/changeset/base/348485 Log: fusefs: check the vnode cache when looking up files for the NFS server FUSE allows entries to be cached for a limited amount of time. fusefs's vnop_lookup method already implements that using the timeout functionality of cache_lookup/cache_enter_time. However, lookups for the NFS server go through a separate path: vfs_vget. That path can't use the same timeout functionality because cache_lookup/cache_enter_time only work on pathnames, whereas vfs_vget works by inode number. This commit adds entry timeout information to the fuse vnode structure, and checks it during vfs_vget. This allows the NFS server to take advantage of cached entries. It's also the same path that FUSE's asynchronous cache invalidation operations will use. Sponsored by: The FreeBSD Foundation Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c projects/fuse2/sys/fs/fuse/fuse_internal.h projects/fuse2/sys/fs/fuse/fuse_node.h projects/fuse2/sys/fs/fuse/fuse_vfsops.c projects/fuse2/sys/fs/fuse/fuse_vnops.c projects/fuse2/tests/sys/fs/fusefs/nfs.cc Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.c Fri May 31 21:02:42 2019 (r348484) +++ projects/fuse2/sys/fs/fuse/fuse_internal.c Fri May 31 21:22:58 2019 (r348485) @@ -750,6 +750,7 @@ fuse_internal_vnode_disappear(struct vnode *vp) ASSERT_VOP_ELOCKED(vp, "fuse_internal_vnode_disappear"); fvdat->flag |= FN_REVOKED; bintime_clear(&fvdat->attr_cache_timeout); + bintime_clear(&fvdat->entry_cache_timeout); cache_purge(vp); } Modified: projects/fuse2/sys/fs/fuse/fuse_internal.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.h Fri May 31 21:02:42 2019 (r348484) +++ projects/fuse2/sys/fs/fuse/fuse_internal.h Fri May 31 21:22:58 2019 (r348485) @@ -68,6 +68,9 @@ #include "fuse_ipc.h" #include "fuse_node.h" +extern u_long fuse_lookup_cache_hits; +extern u_long fuse_lookup_cache_misses; + static inline bool vfs_isrdonly(struct mount *mp) { Modified: projects/fuse2/sys/fs/fuse/fuse_node.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_node.h Fri May 31 21:02:42 2019 (r348484) +++ projects/fuse2/sys/fs/fuse/fuse_node.h Fri May 31 21:22:58 2019 (r348485) @@ -97,6 +97,11 @@ struct fuse_vnode_data { /** meta **/ /* The monotonic time after which the attr cache is invalid */ struct bintime attr_cache_timeout; + /* + * Monotonic time after which the entry is invalid. Used for lookups + * by nodeid instead of pathname. + */ + struct bintime entry_cache_timeout; struct vattr cached_attrs; uint64_t nlookup; enum vtype vtype; Modified: projects/fuse2/sys/fs/fuse/fuse_vfsops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vfsops.c Fri May 31 21:02:42 2019 (r348484) +++ projects/fuse2/sys/fs/fuse/fuse_vfsops.c Fri May 31 21:22:58 2019 (r348485) @@ -527,19 +527,34 @@ fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags struct fuse_dispatcher fdi; struct fuse_entry_out *feo; struct fuse_vnode_data *fvdat; + struct bintime now; const char dot[] = "."; off_t filesize; enum vtype vtyp; int error; + error = vfs_hash_get(mp, fuse_vnode_hash(nodeid), flags, td, vpp, + fuse_vnode_cmp, &nodeid); + if (error) + return error; /* - * TODO Check the vnode cache, verifying entry cache timeout. Normally - * done during VOP_LOOKUP + * Check the entry cache timeout. We have to do this within fusefs + * instead of by using cache_enter_time/cache_lookup because those + * routines are only intended to work with pathnames, not inodes */ - /*error = vfs_hash_get(mp, fuse_vnode_hash(nodeid), LK_EXCLUSIVE, td, vpp,*/ - /*fuse_vnode_cmp, &nodeid);*/ - /*if (error || *vpp != NULL)*/ - /*return error;*/ + if (*vpp != NULL) { + getbinuptime(&now); + if (bintime_cmp(&(VTOFUD(*vpp)->entry_cache_timeout), &now, >)){ + atomic_add_acq_long(&fuse_lookup_cache_hits, 1); + return 0; + } else { + /* Entry cache timeout */ + atomic_add_acq_long(&fuse_lookup_cache_misses, 1); + cache_purge(*vpp); + vput(*vpp); + *vpp = NULL; + } + } /* Do a LOOKUP, using nodeid as the parent and "." as filename */ fdisp_init(&fdi, sizeof(dot)); @@ -585,6 +600,8 @@ fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags fuse_internal_cache_attrs(*vpp, td->td_ucred, &feo->attr, feo->attr_valid, feo->attr_valid_nsec, NULL); + fuse_validity_2_bintime(feo->entry_valid, feo->entry_valid_nsec, + &fvdat->entry_cache_timeout); out: fdisp_destroy(&fdi); return error; Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_vnops.c Fri May 31 21:02:42 2019 (r348484) +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c Fri May 31 21:22:58 2019 (r348485) @@ -218,12 +218,12 @@ struct vop_vector fuse_vnops = { .vop_vptofh = fuse_vnop_vptofh, }; -static u_long fuse_lookup_cache_hits = 0; +u_long fuse_lookup_cache_hits = 0; SYSCTL_ULONG(_vfs_fusefs, OID_AUTO, lookup_cache_hits, CTLFLAG_RD, &fuse_lookup_cache_hits, 0, "number of positive cache hits in lookup"); -static u_long fuse_lookup_cache_misses = 0; +u_long fuse_lookup_cache_misses = 0; SYSCTL_ULONG(_vfs_fusefs, OID_AUTO, lookup_cache_misses, CTLFLAG_RD, &fuse_lookup_cache_misses, 0, "number of cache misses in lookup"); @@ -965,6 +965,8 @@ fuse_vnop_lookup(struct vop_lookup_args *ap) /* Cache timeout */ atomic_add_acq_long(&fuse_lookup_cache_misses, 1); + bintime_clear( + &VTOFUD(*vpp)->entry_cache_timeout); cache_purge(*vpp); if (dvp != *vpp) vput(*vpp); @@ -1103,6 +1105,9 @@ fuse_vnop_lookup(struct vop_lookup_args *ap) MPASS(feo != NULL); fuse_internal_cache_attrs(*vpp, cred, &feo->attr, feo->attr_valid, feo->attr_valid_nsec, NULL); + fuse_validity_2_bintime(feo->entry_valid, + feo->entry_valid_nsec, + &fvdat->entry_cache_timeout); if ((nameiop == DELETE || nameiop == RENAME) && islastcn) @@ -2536,7 +2541,7 @@ fuse_vnop_print(struct vop_print_args *ap) * Get an NFS filehandle for a FUSE file. * * This will only work for FUSE file systems that guarantee the uniqueness of - * nodeid:generation, which most don't + * nodeid:generation, which most don't. */ /* vop_vptofh { Modified: projects/fuse2/tests/sys/fs/fusefs/nfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/nfs.cc Fri May 31 21:02:42 2019 (r348484) +++ projects/fuse2/tests/sys/fs/fusefs/nfs.cc Fri May 31 21:22:58 2019 (r348485) @@ -145,11 +145,7 @@ TEST_F(Fhstat, lookup_dot) } /* Use a file handle whose entry is still cached */ -/* - * Disabled because fuse_vfsop_vget doesn't yet check the entry cache. No PR - * because that's a feature request, not a bug - */ -TEST_F(Fhstat, DISABLED_cached) +TEST_F(Fhstat, cached) { const char FULLPATH[] = "mountpoint/some_dir/."; const char RELDIRPATH[] = "some_dir"; @@ -157,7 +153,6 @@ TEST_F(Fhstat, DISABLED_cached) struct stat sb; const uint64_t ino = 42; const mode_t mode = S_IFDIR | 0755; - const uid_t uid = 12345; EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH) .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { @@ -165,15 +160,57 @@ TEST_F(Fhstat, DISABLED_cached) out.body.entry.attr.mode = mode; out.body.entry.nodeid = ino; out.body.entry.generation = 1; - out.body.entry.attr.uid = uid; + out.body.entry.attr.ino = ino; out.body.entry.attr_valid = UINT64_MAX; out.body.entry.entry_valid = UINT64_MAX; }))); ASSERT_EQ(0, getfh(FULLPATH, &fhp)) << strerror(errno); ASSERT_EQ(0, fhstat(&fhp, &sb)) << strerror(errno); - EXPECT_EQ(uid, sb.st_uid); - EXPECT_EQ(mode, sb.st_mode); + EXPECT_EQ(ino, sb.st_ino); +} + +/* File handle entries should expire from the cache, too */ +TEST_F(Fhstat, cache_expired) +{ + const char FULLPATH[] = "mountpoint/some_dir/."; + const char RELDIRPATH[] = "some_dir"; + fhandle_t fhp; + struct stat sb; + const uint64_t ino = 42; + const mode_t mode = S_IFDIR | 0755; + + EXPECT_LOOKUP(FUSE_ROOT_ID, RELDIRPATH) + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, entry); + out.body.entry.attr.mode = mode; + out.body.entry.nodeid = ino; + out.body.entry.generation = 1; + out.body.entry.attr.ino = ino; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid_nsec = NAP_NS / 2; + }))); + + EXPECT_LOOKUP(ino, ".") + .WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, entry); + out.body.entry.attr.mode = mode; + out.body.entry.nodeid = ino; + out.body.entry.generation = 1; + out.body.entry.attr.ino = ino; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = 0; + }))); + + ASSERT_EQ(0, getfh(FULLPATH, &fhp)) << strerror(errno); + ASSERT_EQ(0, fhstat(&fhp, &sb)) << strerror(errno); + EXPECT_EQ(ino, sb.st_ino); + + nap(); + + /* Cache should be expired; fuse should issue a FUSE_LOOKUP */ + ASSERT_EQ(0, fhstat(&fhp, &sb)) << strerror(errno); + EXPECT_EQ(ino, sb.st_ino); } /* From owner-svn-src-projects@freebsd.org Sat Jun 1 00:11:21 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 3306F15A51F8 for ; Sat, 1 Jun 2019 00:11:21 +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 D94AB89E6D; Sat, 1 Jun 2019 00:11:20 +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 B0FCB7CFD; Sat, 1 Jun 2019 00:11:20 +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 x510BKLQ069735; Sat, 1 Jun 2019 00:11:20 GMT (envelope-from asomers@FreeBSD.org) Received: (from asomers@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x510BJeA068941; Sat, 1 Jun 2019 00:11:19 GMT (envelope-from asomers@FreeBSD.org) Message-Id: <201906010011.x510BJeA068941@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: asomers set sender to asomers@FreeBSD.org using -f From: Alan Somers Date: Sat, 1 Jun 2019 00:11:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r348487 - 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: 348487 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: D94AB89E6D 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)[-1.000,0]; NEURAL_HAM_SHORT(-0.98)[-0.977,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: Sat, 01 Jun 2019 00:11:21 -0000 Author: asomers Date: Sat Jun 1 00:11:19 2019 New Revision: 348487 URL: https://svnweb.freebsd.org/changeset/base/348487 Log: fusefs: support name cache invalidation Protocol 7.12 adds a way for the server to notify the client that it should invalidate an entry from its name cache. This commit implements that mechanism. Sponsored by: The FreeBSD Foundation Added: projects/fuse2/tests/sys/fs/fusefs/notify.cc (contents, props changed) Modified: projects/fuse2/sys/fs/fuse/fuse_device.c projects/fuse2/sys/fs/fuse/fuse_internal.c projects/fuse2/sys/fs/fuse/fuse_internal.h projects/fuse2/tests/sys/fs/fusefs/Makefile projects/fuse2/tests/sys/fs/fusefs/mockfs.cc projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Modified: projects/fuse2/sys/fs/fuse/fuse_device.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_device.c Fri May 31 22:57:20 2019 (r348486) +++ projects/fuse2/sys/fs/fuse/fuse_device.c Sat Jun 1 00:11:19 2019 (r348487) @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include #include "fuse.h" +#include "fuse_internal.h" #include "fuse_ipc.h" SDT_PROVIDER_DECLARE(fusefs); @@ -393,17 +394,17 @@ fuse_ohead_audit(struct fuse_out_header *ohead, struct "differs from size claimed by header"); return (EINVAL); } - if (uio->uio_resid && ohead->error) { + if (uio->uio_resid && ohead->unique != 0 && ohead->error) { SDT_PROBE2(fusefs, , device, trace, 1, "Format error: non zero error but message had a body"); return (EINVAL); } - /* Sanitize the linuxism of negative errnos */ - ohead->error = -(ohead->error); return (0); } +SDT_PROBE_DEFINE1(fusefs, , device, fuse_device_write_notify, + "struct fuse_out_header*"); SDT_PROBE_DEFINE1(fusefs, , device, fuse_device_write_missing_ticket, "uint64_t"); SDT_PROBE_DEFINE1(fusefs, , device, fuse_device_write_found, @@ -420,12 +421,14 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i struct fuse_out_header ohead; int err = 0; struct fuse_data *data; + struct mount *mp; struct fuse_ticket *tick, *itick, *x_tick; int found = 0; 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, @@ -489,6 +492,8 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i */ SDT_PROBE2(fusefs, , device, trace, 1, "pass ticket to a callback"); + /* Sanitize the linuxism of negative errnos */ + ohead.error *= -1; memcpy(&tick->tk_aw_ohead, &ohead, sizeof(ohead)); err = tick->tk_aw_handler(tick, uio); } else { @@ -503,11 +508,24 @@ fuse_device_write(struct cdev *dev, struct uio *uio, i * because fuse_ticket_drop() will deal with refcount anyway. */ fuse_ticket_drop(tick); + } else if (ohead.unique == 0){ + /* unique == 0 means asynchronous notification */ + SDT_PROBE1(fusefs, , device, fuse_device_write_notify, &ohead); + switch (ohead.error) { + case FUSE_NOTIFY_INVAL_ENTRY: + err = fuse_internal_invalidate_entry(mp, uio); + break; + case FUSE_NOTIFY_POLL: + case FUSE_NOTIFY_INVAL_INODE: + default: + /* Not implemented */ + err = ENOSYS; + } } else { /* no callback at all! */ SDT_PROBE1(fusefs, , device, fuse_device_write_missing_ticket, ohead.unique); - if (ohead.error == EAGAIN) { + if (ohead.error == -EAGAIN) { /* * This was probably a response to a FUSE_INTERRUPT * operation whose original operation is already Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.c Fri May 31 22:57:20 2019 (r348486) +++ projects/fuse2/sys/fs/fuse/fuse_internal.c Sat Jun 1 00:11:19 2019 (r348487) @@ -326,6 +326,71 @@ fuse_internal_fsync(struct vnode *vp, return err; } +/* Asynchronous invalidation */ +SDT_PROBE_DEFINE1(fusefs, , internal, invalidate_without_export, + "struct mount*"); +SDT_PROBE_DEFINE2(fusefs, , internal, invalidate_cache_hit, + "struct vnode*", "struct vnode*"); +int +fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio) +{ + struct fuse_notify_inval_entry_out fnieo; + struct fuse_data *data = fuse_get_mpdata(mp); + struct componentname cn; + /*struct vnode *dvp;*/ + struct vnode *dvp, *vp; + char name[PATH_MAX]; + int err; + + if (!(data->dataflags & FSESS_EXPORT_SUPPORT)) { + /* + * Linux allows file systems without export support to use + * asynchronous notification because its inode cache is indexed + * purely by the inode number. But FreeBSD's vnode is cache + * requires access to the entire vnode structure. + */ + SDT_PROBE1(fusefs, , internal, invalidate_without_export, mp); + return (EINVAL); + } + + if ((err = uiomove(&fnieo, sizeof(fnieo), uio)) != 0) + return (err); + + if ((err = uiomove(name, fnieo.namelen, uio)) != 0) + return (err); + name[fnieo.namelen] = '\0'; + /* fusefs does not cache "." or ".." entries */ + if (strncmp(name, ".", sizeof(".")) == 0 || + strncmp(name, "..", sizeof("..")) == 0) + return (0); + + if (fnieo.parent == FUSE_ROOT_ID) + err = VFS_ROOT(mp, LK_SHARED, &dvp); + else + err = VFS_VGET(mp, fnieo.parent, LK_SHARED, &dvp); + if (err != 0) + return (err); + /* + * XXX we can't check dvp's generation because the FUSE invalidate + * entry message doesn't include it. Worse case is that we invalidate + * an entry that didn't need to be invalidated. + */ + + cn.cn_nameiop = LOOKUP; + cn.cn_flags = 0; /* !MAKEENTRY means free cached entry */ + cn.cn_thread = curthread; + cn.cn_cred = curthread->td_ucred; + cn.cn_lkflags = LK_SHARED; + cn.cn_pnbuf = NULL; + cn.cn_nameptr = name; + cn.cn_namelen = fnieo.namelen; + err = cache_lookup(dvp, &vp, &cn, NULL, NULL); + MPASS(err == 0); + fuse_vnode_clear_attr_cache(dvp); + vput(dvp); + return (0); +} + /* mknod */ int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp, Modified: projects/fuse2/sys/fs/fuse/fuse_internal.h ============================================================================== --- projects/fuse2/sys/fs/fuse/fuse_internal.h Fri May 31 22:57:20 2019 (r348486) +++ projects/fuse2/sys/fs/fuse/fuse_internal.h Sat Jun 1 00:11:19 2019 (r348487) @@ -228,17 +228,17 @@ int fuse_internal_do_getattr(struct vnode *vp, struct int fuse_internal_getattr(struct vnode *vp, struct vattr *vap, struct ucred *cred, struct thread *td); -/* readdir */ +/* asynchronous invalidation */ +int fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio); -struct pseudo_dirent { - uint32_t d_namlen; -}; - /* mknod */ int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct vattr *vap); /* readdir */ +struct pseudo_dirent { + uint32_t d_namlen; +}; int fuse_internal_readdir(struct vnode *vp, struct uio *uio, off_t startoff, struct fuse_filehandle *fufh, struct fuse_iov *cookediov, int *ncookies, u_long *cookies); Modified: projects/fuse2/tests/sys/fs/fusefs/Makefile ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/Makefile Fri May 31 22:57:20 2019 (r348486) +++ projects/fuse2/tests/sys/fs/fusefs/Makefile Sat Jun 1 00:11:19 2019 (r348487) @@ -27,6 +27,7 @@ GTESTS+= mkdir GTESTS+= mknod GTESTS+= mount GTESTS+= nfs +GTESTS+= notify GTESTS+= open GTESTS+= opendir GTESTS+= read Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Fri May 31 22:57:20 2019 (r348486) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc Sat Jun 1 00:11:19 2019 (r348487) @@ -153,7 +153,7 @@ void sigint_handler(int __unused sig) { // Don't do anything except interrupt the daemon's read(2) call } -void MockFS::debug_fuseop(const mockfs_buf_in &in) +void MockFS::debug_request(const mockfs_buf_in &in) { printf("%-11s ino=%2" PRIu64, opcode2opname(in.header.opcode), in.header.nodeid); @@ -303,6 +303,30 @@ void MockFS::debug_fuseop(const mockfs_buf_in &in) printf("\n"); } +/* + * Debug a FUSE response. + * + * This is mostly useful for asynchronous notifications, which don't correspond + * to any request + */ +void MockFS::debug_response(const mockfs_buf_out &out) { + const char *name; + + if (verbosity == 0) + return; + + switch (out.header.error) { + case FUSE_NOTIFY_INVAL_ENTRY: + name = (const char*)out.body.bytes + + sizeof(fuse_notify_inval_entry_out); + printf("<- INVAL_ENTRY parent=%" PRIu64 " %s\n", + out.body.inval_entry.parent, name); + break; + default: + break; + } +} + MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions, bool push_symlinks_in, bool ro, enum poll_method pm, uint32_t flags, uint32_t kernel_minor_version) @@ -455,7 +479,7 @@ void MockFS::loop() { if (m_quit) break; if (verbosity > 0) - debug_fuseop(*in); + debug_request(*in); if (pid_ok((pid_t)in->header.pid)) { process(*in, out); } else { @@ -473,6 +497,23 @@ void MockFS::loop() { write_response(*it); out.clear(); } +} + +int MockFS::notify_inval_entry(ino_t parent, const char *name, size_t namelen) +{ + std::unique_ptr out(new mockfs_buf_out); + + out->header.unique = 0; /* 0 means asynchronous notification */ + out->header.error = FUSE_NOTIFY_INVAL_ENTRY; + out->body.inval_entry.parent = parent; + out->body.inval_entry.namelen = namelen; + strlcpy((char*)&out->body.bytes + sizeof(out->body.inval_entry), + name, sizeof(out->body.bytes) - sizeof(out->body.inval_entry)); + out->header.len = sizeof(out->header) + sizeof(out->body.inval_entry) + + namelen; + debug_response(*out); + write_response(*out); + return 0; } bool MockFS::pid_ok(pid_t pid) { Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh ============================================================================== --- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Fri May 31 22:57:20 2019 (r348486) +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh Sat Jun 1 00:11:19 2019 (r348487) @@ -176,6 +176,8 @@ union fuse_payloads_out { fuse_lk_out getlk; fuse_getxattr_out getxattr; fuse_init_out init; + /* The inval_entry structure should be followed by the entry's name */ + fuse_notify_inval_entry_out inval_entry; fuse_listxattr_out listxattr; fuse_open_out open; fuse_statfs_out statfs; @@ -258,7 +260,8 @@ class MockFS { /* Method the daemon should use for I/O to and from /dev/fuse */ enum poll_method m_pm; - void debug_fuseop(const mockfs_buf_in&); + void debug_request(const mockfs_buf_in&); + void debug_response(const mockfs_buf_out&); /* Initialize a session after mounting */ void init(uint32_t flags); @@ -308,6 +311,19 @@ class MockFS { /* Process FUSE requests endlessly */ void loop(); + + /* + * Send an asynchronous notification to invalidate a directory entry. + * Similar to libfuse's fuse_lowlevel_notify_inval_entry + * + * This method will block until the client has responded, so it should + * generally be run in a separate thread from request processing. + * + * @param parent Parent directory's inode number + * @param name name of dirent to invalidate + * @param namelen size of name, including the NUL + */ + int notify_inval_entry(ino_t parent, const char *name, size_t namelen); /* * Request handler Added: projects/fuse2/tests/sys/fs/fusefs/notify.cc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/fuse2/tests/sys/fs/fusefs/notify.cc Sat Jun 1 00:11:19 2019 (r348487) @@ -0,0 +1,240 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 The FreeBSD Foundation + * + * This software was developed by BFF Storage Systems, LLC under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern "C" { +#include +} + +#include "mockfs.hh" +#include "utils.hh" + +using namespace testing; + +/* + * FUSE asynchonous notification + * + * FUSE servers can send unprompted notification messages for things like cache + * invalidation. This file tests our client's handling of those messages. + */ + +class Notify: public FuseTest { +public: +public: +virtual void SetUp() { + m_init_flags = FUSE_EXPORT_SUPPORT; + FuseTest::SetUp(); +} + +void expect_lookup(uint64_t parent, const char *relpath, uint64_t ino, + Sequence &seq) +{ + EXPECT_LOOKUP(parent, relpath) + .InSequence(seq) + .WillOnce(Invoke( + ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, entry); + out.body.entry.attr.mode = S_IFREG | 0644; + out.body.entry.nodeid = ino; + out.body.entry.attr.ino = ino; + out.body.entry.attr.nlink = 1; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = UINT64_MAX; + }))); +} +}; + +struct inval_entry_args { + MockFS *mock; + ino_t parent; + const char *name; + size_t namelen; +}; + +static void* inval_entry(void* arg) { + const struct inval_entry_args *iea = (struct inval_entry_args*)arg; + ssize_t r; + + r = iea->mock->notify_inval_entry(iea->parent, iea->name, iea->namelen); + if (r >= 0) + return 0; + else + return (void*)(intptr_t)errno; +} + +/* Invalidate a nonexistent entry */ +TEST_F(Notify, inval_entry_nonexistent) +{ + const static char *name = "foo"; + struct inval_entry_args iea; + void *thr0_value; + pthread_t th0; + + iea.mock = m_mock; + iea.parent = FUSE_ROOT_ID; + iea.name = name; + iea.namelen = strlen(name); + ASSERT_EQ(0, pthread_create(&th0, NULL, inval_entry, &iea)) + << strerror(errno); + pthread_join(th0, &thr0_value); + /* It's not an error for an entry to not be cached */ + EXPECT_EQ(0, (intptr_t)thr0_value); +} + +/* Invalidate a cached entry */ +TEST_F(Notify, inval_entry) +{ + const static char FULLPATH[] = "mountpoint/foo"; + const static char RELPATH[] = "foo"; + struct inval_entry_args iea; + struct stat sb; + void *thr0_value; + uint64_t ino0 = 42; + uint64_t ino1 = 43; + Sequence seq; + pthread_t th0; + + expect_lookup(FUSE_ROOT_ID, RELPATH, ino0, seq); + expect_lookup(FUSE_ROOT_ID, RELPATH, ino1, seq); + + /* Fill the entry cache */ + ASSERT_EQ(0, stat(FULLPATH, &sb)) << strerror(errno); + EXPECT_EQ(ino0, sb.st_ino); + + /* Now invalidate the entry */ + iea.mock = m_mock; + iea.parent = FUSE_ROOT_ID; + iea.name = RELPATH; + iea.namelen = strlen(RELPATH); + ASSERT_EQ(0, pthread_create(&th0, NULL, inval_entry, &iea)) + << strerror(errno); + pthread_join(th0, &thr0_value); + /* It's not an error for an entry to not be cached */ + EXPECT_EQ(0, (intptr_t)thr0_value); + + /* The second lookup should return the alternate ino */ + ASSERT_EQ(0, stat(FULLPATH, &sb)) << strerror(errno); + EXPECT_EQ(ino1, sb.st_ino); +} + +/* + * Invalidate a cached entry beneath the root, which uses a slightly different + * code path. + */ +TEST_F(Notify, inval_entry_below_root) +{ + const static char FULLPATH[] = "mountpoint/some_dir/foo"; + const static char DNAME[] = "some_dir"; + const static char FNAME[] = "foo"; + struct inval_entry_args iea; + struct stat sb; + void *thr0_value; + uint64_t dir_ino = 41; + uint64_t ino0 = 42; + uint64_t ino1 = 43; + Sequence seq; + pthread_t th0; + + EXPECT_LOOKUP(FUSE_ROOT_ID, DNAME) + .WillOnce(Invoke( + ReturnImmediate([=](auto in __unused, auto& out) { + SET_OUT_HEADER_LEN(out, entry); + out.body.entry.attr.mode = S_IFDIR | 0755; + out.body.entry.nodeid = dir_ino; + out.body.entry.attr.nlink = 2; + out.body.entry.attr_valid = UINT64_MAX; + out.body.entry.entry_valid = UINT64_MAX; + }))); + expect_lookup(dir_ino, FNAME, ino0, seq); + expect_lookup(dir_ino, FNAME, ino1, seq); + + /* Fill the entry cache */ + ASSERT_EQ(0, stat(FULLPATH, &sb)) << strerror(errno); + EXPECT_EQ(ino0, sb.st_ino); + + /* Now invalidate the entry */ + iea.mock = m_mock; + iea.parent = dir_ino; + iea.name = FNAME; + iea.namelen = strlen(FNAME); + ASSERT_EQ(0, pthread_create(&th0, NULL, inval_entry, &iea)) + << strerror(errno); + pthread_join(th0, &thr0_value); + /* It's not an error for an entry to not be cached */ + EXPECT_EQ(0, (intptr_t)thr0_value); + + /* The second lookup should return the alternate ino */ + ASSERT_EQ(0, stat(FULLPATH, &sb)) << strerror(errno); + EXPECT_EQ(ino1, sb.st_ino); +} + +/* Invalidating an entry invalidates the parent directory's attributes */ +TEST_F(Notify, inval_entry_invalidates_parent_attrs) +{ + const static char FULLPATH[] = "mountpoint/foo"; + const static char RELPATH[] = "foo"; + struct inval_entry_args iea; + struct stat sb; + void *thr0_value; + uint64_t ino = 42; + Sequence seq; + pthread_t th0; + + expect_lookup(FUSE_ROOT_ID, RELPATH, ino, seq); + EXPECT_CALL(*m_mock, process( + ResultOf([=](auto in) { + return (in.header.opcode == FUSE_GETATTR && + in.header.nodeid == FUSE_ROOT_ID); + }, Eq(true)), + _) + ).Times(2) + .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { + SET_OUT_HEADER_LEN(out, attr); + out.body.attr.attr.mode = S_IFDIR | 0755; + out.body.attr.attr_valid = UINT64_MAX; + }))); + + /* Fill the attr and entry cache */ + ASSERT_EQ(0, stat("mountpoint", &sb)) << strerror(errno); + ASSERT_EQ(0, stat(FULLPATH, &sb)) << strerror(errno); + + /* Now invalidate the entry */ + iea.mock = m_mock; + iea.parent = FUSE_ROOT_ID; + iea.name = RELPATH; + iea.namelen = strlen(RELPATH); + ASSERT_EQ(0, pthread_create(&th0, NULL, inval_entry, &iea)) + << strerror(errno); + pthread_join(th0, &thr0_value); + /* It's not an error for an entry to not be cached */ + EXPECT_EQ(0, (intptr_t)thr0_value); + + /* /'s attribute cache should be cleared */ + ASSERT_EQ(0, stat("mountpoint", &sb)) << strerror(errno); +}