* Re: [PATCH v6.1 11/11] xfs: add media verification ioctl
[not found] ` <20260120180040.GU15551@frogsfrogsfrogs>
@ 2026-01-21 7:05 ` Christoph Hellwig
2026-01-21 19:58 ` Darrick J. Wong
0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2026-01-21 7:05 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Christoph Hellwig, cem, linux-xfs, linux-fsdevel
On Tue, Jan 20, 2026 at 10:00:40AM -0800, Darrick J. Wong wrote:
> On Tue, Jan 20, 2026 at 08:18:30AM +0100, Christoph Hellwig wrote:
> >
> > > + unsigned int bio_bbcount;
> > > + blk_status_t bio_status;
> > > +
> > > + bio_reset(bio, btp->bt_bdev, REQ_OP_READ);
> > > + bio->bi_iter.bi_sector = daddr;
> > > + bio_add_folio_nofail(bio, folio,
> > > + min(bbcount << SECTOR_SHIFT, folio_size(folio)),
> > > + 0);
> >
> > You could actually use bio_reuse as you implied in the previous mail here
> > and save the bio_add_folio_nofail call. Not really going to make much
> > of a difference, so:
>
> Hrm. Is that bio_reuse patch queued for upstream? Though maybe it'd be
> easier to make a mental note (ha!) to clean this up once both appear
> upstream.
It is queued up in the xfs for-next tree.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6.1 11/11] xfs: add media verification ioctl
2026-01-21 7:05 ` [PATCH v6.1 11/11] xfs: add media verification ioctl Christoph Hellwig
@ 2026-01-21 19:58 ` Darrick J. Wong
0 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2026-01-21 19:58 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: cem, linux-xfs, linux-fsdevel
On Wed, Jan 21, 2026 at 08:05:56AM +0100, Christoph Hellwig wrote:
> On Tue, Jan 20, 2026 at 10:00:40AM -0800, Darrick J. Wong wrote:
> > On Tue, Jan 20, 2026 at 08:18:30AM +0100, Christoph Hellwig wrote:
> > >
> > > > + unsigned int bio_bbcount;
> > > > + blk_status_t bio_status;
> > > > +
> > > > + bio_reset(bio, btp->bt_bdev, REQ_OP_READ);
> > > > + bio->bi_iter.bi_sector = daddr;
> > > > + bio_add_folio_nofail(bio, folio,
> > > > + min(bbcount << SECTOR_SHIFT, folio_size(folio)),
> > > > + 0);
> > >
> > > You could actually use bio_reuse as you implied in the previous mail here
> > > and save the bio_add_folio_nofail call. Not really going to make much
> > > of a difference, so:
> >
> > Hrm. Is that bio_reuse patch queued for upstream? Though maybe it'd be
> > easier to make a mental note (ha!) to clean this up once both appear
> > upstream.
>
> It is queued up in the xfs for-next tree.
Ah, heh. I'll see if cem merges the series atop his xfs-7.0-merge
branch and send a followup. As it is I'm already going to ask Linus if
I can remove the old fsnotify error function (and any new callers that
might pop up) right before -rc1.
--D
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6.1 11/11] xfs: add media verification ioctl
[not found] ` <20260120041226.GJ15551@frogsfrogsfrogs>
[not found] ` <20260120071830.GA5686@lst.de>
@ 2026-02-06 3:01 ` Chris Mason
2026-02-06 4:53 ` Darrick J. Wong
1 sibling, 1 reply; 10+ messages in thread
From: Chris Mason @ 2026-02-06 3:01 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: cem, hch, linux-xfs, linux-fsdevel
"Darrick J. Wong" <djwong@kernel.org> wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> Add a new privileged ioctl so that xfs_scrub can ask the kernel to
> verify the media of the devices backing an xfs filesystem, and have any
> resulting media errors reported to fsnotify and xfs_healer.
Hi everyone,
I'm trying out my AI review prompts on a few more trees, and I ran it
on the fuse-iomap-cache branch:
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/log/?h=fuse-iomap-cache
This was the latest email lore could find, apologies if I grabbed the wrong one.
Hopefully the review below is useful, please let me know if there are places it
has gone wildly wrong. I kept the header to make it obvious exactly which
commit I'd run through.
(This is another XFS commit that ended up in my rev-list range, low confidence
in the actual review, but I'm curious if AI got this one right)
commit 2e5c40a5b6ca722202bc0e99830b6ecf8755d19c
Author: Darrick J. Wong <djwong@kernel.org>
xfs: add media verification ioctl
[ ... ]
> diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c
> --- /dev/null
> +++ b/fs/xfs/xfs_verify_media.c
> @@ -0,0 +1,445 @@
[ ... ]
> +/* Walk reverse mappings to look for all file data loss */
> +static int
> +xfs_verify_report_losses(
> + struct xfs_mount *mp,
> + enum xfs_group_type type,
> + xfs_daddr_t daddr,
> + u64 bblen)
> +{
> + struct xfs_group *xg = NULL;
> + struct xfs_trans *tp;
> + xfs_fsblock_t start_bno, end_bno;
> + uint32_t start_gno, end_gno;
> + int error;
> +
> + if (type == XG_TYPE_RTG) {
> + start_bno = xfs_daddr_to_rtb(mp, daddr);
> + end_bno = xfs_daddr_to_rtb(mp, daddr + bblen - 1);
> + } else {
> + start_bno = XFS_DADDR_TO_FSB(mp, daddr);
> + end_bno = XFS_DADDR_TO_FSB(mp, daddr + bblen - 1);
> + }
> +
> + tp = xfs_trans_alloc_empty(mp);
> + start_gno = xfs_fsb_to_gno(mp, start_bno, type);
> + end_gno = xfs_fsb_to_gno(mp, end_bno, type);
> + while ((xg = xfs_group_next_range(mp, xg, start_gno, end_gno, type))) {
> + struct xfs_buf *agf_bp = NULL;
> + struct xfs_rtgroup *rtg = NULL;
> + struct xfs_btree_cur *cur;
> + struct xfs_rmap_irec ri_low = { };
> + struct xfs_rmap_irec ri_high;
> + struct xfs_group_data_lost lost;
> +
> + if (type == XG_TYPE_AG) {
> + struct xfs_perag *pag = to_perag(xg);
> +
> + error = xfs_alloc_read_agf(pag, tp, 0, &agf_bp);
> + if (error) {
> + xfs_perag_put(pag);
> + break;
> + }
> +
> + cur = xfs_rmapbt_init_cursor(mp, tp, agf_bp, pag);
> + } else {
> + rtg = to_rtg(xg);
> + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
> + cur = xfs_rtrmapbt_init_cursor(tp, rtg);
> + }
Does this code have a reference counting mismatch in the error paths?
The xfs_group returned by xfs_group_next_range() is acquired via
xfs_group_grab() which increments xg_active_ref.
In the error path at line 120, the code uses xfs_perag_put() to release
the reference:
error = xfs_alloc_read_agf(pag, tp, 0, &agf_bp);
if (error) {
xfs_perag_put(pag);
break;
}
And later in the loop, line 144 uses xfs_group_put().
Both xfs_perag_put() and xfs_group_put() decrement xg_ref, not
xg_active_ref. Looking at the reference counting implementation:
xfs_group_grab() calls atomic_inc_not_zero(&xg->xg_active_ref)
xfs_group_rele() calls atomic_dec(&xg->xg_active_ref)
xfs_group_put() calls atomic_dec(&xg->xg_ref)
Should these error paths use xfs_group_rele() instead to match the
xfs_group_grab() in xfs_group_next_range()?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v6.1 11/11] xfs: add media verification ioctl
2026-02-06 3:01 ` Chris Mason
@ 2026-02-06 4:53 ` Darrick J. Wong
0 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2026-02-06 4:53 UTC (permalink / raw)
To: Chris Mason; +Cc: cem, hch, linux-xfs, linux-fsdevel
On Thu, Feb 05, 2026 at 07:01:32PM -0800, Chris Mason wrote:
> "Darrick J. Wong" <djwong@kernel.org> wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > Add a new privileged ioctl so that xfs_scrub can ask the kernel to
> > verify the media of the devices backing an xfs filesystem, and have any
> > resulting media errors reported to fsnotify and xfs_healer.
>
> Hi everyone,
>
> I'm trying out my AI review prompts on a few more trees, and I ran it
> on the fuse-iomap-cache branch:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/log/?h=fuse-iomap-cache
>
> This was the latest email lore could find, apologies if I grabbed the wrong one.
>
> Hopefully the review below is useful, please let me know if there are places it
> has gone wildly wrong. I kept the header to make it obvious exactly which
> commit I'd run through.
>
> (This is another XFS commit that ended up in my rev-list range, low confidence
> in the actual review, but I'm curious if AI got this one right)
>
> commit 2e5c40a5b6ca722202bc0e99830b6ecf8755d19c
> Author: Darrick J. Wong <djwong@kernel.org>
>
> xfs: add media verification ioctl
>
> [ ... ]
>
> > diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c
> > --- /dev/null
> > +++ b/fs/xfs/xfs_verify_media.c
> > @@ -0,0 +1,445 @@
>
> [ ... ]
>
> > +/* Walk reverse mappings to look for all file data loss */
> > +static int
> > +xfs_verify_report_losses(
> > + struct xfs_mount *mp,
> > + enum xfs_group_type type,
> > + xfs_daddr_t daddr,
> > + u64 bblen)
> > +{
> > + struct xfs_group *xg = NULL;
> > + struct xfs_trans *tp;
> > + xfs_fsblock_t start_bno, end_bno;
> > + uint32_t start_gno, end_gno;
> > + int error;
> > +
> > + if (type == XG_TYPE_RTG) {
> > + start_bno = xfs_daddr_to_rtb(mp, daddr);
> > + end_bno = xfs_daddr_to_rtb(mp, daddr + bblen - 1);
> > + } else {
> > + start_bno = XFS_DADDR_TO_FSB(mp, daddr);
> > + end_bno = XFS_DADDR_TO_FSB(mp, daddr + bblen - 1);
> > + }
> > +
> > + tp = xfs_trans_alloc_empty(mp);
> > + start_gno = xfs_fsb_to_gno(mp, start_bno, type);
> > + end_gno = xfs_fsb_to_gno(mp, end_bno, type);
> > + while ((xg = xfs_group_next_range(mp, xg, start_gno, end_gno, type))) {
> > + struct xfs_buf *agf_bp = NULL;
> > + struct xfs_rtgroup *rtg = NULL;
> > + struct xfs_btree_cur *cur;
> > + struct xfs_rmap_irec ri_low = { };
> > + struct xfs_rmap_irec ri_high;
> > + struct xfs_group_data_lost lost;
> > +
> > + if (type == XG_TYPE_AG) {
> > + struct xfs_perag *pag = to_perag(xg);
> > +
> > + error = xfs_alloc_read_agf(pag, tp, 0, &agf_bp);
> > + if (error) {
> > + xfs_perag_put(pag);
> > + break;
> > + }
> > +
> > + cur = xfs_rmapbt_init_cursor(mp, tp, agf_bp, pag);
> > + } else {
> > + rtg = to_rtg(xg);
> > + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
> > + cur = xfs_rtrmapbt_init_cursor(tp, rtg);
> > + }
>
> Does this code have a reference counting mismatch in the error paths?
>
> The xfs_group returned by xfs_group_next_range() is acquired via
> xfs_group_grab() which increments xg_active_ref.
>
> In the error path at line 120, the code uses xfs_perag_put() to release
> the reference:
>
> error = xfs_alloc_read_agf(pag, tp, 0, &agf_bp);
> if (error) {
> xfs_perag_put(pag);
> break;
> }
>
> And later in the loop, line 144 uses xfs_group_put().
>
> Both xfs_perag_put() and xfs_group_put() decrement xg_ref, not
> xg_active_ref. Looking at the reference counting implementation:
>
> xfs_group_grab() calls atomic_inc_not_zero(&xg->xg_active_ref)
> xfs_group_rele() calls atomic_dec(&xg->xg_active_ref)
> xfs_group_put() calls atomic_dec(&xg->xg_ref)
>
> Should these error paths use xfs_group_rele() instead to match the
> xfs_group_grab() in xfs_group_next_range()?
Yep. Wouldn't it be nice if our type system could keep those things
straight... :/
--D
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 02/11] xfs: start creating infrastructure for health monitoring
[not found] ` <176852588582.2137143.1283636639551788931.stgit@frogsfrogsfrogs>
@ 2026-02-06 13:07 ` Pankaj Raghav (Samsung)
2026-02-06 17:47 ` Darrick J. Wong
0 siblings, 1 reply; 10+ messages in thread
From: Pankaj Raghav (Samsung) @ 2026-02-06 13:07 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: cem, hch, linux-xfs, linux-fsdevel, p.raghav
> +static DEFINE_SPINLOCK(xfs_healthmon_lock);
> +
> +/* Grab a reference to the healthmon object for a given mount, if any. */
> +static struct xfs_healthmon *
> +xfs_healthmon_get(
> + struct xfs_mount *mp)
> +{
> + struct xfs_healthmon *hm;
> +
> + rcu_read_lock();
> + hm = mp->m_healthmon;
Nit: Should we do a READ_ONCE(mp->m_healthmon) here to avoid any
compiler tricks that can result in an undefined behaviour? I am not sure
if I am being paranoid here.
> + if (hm && !refcount_inc_not_zero(&hm->ref))
> + hm = NULL;
> + rcu_read_unlock();
> +
> + return hm;
> +}
> +
> +/*
--
Pankaj
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 02/11] xfs: start creating infrastructure for health monitoring
2026-02-06 13:07 ` [PATCH 02/11] xfs: start creating infrastructure for health monitoring Pankaj Raghav (Samsung)
@ 2026-02-06 17:47 ` Darrick J. Wong
2026-02-06 18:54 ` Pankaj Raghav
0 siblings, 1 reply; 10+ messages in thread
From: Darrick J. Wong @ 2026-02-06 17:47 UTC (permalink / raw)
To: Pankaj Raghav (Samsung); +Cc: cem, hch, linux-xfs, linux-fsdevel, p.raghav
On Fri, Feb 06, 2026 at 02:07:56PM +0100, Pankaj Raghav (Samsung) wrote:
> > +static DEFINE_SPINLOCK(xfs_healthmon_lock);
> > +
> > +/* Grab a reference to the healthmon object for a given mount, if any. */
> > +static struct xfs_healthmon *
> > +xfs_healthmon_get(
> > + struct xfs_mount *mp)
> > +{
> > + struct xfs_healthmon *hm;
> > +
> > + rcu_read_lock();
> > + hm = mp->m_healthmon;
>
> Nit: Should we do a READ_ONCE(mp->m_healthmon) here to avoid any
> compiler tricks that can result in an undefined behaviour? I am not sure
> if I am being paranoid here.
Compiler tricks? We've taken the rcu read lock, which adds an
optimization barrier so that the mp->m_healthmon access can't be
reordered before the rcu_read_lock. I'm not sure if that answers your
question.
<confused>
--D
> > + if (hm && !refcount_inc_not_zero(&hm->ref))
> > + hm = NULL;
> > + rcu_read_unlock();
> > +
> > + return hm;
> > +}
> > +
> > +/*
> --
> Pankaj
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 02/11] xfs: start creating infrastructure for health monitoring
2026-02-06 17:47 ` Darrick J. Wong
@ 2026-02-06 18:54 ` Pankaj Raghav
2026-02-06 20:41 ` Darrick J. Wong
0 siblings, 1 reply; 10+ messages in thread
From: Pankaj Raghav @ 2026-02-06 18:54 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: cem, hch, linux-xfs, linux-fsdevel, p.raghav
On 2/6/26 18:47, Darrick J. Wong wrote:
> On Fri, Feb 06, 2026 at 02:07:56PM +0100, Pankaj Raghav (Samsung) wrote:
>>> +static DEFINE_SPINLOCK(xfs_healthmon_lock);
>>> +
>>> +/* Grab a reference to the healthmon object for a given mount, if any. */
>>> +static struct xfs_healthmon *
>>> +xfs_healthmon_get(
>>> + struct xfs_mount *mp)
>>> +{
>>> + struct xfs_healthmon *hm;
>>> +
>>> + rcu_read_lock();
>>> + hm = mp->m_healthmon;
>>
>> Nit: Should we do a READ_ONCE(mp->m_healthmon) here to avoid any
>> compiler tricks that can result in an undefined behaviour? I am not sure
>> if I am being paranoid here.
>
> Compiler tricks? We've taken the rcu read lock, which adds an
> optimization barrier so that the mp->m_healthmon access can't be
> reordered before the rcu_read_lock. I'm not sure if that answers your
> question.
>
This answers. So this is my understanding: RCU guarantees that we get a valid
object (actual data of m_healthmon) but does not guarantee the compiler will not reread
the pointer between checking if hm is !NULL and accessing the pointer as we are doing it
lockless.
So just a barrier() call in rcu_read_lock is enough to make sure this doesn't happen and probably
adding a READ_ONCE() is not needed?
--
Pankaj
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 02/11] xfs: start creating infrastructure for health monitoring
2026-02-06 18:54 ` Pankaj Raghav
@ 2026-02-06 20:41 ` Darrick J. Wong
2026-02-09 6:34 ` Christoph Hellwig
0 siblings, 1 reply; 10+ messages in thread
From: Darrick J. Wong @ 2026-02-06 20:41 UTC (permalink / raw)
To: Pankaj Raghav; +Cc: cem, hch, linux-xfs, linux-fsdevel, p.raghav
On Fri, Feb 06, 2026 at 07:54:51PM +0100, Pankaj Raghav wrote:
>
>
> On 2/6/26 18:47, Darrick J. Wong wrote:
> > On Fri, Feb 06, 2026 at 02:07:56PM +0100, Pankaj Raghav (Samsung) wrote:
> >>> +static DEFINE_SPINLOCK(xfs_healthmon_lock);
> >>> +
> >>> +/* Grab a reference to the healthmon object for a given mount, if any. */
> >>> +static struct xfs_healthmon *
> >>> +xfs_healthmon_get(
> >>> + struct xfs_mount *mp)
> >>> +{
> >>> + struct xfs_healthmon *hm;
> >>> +
> >>> + rcu_read_lock();
> >>> + hm = mp->m_healthmon;
> >>
> >> Nit: Should we do a READ_ONCE(mp->m_healthmon) here to avoid any
> >> compiler tricks that can result in an undefined behaviour? I am not sure
> >> if I am being paranoid here.
> >
> > Compiler tricks? We've taken the rcu read lock, which adds an
> > optimization barrier so that the mp->m_healthmon access can't be
> > reordered before the rcu_read_lock. I'm not sure if that answers your
> > question.
> >
>
> This answers. So this is my understanding: RCU guarantees that we get
> a valid object (actual data of m_healthmon) but does not guarantee the
> compiler will not reread the pointer between checking if hm is !NULL
> and accessing the pointer as we are doing it lockless.
Oh, now I see what you're concerned about. You're worried that the
compiler could turn this:
if (hm && !refcount_inc_not_zero(&hm->ref))
into this:
if (mp->m_healthmon && !refcount_inc_not_zero(&mp->m_healthmon->ref))
which then gives xfs_healthmon_detach the opening it needs to slip in
between the two dereferences of mp and turn m_healthmon into NULL,
leading the "mp->m_healthmon->ref" expression to become a NULL pointer
dereference.
> So just a barrier() call in rcu_read_lock is enough to make sure this
> doesn't happen and probably adding a READ_ONCE() is not needed?
Nope. You're right, we do need READ_ONCE here.
--D
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 02/11] xfs: start creating infrastructure for health monitoring
2026-02-06 20:41 ` Darrick J. Wong
@ 2026-02-09 6:34 ` Christoph Hellwig
2026-02-10 4:57 ` Darrick J. Wong
0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2026-02-09 6:34 UTC (permalink / raw)
To: Darrick J. Wong
Cc: Pankaj Raghav, cem, hch, linux-xfs, linux-fsdevel, p.raghav
On Fri, Feb 06, 2026 at 12:41:35PM -0800, Darrick J. Wong wrote:
> > So just a barrier() call in rcu_read_lock is enough to make sure this
> > doesn't happen and probably adding a READ_ONCE() is not needed?
>
> Nope. You're right, we do need READ_ONCE here.
The right thing is to use rcu_dereference / rcu_assign_pointer and add a
__rcu annotation to m_healthmon.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 02/11] xfs: start creating infrastructure for health monitoring
2026-02-09 6:34 ` Christoph Hellwig
@ 2026-02-10 4:57 ` Darrick J. Wong
0 siblings, 0 replies; 10+ messages in thread
From: Darrick J. Wong @ 2026-02-10 4:57 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Pankaj Raghav, cem, linux-xfs, linux-fsdevel, p.raghav
On Mon, Feb 09, 2026 at 07:34:21AM +0100, Christoph Hellwig wrote:
> On Fri, Feb 06, 2026 at 12:41:35PM -0800, Darrick J. Wong wrote:
> > > So just a barrier() call in rcu_read_lock is enough to make sure this
> > > doesn't happen and probably adding a READ_ONCE() is not needed?
> >
> > Nope. You're right, we do need READ_ONCE here.
>
> The right thing is to use rcu_dereference / rcu_assign_pointer and add a
> __rcu annotation to m_healthmon.
Noted, will change my fixpatch to do that. Thanks for the pointer!
--D
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-02-10 4:57 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <176852588473.2137143.1604994842772101197.stgit@frogsfrogsfrogs>
[not found] ` <176852588776.2137143.7103003682733018282.stgit@frogsfrogsfrogs>
[not found] ` <20260120041226.GJ15551@frogsfrogsfrogs>
[not found] ` <20260120071830.GA5686@lst.de>
[not found] ` <20260120180040.GU15551@frogsfrogsfrogs>
2026-01-21 7:05 ` [PATCH v6.1 11/11] xfs: add media verification ioctl Christoph Hellwig
2026-01-21 19:58 ` Darrick J. Wong
2026-02-06 3:01 ` Chris Mason
2026-02-06 4:53 ` Darrick J. Wong
[not found] ` <176852588582.2137143.1283636639551788931.stgit@frogsfrogsfrogs>
2026-02-06 13:07 ` [PATCH 02/11] xfs: start creating infrastructure for health monitoring Pankaj Raghav (Samsung)
2026-02-06 17:47 ` Darrick J. Wong
2026-02-06 18:54 ` Pankaj Raghav
2026-02-06 20:41 ` Darrick J. Wong
2026-02-09 6:34 ` Christoph Hellwig
2026-02-10 4:57 ` Darrick J. Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox