Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Jun 2019 12:21:14 -0600
From:      Alan Somers <asomers@freebsd.org>
To:        Scott Long <scottl@samsco.org>
Cc:        src-committers <src-committers@freebsd.org>, svn-src-projects@freebsd.org
Subject:   Re: svn commit: r349238 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs
Message-ID:  <CAOtMX2jGYvjKc9iYcDtGkbfqdmTKSz=5hDM9%2BBtF=BAnwVPQQQ@mail.gmail.com>
In-Reply-To: <5E43BBD0-3308-4CDC-9E26-28AE496E8281@samsco.org>
References:  <201906201708.x5KH8M6e002674@repo.freebsd.org> <5E43BBD0-3308-4CDC-9E26-28AE496E8281@samsco.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Well, I haven't tried.  But if maxbcachebuf remains 64KB and MAXPHYS
is 1MB, then reading a file sequentially should start by issuing a
128KB read and progress to 1MB reads if the I/O remains sequential.
One outstanding problem is that fusefs will greedily try to cluster
reads whenever possible, to minimize upcalls.  But if the file system
is stored on rotating media, like for instance when using fusefs-ntfs
on a single HDD, then seeks will probably be slower than upcalls.  In
such a case the greedy clustering could hurt performance.  But I don't
see a good alternative.  The best would be for FUSE_BMAP to include
runp and runb fields, but that would require a change to the FUSE
protocol.
-Alan


