Blame view

drivers/target/target_core_device.c 29.2 KB
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1
2
3
  /*******************************************************************************
   * Filename:  target_core_device.c (based on iscsi_target_device.c)
   *
e3d6f909e   Andy Grover   target: Core clea...
4
   * This file contains the TCM Virtual Device and Disk Transport
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
5
6
   * agnostic related functions.
   *
4c76251e8   Nicholas Bellinger   target: Update co...
7
   * (c) Copyright 2003-2013 Datera, Inc.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
   *
   * Nicholas A. Bellinger <nab@kernel.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   ******************************************************************************/
  
  #include <linux/net.h>
  #include <linux/string.h>
  #include <linux/delay.h>
  #include <linux/timer.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
33
34
  #include <linux/kthread.h>
  #include <linux/in.h>
c53181af8   Paul Gortmaker   drivers/target: A...
35
  #include <linux/export.h>
7bfea53b5   Andy Grover   target: Move pass...
36
  #include <asm/unaligned.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
37
38
  #include <net/sock.h>
  #include <net/tcp.h>
ba9299925   Bart Van Assche   target: Minimize ...
39
40
  #include <scsi/scsi_common.h>
  #include <scsi/scsi_proto.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
41
42
  
  #include <target/target_core_base.h>
c4795fb20   Christoph Hellwig   target: header re...
43
44
  #include <target/target_core_backend.h>
  #include <target/target_core_fabric.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
45

e26d99aed   Christoph Hellwig   target: reshuffle...
46
  #include "target_core_internal.h"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
47
  #include "target_core_alua.h"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
48
49
  #include "target_core_pr.h"
  #include "target_core_ua.h"
d9ea32bff   Nicholas Bellinger   target: Add globa...
50
51
  DEFINE_MUTEX(g_device_mutex);
  LIST_HEAD(g_device_list);
e3d6f909e   Andy Grover   target: Core clea...
52
  static struct se_hba *lun0_hba;
e3d6f909e   Andy Grover   target: Core clea...
53
54
  /* not static, needed by tpg.c */
  struct se_device *g_lun0_dev;
de103c93a   Christoph Hellwig   target: pass sens...
55
  sense_reason_t
f2d306802   Hannes Reinecke   target: use 64-bi...
56
  transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
57
  {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
58
  	struct se_lun *se_lun = NULL;
e3d6f909e   Andy Grover   target: Core clea...
59
  	struct se_session *se_sess = se_cmd->se_sess;
29a05deeb   Nicholas Bellinger   target: Convert s...
60
  	struct se_node_acl *nacl = se_sess->se_node_acl;
29a05deeb   Nicholas Bellinger   target: Convert s...
61
  	struct se_dev_entry *deve;
8fa3a8674   Nicholas Bellinger   target: Make TCM_...
62
  	sense_reason_t ret = TCM_NO_SENSE;
5951146de   Andy Grover   target: More core...
63

29a05deeb   Nicholas Bellinger   target: Convert s...
64
65
66
67
  	rcu_read_lock();
  	deve = target_nacl_find_deve(nacl, unpacked_lun);
  	if (deve) {
  		atomic_long_inc(&deve->total_cmds);
5951146de   Andy Grover   target: More core...
68

5951146de   Andy Grover   target: More core...
69
  		if (se_cmd->data_direction == DMA_TO_DEVICE)
29a05deeb   Nicholas Bellinger   target: Convert s...
70
71
  			atomic_long_add(se_cmd->data_length,
  					&deve->write_bytes);
5951146de   Andy Grover   target: More core...
72
  		else if (se_cmd->data_direction == DMA_FROM_DEVICE)
29a05deeb   Nicholas Bellinger   target: Convert s...
73
74
  			atomic_long_add(se_cmd->data_length,
  					&deve->read_bytes);
5951146de   Andy Grover   target: More core...
75

29a05deeb   Nicholas Bellinger   target: Convert s...
76
77
  		se_lun = rcu_dereference(deve->se_lun);
  		se_cmd->se_lun = rcu_dereference(deve->se_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
78
79
  		se_cmd->pr_res_key = deve->pr_res_key;
  		se_cmd->orig_fe_lun = unpacked_lun;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
80
  		se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
5277797dc   Nicholas Bellinger   target: Add percp...
81
82
83
  
  		percpu_ref_get(&se_lun->lun_ref);
  		se_cmd->lun_ref_active = true;
8fa3a8674   Nicholas Bellinger   target: Make TCM_...
84
85
  
  		if ((se_cmd->data_direction == DMA_TO_DEVICE) &&
03a68b44f   Andy Grover   target: Remove en...
86
  		    deve->lun_access_ro) {
8fa3a8674   Nicholas Bellinger   target: Make TCM_...
87
88
89
90
91
92
93
94
95
  			pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN"
  				" Access for 0x%08llx
  ",
  				se_cmd->se_tfo->get_fabric_name(),
  				unpacked_lun);
  			rcu_read_unlock();
  			ret = TCM_WRITE_PROTECTED;
  			goto ref_dev;
  		}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
96
  	}
29a05deeb   Nicholas Bellinger   target: Convert s...
97
  	rcu_read_unlock();
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
98
99
  
  	if (!se_lun) {
5951146de   Andy Grover   target: More core...
100
101
102
103
104
105
  		/*
  		 * Use the se_portal_group->tpg_virt_lun0 to allow for
  		 * REPORT_LUNS, et al to be returned when no active
  		 * MappedLUN=0 exists for this Initiator Port.
  		 */
  		if (unpacked_lun != 0) {
6708bb27b   Andy Grover   target: Follow up...
106
  			pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN"
f2d306802   Hannes Reinecke   target: use 64-bi...
107
108
  				" Access for 0x%08llx
  ",
e3d6f909e   Andy Grover   target: Core clea...
109
  				se_cmd->se_tfo->get_fabric_name(),
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
110
  				unpacked_lun);
de103c93a   Christoph Hellwig   target: pass sens...
111
  			return TCM_NON_EXISTENT_LUN;
5951146de   Andy Grover   target: More core...
112
  		}
5951146de   Andy Grover   target: More core...
113

adf653f92   Christoph Hellwig   target: Subsume s...
114
115
  		se_lun = se_sess->se_tpg->tpg_virt_lun0;
  		se_cmd->se_lun = se_sess->se_tpg->tpg_virt_lun0;
5951146de   Andy Grover   target: More core...
116
  		se_cmd->orig_fe_lun = 0;
5951146de   Andy Grover   target: More core...
117
  		se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
5277797dc   Nicholas Bellinger   target: Add percp...
118
119
120
  
  		percpu_ref_get(&se_lun->lun_ref);
  		se_cmd->lun_ref_active = true;
8fa3a8674   Nicholas Bellinger   target: Make TCM_...
121
122
123
124
125
126
127
128
129
  
  		/*
  		 * Force WRITE PROTECT for virtual LUN 0
  		 */
  		if ((se_cmd->data_direction != DMA_FROM_DEVICE) &&
  		    (se_cmd->data_direction != DMA_NONE)) {
  			ret = TCM_WRITE_PROTECTED;
  			goto ref_dev;
  		}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
130
  	}
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
131
132
133
134
135
136
  	/*
  	 * RCU reference protected by percpu se_lun->lun_ref taken above that
  	 * must drop to zero (including initial reference) before this se_lun
  	 * pointer can be kfree_rcu() by the final se_lun->lun_group put via
  	 * target_core_fabric_configfs.c:target_fabric_port_release
  	 */
