* [PATCH V3 0/3] md/raid0: fix a takeover BUG and tidy member-size rounding
@ 2026-11-02 8:38 Zizhi Wo
2026-11-02 8:38 ` [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array Zizhi Wo
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Zizhi Wo @ 2026-11-02 8:38 UTC (permalink / raw)
To: song, yukuai, magiclinan, xiao, linux-raid
Cc: linux-kernel, yangerkun, chengzhihao1, wozizhi
Patch 1 fixes a syzbot BUG() in find_zone(): a takeover can build strip
zones that cover less than the array still advertises, and I/O for the tail
reaches find_zone(), which cannot map it. Reject such a takeover up front.
Patch 2 factors out the "member size rounded down to a chunk" computation.
Patch 3 uses it in raid0_size() in place of a power-of-2 mask, which is not
a round down for a non-power-of-2 chunk, to consistent with how
create_strip_zones() already rounds the members when building the zones.
Changes since v2:
- Dropped the first three patches; only the last three are kept. The
changes needed to restore state on a failed takeover, as well as on the
subsequent error paths in level_store(), are fairly large and are not
addressed in this patch set for now.
v2:
https://lore.kernel.org/all/20261019010827.2922617-1-wozizhi@huaweicloud.com/
v1:
https://lore.kernel.org/all/20261017005802.2212102-1-wozizhi@huaweicloud.com/
Zizhi Wo (3):
md/raid0: reject a takeover whose zones cannot cover the array
md/raid0: factor out raid0_member_sectors()
md/raid0: round member size in raid0_size() with sector_div()
drivers/md/raid0.c | 48 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 5 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array 2026-11-02 8:38 [PATCH V3 0/3] md/raid0: fix a takeover BUG and tidy member-size rounding Zizhi Wo @ 2026-11-02 8:38 ` Zizhi Wo 2026-11-06 6:34 ` yu kuai 2026-11-02 8:38 ` [PATCH V3 2/3] md/raid0: factor out raid0_member_sectors() Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 3/3] md/raid0: round member size in raid0_size() with sector_div() Zizhi Wo 2 siblings, 1 reply; 6+ messages in thread From: Zizhi Wo @ 2026-11-02 8:38 UTC (permalink / raw) To: song, yukuai, magiclinan, xiao, linux-raid Cc: linux-kernel, yangerkun, chengzhihao1, wozizhi From: Zizhi Wo <wozizhi@huawei.com> If a raid0 takeover builds strip zones that cover less than the advertised array size, the block layer still accepts I/O for the whole size. raid0_make_request() hands any request past the zones to the mapping code, which fails to map it and triggers a BUG_ON. The zones are built from the member sizes in rdev->sectors, which may not match the size the array already advertises, so the zones can come out covering less than it. The extreme case is a member with no size recorded at all: an array created without metadata imports its devices through md_import_device(dev, -1, -1), which never sets rdev->sectors, and bind_rdev_to_array() does not reject such a member either, because its check that mddev->dev_sectors fits inside a member is skipped when rdev->sectors is zero. Refuse a raid0 takeover when its zones cannot cover the size the gendisk advertises. This prevents the takeover from silently shrinking the array, mirroring the rule raid5_start_reshape() and raid10_start_reshape() apply to a reshape. The check iterates the same devices and uses the same rounding as create_strip_zones(). It does not skip devices with rdev->raid_disk < 0: such devices cannot be raid0 members, so counting them only overestimates the coverage and, if present, the takeover fails later in create_strip_zones() anyway. Fixes: 9af204cf720c ("md: Add support for Raid5->Raid0 and Raid10->Raid0 takeover") Fixes: fc3a08b85b7a ("Add raid1->raid0 takeover support") Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/md/raid0.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 35e103f0c2c3..fccc62a5fecc 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -643,6 +643,34 @@ static void raid0_error(struct mddev *mddev, struct md_rdev *rdev) } } +/* + * Refuse a takeover whose strip zones cannot cover the capacity the gendisk + * advertises: raid0 derives those zones from the sizes of its members, so + * find_zone() cannot map I/O that falls beyond them. + */ +static int raid0_takeover_check(struct mddev *mddev, int chunk) +{ + sector_t capacity = get_capacity(mddev->gendisk); + sector_t coverage = 0; + struct md_rdev *rdev; + + rdev_for_each(rdev, mddev) { + sector_t sectors = rdev->sectors; + + sector_div(sectors, chunk); + coverage += sectors * chunk; + } + + if (coverage < capacity) { + pr_warn("md/raid0:%s: refusing takeover, zones cover only %llu of %llu sectors\n", + mdname(mddev), (unsigned long long)coverage, + (unsigned long long)capacity); + return -EINVAL; + } + + return 0; +} + static void *raid0_takeover_raid45(struct mddev *mddev) { struct md_rdev *rdev; @@ -665,6 +693,9 @@ static void *raid0_takeover_raid45(struct mddev *mddev) rdev->sectors = mddev->dev_sectors; } + if (raid0_takeover_check(mddev, mddev->chunk_sectors)) + return ERR_PTR(-EINVAL); + /* Set new parameters */ mddev->new_level = 0; mddev->new_layout = 0; @@ -707,6 +738,9 @@ static void *raid0_takeover_raid10(struct mddev *mddev) return ERR_PTR(-EINVAL); } + if (raid0_takeover_check(mddev, mddev->chunk_sectors)) + return ERR_PTR(-EINVAL); + /* Set new parameters */ mddev->new_level = 0; mddev->new_layout = 0; @@ -750,6 +784,9 @@ static void *raid0_takeover_raid1(struct mddev *mddev) /* array size does not allow a suitable chunk size */ return ERR_PTR(-EINVAL); + if (raid0_takeover_check(mddev, chunksect)) + return ERR_PTR(-EINVAL); + /* Set new parameters */ mddev->new_level = 0; mddev->new_layout = 0; -- 2.52.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array 2026-11-02 8:38 ` [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array Zizhi Wo @ 2026-11-06 6:34 ` yu kuai 2026-11-06 8:20 ` Zizhi Wo 0 siblings, 1 reply; 6+ messages in thread From: yu kuai @ 2026-11-06 6:34 UTC (permalink / raw) To: Zizhi Wo, song, magiclinan, xiao, linux-raid, yu kuai Cc: linux-kernel, yangerkun, chengzhihao1, wozizhi Hi, 在 2026/11/2 16:38, Zizhi Wo 写道: > From: Zizhi Wo <wozizhi@huawei.com> > > If a raid0 takeover builds strip zones that cover less than the advertised > array size, the block layer still accepts I/O for the whole size. > raid0_make_request() hands any request past the zones to the mapping code, > which fails to map it and triggers a BUG_ON. > > The zones are built from the member sizes in rdev->sectors, which may not > match the size the array already advertises, so the zones can come out > covering less than it. The extreme case is a member with no size recorded > at all: an array created without metadata imports its devices through > md_import_device(dev, -1, -1), which never sets rdev->sectors, and > bind_rdev_to_array() does not reject such a member either, because its > check that mddev->dev_sectors fits inside a member is skipped when > rdev->sectors is zero. > > Refuse a raid0 takeover when its zones cannot cover the size the gendisk > advertises. This prevents the takeover from silently shrinking the array, > mirroring the rule raid5_start_reshape() and raid10_start_reshape() apply > to a reshape. > > The check iterates the same devices and uses the same rounding as > create_strip_zones(). It does not skip devices with rdev->raid_disk < 0: > such devices cannot be raid0 members, so counting them only overestimates > the coverage and, if present, the takeover fails later in > create_strip_zones() anyway. > > Fixes: 9af204cf720c ("md: Add support for Raid5->Raid0 and Raid10->Raid0 takeover") > Fixes: fc3a08b85b7a ("Add raid1->raid0 takeover support") > Signed-off-by: Zizhi Wo <wozizhi@huawei.com> > --- > drivers/md/raid0.c | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c > index 35e103f0c2c3..fccc62a5fecc 100644 > --- a/drivers/md/raid0.c > +++ b/drivers/md/raid0.c > @@ -643,6 +643,34 @@ static void raid0_error(struct mddev *mddev, struct md_rdev *rdev) > } > } > > +/* > + * Refuse a takeover whose strip zones cannot cover the capacity the gendisk > + * advertises: raid0 derives those zones from the sizes of its members, so > + * find_zone() cannot map I/O that falls beyond them. > + */ > +static int raid0_takeover_check(struct mddev *mddev, int chunk) > +{ > + sector_t capacity = get_capacity(mddev->gendisk); > + sector_t coverage = 0; > + struct md_rdev *rdev; > + > + rdev_for_each(rdev, mddev) { > + sector_t sectors = rdev->sectors; > + > + sector_div(sectors, chunk); > + coverage += sectors * chunk; > + } > + > + if (coverage < capacity) { > + pr_warn("md/raid0:%s: refusing takeover, zones cover only %llu of %llu sectors\n", > + mdname(mddev), (unsigned long long)coverage, > + (unsigned long long)capacity); Other than raid1, other levels already have mddev->chunk_secotrs set, and raid456/raid10 already have a full functional raid0, their takeover can not fail. Noted normally mdadm will set rdev->sectors and 1.x metadata will reject zero rdev->sectors in super_1_load. However, it's still possible raid1 can be created with rdev->sectors be zero, this is the root cause of the problem syzbot reported. Although raid0_takeover_raid1() already calculate chunksect by mddev->array_sectors, which is exactly the real rdev->sectors for raid1, and it should be guaranteed such takeover can succeed. However, as it's legacy usage that rdev->sectors can be zero, I'll suggest just checking rdev->sectors in raid0_takeover_raid1() and reject if it's 0. > + return -EINVAL; > + } > + > + return 0; > +} > + > static void *raid0_takeover_raid45(struct mddev *mddev) > { > struct md_rdev *rdev; > @@ -665,6 +693,9 @@ static void *raid0_takeover_raid45(struct mddev *mddev) > rdev->sectors = mddev->dev_sectors; > } > > + if (raid0_takeover_check(mddev, mddev->chunk_sectors)) > + return ERR_PTR(-EINVAL); > + > /* Set new parameters */ > mddev->new_level = 0; > mddev->new_layout = 0; > @@ -707,6 +738,9 @@ static void *raid0_takeover_raid10(struct mddev *mddev) > return ERR_PTR(-EINVAL); > } > > + if (raid0_takeover_check(mddev, mddev->chunk_sectors)) > + return ERR_PTR(-EINVAL); > + > /* Set new parameters */ > mddev->new_level = 0; > mddev->new_layout = 0; > @@ -750,6 +784,9 @@ static void *raid0_takeover_raid1(struct mddev *mddev) > /* array size does not allow a suitable chunk size */ > return ERR_PTR(-EINVAL); > > + if (raid0_takeover_check(mddev, chunksect)) > + return ERR_PTR(-EINVAL); > + > /* Set new parameters */ > mddev->new_level = 0; > mddev->new_layout = 0; -- Thanks, Kuai ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array 2026-11-06 6:34 ` yu kuai @ 2026-11-06 8:20 ` Zizhi Wo 0 siblings, 0 replies; 6+ messages in thread From: Zizhi Wo @ 2026-11-06 8:20 UTC (permalink / raw) To: yukuai, song, magiclinan, xiao, linux-raid Cc: linux-kernel, yangerkun, chengzhihao1, wozizhi Hi,yukuai 在 2026/11/6 14:34, yu kuai 写道: > Hi, > > 在 2026/11/2 16:38, Zizhi Wo 写道: >> From: Zizhi Wo <wozizhi@huawei.com> >> >> If a raid0 takeover builds strip zones that cover less than the advertised >> array size, the block layer still accepts I/O for the whole size. >> raid0_make_request() hands any request past the zones to the mapping code, >> which fails to map it and triggers a BUG_ON. >> >> The zones are built from the member sizes in rdev->sectors, which may not >> match the size the array already advertises, so the zones can come out >> covering less than it. The extreme case is a member with no size recorded >> at all: an array created without metadata imports its devices through >> md_import_device(dev, -1, -1), which never sets rdev->sectors, and >> bind_rdev_to_array() does not reject such a member either, because its >> check that mddev->dev_sectors fits inside a member is skipped when >> rdev->sectors is zero. >> >> Refuse a raid0 takeover when its zones cannot cover the size the gendisk >> advertises. This prevents the takeover from silently shrinking the array, >> mirroring the rule raid5_start_reshape() and raid10_start_reshape() apply >> to a reshape. >> >> The check iterates the same devices and uses the same rounding as >> create_strip_zones(). It does not skip devices with rdev->raid_disk < 0: >> such devices cannot be raid0 members, so counting them only overestimates >> the coverage and, if present, the takeover fails later in >> create_strip_zones() anyway. >> >> Fixes: 9af204cf720c ("md: Add support for Raid5->Raid0 and Raid10->Raid0 takeover") >> Fixes: fc3a08b85b7a ("Add raid1->raid0 takeover support") >> Signed-off-by: Zizhi Wo <wozizhi@huawei.com> >> --- >> drivers/md/raid0.c | 37 +++++++++++++++++++++++++++++++++++++ >> 1 file changed, 37 insertions(+) >> >> diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c >> index 35e103f0c2c3..fccc62a5fecc 100644 >> --- a/drivers/md/raid0.c >> +++ b/drivers/md/raid0.c >> @@ -643,6 +643,34 @@ static void raid0_error(struct mddev *mddev, struct md_rdev *rdev) >> } >> } >> >> +/* >> + * Refuse a takeover whose strip zones cannot cover the capacity the gendisk >> + * advertises: raid0 derives those zones from the sizes of its members, so >> + * find_zone() cannot map I/O that falls beyond them. >> + */ >> +static int raid0_takeover_check(struct mddev *mddev, int chunk) >> +{ >> + sector_t capacity = get_capacity(mddev->gendisk); >> + sector_t coverage = 0; >> + struct md_rdev *rdev; >> + >> + rdev_for_each(rdev, mddev) { >> + sector_t sectors = rdev->sectors; >> + >> + sector_div(sectors, chunk); >> + coverage += sectors * chunk; >> + } >> + >> + if (coverage < capacity) { >> + pr_warn("md/raid0:%s: refusing takeover, zones cover only %llu of %llu sectors\n", >> + mdname(mddev), (unsigned long long)coverage, >> + (unsigned long long)capacity); > > Other than raid1, other levels already have mddev->chunk_secotrs set, and raid456/raid10 already > have a full functional raid0, their takeover can not fail. > > Noted normally mdadm will set rdev->sectors and 1.x metadata will reject zero rdev->sectors in super_1_load. > However, it's still possible raid1 can be created with rdev->sectors be zero, this is the root cause of the > problem syzbot reported. > Please consider the following two cases, both of which reproduce the same BUG_ON locally for me: 1. An array created without metadata leaves rdev->sectors at 0. This isn't raid1-specific — raid10 hits the same BUG_ON too. raid45 only escapes because raid0_takeover_raid45() overwrites rdev->sectors with mddev->dev_sectors first; raid0_takeover_raid10() doesn't. 2. Even with valid non-zero rdev->sectors, growing the chunk of a running raid45 can make the post-takeover coverage smaller than the previously advertised gendisk capacity. E.g. create a raid5 with component_size=8K, chunk=4K, run it, then change chunk to 16K and run raid0_takeover_raid45(). So I think the real root cause is that the size changes across the takeover, and rdev->sectors == 0 is just one special case of it. That's why the patch compares coverage against the gendisk capacity on every takeover path. For case 2, the problem exists even without a takeover: if the chunk change shrinks the usable size, I/O from the upper filesystem will break just the same. So I'm now inclined to reject a chunk change in raid5/10 when it would shrink the usable array size, and additionally check rdev- >sectors for raid1/10 at the takeover path. What do you think? Thanks, Zizhi Wo > Although raid0_takeover_raid1() already calculate chunksect by mddev->array_sectors, which is exactly the > real rdev->sectors for raid1, and it should be guaranteed such takeover can succeed. However, as it's legacy > usage that rdev->sectors can be zero, I'll suggest just checking rdev->sectors in raid0_takeover_raid1() and > reject if it's 0. > >> + return -EINVAL; >> + } >> + >> + return 0; >> +} >> + >> static void *raid0_takeover_raid45(struct mddev *mddev) >> { >> struct md_rdev *rdev; >> @@ -665,6 +693,9 @@ static void *raid0_takeover_raid45(struct mddev *mddev) >> rdev->sectors = mddev->dev_sectors; >> } >> >> + if (raid0_takeover_check(mddev, mddev->chunk_sectors)) >> + return ERR_PTR(-EINVAL); >> + >> /* Set new parameters */ >> mddev->new_level = 0; >> mddev->new_layout = 0; >> @@ -707,6 +738,9 @@ static void *raid0_takeover_raid10(struct mddev *mddev) >> return ERR_PTR(-EINVAL); >> } >> >> + if (raid0_takeover_check(mddev, mddev->chunk_sectors)) >> + return ERR_PTR(-EINVAL); >> + >> /* Set new parameters */ >> mddev->new_level = 0; >> mddev->new_layout = 0; >> @@ -750,6 +784,9 @@ static void *raid0_takeover_raid1(struct mddev *mddev) >> /* array size does not allow a suitable chunk size */ >> return ERR_PTR(-EINVAL); >> >> + if (raid0_takeover_check(mddev, chunksect)) >> + return ERR_PTR(-EINVAL); >> + >> /* Set new parameters */ >> mddev->new_level = 0; >> mddev->new_layout = 0; > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH V3 2/3] md/raid0: factor out raid0_member_sectors() 2026-11-02 8:38 [PATCH V3 0/3] md/raid0: fix a takeover BUG and tidy member-size rounding Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array Zizhi Wo @ 2026-11-02 8:38 ` Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 3/3] md/raid0: round member size in raid0_size() with sector_div() Zizhi Wo 2 siblings, 0 replies; 6+ messages in thread From: Zizhi Wo @ 2026-11-02 8:38 UTC (permalink / raw) To: song, yukuai, magiclinan, xiao, linux-raid Cc: linux-kernel, yangerkun, chengzhihao1, wozizhi From: Zizhi Wo <wozizhi@huawei.com> create_strip_zones() and the takeover coverage check both compute the size a member contributes to a raid0 array. Pull that into a small helper so the two sites share one definition. No functional change. Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/md/raid0.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index fccc62a5fecc..c96ee54f9acc 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -63,6 +63,12 @@ static void dump_zones(struct mddev *mddev) } } +static sector_t raid0_member_sectors(sector_t sectors, unsigned int chunk) +{ + sector_div(sectors, chunk); + return sectors * chunk; +} + static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) { int i, c, err; @@ -86,9 +92,8 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) c = 0; /* round size to chunk_size */ - sectors = rdev1->sectors; - sector_div(sectors, mddev->chunk_sectors); - rdev1->sectors = sectors * mddev->chunk_sectors; + rdev1->sectors = raid0_member_sectors(rdev1->sectors, + mddev->chunk_sectors); if (mddev_is_dm(mddev)) blksize = max(blksize, queue_logical_block_size( @@ -654,12 +659,8 @@ static int raid0_takeover_check(struct mddev *mddev, int chunk) sector_t coverage = 0; struct md_rdev *rdev; - rdev_for_each(rdev, mddev) { - sector_t sectors = rdev->sectors; - - sector_div(sectors, chunk); - coverage += sectors * chunk; - } + rdev_for_each(rdev, mddev) + coverage += raid0_member_sectors(rdev->sectors, chunk); if (coverage < capacity) { pr_warn("md/raid0:%s: refusing takeover, zones cover only %llu of %llu sectors\n", -- 2.52.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH V3 3/3] md/raid0: round member size in raid0_size() with sector_div() 2026-11-02 8:38 [PATCH V3 0/3] md/raid0: fix a takeover BUG and tidy member-size rounding Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 2/3] md/raid0: factor out raid0_member_sectors() Zizhi Wo @ 2026-11-02 8:38 ` Zizhi Wo 2 siblings, 0 replies; 6+ messages in thread From: Zizhi Wo @ 2026-11-02 8:38 UTC (permalink / raw) To: song, yukuai, magiclinan, xiao, linux-raid Cc: linux-kernel, yangerkun, chengzhihao1, wozizhi From: Zizhi Wo <wozizhi@huawei.com> raid0_size() rounds each member device down to the chunk boundary by masking with 'chunk_sectors - 1': rdev->sectors & ~(sector_t)(mddev->chunk_sectors - 1) This bit-masking only yields a correct round-down when chunk_sectors is a power of 2. However, raid0 also supports non-power-of-2 chunk sizes, as handled in raid0_make_request() and map_sector(), so the rounding is wrong in that case. Use raid0_member_sectors() instead, so that each member is rounded down with sector_div() for any chunk size, consistent with how create_strip_zones() already rounds the members when building the zones. Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/md/raid0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index c96ee54f9acc..623b0701ce70 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -369,8 +369,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks "%s does not support generic reshape\n", __func__); rdev_for_each(rdev, mddev) - array_sectors += (rdev->sectors & - ~(sector_t)(mddev->chunk_sectors-1)); + array_sectors += raid0_member_sectors(rdev->sectors, + mddev->chunk_sectors); return array_sectors; } -- 2.52.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-06 8:20 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-02 8:38 [PATCH V3 0/3] md/raid0: fix a takeover BUG and tidy member-size rounding Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 1/3] md/raid0: reject a takeover whose zones cannot cover the array Zizhi Wo 2026-11-06 6:34 ` yu kuai 2026-11-06 8:20 ` Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 2/3] md/raid0: factor out raid0_member_sectors() Zizhi Wo 2026-11-02 8:38 ` [PATCH V3 3/3] md/raid0: round member size in raid0_size() with sector_div() Zizhi Wo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®