public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Eric Sandeen <sandeen@sandeen.net>
Cc: linux-xfs@vger.kernel.org, allison.henderson@oracle.com
Subject: Re: [PATCH 04/17] libfrog: move the GETFSMAP definitions into libfrog
Date: Fri, 4 Feb 2022 16:36:18 -0800	[thread overview]
Message-ID: <20220205003618.GU8313@magnolia> (raw)
In-Reply-To: <bb88560e-bbdf-80c5-b4d6-6c00f4ab3ef1@sandeen.net>

On Fri, Feb 04, 2022 at 05:18:12PM -0600, Eric Sandeen wrote:
> On 1/19/22 6:21 PM, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > Move our private copy of the GETFSMAP definition into a libfrog header
> > file that (preferentially) uses the system header files.  We have no
> > business shipping kernel headers in the xfslibs package, but this shim
> > is still needed to build fully functional xfsprogs on old userspace.
> 
> Hm. Fine, but I wonder if we can get a bit more intentional about how
> we handle this kind of thing, I understand why we copy this stuff into
> xfsprogs early, but then we never know how to get rid of it.
> 
> Do we /need/ to build fully functional xfsprogs on old userspace?
> (really: systems with old kernel headers?)  How far back do we go,
> I wonder?  Anyway...

TBH we could probably get rid of these entirely, assuming nobody is
building xfsprogs with old kernel headers for a system with a newer
kernel?

--D

> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> 
> Reviewed-by: Eric Sandeen <sandeen@redhat.com>
> 
> > ---
> >  include/linux.h   |  105 ------------------------------------------------
> >  io/fsmap.c        |    1 
> >  io/io.h           |    5 --
> >  libfrog/Makefile  |    1 
> >  libfrog/fsmap.h   |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  scrub/phase6.c    |    1 
> >  scrub/phase7.c    |    1 
> >  scrub/spacemap.c  |    1 
> >  spaceman/freesp.c |    1 
> >  spaceman/space.h  |    4 --
> >  10 files changed, 123 insertions(+), 114 deletions(-)
> >  create mode 100644 libfrog/fsmap.h
> > 
> > 
> > diff --git a/include/linux.h b/include/linux.h
> > index de8a7122..3d9f4e3d 100644
> > --- a/include/linux.h
> > +++ b/include/linux.h
> > @@ -251,111 +251,6 @@ struct fsxattr {
> >  #define FS_XFLAG_COWEXTSIZE	0x00010000	/* CoW extent size allocator hint */
> >  #endif
> >  
> > -#ifdef HAVE_GETFSMAP
> > -# include <linux/fsmap.h>
> > -#else
> > -/*
> > - *	Structure for FS_IOC_GETFSMAP.
> > - *
> > - *	The memory layout for this call are the scalar values defined in
> > - *	struct fsmap_head, followed by two struct fsmap that describe
> > - *	the lower and upper bound of mappings to return, followed by an
> > - *	array of struct fsmap mappings.
> > - *
> > - *	fmh_iflags control the output of the call, whereas fmh_oflags report
> > - *	on the overall record output.  fmh_count should be set to the
> > - *	length of the fmh_recs array, and fmh_entries will be set to the
> > - *	number of entries filled out during each call.  If fmh_count is
> > - *	zero, the number of reverse mappings will be returned in
> > - *	fmh_entries, though no mappings will be returned.  fmh_reserved
> > - *	must be set to zero.
> > - *
> > - *	The two elements in the fmh_keys array are used to constrain the
> > - *	output.  The first element in the array should represent the
> > - *	lowest disk mapping ("low key") that the user wants to learn
> > - *	about.  If this value is all zeroes, the filesystem will return
> > - *	the first entry it knows about.  For a subsequent call, the
> > - *	contents of fsmap_head.fmh_recs[fsmap_head.fmh_count - 1] should be
> > - *	copied into fmh_keys[0] to have the kernel start where it left off.
> > - *
> > - *	The second element in the fmh_keys array should represent the
> > - *	highest disk mapping ("high key") that the user wants to learn
> > - *	about.  If this value is all ones, the filesystem will not stop
> > - *	until it runs out of mapping to return or runs out of space in
> > - *	fmh_recs.
> > - *
> > - *	fmr_device can be either a 32-bit cookie representing a device, or
> > - *	a 32-bit dev_t if the FMH_OF_DEV_T flag is set.  fmr_physical,
> > - *	fmr_offset, and fmr_length are expressed in units of bytes.
> > - *	fmr_owner is either an inode number, or a special value if
> > - *	FMR_OF_SPECIAL_OWNER is set in fmr_flags.
> > - */
> > -struct fsmap {
> > -	__u32		fmr_device;	/* device id */
> > -	__u32		fmr_flags;	/* mapping flags */
> > -	__u64		fmr_physical;	/* device offset of segment */
> > -	__u64		fmr_owner;	/* owner id */
> > -	__u64		fmr_offset;	/* file offset of segment */
> > -	__u64		fmr_length;	/* length of segment */
> > -	__u64		fmr_reserved[3];	/* must be zero */
> > -};
> > -
> > -struct fsmap_head {
> > -	__u32		fmh_iflags;	/* control flags */
> > -	__u32		fmh_oflags;	/* output flags */
> > -	__u32		fmh_count;	/* # of entries in array incl. input */
> > -	__u32		fmh_entries;	/* # of entries filled in (output). */
> > -	__u64		fmh_reserved[6];	/* must be zero */
> > -
> > -	struct fsmap	fmh_keys[2];	/* low and high keys for the mapping search */
> > -	struct fsmap	fmh_recs[];	/* returned records */
> > -};
> > -
> > -/* Size of an fsmap_head with room for nr records. */
> > -static inline size_t
> > -fsmap_sizeof(
> > -	unsigned int	nr)
> > -{
> > -	return sizeof(struct fsmap_head) + nr * sizeof(struct fsmap);
> > -}
> > -
> > -/* Start the next fsmap query at the end of the current query results. */
> > -static inline void
> > -fsmap_advance(
> > -	struct fsmap_head	*head)
> > -{
> > -	head->fmh_keys[0] = head->fmh_recs[head->fmh_entries - 1];
> > -}
> > -
> > -/*	fmh_iflags values - set by XFS_IOC_GETFSMAP caller in the header. */
> > -/* no flags defined yet */
> > -#define FMH_IF_VALID		0
> > -
> > -/*	fmh_oflags values - returned in the header segment only. */
> > -#define FMH_OF_DEV_T		0x1	/* fmr_device values will be dev_t */
> > -
> > -/*	fmr_flags values - returned for each non-header segment */
> > -#define FMR_OF_PREALLOC		0x1	/* segment = unwritten pre-allocation */
> > -#define FMR_OF_ATTR_FORK	0x2	/* segment = attribute fork */
> > -#define FMR_OF_EXTENT_MAP	0x4	/* segment = extent map */
> > -#define FMR_OF_SHARED		0x8	/* segment = shared with another file */
> > -#define FMR_OF_SPECIAL_OWNER	0x10	/* owner is a special value */
> > -#define FMR_OF_LAST		0x20	/* segment is the last in the FS */
> > -
> > -/* Each FS gets to define its own special owner codes. */
> > -#define FMR_OWNER(type, code)	(((__u64)type << 32) | \
> > -				 ((__u64)code & 0xFFFFFFFFULL))
> > -#define FMR_OWNER_TYPE(owner)	((__u32)((__u64)owner >> 32))
> > -#define FMR_OWNER_CODE(owner)	((__u32)(((__u64)owner & 0xFFFFFFFFULL)))
> > -#define FMR_OWN_FREE		FMR_OWNER(0, 1) /* free space */
> > -#define FMR_OWN_UNKNOWN		FMR_OWNER(0, 2) /* unknown owner */
> > -#define FMR_OWN_METADATA	FMR_OWNER(0, 3) /* metadata */
> > -
> > -#define FS_IOC_GETFSMAP		_IOWR('X', 59, struct fsmap_head)
> > -
> > -#define HAVE_GETFSMAP
> > -#endif /* HAVE_GETFSMAP */
> > -
> >  #ifndef HAVE_MAP_SYNC
> >  #define MAP_SYNC 0
> >  #define MAP_SHARED_VALIDATE 0
> > diff --git a/io/fsmap.c b/io/fsmap.c
> > index f540a7c0..9ff36bf4 100644
> > --- a/io/fsmap.c
> > +++ b/io/fsmap.c
> > @@ -10,6 +10,7 @@
> >  #include "io.h"
> >  #include "input.h"
> >  #include "libfrog/fsgeom.h"
> > +#include "libfrog/fsmap.h"
> >  
> >  static cmdinfo_t	fsmap_cmd;
> >  static dev_t		xfs_data_dev;
> > diff --git a/io/io.h b/io/io.h
> > index 49db902f..39fb5878 100644
> > --- a/io/io.h
> > +++ b/io/io.h
> > @@ -167,12 +167,7 @@ extern void		readdir_init(void);
> >  extern void		reflink_init(void);
> >  
> >  extern void		cowextsize_init(void);
> > -
> > -#ifdef HAVE_GETFSMAP
> >  extern void		fsmap_init(void);
> > -#else
> > -# define fsmap_init()	do { } while (0)
> > -#endif
> >  
> >  #ifdef HAVE_DEVMAPPER
> >  extern void		log_writes_init(void);
> > diff --git a/libfrog/Makefile b/libfrog/Makefile
> > index 01107082..d6044455 100644
> > --- a/libfrog/Makefile
> > +++ b/libfrog/Makefile
> > @@ -40,6 +40,7 @@ crc32cselftest.h \
> >  crc32defs.h \
> >  crc32table.h \
> >  fsgeom.h \
> > +fsmap.h \
> >  logging.h \
> >  paths.h \
> >  projects.h \
> > diff --git a/libfrog/fsmap.h b/libfrog/fsmap.h
> > new file mode 100644
> > index 00000000..dc290962
> > --- /dev/null
> > +++ b/libfrog/fsmap.h
> > @@ -0,0 +1,117 @@
> > +#ifdef HAVE_GETFSMAP
> > +# include <linux/fsmap.h>
> > +#endif
> > +
> > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> > +/*
> > + * FS_IOC_GETFSMAP ioctl infrastructure.
> > + *
> > + * Copyright (C) 2017 Oracle.  All Rights Reserved.
> > + *
> > + * Author: Darrick J. Wong <djwong@kernel.org>
> > + */
> > +#ifndef _LINUX_FSMAP_H
> > +#define _LINUX_FSMAP_H
> > +
> > +#include <linux/types.h>
> > +
> > +/*
> > + *	Structure for FS_IOC_GETFSMAP.
> > + *
> > + *	The memory layout for this call are the scalar values defined in
> > + *	struct fsmap_head, followed by two struct fsmap that describe
> > + *	the lower and upper bound of mappings to return, followed by an
> > + *	array of struct fsmap mappings.
> > + *
> > + *	fmh_iflags control the output of the call, whereas fmh_oflags report
> > + *	on the overall record output.  fmh_count should be set to the
> > + *	length of the fmh_recs array, and fmh_entries will be set to the
> > + *	number of entries filled out during each call.  If fmh_count is
> > + *	zero, the number of reverse mappings will be returned in
> > + *	fmh_entries, though no mappings will be returned.  fmh_reserved
> > + *	must be set to zero.
> > + *
> > + *	The two elements in the fmh_keys array are used to constrain the
> > + *	output.  The first element in the array should represent the
> > + *	lowest disk mapping ("low key") that the user wants to learn
> > + *	about.  If this value is all zeroes, the filesystem will return
> > + *	the first entry it knows about.  For a subsequent call, the
> > + *	contents of fsmap_head.fmh_recs[fsmap_head.fmh_count - 1] should be
> > + *	copied into fmh_keys[0] to have the kernel start where it left off.
> > + *
> > + *	The second element in the fmh_keys array should represent the
> > + *	highest disk mapping ("high key") that the user wants to learn
> > + *	about.  If this value is all ones, the filesystem will not stop
> > + *	until it runs out of mapping to return or runs out of space in
> > + *	fmh_recs.
> > + *
> > + *	fmr_device can be either a 32-bit cookie representing a device, or
> > + *	a 32-bit dev_t if the FMH_OF_DEV_T flag is set.  fmr_physical,
> > + *	fmr_offset, and fmr_length are expressed in units of bytes.
> > + *	fmr_owner is either an inode number, or a special value if
> > + *	FMR_OF_SPECIAL_OWNER is set in fmr_flags.
> > + */
> > +struct fsmap {
> > +	__u32		fmr_device;	/* device id */
> > +	__u32		fmr_flags;	/* mapping flags */
> > +	__u64		fmr_physical;	/* device offset of segment */
> > +	__u64		fmr_owner;	/* owner id */
> > +	__u64		fmr_offset;	/* file offset of segment */
> > +	__u64		fmr_length;	/* length of segment */
> > +	__u64		fmr_reserved[3];	/* must be zero */
> > +};
> > +
> > +struct fsmap_head {
> > +	__u32		fmh_iflags;	/* control flags */
> > +	__u32		fmh_oflags;	/* output flags */
> > +	__u32		fmh_count;	/* # of entries in array incl. input */
> > +	__u32		fmh_entries;	/* # of entries filled in (output). */
> > +	__u64		fmh_reserved[6];	/* must be zero */
> > +
> > +	struct fsmap	fmh_keys[2];	/* low and high keys for the mapping search */
> > +	struct fsmap	fmh_recs[];	/* returned records */
> > +};
> > +
> > +/* Size of an fsmap_head with room for nr records. */
> > +static __inline__ size_t
> > +fsmap_sizeof(
> > +	unsigned int	nr)
> > +{
> > +	return sizeof(struct fsmap_head) + nr * sizeof(struct fsmap);
> > +}
> > +
> > +/* Start the next fsmap query at the end of the current query results. */
> > +static __inline__ void
> > +fsmap_advance(
> > +	struct fsmap_head	*head)
> > +{
> > +	head->fmh_keys[0] = head->fmh_recs[head->fmh_entries - 1];
> > +}
> > +
> > +/*	fmh_iflags values - set by FS_IOC_GETFSMAP caller in the header. */
> > +/* no flags defined yet */
> > +#define FMH_IF_VALID		0
> > +
> > +/*	fmh_oflags values - returned in the header segment only. */
> > +#define FMH_OF_DEV_T		0x1	/* fmr_device values will be dev_t */
> > +
> > +/*	fmr_flags values - returned for each non-header segment */
> > +#define FMR_OF_PREALLOC		0x1	/* segment = unwritten pre-allocation */
> > +#define FMR_OF_ATTR_FORK	0x2	/* segment = attribute fork */
> > +#define FMR_OF_EXTENT_MAP	0x4	/* segment = extent map */
> > +#define FMR_OF_SHARED		0x8	/* segment = shared with another file */
> > +#define FMR_OF_SPECIAL_OWNER	0x10	/* owner is a special value */
> > +#define FMR_OF_LAST		0x20	/* segment is the last in the dataset */
> > +
> > +/* Each FS gets to define its own special owner codes. */
> > +#define FMR_OWNER(type, code)	(((__u64)type << 32) | \
> > +				 ((__u64)code & 0xFFFFFFFFULL))
> > +#define FMR_OWNER_TYPE(owner)	((__u32)((__u64)owner >> 32))
> > +#define FMR_OWNER_CODE(owner)	((__u32)(((__u64)owner & 0xFFFFFFFFULL)))
> > +#define FMR_OWN_FREE		FMR_OWNER(0, 1) /* free space */
> > +#define FMR_OWN_UNKNOWN		FMR_OWNER(0, 2) /* unknown owner */
> > +#define FMR_OWN_METADATA	FMR_OWNER(0, 3) /* metadata */
> > +
> > +#define FS_IOC_GETFSMAP		_IOWR('X', 59, struct fsmap_head)
> > +
> > +#endif /* _LINUX_FSMAP_H */
> > diff --git a/scrub/phase6.c b/scrub/phase6.c
> > index 87828b60..dd42b66c 100644
> > --- a/scrub/phase6.c
> > +++ b/scrub/phase6.c
> > @@ -10,6 +10,7 @@
> >  #include "handle.h"
> >  #include "libfrog/paths.h"
> >  #include "libfrog/workqueue.h"
> > +#include "libfrog/fsmap.h"
> >  #include "xfs_scrub.h"
> >  #include "common.h"
> >  #include "libfrog/bitmap.h"
> > diff --git a/scrub/phase7.c b/scrub/phase7.c
> > index bc652ab6..e24906d1 100644
> > --- a/scrub/phase7.c
> > +++ b/scrub/phase7.c
> > @@ -9,6 +9,7 @@
> >  #include <sys/statvfs.h>
> >  #include "libfrog/paths.h"
> >  #include "libfrog/ptvar.h"
> > +#include "libfrog/fsmap.h"
> >  #include "list.h"
> >  #include "xfs_scrub.h"
> >  #include "common.h"
> > diff --git a/scrub/spacemap.c b/scrub/spacemap.c
> > index a5508d56..b7f17e57 100644
> > --- a/scrub/spacemap.c
> > +++ b/scrub/spacemap.c
> > @@ -10,6 +10,7 @@
> >  #include <sys/statvfs.h>
> >  #include "libfrog/workqueue.h"
> >  #include "libfrog/paths.h"
> > +#include "libfrog/fsmap.h"
> >  #include "xfs_scrub.h"
> >  #include "common.h"
> >  #include "spacemap.h"
> > diff --git a/spaceman/freesp.c b/spaceman/freesp.c
> > index de301c19..4e46ab26 100644
> > --- a/spaceman/freesp.c
> > +++ b/spaceman/freesp.c
> > @@ -9,6 +9,7 @@
> >  #include "libxfs.h"
> >  #include <linux/fiemap.h>
> >  #include "libfrog/fsgeom.h"
> > +#include "libfrog/fsmap.h"
> >  #include "command.h"
> >  #include "init.h"
> >  #include "libfrog/paths.h"
> > diff --git a/spaceman/space.h b/spaceman/space.h
> > index 723209ed..a8055535 100644
> > --- a/spaceman/space.h
> > +++ b/spaceman/space.h
> > @@ -26,11 +26,7 @@ extern void	help_init(void);
> >  extern void	prealloc_init(void);
> >  extern void	quit_init(void);
> >  extern void	trim_init(void);
> > -#ifdef HAVE_GETFSMAP
> >  extern void	freesp_init(void);
> > -#else
> > -# define freesp_init()	do { } while (0)
> > -#endif
> >  extern void	info_init(void);
> >  extern void	health_init(void);
> >  
> > 

  reply	other threads:[~2022-02-05  0:36 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-20  0:21 [PATCHSET 00/17] xfsprogs: various 5.15 fixes Darrick J. Wong
2022-01-20  0:21 ` [PATCH 01/17] libxcmd: use emacs mode for command history editing Darrick J. Wong
2022-01-20  0:21 ` [PATCH 02/17] libxfs: shut down filesystem if we xfs_trans_cancel with deferred work items Darrick J. Wong
2022-02-04 21:36   ` Eric Sandeen
2022-02-04 21:47     ` Darrick J. Wong
2022-01-20  0:21 ` [PATCH 03/17] libxfs: don't leave dangling perag references from xfs_buf Darrick J. Wong
2022-02-04 22:05   ` Eric Sandeen
2022-01-20  0:21 ` [PATCH 04/17] libfrog: move the GETFSMAP definitions into libfrog Darrick J. Wong
2022-02-04 23:18   ` Eric Sandeen
2022-02-05  0:36     ` Darrick J. Wong [this message]
2022-02-07  1:05       ` Dave Chinner
2022-02-07 17:09         ` Darrick J. Wong
2022-02-07 21:32           ` Eric Sandeen
2022-02-10  3:33             ` Dave Chinner
2022-02-08 16:46   ` [PATCH v1.1 04/17] libfrog: always use the kernel GETFSMAP definitions Darrick J. Wong
2022-02-25 22:35     ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 05/17] misc: add a crc32c self test to mkfs and repair Darrick J. Wong
2022-02-04 23:23   ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 06/17] libxfs-apply: support filterdiff >= 0.4.2 only Darrick J. Wong
2022-01-20  0:22 ` [PATCH 07/17] xfs_db: fix nbits parameter in fa_ino[48] functions Darrick J. Wong
2022-02-25 21:45   ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 08/17] xfs_repair: explicitly cast resource usage counts in do_warn Darrick J. Wong
2022-02-25 21:46   ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 09/17] xfs_repair: explicitly cast directory inode numbers " Darrick J. Wong
2022-02-25 21:48   ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 10/17] xfs_repair: fix indentation problems in upgrade_filesystem Darrick J. Wong
2022-02-25 21:53   ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 11/17] xfs_repair: update secondary superblocks after changing features Darrick J. Wong
2022-02-25 21:57   ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 12/17] xfs_scrub: report optional features in version string Darrick J. Wong
2022-01-20  1:16   ` Theodore Ts'o
2022-01-20  1:28     ` Darrick J. Wong
2022-01-20  1:32   ` [PATCH v2 " Darrick J. Wong
2022-02-25 22:14     ` Eric Sandeen
2022-02-26  0:04       ` Darrick J. Wong
2022-02-26  2:48         ` Darrick J. Wong
2022-02-26  2:53   ` [PATCH v3 " Darrick J. Wong
2022-02-28 21:38     ` Eric Sandeen
2022-01-20  0:22 ` [PATCH 13/17] mkfs: prevent corruption of passed-in suboption string values Darrick J. Wong
2022-01-20  0:22 ` [PATCH 14/17] mkfs: add configuration files for the last few LTS kernels Darrick J. Wong
2022-01-20  0:22 ` [PATCH 15/17] mkfs: document sample configuration file location Darrick J. Wong
2022-01-20  0:23 ` [PATCH 16/17] mkfs: add a config file for x86_64 pmem filesystems Darrick J. Wong
2022-02-25 22:21   ` Eric Sandeen
2022-02-26  2:38     ` Darrick J. Wong
2022-02-26  2:52   ` [PATCH v2 " Darrick J. Wong
2022-02-28 21:37     ` Eric Sandeen
2022-01-20  0:23 ` [PATCH 17/17] mkfs: enable inobtcount and bigtime by default Darrick J. Wong
2022-02-25 22:22   ` Eric Sandeen
2022-01-28 22:44 ` [PATCH 18/17] xfs_scrub: fix reporting if we can't open raw block devices Darrick J. Wong
2022-01-31 12:28   ` Christoph Hellwig
2022-02-26  2:54 ` [PATCH 19/17] mkfs: increase default log size for new (aka bigtime) filesystems Darrick J. Wong
2022-02-26 21:37   ` Dave Chinner
2022-02-28 23:22     ` Darrick J. Wong
2022-03-01  0:42       ` Dave Chinner
2022-03-01  2:38         ` Darrick J. Wong
2022-03-01 15:55           ` Brian Foster
2022-03-01  3:10         ` Dave Chinner
2022-02-28 21:44   ` Eric Sandeen
2022-03-01  2:21     ` Darrick J. Wong
2022-03-01  2:44       ` Eric Sandeen

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=20220205003618.GU8313@magnolia \
    --to=djwong@kernel.org \
    --cc=allison.henderson@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@sandeen.net \
    /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