8fa3a8674   Nicholas Bellinger   target: Make TCM_...
137
  ref_dev:
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
138
139
  	se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev);
  	atomic_long_inc(&se_cmd->se_dev->num_cmds);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
140

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
141
  	if (se_cmd->data_direction == DMA_TO_DEVICE)
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
142
143
  		atomic_long_add(se_cmd->data_length,
  				&se_cmd->se_dev->write_bytes);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
144
  	else if (se_cmd->data_direction == DMA_FROM_DEVICE)
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
145
146
  		atomic_long_add(se_cmd->data_length,
  				&se_cmd->se_dev->read_bytes);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
147

8fa3a8674   Nicholas Bellinger   target: Make TCM_...
148
  	return ret;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
149
  }
5951146de   Andy Grover   target: More core...
150
  EXPORT_SYMBOL(transport_lookup_cmd_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
151

f2d306802   Hannes Reinecke   target: use 64-bi...
152
  int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
153
  {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
154
155
  	struct se_dev_entry *deve;
  	struct se_lun *se_lun = NULL;
e3d6f909e   Andy Grover   target: Core clea...
156
  	struct se_session *se_sess = se_cmd->se_sess;
29a05deeb   Nicholas Bellinger   target: Convert s...
157
  	struct se_node_acl *nacl = se_sess->se_node_acl;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
158
  	struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
5e1be9198   Roland Dreier   target: Make se_t...
159
  	unsigned long flags;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
160

29a05deeb   Nicholas Bellinger   target: Convert s...
161
162
163
164
165
166
  	rcu_read_lock();
  	deve = target_nacl_find_deve(nacl, unpacked_lun);
  	if (deve) {
  		se_tmr->tmr_lun = rcu_dereference(deve->se_lun);
  		se_cmd->se_lun = rcu_dereference(deve->se_lun);
  		se_lun = rcu_dereference(deve->se_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
167
168
  		se_cmd->pr_res_key = deve->pr_res_key;
  		se_cmd->orig_fe_lun = unpacked_lun;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
169
  	}
29a05deeb   Nicholas Bellinger   target: Convert s...
170
  	rcu_read_unlock();
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
171
172
  
  	if (!se_lun) {
6708bb27b   Andy Grover   target: Follow up...
173
  		pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN"
f2d306802   Hannes Reinecke   target: use 64-bi...
174
175
  			" Access for 0x%08llx
  ",
e3d6f909e   Andy Grover   target: Core clea...
176
  			se_cmd->se_tfo->get_fabric_name(),
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
177
  			unpacked_lun);
e3d6f909e   Andy Grover   target: Core clea...
178
  		return -ENODEV;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
179
  	}
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
180
181
182
183
184
  	/*
  	 * XXX: Add percpu se_lun->lun_ref reference count for TMR
  	 */
  	se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev);
  	se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev);
5951146de   Andy Grover   target: More core...
185

5e1be9198   Roland Dreier   target: Make se_t...
186
  	spin_lock_irqsave(&se_tmr->tmr_dev->se_tmr_lock, flags);
5951146de   Andy Grover   target: More core...
187
  	list_add_tail(&se_tmr->tmr_list, &se_tmr->tmr_dev->dev_tmr_list);
5e1be9198   Roland Dreier   target: Make se_t...
188
  	spin_unlock_irqrestore(&se_tmr->tmr_dev->se_tmr_lock, flags);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
189
190
191
  
  	return 0;
  }
5951146de   Andy Grover   target: More core...
192
  EXPORT_SYMBOL(transport_lookup_tmr_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
193

29a05deeb   Nicholas Bellinger   target: Convert s...
194
195
196
197
198
  bool target_lun_is_rdonly(struct se_cmd *cmd)
  {
  	struct se_session *se_sess = cmd->se_sess;
  	struct se_dev_entry *deve;
  	bool ret;
29a05deeb   Nicholas Bellinger   target: Convert s...
199
200
  	rcu_read_lock();
  	deve = target_nacl_find_deve(se_sess->se_node_acl, cmd->orig_fe_lun);
03a68b44f   Andy Grover   target: Remove en...
201
  	ret = deve && deve->lun_access_ro;
29a05deeb   Nicholas Bellinger   target: Convert s...
202
203
204
205
206
  	rcu_read_unlock();
  
  	return ret;
  }
  EXPORT_SYMBOL(target_lun_is_rdonly);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
207
208
  /*
   * This function is called from core_scsi3_emulate_pro_register_and_move()
29a05deeb   Nicholas Bellinger   target: Convert s...
209
   * and core_scsi3_decode_spec_i_port(), and will increment &deve->pr_kref
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
210
211
212
213
214
215
216
217
   * when a matching rtpi is found.
   */
  struct se_dev_entry *core_get_se_deve_from_rtpi(
  	struct se_node_acl *nacl,
  	u16 rtpi)
  {
  	struct se_dev_entry *deve;
  	struct se_lun *lun;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
218
  	struct se_portal_group *tpg = nacl->se_tpg;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
219

29a05deeb   Nicholas Bellinger   target: Convert s...
220
221
222
  	rcu_read_lock();
  	hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
  		lun = rcu_dereference(deve->se_lun);
6708bb27b   Andy Grover   target: Follow up...
223
224
  		if (!lun) {
  			pr_err("%s device entries device pointer is"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
225
226
  				" NULL, but Initiator has access.
  ",
e3d6f909e   Andy Grover   target: Core clea...
227
  				tpg->se_tpg_tfo->get_fabric_name());
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
228
229
  			continue;
  		}
29a05deeb   Nicholas Bellinger   target: Convert s...
230
  		if (lun->lun_rtpi != rtpi)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
231
  			continue;
29a05deeb   Nicholas Bellinger   target: Convert s...
232
233
  		kref_get(&deve->pr_kref);
  		rcu_read_unlock();
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
234
235
236
  
  		return deve;
  	}
29a05deeb   Nicholas Bellinger   target: Convert s...
237
  	rcu_read_unlock();
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
238
239
240
  
  	return NULL;
  }
29a05deeb   Nicholas Bellinger   target: Convert s...
241
  void core_free_device_list_for_node(
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
242
243
244
245
  	struct se_node_acl *nacl,
  	struct se_portal_group *tpg)
  {
  	struct se_dev_entry *deve;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
246

29a05deeb   Nicholas Bellinger   target: Convert s...
247
248
249
250
251
  	mutex_lock(&nacl->lun_entry_mutex);
  	hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
  		struct se_lun *lun = rcu_dereference_check(deve->se_lun,
  					lockdep_is_held(&nacl->lun_entry_mutex));
  		core_disable_device_list_for_node(lun, deve, nacl, tpg);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
252
  	}
29a05deeb   Nicholas Bellinger   target: Convert s...
253
  	mutex_unlock(&nacl->lun_entry_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
254
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
255
  void core_update_device_list_access(
f2d306802   Hannes Reinecke   target: use 64-bi...
256
  	u64 mapped_lun,
03a68b44f   Andy Grover   target: Remove en...
257
  	bool lun_access_ro,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
258
259
260
  	struct se_node_acl *nacl)
  {
  	struct se_dev_entry *deve;
29a05deeb   Nicholas Bellinger   target: Convert s...
261
262
  	mutex_lock(&nacl->lun_entry_mutex);
  	deve = target_nacl_find_deve(nacl, mapped_lun);
03a68b44f   Andy Grover   target: Remove en...
263
264
  	if (deve)
  		deve->lun_access_ro = lun_access_ro;
29a05deeb   Nicholas Bellinger   target: Convert s...
265
  	mutex_unlock(&nacl->lun_entry_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
266
  }
29a05deeb   Nicholas Bellinger   target: Convert s...
267
268
  /*
   * Called with rcu_read_lock or nacl->device_list_lock held.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
269
   */
f2d306802   Hannes Reinecke   target: use 64-bi...
270
  struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *nacl, u64 mapped_lun)
29a05deeb   Nicholas Bellinger   target: Convert s...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  {
  	struct se_dev_entry *deve;
  
  	hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link)
  		if (deve->mapped_lun == mapped_lun)
  			return deve;
  
  	return NULL;
  }
  EXPORT_SYMBOL(target_nacl_find_deve);
  
  void target_pr_kref_release(struct kref *kref)
  {
  	struct se_dev_entry *deve = container_of(kref, struct se_dev_entry,
  						 pr_kref);
  	complete(&deve->pr_comp);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
287
  }
7c0d0d51d   Hannes Reinecke   target: Send UA w...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  static void
  target_luns_data_has_changed(struct se_node_acl *nacl, struct se_dev_entry *new,
  			     bool skip_new)
  {
  	struct se_dev_entry *tmp;
  
  	rcu_read_lock();
  	hlist_for_each_entry_rcu(tmp, &nacl->lun_entry_hlist, link) {
  		if (skip_new && tmp == new)
  			continue;
  		core_scsi3_ua_allocate(tmp, 0x3F,
  				       ASCQ_3FH_REPORTED_LUNS_DATA_HAS_CHANGED);
  	}
  	rcu_read_unlock();
  }
e80ac6c4c   Andy Grover   target: refactor ...
303
  int core_enable_device_list_for_node(
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
304
305
  	struct se_lun *lun,
  	struct se_lun_acl *lun_acl,
f2d306802   Hannes Reinecke   target: use 64-bi...
306
  	u64 mapped_lun,
03a68b44f   Andy Grover   target: Remove en...
307
  	bool lun_access_ro,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
308
  	struct se_node_acl *nacl,
e80ac6c4c   Andy Grover   target: refactor ...
309
  	struct se_portal_group *tpg)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
310
  {
29a05deeb   Nicholas Bellinger   target: Convert s...
311
  	struct se_dev_entry *orig, *new;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
312

29a05deeb   Nicholas Bellinger   target: Convert s...
313
314
315
316
317
318
  	new = kzalloc(sizeof(*new), GFP_KERNEL);
  	if (!new) {
  		pr_err("Unable to allocate se_dev_entry memory
  ");
  		return -ENOMEM;
  	}
e80ac6c4c   Andy Grover   target: refactor ...
319

29a05deeb   Nicholas Bellinger   target: Convert s...
320
321
  	atomic_set(&new->ua_count, 0);
  	spin_lock_init(&new->ua_lock);
29a05deeb   Nicholas Bellinger   target: Convert s...
322
  	INIT_LIST_HEAD(&new->ua_list);
adf653f92   Christoph Hellwig   target: Subsume s...
323
  	INIT_LIST_HEAD(&new->lun_link);
e80ac6c4c   Andy Grover   target: refactor ...
324

29a05deeb   Nicholas Bellinger   target: Convert s...
325
326
327
  	new->mapped_lun = mapped_lun;
  	kref_init(&new->pr_kref);
  	init_completion(&new->pr_comp);
03a68b44f   Andy Grover   target: Remove en...
328
  	new->lun_access_ro = lun_access_ro;
29a05deeb   Nicholas Bellinger   target: Convert s...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  	new->creation_time = get_jiffies_64();
  	new->attach_count++;
  
  	mutex_lock(&nacl->lun_entry_mutex);
  	orig = target_nacl_find_deve(nacl, mapped_lun);
  	if (orig && orig->se_lun) {
  		struct se_lun *orig_lun = rcu_dereference_check(orig->se_lun,
  					lockdep_is_held(&nacl->lun_entry_mutex));
  
  		if (orig_lun != lun) {
  			pr_err("Existing orig->se_lun doesn't match new lun"
  			       " for dynamic -> explicit NodeACL conversion:"
  				" %s
  ", nacl->initiatorname);
  			mutex_unlock(&nacl->lun_entry_mutex);
  			kfree(new);
e80ac6c4c   Andy Grover   target: refactor ...
345
  			return -EINVAL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
346
  		}
eb49824ca   Nicholas Bellinger   target: Don't BUG...
347
348
349
350
351
352
353
354
355
356
  		if (orig->se_lun_acl != NULL) {
  			pr_warn_ratelimited("Detected existing explicit"
  				" se_lun_acl->se_lun_group reference for %s"
  				" mapped_lun: %llu, failing
  ",
  				 nacl->initiatorname, mapped_lun);
  			mutex_unlock(&nacl->lun_entry_mutex);
  			kfree(new);
  			return -EINVAL;
  		}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
357

29a05deeb   Nicholas Bellinger   target: Convert s...
358
359
360
361
362
  		rcu_assign_pointer(new->se_lun, lun);
  		rcu_assign_pointer(new->se_lun_acl, lun_acl);
  		hlist_del_rcu(&orig->link);
  		hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist);
  		mutex_unlock(&nacl->lun_entry_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
363

1adff1b3a   Nicholas Bellinger   target: Convert s...
364
  		spin_lock(&lun->lun_deve_lock);
adf653f92   Christoph Hellwig   target: Subsume s...
365
366
  		list_del(&orig->lun_link);
  		list_add_tail(&new->lun_link, &lun->lun_deve_list);
1adff1b3a   Nicholas Bellinger   target: Convert s...
367
  		spin_unlock(&lun->lun_deve_lock);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
368

29a05deeb   Nicholas Bellinger   target: Convert s...
369
370
  		kref_put(&orig->pr_kref, target_pr_kref_release);
  		wait_for_completion(&orig->pr_comp);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
371

7c0d0d51d   Hannes Reinecke   target: Send UA w...
372
  		target_luns_data_has_changed(nacl, new, true);
29a05deeb   Nicholas Bellinger   target: Convert s...
373
374
  		kfree_rcu(orig, rcu_head);
  		return 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
375
  	}
e80ac6c4c   Andy Grover   target: refactor ...
376

29a05deeb   Nicholas Bellinger   target: Convert s...
377
378
379
380
  	rcu_assign_pointer(new->se_lun, lun);
  	rcu_assign_pointer(new->se_lun_acl, lun_acl);
  	hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist);
  	mutex_unlock(&nacl->lun_entry_mutex);
e80ac6c4c   Andy Grover   target: refactor ...
381

1adff1b3a   Nicholas Bellinger   target: Convert s...
382
  	spin_lock(&lun->lun_deve_lock);
adf653f92   Christoph Hellwig   target: Subsume s...
383
  	list_add_tail(&new->lun_link, &lun->lun_deve_list);
1adff1b3a   Nicholas Bellinger   target: Convert s...
384
  	spin_unlock(&lun->lun_deve_lock);
e80ac6c4c   Andy Grover   target: refactor ...
385

7c0d0d51d   Hannes Reinecke   target: Send UA w...
386
  	target_luns_data_has_changed(nacl, new, true);
e80ac6c4c   Andy Grover   target: refactor ...
387
388
  	return 0;
  }
29a05deeb   Nicholas Bellinger   target: Convert s...
389
390
  /*
   *	Called with se_node_acl->lun_entry_mutex held.
e80ac6c4c   Andy Grover   target: refactor ...
391
   */
29a05deeb   Nicholas Bellinger   target: Convert s...
392
  void core_disable_device_list_for_node(
e80ac6c4c   Andy Grover   target: refactor ...
393
  	struct se_lun *lun,
29a05deeb   Nicholas Bellinger   target: Convert s...
394
  	struct se_dev_entry *orig,
e80ac6c4c   Andy Grover   target: refactor ...
395
396
397
  	struct se_node_acl *nacl,
  	struct se_portal_group *tpg)
  {
e80ac6c4c   Andy Grover   target: refactor ...
398
  	/*
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
399
400
401
402
  	 * rcu_dereference_raw protected by se_lun->lun_group symlink
  	 * reference to se_device->dev_group.
  	 */
  	struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev);
e80ac6c4c   Andy Grover   target: refactor ...
403
404
  	/*
  	 * If the MappedLUN entry is being disabled, the entry in
adf653f92   Christoph Hellwig   target: Subsume s...
405
  	 * lun->lun_deve_list must be removed now before clearing the
e80ac6c4c   Andy Grover   target: refactor ...
406
407
408
409
410
  	 * struct se_dev_entry pointers below as logic in
  	 * core_alua_do_transition_tg_pt() depends on these being present.
  	 *
  	 * deve->se_lun_acl will be NULL for demo-mode created LUNs
  	 * that have not been explicitly converted to MappedLUNs ->
adf653f92   Christoph Hellwig   target: Subsume s...
411
412
  	 * struct se_lun_acl, but we remove deve->lun_link from
  	 * lun->lun_deve_list. This also means that active UAs and
e80ac6c4c   Andy Grover   target: refactor ...
413
414
415
  	 * NodeACL context specific PR metadata for demo-mode
  	 * MappedLUN *deve will be released below..
  	 */
1adff1b3a   Nicholas Bellinger   target: Convert s...
416
  	spin_lock(&lun->lun_deve_lock);
adf653f92   Christoph Hellwig   target: Subsume s...
417
  	list_del(&orig->lun_link);
1adff1b3a   Nicholas Bellinger   target: Convert s...
418
  	spin_unlock(&lun->lun_deve_lock);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
419
  	/*
29a05deeb   Nicholas Bellinger   target: Convert s...
420
  	 * Disable struct se_dev_entry LUN ACL mapping
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
421
  	 */
29a05deeb   Nicholas Bellinger   target: Convert s...
422
423
424
  	core_scsi3_ua_release_all(orig);
  
  	hlist_del_rcu(&orig->link);
80bfdfa92   Nicholas Bellinger   target/pr: Use at...
425
  	clear_bit(DEF_PR_REG_ACTIVE, &orig->deve_flags);
03a68b44f   Andy Grover   target: Remove en...
426
  	orig->lun_access_ro = false;
29a05deeb   Nicholas Bellinger   target: Convert s...
427
428
  	orig->creation_time = 0;
  	orig->attach_count--;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
429
  	/*
29a05deeb   Nicholas Bellinger   target: Convert s...
430
431
  	 * Before firing off RCU callback, wait for any in process SPEC_I_PT=1
  	 * or REGISTER_AND_MOVE PR operation to complete.
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
432
  	 */
29a05deeb   Nicholas Bellinger   target: Convert s...
433
434
  	kref_put(&orig->pr_kref, target_pr_kref_release);
  	wait_for_completion(&orig->pr_comp);
3ccd6e83d   Nicholas Bellinger   target: Fix PR re...
435
436
  	rcu_assign_pointer(orig->se_lun, NULL);
  	rcu_assign_pointer(orig->se_lun_acl, NULL);
29a05deeb   Nicholas Bellinger   target: Convert s...
437
  	kfree_rcu(orig, rcu_head);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
438

4cc987eaf   Nicholas Bellinger   target: Drop lun_...
439
  	core_scsi3_free_pr_reg_from_nacl(dev, nacl);
7c0d0d51d   Hannes Reinecke   target: Send UA w...
440
  	target_luns_data_has_changed(nacl, NULL, false);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
441
442
443
444
445
446
447
448
449
450
  }
  
  /*      core_clear_lun_from_tpg():
   *
   *
   */
  void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg)
  {
  	struct se_node_acl *nacl;
  	struct se_dev_entry *deve;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
451

403edd78a   Nicholas Bellinger   target: Convert s...
452
  	mutex_lock(&tpg->acl_node_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
453
  	list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
454

29a05deeb   Nicholas Bellinger   target: Convert s...
455
456
457
458
  		mutex_lock(&nacl->lun_entry_mutex);
  		hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
  			struct se_lun *tmp_lun = rcu_dereference_check(deve->se_lun,
  					lockdep_is_held(&nacl->lun_entry_mutex));
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
459

29a05deeb   Nicholas Bellinger   target: Convert s...
460
461
  			if (lun != tmp_lun)
  				continue;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
462

29a05deeb   Nicholas Bellinger   target: Convert s...
463
  			core_disable_device_list_for_node(lun, deve, nacl, tpg);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
464
  		}
29a05deeb   Nicholas Bellinger   target: Convert s...
465
  		mutex_unlock(&nacl->lun_entry_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
466
  	}
403edd78a   Nicholas Bellinger   target: Convert s...
467
  	mutex_unlock(&tpg->acl_node_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
468
  }
adf653f92   Christoph Hellwig   target: Subsume s...
469
  int core_alloc_rtpi(struct se_lun *lun, struct se_device *dev)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
470
  {
adf653f92   Christoph Hellwig   target: Subsume s...
471
  	struct se_lun *tmp;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
472
473
  
  	spin_lock(&dev->se_port_lock);
adf653f92   Christoph Hellwig   target: Subsume s...
474
  	if (dev->export_count == 0x0000ffff) {
6708bb27b   Andy Grover   target: Follow up...
475
  		pr_warn("Reached dev->dev_port_count =="
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
476
477
478
  				" 0x0000ffff
  ");
  		spin_unlock(&dev->se_port_lock);
adf653f92   Christoph Hellwig   target: Subsume s...
479
  		return -ENOSPC;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
480
481
482
  	}
  again:
  	/*
35d1efe80   Masanari Iida   target: Fix minor...
483
  	 * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
484
485
486
487
488
489
490
491
492
493
  	 * Here is the table from spc4r17 section 7.7.3.8.
  	 *
  	 *    Table 473 -- RELATIVE TARGET PORT IDENTIFIER field
  	 *
  	 * Code      Description
  	 * 0h        Reserved
  	 * 1h        Relative port 1, historically known as port A
  	 * 2h        Relative port 2, historically known as port B
  	 * 3h to FFFFh    Relative port 3 through 65 535
  	 */
adf653f92   Christoph Hellwig   target: Subsume s...
494
495
  	lun->lun_rtpi = dev->dev_rpti_counter++;
  	if (!lun->lun_rtpi)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
496
  		goto again;
adf653f92   Christoph Hellwig   target: Subsume s...
497
  	list_for_each_entry(tmp, &dev->dev_sep_list, lun_dev_link) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
498
  		/*
35d1efe80   Masanari Iida   target: Fix minor...
499
  		 * Make sure RELATIVE TARGET PORT IDENTIFIER is unique
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
500
501
  		 * for 16-bit wrap..
  		 */
adf653f92   Christoph Hellwig   target: Subsume s...
502
  		if (lun->lun_rtpi == tmp->lun_rtpi)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
503
504
505
  			goto again;
  	}
  	spin_unlock(&dev->se_port_lock);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
506
507
  	return 0;
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
508
  static void se_release_vpd_for_dev(struct se_device *dev)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
509
510
  {
  	struct t10_vpd *vpd, *vpd_tmp;
0fd97ccf4   Christoph Hellwig   target: kill stru...
511
  	spin_lock(&dev->t10_wwn.t10_vpd_lock);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
512
  	list_for_each_entry_safe(vpd, vpd_tmp,
0fd97ccf4   Christoph Hellwig   target: kill stru...
513
  			&dev->t10_wwn.t10_vpd_list, vpd_list) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
514
515
516
  		list_del(&vpd->vpd_list);
  		kfree(vpd);
  	}
0fd97ccf4   Christoph Hellwig   target: kill stru...
517
  	spin_unlock(&dev->t10_wwn.t10_vpd_lock);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
518
  }
c8045372d   Roland Dreier   target: Make unne...
519
  static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
525a48a21   Nicholas Bellinger   target: Fix task ...
520
  {
3e03989b5   Roland Dreier   target: Avoid int...
521
522
  	u32 aligned_max_sectors;
  	u32 alignment;
525a48a21   Nicholas Bellinger   target: Fix task ...
523
524
525
526
  	/*
  	 * Limit max_sectors to a PAGE_SIZE aligned value for modern
  	 * transport_allocate_data_tasks() operation.
  	 */
3e03989b5   Roland Dreier   target: Avoid int...
527
528
529
530
531
532
533
  	alignment = max(1ul, PAGE_SIZE / block_size);
  	aligned_max_sectors = rounddown(max_sectors, alignment);
  
  	if (max_sectors != aligned_max_sectors)
  		pr_info("Rounding down aligned max_sectors from %u to %u
  ",
  			max_sectors, aligned_max_sectors);
525a48a21   Nicholas Bellinger   target: Fix task ...
534

3e03989b5   Roland Dreier   target: Avoid int...
535
  	return aligned_max_sectors;
525a48a21   Nicholas Bellinger   target: Fix task ...
536
  }
6bb826121   Nicholas Bellinger   target: Convert s...
537
  int core_dev_add_lun(
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
538
  	struct se_portal_group *tpg,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
539
  	struct se_device *dev,
6bb826121   Nicholas Bellinger   target: Convert s...
540
  	struct se_lun *lun)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
541
  {
8d9efe539   Sebastian Andrzej Siewior   target: fix retur...
542
  	int rc;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
543

03a68b44f   Andy Grover   target: Remove en...
544
  	rc = core_tpg_add_lun(tpg, lun, false, dev);
8d9efe539   Sebastian Andrzej Siewior   target: fix retur...
545
  	if (rc < 0)
6bb826121   Nicholas Bellinger   target: Convert s...
546
  		return rc;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
547

f2d306802   Hannes Reinecke   target: use 64-bi...
548
  	pr_debug("%s_TPG[%u]_LUN[%llu] - Activated %s Logical Unit from"
e3d6f909e   Andy Grover   target: Core clea...
549
550
  		" CORE HBA: %u
  ", tpg->se_tpg_tfo->get_fabric_name(),
2af7973a3   Andy Grover   target: Refer to ...
551
  		tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun,
2dca673b4   Andy Grover   target: Remove hb...
552
  		tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
553
554
555
556
  	/*
  	 * Update LUN maps for dynamically added initiators when
  	 * generate_node_acl is enabled.
  	 */
e3d6f909e   Andy Grover   target: Core clea...
557
  	if (tpg->se_tpg_tfo->tpg_check_demo_mode(tpg)) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
558
  		struct se_node_acl *acl;
403edd78a   Nicholas Bellinger   target: Convert s...
559
560
  
  		mutex_lock(&tpg->acl_node_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
561
  		list_for_each_entry(acl, &tpg->acl_node_list, acl_list) {
052605c6c   Nicholas Bellinger   target: Make stan...
562
563
564
  			if (acl->dynamic_node_acl &&
  			    (!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only ||
  			     !tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) {
df9766ca9   Nicholas Bellinger   target: Only rese...
565
  				core_tpg_add_node_to_devs(acl, tpg, lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
566
567
  			}
  		}
403edd78a   Nicholas Bellinger   target: Convert s...
568
  		mutex_unlock(&tpg->acl_node_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
569
  	}
6bb826121   Nicholas Bellinger   target: Convert s...
570
  	return 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
571
572
573
574
575
576
  }
  
  /*      core_dev_del_lun():
   *
   *
   */
cd9d7cbae   Andy Grover   target: Change co...
577
  void core_dev_del_lun(
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
578
  	struct se_portal_group *tpg,
cd9d7cbae   Andy Grover   target: Change co...
579
  	struct se_lun *lun)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
580
  {
f2d306802   Hannes Reinecke   target: use 64-bi...
581
  	pr_debug("%s_TPG[%u]_LUN[%llu] - Deactivating %s Logical Unit from"
e3d6f909e   Andy Grover   target: Core clea...
582
583
  		" device object
  ", tpg->se_tpg_tfo->get_fabric_name(),
cd9d7cbae   Andy Grover   target: Change co...
584
  		tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun,
e3d6f909e   Andy Grover   target: Core clea...
585
  		tpg->se_tpg_tfo->get_fabric_name());
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
586

cd9d7cbae   Andy Grover   target: Change co...
587
  	core_tpg_remove_lun(tpg, lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
588
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
589
590
  struct se_lun_acl *core_dev_init_initiator_node_lun_acl(
  	struct se_portal_group *tpg,
fcf29481f   Nicholas Bellinger   target: Fix looku...
591
  	struct se_node_acl *nacl,
f2d306802   Hannes Reinecke   target: use 64-bi...
592
  	u64 mapped_lun,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
593
594
595
  	int *ret)
  {
  	struct se_lun_acl *lacl;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
596

fcf29481f   Nicholas Bellinger   target: Fix looku...
597
  	if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) {
6708bb27b   Andy Grover   target: Follow up...
598
599
  		pr_err("%s InitiatorName exceeds maximum size.
  ",
e3d6f909e   Andy Grover   target: Core clea...
600
  			tpg->se_tpg_tfo->get_fabric_name());
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
601
602
603
  		*ret = -EOVERFLOW;
  		return NULL;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
604
  	lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL);
6708bb27b   Andy Grover   target: Follow up...
605
606
607
  	if (!lacl) {
  		pr_err("Unable to allocate memory for struct se_lun_acl.
  ");
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
608
609
610
  		*ret = -ENOMEM;
  		return NULL;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
611
612
  	lacl->mapped_lun = mapped_lun;
  	lacl->se_lun_nacl = nacl;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
613
614
615
616
617
618
619
  
  	return lacl;
  }
  
  int core_dev_add_initiator_node_lun_acl(
  	struct se_portal_group *tpg,
  	struct se_lun_acl *lacl,
6bb826121   Nicholas Bellinger   target: Convert s...
620
  	struct se_lun *lun,
03a68b44f   Andy Grover   target: Remove en...
621
  	bool lun_access_ro)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
622
  {
6bb826121   Nicholas Bellinger   target: Convert s...
623
  	struct se_node_acl *nacl = lacl->se_lun_nacl;
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
624
625
626
627
628
  	/*
  	 * rcu_dereference_raw protected by se_lun->lun_group symlink
  	 * reference to se_device->dev_group.
  	 */
  	struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
629

6708bb27b   Andy Grover   target: Follow up...
630
  	if (!nacl)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
631
  		return -EINVAL;
03a68b44f   Andy Grover   target: Remove en...
632
633
  	if (lun->lun_access_ro)
  		lun_access_ro = true;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
634
635
  
  	lacl->se_lun = lun;
e80ac6c4c   Andy Grover   target: refactor ...
636
  	if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun,
03a68b44f   Andy Grover   target: Remove en...
637
  			lun_access_ro, nacl, tpg) < 0)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
638
  		return -EINVAL;
f2d306802   Hannes Reinecke   target: use 64-bi...
639
  	pr_debug("%s_TPG[%hu]_LUN[%llu->%llu] - Added %s ACL for "
e3d6f909e   Andy Grover   target: Core clea...
640
641
  		" InitiatorNode: %s
  ", tpg->se_tpg_tfo->get_fabric_name(),
6bb826121   Nicholas Bellinger   target: Convert s...
642
  		tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun,
03a68b44f   Andy Grover   target: Remove en...
643
  		lun_access_ro ? "RO" : "RW",
b6a54b8d8   Chris Zankel   target: remove in...
644
  		nacl->initiatorname);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
645
646
647
648
  	/*
  	 * Check to see if there are any existing persistent reservation APTPL
  	 * pre-registrations that need to be enabled for this LUN ACL..
  	 */
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
649
  	core_scsi3_check_aptpl_registration(dev, tpg, lun, nacl,
e24805637   Nicholas Bellinger   target: Fix APTPL...
650
  					    lacl->mapped_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
651
652
  	return 0;
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
653
  int core_dev_del_initiator_node_lun_acl(
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
654
655
656
  	struct se_lun *lun,
  	struct se_lun_acl *lacl)
  {
adf653f92   Christoph Hellwig   target: Subsume s...
657
  	struct se_portal_group *tpg = lun->lun_tpg;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
658
  	struct se_node_acl *nacl;
29a05deeb   Nicholas Bellinger   target: Convert s...
659
  	struct se_dev_entry *deve;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
660
661
  
  	nacl = lacl->se_lun_nacl;
6708bb27b   Andy Grover   target: Follow up...
662
  	if (!nacl)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
663
  		return -EINVAL;
29a05deeb   Nicholas Bellinger   target: Convert s...
664
665
666
667
668
  	mutex_lock(&nacl->lun_entry_mutex);
  	deve = target_nacl_find_deve(nacl, lacl->mapped_lun);
  	if (deve)
  		core_disable_device_list_for_node(lun, deve, nacl, tpg);
  	mutex_unlock(&nacl->lun_entry_mutex);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
669

f2d306802   Hannes Reinecke   target: use 64-bi...
670
671
672
  	pr_debug("%s_TPG[%hu]_LUN[%llu] - Removed ACL for"
  		" InitiatorNode: %s Mapped LUN: %llu
  ",
e3d6f909e   Andy Grover   target: Core clea...
673
674
  		tpg->se_tpg_tfo->get_fabric_name(),
  		tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun,
b6a54b8d8   Chris Zankel   target: remove in...
675
  		nacl->initiatorname, lacl->mapped_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
676
677
678
679
680
681
682
683
  
  	return 0;
  }
  
  void core_dev_free_initiator_node_lun_acl(
  	struct se_portal_group *tpg,
  	struct se_lun_acl *lacl)
  {
6708bb27b   Andy Grover   target: Follow up...
684
  	pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s"
f2d306802   Hannes Reinecke   target: use 64-bi...
685
686
  		" Mapped LUN: %llu
  ", tpg->se_tpg_tfo->get_fabric_name(),
e3d6f909e   Andy Grover   target: Core clea...
687
688
  		tpg->se_tpg_tfo->tpg_get_tag(tpg),
  		tpg->se_tpg_tfo->get_fabric_name(),
b6a54b8d8   Chris Zankel   target: remove in...
689
  		lacl->se_lun_nacl->initiatorname, lacl->mapped_lun);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
690
691
692
  
  	kfree(lacl);
  }
0fd97ccf4   Christoph Hellwig   target: kill stru...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
  static void scsi_dump_inquiry(struct se_device *dev)
  {
  	struct t10_wwn *wwn = &dev->t10_wwn;
  	char buf[17];
  	int i, device_type;
  	/*
  	 * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer
  	 */
  	for (i = 0; i < 8; i++)
  		if (wwn->vendor[i] >= 0x20)
  			buf[i] = wwn->vendor[i];
  		else
  			buf[i] = ' ';
  	buf[i] = '\0';
  	pr_debug("  Vendor: %s
  ", buf);
  
  	for (i = 0; i < 16; i++)
  		if (wwn->model[i] >= 0x20)
  			buf[i] = wwn->model[i];
  		else
  			buf[i] = ' ';
  	buf[i] = '\0';
  	pr_debug("  Model: %s
  ", buf);
  
  	for (i = 0; i < 4; i++)
  		if (wwn->revision[i] >= 0x20)
  			buf[i] = wwn->revision[i];
  		else
  			buf[i] = ' ';
  	buf[i] = '\0';
  	pr_debug("  Revision: %s
  ", buf);
  
  	device_type = dev->transport->get_device_type(dev);
  	pr_debug("  Type:   %s ", scsi_device_type(device_type));
0fd97ccf4   Christoph Hellwig   target: kill stru...
730
731
732
733
734
  }
  
  struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
  {
  	struct se_device *dev;
4863e5256   Nicholas Bellinger   target: Add per d...
735
  	struct se_lun *xcopy_lun;
0fd97ccf4   Christoph Hellwig   target: kill stru...
736

0a06d4309   Christoph Hellwig   target: simplify ...
737
  	dev = hba->backend->ops->alloc_device(hba, name);
0fd97ccf4   Christoph Hellwig   target: kill stru...
738
739
  	if (!dev)
  		return NULL;
0ff875498   Nicholas Bellinger   target: Add link_...
740
  	dev->dev_link_magic = SE_DEV_LINK_MAGIC;
0fd97ccf4   Christoph Hellwig   target: kill stru...
741
  	dev->se_hba = hba;
0a06d4309   Christoph Hellwig   target: simplify ...
742
  	dev->transport = hba->backend->ops;
fe052a181   Sagi Grimberg   target: Use struc...
743
  	dev->prot_length = sizeof(struct t10_pi_tuple);
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
744
  	dev->hba_index = hba->hba_index;
0fd97ccf4   Christoph Hellwig   target: kill stru...
745
746
747
748
749
750
751
  
  	INIT_LIST_HEAD(&dev->dev_list);
  	INIT_LIST_HEAD(&dev->dev_sep_list);
  	INIT_LIST_HEAD(&dev->dev_tmr_list);
  	INIT_LIST_HEAD(&dev->delayed_cmd_list);
  	INIT_LIST_HEAD(&dev->state_list);
  	INIT_LIST_HEAD(&dev->qf_cmd_list);
d9ea32bff   Nicholas Bellinger   target: Add globa...
752
  	INIT_LIST_HEAD(&dev->g_dev_node);
0fd97ccf4   Christoph Hellwig   target: kill stru...
753
754
755
756
757
758
  	spin_lock_init(&dev->execute_task_lock);
  	spin_lock_init(&dev->delayed_cmd_lock);
  	spin_lock_init(&dev->dev_reservation_lock);
  	spin_lock_init(&dev->se_port_lock);
  	spin_lock_init(&dev->se_tmr_lock);
  	spin_lock_init(&dev->qf_cmd_lock);
68ff9b9b2   Nicholas Bellinger   target: Add suppo...
759
  	sema_init(&dev->caw_sem, 1);
0fd97ccf4   Christoph Hellwig   target: kill stru...
760
761
762
763
764
765
766
767
  	INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list);
  	spin_lock_init(&dev->t10_wwn.t10_vpd_lock);
  	INIT_LIST_HEAD(&dev->t10_pr.registration_list);
  	INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list);
  	spin_lock_init(&dev->t10_pr.registration_lock);
  	spin_lock_init(&dev->t10_pr.aptpl_reg_lock);
  	INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list);
  	spin_lock_init(&dev->t10_alua.tg_pt_gps_lock);
c66094bf3   Hannes Reinecke   target_core_alua:...
768
769
  	INIT_LIST_HEAD(&dev->t10_alua.lba_map_list);
  	spin_lock_init(&dev->t10_alua.lba_map_lock);
0fd97ccf4   Christoph Hellwig   target: kill stru...
770

0fd97ccf4   Christoph Hellwig   target: kill stru...
771
772
773
774
  	dev->t10_wwn.t10_dev = dev;
  	dev->t10_alua.t10_dev = dev;
  
  	dev->dev_attrib.da_dev = dev;
adfa9570a   Tregaron Bayly   target: Add devic...
775
  	dev->dev_attrib.emulate_model_alias = DA_EMULATE_MODEL_ALIAS;
814e5b451   Christoph Hellwig   target: fix DPO a...
776
777
778
  	dev->dev_attrib.emulate_dpo = 1;
  	dev->dev_attrib.emulate_fua_write = 1;
  	dev->dev_attrib.emulate_fua_read = 1;
0fd97ccf4   Christoph Hellwig   target: kill stru...
779
780
781
782
783
  	dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE;
  	dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL;
  	dev->dev_attrib.emulate_tas = DA_EMULATE_TAS;
  	dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU;
  	dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS;
0123a9ec6   Nicholas Bellinger   target: Add MAXIM...
784
  	dev->dev_attrib.emulate_caw = DA_EMULATE_CAW;
d397a445f   Nicholas Bellinger   target: Add Third...
785
  	dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC;
2ed22c9cb   Nicholas Bellinger   target/configfs: ...
786
  	dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT;
0fd97ccf4   Christoph Hellwig   target: kill stru...
787
  	dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
92404e609   Nicholas Bellinger   target: Add force...
788
  	dev->dev_attrib.force_pr_aptpl = DA_FORCE_PR_APTPL;
0fd97ccf4   Christoph Hellwig   target: kill stru...
789
790
791
792
793
794
795
796
  	dev->dev_attrib.is_nonrot = DA_IS_NONROT;
  	dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD;
  	dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT;
  	dev->dev_attrib.max_unmap_block_desc_count =
  		DA_MAX_UNMAP_BLOCK_DESC_COUNT;
  	dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT;
  	dev->dev_attrib.unmap_granularity_alignment =
  				DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
e6f41633c   Jamie Pocas   target/sbc: Add L...
797
798
  	dev->dev_attrib.unmap_zeroes_data =
  				DA_UNMAP_ZEROES_DATA_DEFAULT;
773cbaf74   Nicholas Bellinger   target: Add/check...
799
  	dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN;
0fd97ccf4   Christoph Hellwig   target: kill stru...
800

4863e5256   Nicholas Bellinger   target: Add per d...
801
  	xcopy_lun = &dev->xcopy_lun;
4cc987eaf   Nicholas Bellinger   target: Drop lun_...
802
  	rcu_assign_pointer(xcopy_lun->lun_se_dev, dev);
4863e5256   Nicholas Bellinger   target: Add per d...
803
  	init_completion(&xcopy_lun->lun_ref_comp);
adf653f92   Christoph Hellwig   target: Subsume s...
804
805
806
807
  	INIT_LIST_HEAD(&xcopy_lun->lun_deve_list);
  	INIT_LIST_HEAD(&xcopy_lun->lun_dev_link);
  	mutex_init(&xcopy_lun->lun_tg_pt_md_mutex);
  	xcopy_lun->lun_tpg = &xcopy_pt_tpg;
4863e5256   Nicholas Bellinger   target: Add per d...
808

0fd97ccf4   Christoph Hellwig   target: kill stru...
809
810
  	return dev;
  }
8a9ebe717   Mike Christie   target: Fix WRITE...
811
812
813
814
815
816
  /*
   * Check if the underlying struct block_device request_queue supports
   * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
   * in ATA and we need to set TPE=1
   */
  bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
ea263c7fa   Mike Christie   target: Fix max_u...
817
  				       struct request_queue *q)
8a9ebe717   Mike Christie   target: Fix WRITE...
818
  {
ea263c7fa   Mike Christie   target: Fix max_u...
819
  	int block_size = queue_logical_block_size(q);
8a9ebe717   Mike Christie   target: Fix WRITE...
820
821
  	if (!blk_queue_discard(q))
  		return false;
ea263c7fa   Mike Christie   target: Fix max_u...
822
823
  	attrib->max_unmap_lba_count =
  		q->limits.max_discard_sectors >> (ilog2(block_size) - 9);
8a9ebe717   Mike Christie   target: Fix WRITE...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
  	/*
  	 * Currently hardcoded to 1 in Linux/SCSI code..
  	 */
  	attrib->max_unmap_block_desc_count = 1;
  	attrib->unmap_granularity = q->limits.discard_granularity / block_size;
  	attrib->unmap_granularity_alignment = q->limits.discard_alignment /
  								block_size;
  	attrib->unmap_zeroes_data = q->limits.discard_zeroes_data;
  	return true;
  }
  EXPORT_SYMBOL(target_configure_unmap_from_queue);
  
  /*
   * Convert from blocksize advertised to the initiator to the 512 byte
   * units unconditionally used by the Linux block layer.
   */
  sector_t target_to_linux_sector(struct se_device *dev, sector_t lb)
  {
  	switch (dev->dev_attrib.block_size) {
  	case 4096:
  		return lb << 3;
  	case 2048:
  		return lb << 2;
  	case 1024:
  		return lb << 1;
  	default:
  		return lb;
  	}
  }
  EXPORT_SYMBOL(target_to_linux_sector);
0fd97ccf4   Christoph Hellwig   target: kill stru...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
  int target_configure_device(struct se_device *dev)
  {
  	struct se_hba *hba = dev->se_hba;
  	int ret;
  
  	if (dev->dev_flags & DF_CONFIGURED) {
  		pr_err("se_dev->se_dev_ptr already set for storage"
  				" object
  ");
  		return -EEXIST;
  	}
  
  	ret = dev->transport->configure_device(dev);
  	if (ret)
  		goto out;
0fd97ccf4   Christoph Hellwig   target: kill stru...
869
870
871
872
873
874
875
876
877
878
879
880
  	/*
  	 * XXX: there is not much point to have two different values here..
  	 */
  	dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size;
  	dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth;
  
  	/*
  	 * Align max_hw_sectors down to PAGE_SIZE I/O transfers
  	 */
  	dev->dev_attrib.hw_max_sectors =
  		se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors,
  					 dev->dev_attrib.hw_block_size);
046ba6428   Nicholas Bellinger   target: Drop arbi...
881
  	dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors;
0fd97ccf4   Christoph Hellwig   target: kill stru...
882
883
884
  
  	dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX);
  	dev->creation_time = get_jiffies_64();
0fd97ccf4   Christoph Hellwig   target: kill stru...
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
  	ret = core_setup_alua(dev);
  	if (ret)
  		goto out;
  
  	/*
  	 * Startup the struct se_device processing thread
  	 */
  	dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1,
  				      dev->transport->name);
  	if (!dev->tmr_wq) {
  		pr_err("Unable to create tmr workqueue for %s
  ",
  			dev->transport->name);
  		ret = -ENOMEM;
  		goto out_free_alua;
  	}
  
  	/*
  	 * Setup work_queue for QUEUE_FULL
  	 */
  	INIT_WORK(&dev->qf_work_queue, target_qf_do_work);
  
  	/*
  	 * Preload the initial INQUIRY const values if we are doing
  	 * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI
  	 * passthrough because this is being provided by the backend LLD.
  	 */
a3541703e   Andy Grover   target: Use a PAS...
912
  	if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)) {
0fd97ccf4   Christoph Hellwig   target: kill stru...
913
914
915
916
917
918
919
920
921
922
923
924
  		strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8);
  		strncpy(&dev->t10_wwn.model[0],
  			dev->transport->inquiry_prod, 16);
  		strncpy(&dev->t10_wwn.revision[0],
  			dev->transport->inquiry_rev, 4);
  	}
  
  	scsi_dump_inquiry(dev);
  
  	spin_lock(&hba->device_lock);
  	hba->dev_count++;
  	spin_unlock(&hba->device_lock);
d9ea32bff   Nicholas Bellinger   target: Add globa...
925
926
927
928
  
  	mutex_lock(&g_device_mutex);
  	list_add_tail(&dev->g_dev_node, &g_device_list);
  	mutex_unlock(&g_device_mutex);
5f7da044f   Nicholas Bellinger   target: Fix virtu...
929
  	dev->dev_flags |= DF_CONFIGURED;
0fd97ccf4   Christoph Hellwig   target: kill stru...
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
  	return 0;
  
  out_free_alua:
  	core_alua_free_lu_gp_mem(dev);
  out:
  	se_release_vpd_for_dev(dev);
  	return ret;
  }
  
  void target_free_device(struct se_device *dev)
  {
  	struct se_hba *hba = dev->se_hba;
  
  	WARN_ON(!list_empty(&dev->dev_sep_list));
  
  	if (dev->dev_flags & DF_CONFIGURED) {
  		destroy_workqueue(dev->tmr_wq);
d9ea32bff   Nicholas Bellinger   target: Add globa...
947
948
949
  		mutex_lock(&g_device_mutex);
  		list_del(&dev->g_dev_node);
  		mutex_unlock(&g_device_mutex);
0fd97ccf4   Christoph Hellwig   target: kill stru...
950
951
952
953
954
955
  		spin_lock(&hba->device_lock);
  		hba->dev_count--;
  		spin_unlock(&hba->device_lock);
  	}
  
  	core_alua_free_lu_gp_mem(dev);
229d4f112   Hannes Reinecke   target_core_alua:...
956
  	core_alua_set_lba_map(dev, NULL, 0, 0);
0fd97ccf4   Christoph Hellwig   target: kill stru...
957
958
  	core_scsi3_free_all_registrations(dev);
  	se_release_vpd_for_dev(dev);
2ed22c9cb   Nicholas Bellinger   target/configfs: ...
959
960
  	if (dev->transport->free_prot)
  		dev->transport->free_prot(dev);
0fd97ccf4   Christoph Hellwig   target: kill stru...
961
962
  	dev->transport->free_device(dev);
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
963
964
965
966
  int core_dev_setup_virtual_lun0(void)
  {
  	struct se_hba *hba;
  	struct se_device *dev;
db5d1c3cc   Andy Grover   target: Make virt...
967
  	char buf[] = "rd_pages=8,rd_nullio=1";
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
968
  	int ret;
6708bb27b   Andy Grover   target: Follow up...
969
  	hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
970
971
  	if (IS_ERR(hba))
  		return PTR_ERR(hba);
0fd97ccf4   Christoph Hellwig   target: kill stru...
972
973
  	dev = target_alloc_device(hba, "virt_lun0");
  	if (!dev) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
974
  		ret = -ENOMEM;
0fd97ccf4   Christoph Hellwig   target: kill stru...
975
  		goto out_free_hba;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
976
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
977

0a06d4309   Christoph Hellwig   target: simplify ...
978
  	hba->backend->ops->set_configfs_dev_params(dev, buf, sizeof(buf));
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
979

0fd97ccf4   Christoph Hellwig   target: kill stru...
980
981
982
  	ret = target_configure_device(dev);
  	if (ret)
  		goto out_free_se_dev;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
983

0fd97ccf4   Christoph Hellwig   target: kill stru...
984
985
  	lun0_hba = hba;
  	g_lun0_dev = dev;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
986
  	return 0;
0fd97ccf4   Christoph Hellwig   target: kill stru...
987
988
989
990
991
  
  out_free_se_dev:
  	target_free_device(dev);
  out_free_hba:
  	core_delete_hba(hba);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
992
993
994
995
996
997
  	return ret;
  }
  
  
  void core_dev_release_virtual_lun0(void)
  {
e3d6f909e   Andy Grover   target: Core clea...
998
  	struct se_hba *hba = lun0_hba;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
999

6708bb27b   Andy Grover   target: Follow up...
1000
  	if (!hba)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1001
  		return;
e3d6f909e   Andy Grover   target: Core clea...
1002
  	if (g_lun0_dev)
0fd97ccf4   Christoph Hellwig   target: kill stru...
1003
  		target_free_device(g_lun0_dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1004
1005
  	core_delete_hba(hba);
  }
7bfea53b5   Andy Grover   target: Move pass...
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
  
  /*
   * Common CDB parsing for kernel and user passthrough.
   */
  sense_reason_t
  passthrough_parse_cdb(struct se_cmd *cmd,
  	sense_reason_t (*exec_cmd)(struct se_cmd *cmd))
  {
  	unsigned char *cdb = cmd->t_task_cdb;
  
  	/*
  	 * Clear a lun set in the cdb if the initiator talking to use spoke
  	 * and old standards version, as we can't assume the underlying device
  	 * won't choke up on it.
  	 */
  	switch (cdb[0]) {
  	case READ_10: /* SBC - RDProtect */
  	case READ_12: /* SBC - RDProtect */
  	case READ_16: /* SBC - RDProtect */
  	case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */
  	case VERIFY: /* SBC - VRProtect */
  	case VERIFY_16: /* SBC - VRProtect */
  	case WRITE_VERIFY: /* SBC - VRProtect */
  	case WRITE_VERIFY_12: /* SBC - VRProtect */
  	case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */
  		break;
  	default:
  		cdb[1] &= 0x1f; /* clear logical unit number */
  		break;
  	}
  
  	/*
  	 * For REPORT LUNS we always need to emulate the response, for everything
  	 * else, pass it up.
  	 */
  	if (cdb[0] == REPORT_LUNS) {
  		cmd->execute_cmd = spc_emulate_report_luns;
  		return TCM_NO_SENSE;
  	}
  
  	/* Set DATA_CDB flag for ops that should have it */
  	switch (cdb[0]) {
  	case READ_6:
  	case READ_10:
  	case READ_12:
  	case READ_16:
  	case WRITE_6:
  	case WRITE_10:
  	case WRITE_12:
  	case WRITE_16:
  	case WRITE_VERIFY:
  	case WRITE_VERIFY_12:
  	case 0x8e: /* WRITE_VERIFY_16 */
  	case COMPARE_AND_WRITE:
  	case XDWRITEREAD_10:
  		cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
  		break;
  	case VARIABLE_LENGTH_CMD:
  		switch (get_unaligned_be16(&cdb[8])) {
  		case READ_32:
  		case WRITE_32:
  		case 0x0c: /* WRITE_VERIFY_32 */
  		case XDWRITEREAD_32:
  			cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
  			break;
  		}
  	}
  
  	cmd->execute_cmd = exec_cmd;
  
  	return TCM_NO_SENSE;
  }
  EXPORT_SYMBOL(passthrough_parse_cdb);