mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kamal Mostafa <kamal@canonical.com>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	kernel-team@lists.ubuntu.com
Cc: Alex Elder <elder@linaro.org>, Ilya Dryomov <idryomov@gmail.com>,
	Kamal Mostafa <kamal@canonical.com>
Subject: [PATCH 3.19.y-ckt 027/102] rbd: fix copyup completion race
Date: Tue, 22 Sep 2015 10:51:23 -0700	[thread overview]
Message-ID: <1442944358-1248-28-git-send-email-kamal@canonical.com> (raw)
In-Reply-To: <1442944358-1248-1-git-send-email-kamal@canonical.com>

3.19.8-ckt7 -stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Dryomov <idryomov@gmail.com>

commit 2761713d35e370fd640b5781109f753066b746c4 upstream.

For write/discard obj_requests that involved a copyup method call, the
opcode of the first op is CEPH_OSD_OP_CALL and the ->callback is
rbd_img_obj_copyup_callback().  The latter frees copyup pages, sets
->xferred and delegates to rbd_img_obj_callback(), the "normal" image
object callback, for reporting to block layer and putting refs.

rbd_osd_req_callback() however treats CEPH_OSD_OP_CALL as a trivial op,
which means obj_request is marked done in rbd_osd_trivial_callback(),
*before* ->callback is invoked and rbd_img_obj_copyup_callback() has
a chance to run.  Marking obj_request done essentially means giving
rbd_img_obj_callback() a license to end it at any moment, so if another
obj_request from the same img_request is being completed concurrently,
rbd_img_obj_end_request() may very well be called on such prematurally
marked done request:

<obj_request-1/2 reply>
handle_reply()
  rbd_osd_req_callback()
    rbd_osd_trivial_callback()
    rbd_obj_request_complete()
    rbd_img_obj_copyup_callback()
    rbd_img_obj_callback()
                                    <obj_request-2/2 reply>
                                    handle_reply()
                                      rbd_osd_req_callback()
                                        rbd_osd_trivial_callback()
      for_each_obj_request(obj_request->img_request) {
        rbd_img_obj_end_request(obj_request-1/2)
        rbd_img_obj_end_request(obj_request-2/2) <--
      }

Calling rbd_img_obj_end_request() on such a request leads to trouble,
in particular because its ->xfferred is 0.  We report 0 to the block
layer with blk_update_request(), get back 1 for "this request has more
data in flight" and then trip on

    rbd_assert(more ^ (which == img_request->obj_request_count));

with rhs (which == ...) being 1 because rbd_img_obj_end_request() has
been called for both requests and lhs (more) being 1 because we haven't
got a chance to set ->xfferred in rbd_img_obj_copyup_callback() yet.

To fix this, leverage that rbd wants to call class methods in only two
cases: one is a generic method call wrapper (obj_request is standalone)
and the other is a copyup (obj_request is part of an img_request).  So
make a dedicated handler for CEPH_OSD_OP_CALL and directly invoke
rbd_img_obj_copyup_callback() from it if obj_request is part of an
img_request, similar to how CEPH_OSD_OP_READ handler invokes
rbd_img_obj_request_read_callback().

Since rbd_img_obj_copyup_callback() is now being called from the OSD
request callback (only), it is renamed to rbd_osd_copyup_callback().

Cc: Alex Elder <elder@linaro.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 drivers/block/rbd.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 0c4ede9..f33ff6c 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -520,6 +520,7 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...)
 #  define rbd_assert(expr)	((void) 0)
 #endif /* !RBD_DEBUG */
 
+static void rbd_osd_copyup_callback(struct rbd_obj_request *obj_request);
 static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request);
 static void rbd_img_parent_read(struct rbd_obj_request *obj_request);
 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
@@ -1795,6 +1796,16 @@ static void rbd_osd_stat_callback(struct rbd_obj_request *obj_request)
 	obj_request_done_set(obj_request);
 }
 
+static void rbd_osd_call_callback(struct rbd_obj_request *obj_request)
+{
+	dout("%s: obj %p\n", __func__, obj_request);
+
+	if (obj_request_img_data_test(obj_request))
+		rbd_osd_copyup_callback(obj_request);
+	else
+		obj_request_done_set(obj_request);
+}
+
 static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
 				struct ceph_msg *msg)
 {
@@ -1842,6 +1853,8 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
 		rbd_osd_discard_callback(obj_request);
 		break;
 	case CEPH_OSD_OP_CALL:
+		rbd_osd_call_callback(obj_request);
+		break;
 	case CEPH_OSD_OP_NOTIFY_ACK:
 	case CEPH_OSD_OP_WATCH:
 		rbd_osd_trivial_callback(obj_request);
@@ -2503,13 +2516,15 @@ out_unwind:
 }
 
 static void
-rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
+rbd_osd_copyup_callback(struct rbd_obj_request *obj_request)
 {
 	struct rbd_img_request *img_request;
 	struct rbd_device *rbd_dev;
 	struct page **pages;
 	u32 page_count;
 
+	dout("%s: obj %p\n", __func__, obj_request);
+
 	rbd_assert(obj_request->type == OBJ_REQUEST_BIO ||
 		obj_request->type == OBJ_REQUEST_NODATA);
 	rbd_assert(obj_request_img_data_test(obj_request));
@@ -2536,9 +2551,7 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
 	if (!obj_request->result)
 		obj_request->xferred = obj_request->length;
 
-	/* Finish up with the normal image object callback */
-
-	rbd_img_obj_callback(obj_request);
+	obj_request_done_set(obj_request);
 }
 
 static void
@@ -2623,7 +2636,6 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
 
 	/* All set, send it off. */
 
-	orig_request->callback = rbd_img_obj_copyup_callback;
 	osdc = &rbd_dev->rbd_client->client->osdc;
 	img_result = rbd_obj_request_submit(osdc, orig_request);
 	if (!img_result)
-- 
1.9.1


  parent reply	other threads:[~2015-09-22 18:25 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-22 17:50 [3.19.y-ckt stable] Linux 3.19.8-ckt7 stable review Kamal Mostafa
2015-09-22 17:50 ` [PATCH 3.19.y-ckt 001/102] [3.19-stable only] Revert "dmaengine: pl330: Fix overflow when reporting residue in memcpy" Kamal Mostafa
2015-09-22 17:50 ` [PATCH 3.19.y-ckt 002/102] x86/ldt: Make modify_ldt synchronous Kamal Mostafa
2015-09-22 17:50 ` [PATCH 3.19.y-ckt 003/102] x86/ldt: Correct LDT access in single stepping logic Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 004/102] x86/ldt: Correct FPU emulation access to LDT Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 005/102] md: flush ->event_work before stopping array Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 006/102] ipmi/powernv: Fix minor locking bug Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 007/102] ipv6: addrconf: validate new MTU before applying it Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 008/102] virtio-net: drop NETIF_F_FRAGLIST Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 009/102] RDS: verify the underlying transport exists before creating a connection Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 010/102] xen/gntdev: convert priv->lock to a mutex Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 011/102] xen/gntdevt: Fix race condition in gntdev_release() Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 012/102] PCI: Restore PCI_MSIX_FLAGS_BIRMASK definition Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 013/102] USB: qcserial/option: make AT URCs work for Sierra Wireless MC7305/MC7355 Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 014/102] USB: qcserial: Add support for Dell Wireless 5809e 4G Modem Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 015/102] nfsd: Drop BUG_ON and ignore SECLABEL on absent filesystem Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 016/102] usb: chipidea: ehci_init_driver is intended to call one time Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 017/102] crypto: qat - Fix invalid synchronization between register/unregister sym algs Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 018/102] crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 019/102] mfd: arizona: Fix initialisation of the PM runtime Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 020/102] xen-blkfront: don't add indirect pages to list when !feature_persistent Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 021/102] xen-blkback: replace work_pending with work_busy in purge_persistent_gnt() Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 022/102] usb: gadget: f_uac2: fix calculation of uac2->p_interval Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 023/102] hwrng: core - correct error check of kthread_run call Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 024/102] USB: sierra: add 1199:68AB device ID Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 025/102] regmap: regcache-rbtree: Clean new present bits on present bitmap resize Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 026/102] target/iscsi: Fix double free of a TUR followed by a solicited NOPOUT Kamal Mostafa
2015-09-22 17:51 ` Kamal Mostafa [this message]
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 028/102] md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 029/102] target: REPORT LUNS should return LUN 0 even for dynamic ACLs Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 030/102] MIPS: Fix sched_getaffinity with MT FPAFF enabled Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 031/102] MIPS: Malta: Don't reinitialise RTC Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 032/102] MIPS: do_mcheck: Fix kernel code dump with EVA Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 033/102] MIPS: show_stack: Fix stack trace " Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 034/102] MIPS: Export get_c0_perfcount_int() Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 035/102] rtlwifi: rtl8723be: Add module parameter for MSI interrupts Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 036/102] MIPS: Flush RPS on kernel entry with EVA Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 037/102] usb: udc: core: add device_del() call to error pathway Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 038/102] xhci: fix off by one error in TRB DMA address boundary check Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 039/102] drivers/usb: Delete XHCI command timer if necessary Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 040/102] staging: vt6655: vnt_bss_info_changed check conf->beacon_rate is not NULL Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 041/102] dm: fix dm_merge_bvec regression on 32 bit systems Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 042/102] perf: Fix fasync handling on inherited events Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 043/102] drm/dp-mst: Remove debug WARN_ON Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 044/102] ALSA: fireworks/firewire-lib: add support for recent firmware quirk Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 045/102] mm, vmscan: Do not wait for page writeback for GFP_NOFS allocations Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 046/102] MIPS: Make set_pte() SMP safe Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 047/102] ipc: modify message queue accounting to not take kernel data structures into account Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 048/102] ocfs2: fix BUG in ocfs2_downconvert_thread_do_work() Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 049/102] fsnotify: fix oops in fsnotify_clear_marks_by_group_flags() Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 050/102] KVM: x86: Use adjustment in guest cycles when handling MSR_IA32_TSC_ADJUST Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 051/102] x86/xen: build "Xen PV" APIC driver for domU as well Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 052/102] cpuset: use trialcs->mems_allowed as a temp variable Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 053/102] drm/dp/mst: Remove port after removing connector Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 054/102] localmodconfig: Use Kbuild files too Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 055/102] dm thin metadata: delete btrees when releasing metadata snapshot Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 056/102] dm btree: add ref counting ops for the leaves of top level btrees Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 057/102] drm/radeon: add new OLAND pci id Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 058/102] libiscsi: Fix host busy blocking during connection teardown Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 059/102] libfc: Fix fc_exch_recv_req() error path Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 060/102] libfc: Fix fc_fcp_cleanup_each_cmd() Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 061/102] sd: Fix maximum I/O size for BLOCK_PC requests Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 062/102] EDAC, ppc4xx: Access mci->csrows array elements properly Kamal Mostafa
2015-09-22 17:51 ` [PATCH 3.19.y-ckt 063/102] crypto: caam - fix memory corruption in ahash_final_ctx Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 064/102] drm/vmwgfx: Fix execbuf locking issues Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 065/102] mm/hwpoison: fix page refcount of unknown non LRU page Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 066/102] ipc,sem: fix use after free on IPC_RMID after a task using same semaphore set exits Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 067/102] ipc/sem.c: update/correct memory barriers Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 068/102] MIPS: Fix seccomp syscall argument for MIPS64 Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 069/102] x86/ldt: Further fix FPU emulation Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 070/102] drm/i915: Flag the execlists context object as dirty after every use Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 071/102] fnic: Use the local variable instead of I/O flag to acquire io_req_lock in fnic_queuecommand() to avoid deadloack Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 072/102] SCSI: Fix NULL pointer dereference in runtime PM Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 073/102] ALSA: usb-audio: Fix runtime PM unbalance Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 074/102] x86/xen: make CONFIG_XEN depend on CONFIG_X86_LOCAL_APIC Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 075/102] Input: gpio_keys_polled - request GPIO pin as input Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 076/102] PCI: Don't use 64-bit bus addresses on PA-RISC Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 077/102] ALSA: usb: Add native DSD support for Gustard DAC-X20U Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 078/102] Add factory recertified Crucial M500s to blacklist Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 079/102] arm64: KVM: Fix host crash when injecting a fault into a 32bit guest Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 080/102] batman-adv: protect tt_local_entry from concurrent delete events Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 081/102] ip6_gre: release cached dst on tunnel removal Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 082/102] perf: Fix PERF_EVENT_IOC_PERIOD migration race Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 083/102] net: Fix RCU splat in af_key Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 084/102] bna: fix interrupts storm caused by erroneous packets Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 085/102] net: Fix skb_set_peeked use-after-free bug Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 086/102] rds: fix an integer overflow test in rds_info_getsockopt() Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 087/102] fq_codel: explicitly reset flows in ->reset() Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 088/102] bridge: netlink: account for the IFLA_BRPORT_PROXYARP attribute size and policy Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 089/102] batman-adv: fix kernel crash due to missing NULL checks Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 090/102] fbdev: select versatile helpers for the integrator Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 091/102] rocker: free netdevice during netdevice removal Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 092/102] udp: fix dst races with multicast early demux Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 093/102] net: phy: add locking to phy_read_mmd_indirect()/phy_write_mmd_indirect() Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 094/102] sparc64: Fix userspace FPU register corruptions Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 095/102] rtnetlink: verify IFLA_VF_INFO attributes before passing them to driver Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 096/102] net/tipc: initialize security state for new connection socket Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 097/102] net: pktgen: fix race between pktgen_thread_worker() and kthread_stop() Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 098/102] net: Fix skb csum races when peeking Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 099/102] ipv6: lock socket in ip6_datagram_connect() Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 100/102] Revert "sit: Add gro callbacks to sit_offload" Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 101/102] bonding: correct the MAC address for "follow" fail_over_mac policy Kamal Mostafa
2015-09-22 17:52 ` [PATCH 3.19.y-ckt 102/102] netlink: don't hold mutex in rcu callback when releasing mmapd ring Kamal Mostafa

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=1442944358-1248-28-git-send-email-kamal@canonical.com \
    --to=kamal@canonical.com \
    --cc=elder@linaro.org \
    --cc=idryomov@gmail.com \
    --cc=kernel-team@lists.ubuntu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@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

all inboxes | Powered by JetHome®