From: "Darrick J. Wong" <djwong@kernel.org>
To: djwong@kernel.org
Cc: allison.henderson@oracle.com, linux-xfs@vger.kernel.org
Subject: [PATCH 12/17] xfs: overlay alfi_nname_len atop alfi_name_len for NVREPLACE
Date: Thu, 16 Mar 2023 12:24:36 -0700 [thread overview]
Message-ID: <167899414525.15363.10856383808135579343.stgit@frogsfrogsfrogs> (raw)
In-Reply-To: <167899414339.15363.12404998880107296432.stgit@frogsfrogsfrogs>
From: Darrick J. Wong <djwong@kernel.org>
In preparation for being able to log the old attr value in a NVREPLACE
operation, encode the old and new name lengths in the alfi_name_len
field. We haven't shipped a kernel with XFS_ATTRI_OP_FLAGS_NVREPLACE,
so we can still tweak the ondisk log item format.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_log_format.h | 14 +++++-
fs/xfs/xfs_attr_item.c | 99 ++++++++++++++++++++++------------------
2 files changed, 67 insertions(+), 46 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index 1fe9f7394812..32035786135b 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -979,11 +979,21 @@ struct xfs_icreate_log {
struct xfs_attri_log_format {
uint16_t alfi_type; /* attri log item type */
uint16_t alfi_size; /* size of this item */
- uint32_t alfi_nname_len; /* attr new name length */
+ uint32_t __pad; /* pad to 64 bit aligned */
uint64_t alfi_id; /* attri identifier */
uint64_t alfi_ino; /* the inode for this attr operation */
uint32_t alfi_op_flags; /* marks the op as a set or remove */
- uint32_t alfi_name_len; /* attr name length */
+ union {
+ uint32_t alfi_name_len; /* attr name length */
+ struct {
+ /*
+ * For NVREPLACE, these are the lengths of the old and
+ * new attr name.
+ */
+ uint16_t alfi_oldname_len;
+ uint16_t alfi_newname_len;
+ };
+ };
uint32_t alfi_value_len; /* attr value length */
uint32_t alfi_attr_filter;/* attr filter flags */
};
diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c
index 4472250f461c..bb21d4e6dcf2 100644
--- a/fs/xfs/xfs_attr_item.c
+++ b/fs/xfs/xfs_attr_item.c
@@ -402,8 +402,14 @@ xfs_attr_log_item(
ASSERT(!(attr->xattri_op_flags & ~XFS_ATTRI_OP_FLAGS_TYPE_MASK));
attrp->alfi_op_flags = attr->xattri_op_flags;
attrp->alfi_value_len = attr->xattri_nameval->value.i_len;
- attrp->alfi_name_len = attr->xattri_nameval->name.i_len;
- attrp->alfi_nname_len = attr->xattri_nameval->nname.i_len;
+
+ if (xfs_attr_log_item_op(attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACE) {
+ attrp->alfi_oldname_len = attr->xattri_nameval->name.i_len;
+ attrp->alfi_newname_len = attr->xattri_nameval->nname.i_len;
+ } else {
+ attrp->alfi_name_len = attr->xattri_nameval->name.i_len;
+ }
+
ASSERT(!(attr->xattri_da_args->attr_filter & ~XFS_ATTRI_FILTER_MASK));
attrp->alfi_attr_filter = attr->xattri_da_args->attr_filter;
}
@@ -533,10 +539,6 @@ xfs_attri_validate(
{
unsigned int op = xfs_attr_log_item_op(attrp);
- if (op != XFS_ATTRI_OP_FLAGS_NVREPLACE &&
- attrp->alfi_nname_len != 0)
- return false;
-
if (attrp->alfi_op_flags & ~XFS_ATTRI_OP_FLAGS_TYPE_MASK)
return false;
@@ -545,29 +547,37 @@ xfs_attri_validate(
/* alfi_op_flags should be either a set or remove */
switch (op) {
+ case XFS_ATTRI_OP_FLAGS_REMOVE:
+ if (attrp->alfi_value_len != 0)
+ return false;
+ if (attrp->alfi_name_len == 0 ||
+ attrp->alfi_name_len > XATTR_NAME_MAX)
+ return false;
+ break;
case XFS_ATTRI_OP_FLAGS_SET:
case XFS_ATTRI_OP_FLAGS_REPLACE:
- case XFS_ATTRI_OP_FLAGS_REMOVE:
- case XFS_ATTRI_OP_FLAGS_NVREPLACE:
case XFS_ATTRI_OP_FLAGS_NVREMOVE:
case XFS_ATTRI_OP_FLAGS_NVSET:
+ if (attrp->alfi_name_len == 0 ||
+ attrp->alfi_name_len > XATTR_NAME_MAX)
+ return false;
+ if (attrp->alfi_value_len > XATTR_SIZE_MAX)
+ return false;
+ break;
+ case XFS_ATTRI_OP_FLAGS_NVREPLACE:
+ if (attrp->alfi_oldname_len == 0 ||
+ attrp->alfi_oldname_len > XATTR_NAME_MAX)
+ return false;
+ if (attrp->alfi_newname_len == 0 ||
+ attrp->alfi_newname_len > XATTR_NAME_MAX)
+ return false;
+ if (attrp->alfi_value_len > XATTR_SIZE_MAX)
+ return false;
break;
default:
return false;
}
- if (attrp->alfi_value_len > XATTR_SIZE_MAX)
- return false;
-
- if ((attrp->alfi_name_len > XATTR_NAME_MAX) ||
- (attrp->alfi_nname_len > XATTR_NAME_MAX) ||
- (attrp->alfi_name_len == 0))
- return false;
-
- if (op == XFS_ATTRI_OP_FLAGS_REMOVE &&
- attrp->alfi_value_len != 0)
- return false;
-
return xfs_verify_ino(mp, attrp->alfi_ino);
}
@@ -735,8 +745,12 @@ xfs_attri_item_relog(
new_attrp->alfi_ino = old_attrp->alfi_ino;
new_attrp->alfi_op_flags = old_attrp->alfi_op_flags;
new_attrp->alfi_value_len = old_attrp->alfi_value_len;
- new_attrp->alfi_name_len = old_attrp->alfi_name_len;
- new_attrp->alfi_nname_len = old_attrp->alfi_nname_len;
+ if (xfs_attr_log_item_op(old_attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACE) {
+ new_attrp->alfi_newname_len = old_attrp->alfi_newname_len;
+ new_attrp->alfi_oldname_len = old_attrp->alfi_oldname_len;
+ } else {
+ new_attrp->alfi_name_len = old_attrp->alfi_name_len;
+ }
new_attrp->alfi_attr_filter = old_attrp->alfi_attr_filter;
xfs_trans_add_item(tp, &new_attrip->attri_item);
@@ -759,7 +773,8 @@ xlog_recover_attri_commit_pass2(
const void *attr_value = NULL;
const void *attr_name;
size_t len;
- const void *attr_nname = NULL;
+ const void *attr_newname = NULL;
+ unsigned int name_len = 0, newname_len = 0;
int op, i = 0;
/* Validate xfs_attri_log_format before the large memory allocation */
@@ -787,6 +802,7 @@ xlog_recover_attri_commit_pass2(
attri_formatp, len);
return -EFSCORRUPTED;
}
+ name_len = attri_formatp->alfi_name_len;
break;
case XFS_ATTRI_OP_FLAGS_SET:
case XFS_ATTRI_OP_FLAGS_REPLACE:
@@ -796,6 +812,7 @@ xlog_recover_attri_commit_pass2(
attri_formatp, len);
return -EFSCORRUPTED;
}
+ name_len = attri_formatp->alfi_name_len;
break;
case XFS_ATTRI_OP_FLAGS_REMOVE:
/* Log item, attr name */
@@ -804,6 +821,7 @@ xlog_recover_attri_commit_pass2(
attri_formatp, len);
return -EFSCORRUPTED;
}
+ name_len = attri_formatp->alfi_name_len;
break;
case XFS_ATTRI_OP_FLAGS_NVREPLACE:
/* Log item, attr name, new attr name, attr value */
@@ -812,6 +830,8 @@ xlog_recover_attri_commit_pass2(
attri_formatp, len);
return -EFSCORRUPTED;
}
+ name_len = attri_formatp->alfi_oldname_len;
+ newname_len = attri_formatp->alfi_newname_len;
break;
default:
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
@@ -821,15 +841,14 @@ xlog_recover_attri_commit_pass2(
i++;
/* Validate the attr name */
- if (item->ri_buf[i].i_len !=
- xlog_calc_iovec_len(attri_formatp->alfi_name_len)) {
+ if (item->ri_buf[i].i_len != xlog_calc_iovec_len(name_len)) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
attri_formatp, len);
return -EFSCORRUPTED;
}
attr_name = item->ri_buf[i].i_addr;
- if (!xfs_attr_namecheck(mp, attr_name, attri_formatp->alfi_name_len,
+ if (!xfs_attr_namecheck(mp, attr_name, name_len,
attri_formatp->alfi_attr_filter)) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
item->ri_buf[i].i_addr, item->ri_buf[i].i_len);
@@ -837,19 +856,17 @@ xlog_recover_attri_commit_pass2(
}
i++;
- /* Validate the attr name. */
- if (attri_formatp->alfi_nname_len) {
- if (item->ri_buf[i].i_len !=
- xlog_calc_iovec_len(attri_formatp->alfi_nname_len)) {
+ /* Validate the attr nname */
+ if (newname_len > 0) {
+ if (item->ri_buf[i].i_len != xlog_calc_iovec_len(newname_len)) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
item->ri_buf[i].i_addr,
item->ri_buf[i].i_len);
return -EFSCORRUPTED;
}
- attr_nname = item->ri_buf[i].i_addr;
- if (!xfs_attr_namecheck(mp, attr_nname,
- attri_formatp->alfi_nname_len,
+ attr_newname = item->ri_buf[i].i_addr;
+ if (!xfs_attr_namecheck(mp, attr_newname, newname_len,
attri_formatp->alfi_attr_filter)) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
item->ri_buf[i].i_addr,
@@ -903,12 +920,7 @@ xlog_recover_attri_commit_pass2(
* Name-value set/remove operations must have a name, do not
* take a newname, and can take a value.
*/
- if (attr_name == NULL || attri_formatp->alfi_name_len == 0) {
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
- attri_formatp, len);
- return -EFSCORRUPTED;
- }
- if (attr_nname != NULL || attri_formatp->alfi_nname_len != 0) {
+ if (attr_name == NULL || name_len == 0) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
attri_formatp, len);
return -EFSCORRUPTED;
@@ -919,12 +931,12 @@ xlog_recover_attri_commit_pass2(
* Name-value replace operations require the caller to specify
* the old and new name explicitly. Values are optional.
*/
- if (attr_name == NULL || attri_formatp->alfi_name_len == 0) {
+ if (attr_name == NULL || name_len == 0) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
attri_formatp, len);
return -EFSCORRUPTED;
}
- if (attr_nname == NULL || attri_formatp->alfi_nname_len == 0) {
+ if (attr_newname == NULL || newname_len == 0) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
attri_formatp, len);
return -EFSCORRUPTED;
@@ -937,9 +949,8 @@ xlog_recover_attri_commit_pass2(
* name/value buffer to the recovered incore log item and drop our
* reference.
*/
- nv = xfs_attri_log_nameval_alloc(attr_name,
- attri_formatp->alfi_name_len, attr_nname,
- attri_formatp->alfi_nname_len, attr_value,
+ nv = xfs_attri_log_nameval_alloc(attr_name, name_len, attr_newname,
+ newname_len, attr_value,
attri_formatp->alfi_value_len);
attrip = xfs_attri_init(mp, nv);
next prev parent reply other threads:[~2023-03-16 19:24 UTC|newest]
Thread overview: 94+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-16 18:54 [RFC DELUGE v10r1d2] xfs: Parent Pointers Darrick J. Wong
2023-03-16 19:17 ` [PATCHSET v10r1d2 0/7] xfs: bug fixes for parent pointers Darrick J. Wong
2023-03-16 19:19 ` [PATCH 1/7] xfs: validate parent pointer xattrs in getparent Darrick J. Wong
2023-03-16 19:20 ` [PATCH 2/7] xfs: rename xfs_pptr_info to xfs_getparents Darrick J. Wong
2023-03-16 19:20 ` [PATCH 3/7] xfs: rename xfs_parent_ptr Darrick J. Wong
2023-03-16 19:20 ` [PATCH 4/7] xfs: fix GETPARENTS ioctl Darrick J. Wong
2023-03-16 19:20 ` [PATCH 5/7] xfs: add tracing to the " Darrick J. Wong
2023-03-16 19:21 ` [PATCH 6/7] xfs: shorten parent pointer function names Darrick J. Wong
2023-03-16 19:21 ` [PATCH 7/7] xfs: rearrange bits of the parent pointer apis for fsck Darrick J. Wong
2023-03-16 19:17 ` [PATCHSET v10r1d2 00/17] xfs: encode parent pointer name in xattr key Darrick J. Wong
2023-03-16 19:21 ` [PATCH 01/17] xfs: document the ri_total validation in xlog_recover_attri_commit_pass2 Darrick J. Wong
2023-03-16 19:22 ` [PATCH 02/17] xfs: make xfs_attr_set require XFS_DA_OP_REMOVE Darrick J. Wong
2023-03-16 19:22 ` [PATCH 03/17] xfs: allow xattr matching on value for local/sf attrs Darrick J. Wong
2023-03-16 19:22 ` [PATCH 04/17] xfs: preserve VLOOKUP in xfs_attr_set Darrick J. Wong
2023-03-16 19:22 ` [PATCH 05/17] xfs: restructure xfs_attr_complete_op a bit Darrick J. Wong
2023-03-16 19:23 ` [PATCH 06/17] xfs: use helpers to extract xattr op from opflags Darrick J. Wong
2023-03-16 19:23 ` [PATCH 07/17] xfs: validate recovered name buffers when recovering xattr items Darrick J. Wong
2023-03-16 19:23 ` [PATCH 08/17] xfs: always set args->value in xfs_attri_item_recover Darrick J. Wong
2023-03-16 19:23 ` [PATCH 09/17] xfs: flip nvreplace detection in xfs_attr_complete_op Darrick J. Wong
2023-03-16 19:24 ` [PATCH 10/17] xfs: log VLOOKUP xattr removal operations Darrick J. Wong
2023-03-16 19:24 ` [PATCH 11/17] xfs: log VLOOKUP xattr setting operations Darrick J. Wong
2023-03-16 19:24 ` Darrick J. Wong [this message]
2023-03-16 19:24 ` [PATCH 13/17] xfs: refactor value length in xlog_recover_attri_commit_pass2 Darrick J. Wong
2023-03-16 19:25 ` [PATCH 14/17] xfs: rename nname to newname Darrick J. Wong
2023-03-16 19:25 ` [PATCH 15/17] xfs: log VLOOKUP xattr nvreplace operations Darrick J. Wong
2023-03-16 19:25 ` [PATCH 16/17] xfs: log new xattr values for NVREPLACEXXX operations Darrick J. Wong
2023-03-16 19:25 ` [PATCH 17/17] xfs: replace parent pointer diroffset with full dirent name Darrick J. Wong
2023-03-24 17:10 ` [PATCHSET v10r1d2 00/17] xfs: encode parent pointer name in xattr key Allison Henderson
2023-03-25 7:59 ` Amir Goldstein
2023-03-25 17:01 ` Darrick J. Wong
2023-03-26 3:21 ` Amir Goldstein
2023-03-28 1:29 ` Darrick J. Wong
2023-03-28 7:21 ` Amir Goldstein
2023-03-28 22:29 ` Dave Chinner
2023-03-28 23:54 ` Darrick J. Wong
2023-03-29 0:19 ` Dave Chinner
2023-03-29 0:46 ` Darrick J. Wong
2023-03-30 1:56 ` Darrick J. Wong
2023-03-25 17:03 ` Darrick J. Wong
2023-03-16 19:17 ` [PATCHSET v10r1d2 0/9] xfsprogs: tool fixes for parent pointers Darrick J. Wong
2023-03-16 19:26 ` [PATCH 1/9] libxfs: initialize the slab cache for parent defer items Darrick J. Wong
2023-03-16 19:26 ` [PATCH 2/9] mkfs: fix libxfs api misuse Darrick J. Wong
2023-03-16 19:26 ` [PATCH 3/9] libxfs: create new files with attr forks if necessary Darrick J. Wong
2023-03-16 19:26 ` [PATCH 4/9] mkfs: fix subdir parent pointer creation Darrick J. Wong
2023-03-16 19:27 ` [PATCH 5/9] xfs_db: report parent pointer keys Darrick J. Wong
2023-03-16 19:27 ` [PATCH 6/9] xfs_db: obfuscate dirent and pptr names consistently Darrick J. Wong
2023-03-16 19:27 ` [PATCH 7/9] xfs_io: print path in path_print Darrick J. Wong
2023-03-16 19:27 ` [PATCH 8/9] xfs_io: parent command is not experts-only Darrick J. Wong
2023-03-16 19:28 ` [PATCH 9/9] xfs_repair: fix incorrect dabtree hashval comparison Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/2] xfsprogs: actually use getparent ioctl Darrick J. Wong
2023-03-16 19:28 ` [PATCH 1/2] xfs_scrub: revert unnecessary code from "implement the upper half of parent pointers" Darrick J. Wong
2023-03-16 19:28 ` [PATCH 2/2] xfs_scrub: use parent pointers when possible to report file operations Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/7] libfrog: fix parent pointer library code Darrick J. Wong
2023-03-16 19:29 ` [PATCH 1/7] xfs_io: move parent pointer filtering and formatting flags out of libhandle Darrick J. Wong
2023-03-16 19:29 ` [PATCH 2/7] libfrog: remove all the parent pointer code from libhandle Darrick J. Wong
2023-03-16 19:29 ` [PATCH 3/7] libfrog: fix indenting errors in xfss_pptr_alloc Darrick J. Wong
2023-03-16 19:29 ` [PATCH 4/7] libfrog: return positive errno in pptrs.c Darrick J. Wong
2023-03-16 19:30 ` [PATCH 5/7] libfrog: only walk one parent pointer at a time in handle_walk_parent_path_ptr Darrick J. Wong
2023-03-16 19:30 ` [PATCH 6/7] libfrog: trim trailing slashes when printing pptr paths Darrick J. Wong
2023-03-16 19:30 ` [PATCH 7/7] libfrog: fix a buffer overrun in path_list_to_string Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/5] xfsprogs: bug fixes for parent pointers Darrick J. Wong
2023-03-16 19:30 ` [PATCH 1/5] xfs: rename xfs_pptr_info to xfs_getparents Darrick J. Wong
2023-03-16 19:31 ` [PATCH 2/5] xfs: rename xfs_parent_ptr Darrick J. Wong
2023-03-16 19:31 ` [PATCH 3/5] xfs: fix GETPARENTS ioctl Darrick J. Wong
2023-03-16 19:31 ` [PATCH 4/5] xfs: shorten parent pointer function names Darrick J. Wong
2023-03-16 19:31 ` [PATCH 5/5] xfs: rearrange bits of the parent pointer apis for fsck Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/4] xfs_logprint: clean up attri/pptr dumping Darrick J. Wong
2023-03-16 19:32 ` [PATCH 1/4] xfs: revert "xfsprogs: Print pptrs in ATTRI items" Darrick J. Wong
2023-03-16 19:32 ` [PATCH 2/4] xfs_logprint: print missing attri header fields Darrick J. Wong
2023-03-16 19:32 ` [PATCH 3/4] xfs: make logprint note attr names and newnames consistently Darrick J. Wong
2023-03-16 19:32 ` [PATCH 4/4] xfs_logprint: decode parent pointers fully Darrick J. Wong
2023-03-16 19:19 ` [PATCHSET v10r1d2 00/14] fstests: adjust tests for xfs parent pointers Darrick J. Wong
2023-03-16 19:33 ` [PATCH 01/14] xfs/122: update for " Darrick J. Wong
2023-03-16 19:33 ` [PATCH 02/14] populate: create hardlinks " Darrick J. Wong
2023-03-16 19:33 ` [PATCH 03/14] xfs/021: adapt golden output files " Darrick J. Wong
2023-03-16 19:33 ` [PATCH 04/14] generic/050: adapt " Darrick J. Wong
2023-03-16 19:34 ` [PATCH 05/14] xfs/018: disable parent pointers for this test Darrick J. Wong
2023-03-16 19:34 ` [PATCH 06/14] xfs/306: fix formatting failures with parent pointers Darrick J. Wong
2023-03-16 19:34 ` [PATCH 07/14] common: add helpers for parent pointer tests Darrick J. Wong
2023-03-16 19:35 ` [PATCH 08/14] xfs: add parent pointer test Darrick J. Wong
2023-03-16 19:35 ` [PATCH 09/14] xfs: add multi link " Darrick J. Wong
2023-03-16 19:35 ` [PATCH 10/14] xfs: add parent pointer inject test Darrick J. Wong
2023-03-16 19:35 ` [PATCH 11/14] common/parent: add license and copyright Darrick J. Wong
2023-03-16 19:36 ` [PATCH 12/14] common/parent: don't _fail on missing parent pointer components Darrick J. Wong
2023-03-16 19:36 ` [PATCH 13/14] common/parent: check xfs_io parent command paths Darrick J. Wong
2023-03-16 19:36 ` [PATCH 14/14] xfs/851: test xfs_io parent -p too Darrick J. Wong
2023-03-16 19:19 ` [PATCHSET v10r1d2 0/1] xfs: bug fixes for parent pointers Darrick J. Wong
2023-03-16 19:36 ` [PATCH 1/1] xfs/122: fix parent pointer ioctl structure sizes Darrick J. Wong
2023-03-16 19:19 ` [PATCHSET v10r1d2 0/1] fstests: encode parent pointer name in xattr key Darrick J. Wong
2023-03-16 19:37 ` [PATCH 1/1] xfs/{021,122}: adjust parent pointer encoding format Darrick J. Wong
2023-03-17 19:06 ` [RFC DELUGE v10r1d2] xfs: Parent Pointers Allison Henderson
2023-03-17 23:45 ` Darrick J. Wong
2023-03-21 21:14 ` Allison Henderson
2023-03-25 17:02 ` 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=167899414525.15363.10856383808135579343.stgit@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=allison.henderson@oracle.com \
--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).