From: Brian Foster <bfoster@redhat.com>
To: Christoph Hellwig <hch@lst.de>
Cc: linux-xfs@vger.kernel.org, "Darrick J . Wong" <darrick.wong@oracle.com>
Subject: Re: [PATCH 02/11] xfs: remove the io_type field from the writeback context and ioend
Date: Thu, 31 Jan 2019 13:10:06 -0500 [thread overview]
Message-ID: <20190131181005.GD36239@bfoster> (raw)
In-Reply-To: <20190131075524.4769-3-hch@lst.de>
On Thu, Jan 31, 2019 at 08:55:15AM +0100, Christoph Hellwig wrote:
> The io_type field contains what is basically a summary of information
> from the inode fork and the imap. But we can just as easily use that
> information directly, simplifying a few bits here and there and
> improving the trace points.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
Reviewed-by: Brian Foster <bfoster@redhat.com>
> fs/xfs/xfs_aops.c | 93 ++++++++++++++++++++------------------------
> fs/xfs/xfs_aops.h | 24 +-----------
> fs/xfs/xfs_iomap.c | 8 ++--
> fs/xfs/xfs_reflink.c | 2 +-
> fs/xfs/xfs_trace.h | 34 +++++++---------
> 5 files changed, 63 insertions(+), 98 deletions(-)
>
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 515532f45beb..a3fa60d1d2df 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -28,7 +28,7 @@
> */
> struct xfs_writepage_ctx {
> struct xfs_bmbt_irec imap;
> - unsigned int io_type;
> + int fork;
> unsigned int data_seq;
> unsigned int cow_seq;
> struct xfs_ioend *ioend;
> @@ -256,30 +256,20 @@ xfs_end_io(
> */
> error = blk_status_to_errno(ioend->io_bio->bi_status);
> if (unlikely(error)) {
> - switch (ioend->io_type) {
> - case XFS_IO_COW:
> + if (ioend->io_fork == XFS_COW_FORK)
> xfs_reflink_cancel_cow_range(ip, offset, size, true);
> - break;
> - }
> -
> goto done;
> }
>
> /*
> - * Success: commit the COW or unwritten blocks if needed.
> + * Success: commit the COW or unwritten blocks if needed.
> */
> - switch (ioend->io_type) {
> - case XFS_IO_COW:
> + if (ioend->io_fork == XFS_COW_FORK)
> error = xfs_reflink_end_cow(ip, offset, size);
> - break;
> - case XFS_IO_UNWRITTEN:
> - /* writeback should never update isize */
> + else if (ioend->io_state == XFS_EXT_UNWRITTEN)
> error = xfs_iomap_write_unwritten(ip, offset, size, false);
> - break;
> - default:
> + else
> ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_append_trans);
> - break;
> - }
>
> done:
> if (ioend->io_append_trans)
> @@ -294,7 +284,8 @@ xfs_end_bio(
> struct xfs_ioend *ioend = bio->bi_private;
> struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount;
>
> - if (ioend->io_type == XFS_IO_UNWRITTEN || ioend->io_type == XFS_IO_COW)
> + if (ioend->io_fork == XFS_COW_FORK ||
> + ioend->io_state == XFS_EXT_UNWRITTEN)
> queue_work(mp->m_unwritten_workqueue, &ioend->io_work);
> else if (ioend->io_append_trans)
> queue_work(mp->m_data_workqueue, &ioend->io_work);
> @@ -320,7 +311,7 @@ xfs_imap_valid(
> * covers the offset. Be careful to check this first because the caller
> * can revalidate a COW mapping without updating the data seqno.
> */
> - if (wpc->io_type == XFS_IO_COW)
> + if (wpc->fork == XFS_COW_FORK)
> return true;
>
> /*
> @@ -350,7 +341,6 @@ xfs_map_blocks(
> xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb;
> xfs_fileoff_t cow_fsb = NULLFILEOFF;
> struct xfs_bmbt_irec imap;
> - int whichfork = XFS_DATA_FORK;
> struct xfs_iext_cursor icur;
> int error = 0;
>
> @@ -400,6 +390,9 @@ xfs_map_blocks(
> if (cow_fsb != NULLFILEOFF && cow_fsb <= offset_fsb) {
> wpc->cow_seq = READ_ONCE(ip->i_cowfp->if_seq);
> xfs_iunlock(ip, XFS_ILOCK_SHARED);
> +
> + wpc->fork = XFS_COW_FORK;
> +
> /*
> * Truncate can race with writeback since writeback doesn't
> * take the iolock and truncate decreases the file size before
> @@ -412,11 +405,13 @@ xfs_map_blocks(
> * will kill the contents anyway.
> */
> if (offset > i_size_read(inode)) {
> - wpc->io_type = XFS_IO_HOLE;
> + wpc->imap.br_blockcount = end_fsb - offset_fsb;
> + wpc->imap.br_startoff = offset_fsb;
> + wpc->imap.br_startblock = HOLESTARTBLOCK;
> + wpc->imap.br_state = XFS_EXT_NORM;
> return 0;
> }
> - whichfork = XFS_COW_FORK;
> - wpc->io_type = XFS_IO_COW;
> +
> goto allocate_blocks;
> }
>
> @@ -439,12 +434,14 @@ xfs_map_blocks(
> wpc->data_seq = READ_ONCE(ip->i_df.if_seq);
> xfs_iunlock(ip, XFS_ILOCK_SHARED);
>
> + wpc->fork = XFS_DATA_FORK;
> +
> if (imap.br_startoff > offset_fsb) {
> /* landed in a hole or beyond EOF */
> imap.br_blockcount = imap.br_startoff - offset_fsb;
> imap.br_startoff = offset_fsb;
> imap.br_startblock = HOLESTARTBLOCK;
> - wpc->io_type = XFS_IO_HOLE;
> + imap.br_state = XFS_EXT_NORM;
> } else {
> /*
> * Truncate to the next COW extent if there is one. This is the
> @@ -456,31 +453,24 @@ xfs_map_blocks(
> cow_fsb < imap.br_startoff + imap.br_blockcount)
> imap.br_blockcount = cow_fsb - imap.br_startoff;
>
> - if (isnullstartblock(imap.br_startblock)) {
> - /* got a delalloc extent */
> - wpc->io_type = XFS_IO_DELALLOC;
> + /* got a delalloc extent? */
> + if (isnullstartblock(imap.br_startblock))
> goto allocate_blocks;
> - }
> -
> - if (imap.br_state == XFS_EXT_UNWRITTEN)
> - wpc->io_type = XFS_IO_UNWRITTEN;
> - else
> - wpc->io_type = XFS_IO_OVERWRITE;
> }
>
> wpc->imap = imap;
> - trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap);
> + trace_xfs_map_blocks_found(ip, offset, count, wpc->fork, &imap);
> return 0;
> allocate_blocks:
> - error = xfs_iomap_write_allocate(ip, whichfork, offset, &imap,
> - whichfork == XFS_COW_FORK ?
> + error = xfs_iomap_write_allocate(ip, wpc->fork, offset, &imap,
> + wpc->fork == XFS_COW_FORK ?
> &wpc->cow_seq : &wpc->data_seq);
> if (error)
> return error;
> - ASSERT(whichfork == XFS_COW_FORK || cow_fsb == NULLFILEOFF ||
> + ASSERT(wpc->fork == XFS_COW_FORK || cow_fsb == NULLFILEOFF ||
> imap.br_startoff + imap.br_blockcount <= cow_fsb);
> wpc->imap = imap;
> - trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap);
> + trace_xfs_map_blocks_alloc(ip, offset, count, wpc->fork, &imap);
> return 0;
> }
>
> @@ -505,7 +495,7 @@ xfs_submit_ioend(
> int status)
> {
> /* Convert CoW extents to regular */
> - if (!status && ioend->io_type == XFS_IO_COW) {
> + if (!status && ioend->io_fork == XFS_COW_FORK) {
> /*
> * Yuk. This can do memory allocation, but is not a
> * transactional operation so everything is done in GFP_KERNEL
> @@ -523,7 +513,8 @@ xfs_submit_ioend(
>
> /* Reserve log space if we might write beyond the on-disk inode size. */
> if (!status &&
> - ioend->io_type != XFS_IO_UNWRITTEN &&
> + (ioend->io_fork == XFS_COW_FORK ||
> + ioend->io_state != XFS_EXT_UNWRITTEN) &&
> xfs_ioend_is_append(ioend) &&
> !ioend->io_append_trans)
> status = xfs_setfilesize_trans_alloc(ioend);
> @@ -552,7 +543,8 @@ xfs_submit_ioend(
> static struct xfs_ioend *
> xfs_alloc_ioend(
> struct inode *inode,
> - unsigned int type,
> + int fork,
> + xfs_exntst_t state,
> xfs_off_t offset,
> struct block_device *bdev,
> sector_t sector)
> @@ -566,7 +558,8 @@ xfs_alloc_ioend(
>
> ioend = container_of(bio, struct xfs_ioend, io_inline_bio);
> INIT_LIST_HEAD(&ioend->io_list);
> - ioend->io_type = type;
> + ioend->io_fork = fork;
> + ioend->io_state = state;
> ioend->io_inode = inode;
> ioend->io_size = 0;
> ioend->io_offset = offset;
> @@ -627,13 +620,15 @@ xfs_add_to_ioend(
> sector = xfs_fsb_to_db(ip, wpc->imap.br_startblock) +
> ((offset - XFS_FSB_TO_B(mp, wpc->imap.br_startoff)) >> 9);
>
> - if (!wpc->ioend || wpc->io_type != wpc->ioend->io_type ||
> + if (!wpc->ioend ||
> + wpc->fork != wpc->ioend->io_fork ||
> + wpc->imap.br_state != wpc->ioend->io_state ||
> sector != bio_end_sector(wpc->ioend->io_bio) ||
> offset != wpc->ioend->io_offset + wpc->ioend->io_size) {
> if (wpc->ioend)
> list_add(&wpc->ioend->io_list, iolist);
> - wpc->ioend = xfs_alloc_ioend(inode, wpc->io_type, offset,
> - bdev, sector);
> + wpc->ioend = xfs_alloc_ioend(inode, wpc->fork,
> + wpc->imap.br_state, offset, bdev, sector);
> }
>
> if (!__bio_try_merge_page(wpc->ioend->io_bio, page, len, poff)) {
> @@ -742,7 +737,7 @@ xfs_writepage_map(
> error = xfs_map_blocks(wpc, inode, file_offset);
> if (error)
> break;
> - if (wpc->io_type == XFS_IO_HOLE)
> + if (wpc->imap.br_startblock == HOLESTARTBLOCK)
> continue;
> xfs_add_to_ioend(inode, file_offset, page, iop, wpc, wbc,
> &submit_list);
> @@ -937,9 +932,7 @@ xfs_vm_writepage(
> struct page *page,
> struct writeback_control *wbc)
> {
> - struct xfs_writepage_ctx wpc = {
> - .io_type = XFS_IO_HOLE,
> - };
> + struct xfs_writepage_ctx wpc = { };
> int ret;
>
> ret = xfs_do_writepage(page, wbc, &wpc);
> @@ -953,9 +946,7 @@ xfs_vm_writepages(
> struct address_space *mapping,
> struct writeback_control *wbc)
> {
> - struct xfs_writepage_ctx wpc = {
> - .io_type = XFS_IO_HOLE,
> - };
> + struct xfs_writepage_ctx wpc = { };
> int ret;
>
> xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED);
> diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
> index e5c23948a8ab..6c2615b83c5d 100644
> --- a/fs/xfs/xfs_aops.h
> +++ b/fs/xfs/xfs_aops.h
> @@ -8,33 +8,13 @@
>
> extern struct bio_set xfs_ioend_bioset;
>
> -/*
> - * Types of I/O for bmap clustering and I/O completion tracking.
> - *
> - * This enum is used in string mapping in xfs_trace.h; please keep the
> - * TRACE_DEFINE_ENUMs for it up to date.
> - */
> -enum {
> - XFS_IO_HOLE, /* covers region without any block allocation */
> - XFS_IO_DELALLOC, /* covers delalloc region */
> - XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */
> - XFS_IO_OVERWRITE, /* covers already allocated extent */
> - XFS_IO_COW, /* covers copy-on-write extent */
> -};
> -
> -#define XFS_IO_TYPES \
> - { XFS_IO_HOLE, "hole" }, \
> - { XFS_IO_DELALLOC, "delalloc" }, \
> - { XFS_IO_UNWRITTEN, "unwritten" }, \
> - { XFS_IO_OVERWRITE, "overwrite" }, \
> - { XFS_IO_COW, "CoW" }
> -
> /*
> * Structure for buffered I/O completions.
> */
> struct xfs_ioend {
> struct list_head io_list; /* next ioend in chain */
> - unsigned int io_type; /* delalloc / unwritten */
> + int io_fork; /* inode fork written back */
> + xfs_exntst_t io_state; /* extent state */
> struct inode *io_inode; /* file being written to */
> size_t io_size; /* size of the extent */
> xfs_off_t io_offset; /* offset in the file */
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 9849c3a5a435..b7c1b279057b 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -575,7 +575,7 @@ xfs_file_iomap_begin_delay(
> goto out_unlock;
> }
>
> - trace_xfs_iomap_found(ip, offset, count, 0, &got);
> + trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK, &got);
> goto done;
> }
>
> @@ -647,7 +647,7 @@ xfs_file_iomap_begin_delay(
> * them out if the write happens to fail.
> */
> iomap->flags |= IOMAP_F_NEW;
> - trace_xfs_iomap_alloc(ip, offset, count, 0, &got);
> + trace_xfs_iomap_alloc(ip, offset, count, XFS_DATA_FORK, &got);
> done:
> if (isnullstartblock(got.br_startblock))
> got.br_startblock = DELAYSTARTBLOCK;
> @@ -1082,7 +1082,7 @@ xfs_file_iomap_begin(
> return error;
>
> iomap->flags |= IOMAP_F_NEW;
> - trace_xfs_iomap_alloc(ip, offset, length, 0, &imap);
> + trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap);
>
> out_finish:
> if (xfs_ipincount(ip) && (ip->i_itemp->ili_fsync_fields
> @@ -1098,7 +1098,7 @@ xfs_file_iomap_begin(
> out_found:
> ASSERT(nimaps);
> xfs_iunlock(ip, lockmode);
> - trace_xfs_iomap_found(ip, offset, length, 0, &imap);
> + trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap);
> goto out_finish;
>
> out_unlock:
> diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
> index c5b4fa004ca4..2babc2cbe103 100644
> --- a/fs/xfs/xfs_reflink.c
> +++ b/fs/xfs/xfs_reflink.c
> @@ -1192,7 +1192,7 @@ xfs_reflink_remap_blocks(
> break;
> ASSERT(nimaps == 1);
>
> - trace_xfs_reflink_remap_imap(src, srcoff, len, XFS_IO_OVERWRITE,
> + trace_xfs_reflink_remap_imap(src, srcoff, len, XFS_DATA_FORK,
> &imap);
>
> /* Translate imap into the destination file. */
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 6fcc893dfc91..f75c6d380543 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -1218,23 +1218,17 @@ DEFINE_EVENT(xfs_readpage_class, name, \
> DEFINE_READPAGE_EVENT(xfs_vm_readpage);
> DEFINE_READPAGE_EVENT(xfs_vm_readpages);
>
> -TRACE_DEFINE_ENUM(XFS_IO_HOLE);
> -TRACE_DEFINE_ENUM(XFS_IO_DELALLOC);
> -TRACE_DEFINE_ENUM(XFS_IO_UNWRITTEN);
> -TRACE_DEFINE_ENUM(XFS_IO_OVERWRITE);
> -TRACE_DEFINE_ENUM(XFS_IO_COW);
> -
> DECLARE_EVENT_CLASS(xfs_imap_class,
> TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
> - int type, struct xfs_bmbt_irec *irec),
> - TP_ARGS(ip, offset, count, type, irec),
> + int whichfork, struct xfs_bmbt_irec *irec),
> + TP_ARGS(ip, offset, count, whichfork, irec),
> TP_STRUCT__entry(
> __field(dev_t, dev)
> __field(xfs_ino_t, ino)
> __field(loff_t, size)
> __field(loff_t, offset)
> __field(size_t, count)
> - __field(int, type)
> + __field(int, whichfork)
> __field(xfs_fileoff_t, startoff)
> __field(xfs_fsblock_t, startblock)
> __field(xfs_filblks_t, blockcount)
> @@ -1245,33 +1239,33 @@ DECLARE_EVENT_CLASS(xfs_imap_class,
> __entry->size = ip->i_d.di_size;
> __entry->offset = offset;
> __entry->count = count;
> - __entry->type = type;
> + __entry->whichfork = whichfork;
> __entry->startoff = irec ? irec->br_startoff : 0;
> __entry->startblock = irec ? irec->br_startblock : 0;
> __entry->blockcount = irec ? irec->br_blockcount : 0;
> ),
> TP_printk("dev %d:%d ino 0x%llx size 0x%llx offset 0x%llx count %zd "
> - "type %s startoff 0x%llx startblock %lld blockcount 0x%llx",
> + "fork %s startoff 0x%llx startblock %lld blockcount 0x%llx",
> MAJOR(__entry->dev), MINOR(__entry->dev),
> __entry->ino,
> __entry->size,
> __entry->offset,
> __entry->count,
> - __print_symbolic(__entry->type, XFS_IO_TYPES),
> + __entry->whichfork == XFS_COW_FORK ? "cow" : "data",
> __entry->startoff,
> (int64_t)__entry->startblock,
> __entry->blockcount)
> )
>
> -#define DEFINE_IOMAP_EVENT(name) \
> +#define DEFINE_IMAP_EVENT(name) \
> DEFINE_EVENT(xfs_imap_class, name, \
> TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \
> - int type, struct xfs_bmbt_irec *irec), \
> - TP_ARGS(ip, offset, count, type, irec))
> -DEFINE_IOMAP_EVENT(xfs_map_blocks_found);
> -DEFINE_IOMAP_EVENT(xfs_map_blocks_alloc);
> -DEFINE_IOMAP_EVENT(xfs_iomap_alloc);
> -DEFINE_IOMAP_EVENT(xfs_iomap_found);
> + int whichfork, struct xfs_bmbt_irec *irec), \
> + TP_ARGS(ip, offset, count, whichfork, irec))
> +DEFINE_IMAP_EVENT(xfs_map_blocks_found);
> +DEFINE_IMAP_EVENT(xfs_map_blocks_alloc);
> +DEFINE_IMAP_EVENT(xfs_iomap_alloc);
> +DEFINE_IMAP_EVENT(xfs_iomap_found);
>
> DECLARE_EVENT_CLASS(xfs_simple_io_class,
> TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count),
> @@ -3078,7 +3072,7 @@ DEFINE_EVENT(xfs_inode_irec_class, name, \
> DEFINE_INODE_EVENT(xfs_reflink_set_inode_flag);
> DEFINE_INODE_EVENT(xfs_reflink_unset_inode_flag);
> DEFINE_ITRUNC_EVENT(xfs_reflink_update_inode_size);
> -DEFINE_IOMAP_EVENT(xfs_reflink_remap_imap);
> +DEFINE_IMAP_EVENT(xfs_reflink_remap_imap);
> TRACE_EVENT(xfs_reflink_remap_blocks_loop,
> TP_PROTO(struct xfs_inode *src, xfs_fileoff_t soffset,
> xfs_filblks_t len, struct xfs_inode *dest,
> --
> 2.20.1
>
next prev parent reply other threads:[~2019-01-31 18:10 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-31 7:55 make delalloc conversion more robust and clear Christoph Hellwig
2019-01-31 7:55 ` [PATCH 01/11] FOLD: improve xfs_bmapi_delalloc Christoph Hellwig
2019-01-31 18:09 ` Brian Foster
2019-02-01 7:23 ` Christoph Hellwig
2019-02-01 7:28 ` Christoph Hellwig
2019-02-01 12:46 ` Brian Foster
2019-02-01 16:08 ` Christoph Hellwig
2019-01-31 7:55 ` [PATCH 02/11] xfs: remove the io_type field from the writeback context and ioend Christoph Hellwig
2019-01-31 18:10 ` Brian Foster [this message]
2019-01-31 7:55 ` [PATCH 03/11] xfs: remove the s_maxbytes checks in xfs_map_blocks Christoph Hellwig
2019-01-31 18:10 ` Brian Foster
2019-01-31 7:55 ` [PATCH 04/11] xfs: don't try to map blocks beyond i_size in writeback Christoph Hellwig
2019-01-31 18:11 ` Brian Foster
2019-02-01 7:25 ` Christoph Hellwig
2019-02-01 12:46 ` Brian Foster
2019-02-01 16:07 ` Christoph Hellwig
2019-01-31 7:55 ` [PATCH 05/11] xfs: simplify the xfs_bmap_btree_to_extents calling conventions Christoph Hellwig
2019-01-31 18:11 ` Brian Foster
2019-01-31 7:55 ` [PATCH 06/11] xfs: factor out two helpers from xfs_bmapi_write Christoph Hellwig
2019-01-31 18:28 ` Brian Foster
2019-01-31 7:55 ` [PATCH 07/11] xfs: split XFS_BMAPI_DELALLOC handling " Christoph Hellwig
2019-01-31 19:28 ` Brian Foster
2019-01-31 7:55 ` [PATCH 08/11] xfs: move transaction handling to xfs_bmapi_convert_delalloc Christoph Hellwig
2019-01-31 19:28 ` Brian Foster
2019-01-31 7:55 ` [PATCH 09/11] xfs: move stat accounting " Christoph Hellwig
2019-01-31 19:29 ` Brian Foster
2019-01-31 7:55 ` [PATCH 10/11] xfs: move xfs_iomap_write_allocate to xfs_aops.c Christoph Hellwig
2019-01-31 19:31 ` Brian Foster
2019-01-31 7:55 ` [PATCH 11/11] xfs: retry COW fork delalloc conversion when no extent was found Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2019-01-17 16:36 COW improvements and always_cow support V4 Christoph Hellwig
2019-01-17 16:36 ` [PATCH 02/11] xfs: remove the io_type field from the writeback context and ioend Christoph Hellwig
2018-12-03 22:24 COW improvements and always_cow support V3 Christoph Hellwig
2018-12-03 22:24 ` [PATCH 02/11] xfs: remove the io_type field from the writeback context and ioend Christoph Hellwig
2018-12-18 21:45 ` Darrick J. Wong
2018-12-03 16:21 COW improvements and always_cow support V3 Christoph Hellwig
2018-12-03 16:21 ` [PATCH 02/11] xfs: remove the io_type field from the writeback context and ioend Christoph Hellwig
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=20190131181005.GD36239@bfoster \
--to=bfoster@redhat.com \
--cc=darrick.wong@oracle.com \
--cc=hch@lst.de \
--cc=linux-xfs@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;
as well as URLs for NNTP newsgroup(s).