From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Yan Zheng <zheng.yan@oracle.com>,
Chris Mason <chris.mason@oracle.com>,
Jeff Mahoney <jeffm@suse.com>
Subject: [043/111] Btrfs: Avoid superfluous tree-log writeout
Date: Wed, 11 Aug 2010 16:54:24 -0700 [thread overview]
Message-ID: <20100811235459.455263365@clark.site> (raw)
In-Reply-To: <20100811235623.GA24440@kroah.com>
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Yan, Zheng <zheng.yan@oracle.com>
commit 8cef4e160d74920ad1725f58c89fd75ec4c4ac38 upstream.
We allow two log transactions at a time, but use same flag
to mark dirty tree-log btree blocks. So we may flush dirty
blocks belonging to newer log transaction when committing a
log transaction. This patch fixes the issue by using two
flags to mark dirty tree-log btree blocks.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Acked-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/btrfs/disk-io.c | 6 +++---
fs/btrfs/extent-tree.c | 12 ++++++++++--
fs/btrfs/transaction.c | 21 +++++++++++----------
fs/btrfs/transaction.h | 6 +++---
fs/btrfs/tree-log.c | 33 ++++++++++++++++++++-------------
5 files changed, 47 insertions(+), 31 deletions(-)
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -980,12 +980,12 @@ int btrfs_free_log_root_tree(struct btrf
while (1) {
ret = find_first_extent_bit(&log_root_tree->dirty_log_pages,
- 0, &start, &end, EXTENT_DIRTY);
+ 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW);
if (ret)
break;
- clear_extent_dirty(&log_root_tree->dirty_log_pages,
- start, end, GFP_NOFS);
+ clear_extent_bits(&log_root_tree->dirty_log_pages, start, end,
+ EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS);
}
eb = fs_info->log_root_tree->node;
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4919,8 +4919,16 @@ struct extent_buffer *btrfs_init_new_buf
btrfs_set_buffer_uptodate(buf);
if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) {
- set_extent_dirty(&root->dirty_log_pages, buf->start,
- buf->start + buf->len - 1, GFP_NOFS);
+ /*
+ * we allow two log transactions at a time, use different
+ * EXENT bit to differentiate dirty pages.
+ */
+ if (root->log_transid % 2 == 0)
+ set_extent_dirty(&root->dirty_log_pages, buf->start,
+ buf->start + buf->len - 1, GFP_NOFS);
+ else
+ set_extent_new(&root->dirty_log_pages, buf->start,
+ buf->start + buf->len - 1, GFP_NOFS);
} else {
set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
buf->start + buf->len - 1, GFP_NOFS);
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -354,7 +354,7 @@ int btrfs_end_transaction_throttle(struc
* those extents are sent to disk but does not wait on them
*/
int btrfs_write_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages)
+ struct extent_io_tree *dirty_pages, int mark)
{
int ret;
int err = 0;
@@ -367,7 +367,7 @@ int btrfs_write_marked_extents(struct bt
while (1) {
ret = find_first_extent_bit(dirty_pages, start, &start, &end,
- EXTENT_DIRTY);
+ mark);
if (ret)
break;
while (start <= end) {
@@ -413,7 +413,7 @@ int btrfs_write_marked_extents(struct bt
* on all the pages and clear them from the dirty pages state tree
*/
int btrfs_wait_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages)
+ struct extent_io_tree *dirty_pages, int mark)
{
int ret;
int err = 0;
@@ -425,12 +425,12 @@ int btrfs_wait_marked_extents(struct btr
unsigned long index;
while (1) {
- ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
- EXTENT_DIRTY);
+ ret = find_first_extent_bit(dirty_pages, start, &start, &end,
+ mark);
if (ret)
break;
- clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
+ clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS);
while (start <= end) {
index = start >> PAGE_CACHE_SHIFT;
start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
@@ -460,13 +460,13 @@ int btrfs_wait_marked_extents(struct btr
* those extents are on disk for transaction or log commit
*/
int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages)
+ struct extent_io_tree *dirty_pages, int mark)
{
int ret;
int ret2;
- ret = btrfs_write_marked_extents(root, dirty_pages);
- ret2 = btrfs_wait_marked_extents(root, dirty_pages);
+ ret = btrfs_write_marked_extents(root, dirty_pages, mark);
+ ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
return ret || ret2;
}
@@ -479,7 +479,8 @@ int btrfs_write_and_wait_transaction(str
return filemap_write_and_wait(btree_inode->i_mapping);
}
return btrfs_write_and_wait_marked_extents(root,
- &trans->transaction->dirty_pages);
+ &trans->transaction->dirty_pages,
+ EXTENT_DIRTY);
}
/*
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -107,10 +107,10 @@ void btrfs_throttle(struct btrfs_root *r
int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages);
+ struct extent_io_tree *dirty_pages, int mark);
int btrfs_write_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages);
+ struct extent_io_tree *dirty_pages, int mark);
int btrfs_wait_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages);
+ struct extent_io_tree *dirty_pages, int mark);
int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
#endif
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1977,10 +1977,11 @@ int btrfs_sync_log(struct btrfs_trans_ha
{
int index1;
int index2;
+ int mark;
int ret;
struct btrfs_root *log = root->log_root;
struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
- u64 log_transid = 0;
+ unsigned long log_transid = 0;
mutex_lock(&root->log_mutex);
index1 = root->log_transid % 2;
@@ -2014,24 +2015,29 @@ int btrfs_sync_log(struct btrfs_trans_ha
goto out;
}
+ log_transid = root->log_transid;
+ if (log_transid % 2 == 0)
+ mark = EXTENT_DIRTY;
+ else
+ mark = EXTENT_NEW;
+
/* we start IO on all the marked extents here, but we don't actually
* wait for them until later.
*/
- ret = btrfs_write_marked_extents(log, &log->dirty_log_pages);
+ ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark);
BUG_ON(ret);
btrfs_set_root_node(&log->root_item, log->node);
root->log_batch = 0;
- log_transid = root->log_transid;
root->log_transid++;
log->log_transid = root->log_transid;
root->log_start_pid = 0;
smp_mb();
/*
- * log tree has been flushed to disk, new modifications of
- * the log will be written to new positions. so it's safe to
- * allow log writers to go in.
+ * IO has been started, blocks of the log tree have WRITTEN flag set
+ * in their headers. new modifications of the log will be written to
+ * new positions. so it's safe to allow log writers to go in.
*/
mutex_unlock(&root->log_mutex);
@@ -2052,7 +2058,7 @@ int btrfs_sync_log(struct btrfs_trans_ha
index2 = log_root_tree->log_transid % 2;
if (atomic_read(&log_root_tree->log_commit[index2])) {
- btrfs_wait_marked_extents(log, &log->dirty_log_pages);
+ btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
wait_log_commit(trans, log_root_tree,
log_root_tree->log_transid);
mutex_unlock(&log_root_tree->log_mutex);
@@ -2072,16 +2078,17 @@ int btrfs_sync_log(struct btrfs_trans_ha
* check the full commit flag again
*/
if (root->fs_info->last_trans_log_full_commit == trans->transid) {
- btrfs_wait_marked_extents(log, &log->dirty_log_pages);
+ btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
mutex_unlock(&log_root_tree->log_mutex);
ret = -EAGAIN;
goto out_wake_log_root;
}
ret = btrfs_write_and_wait_marked_extents(log_root_tree,
- &log_root_tree->dirty_log_pages);
+ &log_root_tree->dirty_log_pages,
+ EXTENT_DIRTY | EXTENT_NEW);
BUG_ON(ret);
- btrfs_wait_marked_extents(log, &log->dirty_log_pages);
+ btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
btrfs_set_super_log_root(&root->fs_info->super_for_commit,
log_root_tree->node->start);
@@ -2147,12 +2154,12 @@ int btrfs_free_log(struct btrfs_trans_ha
while (1) {
ret = find_first_extent_bit(&log->dirty_log_pages,
- 0, &start, &end, EXTENT_DIRTY);
+ 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW);
if (ret)
break;
- clear_extent_dirty(&log->dirty_log_pages,
- start, end, GFP_NOFS);
+ clear_extent_bits(&log->dirty_log_pages, start, end,
+ EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS);
}
if (log->log_transid > 0) {
next prev parent reply other threads:[~2010-08-11 23:58 UTC|newest]
Thread overview: 115+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-11 23:56 [000/111] 2.6.32.19 -stable review Greg KH
2010-08-11 23:53 ` [001/111] ata_piix: fix locking around SIDPR access Greg KH
2010-08-11 23:53 ` [002/111] powerpc: fix build with make 3.82 Greg KH
2010-08-11 23:53 ` [003/111] nvram: Fix write beyond end condition; prove to gcc copy is safe Greg KH
2010-08-11 23:53 ` [004/111] x86: Add memory modify constraints to xchg() and cmpxchg() Greg KH
2010-08-11 23:53 ` [005/111] x86, vmware: Preset lpj values when on VMware Greg KH
2010-08-11 23:53 ` [006/111] Staging: line6: needs to select SND_PCM Greg KH
2010-08-11 23:53 ` [007/111] Staging: panel: Prevent double-calling of parport_release - fix oops Greg KH
2010-08-11 23:53 ` [008/111] PCI: Do not run NVidia quirks related to MSI with MSI disabled Greg KH
2010-08-11 23:53 ` [009/111] PCI: disable MSI on VIA K8M800 Greg KH
2010-08-11 23:53 ` [010/111] solos-pci: Fix race condition in tasklet RX handling Greg KH
2010-08-11 23:53 ` [011/111] splice: fix misuse of SPLICE_F_NONBLOCK Greg KH
2010-08-11 23:53 ` [012/111] drivers/video/w100fb.c: ignore void return value / fix build failure Greg KH
2010-08-11 23:53 ` [013/111] ide-cd: Do not access completed requests in the irq handler Greg KH
2010-08-11 23:53 ` [014/111] md/raid10: fix deadlock with unaligned read during resync Greg KH
2010-08-11 23:53 ` [015/111] blkdev: cgroup whitelist permission fix Greg KH
2010-08-11 23:53 ` [016/111] eCryptfs: Handle ioctl calls with unlocked and compat functions Greg KH
2010-08-11 23:53 ` [017/111] ecryptfs: release reference to lower mount if interpose fails Greg KH
2010-08-11 23:53 ` [018/111] fs/ecryptfs/file.c: introduce missing free Greg KH
2010-08-11 23:54 ` [019/111] bio, fs: update RWA_MASK, READA and SWRITE to match the corresponding BIO_RW_* bits Greg KH
2010-08-11 23:54 ` [020/111] signalfd: fill in ssi_int for posix timers and message queues Greg KH
2010-08-11 23:54 ` [021/111] smsc911x: Add spinlocks around registers access Greg KH
2010-08-11 23:54 ` [022/111] ARM: 6299/1: errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID Greg KH
2010-08-11 23:54 ` [023/111] ARM: 6280/1: imx: Fix build failure when including <mach/gpio.h> without <linux/spinlock.h> Greg KH
2010-08-11 23:54 ` [024/111] USB: resizing usbmon binary interface buffer causes protection faults Greg KH
2010-08-11 23:54 ` [025/111] USB delay init quirk for logitech Harmony 700-series devices Greg KH
2010-08-11 23:54 ` [026/111] USB: serial: enabling support for Segway RMP in ftdi_sio Greg KH
2010-08-11 23:54 ` [027/111] USB: option: Huawei ETS 1220 support added Greg KH
2010-08-11 23:54 ` [028/111] USB: option: add huawei k3765 k4505 devices to work properly Greg KH
2010-08-11 23:54 ` [029/111] USB: ftdi_sio: device id for Navitator Greg KH
2010-08-11 23:54 ` [030/111] USB: cp210x: Add four new device IDs Greg KH
2010-08-11 23:54 ` [031/111] USB: usbtest: avoid to free coherent buffer in atomic context Greg KH
2010-08-11 23:54 ` [032/111] USB: fix thread-unsafe anchor utiliy routines Greg KH
2010-08-11 23:54 ` [033/111] drm/edid: Fix the HDTV hack sync adjustment Greg KH
2010-08-11 23:54 ` [034/111] Bluetooth: Added support for controller shipped with iMac i5 Greg KH
2010-08-11 23:54 ` [035/111] jfs: dont allow os2 xattr namespace overlap with others Greg KH
2010-08-11 23:54 ` [036/111] arp_notify: allow drivers to explicitly request a notification event Greg KH
2010-08-11 23:54 ` [037/111] xen: netfront: explicitly generate arp_notify event after migration Greg KH
2010-08-11 23:54 ` Greg KH
2010-08-11 23:54 ` [038/111] net: Fix NETDEV_NOTIFY_PEERS to not conflict with NETDEV_BONDING_DESLAVE Greg KH
2010-08-11 23:54 ` [039/111] irq: Add new IRQ flag IRQF_NO_SUSPEND Greg KH
2010-08-11 23:54 ` Greg KH
2010-08-11 23:54 ` [040/111] xen: Do not suspend IPI IRQs Greg KH
2010-08-11 23:54 ` Greg KH
2010-08-11 23:54 ` [041/111] ext4: fix freeze deadlock under IO Greg KH
2010-08-11 23:54 ` [042/111] drm/i915: Use RSEN instead of HTPLG for tfp410 monitor detection Greg KH
2010-08-11 23:54 ` Greg KH [this message]
2010-08-11 23:54 ` [044/111] Btrfs: Add btrfs_duplicate_item Greg KH
2010-08-11 23:54 ` [045/111] Btrfs: Rewrite btrfs_drop_extents Greg KH
2010-08-11 23:54 ` [046/111] Btrfs: Fix disk_i_size update corner case Greg KH
2010-08-11 23:54 ` [047/111] Btrfs: Avoid orphan inodes cleanup while replaying log Greg KH
2010-08-11 23:54 ` [048/111] Btrfs: Avoid orphan inodes cleanup during committing transaction Greg KH
2010-08-11 23:54 ` [049/111] Btrfs: Make fallocate(2) more ENOSPC friendly Greg KH
2010-08-11 23:54 ` [050/111] Btrfs: Make truncate(2) " Greg KH
2010-08-11 23:54 ` [051/111] Btrfs: Pass transaction handle to security and ACL initialization functions Greg KH
2010-08-11 23:54 ` [052/111] Btrfs: Add delayed iput Greg KH
2010-08-11 23:54 ` [053/111] Btrfs: Fix btrfs_drop_extent_cache for skip pinned case Greg KH
2010-08-11 23:54 ` [054/111] Btrfs: Fix per root used space accounting Greg KH
2010-08-11 23:54 ` [055/111] Btrfs: dont add extent 0 to the free space cache v2 Greg KH
2010-08-11 23:54 ` [056/111] Btrfs: fail mount on bad mount options Greg KH
2010-08-11 23:54 ` [057/111] Btrfs: deny sys_link across subvolumes Greg KH
2010-08-11 23:54 ` [058/111] Btrfs: Show discard option in /proc/mounts Greg KH
2010-08-11 23:54 ` [059/111] Btrfs: make metadata chunks smaller Greg KH
2010-08-11 23:54 ` [060/111] Btrfs: make sure fallocate properly starts a transaction Greg KH
2010-08-11 23:54 ` [061/111] btrfs: fix missing last-entry in readdir(3) Greg KH
2010-08-11 23:54 ` [062/111] Btrfs: align offsets for btrfs_ordered_update_i_size Greg KH
2010-08-11 23:54 ` [063/111] Btrfs, fix memory leaks in error paths Greg KH
2010-08-11 23:54 ` [064/111] Btrfs: Fix race in btrfs_mark_extent_written Greg KH
2010-08-11 23:54 ` [065/111] Btrfs: fix regression in orphan cleanup Greg KH
2010-08-11 23:54 ` [066/111] Btrfs: deal with NULL acl sent to btrfs_set_acl Greg KH
2010-08-11 23:54 ` [067/111] Btrfs: fix possible panic on unmount Greg KH
2010-08-11 23:54 ` [068/111] Btrfs: Use correct values when updating inode i_size on fallocate Greg KH
2010-08-11 23:54 ` [069/111] Btrfs: fix a memory leak in btrfs_init_acl Greg KH
2010-08-11 23:54 ` [070/111] Btrfs: run orphan cleanup on default fs root Greg KH
2010-08-11 23:54 ` [071/111] Btrfs: do not mark the chunk as readonly if in degraded mode Greg KH
2010-08-11 23:54 ` [072/111] Btrfs: check return value of open_bdev_exclusive properly Greg KH
2010-08-11 23:54 ` [073/111] Btrfs: check total number of devices when removing missing Greg KH
2010-08-11 23:54 ` [074/111] Btrfs: fix race between allocate and release extent buffer Greg KH
2010-08-11 23:54 ` [075/111] Btrfs: make error return negative in btrfs_sync_file() Greg KH
2010-08-11 23:54 ` [076/111] Btrfs: remove BUG_ON() due to mounting bad filesystem Greg KH
2010-08-11 23:54 ` [077/111] Btrfs: Fix oopsen when dropping empty tree Greg KH
2010-08-11 23:54 ` [078/111] Btrfs: do not try and lookup the file extent when finishing ordered io Greg KH
2010-08-11 23:55 ` [079/111] Btrfs: apply updated fallocate i_size fix Greg KH
2010-08-11 23:55 ` [080/111] Btrfs: btrfs_mark_extent_written uses the wrong slot Greg KH
2010-08-11 23:55 ` [081/111] Btrfs: kfree correct pointer during mount option parsing Greg KH
2010-08-11 23:55 ` [082/111] nohz: Introduce arch_needs_cpu Greg KH
2010-08-11 23:55 ` [083/111] nohz: Reuse ktime in sub-functions of tick_check_idle Greg KH
2010-08-11 23:55 ` [084/111] timekeeping: Fix clock_gettime vsyscall time warp Greg KH
2010-08-11 23:55 ` [085/111] sched: Fix granularity of task_u/stime() Greg KH
2010-08-11 23:55 ` [086/111] sched, cputime: Introduce thread_group_times() Greg KH
2010-08-11 23:55 ` [087/111] mutex: Dont spin when the owner CPU is offline or other weird cases Greg KH
2010-08-11 23:55 ` [088/111] [IA64] fix SBA IOMMU to handle allocation failure properly Greg KH
2010-08-11 23:55 ` [089/111] crypto: testmgr - Fix complain about lack test for internal used algorithm Greg KH
2010-08-11 23:55 ` [090/111] memory hotplug: fix a bug on /dev/mem for 64-bit kernels Greg KH
2010-08-11 23:55 ` [091/111] x86: Fix out of order of gsi Greg KH
2010-08-11 23:55 ` [092/111] HWPOISON: remove the anonymous entry Greg KH
2010-08-11 23:55 ` [093/111] HWPOISON: abort on failed unmap Greg KH
2010-08-11 23:55 ` [094/111] powerpc/eeh: Fix a bug when pci structure is null Greg KH
2010-08-11 23:55 ` [095/111] ACPI: Fix regression where _PPC is not read at boot even when ignore_ppc=0 Greg KH
2010-08-11 23:55 ` [096/111] ext4: Make sure the MOVE_EXT ioctl cant overwrite append-only files Greg KH
2010-08-11 23:55 ` [097/111] ext4: Fix optional-arg mount options Greg KH
2010-08-11 23:55 ` [098/111] reiserfs: properly honor read-only devices Greg KH
2010-08-11 23:55 ` [099/111] reiserfs: fix oops while creating privroot with selinux enabled Greg KH
2010-08-11 23:55 ` [100/111] dlm: always use GFP_NOFS Greg KH
2010-08-11 23:55 ` [101/111] dlm: fix ordering of bast and cast Greg KH
2010-08-11 23:55 ` [102/111] dlm: send reply before bast Greg KH
2010-08-11 23:55 ` [103/111] ocfs2: Find proper end cpos for a leaf refcount block Greg KH
2010-08-11 23:55 ` [104/111] ocfs2: Set MS_POSIXACL on remount Greg KH
2010-08-11 23:55 ` [105/111] [PATCH] Skip check for mandatory locks when unlocking Greg KH
2010-08-11 23:55 ` [106/111] loop: Update mtime when writing using aops Greg KH
2010-08-11 23:55 ` [107/111] [SCSI] aic79xx: check for non-NULL scb in ahd_handle_nonpkt_busfree Greg KH
2010-08-11 23:55 ` [108/111] [SCSI] ibmvfc: Fix command completion handling Greg KH
2010-08-11 23:55 ` [109/111] [SCSI] ibmvfc: Reduce error recovery timeout Greg KH
2010-08-11 23:55 ` [110/111] md/raid1: delay reads that could overtake behind-writes Greg KH
2010-08-11 23:55 ` [111/111] mm: fix corruption of hibernation caused by reusing swap during image saving Greg KH
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=20100811235459.455263365@clark.site \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=chris.mason@oracle.com \
--cc=jeffm@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable-review@kernel.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=zheng.yan@oracle.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.