From: "Darrick J. Wong" <djwong@kernel.org>
To: Brian Foster <bfoster@redhat.com>
Cc: fstests@vger.kernel.org
Subject: Re: [PATCH 1/2] fsx: support unshare range fallocate mode
Date: Thu, 26 Sep 2024 07:48:02 -0700 [thread overview]
Message-ID: <20240926144802.GB21840@frogsfrogsfrogs> (raw)
In-Reply-To: <20240926144147.106685-2-bfoster@redhat.com>
On Thu, Sep 26, 2024 at 10:41:46AM -0400, Brian Foster wrote:
> The fallocate unshare mode flag modifies traditional preallocate
> mode to unshare any shared extents backing the target range. Without
> the unshare flag, preallocate mode simply assures that blocks are
> physically allocated, regardless of whether they might be shared.
> Unshare mode behaves the same as preallocate mode outside of the
> shared extent case.
>
> Since unshare is fundamentally a modifier to preallocate mode,
> enable it via an operation flag. Similar to keep size mode, select
> it randomly for fallocate operations and track it via a flag and
> string combination for operation logging and replay.
>
> Unshare is mainly used for filesystems that support reflink, but the
> operation is equivalent to preallocate mode for non-shared ranges,
> so enable it by default. Filesystems that do not support the
> fallocate flag (such as those that might not support reflink) will
> fail the test operation and disable unshare calls at runtime. Also
> provide a new command line option to explicitly disable unshare
> calls.
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> ---
> ltp/fsx.c | 67 ++++++++++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 51 insertions(+), 16 deletions(-)
>
> diff --git a/ltp/fsx.c b/ltp/fsx.c
> index 1ba1bf65..677f8c9f 100644
> --- a/ltp/fsx.c
> +++ b/ltp/fsx.c
> @@ -45,9 +45,14 @@
>
> #define NUMPRINTCOLUMNS 32 /* # columns of data to print on each line */
>
> -/* Operation flags */
> -
> -enum opflags { FL_NONE = 0, FL_SKIPPED = 1, FL_CLOSE_OPEN = 2, FL_KEEP_SIZE = 4 };
> +/* Operation flags (bitmask) */
> +enum opflags {
> + FL_NONE = 0,
> + FL_SKIPPED = 1,
> + FL_CLOSE_OPEN = 2,
> + FL_KEEP_SIZE = 4,
> + FL_UNSHARE = 8
> +};
>
> /*
> * A log entry is an operation and a bunch of arguments.
> @@ -167,6 +172,7 @@ int seed = 1; /* -S flag */
> int mapped_writes = 1; /* -W flag disables */
> int fallocate_calls = 1; /* -F flag disables */
> int keep_size_calls = 1; /* -K flag disables */
> +int unshare_range_calls = 1; /* -u flag disables */
Broken indentation (you used tab, existing code uses space).
With that fixed, this look ok to me
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> int punch_hole_calls = 1; /* -H flag disables */
> int zero_range_calls = 1; /* -z flag disables */
> int collapse_range_calls = 1; /* -C flag disables */
> @@ -543,6 +549,8 @@ logdump(void)
> fprintf(logopsf, " keep_size");
> if (lp->flags & FL_CLOSE_OPEN)
> fprintf(logopsf, " close_open");
> + if (lp->flags & FL_UNSHARE)
> + fprintf(logopsf, " unshare");
> if (overlap)
> fprintf(logopsf, " *");
> fprintf(logopsf, "\n");
> @@ -1879,15 +1887,27 @@ do_copy_range(unsigned offset, unsigned length, unsigned dest)
> #ifdef HAVE_LINUX_FALLOC_H
> /* fallocate is basically a no-op unless extending, then a lot like a truncate */
> void
> -do_preallocate(unsigned offset, unsigned length, int keep_size)
> +do_preallocate(unsigned offset, unsigned length, int keep_size, int unshare)
> {
> unsigned end_offset;
> + enum opflags opflags = FL_NONE;
> + int mode = 0;
> +
> + if (keep_size) {
> + opflags |= FL_KEEP_SIZE;
> + mode |= FALLOC_FL_KEEP_SIZE;
> + }
> +#ifdef FALLOC_FL_UNSHARE_RANGE
> + if (unshare) {
> + opflags |= FL_UNSHARE;
> + mode |= FALLOC_FL_UNSHARE_RANGE;
> + }
> +#endif
>
> if (length == 0) {
> if (!quiet && testcalls > simulatedopcount)
> prt("skipping zero length fallocate\n");
> - log4(OP_FALLOCATE, offset, length, FL_SKIPPED |
> - (keep_size ? FL_KEEP_SIZE : FL_NONE));
> + log4(OP_FALLOCATE, offset, length, FL_SKIPPED | opflags);
> return;
> }
>
> @@ -1905,8 +1925,7 @@ do_preallocate(unsigned offset, unsigned length, int keep_size)
> * 1: extending prealloc
> * 2: interior prealloc
> */
> - log4(OP_FALLOCATE, offset, length,
> - keep_size ? FL_KEEP_SIZE : FL_NONE);
> + log4(OP_FALLOCATE, offset, length, opflags);
>
> if (end_offset > file_size) {
> memset(good_buf + file_size, '\0', end_offset - file_size);
> @@ -1921,7 +1940,7 @@ do_preallocate(unsigned offset, unsigned length, int keep_size)
> end_offset <= monitorend)))
> prt("%lld falloc\tfrom 0x%x to 0x%x (0x%x bytes)\n", testcalls,
> offset, offset + length, length);
> - if (fallocate(fd, keep_size ? FALLOC_FL_KEEP_SIZE : 0, (loff_t)offset, (loff_t)length) == -1) {
> + if (fallocate(fd, mode, (loff_t)offset, (loff_t)length) == -1) {
> prt("fallocate: 0x%x to 0x%x\n", offset, offset + length);
> prterr("do_preallocate: fallocate");
> report_failure(161);
> @@ -1929,7 +1948,7 @@ do_preallocate(unsigned offset, unsigned length, int keep_size)
> }
> #else
> void
> -do_preallocate(unsigned offset, unsigned length, int keep_size)
> +do_preallocate(unsigned offset, unsigned length, int keep_size, int unshare)
> {
> return;
> }
> @@ -2095,6 +2114,8 @@ read_op(struct log_entry *log_entry)
> log_entry->flags |= FL_KEEP_SIZE;
> else if (strcmp(str, "close_open") == 0)
> log_entry->flags |= FL_CLOSE_OPEN;
> + else if (strcmp(str, "unshare") == 0)
> + log_entry->flags |= FL_UNSHARE;
> else if (strcmp(str, "*") == 0)
> ; /* overlap marker; ignore */
> else
> @@ -2161,6 +2182,7 @@ test(void)
> unsigned long rv;
> unsigned long op;
> int keep_size = 0;
> + int unshare = 0;
>
> if (simulatedopcount > 0 && testcalls == simulatedopcount)
> writefileimage();
> @@ -2190,6 +2212,7 @@ test(void)
> offset2 = log_entry.args[2];
> closeopen = !!(log_entry.flags & FL_CLOSE_OPEN);
> keep_size = !!(log_entry.flags & FL_KEEP_SIZE);
> + unshare = !!(log_entry.flags & FL_UNSHARE);
> goto have_op;
> }
> return 0;
> @@ -2219,8 +2242,12 @@ test(void)
> size = random() % maxfilelen;
> break;
> case OP_FALLOCATE:
> - if (fallocate_calls && size && keep_size_calls)
> - keep_size = random() % 2;
> + if (fallocate_calls && size) {
> + if (keep_size_calls)
> + keep_size = random() % 2;
> + if (unshare_range_calls)
> + unshare = random() % 2;
> + }
> break;
> case OP_ZERO_RANGE:
> if (zero_range_calls && size && keep_size_calls)
> @@ -2334,7 +2361,7 @@ have_op:
>
> case OP_FALLOCATE:
> TRIM_OFF_LEN(offset, size, maxfilelen);
> - do_preallocate(offset, size, keep_size);
> + do_preallocate(offset, size, keep_size, unshare);
> break;
>
> case OP_PUNCH_HOLE:
> @@ -2468,8 +2495,11 @@ usage(void)
> -q: quieter operation\n\
> -r readbdy: 4096 would make reads page aligned (default 1)\n\
> -s style: 1 gives smaller truncates (default 0)\n\
> - -t truncbdy: 4096 would make truncates page aligned (default 1)\n\
> - -w writebdy: 4096 would make writes page aligned (default 1)\n\
> + -t truncbdy: 4096 would make truncates page aligned (default 1)\n"
> +#ifdef FALLOC_FL_UNSHARE_RANGE
> +" -u Do not use unshare range\n"
> +#endif
> +" -w writebdy: 4096 would make writes page aligned (default 1)\n\
> -x: preallocate file space before starting, XFS only\n\
> -y: synchronize changes to a file\n"
>
> @@ -2853,7 +2883,7 @@ main(int argc, char **argv)
> setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */
>
> while ((ch = getopt_long(argc, argv,
> - "0b:c:de:fg:i:j:kl:m:no:p:qr:s:t:w:xyABD:EFJKHzCILN:OP:RS:UWXZ",
> + "0b:c:de:fg:i:j:kl:m:no:p:qr:s:t:uw:xyABD:EFJKHzCILN:OP:RS:UWXZ",
> longopts, NULL)) != EOF)
> switch (ch) {
> case 'b':
> @@ -2952,6 +2982,9 @@ main(int argc, char **argv)
> if (truncbdy <= 0)
> usage();
> break;
> + case 'u':
> + unshare_range_calls = 0;
> + break;
> case 'w':
> writebdy = getnum(optarg, &endp);
> if (writebdy <= 0)
> @@ -3242,6 +3275,8 @@ main(int argc, char **argv)
> fallocate_calls = test_fallocate(0);
> if (keep_size_calls)
> keep_size_calls = test_fallocate(FALLOC_FL_KEEP_SIZE);
> + if (unshare_range_calls)
> + unshare_range_calls = test_fallocate(FALLOC_FL_UNSHARE_RANGE);
> if (punch_hole_calls)
> punch_hole_calls = test_fallocate(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE);
> if (zero_range_calls)
> --
> 2.46.1
>
>
next prev parent reply other threads:[~2024-09-26 14:48 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-26 14:41 [PATCH 0/2] fsx: support unshare range fallocate mode Brian Foster
2024-09-26 14:41 ` [PATCH 1/2] " Brian Foster
2024-09-26 14:48 ` Darrick J. Wong [this message]
2024-09-26 15:53 ` Brian Foster
2024-09-27 3:40 ` Zorro Lang
2024-09-26 14:41 ` [PATCH 2/2] fsx: add missing fallocate flag ifdefs Brian Foster
2024-09-26 14:50 ` Darrick J. Wong
2024-09-26 15:55 ` Brian Foster
2024-09-27 5:42 ` Zorro Lang
2024-09-27 12:07 ` Brian Foster
2024-09-27 15:25 ` Darrick J. Wong
2024-09-27 18:34 ` Brian Foster
2024-09-28 8:03 ` Zorro Lang
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=20240926144802.GB21840@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=bfoster@redhat.com \
--cc=fstests@vger.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