aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@daterainc.com>2013-08-20 18:38:55 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-09-10 19:48:43 -0400
commitcbf031f425fd0b30ff10ba83b612753189a6bbbf (patch)
treedcc5696e342739cf9f8b2d9791b19036025075c7
parent89c12cc925a7d0982dc53b743a42108acc76aef4 (diff)
target: Add support for EXTENDED_COPY copy offload emulation
This patch adds support for EXTENDED_COPY emulation from SPC-3, that enables full copy offload target support within both a single virtual backend device, and across multiple virtual backend devices. It also functions independent of target fabric, and supports copy offload across multiple target fabric ports. This implemenation supports both EXTENDED_COPY PUSH and PULL models of operation, so the actual CDB may be received on either source or desination logical unit. For Target Descriptors, it currently supports the NAA IEEE Registered Extended designator (type 0xe4), which allows the reference of target ports to occur independent of fabric type using EVPD 0x83 WWNs. For Segment Descriptors, it currently supports copy from block to block (0x02) mode. It also honors any present SCSI reservations of the destination target port. Note that only Supports No List Identifier (SNLID=1) mode is supported. Also included is basic RECEIVE_COPY_RESULTS with service action type OPERATING PARAMETERS (0x03) required for SNLID=1 operation. v3 changes: - Fix incorrect return type in target_do_receive_copy_results() (Fengguang) v2 changes: - Use target_alloc_sgl() instead of transport_generic_get_mem() - Convert debug output to use pr_debug() - Convert target_xcopy_parse_target_descriptors() NAA IEEN WWN dump to use 0x%16phN format specification - Drop unnecessary xcopy_pt_cmd->xpt_passthrough_wsem, and associated usage in xcopy_pt_write_pending() and target_xcopy_issue_pt_cmd() - Add check for unsupported EXTENDED_COPY(LID4) service action bits in target_do_xcopy() Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Martin Petersen <martin.petersen@oracle.com> Cc: Chris Mason <chris.mason@fusionio.com> Cc: Roland Dreier <roland@purestorage.com> Cc: Zach Brown <zab@redhat.com> Cc: James Bottomley <JBottomley@Parallels.com> Cc: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Nicholas Bellinger <nab@daterainc.com>
-rw-r--r--drivers/target/Makefile3
-rw-r--r--drivers/target/target_core_xcopy.c1082
-rw-r--r--drivers/target/target_core_xcopy.h62
-rw-r--r--include/target/target_core_base.h1
4 files changed, 1147 insertions, 1 deletions
diff --git a/drivers/target/Makefile b/drivers/target/Makefile
index 9fdcb561422f..85b012d2f89b 100644
--- a/drivers/target/Makefile
+++ b/drivers/target/Makefile
@@ -13,7 +13,8 @@ target_core_mod-y := target_core_configfs.o \
13 target_core_spc.o \ 13 target_core_spc.o \
14 target_core_ua.o \ 14 target_core_ua.o \
15 target_core_rd.o \ 15 target_core_rd.o \
16 target_core_stat.o 16 target_core_stat.o \
17 target_core_xcopy.o
17 18
18obj-$(CONFIG_TARGET_CORE) += target_core_mod.o 19obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
19 20
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
new file mode 100644
index 000000000000..cf566a114911
--- /dev/null
+++ b/drivers/target/target_core_xcopy.c
@@ -0,0 +1,1082 @@
1/*******************************************************************************
2 * Filename: target_core_xcopy.c
3 *
4 * This file contains support for SPC-4 Extended-Copy offload with generic
5 * TCM backends.
6 *
7 * Copyright (c) 2011-2013 Datera, Inc. All rights reserved.
8 *
9 * Author:
10 * Nicholas A. Bellinger <nab@daterainc.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 ******************************************************************************/
23
24#include <linux/version.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <linux/list.h>
28#include <linux/configfs.h>
29#include <scsi/scsi.h>
30#include <scsi/scsi_cmnd.h>
31#include <asm/unaligned.h>
32
33#include <target/target_core_base.h>
34#include <target/target_core_backend.h>
35#include <target/target_core_fabric.h>
36#include <target/target_core_configfs.h>
37
38#include "target_core_pr.h"
39#include "target_core_ua.h"
40#include "target_core_xcopy.h"
41
42static struct workqueue_struct *xcopy_wq = NULL;
43/*
44 * From target_core_spc.c
45 */
46extern void spc_parse_naa_6h_vendor_specific(struct se_device *, unsigned char *);
47/*
48 * From target_core_device.c
49 */
50extern struct mutex g_device_mutex;
51extern struct list_head g_device_list;
52/*
53 * From target_core_configfs.c
54 */
55extern struct configfs_subsystem *target_core_subsystem[];
56
57static int target_xcopy_gen_naa_ieee(struct se_device *dev, unsigned char *buf)
58{
59 int off = 0;
60
61 buf[off++] = (0x6 << 4);
62 buf[off++] = 0x01;
63 buf[off++] = 0x40;
64 buf[off] = (0x5 << 4);
65
66 spc_parse_naa_6h_vendor_specific(dev, &buf[off]);
67 return 0;
68}
69
70static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op *xop,
71 bool src)
72{
73 struct se_device *se_dev;
74 struct configfs_subsystem *subsys = target_core_subsystem[0];
75 unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN], *dev_wwn;
76 int rc;
77
78 if (src == true)
79 dev_wwn = &xop->dst_tid_wwn[0];
80 else
81 dev_wwn = &xop->src_tid_wwn[0];
82
83 mutex_lock(&g_device_mutex);
84 list_for_each_entry(se_dev, &g_device_list, g_dev_node) {
85
86 memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN);
87 target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]);
88
89 rc = memcmp(&tmp_dev_wwn[0], dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
90 if (rc != 0)
91 continue;
92
93 if (src == true) {
94 xop->dst_dev = se_dev;
95 pr_debug("XCOPY 0xe4: Setting xop->dst_dev: %p from located"
96 " se_dev\n", xop->dst_dev);
97 } else {
98 xop->src_dev = se_dev;
99 pr_debug("XCOPY 0xe4: Setting xop->src_dev: %p from located"
100 " se_dev\n", xop->src_dev);
101 }
102
103 rc = configfs_depend_item(subsys,
104 &se_dev->dev_group.cg_item);
105 if (rc != 0) {
106 pr_err("configfs_depend_item attempt failed:"
107 " %d for se_dev: %p\n", rc, se_dev);
108 mutex_unlock(&g_device_mutex);
109 return rc;
110 }
111
112 pr_debug("Called configfs_depend_item for subsys: %p se_dev: %p"
113 " se_dev->se_dev_group: %p\n", subsys, se_dev,
114 &se_dev->dev_group);
115
116 mutex_unlock(&g_device_mutex);
117 return 0;
118 }
119 mutex_unlock(&g_device_mutex);
120
121 pr_err("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
122 return -EINVAL;
123}
124
125static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op *xop,
126 unsigned char *p, bool src)
127{
128 unsigned char *desc = p;
129 unsigned short ript;
130 u8 desig_len;
131 /*
132 * Extract RELATIVE INITIATOR PORT IDENTIFIER
133 */
134 ript = get_unaligned_be16(&desc[2]);
135 pr_debug("XCOPY 0xe4: RELATIVE INITIATOR PORT IDENTIFIER: %hu\n", ript);
136 /*
137 * Check for supported code set, association, and designator type
138 */
139 if ((desc[4] & 0x0f) != 0x1) {
140 pr_err("XCOPY 0xe4: code set of non binary type not supported\n");
141 return -EINVAL;
142 }
143 if ((desc[5] & 0x30) != 0x00) {
144 pr_err("XCOPY 0xe4: association other than LUN not supported\n");
145 return -EINVAL;
146 }
147 if ((desc[5] & 0x0f) != 0x3) {
148 pr_err("XCOPY 0xe4: designator type unsupported: 0x%02x\n",
149 (desc[5] & 0x0f));
150 return -EINVAL;
151 }
152 /*
153 * Check for matching 16 byte length for NAA IEEE Registered Extended
154 * Assigned designator
155 */
156 desig_len = desc[7];
157 if (desig_len != 16) {
158 pr_err("XCOPY 0xe4: invalid desig_len: %d\n", (int)desig_len);
159 return -EINVAL;
160 }
161 pr_debug("XCOPY 0xe4: desig_len: %d\n", (int)desig_len);
162 /*
163 * Check for NAA IEEE Registered Extended Assigned header..
164 */
165 if ((desc[8] & 0xf0) != 0x60) {