From: "Darrick J. Wong" <djwong@kernel.org>
To: Zorro Lang <zlang@redhat.com>
Cc: hch@lst.de, fstests@vger.kernel.org, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 1/2] misc: privatize the FIEXCHANGE ioctl for now
Date: Thu, 16 Nov 2023 08:35:05 -0800 [thread overview]
Message-ID: <20231116163505.GE36211@frogsfrogsfrogs> (raw)
In-Reply-To: <20231116151408.rbs4skzefu4zbjag@dell-per750-06-vm-08.rhts.eng.pek2.redhat.com>
On Thu, Nov 16, 2023 at 11:14:08PM +0800, Zorro Lang wrote:
> On Wed, Nov 08, 2023 at 01:45:26PM -0800, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > I'm abandoning (for now) efforts to bring atomic file content exchanges
> > to the VFS. The goal here is to reduce friction in getting online fsck
> > merged, so Dave and I want to take this back to being a private XFS
> > ioctl so we can explore with it for a while before committing it to the
> > stable KABI.
> >
> > Shift all the existing FIEXCHANGE usage to XFS_IOC_EXCHANGE_RANGE, and
> > try to pick it up from xfs_fs_staging.h if the system xfslibs-dev
> > package has such an animal.
> >
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > ---
>
> Hi Darrick,
>
> Could you please rebase this patchset onto latest fstests for-next branch?
> I can't merge it onto for-next or master branch, always hit:
> $ git am -s ./20231108_djwong_fstests_fiexchange_is_now_an_xfs_ioctl.mbx
> Applying: misc: privatize the FIEXCHANGE ioctl for now
> error: patch failed: configure.ac:70
> error: configure.ac: patch does not apply
> error: patch failed: include/builddefs.in:72
> error: include/builddefs.in: patch does not apply
> error: patch failed: m4/package_libcdev.m4:155
> error: m4/package_libcdev.m4: patch does not apply
> error: patch failed: src/Makefile:98
> error: src/Makefile: patch does not apply
> Patch failed at 0001 misc: privatize the FIEXCHANGE ioctl for now
>
> Can you rebase this patchset onto latest for-next branch, better to after:
>
> [PATCH 1/1] generic: test reads racing with slow reflink operations
I'll ... try to figure out what the FIEXCHANGE patch is tripping over.
If I figure it out I'll send you a pull request; if not, I'll reply to
this thread.
> I've merged it.
>
> And of course, you please keep the RVB from Christoph Hellwig :)
Will do.
--D
> Thanks,
> Zorro
>
>
> > configure.ac | 2 +-
> > doc/group-names.txt | 2 +-
> > include/builddefs.in | 2 +-
> > ltp/Makefile | 4 ++--
> > ltp/fsstress.c | 10 +++++-----
> > ltp/fsx.c | 20 ++++++++++----------
> > m4/package_libcdev.m4 | 19 -------------------
> > m4/package_xfslibs.m4 | 14 ++++++++++++++
> > src/Makefile | 4 ++++
> > src/fiexchange.h | 44 ++++++++++++++++++++++----------------------
> > src/global.h | 4 +---
> > src/vfs/Makefile | 4 ++++
> > tests/generic/724 | 2 +-
> > tests/xfs/122.out | 1 +
> > tests/xfs/791 | 2 +-
> > 15 files changed, 68 insertions(+), 66 deletions(-)
> >
> >
> > diff --git a/configure.ac b/configure.ac
> > index 7333045330..b22fc52bff 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -70,7 +70,7 @@ AC_HAVE_SEEK_DATA
> > AC_HAVE_BMV_OF_SHARED
> > AC_HAVE_NFTW
> > AC_HAVE_RLIMIT_NOFILE
> > -AC_HAVE_FIEXCHANGE
> > +AC_HAVE_XFS_IOC_EXCHANGE_RANGE
> > AC_HAVE_FICLONE
> >
> > AC_CHECK_FUNCS([renameat2])
> > diff --git a/doc/group-names.txt b/doc/group-names.txt
> > index c3dcca3755..fec6bf71ab 100644
> > --- a/doc/group-names.txt
> > +++ b/doc/group-names.txt
> > @@ -52,7 +52,7 @@ enospc ENOSPC error reporting
> > exportfs file handles
> > fiemap fiemap ioctl
> > filestreams XFS filestreams allocator
> > -fiexchange FIEXCHANGE_RANGE ioctl
> > +fiexchange XFS_IOC_EXCHANGE_RANGE ioctl
> > freeze filesystem freeze tests
> > fsck general fsck tests
> > fsmap FS_IOC_GETFSMAP ioctl
> > diff --git a/include/builddefs.in b/include/builddefs.in
> > index 446350d5fc..ce95fe7d4b 100644
> > --- a/include/builddefs.in
> > +++ b/include/builddefs.in
> > @@ -72,7 +72,7 @@ HAVE_SEEK_DATA = @have_seek_data@
> > HAVE_NFTW = @have_nftw@
> > HAVE_BMV_OF_SHARED = @have_bmv_of_shared@
> > HAVE_RLIMIT_NOFILE = @have_rlimit_nofile@
> > -HAVE_FIEXCHANGE = @have_fiexchange@
> > +HAVE_XFS_IOC_EXCHANGE_RANGE = @have_xfs_ioc_exchange_range@
> > HAVE_FICLONE = @have_ficlone@
> >
> > GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall
> > diff --git a/ltp/Makefile b/ltp/Makefile
> > index c2b70d896e..c0b2824076 100644
> > --- a/ltp/Makefile
> > +++ b/ltp/Makefile
> > @@ -36,8 +36,8 @@ ifeq ($(HAVE_COPY_FILE_RANGE),yes)
> > LCFLAGS += -DHAVE_COPY_FILE_RANGE
> > endif
> >
> > -ifeq ($(HAVE_FIEXCHANGE),yes)
> > -LCFLAGS += -DHAVE_FIEXCHANGE
> > +ifeq ($(HAVE_XFS_IOC_EXCHANGE_RANGE),yes)
> > +LCFLAGS += -DHAVE_XFS_IOC_EXCHANGE_RANGE
> > endif
> >
> > default: depend $(TARGETS)
> > diff --git a/ltp/fsstress.c b/ltp/fsstress.c
> > index abe2874253..2681ed2b08 100644
> > --- a/ltp/fsstress.c
> > +++ b/ltp/fsstress.c
> > @@ -2592,8 +2592,8 @@ xchgrange_f(
> > opnum_t opno,
> > long r)
> > {
> > -#ifdef FIEXCHANGE_RANGE
> > - struct file_xchg_range fxr = { 0 };
> > +#ifdef XFS_IOC_EXCHANGE_RANGE
> > + struct xfs_exch_range fxr = { 0 };
> > static __u64 swap_flags = 0;
> > struct pathname fpath1;
> > struct pathname fpath2;
> > @@ -2721,10 +2721,10 @@ xchgrange_f(
> > fxr.flags = swap_flags;
> >
> > retry:
> > - ret = ioctl(fd2, FIEXCHANGE_RANGE, &fxr);
> > + ret = ioctl(fd2, XFS_IOC_EXCHANGE_RANGE, &fxr);
> > e = ret < 0 ? errno : 0;
> > - if (e == EOPNOTSUPP && !(swap_flags & FILE_XCHG_RANGE_NONATOMIC)) {
> > - swap_flags = FILE_XCHG_RANGE_NONATOMIC;
> > + if (e == EOPNOTSUPP && !(swap_flags & XFS_EXCH_RANGE_NONATOMIC)) {
> > + swap_flags = XFS_EXCH_RANGE_NONATOMIC;
> > fxr.flags |= swap_flags;
> > goto retry;
> > }
> > diff --git a/ltp/fsx.c b/ltp/fsx.c
> > index a30e2a8dbc..777ba0de5d 100644
> > --- a/ltp/fsx.c
> > +++ b/ltp/fsx.c
> > @@ -1389,27 +1389,27 @@ do_insert_range(unsigned offset, unsigned length)
> > }
> > #endif
> >
> > -#ifdef FIEXCHANGE_RANGE
> > +#ifdef XFS_IOC_EXCHANGE_RANGE
> > static __u64 swap_flags = 0;
> >
> > int
> > test_xchg_range(void)
> > {
> > - struct file_xchg_range fsr = {
> > + struct xfs_exch_range fsr = {
> > .file1_fd = fd,
> > - .flags = FILE_XCHG_RANGE_DRY_RUN | swap_flags,
> > + .flags = XFS_EXCH_RANGE_DRY_RUN | swap_flags,
> > };
> > int ret, e;
> >
> > retry:
> > - ret = ioctl(fd, FIEXCHANGE_RANGE, &fsr);
> > + ret = ioctl(fd, XFS_IOC_EXCHANGE_RANGE, &fsr);
> > e = ret < 0 ? errno : 0;
> > - if (e == EOPNOTSUPP && !(swap_flags & FILE_XCHG_RANGE_NONATOMIC)) {
> > + if (e == EOPNOTSUPP && !(swap_flags & XFS_EXCH_RANGE_NONATOMIC)) {
> > /*
> > * If the call fails with atomic mode, try again with non
> > * atomic mode.
> > */
> > - swap_flags = FILE_XCHG_RANGE_NONATOMIC;
> > + swap_flags = XFS_EXCH_RANGE_NONATOMIC;
> > fsr.flags |= swap_flags;
> > goto retry;
> > }
> > @@ -1427,7 +1427,7 @@ test_xchg_range(void)
> > void
> > do_xchg_range(unsigned offset, unsigned length, unsigned dest)
> > {
> > - struct file_xchg_range fsr = {
> > + struct xfs_exch_range fsr = {
> > .file1_fd = fd,
> > .file1_offset = offset,
> > .file2_offset = dest,
> > @@ -1470,10 +1470,10 @@ do_xchg_range(unsigned offset, unsigned length, unsigned dest)
> > testcalls, offset, offset+length, length, dest);
> > }
> >
> > - if (ioctl(fd, FIEXCHANGE_RANGE, &fsr) == -1) {
> > + if (ioctl(fd, XFS_IOC_EXCHANGE_RANGE, &fsr) == -1) {
> > prt("exchange range: 0x%x to 0x%x at 0x%x\n", offset,
> > offset + length, dest);
> > - prterr("do_xchg_range: FIEXCHANGE_RANGE");
> > + prterr("do_xchg_range: XFS_IOC_EXCHANGE_RANGE");
> > report_failure(161);
> > goto out_free;
> > }
> > @@ -2452,7 +2452,7 @@ usage(void)
> > #ifdef HAVE_COPY_FILE_RANGE
> > " -E: Do not use copy range calls\n"
> > #endif
> > -#ifdef FIEXCHANGE_RANGE
> > +#ifdef XFS_IOC_EXCHANGE_RANGE
> > " -0: Do not use exchange range calls\n"
> > #endif
> > " -K: Do not use keep size\n\
> > diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4
> > index 91eb64db21..d5d88b8e44 100644
> > --- a/m4/package_libcdev.m4
> > +++ b/m4/package_libcdev.m4
> > @@ -155,25 +155,6 @@ AC_DEFUN([AC_HAVE_RLIMIT_NOFILE],
> > AC_SUBST(have_rlimit_nofile)
> > ])
> >
> > -#
> > -# Check if we have a FIEXCHANGE_RANGE ioctl (Linux)
> > -#
> > -AC_DEFUN([AC_HAVE_FIEXCHANGE],
> > - [ AC_MSG_CHECKING([for FIEXCHANGE_RANGE])
> > - AC_LINK_IFELSE([AC_LANG_PROGRAM([[
> > -#define _GNU_SOURCE
> > -#include <sys/syscall.h>
> > -#include <sys/ioctl.h>
> > -#include <unistd.h>
> > -#include <linux/fs.h>
> > -#include <linux/fiexchange.h>
> > - ]], [[
> > - struct file_xchg_range fxr;
> > - ioctl(-1, FIEXCHANGE_RANGE, &fxr);
> > - ]])],[have_fiexchange=yes
> > - AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
> > - AC_SUBST(have_fiexchange)
> > -
> > # Check if we have FICLONE
> > AC_DEFUN([AC_HAVE_FICLONE],
> > [ AC_MSG_CHECKING([for FICLONE])
> > diff --git a/m4/package_xfslibs.m4 b/m4/package_xfslibs.m4
> > index 8ef58cc064..1549360df6 100644
> > --- a/m4/package_xfslibs.m4
> > +++ b/m4/package_xfslibs.m4
> > @@ -119,3 +119,17 @@ AC_DEFUN([AC_HAVE_BMV_OF_SHARED],
> > AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
> > AC_SUBST(have_bmv_of_shared)
> > ])
> > +
> > +# Check if we have XFS_IOC_EXCHANGE_RANGE
> > +AC_DEFUN([AC_HAVE_XFS_IOC_EXCHANGE_RANGE],
> > + [ AC_MSG_CHECKING([for XFS_IOC_EXCHANGE_RANGE])
> > + AC_LINK_IFELSE([AC_LANG_PROGRAM([[
> > +#define _GNU_SOURCE
> > +#include <xfs/xfs.h>
> > + ]], [[
> > + struct xfs_exch_range obj;
> > + ioctl(-1, XFS_IOC_EXCHANGE_RANGE, &obj);
> > + ]])],[have_xfs_ioc_exchange_range=yes
> > + AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
> > + AC_SUBST(have_xfs_ioc_exchange_range)
> > + ])
> > diff --git a/src/Makefile b/src/Makefile
> > index 49dd2f6c1e..8160a0e8ec 100644
> > --- a/src/Makefile
> > +++ b/src/Makefile
> > @@ -98,6 +98,10 @@ ifeq ($(HAVE_FICLONE),yes)
> > TARGETS += t_reflink_read_race
> > endif
> >
> > +ifeq ($(HAVE_XFS_IOC_EXCHANGE_RANGE),yes)
> > +LCFLAGS += -DHAVE_XFS_IOC_EXCHANGE_RANGE
> > +endif
> > +
> > CFILES = $(TARGETS:=.c)
> > LDIRT = $(TARGETS) fssum
> >
> > diff --git a/src/fiexchange.h b/src/fiexchange.h
> > index 29b3ac0ff5..6a3ae8964d 100644
> > --- a/src/fiexchange.h
> > +++ b/src/fiexchange.h
> > @@ -16,13 +16,13 @@
> > * called against (which we'll call file2). Filesystems must be able to
> > * restart and complete the operation even after the system goes down.
> > */
> > -struct file_xchg_range {
> > +struct xfs_exch_range {
> > __s64 file1_fd;
> > __s64 file1_offset; /* file1 offset, bytes */
> > __s64 file2_offset; /* file2 offset, bytes */
> > __s64 length; /* bytes to exchange */
> >
> > - __u64 flags; /* see FILE_XCHG_RANGE_* below */
> > + __u64 flags; /* see XFS_EXCH_RANGE_* below */
> >
> > /* file2 metadata for optional freshness checks */
> > __s64 file2_ino; /* inode number */
> > @@ -38,39 +38,39 @@ struct file_xchg_range {
> > * Atomic exchange operations are not required. This relaxes the requirement
> > * that the filesystem must be able to complete the operation after a crash.
> > */
> > -#define FILE_XCHG_RANGE_NONATOMIC (1 << 0)
> > +#define XFS_EXCH_RANGE_NONATOMIC (1 << 0)
> >
> > /*
> > * Check that file2's inode number, mtime, and ctime against the values
> > * provided, and return -EBUSY if there isn't an exact match.
> > */
> > -#define FILE_XCHG_RANGE_FILE2_FRESH (1 << 1)
> > +#define XFS_EXCH_RANGE_FILE2_FRESH (1 << 1)
> >
> > /*
> > * Check that the file1's length is equal to file1_offset + length, and that
> > * file2's length is equal to file2_offset + length. Returns -EDOM if there
> > * isn't an exact match.
> > */
> > -#define FILE_XCHG_RANGE_FULL_FILES (1 << 2)
> > +#define XFS_EXCH_RANGE_FULL_FILES (1 << 2)
> >
> > /*
> > * Exchange file data all the way to the ends of both files, and then exchange
> > * the file sizes. This flag can be used to replace a file's contents with a
> > * different amount of data. length will be ignored.
> > */
> > -#define FILE_XCHG_RANGE_TO_EOF (1 << 3)
> > +#define XFS_EXCH_RANGE_TO_EOF (1 << 3)
> >
> > /* Flush all changes in file data and file metadata to disk before returning. */
> > -#define FILE_XCHG_RANGE_FSYNC (1 << 4)
> > +#define XFS_EXCH_RANGE_FSYNC (1 << 4)
> >
> > /* Dry run; do all the parameter verification but do not change anything. */
> > -#define FILE_XCHG_RANGE_DRY_RUN (1 << 5)
> > +#define XFS_EXCH_RANGE_DRY_RUN (1 << 5)
> >
> > /*
> > - * Do not exchange any part of the range where file1's mapping is a hole. This
> > - * can be used to emulate scatter-gather atomic writes with a temp file.
> > + * Only exchange ranges where file1's range maps to a written extent. This can
> > + * be used to emulate scatter-gather atomic writes with a temp file.
> > */
> > -#define FILE_XCHG_RANGE_SKIP_FILE1_HOLES (1 << 6)
> > +#define XFS_EXCH_RANGE_FILE1_WRITTEN (1 << 6)
> >
> > /*
> > * Commit the contents of file1 into file2 if file2 has the same inode number,
> > @@ -83,19 +83,19 @@ struct file_xchg_range {
> > * commit is complete.
> > *
> > * This flag should not be combined with NONATOMIC. It can be combined with
> > - * SKIP_FILE1_HOLES.
> > + * FILE1_WRITTEN.
> > */
> > -#define FILE_XCHG_RANGE_COMMIT (FILE_XCHG_RANGE_FILE2_FRESH | \
> > - FILE_XCHG_RANGE_FSYNC)
> > +#define XFS_EXCH_RANGE_COMMIT (XFS_EXCH_RANGE_FILE2_FRESH | \
> > + XFS_EXCH_RANGE_FSYNC)
> >
> > -#define FILE_XCHG_RANGE_ALL_FLAGS (FILE_XCHG_RANGE_NONATOMIC | \
> > - FILE_XCHG_RANGE_FILE2_FRESH | \
> > - FILE_XCHG_RANGE_FULL_FILES | \
> > - FILE_XCHG_RANGE_TO_EOF | \
> > - FILE_XCHG_RANGE_FSYNC | \
> > - FILE_XCHG_RANGE_DRY_RUN | \
> > - FILE_XCHG_RANGE_SKIP_FILE1_HOLES)
> > +#define XFS_EXCH_RANGE_ALL_FLAGS (XFS_EXCH_RANGE_NONATOMIC | \
> > + XFS_EXCH_RANGE_FILE2_FRESH | \
> > + XFS_EXCH_RANGE_FULL_FILES | \
> > + XFS_EXCH_RANGE_TO_EOF | \
> > + XFS_EXCH_RANGE_FSYNC | \
> > + XFS_EXCH_RANGE_DRY_RUN | \
> > + XFS_EXCH_RANGE_FILE1_WRITTEN)
> >
> > -#define FIEXCHANGE_RANGE _IOWR('X', 129, struct file_xchg_range)
> > +#define XFS_IOC_EXCHANGE_RANGE _IOWR('X', 129, struct xfs_exch_range)
> >
> > #endif /* _LINUX_FIEXCHANGE_H */
> > diff --git a/src/global.h b/src/global.h
> > index 49570ef117..4f92308d6c 100644
> > --- a/src/global.h
> > +++ b/src/global.h
> > @@ -171,9 +171,7 @@
> > #include <sys/mman.h>
> > #endif
> >
> > -#ifdef HAVE_FIEXCHANGE
> > -# include <linux/fiexchange.h>
> > -#else
> > +#ifndef HAVE_XFS_IOC_EXCHANGE_RANGE
> > # include "fiexchange.h"
> > #endif
> >
> > diff --git a/src/vfs/Makefile b/src/vfs/Makefile
> > index 4841da1286..868540f578 100644
> > --- a/src/vfs/Makefile
> > +++ b/src/vfs/Makefile
> > @@ -19,6 +19,10 @@ ifeq ($(HAVE_URING), true)
> > LLDLIBS += -luring
> > endif
> >
> > +ifeq ($(HAVE_XFS_IOC_EXCHANGE_RANGE),yes)
> > +LCFLAGS += -DHAVE_XFS_IOC_EXCHANGE_RANGE
> > +endif
> > +
> > default: depend $(TARGETS)
> >
> > depend: .dep
> > diff --git a/tests/generic/724 b/tests/generic/724
> > index 8d7dc4e12a..67e0dba446 100755
> > --- a/tests/generic/724
> > +++ b/tests/generic/724
> > @@ -5,7 +5,7 @@
> > # FS QA Test No. 724
> > #
> > # Test scatter-gather atomic file writes. We create a temporary file, write
> > -# sparsely to it, then use FILE_SWAP_RANGE_SKIP_FILE1_HOLES flag to swap
> > +# sparsely to it, then use XFS_EXCH_RANGE_FILE1_WRITTEN flag to swap
> > # atomicallly only the ranges that we wrote.
> >
> > . ./common/preamble
> > diff --git a/tests/xfs/122.out b/tests/xfs/122.out
> > index 21549db7fd..89f7b735b0 100644
> > --- a/tests/xfs/122.out
> > +++ b/tests/xfs/122.out
> > @@ -90,6 +90,7 @@ sizeof(struct xfs_disk_dquot) = 104
> > sizeof(struct xfs_dqblk) = 136
> > sizeof(struct xfs_dsb) = 264
> > sizeof(struct xfs_dsymlink_hdr) = 56
> > +sizeof(struct xfs_exch_range) = 120
> > sizeof(struct xfs_extent_data) = 24
> > sizeof(struct xfs_extent_data_info) = 32
> > sizeof(struct xfs_fs_eofblocks) = 128
> > diff --git a/tests/xfs/791 b/tests/xfs/791
> > index d82314ee08..4944c1517c 100755
> > --- a/tests/xfs/791
> > +++ b/tests/xfs/791
> > @@ -5,7 +5,7 @@
> > # FS QA Test No. 791
> > #
> > # Test scatter-gather atomic file writes. We create a temporary file, write
> > -# sparsely to it, then use FILE_SWAP_RANGE_SKIP_FILE1_HOLES flag to swap
> > +# sparsely to it, then use XFS_EXCH_RANGE_FILE1_WRITTEN flag to swap
> > # atomicallly only the ranges that we wrote. Inject an error so that we can
> > # test that log recovery finishes the swap.
> >
> >
>
next prev parent reply other threads:[~2023-11-16 16:35 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-08 21:45 [PATCHSET v27.0 0/2] fstests: FIEXCHANGE is now an XFS ioctl Darrick J. Wong
2023-11-08 21:45 ` [PATCH 1/2] misc: privatize the FIEXCHANGE ioctl for now Darrick J. Wong
2023-11-16 15:14 ` Zorro Lang
2023-11-16 16:35 ` Darrick J. Wong [this message]
2023-11-08 21:45 ` [PATCH 2/2] misc: update xfs_io swapext usage Darrick J. Wong
2023-11-09 5:21 ` [PATCHSET v27.0 0/2] fstests: FIEXCHANGE is now an XFS ioctl Christoph Hellwig
2023-11-10 4:48 ` Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2023-11-16 17:30 [PATCHSET v27.1 " Darrick J. Wong
2023-11-16 17:30 ` [PATCH 1/2] misc: privatize the FIEXCHANGE ioctl for now 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=20231116163505.GE36211@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=fstests@vger.kernel.org \
--cc=hch@lst.de \
--cc=linux-xfs@vger.kernel.org \
--cc=zlang@redhat.com \
/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