On Thu, Jun 20, 2019 at 12:12 PM Scott Long <scottl@samsco.org> wrote:
>
> Great work!  What happens if you set MAXPHYS to something big like 1MB?
>
> Scott
>
>
> > On Jun 20, 2019, at 11:08 AM, Alan Somers <asomers@freebsd.org> wrote:
> >
> > Author: asomers
> > Date: Thu Jun 20 17:08:21 2019
> > New Revision: 349238
> > URL: https://svnweb.freebsd.org/changeset/base/349238
> >
> > Log:
> >  fusefs: implement VOP_BMAP
> >
> >  If the fuse daemon supports FUSE_BMAP, then use that for the block mapping.
> >  Otherwise, use the same technique used by vop_stdbmap.  Report large values
> >  for runp and runb in order to maximize read clustering and minimize upcalls,
> >  even if we don't know the true layout.
> >
> >  The major result of this change is that sequential reads to FUSE files will
> >  now usually happen 128KB at a time instead of 64KB.
> >
> >  Sponsored by:        The FreeBSD Foundation
> >
> > Added:
> >  projects/fuse2/tests/sys/fs/fusefs/bmap.cc   (contents, props changed)
> > Modified:
> >  projects/fuse2/sys/fs/fuse/fuse_internal.c
> >  projects/fuse2/sys/fs/fuse/fuse_io.c
> >  projects/fuse2/sys/fs/fuse/fuse_ipc.c
> >  projects/fuse2/sys/fs/fuse/fuse_ipc.h
> >  projects/fuse2/sys/fs/fuse/fuse_vnops.c
> >  projects/fuse2/tests/sys/fs/fusefs/Makefile
> >  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/utils.cc
> >
> > Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
> > ==============================================================================
> > --- projects/fuse2/sys/fs/fuse/fuse_internal.c        Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/sys/fs/fuse/fuse_internal.c        Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -908,7 +908,8 @@ fuse_internal_init_callback(struct fuse_ticket *tick,
> >
> >       if (fuse_libabi_geq(data, 7, 5)) {
> >               if (fticket_resp(tick)->len == sizeof(struct fuse_init_out)) {
> > -                     data->max_readahead = fiio->max_readahead;
> > +                     data->max_readahead_blocks = fiio->max_readahead /
> > +                             maxbcachebuf;
> >                       data->max_write = fiio->max_write;
> >                       if (fiio->flags & FUSE_ASYNC_READ)
> >                               data->dataflags |= FSESS_ASYNC_READ;
> >
> > Modified: projects/fuse2/sys/fs/fuse/fuse_io.c
> > ==============================================================================
> > --- projects/fuse2/sys/fs/fuse/fuse_io.c      Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/sys/fs/fuse/fuse_io.c      Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -321,10 +321,10 @@ fuse_read_biobackend(struct vnode *vp, struct uio *uio
> >                       /* Try clustered read */
> >                       long totread = uio->uio_resid + on;
> >                       seqcount = MIN(seqcount,
> > -                             data->max_readahead / biosize + 1);
> > +                             data->max_readahead_blocks + 1);
> >                       err = cluster_read(vp, filesize, lbn, bcount, NOCRED,
> >                               totread, seqcount, 0, &bp);
> > -             } else if (seqcount > 1 && data->max_readahead >= nextsize) {
> > +             } else if (seqcount > 1 && data->max_readahead_blocks >= 1) {
> >                       /* Try non-clustered readahead */
> >                       err = breadn(vp, lbn, bcount, &nextlbn, &nextsize, 1,
> >                               NOCRED, &bp);
> >
> > Modified: projects/fuse2/sys/fs/fuse/fuse_ipc.c
> > ==============================================================================
> > --- projects/fuse2/sys/fs/fuse/fuse_ipc.c     Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/sys/fs/fuse/fuse_ipc.c     Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -711,6 +711,10 @@ fuse_body_audit(struct fuse_ticket *ftick, size_t blen
> >       opcode = fticket_opcode(ftick);
> >
> >       switch (opcode) {
> > +     case FUSE_BMAP:
> > +             err = (blen == sizeof(struct fuse_bmap_out)) ? 0 : EINVAL;
> > +             break;
> > +
> >       case FUSE_LINK:
> >       case FUSE_LOOKUP:
> >       case FUSE_MKDIR:
> >
> > Modified: projects/fuse2/sys/fs/fuse/fuse_ipc.h
> > ==============================================================================
> > --- projects/fuse2/sys/fs/fuse/fuse_ipc.h     Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/sys/fs/fuse/fuse_ipc.h     Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -197,7 +197,7 @@ struct fuse_data {
> >       uint32_t                        fuse_libabi_major;
> >       uint32_t                        fuse_libabi_minor;
> >
> > -     uint32_t                        max_readahead;
> > +     uint32_t                        max_readahead_blocks;
> >       uint32_t                        max_write;
> >       uint32_t                        max_read;
> >       uint32_t                        subtype;
> >
> > Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
> > ==============================================================================
> > --- projects/fuse2/sys/fs/fuse/fuse_vnops.c   Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/sys/fs/fuse/fuse_vnops.c   Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -120,6 +120,7 @@ SDT_PROBE_DEFINE2(fusefs, , vnops, trace, "int", "char
> > /* vnode ops */
> > static vop_access_t fuse_vnop_access;
> > static vop_advlock_t fuse_vnop_advlock;
> > +static vop_bmap_t fuse_vnop_bmap;
> > static vop_close_t fuse_fifo_close;
> > static vop_close_t fuse_vnop_close;
> > static vop_create_t fuse_vnop_create;
> > @@ -174,6 +175,7 @@ struct vop_vector fuse_vnops = {
> >       .vop_default = &default_vnodeops,
> >       .vop_access = fuse_vnop_access,
> >       .vop_advlock = fuse_vnop_advlock,
> > +     .vop_bmap = fuse_vnop_bmap,
> >       .vop_close = fuse_vnop_close,
> >       .vop_create = fuse_vnop_create,
> >       .vop_deleteextattr = fuse_vnop_deleteextattr,
> > @@ -464,6 +466,92 @@ fuse_vnop_advlock(struct vop_advlock_args *ap)
> >       }
> >
> >       return err;
> > +}
> > +
> > +/* {
> > +     struct vnode *a_vp;
> > +     daddr_t a_bn;
> > +     struct bufobj **a_bop;
> > +     daddr_t *a_bnp;
> > +     int *a_runp;
> > +     int *a_runb;
> > +} */
> > +static int
> > +fuse_vnop_bmap(struct vop_bmap_args *ap)
> > +{
> > +     struct vnode *vp = ap->a_vp;
> > +     struct bufobj **bo = ap->a_bop;
> > +     struct thread *td = curthread;
> > +     struct mount *mp;
> > +     struct fuse_dispatcher fdi;
> > +     struct fuse_bmap_in *fbi;
> > +     struct fuse_bmap_out *fbo;
> > +     struct fuse_data *data;
> > +     uint64_t biosize;
> > +     off_t filesize;
> > +     daddr_t lbn = ap->a_bn;
> > +     daddr_t *pbn = ap->a_bnp;
> > +     int *runp = ap->a_runp;
> > +     int *runb = ap->a_runb;
> > +     int error = 0;
> > +     int maxrun;
> > +
> > +     if (fuse_isdeadfs(vp)) {
> > +             return ENXIO;
> > +     }
> > +
> > +     mp = vnode_mount(vp);
> > +     data = fuse_get_mpdata(mp);
> > +     biosize = fuse_iosize(vp);
> > +     maxrun = MIN(vp->v_mount->mnt_iosize_max / biosize - 1,
> > +             data->max_readahead_blocks);
> > +
> > +     if (bo != NULL)
> > +             *bo = &vp->v_bufobj;
> > +
> > +     /*
> > +      * The FUSE_BMAP operation does not include the runp and runb
> > +      * variables, so we must guess.  Report nonzero contiguous runs so
> > +      * cluster_read will combine adjacent reads.  It's worthwhile to reduce
> > +      * upcalls even if we don't know the true physical layout of the file.
> > +      *
> > +      * FUSE file systems may opt out of read clustering in two ways:
> > +      * * mounting with -onoclusterr
> > +      * * Setting max_readahead <= maxbcachebuf during FUSE_INIT
> > +      */
> > +     if (runb != NULL)
> > +             *runb = MIN(lbn, maxrun);
> > +     if (runp != NULL) {
> > +             error = fuse_vnode_size(vp, &filesize, td->td_ucred, td);
> > +             if (error == 0)
> > +                     *runp = MIN(MAX(0, filesize / biosize - lbn - 1),
> > +                                 maxrun);
> > +             else
> > +                     *runp = 0;
> > +     }
> > +
> > +     if (fsess_isimpl(mp, FUSE_BMAP)) {
> > +             fdisp_init(&fdi, sizeof(*fbi));
> > +             fdisp_make_vp(&fdi, FUSE_BMAP, vp, td, td->td_ucred);
> > +             fbi = fdi.indata;
> > +             fbi->block = lbn;
> > +             fbi->blocksize = biosize;
> > +             error = fdisp_wait_answ(&fdi);
> > +             if (error == ENOSYS) {
> > +                     fsess_set_notimpl(mp, FUSE_BMAP);
> > +                     error = 0;
> > +             } else {
> > +                     fbo = fdi.answ;
> > +                     if (error == 0 && pbn != NULL)
> > +                             *pbn = fbo->block;
> > +                     return error;
> > +             }
> > +     }
> > +
> > +     /* If the daemon doesn't support BMAP, make up a sensible default */
> > +     if (pbn != NULL)
> > +             *pbn = lbn * btodb(biosize);
> > +     return (error);
> > }
> >
> > /*
> >
> > Modified: projects/fuse2/tests/sys/fs/fusefs/Makefile
> > ==============================================================================
> > --- projects/fuse2/tests/sys/fs/fusefs/Makefile       Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/tests/sys/fs/fusefs/Makefile       Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -9,6 +9,7 @@ TESTSDIR=     ${TESTSBASE}/sys/fs/fusefs
> > # out, so we get more granular reporting.
> > GTESTS+=      access
> > GTESTS+=      allow_other
> > +GTESTS+=     bmap
> > GTESTS+=      create
> > GTESTS+=      default_permissions
> > GTESTS+=      default_permissions_privileged
> >
> > Added: projects/fuse2/tests/sys/fs/fusefs/bmap.cc
> > ==============================================================================
> > --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> > +++ projects/fuse2/tests/sys/fs/fusefs/bmap.cc        Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -0,0 +1,159 @@
> > +/*-
> > + * 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 <sys/param.h>
> > +#include <sys/ioctl.h>
> > +#include <sys/filio.h>
> > +
> > +#include <fcntl.h>
> > +}
> > +
> > +#include "mockfs.hh"
> > +#include "utils.hh"
> > +
> > +using namespace testing;
> > +
> > +const static char FULLPATH[] = "mountpoint/foo";
> > +const static char RELPATH[] = "foo";
> > +
> > +class Bmap: public FuseTest {
> > +public:
> > +virtual void SetUp() {
> > +     m_maxreadahead = UINT32_MAX;
> > +     FuseTest::SetUp();
> > +}
> > +void expect_bmap(uint64_t ino, uint64_t lbn, uint32_t blocksize, uint64_t pbn)
> > +{
> > +     EXPECT_CALL(*m_mock, process(
> > +             ResultOf([=](auto in) {
> > +                     return (in.header.opcode == FUSE_BMAP &&
> > +                             in.header.nodeid == ino &&
> > +                             in.body.bmap.block == lbn &&
> > +                             in.body.bmap.blocksize == blocksize);
> > +             }, Eq(true)),
> > +             _)
> > +     ).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto& out) {
> > +             SET_OUT_HEADER_LEN(out, bmap);
> > +             out.body.bmap.block = pbn;
> > +     })));
> > +}
> > +
> > +void expect_lookup(const char *relpath, uint64_t ino, off_t size)
> > +{
> > +     FuseTest::expect_lookup(relpath, ino, S_IFREG | 0644, size, 1,
> > +             UINT64_MAX);
> > +}
> > +};
> > +
> > +/*
> > + * Test FUSE_BMAP
> > + * XXX The FUSE protocol does not include the runp and runb variables, so those
> > + * must be guessed in-kernel.
> > + */
> > +TEST_F(Bmap, bmap)
> > +{
> > +     struct fiobmap2_arg arg;
> > +     const off_t filesize = 1 << 20;
> > +     const ino_t ino = 42;
> > +     int64_t lbn = 10;
> > +     int64_t pbn = 12345;
> > +     int fd;
> > +
> > +     expect_lookup(RELPATH, 42, filesize);
> > +     expect_open(ino, 0, 1);
> > +     expect_bmap(ino, lbn, m_maxbcachebuf, pbn);
> > +
> > +     fd = open(FULLPATH, O_RDWR);
> > +     ASSERT_LE(0, fd) << strerror(errno);
> > +
> > +     arg.bn = lbn;
> > +     arg.runp = -1;
> > +     arg.runb = -1;
> > +     ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
> > +     EXPECT_EQ(arg.bn, pbn);
> > +     EXPECT_EQ(arg.runp, MAXPHYS / m_maxbcachebuf - 1);
> > +     EXPECT_EQ(arg.runb, MAXPHYS / m_maxbcachebuf - 1);
> > +}
> > +
> > +/*
> > + * If the daemon does not implement VOP_BMAP, fusefs should return sensible
> > + * defaults.
> > + */
> > +TEST_F(Bmap, default_)
> > +{
> > +     struct fiobmap2_arg arg;
> > +     const off_t filesize = 1 << 20;
> > +     const ino_t ino = 42;
> > +     int64_t lbn;
> > +     int fd;
> > +
> > +     expect_lookup(RELPATH, 42, filesize);
> > +     expect_open(ino, 0, 1);
> > +     EXPECT_CALL(*m_mock, process(
> > +             ResultOf([=](auto in) {
> > +                     return (in.header.opcode == FUSE_BMAP);
> > +             }, Eq(true)),
> > +             _)
> > +     ).WillOnce(Invoke(ReturnErrno(ENOSYS)));
> > +
> > +     fd = open(FULLPATH, O_RDWR);
> > +     ASSERT_LE(0, fd) << strerror(errno);
> > +
> > +     /* First block */
> > +     lbn = 0;
> > +     arg.bn = lbn;
> > +     arg.runp = -1;
> > +     arg.runb = -1;
> > +     ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
> > +     EXPECT_EQ(arg.bn, 0);
> > +     EXPECT_EQ(arg.runp, MAXPHYS / m_maxbcachebuf - 1);
> > +     EXPECT_EQ(arg.runb, 0);
> > +
> > +     /* In the middle */
> > +     lbn = filesize / m_maxbcachebuf / 2;
> > +     arg.bn = lbn;
> > +     arg.runp = -1;
> > +     arg.runb = -1;
> > +     ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
> > +     EXPECT_EQ(arg.bn, lbn * m_maxbcachebuf / DEV_BSIZE);
> > +     EXPECT_EQ(arg.runp, MAXPHYS / m_maxbcachebuf - 1);
> > +     EXPECT_EQ(arg.runb, MAXPHYS / m_maxbcachebuf - 1);
> > +
> > +     /* Last block */
> > +     lbn = filesize / m_maxbcachebuf - 1;
> > +     arg.bn = lbn;
> > +     arg.runp = -1;
> > +     arg.runb = -1;
> > +     ASSERT_EQ(0, ioctl(fd, FIOBMAP2, &arg)) << strerror(errno);
> > +     EXPECT_EQ(arg.bn, lbn * m_maxbcachebuf / DEV_BSIZE);
> > +     EXPECT_EQ(arg.runp, 0);
> > +     EXPECT_EQ(arg.runb, MAXPHYS / m_maxbcachebuf - 1);
> > +}
> >
> > Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.cc
> > ==============================================================================
> > --- projects/fuse2/tests/sys/fs/fusefs/mockfs.cc      Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.cc      Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -168,6 +168,10 @@ void MockFS::debug_request(const mockfs_buf_in &in)
> >               case FUSE_ACCESS:
> >                       printf(" mask=%#x", in.body.access.mask);
> >                       break;
> > +             case FUSE_BMAP:
> > +                     printf(" block=%#lx blocksize=%#x", in.body.bmap.block,
> > +                             in.body.bmap.blocksize);
> > +                     break;
> >               case FUSE_CREATE:
> >                       if (m_kernel_minor_version >= 12)
> >                               name = (const char*)in.body.bytes +
> >
> > Modified: projects/fuse2/tests/sys/fs/fusefs/mockfs.hh
> > ==============================================================================
> > --- projects/fuse2/tests/sys/fs/fusefs/mockfs.hh      Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/tests/sys/fs/fusefs/mockfs.hh      Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -124,6 +124,7 @@ struct fuse_create_out_7_8 {
> >
> > union fuse_payloads_in {
> >       fuse_access_in  access;
> > +     fuse_bmap_in    bmap;
> >       /* value is from fuse_kern_chan.c in fusefs-libs */
> >       uint8_t         bytes[0x21000 - sizeof(struct fuse_in_header)];
> >       fuse_create_in  create;
> > @@ -164,6 +165,7 @@ struct mockfs_buf_in {
> > union fuse_payloads_out {
> >       fuse_attr_out           attr;
> >       fuse_attr_out_7_8       attr_7_8;
> > +     fuse_bmap_out           bmap;
> >       fuse_create_out         create;
> >       fuse_create_out_7_8     create_7_8;
> >       /*
> >
> > Modified: projects/fuse2/tests/sys/fs/fusefs/read.cc
> > ==============================================================================
> > --- projects/fuse2/tests/sys/fs/fusefs/read.cc        Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/tests/sys/fs/fusefs/read.cc        Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -29,7 +29,7 @@
> >  */
> >
> > extern "C" {
> > -#include <sys/types.h>
> > +#include <sys/param.h>
> > #include <sys/mman.h>
> > #include <sys/socket.h>
> > #include <sys/sysctl.h>
> > @@ -749,16 +749,15 @@ TEST_F(ReadCacheable, DISABLED_sendfile_eio)
> >       /* Deliberately leak fd.  close(2) will be tested in release.cc */
> > }
> >
> > -/* Large reads should be clustered, even across cache block boundaries */
> > -/*
> > - * Disabled because clustered reads requires VOP_BMAP, which fusefs does not
> > - * yet support
> > +/*
> > + * Sequential reads should use readahead.  And if allowed, large reads should
> > + * be clustered.
> >  */
> > -TEST_P(ReadAhead, DISABLED_cluster) {
> > +TEST_P(ReadAhead, readahead) {
> >       const char FULLPATH[] = "mountpoint/some_file.txt";
> >       const char RELPATH[] = "some_file.txt";
> >       uint64_t ino = 42;
> > -     int fd, maxcontig;
> > +     int fd, maxcontig, clustersize;
> >       ssize_t bufsize = 4 * m_maxbcachebuf;
> >       ssize_t filesize = bufsize;
> >       uint64_t len;
> > @@ -774,8 +773,9 @@ TEST_P(ReadAhead, DISABLED_cluster) {
> >       expect_open(ino, 0, 1);
> >       maxcontig = m_noclusterr ? m_maxbcachebuf :
> >                                  m_maxbcachebuf + (int)get<1>(GetParam());
> > -     for (offs = 0; offs < bufsize; offs += maxcontig) {
> > -             len = std::min((size_t)maxcontig, (size_t)(filesize - offs));
> > +     clustersize = MIN(maxcontig, MAXPHYS);
> > +     for (offs = 0; offs < bufsize; offs += clustersize) {
> > +             len = std::min((size_t)clustersize, (size_t)(filesize - offs));
> >               expect_read(ino, offs, len, len, contents + offs);
> >       }
> >
> > @@ -791,47 +791,11 @@ TEST_P(ReadAhead, DISABLED_cluster) {
> >       /* Deliberately leak fd.  close(2) will be tested in release.cc */
> > }
> >
> > -/* fuse(4) should honor the filesystem's requested m_readahead parameter */
> > -TEST_P(ReadAhead, readahead) {
> > -     const char FULLPATH[] = "mountpoint/some_file.txt";
> > -     const char RELPATH[] = "some_file.txt";
> > -     uint64_t ino = 42;
> > -     int fd, i;
> > -     ssize_t bufsize = m_maxbcachebuf;
> > -     ssize_t filesize = m_maxbcachebuf * 6;
> > -     char *rbuf, *contents;
> > -
> > -     contents = (char*)malloc(filesize);
> > -     ASSERT_NE(NULL, contents);
> > -     memset(contents, 'X', filesize);
> > -     rbuf = (char*)calloc(1, bufsize);
> > -
> > -     expect_lookup(RELPATH, ino, filesize);
> > -     expect_open(ino, 0, 1);
> > -     /* fuse(4) should only read ahead the allowed amount */
> > -     expect_read(ino, 0, m_maxbcachebuf, m_maxbcachebuf, contents);
> > -     for (i = 0; i < (int)get<1>(GetParam()) / m_maxbcachebuf; i++) {
> > -             off_t offs = (i + 1) * m_maxbcachebuf;
> > -             expect_read(ino, offs, m_maxbcachebuf, m_maxbcachebuf,
> > -                     contents + offs);
> > -     }
> > -
> > -     fd = open(FULLPATH, O_RDONLY);
> > -     ASSERT_LE(0, fd) << strerror(errno);
> > -
> > -     /* Set the internal readahead counter to a "large" value */
> > -     ASSERT_EQ(0, fcntl(fd, F_READAHEAD, 1'000'000'000)) << strerror(errno);
> > -
> > -     ASSERT_EQ(bufsize, read(fd, rbuf, bufsize)) << strerror(errno);
> > -     ASSERT_EQ(0, memcmp(rbuf, contents, bufsize));
> > -
> > -     /* Deliberately leak fd.  close(2) will be tested in release.cc */
> > -}
> > -
> > INSTANTIATE_TEST_CASE_P(RA, ReadAhead,
> >       Values(tuple<bool, int>(false, 0u),
> >              tuple<bool, int>(false, 0x10000),
> >              tuple<bool, int>(false, 0x20000),
> >              tuple<bool, int>(false, 0x30000),
> >              tuple<bool, int>(true, 0u),
> > -            tuple<bool, int>(true, 0x10000)));
> > +            tuple<bool, int>(true, 0x10000),
> > +            tuple<bool, int>(true, 0x20000)));
> >
> > Modified: projects/fuse2/tests/sys/fs/fusefs/utils.cc
> > ==============================================================================
> > --- projects/fuse2/tests/sys/fs/fusefs/utils.cc       Thu Jun 20 16:36:20 2019        (r349237)
> > +++ projects/fuse2/tests/sys/fs/fusefs/utils.cc       Thu Jun 20 17:08:21 2019        (r349238)
> > @@ -129,6 +129,20 @@ void FuseTest::SetUp() {
> >                       _)
> >               ).Times(AnyNumber())
> >               .WillRepeatedly(Invoke(ReturnErrno(ENOSYS)));
> > +             /*
> > +              * FUSE_BMAP is called for most test cases that read data.  Set
> > +              * a default expectation and return ENOSYS.
> > +              *
> > +              * Individual test cases can override this expectation since
> > +              * googlemock evaluates expectations in LIFO order.
> > +              */
> > +             EXPECT_CALL(*m_mock, process(
> > +                     ResultOf([=](auto in) {
> > +                             return (in.header.opcode == FUSE_BMAP);
> > +                     }, Eq(true)),
> > +                     _)
> > +             ).Times(AnyNumber())
> > +             .WillRepeatedly(Invoke(ReturnErrno(ENOSYS)));
> >       } catch (std::system_error err) {
> >               FAIL() << err.what();
> >       }
> >
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAOtMX2jGYvjKc9iYcDtGkbfqdmTKSz=5hDM9%2BBtF=BAnwVPQQQ>