lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <alpine.LRH.2.02.1512101212220.25927@file01.intranet.prod.int.rdu2.redhat.com>
Date:	Thu, 10 Dec 2015 12:30:37 -0500 (EST)
From:	Mikulas Patocka <mpatocka@...hat.com>
To:	"James E.J. Bottomley" <JBottomley@...n.com>,
	"Martin K. Petersen" <martin.petersen@...cle.com>,
	Jens Axboe <axboe@...nel.dk>,
	Mike Snitzer <msnitzer@...hat.com>,
	Jonathan Brassow <jbrassow@...hat.com>
cc:	dm-devel@...hat.com, linux-scsi@...r.kernel.org,
	linux-kernel@...r.kernel.org, linux-block@...r.kernel.org
Subject: [PATCH 7/15] scsi xcopy: keep cache of failures

If xcopy between two devices fails, it is pointless to send more xcopy
command between there two devices because they take time and they will
likely also fail.

This patch keeps a cache of (source_device,destination_device) pairs where
copying failed and makes sure that no xcopy command is sooner than 30
seconds after the last failure.

Signed-off-by: Mikulas Patocka <mpatocka@...hat.com>

---
 drivers/scsi/sd.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Index: linux-4.4-rc4/drivers/scsi/sd.c
===================================================================
--- linux-4.4-rc4.orig/drivers/scsi/sd.c	2015-12-07 16:59:09.000000000 +0100
+++ linux-4.4-rc4/drivers/scsi/sd.c	2015-12-07 16:59:12.000000000 +0100
@@ -939,6 +939,26 @@ static void sd_config_copy(struct scsi_d
 				   (logical_block_size >> 9));
 }
 
+#define SD_COPY_DISABLED_CACHE_TIME		(HZ * 30)
+#define SD_COPY_DISABLED_CACHE_HASH_BITS	6
+#define SD_COPY_DISABLED_CACHE_HASH		(1 << SD_COPY_DISABLED_CACHE_HASH_BITS)
+
+struct sd_copy_disabled_cache_entry {
+	struct scsi_device *src;
+	struct scsi_device *dst;
+	unsigned long jiffies;
+};
+
+static struct sd_copy_disabled_cache_entry sd_copy_disabled_cache[SD_COPY_DISABLED_CACHE_HASH];
+
+static struct sd_copy_disabled_cache_entry *sd_copy_disabled_cache_hash(
+	struct scsi_device *src, struct scsi_device *dst)
+{
+	return &sd_copy_disabled_cache[
+		hash_long((unsigned long)src + ((unsigned long)dst >> 1), SD_COPY_DISABLED_CACHE_HASH_BITS)
+	];
+}
+
 static int sd_setup_copy_cmnd(struct scsi_cmnd *cmd)
 {
 	struct request *rq = cmd->request;
@@ -951,6 +971,7 @@ static int sd_setup_copy_cmnd(struct scs
 	struct bio *bio = rq->bio;
 	struct page *page;
 	unsigned char *buf;
+	struct sd_copy_disabled_cache_entry *e;
 
 	dst_sdp = scsi_disk(rq->rq_disk)->device;
 	dst_queue = rq->rq_disk->queue;
@@ -970,6 +991,12 @@ static int sd_setup_copy_cmnd(struct scs
 	if (src_sdp->sector_size != dst_sdp->sector_size)
 		return BLKPREP_KILL;
 
+	/* The copy failed in the past, so do not retry it for some time */
+	e = sd_copy_disabled_cache_hash(src_sdp, dst_sdp);
+	if (unlikely(jiffies - ACCESS_ONCE(e->jiffies) < SD_COPY_DISABLED_CACHE_TIME) &&
+	    likely(ACCESS_ONCE(e->src) == src_sdp) && likely(ACCESS_ONCE(e->dst) == dst_sdp))
+		return BLKPREP_KILL;
+
 	dst_lba = blk_rq_pos(rq) >> (ilog2(dst_sdp->sector_size) - 9);
 	src_lba = bio->bi_copy->pair[0]->bi_iter.bi_sector >> (ilog2(src_sdp->sector_size) - 9);
 	nr_blocks = blk_rq_sectors(rq) >> (ilog2(dst_sdp->sector_size) - 9);
@@ -2003,6 +2030,16 @@ static int sd_done(struct scsi_cmnd *SCp
 			 */
 			case EXTENDED_COPY:
 				if ((SCpnt->cmnd[1] & 0x1f) == 0) {
+					struct sd_copy_disabled_cache_entry *e;
+					struct scsi_device *src_sdp, *dst_sdp;
+
+					dst_sdp = sdkp->device;
+					src_sdp = scsi_disk(req->bio->bi_copy->pair[0]->bi_bdev->bd_disk)->device;
+					e = sd_copy_disabled_cache_hash(src_sdp, dst_sdp);
+					ACCESS_ONCE(e->src) = src_sdp;
+					ACCESS_ONCE(e->dst) = dst_sdp;
+					ACCESS_ONCE(e->jiffies) = jiffies;
+
 					good_bytes = 0;
 					req->__data_len = blk_rq_bytes(req);
 					req->cmd_flags |= REQ_QUIET;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