Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Jun 2019 12:11:48 -0600
From:      Scott Long <scottl@samsco.org>
To:        Alan Somers <asomers@freebsd.org>
Cc:        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:  <5E43BBD0-3308-4CDC-9E26-28AE496E8281@samsco.org>
In-Reply-To: <201906201708.x5KH8M6e002674@repo.freebsd.org>
References:  <201906201708.x5KH8M6e002674@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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:
>=20
> Author: asomers
> Date: Thu Jun 20 17:08:21 2019
> New Revision: 349238
> URL: https://svnweb.freebsd.org/changeset/base/349238
>=20
> Log:
>  fusefs: implement VOP_BMAP
>=20
>  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.
>=20
>  The major result of this change is that sequential reads to FUSE =
files will
>  now usually happen 128KB at a time instead of 64KB.
>=20
>  Sponsored by:	The FreeBSD Foundation
>=20
> 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
>=20
> Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
> =
=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/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,=20
>=20
> 	if (fuse_libabi_geq(data, 7, 5)) {
> 		if (fticket_resp(tick)->len =3D=3D sizeof(struct =
fuse_init_out)) {
> -			data->max_readahead =3D fiio->max_readahead;
> +			data->max_readahead_blocks =3D =
fiio->max_readahead /
> +				maxbcachebuf;
> 			data->max_write =3D fiio->max_write;
> 			if (fiio->flags & FUSE_ASYNC_READ)
> 				data->dataflags |=3D FSESS_ASYNC_READ;
>=20
> Modified: projects/fuse2/sys/fs/fuse/fuse_io.c
> =
=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/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 =3D uio->uio_resid + on;
> 			seqcount =3D MIN(seqcount,
> -				data->max_readahead / biosize + 1);
> +				data->max_readahead_blocks + 1);
> 			err =3D cluster_read(vp, filesize, lbn, bcount, =
NOCRED,
> 				totread, seqcount, 0, &bp);
> -		} else if (seqcount > 1 && data->max_readahead >=3D =
nextsize) {
> +		} else if (seqcount > 1 && data->max_readahead_blocks >=3D=
 1) {
> 			/* Try non-clustered readahead */
> 			err =3D breadn(vp, lbn, bcount, &nextlbn, =
&nextsize, 1,
> 				NOCRED, &bp);
>=20
> Modified: projects/fuse2/sys/fs/fuse/fuse_ipc.c
> =
=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/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 =3D fticket_opcode(ftick);
>=20
> 	switch (opcode) {
> +	case FUSE_BMAP:
> +		err =3D (blen =3D=3D sizeof(struct fuse_bmap_out)) ? 0 : =
EINVAL;
> +		break;
> +
> 	case FUSE_LINK:
> 	case FUSE_LOOKUP:
> 	case FUSE_MKDIR:
>=20
> Modified: projects/fuse2/sys/fs/fuse/fuse_ipc.h
> =
=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/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;
>=20
> -	uint32_t			max_readahead;
> +	uint32_t			max_readahead_blocks;
> 	uint32_t			max_write;
> 	uint32_t			max_read;
> 	uint32_t			subtype;
>=20
> Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
> =
=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/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 =3D {
> 	.vop_default =3D &default_vnodeops,
> 	.vop_access =3D fuse_vnop_access,
> 	.vop_advlock =3D fuse_vnop_advlock,
> +	.vop_bmap =3D fuse_vnop_bmap,
> 	.vop_close =3D fuse_vnop_close,
> 	.vop_create =3D fuse_vnop_create,
> 	.vop_deleteextattr =3D fuse_vnop_deleteextattr,
> @@ -464,6 +466,92 @@ fuse_vnop_advlock(struct vop_advlock_args *ap)
> 	}
>=20
> 	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 =3D ap->a_vp;
> +	struct bufobj **bo =3D ap->a_bop;
> +	struct thread *td =3D 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 =3D ap->a_bn;
> +	daddr_t *pbn =3D ap->a_bnp;
> +	int *runp =3D ap->a_runp;
> +	int *runb =3D ap->a_runb;
> +	int error =3D 0;
> +	int maxrun;
> +
> +	if (fuse_isdeadfs(vp)) {
> +		return ENXIO;
> +	}
> +
> +	mp =3D vnode_mount(vp);
> +	data =3D fuse_get_mpdata(mp);
> +	biosize =3D fuse_iosize(vp);
> +	maxrun =3D MIN(vp->v_mount->mnt_iosize_max / biosize - 1,
> +		data->max_readahead_blocks);
> +
> +	if (bo !=3D NULL)
> +		*bo =3D &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.
> +	 *=20
> +	 * FUSE file systems may opt out of read clustering in two ways:
> +	 * * mounting with -onoclusterr
> +	 * * Setting max_readahead <=3D maxbcachebuf during FUSE_INIT
> +	 */
> +	if (runb !=3D NULL)
> +		*runb =3D MIN(lbn, maxrun);
> +	if (runp !=3D NULL) {
> +		error =3D fuse_vnode_size(vp, &filesize, td->td_ucred, =
td);
> +		if (error =3D=3D 0)
> +			*runp =3D MIN(MAX(0, filesize / biosize - lbn - =
1),
> +				    maxrun);
> +		else
> +			*runp =3D 0;
> +	}
> +
> +	if (fsess_isimpl(mp, FUSE_BMAP)) {
> +		fdisp_init(&fdi, sizeof(*fbi));
> +		fdisp_make_vp(&fdi, FUSE_BMAP, vp, td, td->td_ucred);
> +		fbi =3D fdi.indata;
> +		fbi->block =3D lbn;
> +		fbi->blocksize =3D biosize;
> +		error =3D fdisp_wait_answ(&fdi);
> +		if (error =3D=3D ENOSYS) {
> +			fsess_set_notimpl(mp, FUSE_BMAP);
> +			error =3D 0;
> +		} else {
> +			fbo =3D fdi.answ;
> +			if (error =3D=3D 0 && pbn !=3D NULL)
> +				*pbn =3D fbo->block;
> +			return error;
> +		}
> +	}
> +
> +	/* If the daemon doesn't support BMAP, make up a sensible =
default */
> +	if (pbn !=3D NULL)
> +		*pbn =3D lbn * btodb(biosize);
> +	return (error);
> }
>=20
> /*
>=20
> Modified: projects/fuse2/tests/sys/fs/fusefs/Makefile
> =
=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/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=3D	${TESTSBASE}/sys/fs/fusefs
> # out, so we get more granular reporting.
> GTESTS+=3D	access
> GTESTS+=3D	allow_other
> +GTESTS+=3D	bmap
> GTESTS+=3D	create
> GTESTS+=3D	default_permissions
> GTESTS+=3D	default_permissions_privileged
>=20
> Added: projects/fuse2/tests/sys/fs/fusefs/bmap.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
> --- /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[] =3D "mountpoint/foo";
> +const static char RELPATH[] =3D "foo";
> +
> +class Bmap: public FuseTest {
> +public:
> +virtual void SetUp() {
> +	m_maxreadahead =3D 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([=3D](auto in) {
> +			return (in.header.opcode =3D=3D FUSE_BMAP &&
> +				in.header.nodeid =3D=3D ino &&
> +				in.body.bmap.block =3D=3D lbn &&
> +				in.body.bmap.blocksize =3D=3D =
blocksize);
> +		}, Eq(true)),
> +		_)
> +	).WillOnce(Invoke(ReturnImmediate([=3D](auto i __unused, auto& =
out) {
> +		SET_OUT_HEADER_LEN(out, bmap);
> +		out.body.bmap.block =3D pbn;
> +	})));
> +}
> +=09
> +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 =3D 1 << 20;
> +	const ino_t ino =3D 42;
> +	int64_t lbn =3D 10;
> +	int64_t pbn =3D 12345;
> +	int fd;
> +
> +	expect_lookup(RELPATH, 42, filesize);
> +	expect_open(ino, 0, 1);
> +	expect_bmap(ino, lbn, m_maxbcachebuf, pbn);
> +
> +	fd =3D open(FULLPATH, O_RDWR);
> +	ASSERT_LE(0, fd) << strerror(errno);
> +
> +	arg.bn =3D lbn;
> +	arg.runp =3D -1;
> +	arg.runb =3D -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);
> +}
> +
> +/*=20
> + * 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 =3D 1 << 20;
> +	const ino_t ino =3D 42;
> +	int64_t lbn;
> +	int fd;
> +
> +	expect_lookup(RELPATH, 42, filesize);
> +	expect_open(ino, 0, 1);
> +	EXPECT_CALL(*m_mock, process(
> +		ResultOf([=3D](auto in) {
> +			return (in.header.opcode =3D=3D FUSE_BMAP);
> +		}, Eq(true)),
> +		_)
> +	).WillOnce(Invoke(ReturnErrno(ENOSYS)));
> +
> +	fd =3D open(FULLPATH, O_RDWR);
> +	ASSERT_LE(0, fd) << strerror(errno);
> +
> +	/* First block */
> +	lbn =3D 0;
> +	arg.bn =3D lbn;
> +	arg.runp =3D -1;
> +	arg.runb =3D -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 =3D filesize / m_maxbcachebuf / 2;
> +	arg.bn =3D lbn;
> +	arg.runp =3D -1;
> +	arg.runb =3D -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 =3D filesize / m_maxbcachebuf - 1;
> +	arg.bn =3D lbn;
> +	arg.runp =3D -1;
> +	arg.runb =3D -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);
> +}
>=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	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=3D%#x", in.body.access.mask);
> 			break;
> +		case FUSE_BMAP:
> +			printf(" block=3D%#lx blocksize=3D%#x", =
in.body.bmap.block,
> +				in.body.bmap.blocksize);
> +			break;
> 		case FUSE_CREATE:
> 			if (m_kernel_minor_version >=3D 12)
> 				name =3D (const char*)in.body.bytes +
>=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	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 {
>=20
> 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;
> 	/*
>=20
> Modified: projects/fuse2/tests/sys/fs/fusefs/read.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/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 @@
>  */
>=20
> 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 =
*/
> }
>=20
> -/* Large reads should be clustered, even across cache block =
boundaries */
> -/*=20
> - * 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[] =3D "mountpoint/some_file.txt";
> 	const char RELPATH[] =3D "some_file.txt";
> 	uint64_t ino =3D 42;
> -	int fd, maxcontig;
> +	int fd, maxcontig, clustersize;
> 	ssize_t bufsize =3D 4 * m_maxbcachebuf;
> 	ssize_t filesize =3D bufsize;
> 	uint64_t len;
> @@ -774,8 +773,9 @@ TEST_P(ReadAhead, DISABLED_cluster) {
> 	expect_open(ino, 0, 1);
> 	maxcontig =3D m_noclusterr ? m_maxbcachebuf :
> 				   m_maxbcachebuf + =
(int)get<1>(GetParam());
> -	for (offs =3D 0; offs < bufsize; offs +=3D maxcontig) {
> -		len =3D std::min((size_t)maxcontig, (size_t)(filesize - =
offs));
> +	clustersize =3D MIN(maxcontig, MAXPHYS);
> +	for (offs =3D 0; offs < bufsize; offs +=3D clustersize) {
> +		len =3D std::min((size_t)clustersize, (size_t)(filesize =
- offs));
> 		expect_read(ino, offs, len, len, contents + offs);
> 	}
>=20
> @@ -791,47 +791,11 @@ TEST_P(ReadAhead, DISABLED_cluster) {
> 	/* Deliberately leak fd.  close(2) will be tested in release.cc =
*/
> }
>=20
> -/* fuse(4) should honor the filesystem's requested m_readahead =
parameter */
> -TEST_P(ReadAhead, readahead) {
> -	const char FULLPATH[] =3D "mountpoint/some_file.txt";
> -	const char RELPATH[] =3D "some_file.txt";
> -	uint64_t ino =3D 42;
> -	int fd, i;
> -	ssize_t bufsize =3D m_maxbcachebuf;
> -	ssize_t filesize =3D m_maxbcachebuf * 6;
> -	char *rbuf, *contents;
> -
> -	contents =3D (char*)malloc(filesize);
> -	ASSERT_NE(NULL, contents);
> -	memset(contents, 'X', filesize);
> -	rbuf =3D (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 =3D 0; i < (int)get<1>(GetParam()) / m_maxbcachebuf; i++) =
{
> -		off_t offs =3D (i + 1) * m_maxbcachebuf;
> -		expect_read(ino, offs, m_maxbcachebuf, m_maxbcachebuf,
> -			contents + offs);
> -	}
> -
> -	fd =3D 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)));
>=20
> Modified: projects/fuse2/tests/sys/fs/fusefs/utils.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/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([=3D](auto in) {
> +				return (in.header.opcode =3D=3D =
FUSE_BMAP);
> +			}, Eq(true)),
> +			_)
> +		).Times(AnyNumber())
> +		.WillRepeatedly(Invoke(ReturnErrno(ENOSYS)));
> 	} catch (std::system_error err) {
> 		FAIL() << err.what();
> 	}
>=20




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5E43BBD0-3308-4CDC-9E26-28AE496E8281>