FS/XFS testing framework
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Jens Axboe <axboe@kernel.dk>
Cc: zlang@kernel.org, fstests@vger.kernel.org
Subject: Re: [PATCH 1/2] fsstress: add support for RWF_DONTCACHE
Date: Tue, 7 Jan 2025 09:31:35 -0800	[thread overview]
Message-ID: <20250107173135.GR6160@frogsfrogsfrogs> (raw)
In-Reply-To: <20250107160617.222775-2-axboe@kernel.dk>

On Tue, Jan 07, 2025 at 09:05:14AM -0700, Jens Axboe wrote:
> Using RWF_DONTCACHE tells the kernel that any page cache instantiated
> by this operation should get pruned once the operation completes. If
> data is in cache prior to the operation it will remain there.
> 
> Add ops for testing both the read and write side of this. If the kernel
> being tested doesn't support RWF_DONTCACHE, then operations are performed
> with regular read/write buffered IO.
> 
> See the kernel posting adding support:
> 
> https://lore.kernel.org/linux-fsdevel/20241220154831.1086649-1-axboe@kernel.dk/
> 
> Signed-off-by: Jens Axboe <axboe@kernel.dk>

Looks good to me now,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  ltp/fsstress.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 144 insertions(+)
> 
> diff --git a/ltp/fsstress.c b/ltp/fsstress.c
> index 3d248ee25791..c5554d651b67 100644
> --- a/ltp/fsstress.c
> +++ b/ltp/fsstress.c
> @@ -82,6 +82,16 @@ static int renameat2(int dfd1, const char *path1,
>  #define RENAME_WHITEOUT		(1 << 2)	/* Whiteout source */
>  #endif
>  
> +#ifndef RWF_DONTCACHE
> +#define RWF_DONTCACHE		0x80
> +#endif
> +
> +/*
> + * Default to RWF_DONTCACHE being available, turn it off if -EOPNOTSUPP
> + * is seen during issue.
> + */
> +static int have_rwf_dontcache = 1;
> +
>  #define FILELEN_MAX		(32*4096)
>  
>  typedef enum {
> @@ -117,6 +127,7 @@ typedef enum {
>  	OP_COLLAPSE,
>  	OP_INSERT,
>  	OP_READ,
> +	OP_READ_DONTCACHE,
>  	OP_READLINK,
>  	OP_READV,
>  	OP_REMOVEFATTR,
> @@ -143,6 +154,7 @@ typedef enum {
>  	OP_URING_READ,
>  	OP_URING_WRITE,
>  	OP_WRITE,
> +	OP_WRITE_DONTCACHE,
>  	OP_WRITEV,
>  	OP_EXCHANGE_RANGE,
>  	OP_LAST
> @@ -248,6 +260,7 @@ void	zero_f(opnum_t, long);
>  void	collapse_f(opnum_t, long);
>  void	insert_f(opnum_t, long);
>  void	unshare_f(opnum_t, long);
> +void	read_dontcache_f(opnum_t, long);
>  void	read_f(opnum_t, long);
>  void	readlink_f(opnum_t, long);
>  void	readv_f(opnum_t, long);
> @@ -273,6 +286,7 @@ void	unlink_f(opnum_t, long);
>  void	unresvsp_f(opnum_t, long);
>  void	uring_read_f(opnum_t, long);
>  void	uring_write_f(opnum_t, long);
> +void	write_dontcache_f(opnum_t, long);
>  void	write_f(opnum_t, long);
>  void	writev_f(opnum_t, long);
>  void	exchangerange_f(opnum_t, long);
> @@ -315,6 +329,7 @@ struct opdesc	ops[OP_LAST]	= {
>  	[OP_COLLAPSE]	   = {"collapse",      collapse_f,	1, 1 },
>  	[OP_INSERT]	   = {"insert",	       insert_f,	1, 1 },
>  	[OP_READ]	   = {"read",	       read_f,		1, 0 },
> +	[OP_READ_DONTCACHE] = {"read_dontcache", read_dontcache_f,	1, 0 },
>  	[OP_READLINK]	   = {"readlink",      readlink_f,	1, 0 },
>  	[OP_READV]	   = {"readv",	       readv_f,		1, 0 },
>  	/* remove (delete) extended attribute */
> @@ -346,6 +361,7 @@ struct opdesc	ops[OP_LAST]	= {
>  	[OP_URING_WRITE]   = {"uring_write",   uring_write_f,	1, 1 },
>  	[OP_WRITE]	   = {"write",	       write_f,		4, 1 },
>  	[OP_WRITEV]	   = {"writev",	       writev_f,	4, 1 },
> +	[OP_WRITE_DONTCACHE]= {"write_dontcache", write_dontcache_f,4, 1 },
>  	[OP_EXCHANGE_RANGE]= {"exchangerange", exchangerange_f,	2, 1 },
>  }, *ops_end;
>  
> @@ -4635,6 +4651,73 @@ readv_f(opnum_t opno, long r)
>  	close(fd);
>  }
>  
> +void
> +read_dontcache_f(opnum_t opno, long r)
> +{
> +	int		e;
> +	pathname_t	f;
> +	int		fd;
> +	int64_t		lr;
> +	off64_t		off;
> +	struct stat64	stb;
> +	int		v;
> +	char		st[1024];
> +	struct iovec	iov;
> +	int flags;
> +
> +	init_pathname(&f);
> +	if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
> +		if (v)
> +			printf("%d/%lld: read - no filename\n", procid, opno);
> +		free_pathname(&f);
> +		return;
> +	}
> +	fd = open_path(&f, O_RDONLY);
> +	e = fd < 0 ? errno : 0;
> +	check_cwd();
> +	if (fd < 0) {
> +		if (v)
> +			printf("%d/%lld: read - open %s failed %d\n",
> +				procid, opno, f.path, e);
> +		free_pathname(&f);
> +		return;
> +	}
> +	if (fstat64(fd, &stb) < 0) {
> +		if (v)
> +			printf("%d/%lld: read - fstat64 %s failed %d\n",
> +				procid, opno, f.path, errno);
> +		free_pathname(&f);
> +		close(fd);
> +		return;
> +	}
> +	inode_info(st, sizeof(st), &stb, v);
> +	if (stb.st_size == 0) {
> +		if (v)
> +			printf("%d/%lld: read - %s%s zero size\n", procid, opno,
> +			       f.path, st);
> +		free_pathname(&f);
> +		close(fd);
> +		return;
> +	}
> +	lr = ((int64_t)random() << 32) + random();
> +	off = (off64_t)(lr % stb.st_size);
> +	iov.iov_len = (random() % FILELEN_MAX) + 1;
> +	iov.iov_base = malloc(iov.iov_len);
> +	flags = have_rwf_dontcache ? RWF_DONTCACHE : 0;
> +	e = preadv2(fd, &iov, 1, off, flags) < 0 ? errno : 0;
> +	if (have_rwf_dontcache && e == EOPNOTSUPP) {
> +		have_rwf_dontcache = 0;
> +		e = preadv2(fd, &iov, 1, off, 0) < 0 ? errno : 0;
> +	}
> +	free(iov.iov_base);
> +	if (v)
> +		printf("%d/%lld: read dontcache %s%s [%lld,%d] %d\n",
> +		       procid, opno, f.path, st, (long long)off,
> +		       (int)iov.iov_len, e);
> +	free_pathname(&f);
> +	close(fd);
> +}
> +
>  void
>  removefattr_f(opnum_t opno, long r)
>  {
> @@ -5509,6 +5592,67 @@ writev_f(opnum_t opno, long r)
>  	close(fd);
>  }
>  
> +void
> +write_dontcache_f(opnum_t opno, long r)
> +{
> +	int		e;
> +	pathname_t	f;
> +	int		fd;
> +	int64_t		lr;
> +	off64_t		off;
> +	struct stat64	stb;
> +	int		v;
> +	char		st[1024];
> +	struct iovec	iov;
> +	int flags;
> +
> +	init_pathname(&f);
> +	if (!get_fname(FT_REGm, r, &f, NULL, NULL, &v)) {
> +		if (v)
> +			printf("%d/%lld: write - no filename\n", procid, opno);
> +		free_pathname(&f);
> +		return;
> +	}
> +	fd = open_path(&f, O_WRONLY);
> +	e = fd < 0 ? errno : 0;
> +	check_cwd();
> +	if (fd < 0) {
> +		if (v)
> +			printf("%d/%lld: write - open %s failed %d\n",
> +				procid, opno, f.path, e);
> +		free_pathname(&f);
> +		return;
> +	}
> +	if (fstat64(fd, &stb) < 0) {
> +		if (v)
> +			printf("%d/%lld: write - fstat64 %s failed %d\n",
> +				procid, opno, f.path, errno);
> +		free_pathname(&f);
> +		close(fd);
> +		return;
> +	}
> +	inode_info(st, sizeof(st), &stb, v);
> +	lr = ((int64_t)random() << 32) + random();
> +	off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
> +	off %= maxfsize;
> +	iov.iov_len = (random() % FILELEN_MAX) + 1;
> +	iov.iov_base = malloc(iov.iov_len);
> +	memset(iov.iov_base, nameseq & 0xff, iov.iov_len);
> +	flags = have_rwf_dontcache ? RWF_DONTCACHE : 0;
> +	e = pwritev2(fd, &iov, 1, off, flags) < 0 ? errno : 0;
> +	if (have_rwf_dontcache && e == EOPNOTSUPP) {
> +		have_rwf_dontcache = 0;
> +		e = pwritev2(fd, &iov, 1, off, 0) < 0 ? errno : 0;
> +	}
> +	free(iov.iov_base);
> +	if (v)
> +		printf("%d/%lld: write dontcache %s%s [%lld,%d] %d\n",
> +		       procid, opno, f.path, st, (long long)off,
> +		       (int)iov.iov_len, e);
> +	free_pathname(&f);
> +	close(fd);
> +}
> +
>  char *
>  xattr_flag_to_string(int flag)
>  {
> -- 
> 2.47.1
> 
> 

  reply	other threads:[~2025-01-07 17:31 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-07 16:05 [PATCHSET v2 0/2] Add RWF_DONTCACHE support Jens Axboe
2025-01-07 16:05 ` [PATCH 1/2] fsstress: add support for RWF_DONTCACHE Jens Axboe
2025-01-07 17:31   ` Darrick J. Wong [this message]
2025-01-07 16:05 ` [PATCH 2/2] fsx: " Jens Axboe
2025-01-07 18:19   ` Darrick J. Wong
2025-01-07 18:24     ` Jens Axboe
2025-01-07 23:22       ` Darrick J. Wong
2025-01-08  0:00         ` Jens Axboe
  -- strict thread matches above, loose matches on Subject: below --
2025-01-06 17:48 [PATCHSET 0/2] Add RWF_DONTCACHE support Jens Axboe
2025-01-06 17:48 ` [PATCH 1/2] fsstress: add support for RWF_DONTCACHE Jens Axboe
2025-01-07  2:11   ` Darrick J. Wong
2025-01-07  2:16     ` Jens Axboe
2025-01-07 17:30       ` Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250107173135.GR6160@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=fstests@vger.kernel.org \
    --cc=zlang@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox