Print this page
NEX-6832 fcsm module's debug level default should be 0 (cstyle fix)
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-7503 backport illumos #7307
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-7048 COMSTAR MODE_SENSE support is broken
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5428 Backout the 5.0 changes
NEX-2937 Continuous write_same starves all other commands
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-4707 memory leak in stmf_sbd`sbd_attach() on successful property lookup
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3508 CLONE - Port NEX-2946 Add UNMAP/TRIM functionality to ZFS and illumos
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Conflicts:
usr/src/uts/common/io/scsi/targets/sd.c
usr/src/uts/common/sys/scsi/targets/sddef.h
NEX-3111 Comstar does not pass cstyle and hdrchk
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Tony Nguyen <tony.nguyen@nexenta.com>
NEX-3023 Panics and hangs when using write_same and compare_and_write
Review by: Bayard Bell <bayard.bell@nexenta.com>
Review by: Rick McNeal <rick.mcneal@nexenta.com>
Review by: Jean McCormack <jean.mccormack@nexenta.com>
Approved by: Jean McCormack <jean.mccormack@nexenta.com>
Related bug: NEX-2723 Kernel panic in xfer_completion code for write_same (0x93) and compare_and_write (0x89)
NEX-1965 Page fault at netbios_first_level_name_decode+0xbb
Support simultaneous compare_and_write operations for VAAI
Bug IDs SUP-505
SUP-1768
SUP-1928
Code Reviewers:
Sarah Jelinek
Jeffry Molanus
Albert Lee
Harold Shaw
NEX-988 itask_lu_[read|write]_time was inadvertently removed by the Illumos 3862 fix
re #12618 rb4053 Creating LU unconditionally enables write cache on backing store device
re #7936 rb3706 Support for COMSTAR/OEM
re #8002 rb3706 Allow setting iSCSI vendor ID via stmf_sbd.conf
re #11454 rb3750 Fix inconsistent vid/pid in stmf
Re #6790 backspace should perform delete on console
VAAI (XXX ATS support for COMSTAR, YYY Block-copy support for COMSTAR)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
+++ new/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 - * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 24 * Copyright (c) 2013 by Delphix. All rights reserved.
25 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
26 26 */
27 27
28 -#include <sys/sysmacros.h>
29 28 #include <sys/conf.h>
29 +#include <sys/list.h>
30 30 #include <sys/file.h>
31 31 #include <sys/ddi.h>
32 32 #include <sys/sunddi.h>
33 33 #include <sys/modctl.h>
34 34 #include <sys/scsi/scsi.h>
35 35 #include <sys/scsi/impl/scsi_reset_notify.h>
36 36 #include <sys/disp.h>
37 37 #include <sys/byteorder.h>
38 38 #include <sys/pathname.h>
39 39 #include <sys/atomic.h>
40 40 #include <sys/nvpair.h>
41 41 #include <sys/fs/zfs.h>
42 42 #include <sys/sdt.h>
43 43 #include <sys/dkio.h>
44 44 #include <sys/zfs_ioctl.h>
45 45
46 46 #include <sys/stmf.h>
47 47 #include <sys/lpif.h>
48 48 #include <sys/stmf_ioctl.h>
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
49 49 #include <sys/stmf_sbd_ioctl.h>
50 50
51 51 #include "stmf_sbd.h"
52 52 #include "sbd_impl.h"
53 53
54 54 #define SBD_IS_ZVOL(zvol) (strncmp("/dev/zvol", zvol, 9))
55 55
56 56 extern sbd_status_t sbd_pgr_meta_init(sbd_lu_t *sl);
57 57 extern sbd_status_t sbd_pgr_meta_load(sbd_lu_t *sl);
58 58 extern void sbd_pgr_reset(sbd_lu_t *sl);
59 +extern int HardwareAcceleratedLocking;
60 +extern int HardwareAcceleratedInit;
61 +extern int HardwareAcceleratedMove;
62 +extern uint8_t sbd_unmap_enable;
59 63
60 64 static int sbd_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
61 65 void **result);
62 66 static int sbd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
63 67 static int sbd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
64 68 static int sbd_open(dev_t *devp, int flag, int otype, cred_t *credp);
65 69 static int sbd_close(dev_t dev, int flag, int otype, cred_t *credp);
66 70 static int stmf_sbd_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
67 71 cred_t *credp, int *rval);
68 72 void sbd_lp_cb(stmf_lu_provider_t *lp, int cmd, void *arg, uint32_t flags);
69 73 stmf_status_t sbd_proxy_reg_lu(uint8_t *luid, void *proxy_reg_arg,
70 74 uint32_t proxy_reg_arg_len);
71 75 stmf_status_t sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg,
72 76 uint32_t proxy_reg_arg_len);
73 77 stmf_status_t sbd_proxy_msg(uint8_t *luid, void *proxy_arg,
74 78 uint32_t proxy_arg_len, uint32_t type);
75 79 int sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
76 80 uint32_t *err_ret);
77 81 int sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret);
78 82 int sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret);
79 83 int sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret,
80 84 int no_register, sbd_lu_t **slr);
81 85 int sbd_import_active_lu(sbd_import_lu_t *ilu, sbd_lu_t *sl, uint32_t *err_ret);
82 86 int sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret);
83 87 int sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret);
84 88 int sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz,
85 89 uint32_t *err_ret);
86 90 int sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz,
87 91 uint32_t *err_ret);
88 92 int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
89 93 sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret);
90 94 static char *sbd_get_zvol_name(sbd_lu_t *);
91 95 static int sbd_get_unmap_props(sbd_unmap_props_t *sup, sbd_unmap_props_t *osup,
92 96 uint32_t *err_ret);
93 97 sbd_status_t sbd_create_zfs_meta_object(sbd_lu_t *sl);
94 98 sbd_status_t sbd_open_zfs_meta(sbd_lu_t *sl);
95 99 sbd_status_t sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz,
96 100 uint64_t off);
97 101 sbd_status_t sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz,
98 102 uint64_t off);
99 103 sbd_status_t sbd_update_zfs_prop(sbd_lu_t *sl);
100 104 int sbd_is_zvol(char *path);
101 105 int sbd_zvolget(char *zvol_name, char **comstarprop);
|
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
102 106 int sbd_zvolset(char *zvol_name, char *comstarprop);
103 107 char sbd_ctoi(char c);
104 108 void sbd_close_lu(sbd_lu_t *sl);
105 109
106 110 static ldi_ident_t sbd_zfs_ident;
107 111 static stmf_lu_provider_t *sbd_lp;
108 112 static sbd_lu_t *sbd_lu_list = NULL;
109 113 static kmutex_t sbd_lock;
110 114 static dev_info_t *sbd_dip;
111 115 static uint32_t sbd_lu_count = 0;
116 +uint8_t sbd_enable_unmap_sync = 0;
112 117
113 118 /* Global property settings for the logical unit */
114 -char sbd_vendor_id[] = "SUN ";
119 +char sbd_vendor_id[] = "NEXENTA ";
115 120 char sbd_product_id[] = "COMSTAR ";
116 121 char sbd_revision[] = "1.0 ";
117 122 char *sbd_mgmt_url = NULL;
118 123 uint16_t sbd_mgmt_url_alloc_size = 0;
119 124 krwlock_t sbd_global_prop_lock;
120 125
121 126 static char sbd_name[] = "sbd";
122 127
123 128 static struct cb_ops sbd_cb_ops = {
124 129 sbd_open, /* open */
125 130 sbd_close, /* close */
126 131 nodev, /* strategy */
127 132 nodev, /* print */
128 133 nodev, /* dump */
129 134 nodev, /* read */
130 135 nodev, /* write */
131 136 stmf_sbd_ioctl, /* ioctl */
132 137 nodev, /* devmap */
133 138 nodev, /* mmap */
134 139 nodev, /* segmap */
135 140 nochpoll, /* chpoll */
136 141 ddi_prop_op, /* cb_prop_op */
137 142 0, /* streamtab */
138 143 D_NEW | D_MP, /* cb_flag */
139 144 CB_REV, /* rev */
140 145 nodev, /* aread */
141 146 nodev /* awrite */
142 147 };
143 148
144 149 static struct dev_ops sbd_ops = {
145 150 DEVO_REV,
146 151 0,
147 152 sbd_getinfo,
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
148 153 nulldev, /* identify */
149 154 nulldev, /* probe */
150 155 sbd_attach,
151 156 sbd_detach,
152 157 nodev, /* reset */
153 158 &sbd_cb_ops,
154 159 NULL, /* bus_ops */
155 160 NULL /* power */
156 161 };
157 162
158 -#define SBD_NAME "COMSTAR SBD"
163 +#ifdef DEBUG
164 +#define SBD_NAME "COMSTAR SBD+ " __DATE__ " " __TIME__ " DEBUG"
165 +#else
166 +#define SBD_NAME "COMSTAR SBD+"
167 +#endif
159 168
160 169 static struct modldrv modldrv = {
161 170 &mod_driverops,
162 171 SBD_NAME,
163 172 &sbd_ops
164 173 };
165 174
166 175 static struct modlinkage modlinkage = {
167 176 MODREV_1,
168 177 &modldrv,
169 178 NULL
170 179 };
171 180
172 181 int
173 182 _init(void)
174 183 {
175 184 int ret;
176 185
177 186 ret = mod_install(&modlinkage);
178 187 if (ret)
179 188 return (ret);
180 189 sbd_lp = (stmf_lu_provider_t *)stmf_alloc(STMF_STRUCT_LU_PROVIDER,
181 190 0, 0);
182 191 sbd_lp->lp_lpif_rev = LPIF_REV_2;
183 192 sbd_lp->lp_instance = 0;
184 193 sbd_lp->lp_name = sbd_name;
185 194 sbd_lp->lp_cb = sbd_lp_cb;
186 195 sbd_lp->lp_alua_support = 1;
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
187 196 sbd_lp->lp_proxy_msg = sbd_proxy_msg;
188 197 sbd_zfs_ident = ldi_ident_from_anon();
189 198
190 199 if (stmf_register_lu_provider(sbd_lp) != STMF_SUCCESS) {
191 200 (void) mod_remove(&modlinkage);
192 201 stmf_free(sbd_lp);
193 202 return (EINVAL);
194 203 }
195 204 mutex_init(&sbd_lock, NULL, MUTEX_DRIVER, NULL);
196 205 rw_init(&sbd_global_prop_lock, NULL, RW_DRIVER, NULL);
206 +
207 + if (HardwareAcceleratedLocking == 0)
208 + cmn_err(CE_NOTE, "HardwareAcceleratedLocking Disabled");
209 + if (HardwareAcceleratedMove == 0)
210 + cmn_err(CE_NOTE, "HardwareAcceleratedMove Disabled");
211 + if (HardwareAcceleratedInit == 0)
212 + cmn_err(CE_NOTE, "HardwareAcceleratedInit Disabled");
213 +
197 214 return (0);
198 215 }
199 216
200 217 int
201 218 _fini(void)
202 219 {
203 220 int ret;
204 221
205 222 /*
206 223 * If we have registered lus, then make sure they are all offline
207 224 * if so then deregister them. This should drop the sbd_lu_count
208 225 * to zero.
209 226 */
210 227 if (sbd_lu_count) {
211 228 sbd_lu_t *slu;
212 229
213 230 /* See if all of them are offline */
214 231 mutex_enter(&sbd_lock);
215 232 for (slu = sbd_lu_list; slu != NULL; slu = slu->sl_next) {
216 233 if ((slu->sl_state != STMF_STATE_OFFLINE) ||
217 234 slu->sl_state_not_acked) {
218 235 mutex_exit(&sbd_lock);
219 236 return (EBUSY);
220 237 }
221 238 }
222 239 mutex_exit(&sbd_lock);
223 240
224 241 #if 0
225 242 /* ok start deregistering them */
226 243 while (sbd_lu_list) {
227 244 sbd_store_t *sst = sbd_lu_list->sl_sst;
228 245 if (sst->sst_deregister_lu(sst) != STMF_SUCCESS)
229 246 return (EBUSY);
230 247 }
231 248 #endif
232 249 return (EBUSY);
233 250 }
234 251 if (stmf_deregister_lu_provider(sbd_lp) != STMF_SUCCESS)
235 252 return (EBUSY);
236 253 ret = mod_remove(&modlinkage);
237 254 if (ret != 0) {
238 255 (void) stmf_register_lu_provider(sbd_lp);
239 256 return (ret);
240 257 }
241 258 stmf_free(sbd_lp);
242 259 mutex_destroy(&sbd_lock);
243 260 rw_destroy(&sbd_global_prop_lock);
244 261 ldi_ident_release(sbd_zfs_ident);
245 262 return (0);
246 263 }
247 264
248 265 int
249 266 _info(struct modinfo *modinfop)
250 267 {
251 268 return (mod_info(&modlinkage, modinfop));
252 269 }
253 270
254 271 /* ARGSUSED */
255 272 static int
256 273 sbd_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
257 274 {
258 275 switch (cmd) {
259 276 case DDI_INFO_DEVT2DEVINFO:
260 277 *result = sbd_dip;
261 278 break;
262 279 case DDI_INFO_DEVT2INSTANCE:
263 280 *result = (void *)(uintptr_t)ddi_get_instance(sbd_dip);
264 281 break;
|
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
265 282 default:
266 283 return (DDI_FAILURE);
267 284 }
268 285
269 286 return (DDI_SUCCESS);
270 287 }
271 288
272 289 static int
273 290 sbd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
274 291 {
292 + char *prop;
293 +
275 294 switch (cmd) {
276 295 case DDI_ATTACH:
277 296 sbd_dip = dip;
278 297
279 298 if (ddi_create_minor_node(dip, "admin", S_IFCHR, 0,
280 299 DDI_NT_STMF_LP, 0) != DDI_SUCCESS) {
281 300 break;
282 301 }
283 302 ddi_report_dev(dip);
303 +
304 + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
305 + DDI_PROP_DONTPASS, "vendor-id", &prop) == DDI_SUCCESS) {
306 + (void) snprintf(sbd_vendor_id, 9, "%s%8s", prop, "");
307 + ddi_prop_free(prop);
308 + }
309 + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
310 + DDI_PROP_DONTPASS, "product-id", &prop) == DDI_SUCCESS) {
311 + (void) snprintf(sbd_product_id, 17, "%s%16s", prop, "");
312 + ddi_prop_free(prop);
313 + }
314 + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
315 + DDI_PROP_DONTPASS, "revision", &prop) == DDI_SUCCESS) {
316 + (void) snprintf(sbd_revision, 5, "%s%4s", prop, "");
317 + ddi_prop_free(prop);
318 + }
319 +
284 320 return (DDI_SUCCESS);
285 321 }
286 322
287 323 return (DDI_FAILURE);
288 324 }
289 325
290 326 static int
291 327 sbd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
292 328 {
293 329 switch (cmd) {
294 330 case DDI_DETACH:
295 331 ddi_remove_minor_node(dip, 0);
296 332 return (DDI_SUCCESS);
297 333 }
298 334
299 335 return (DDI_FAILURE);
300 336 }
301 337
302 338 /* ARGSUSED */
303 339 static int
304 340 sbd_open(dev_t *devp, int flag, int otype, cred_t *credp)
305 341 {
306 342 if (otype != OTYP_CHR)
307 343 return (EINVAL);
308 344 return (0);
309 345 }
310 346
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
311 347 /* ARGSUSED */
312 348 static int
313 349 sbd_close(dev_t dev, int flag, int otype, cred_t *credp)
314 350 {
315 351 return (0);
316 352 }
317 353
318 354 /* ARGSUSED */
319 355 static int
320 356 stmf_sbd_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
321 - cred_t *credp, int *rval)
357 + cred_t *credp, int *rval)
322 358 {
323 359 stmf_iocdata_t *iocd;
324 360 void *ibuf = NULL;
325 361 void *obuf = NULL;
326 362 sbd_lu_t *nsl;
327 363 int i;
328 364 int ret;
329 365
330 366 if (drv_priv(credp) != 0) {
331 367 return (EPERM);
332 368 }
333 369
334 370 ret = stmf_copyin_iocdata(data, mode, &iocd, &ibuf, &obuf);
335 371 if (ret)
336 372 return (ret);
337 373 iocd->stmf_error = 0;
338 374
339 375 switch (cmd) {
340 376 case SBD_IOCTL_CREATE_AND_REGISTER_LU:
341 377 if (iocd->stmf_ibuf_size <
342 378 (sizeof (sbd_create_and_reg_lu_t) - 8)) {
343 379 ret = EFAULT;
344 380 break;
345 381 }
346 382 if ((iocd->stmf_obuf_size == 0) ||
347 383 (iocd->stmf_obuf_size > iocd->stmf_ibuf_size)) {
348 384 ret = EINVAL;
349 385 break;
350 386 }
351 387 ret = sbd_create_register_lu((sbd_create_and_reg_lu_t *)
352 388 ibuf, iocd->stmf_ibuf_size, &iocd->stmf_error);
353 389 bcopy(ibuf, obuf, iocd->stmf_obuf_size);
354 390 break;
355 391 case SBD_IOCTL_SET_LU_STANDBY:
356 392 if (iocd->stmf_ibuf_size < sizeof (sbd_set_lu_standby_t)) {
357 393 ret = EFAULT;
358 394 break;
359 395 }
360 396 if (iocd->stmf_obuf_size) {
361 397 ret = EINVAL;
362 398 break;
363 399 }
364 400 ret = sbd_set_lu_standby((sbd_set_lu_standby_t *)ibuf,
365 401 &iocd->stmf_error);
366 402 break;
367 403 case SBD_IOCTL_IMPORT_LU:
368 404 if (iocd->stmf_ibuf_size <
369 405 (sizeof (sbd_import_lu_t) - 8)) {
370 406 ret = EFAULT;
371 407 break;
372 408 }
373 409 if ((iocd->stmf_obuf_size == 0) ||
374 410 (iocd->stmf_obuf_size > iocd->stmf_ibuf_size)) {
375 411 ret = EINVAL;
376 412 break;
377 413 }
378 414 ret = sbd_import_lu((sbd_import_lu_t *)ibuf,
379 415 iocd->stmf_ibuf_size, &iocd->stmf_error, 0, NULL);
380 416 bcopy(ibuf, obuf, iocd->stmf_obuf_size);
381 417 break;
382 418 case SBD_IOCTL_DELETE_LU:
383 419 if (iocd->stmf_ibuf_size < (sizeof (sbd_delete_lu_t) - 8)) {
384 420 ret = EFAULT;
385 421 break;
386 422 }
387 423 if (iocd->stmf_obuf_size) {
388 424 ret = EINVAL;
389 425 break;
390 426 }
391 427 ret = sbd_delete_lu((sbd_delete_lu_t *)ibuf,
392 428 iocd->stmf_ibuf_size, &iocd->stmf_error);
393 429 break;
394 430 case SBD_IOCTL_MODIFY_LU:
395 431 if (iocd->stmf_ibuf_size < (sizeof (sbd_modify_lu_t) - 8)) {
396 432 ret = EFAULT;
397 433 break;
398 434 }
399 435 if (iocd->stmf_obuf_size) {
400 436 ret = EINVAL;
401 437 break;
402 438 }
403 439 ret = sbd_modify_lu((sbd_modify_lu_t *)ibuf,
404 440 iocd->stmf_ibuf_size, &iocd->stmf_error);
405 441 break;
406 442 case SBD_IOCTL_SET_GLOBAL_LU:
407 443 if (iocd->stmf_ibuf_size < (sizeof (sbd_global_props_t) - 8)) {
408 444 ret = EFAULT;
409 445 break;
410 446 }
411 447 if (iocd->stmf_obuf_size) {
412 448 ret = EINVAL;
413 449 break;
414 450 }
415 451 ret = sbd_set_global_props((sbd_global_props_t *)ibuf,
416 452 iocd->stmf_ibuf_size, &iocd->stmf_error);
417 453 break;
418 454 case SBD_IOCTL_GET_GLOBAL_LU:
419 455 if (iocd->stmf_ibuf_size) {
420 456 ret = EINVAL;
421 457 break;
422 458 }
423 459 if (iocd->stmf_obuf_size < sizeof (sbd_global_props_t)) {
424 460 ret = EINVAL;
425 461 break;
426 462 }
427 463 ret = sbd_get_global_props((sbd_global_props_t *)obuf,
428 464 iocd->stmf_obuf_size, &iocd->stmf_error);
429 465 break;
430 466 case SBD_IOCTL_GET_LU_PROPS:
431 467 if (iocd->stmf_ibuf_size < (sizeof (sbd_lu_props_t) - 8)) {
432 468 ret = EFAULT;
433 469 break;
434 470 }
435 471 if (iocd->stmf_obuf_size < sizeof (sbd_lu_props_t)) {
436 472 ret = EINVAL;
437 473 break;
438 474 }
439 475 ret = sbd_get_lu_props((sbd_lu_props_t *)ibuf,
440 476 iocd->stmf_ibuf_size, (sbd_lu_props_t *)obuf,
441 477 iocd->stmf_obuf_size, &iocd->stmf_error);
442 478 break;
443 479 case SBD_IOCTL_GET_LU_LIST:
444 480 mutex_enter(&sbd_lock);
445 481 iocd->stmf_obuf_max_nentries = sbd_lu_count;
446 482 iocd->stmf_obuf_nentries = min((iocd->stmf_obuf_size >> 4),
447 483 sbd_lu_count);
448 484 for (nsl = sbd_lu_list, i = 0; nsl &&
449 485 (i < iocd->stmf_obuf_nentries); i++, nsl = nsl->sl_next) {
450 486 bcopy(nsl->sl_device_id + 4,
451 487 &(((uint8_t *)obuf)[i << 4]), 16);
452 488 }
453 489 mutex_exit(&sbd_lock);
454 490 ret = 0;
455 491 iocd->stmf_error = 0;
456 492 break;
457 493 case SBD_IOCTL_GET_UNMAP_PROPS:
458 494 if (iocd->stmf_ibuf_size < sizeof (sbd_unmap_props_t)) {
459 495 ret = EFAULT;
460 496 break;
461 497 }
462 498 if (iocd->stmf_obuf_size < sizeof (sbd_unmap_props_t)) {
463 499 ret = EINVAL;
464 500 break;
465 501 }
466 502 ret = sbd_get_unmap_props((sbd_unmap_props_t *)ibuf,
467 503 (sbd_unmap_props_t *)obuf, &iocd->stmf_error);
468 504 break;
469 505 default:
470 506 ret = ENOTTY;
471 507 }
472 508
473 509 if (ret == 0) {
474 510 ret = stmf_copyout_iocdata(data, mode, iocd, obuf);
475 511 } else if (iocd->stmf_error) {
476 512 (void) stmf_copyout_iocdata(data, mode, iocd, obuf);
477 513 }
478 514 if (obuf) {
479 515 kmem_free(obuf, iocd->stmf_obuf_size);
480 516 obuf = NULL;
481 517 }
482 518 if (ibuf) {
483 519 kmem_free(ibuf, iocd->stmf_ibuf_size);
484 520 ibuf = NULL;
485 521 }
486 522 kmem_free(iocd, sizeof (stmf_iocdata_t));
487 523 return (ret);
488 524 }
489 525
490 526 /* ARGSUSED */
491 527 void
492 528 sbd_lp_cb(stmf_lu_provider_t *lp, int cmd, void *arg, uint32_t flags)
493 529 {
494 530 nvpair_t *np;
495 531 char *s;
496 532 sbd_import_lu_t *ilu;
497 533 uint32_t ilu_sz;
498 534 uint32_t struct_sz;
499 535 uint32_t err_ret;
500 536 int iret;
501 537
502 538 if ((cmd != STMF_PROVIDER_DATA_UPDATED) || (arg == NULL)) {
503 539 return;
504 540 }
505 541
506 542 if ((flags & (STMF_PCB_STMF_ONLINING | STMF_PCB_PREG_COMPLETE)) == 0) {
507 543 return;
508 544 }
509 545
510 546 np = NULL;
511 547 ilu_sz = 1024;
512 548 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP);
513 549 while ((np = nvlist_next_nvpair((nvlist_t *)arg, np)) != NULL) {
514 550 if (nvpair_type(np) != DATA_TYPE_STRING) {
515 551 continue;
516 552 }
517 553 if (nvpair_value_string(np, &s) != 0) {
518 554 continue;
519 555 }
520 556 struct_sz = max(8, strlen(s) + 1);
521 557 struct_sz += sizeof (sbd_import_lu_t) - 8;
522 558 if (struct_sz > ilu_sz) {
523 559 kmem_free(ilu, ilu_sz);
524 560 ilu_sz = struct_sz + 32;
525 561 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP);
526 562 }
527 563 ilu->ilu_struct_size = struct_sz;
528 564 (void) strcpy(ilu->ilu_meta_fname, s);
529 565 iret = sbd_import_lu(ilu, struct_sz, &err_ret, 0, NULL);
530 566 if (iret) {
531 567 stmf_trace(0, "sbd_lp_cb: import_lu failed, ret = %d, "
532 568 "err_ret = %d", iret, err_ret);
533 569 } else {
534 570 stmf_trace(0, "Imported the LU %s", nvpair_name(np));
535 571 }
536 572 }
537 573
538 574 if (ilu) {
539 575 kmem_free(ilu, ilu_sz);
540 576 ilu = NULL;
541 577 }
542 578 }
543 579
544 580 sbd_status_t
545 581 sbd_link_lu(sbd_lu_t *sl)
546 582 {
547 583 sbd_lu_t *nsl;
548 584
549 585 mutex_enter(&sbd_lock);
550 586 mutex_enter(&sl->sl_lock);
551 587 ASSERT(sl->sl_trans_op != SL_OP_NONE);
552 588
553 589 if (sl->sl_flags & SL_LINKED) {
554 590 mutex_exit(&sbd_lock);
555 591 mutex_exit(&sl->sl_lock);
556 592 return (SBD_ALREADY);
557 593 }
558 594 for (nsl = sbd_lu_list; nsl; nsl = nsl->sl_next) {
559 595 if (strcmp(nsl->sl_name, sl->sl_name) == 0)
560 596 break;
561 597 }
562 598 if (nsl) {
563 599 mutex_exit(&sbd_lock);
564 600 mutex_exit(&sl->sl_lock);
565 601 return (SBD_ALREADY);
566 602 }
567 603 sl->sl_next = sbd_lu_list;
568 604 sbd_lu_list = sl;
569 605 sl->sl_flags |= SL_LINKED;
570 606 mutex_exit(&sbd_lock);
571 607 mutex_exit(&sl->sl_lock);
572 608 return (SBD_SUCCESS);
573 609 }
574 610
575 611 void
576 612 sbd_unlink_lu(sbd_lu_t *sl)
577 613 {
578 614 sbd_lu_t **ppnsl;
579 615
580 616 mutex_enter(&sbd_lock);
581 617 mutex_enter(&sl->sl_lock);
582 618 ASSERT(sl->sl_trans_op != SL_OP_NONE);
583 619
584 620 ASSERT(sl->sl_flags & SL_LINKED);
585 621 for (ppnsl = &sbd_lu_list; *ppnsl; ppnsl = &((*ppnsl)->sl_next)) {
586 622 if (*ppnsl == sl)
587 623 break;
588 624 }
589 625 ASSERT(*ppnsl);
590 626 *ppnsl = (*ppnsl)->sl_next;
591 627 sl->sl_flags &= ~SL_LINKED;
592 628 mutex_exit(&sbd_lock);
593 629 mutex_exit(&sl->sl_lock);
594 630 }
595 631
596 632 sbd_status_t
597 633 sbd_find_and_lock_lu(uint8_t *guid, uint8_t *meta_name, uint8_t op,
598 634 sbd_lu_t **ppsl)
599 635 {
600 636 sbd_lu_t *sl;
601 637 int found = 0;
602 638 sbd_status_t sret;
603 639
604 640 mutex_enter(&sbd_lock);
605 641 for (sl = sbd_lu_list; sl; sl = sl->sl_next) {
606 642 if (guid) {
607 643 found = bcmp(sl->sl_device_id + 4, guid, 16) == 0;
608 644 } else {
609 645 found = strcmp(sl->sl_name, (char *)meta_name) == 0;
610 646 }
611 647 if (found)
612 648 break;
613 649 }
614 650 if (!found) {
615 651 mutex_exit(&sbd_lock);
616 652 return (SBD_NOT_FOUND);
617 653 }
618 654 mutex_enter(&sl->sl_lock);
619 655 if (sl->sl_trans_op == SL_OP_NONE) {
620 656 sl->sl_trans_op = op;
621 657 *ppsl = sl;
622 658 sret = SBD_SUCCESS;
623 659 } else {
624 660 sret = SBD_BUSY;
625 661 }
626 662 mutex_exit(&sl->sl_lock);
627 663 mutex_exit(&sbd_lock);
628 664 return (sret);
629 665 }
630 666
631 667 sbd_status_t
632 668 sbd_read_meta(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf)
633 669 {
634 670 uint64_t meta_align;
635 671 uint64_t starting_off;
636 672 uint64_t data_off;
637 673 uint64_t ending_off;
638 674 uint64_t io_size;
639 675 uint8_t *io_buf;
640 676 vnode_t *vp;
641 677 sbd_status_t ret;
642 678 ssize_t resid;
643 679 int vret;
644 680
645 681 ASSERT(sl->sl_flags & SL_META_OPENED);
646 682 if (sl->sl_flags & SL_SHARED_META) {
647 683 meta_align = (((uint64_t)1) << sl->sl_data_blocksize_shift) - 1;
648 684 vp = sl->sl_data_vp;
649 685 ASSERT(vp);
650 686 } else {
651 687 meta_align = (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1;
652 688 if ((sl->sl_flags & SL_ZFS_META) == 0) {
653 689 vp = sl->sl_meta_vp;
654 690 ASSERT(vp);
655 691 }
656 692 }
657 693 starting_off = offset & ~(meta_align);
658 694 data_off = offset & meta_align;
659 695 ending_off = (offset + size + meta_align) & (~meta_align);
660 696 if (ending_off > sl->sl_meta_size_used) {
661 697 bzero(buf, size);
662 698 if (starting_off >= sl->sl_meta_size_used) {
663 699 return (SBD_SUCCESS);
664 700 }
665 701 ending_off = (sl->sl_meta_size_used + meta_align) &
666 702 (~meta_align);
667 703 if (size > (ending_off - (starting_off + data_off))) {
668 704 size = ending_off - (starting_off + data_off);
669 705 }
670 706 }
671 707 io_size = ending_off - starting_off;
672 708 io_buf = (uint8_t *)kmem_zalloc(io_size, KM_SLEEP);
673 709 ASSERT((starting_off + io_size) <= sl->sl_total_meta_size);
674 710
675 711 /*
676 712 * Don't proceed if the device has been closed
677 713 * This can occur on an access state change to standby or
678 714 * a delete. The writer lock is acquired before closing the
679 715 * lu. If importing, reading the metadata is valid, hence
680 716 * the check on SL_OP_IMPORT_LU.
681 717 */
682 718 rw_enter(&sl->sl_access_state_lock, RW_READER);
683 719 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0 &&
684 720 sl->sl_trans_op != SL_OP_IMPORT_LU) {
685 721 rw_exit(&sl->sl_access_state_lock);
686 722 ret = SBD_FILEIO_FAILURE;
687 723 goto sbd_read_meta_failure;
688 724 }
689 725 if (sl->sl_flags & SL_ZFS_META) {
690 726 if ((ret = sbd_read_zfs_meta(sl, io_buf, io_size,
691 727 starting_off)) != SBD_SUCCESS) {
692 728 rw_exit(&sl->sl_access_state_lock);
693 729 goto sbd_read_meta_failure;
694 730 }
695 731 } else {
696 732 vret = vn_rdwr(UIO_READ, vp, (caddr_t)io_buf, (ssize_t)io_size,
697 733 (offset_t)starting_off, UIO_SYSSPACE, FRSYNC,
698 734 RLIM64_INFINITY, CRED(), &resid);
699 735
700 736 if (vret || resid) {
701 737 ret = SBD_FILEIO_FAILURE | vret;
702 738 rw_exit(&sl->sl_access_state_lock);
703 739 goto sbd_read_meta_failure;
704 740 }
705 741 }
706 742 rw_exit(&sl->sl_access_state_lock);
707 743
708 744 bcopy(io_buf + data_off, buf, size);
709 745 ret = SBD_SUCCESS;
710 746
711 747 sbd_read_meta_failure:
712 748 kmem_free(io_buf, io_size);
713 749 return (ret);
714 750 }
715 751
716 752 sbd_status_t
717 753 sbd_write_meta(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf)
718 754 {
719 755 uint64_t meta_align;
720 756 uint64_t starting_off;
721 757 uint64_t data_off;
722 758 uint64_t ending_off;
723 759 uint64_t io_size;
724 760 uint8_t *io_buf;
725 761 vnode_t *vp;
726 762 sbd_status_t ret;
727 763 ssize_t resid;
728 764 int vret;
729 765
730 766 ASSERT(sl->sl_flags & SL_META_OPENED);
731 767 if (sl->sl_flags & SL_SHARED_META) {
732 768 meta_align = (((uint64_t)1) << sl->sl_data_blocksize_shift) - 1;
733 769 vp = sl->sl_data_vp;
734 770 ASSERT(vp);
735 771 } else {
736 772 meta_align = (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1;
737 773 if ((sl->sl_flags & SL_ZFS_META) == 0) {
738 774 vp = sl->sl_meta_vp;
739 775 ASSERT(vp);
740 776 }
741 777 }
742 778 starting_off = offset & ~(meta_align);
743 779 data_off = offset & meta_align;
744 780 ending_off = (offset + size + meta_align) & (~meta_align);
745 781 io_size = ending_off - starting_off;
746 782 io_buf = (uint8_t *)kmem_zalloc(io_size, KM_SLEEP);
747 783 ret = sbd_read_meta(sl, starting_off, io_size, io_buf);
748 784 if (ret != SBD_SUCCESS) {
749 785 goto sbd_write_meta_failure;
750 786 }
751 787 bcopy(buf, io_buf + data_off, size);
752 788 /*
753 789 * Don't proceed if the device has been closed
754 790 * This can occur on an access state change to standby or
755 791 * a delete. The writer lock is acquired before closing the
756 792 * lu. If importing, reading the metadata is valid, hence
757 793 * the check on SL_OP_IMPORT_LU.
758 794 */
759 795 rw_enter(&sl->sl_access_state_lock, RW_READER);
760 796 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0 &&
761 797 sl->sl_trans_op != SL_OP_IMPORT_LU) {
762 798 rw_exit(&sl->sl_access_state_lock);
763 799 ret = SBD_FILEIO_FAILURE;
764 800 goto sbd_write_meta_failure;
765 801 }
766 802 if (sl->sl_flags & SL_ZFS_META) {
767 803 if ((ret = sbd_write_zfs_meta(sl, io_buf, io_size,
768 804 starting_off)) != SBD_SUCCESS) {
769 805 rw_exit(&sl->sl_access_state_lock);
770 806 goto sbd_write_meta_failure;
771 807 }
772 808 } else {
773 809 vret = vn_rdwr(UIO_WRITE, vp, (caddr_t)io_buf, (ssize_t)io_size,
774 810 (offset_t)starting_off, UIO_SYSSPACE, FDSYNC,
775 811 RLIM64_INFINITY, CRED(), &resid);
776 812
777 813 if (vret || resid) {
778 814 ret = SBD_FILEIO_FAILURE | vret;
779 815 rw_exit(&sl->sl_access_state_lock);
780 816 goto sbd_write_meta_failure;
781 817 }
782 818 }
783 819 rw_exit(&sl->sl_access_state_lock);
784 820
785 821 ret = SBD_SUCCESS;
786 822
787 823 sbd_write_meta_failure:
788 824 kmem_free(io_buf, io_size);
789 825 return (ret);
790 826 }
791 827
792 828 uint8_t
793 829 sbd_calc_sum(uint8_t *buf, int size)
794 830 {
795 831 uint8_t s = 0;
796 832
797 833 while (size > 0)
798 834 s += buf[--size];
799 835
800 836 return (s);
801 837 }
802 838
803 839 uint8_t
804 840 sbd_calc_section_sum(sm_section_hdr_t *sm, uint32_t sz)
805 841 {
806 842 uint8_t s, o;
807 843
808 844 o = sm->sms_chksum;
809 845 sm->sms_chksum = 0;
810 846 s = sbd_calc_sum((uint8_t *)sm, sz);
811 847 sm->sms_chksum = o;
812 848
813 849 return (s);
814 850 }
815 851
816 852 uint32_t
817 853 sbd_strlen(char *str, uint32_t maxlen)
818 854 {
819 855 uint32_t i;
820 856
821 857 for (i = 0; i < maxlen; i++) {
822 858 if (str[i] == 0)
823 859 return (i);
824 860 }
825 861 return (i);
826 862 }
827 863
828 864 void
829 865 sbd_swap_meta_start(sbd_meta_start_t *sm)
830 866 {
831 867 if (sm->sm_magic == SBD_MAGIC)
832 868 return;
833 869 sm->sm_magic = BSWAP_64(sm->sm_magic);
834 870 sm->sm_meta_size = BSWAP_64(sm->sm_meta_size);
835 871 sm->sm_meta_size_used = BSWAP_64(sm->sm_meta_size_used);
836 872 sm->sm_ver_major = BSWAP_16(sm->sm_ver_major);
837 873 sm->sm_ver_minor = BSWAP_16(sm->sm_ver_minor);
838 874 sm->sm_ver_subminor = BSWAP_16(sm->sm_ver_subminor);
839 875 }
840 876
841 877 void
842 878 sbd_swap_section_hdr(sm_section_hdr_t *sm)
843 879 {
844 880 if (sm->sms_data_order == SMS_DATA_ORDER)
845 881 return;
846 882 sm->sms_offset = BSWAP_64(sm->sms_offset);
847 883 sm->sms_size = BSWAP_32(sm->sms_size);
848 884 sm->sms_id = BSWAP_16(sm->sms_id);
849 885 sm->sms_chksum += SMS_DATA_ORDER - sm->sms_data_order;
850 886 sm->sms_data_order = SMS_DATA_ORDER;
851 887 }
852 888
853 889 void
854 890 sbd_swap_lu_info_1_0(sbd_lu_info_1_0_t *sli)
855 891 {
856 892 sbd_swap_section_hdr(&sli->sli_sms_header);
857 893 if (sli->sli_data_order == SMS_DATA_ORDER)
858 894 return;
859 895 sli->sli_sms_header.sms_chksum += SMS_DATA_ORDER - sli->sli_data_order;
860 896 sli->sli_data_order = SMS_DATA_ORDER;
861 897 sli->sli_total_store_size = BSWAP_64(sli->sli_total_store_size);
862 898 sli->sli_total_meta_size = BSWAP_64(sli->sli_total_meta_size);
863 899 sli->sli_lu_data_offset = BSWAP_64(sli->sli_lu_data_offset);
864 900 sli->sli_lu_data_size = BSWAP_64(sli->sli_lu_data_size);
865 901 sli->sli_flags = BSWAP_32(sli->sli_flags);
866 902 sli->sli_blocksize = BSWAP_16(sli->sli_blocksize);
867 903 }
868 904
869 905 void
870 906 sbd_swap_lu_info_1_1(sbd_lu_info_1_1_t *sli)
871 907 {
872 908 sbd_swap_section_hdr(&sli->sli_sms_header);
873 909 if (sli->sli_data_order == SMS_DATA_ORDER)
874 910 return;
875 911 sli->sli_sms_header.sms_chksum += SMS_DATA_ORDER - sli->sli_data_order;
876 912 sli->sli_data_order = SMS_DATA_ORDER;
877 913 sli->sli_flags = BSWAP_32(sli->sli_flags);
878 914 sli->sli_lu_size = BSWAP_64(sli->sli_lu_size);
879 915 sli->sli_meta_fname_offset = BSWAP_64(sli->sli_meta_fname_offset);
880 916 sli->sli_data_fname_offset = BSWAP_64(sli->sli_data_fname_offset);
881 917 sli->sli_serial_offset = BSWAP_64(sli->sli_serial_offset);
882 918 sli->sli_alias_offset = BSWAP_64(sli->sli_alias_offset);
883 919 sli->sli_mgmt_url_offset = BSWAP_64(sli->sli_mgmt_url_offset);
884 920 }
885 921
886 922 sbd_status_t
887 923 sbd_load_section_hdr(sbd_lu_t *sl, sm_section_hdr_t *sms)
888 924 {
889 925 sm_section_hdr_t h;
890 926 uint64_t st;
891 927 sbd_status_t ret;
892 928
893 929 for (st = sl->sl_meta_offset + sizeof (sbd_meta_start_t);
894 930 st < sl->sl_meta_size_used; st += h.sms_size) {
895 931 if ((ret = sbd_read_meta(sl, st, sizeof (sm_section_hdr_t),
896 932 (uint8_t *)&h)) != SBD_SUCCESS) {
897 933 return (ret);
898 934 }
899 935 if (h.sms_data_order != SMS_DATA_ORDER) {
900 936 sbd_swap_section_hdr(&h);
901 937 }
902 938 if ((h.sms_data_order != SMS_DATA_ORDER) ||
903 939 (h.sms_offset != st) || (h.sms_size < sizeof (h)) ||
904 940 ((st + h.sms_size) > sl->sl_meta_size_used)) {
905 941 return (SBD_META_CORRUPTED);
906 942 }
907 943 if (h.sms_id == sms->sms_id) {
908 944 bcopy(&h, sms, sizeof (h));
909 945 return (SBD_SUCCESS);
910 946 }
911 947 }
912 948
913 949 return (SBD_NOT_FOUND);
914 950 }
915 951
916 952 sbd_status_t
917 953 sbd_load_meta_start(sbd_lu_t *sl)
918 954 {
919 955 sbd_meta_start_t *sm;
920 956 sbd_status_t ret;
921 957
922 958 /* Fake meta params initially */
923 959 sl->sl_total_meta_size = (uint64_t)-1;
924 960 sl->sl_meta_size_used = sl->sl_meta_offset + sizeof (sbd_meta_start_t);
925 961
926 962 sm = kmem_zalloc(sizeof (*sm), KM_SLEEP);
927 963 ret = sbd_read_meta(sl, sl->sl_meta_offset, sizeof (*sm),
928 964 (uint8_t *)sm);
929 965 if (ret != SBD_SUCCESS) {
930 966 goto load_meta_start_failed;
931 967 }
932 968
933 969 if (sm->sm_magic != SBD_MAGIC) {
934 970 sbd_swap_meta_start(sm);
935 971 }
936 972
937 973 if ((sm->sm_magic != SBD_MAGIC) || (sbd_calc_sum((uint8_t *)sm,
938 974 sizeof (*sm) - 1) != sm->sm_chksum)) {
939 975 ret = SBD_META_CORRUPTED;
940 976 goto load_meta_start_failed;
941 977 }
942 978
943 979 if (sm->sm_ver_major != SBD_VER_MAJOR) {
944 980 ret = SBD_NOT_SUPPORTED;
945 981 goto load_meta_start_failed;
946 982 }
947 983
948 984 sl->sl_total_meta_size = sm->sm_meta_size;
949 985 sl->sl_meta_size_used = sm->sm_meta_size_used;
950 986 ret = SBD_SUCCESS;
951 987
952 988 load_meta_start_failed:
953 989 kmem_free(sm, sizeof (*sm));
954 990 return (ret);
955 991 }
956 992
957 993 sbd_status_t
958 994 sbd_write_meta_start(sbd_lu_t *sl, uint64_t meta_size, uint64_t meta_size_used)
959 995 {
960 996 sbd_meta_start_t *sm;
961 997 sbd_status_t ret;
962 998
963 999 sm = (sbd_meta_start_t *)kmem_zalloc(sizeof (sbd_meta_start_t),
964 1000 KM_SLEEP);
965 1001
966 1002 sm->sm_magic = SBD_MAGIC;
967 1003 sm->sm_meta_size = meta_size;
968 1004 sm->sm_meta_size_used = meta_size_used;
969 1005 sm->sm_ver_major = SBD_VER_MAJOR;
970 1006 sm->sm_ver_minor = SBD_VER_MINOR;
971 1007 sm->sm_ver_subminor = SBD_VER_SUBMINOR;
972 1008 sm->sm_chksum = sbd_calc_sum((uint8_t *)sm, sizeof (*sm) - 1);
973 1009
974 1010 ret = sbd_write_meta(sl, sl->sl_meta_offset, sizeof (*sm),
975 1011 (uint8_t *)sm);
976 1012 kmem_free(sm, sizeof (*sm));
977 1013
978 1014 return (ret);
979 1015 }
980 1016
981 1017 sbd_status_t
982 1018 sbd_read_meta_section(sbd_lu_t *sl, sm_section_hdr_t **ppsms, uint16_t sms_id)
983 1019 {
984 1020 sbd_status_t ret;
985 1021 sm_section_hdr_t sms;
986 1022 int alloced = 0;
987 1023
988 1024 mutex_enter(&sl->sl_metadata_lock);
989 1025 if (((*ppsms) == NULL) || ((*ppsms)->sms_offset == 0)) {
990 1026 bzero(&sms, sizeof (sm_section_hdr_t));
991 1027 sms.sms_id = sms_id;
992 1028 if ((ret = sbd_load_section_hdr(sl, &sms)) != SBD_SUCCESS) {
993 1029 mutex_exit(&sl->sl_metadata_lock);
994 1030 return (ret);
995 1031 } else {
996 1032 if ((*ppsms) == NULL) {
997 1033 *ppsms = (sm_section_hdr_t *)kmem_zalloc(
998 1034 sms.sms_size, KM_SLEEP);
999 1035 alloced = 1;
1000 1036 }
1001 1037 bcopy(&sms, *ppsms, sizeof (sm_section_hdr_t));
1002 1038 }
1003 1039 }
1004 1040
1005 1041 ret = sbd_read_meta(sl, (*ppsms)->sms_offset, (*ppsms)->sms_size,
1006 1042 (uint8_t *)(*ppsms));
1007 1043 if (ret == SBD_SUCCESS) {
1008 1044 uint8_t s;
1009 1045 if ((*ppsms)->sms_data_order != SMS_DATA_ORDER)
1010 1046 sbd_swap_section_hdr(*ppsms);
1011 1047 if ((*ppsms)->sms_id != SMS_ID_UNUSED) {
1012 1048 s = sbd_calc_section_sum(*ppsms, (*ppsms)->sms_size);
1013 1049 if (s != (*ppsms)->sms_chksum)
1014 1050 ret = SBD_META_CORRUPTED;
1015 1051 }
1016 1052 }
1017 1053 mutex_exit(&sl->sl_metadata_lock);
1018 1054
1019 1055 if ((ret != SBD_SUCCESS) && alloced)
1020 1056 kmem_free(*ppsms, sms.sms_size);
1021 1057 return (ret);
1022 1058 }
1023 1059
1024 1060 sbd_status_t
1025 1061 sbd_load_section_hdr_unbuffered(sbd_lu_t *sl, sm_section_hdr_t *sms)
1026 1062 {
1027 1063 sbd_status_t ret;
1028 1064
1029 1065 /*
1030 1066 * Bypass buffering and re-read the meta data from permanent storage.
1031 1067 */
1032 1068 if (sl->sl_flags & SL_ZFS_META) {
1033 1069 if ((ret = sbd_open_zfs_meta(sl)) != SBD_SUCCESS) {
1034 1070 return (ret);
1035 1071 }
1036 1072 }
1037 1073 /* Re-get the meta sizes into sl */
1038 1074 if ((ret = sbd_load_meta_start(sl)) != SBD_SUCCESS) {
1039 1075 return (ret);
1040 1076 }
1041 1077 return (sbd_load_section_hdr(sl, sms));
1042 1078 }
1043 1079
1044 1080 sbd_status_t
1045 1081 sbd_write_meta_section(sbd_lu_t *sl, sm_section_hdr_t *sms)
1046 1082 {
1047 1083 sm_section_hdr_t t;
1048 1084 uint64_t off, s;
1049 1085 uint64_t unused_start;
1050 1086 sbd_status_t ret;
1051 1087 sbd_status_t write_meta_ret = SBD_SUCCESS;
1052 1088 uint8_t *cb;
1053 1089 int meta_size_changed = 0;
1054 1090 sm_section_hdr_t sms_before_unused = {0};
1055 1091
1056 1092 mutex_enter(&sl->sl_metadata_lock);
1057 1093 write_meta_section_again:
1058 1094 if (sms->sms_offset) {
1059 1095 /*
1060 1096 * If the section already exists and the size is the
1061 1097 * same as this new data then overwrite in place. If
1062 1098 * the sizes are different then mark the existing as
1063 1099 * unused and look for free space.
1064 1100 */
1065 1101 ret = sbd_read_meta(sl, sms->sms_offset, sizeof (t),
1066 1102 (uint8_t *)&t);
1067 1103 if (ret != SBD_SUCCESS) {
1068 1104 mutex_exit(&sl->sl_metadata_lock);
1069 1105 return (ret);
1070 1106 }
1071 1107 if (t.sms_data_order != SMS_DATA_ORDER) {
1072 1108 sbd_swap_section_hdr(&t);
1073 1109 }
1074 1110 if (t.sms_id != sms->sms_id) {
1075 1111 mutex_exit(&sl->sl_metadata_lock);
1076 1112 return (SBD_INVALID_ARG);
1077 1113 }
1078 1114 if (t.sms_size == sms->sms_size) {
1079 1115 ret = sbd_write_meta(sl, sms->sms_offset,
1080 1116 sms->sms_size, (uint8_t *)sms);
1081 1117 mutex_exit(&sl->sl_metadata_lock);
1082 1118 return (ret);
1083 1119 }
1084 1120 sms_before_unused = t;
1085 1121
1086 1122 t.sms_id = SMS_ID_UNUSED;
1087 1123 /*
1088 1124 * For unused sections we only use chksum of the header. for
1089 1125 * all other sections, the chksum is for the entire section.
1090 1126 */
1091 1127 t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t));
1092 1128 ret = sbd_write_meta(sl, t.sms_offset, sizeof (t),
1093 1129 (uint8_t *)&t);
1094 1130 if (ret != SBD_SUCCESS) {
1095 1131 mutex_exit(&sl->sl_metadata_lock);
1096 1132 return (ret);
1097 1133 }
1098 1134 sms->sms_offset = 0;
1099 1135 } else {
1100 1136 /* Section location is unknown, search for it. */
1101 1137 t.sms_id = sms->sms_id;
1102 1138 t.sms_data_order = SMS_DATA_ORDER;
1103 1139 ret = sbd_load_section_hdr(sl, &t);
1104 1140 if (ret == SBD_SUCCESS) {
1105 1141 sms->sms_offset = t.sms_offset;
1106 1142 sms->sms_chksum =
1107 1143 sbd_calc_section_sum(sms, sms->sms_size);
1108 1144 goto write_meta_section_again;
1109 1145 } else if (ret != SBD_NOT_FOUND) {
1110 1146 mutex_exit(&sl->sl_metadata_lock);
1111 1147 return (ret);
1112 1148 }
1113 1149 }
1114 1150
1115 1151 /*
1116 1152 * At this point we know that section does not already exist.
1117 1153 * Find space large enough to hold the section or grow meta if
1118 1154 * possible.
1119 1155 */
1120 1156 unused_start = 0;
1121 1157 s = 0; /* size of space found */
1122 1158
1123 1159 /*
1124 1160 * Search all sections for unused space of sufficient size.
1125 1161 * The first one found is taken. Contiguous unused sections
1126 1162 * will be combined.
1127 1163 */
1128 1164 for (off = sl->sl_meta_offset + sizeof (sbd_meta_start_t);
1129 1165 off < sl->sl_meta_size_used; off += t.sms_size) {
1130 1166 ret = sbd_read_meta(sl, off, sizeof (t), (uint8_t *)&t);
1131 1167 if (ret != SBD_SUCCESS) {
1132 1168 mutex_exit(&sl->sl_metadata_lock);
1133 1169 return (ret);
1134 1170 }
1135 1171 if (t.sms_data_order != SMS_DATA_ORDER)
1136 1172 sbd_swap_section_hdr(&t);
1137 1173 if (t.sms_size == 0) {
1138 1174 mutex_exit(&sl->sl_metadata_lock);
1139 1175 return (SBD_META_CORRUPTED);
1140 1176 }
1141 1177 if (t.sms_id == SMS_ID_UNUSED) {
1142 1178 if (unused_start == 0)
1143 1179 unused_start = off;
1144 1180 /*
1145 1181 * Calculate size of the unused space, break out
1146 1182 * if it satisfies the requirement.
1147 1183 */
1148 1184 s = t.sms_size - unused_start + off;
1149 1185 if ((s == sms->sms_size) || (s >= (sms->sms_size +
1150 1186 sizeof (t)))) {
1151 1187 break;
1152 1188 } else {
1153 1189 s = 0;
1154 1190 }
1155 1191 } else {
1156 1192 unused_start = 0;
1157 1193 }
1158 1194 }
1159 1195
1160 1196 off = (unused_start == 0) ? sl->sl_meta_size_used : unused_start;
1161 1197 /*
1162 1198 * If none found, how much room is at the end?
1163 1199 * See if the data can be expanded.
1164 1200 */
1165 1201 if (s == 0) {
1166 1202 s = sl->sl_total_meta_size - off;
1167 1203 if (s >= sms->sms_size || !(sl->sl_flags & SL_SHARED_META)) {
1168 1204 s = sms->sms_size;
1169 1205 meta_size_changed = 1;
1170 1206 } else {
1171 1207 s = 0;
1172 1208 }
1173 1209 }
1174 1210
1175 1211 if (s == 0) {
1176 1212 mutex_exit(&sl->sl_metadata_lock);
1177 1213 return (SBD_ALLOC_FAILURE);
1178 1214 }
1179 1215
1180 1216 sms->sms_offset = off;
1181 1217 sms->sms_chksum = sbd_calc_section_sum(sms, sms->sms_size);
1182 1218 /*
1183 1219 * Since we may have to write more than one section (current +
1184 1220 * any unused), use a combined buffer.
1185 1221 */
1186 1222 cb = kmem_zalloc(s, KM_SLEEP);
1187 1223 bcopy(sms, cb, sms->sms_size);
1188 1224 if (s > sms->sms_size) {
1189 1225 t.sms_offset = off + sms->sms_size;
1190 1226 t.sms_size = s - sms->sms_size;
1191 1227 t.sms_id = SMS_ID_UNUSED;
1192 1228 t.sms_data_order = SMS_DATA_ORDER;
1193 1229 t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t));
1194 1230 bcopy(&t, cb + sms->sms_size, sizeof (t));
1195 1231 }
1196 1232 /*
1197 1233 * Two write events & statuses take place. Failure writing the
1198 1234 * meta section takes precedence, can possibly be rolled back,
1199 1235 * & gets reported. Else return status from writing the meta start.
1200 1236 */
1201 1237 ret = SBD_SUCCESS; /* Set a default, it's not always loaded below. */
1202 1238 if (meta_size_changed) {
1203 1239 uint64_t old_meta_size;
1204 1240 uint64_t old_sz_used = sl->sl_meta_size_used; /* save a copy */
1205 1241 old_meta_size = sl->sl_total_meta_size; /* save a copy */
1206 1242
1207 1243 write_meta_ret = sbd_write_meta(sl, off, s, cb);
1208 1244 if (write_meta_ret == SBD_SUCCESS) {
1209 1245 sl->sl_meta_size_used = off + s;
1210 1246 if (sl->sl_total_meta_size < sl->sl_meta_size_used) {
1211 1247 uint64_t meta_align =
1212 1248 (((uint64_t)1) <<
1213 1249 sl->sl_meta_blocksize_shift) - 1;
1214 1250 sl->sl_total_meta_size =
1215 1251 (sl->sl_meta_size_used + meta_align) &
1216 1252 (~meta_align);
1217 1253 }
1218 1254 ret = sbd_write_meta_start(sl, sl->sl_total_meta_size,
1219 1255 sl->sl_meta_size_used);
1220 1256 if (ret != SBD_SUCCESS) {
1221 1257 sl->sl_meta_size_used = old_sz_used;
1222 1258 sl->sl_total_meta_size = old_meta_size;
1223 1259 }
1224 1260 } else {
1225 1261 sl->sl_meta_size_used = old_sz_used;
1226 1262 sl->sl_total_meta_size = old_meta_size;
1227 1263 }
1228 1264 } else {
1229 1265 write_meta_ret = sbd_write_meta(sl, off, s, cb);
1230 1266 }
1231 1267 if ((write_meta_ret != SBD_SUCCESS) &&
1232 1268 (sms_before_unused.sms_offset != 0)) {
1233 1269 sm_section_hdr_t new_sms;
1234 1270 sm_section_hdr_t *unused_sms;
1235 1271 /*
1236 1272 * On failure writing the meta section attempt to undo
1237 1273 * the change to unused.
1238 1274 * Re-read the meta data from permanent storage.
1239 1275 * The section id can't exist for undo to be possible.
1240 1276 * Read what should be the entire old section data and
1241 1277 * insure the old data's still present by validating
1242 1278 * against it's old checksum.
1243 1279 */
1244 1280 new_sms.sms_id = sms->sms_id;
1245 1281 new_sms.sms_data_order = SMS_DATA_ORDER;
1246 1282 if (sbd_load_section_hdr_unbuffered(sl, &new_sms) !=
1247 1283 SBD_NOT_FOUND) {
1248 1284 goto done;
1249 1285 }
1250 1286 unused_sms = kmem_zalloc(sms_before_unused.sms_size, KM_SLEEP);
1251 1287 if (sbd_read_meta(sl, sms_before_unused.sms_offset,
1252 1288 sms_before_unused.sms_size,
1253 1289 (uint8_t *)unused_sms) != SBD_SUCCESS) {
1254 1290 goto done;
1255 1291 }
1256 1292 if (unused_sms->sms_data_order != SMS_DATA_ORDER) {
1257 1293 sbd_swap_section_hdr(unused_sms);
1258 1294 }
1259 1295 if (unused_sms->sms_id != SMS_ID_UNUSED) {
1260 1296 goto done;
1261 1297 }
1262 1298 if (unused_sms->sms_offset != sms_before_unused.sms_offset) {
1263 1299 goto done;
1264 1300 }
1265 1301 if (unused_sms->sms_size != sms_before_unused.sms_size) {
1266 1302 goto done;
1267 1303 }
1268 1304 unused_sms->sms_id = sms_before_unused.sms_id;
1269 1305 if (sbd_calc_section_sum(unused_sms,
1270 1306 sizeof (sm_section_hdr_t)) !=
1271 1307 sbd_calc_section_sum(&sms_before_unused,
1272 1308 sizeof (sm_section_hdr_t))) {
1273 1309 goto done;
1274 1310 }
1275 1311 unused_sms->sms_chksum =
1276 1312 sbd_calc_section_sum(unused_sms, unused_sms->sms_size);
1277 1313 if (unused_sms->sms_chksum != sms_before_unused.sms_chksum) {
1278 1314 goto done;
1279 1315 }
1280 1316 (void) sbd_write_meta(sl, unused_sms->sms_offset,
1281 1317 sizeof (sm_section_hdr_t), (uint8_t *)unused_sms);
1282 1318 }
1283 1319 done:
1284 1320 mutex_exit(&sl->sl_metadata_lock);
1285 1321 kmem_free(cb, s);
1286 1322 if (write_meta_ret != SBD_SUCCESS) {
1287 1323 return (write_meta_ret);
1288 1324 }
1289 1325 return (ret);
1290 1326 }
1291 1327
1292 1328 sbd_status_t
1293 1329 sbd_write_lu_info(sbd_lu_t *sl)
1294 1330 {
1295 1331 sbd_lu_info_1_1_t *sli;
1296 1332 int s;
1297 1333 uint8_t *p;
1298 1334 char *zvol_name = NULL;
1299 1335 sbd_status_t ret;
1300 1336
1301 1337 mutex_enter(&sl->sl_lock);
1302 1338
1303 1339 s = sl->sl_serial_no_size;
1304 1340 if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) {
1305 1341 if (sl->sl_data_filename) {
1306 1342 s += strlen(sl->sl_data_filename) + 1;
1307 1343 }
1308 1344 }
1309 1345 if (sl->sl_flags & SL_ZFS_META) {
1310 1346 zvol_name = sbd_get_zvol_name(sl);
1311 1347 s += strlen(zvol_name) + 1;
1312 1348 }
1313 1349 if (sl->sl_alias) {
1314 1350 s += strlen(sl->sl_alias) + 1;
1315 1351 }
1316 1352 if (sl->sl_mgmt_url) {
1317 1353 s += strlen(sl->sl_mgmt_url) + 1;
1318 1354 }
1319 1355 sli = (sbd_lu_info_1_1_t *)kmem_zalloc(sizeof (*sli) + s, KM_SLEEP);
1320 1356 p = sli->sli_buf;
1321 1357 if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) {
1322 1358 sli->sli_flags |= SLI_SEPARATE_META;
1323 1359 (void) strcpy((char *)p, sl->sl_data_filename);
1324 1360 sli->sli_data_fname_offset =
1325 1361 (uintptr_t)p - (uintptr_t)sli->sli_buf;
1326 1362 sli->sli_flags |= SLI_DATA_FNAME_VALID;
1327 1363 p += strlen(sl->sl_data_filename) + 1;
1328 1364 }
1329 1365 if (sl->sl_flags & SL_ZFS_META) {
1330 1366 (void) strcpy((char *)p, zvol_name);
1331 1367 sli->sli_meta_fname_offset =
1332 1368 (uintptr_t)p - (uintptr_t)sli->sli_buf;
1333 1369 sli->sli_flags |= SLI_META_FNAME_VALID | SLI_ZFS_META;
1334 1370 p += strlen(zvol_name) + 1;
1335 1371 kmem_free(zvol_name, strlen(zvol_name) + 1);
1336 1372 zvol_name = NULL;
1337 1373 }
1338 1374 if (sl->sl_alias) {
1339 1375 (void) strcpy((char *)p, sl->sl_alias);
1340 1376 sli->sli_alias_offset =
1341 1377 (uintptr_t)p - (uintptr_t)sli->sli_buf;
1342 1378 sli->sli_flags |= SLI_ALIAS_VALID;
1343 1379 p += strlen(sl->sl_alias) + 1;
1344 1380 }
1345 1381 if (sl->sl_mgmt_url) {
1346 1382 (void) strcpy((char *)p, sl->sl_mgmt_url);
1347 1383 sli->sli_mgmt_url_offset =
1348 1384 (uintptr_t)p - (uintptr_t)sli->sli_buf;
1349 1385 sli->sli_flags |= SLI_MGMT_URL_VALID;
1350 1386 p += strlen(sl->sl_mgmt_url) + 1;
1351 1387 }
1352 1388 if (sl->sl_flags & SL_WRITE_PROTECTED) {
1353 1389 sli->sli_flags |= SLI_WRITE_PROTECTED;
1354 1390 }
1355 1391 if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) {
1356 1392 sli->sli_flags |= SLI_WRITEBACK_CACHE_DISABLE;
1357 1393 }
1358 1394 if (sl->sl_flags & SL_VID_VALID) {
1359 1395 bcopy(sl->sl_vendor_id, sli->sli_vid, 8);
1360 1396 sli->sli_flags |= SLI_VID_VALID;
1361 1397 }
1362 1398 if (sl->sl_flags & SL_PID_VALID) {
1363 1399 bcopy(sl->sl_product_id, sli->sli_pid, 16);
1364 1400 sli->sli_flags |= SLI_PID_VALID;
1365 1401 }
1366 1402 if (sl->sl_flags & SL_REV_VALID) {
1367 1403 bcopy(sl->sl_revision, sli->sli_rev, 4);
1368 1404 sli->sli_flags |= SLI_REV_VALID;
1369 1405 }
1370 1406 if (sl->sl_serial_no_size) {
1371 1407 bcopy(sl->sl_serial_no, p, sl->sl_serial_no_size);
1372 1408 sli->sli_serial_size = sl->sl_serial_no_size;
1373 1409 sli->sli_serial_offset =
1374 1410 (uintptr_t)p - (uintptr_t)sli->sli_buf;
1375 1411 sli->sli_flags |= SLI_SERIAL_VALID;
1376 1412 p += sli->sli_serial_size;
1377 1413 }
1378 1414 sli->sli_lu_size = sl->sl_lu_size;
1379 1415 sli->sli_data_blocksize_shift = sl->sl_data_blocksize_shift;
1380 1416 sli->sli_data_order = SMS_DATA_ORDER;
1381 1417 bcopy(sl->sl_device_id, sli->sli_device_id, 20);
1382 1418
1383 1419 sli->sli_sms_header.sms_size = sizeof (*sli) + s;
1384 1420 sli->sli_sms_header.sms_id = SMS_ID_LU_INFO_1_1;
1385 1421 sli->sli_sms_header.sms_data_order = SMS_DATA_ORDER;
1386 1422
1387 1423 mutex_exit(&sl->sl_lock);
1388 1424 ret = sbd_write_meta_section(sl, (sm_section_hdr_t *)sli);
|
↓ open down ↓ |
1057 lines elided |
↑ open up ↑ |
1389 1425 kmem_free(sli, sizeof (*sli) + s);
1390 1426 return (ret);
1391 1427 }
1392 1428
1393 1429 /*
1394 1430 * Will scribble SL_UNMAP_ENABLED into sl_flags if we succeed.
1395 1431 */
1396 1432 static void
1397 1433 do_unmap_setup(sbd_lu_t *sl)
1398 1434 {
1399 - ASSERT((sl->sl_flags & SL_UNMAP_ENABLED) == 0);
1435 + if (sbd_unmap_enable == 0) {
1436 + sl->sl_flags &= ~(SL_UNMAP_ENABLED);
1437 + return;
1438 + }
1400 1439
1401 1440 if ((sl->sl_flags & SL_ZFS_META) == 0)
1402 1441 return; /* No UNMAP for you. */
1403 1442
1404 1443 sl->sl_flags |= SL_UNMAP_ENABLED;
1405 1444 }
1406 1445
1407 1446 int
1408 1447 sbd_populate_and_register_lu(sbd_lu_t *sl, uint32_t *err_ret)
1409 1448 {
1410 1449 stmf_lu_t *lu = sl->sl_lu;
1411 1450 stmf_status_t ret;
1412 1451
1413 1452 do_unmap_setup(sl);
1414 1453
1415 1454 lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id;
1416 1455 if (sl->sl_alias) {
1417 1456 lu->lu_alias = sl->sl_alias;
1418 1457 } else {
1419 1458 lu->lu_alias = sl->sl_name;
1420 1459 }
1421 1460 if (sl->sl_access_state == SBD_LU_STANDBY) {
1422 1461 /* call set access state */
1423 1462 ret = stmf_set_lu_access(lu, STMF_LU_STANDBY);
1424 1463 if (ret != STMF_SUCCESS) {
1425 1464 *err_ret = SBD_RET_ACCESS_STATE_FAILED;
1426 1465 return (EIO);
1427 1466 }
1428 1467 }
1429 1468 /* set proxy_reg_cb_arg to meta filename */
1430 1469 if (sl->sl_meta_filename) {
1431 1470 lu->lu_proxy_reg_arg = sl->sl_meta_filename;
1432 1471 lu->lu_proxy_reg_arg_len = strlen(sl->sl_meta_filename) + 1;
1433 1472 } else {
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
1434 1473 lu->lu_proxy_reg_arg = sl->sl_data_filename;
1435 1474 lu->lu_proxy_reg_arg_len = strlen(sl->sl_data_filename) + 1;
1436 1475 }
1437 1476 lu->lu_lp = sbd_lp;
1438 1477 lu->lu_task_alloc = sbd_task_alloc;
1439 1478 lu->lu_new_task = sbd_new_task;
1440 1479 lu->lu_dbuf_xfer_done = sbd_dbuf_xfer_done;
1441 1480 lu->lu_send_status_done = sbd_send_status_done;
1442 1481 lu->lu_task_free = sbd_task_free;
1443 1482 lu->lu_abort = sbd_abort;
1483 + lu->lu_task_poll = sbd_task_poll;
1444 1484 lu->lu_dbuf_free = sbd_dbuf_free;
1445 1485 lu->lu_ctl = sbd_ctl;
1486 + lu->lu_task_done = sbd_ats_remove_by_task;
1446 1487 lu->lu_info = sbd_info;
1447 1488 sl->sl_state = STMF_STATE_OFFLINE;
1448 1489
1449 1490 if ((ret = stmf_register_lu(lu)) != STMF_SUCCESS) {
1450 1491 stmf_trace(0, "Failed to register with framework, ret=%llx",
1451 1492 ret);
1452 1493 if (ret == STMF_ALREADY) {
1453 1494 *err_ret = SBD_RET_GUID_ALREADY_REGISTERED;
1454 1495 }
1455 1496 return (EIO);
1456 1497 }
1457 1498
1499 + /*
1500 + * setup the ATS (compare and write) lists to handle multiple
1501 + * ATS commands simultaneously
1502 + */
1503 + list_create(&sl->sl_ats_io_list, sizeof (ats_state_t),
1504 + offsetof(ats_state_t, as_next));
1458 1505 *err_ret = 0;
1459 1506 return (0);
1460 1507 }
1461 1508
1462 1509 int
1463 1510 sbd_open_data_file(sbd_lu_t *sl, uint32_t *err_ret, int lu_size_valid,
1464 1511 int vp_valid, int keep_open)
1465 1512 {
1466 1513 int ret;
1467 1514 int flag;
1468 1515 ulong_t nbits;
1469 1516 uint64_t supported_size;
1470 1517 vattr_t vattr;
1471 1518 enum vtype vt;
1472 1519 struct dk_cinfo dki;
1473 1520 int unused;
1474 1521
1475 1522 mutex_enter(&sl->sl_lock);
1476 1523 if (vp_valid) {
1477 1524 goto odf_over_open;
1478 1525 }
1479 1526 if (sl->sl_data_filename[0] != '/') {
1480 1527 *err_ret = SBD_RET_DATA_PATH_NOT_ABSOLUTE;
1481 1528 mutex_exit(&sl->sl_lock);
1482 1529 return (EINVAL);
1483 1530 }
1484 1531 if ((ret = lookupname(sl->sl_data_filename, UIO_SYSSPACE, FOLLOW,
1485 1532 NULLVPP, &sl->sl_data_vp)) != 0) {
1486 1533 *err_ret = SBD_RET_DATA_FILE_LOOKUP_FAILED;
1487 1534 mutex_exit(&sl->sl_lock);
1488 1535 return (ret);
1489 1536 }
1490 1537 sl->sl_data_vtype = vt = sl->sl_data_vp->v_type;
1491 1538 VN_RELE(sl->sl_data_vp);
1492 1539 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) {
1493 1540 *err_ret = SBD_RET_WRONG_DATA_FILE_TYPE;
1494 1541 mutex_exit(&sl->sl_lock);
1495 1542 return (EINVAL);
1496 1543 }
1497 1544 if (sl->sl_flags & SL_WRITE_PROTECTED) {
1498 1545 flag = FREAD | FOFFMAX;
1499 1546 } else {
1500 1547 flag = FREAD | FWRITE | FOFFMAX | FEXCL;
1501 1548 }
1502 1549 if ((ret = vn_open(sl->sl_data_filename, UIO_SYSSPACE, flag, 0,
1503 1550 &sl->sl_data_vp, 0, 0)) != 0) {
1504 1551 *err_ret = SBD_RET_DATA_FILE_OPEN_FAILED;
1505 1552 mutex_exit(&sl->sl_lock);
1506 1553 return (ret);
1507 1554 }
1508 1555 odf_over_open:
1509 1556 vattr.va_mask = AT_SIZE;
1510 1557 if ((ret = VOP_GETATTR(sl->sl_data_vp, &vattr, 0, CRED(), NULL)) != 0) {
1511 1558 *err_ret = SBD_RET_DATA_FILE_GETATTR_FAILED;
1512 1559 goto odf_close_data_and_exit;
1513 1560 }
1514 1561 if ((vt != VREG) && (vattr.va_size == 0)) {
1515 1562 /*
1516 1563 * Its a zero byte block or char device. This cannot be
1517 1564 * a raw disk.
1518 1565 */
1519 1566 *err_ret = SBD_RET_WRONG_DATA_FILE_TYPE;
1520 1567 ret = EINVAL;
1521 1568 goto odf_close_data_and_exit;
1522 1569 }
1523 1570 /* sl_data_readable size includes any metadata. */
1524 1571 sl->sl_data_readable_size = vattr.va_size;
1525 1572
1526 1573 if (VOP_PATHCONF(sl->sl_data_vp, _PC_FILESIZEBITS, &nbits,
1527 1574 CRED(), NULL) != 0) {
1528 1575 nbits = 0;
1529 1576 }
1530 1577 /* nbits cannot be greater than 64 */
1531 1578 sl->sl_data_fs_nbits = (uint8_t)nbits;
1532 1579 if (lu_size_valid) {
1533 1580 sl->sl_total_data_size = sl->sl_lu_size;
1534 1581 if (sl->sl_flags & SL_SHARED_META) {
1535 1582 sl->sl_total_data_size += SHARED_META_DATA_SIZE;
1536 1583 }
1537 1584 if ((nbits > 0) && (nbits < 64)) {
1538 1585 /*
1539 1586 * The expression below is correct only if nbits is
1540 1587 * positive and less than 64.
1541 1588 */
1542 1589 supported_size = (((uint64_t)1) << nbits) - 1;
1543 1590 if (sl->sl_total_data_size > supported_size) {
1544 1591 *err_ret = SBD_RET_SIZE_NOT_SUPPORTED_BY_FS;
1545 1592 ret = EINVAL;
1546 1593 goto odf_close_data_and_exit;
1547 1594 }
1548 1595 }
1549 1596 } else {
1550 1597 sl->sl_total_data_size = vattr.va_size;
1551 1598 if (sl->sl_flags & SL_SHARED_META) {
1552 1599 if (vattr.va_size > SHARED_META_DATA_SIZE) {
1553 1600 sl->sl_lu_size = vattr.va_size -
|
↓ open down ↓ |
86 lines elided |
↑ open up ↑ |
1554 1601 SHARED_META_DATA_SIZE;
1555 1602 } else {
1556 1603 *err_ret = SBD_RET_FILE_SIZE_ERROR;
1557 1604 ret = EINVAL;
1558 1605 goto odf_close_data_and_exit;
1559 1606 }
1560 1607 } else {
1561 1608 sl->sl_lu_size = vattr.va_size;
1562 1609 }
1563 1610 }
1611 +
1564 1612 if (sl->sl_lu_size < SBD_MIN_LU_SIZE) {
1565 1613 *err_ret = SBD_RET_FILE_SIZE_ERROR;
1566 1614 ret = EINVAL;
1567 1615 goto odf_close_data_and_exit;
1568 1616 }
1569 1617 if (sl->sl_lu_size &
1570 1618 ((((uint64_t)1) << sl->sl_data_blocksize_shift) - 1)) {
1571 1619 *err_ret = SBD_RET_FILE_ALIGN_ERROR;
1572 1620 ret = EINVAL;
1573 1621 goto odf_close_data_and_exit;
1574 1622 }
1575 1623 /*
1576 1624 * Get the minor device for direct zvol access
1577 1625 */
1578 1626 if (sl->sl_flags & SL_ZFS_META) {
1579 1627 if ((ret = VOP_IOCTL(sl->sl_data_vp, DKIOCINFO, (intptr_t)&dki,
1580 1628 FKIOCTL, kcred, &unused, NULL)) != 0) {
1581 1629 cmn_err(CE_WARN, "ioctl(DKIOCINFO) failed %d", ret);
1582 1630 /* zvol reserves 0, so this would fail later */
1583 1631 sl->sl_zvol_minor = 0;
1584 1632 } else {
1585 1633 sl->sl_zvol_minor = dki.dki_unit;
1586 1634 if (sbd_zvol_get_volume_params(sl) == 0)
1587 1635 sl->sl_flags |= SL_CALL_ZVOL;
1588 1636 }
1589 1637 }
1590 1638 sl->sl_flags |= SL_MEDIA_LOADED;
1591 1639 mutex_exit(&sl->sl_lock);
1592 1640 return (0);
1593 1641
1594 1642 odf_close_data_and_exit:
1595 1643 if (!keep_open) {
1596 1644 (void) VOP_CLOSE(sl->sl_data_vp, flag, 1, 0, CRED(), NULL);
1597 1645 VN_RELE(sl->sl_data_vp);
1598 1646 }
1599 1647 mutex_exit(&sl->sl_lock);
1600 1648 return (ret);
1601 1649 }
1602 1650
1603 1651 void
1604 1652 sbd_close_lu(sbd_lu_t *sl)
1605 1653 {
1606 1654 int flag;
1607 1655
1608 1656 if (((sl->sl_flags & SL_SHARED_META) == 0) &&
1609 1657 (sl->sl_flags & SL_META_OPENED)) {
1610 1658 if (sl->sl_flags & SL_ZFS_META) {
1611 1659 rw_destroy(&sl->sl_zfs_meta_lock);
1612 1660 if (sl->sl_zfs_meta) {
1613 1661 kmem_free(sl->sl_zfs_meta, ZAP_MAXVALUELEN / 2);
1614 1662 sl->sl_zfs_meta = NULL;
1615 1663 }
1616 1664 } else {
1617 1665 flag = FREAD | FWRITE | FOFFMAX | FEXCL;
1618 1666 (void) VOP_CLOSE(sl->sl_meta_vp, flag, 1, 0,
1619 1667 CRED(), NULL);
1620 1668 VN_RELE(sl->sl_meta_vp);
1621 1669 }
1622 1670 sl->sl_flags &= ~SL_META_OPENED;
1623 1671 }
1624 1672 if (sl->sl_flags & SL_MEDIA_LOADED) {
1625 1673 if (sl->sl_flags & SL_WRITE_PROTECTED) {
1626 1674 flag = FREAD | FOFFMAX;
1627 1675 } else {
1628 1676 flag = FREAD | FWRITE | FOFFMAX | FEXCL;
1629 1677 }
1630 1678 (void) VOP_CLOSE(sl->sl_data_vp, flag, 1, 0, CRED(), NULL);
1631 1679 VN_RELE(sl->sl_data_vp);
1632 1680 sl->sl_flags &= ~SL_MEDIA_LOADED;
1633 1681 if (sl->sl_flags & SL_SHARED_META) {
1634 1682 sl->sl_flags &= ~SL_META_OPENED;
1635 1683 }
1636 1684 }
1637 1685 }
1638 1686
1639 1687 int
1640 1688 sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret)
1641 1689 {
1642 1690 sbd_lu_t *sl;
1643 1691 sbd_status_t sret;
1644 1692 stmf_status_t stret;
1645 1693 uint8_t old_access_state;
1646 1694
1647 1695 sret = sbd_find_and_lock_lu(stlu->stlu_guid, NULL,
1648 1696 SL_OP_MODIFY_LU, &sl);
1649 1697 if (sret != SBD_SUCCESS) {
1650 1698 if (sret == SBD_BUSY) {
1651 1699 *err_ret = SBD_RET_LU_BUSY;
1652 1700 return (EBUSY);
1653 1701 } else if (sret == SBD_NOT_FOUND) {
1654 1702 *err_ret = SBD_RET_NOT_FOUND;
1655 1703 return (ENOENT);
1656 1704 }
1657 1705 *err_ret = SBD_RET_ACCESS_STATE_FAILED;
1658 1706 return (EIO);
1659 1707 }
1660 1708
1661 1709 old_access_state = sl->sl_access_state;
1662 1710 sl->sl_access_state = SBD_LU_TRANSITION_TO_STANDBY;
1663 1711 stret = stmf_set_lu_access((stmf_lu_t *)sl->sl_lu, STMF_LU_STANDBY);
1664 1712 if (stret != STMF_SUCCESS) {
1665 1713 sl->sl_trans_op = SL_OP_NONE;
1666 1714 *err_ret = SBD_RET_ACCESS_STATE_FAILED;
1667 1715 sl->sl_access_state = old_access_state;
1668 1716 return (EIO);
1669 1717 }
1670 1718
1671 1719 /*
1672 1720 * acquire the writer lock here to ensure we're not pulling
1673 1721 * the rug from the vn_rdwr to the backing store
1674 1722 */
1675 1723 rw_enter(&sl->sl_access_state_lock, RW_WRITER);
1676 1724 sbd_close_lu(sl);
1677 1725 rw_exit(&sl->sl_access_state_lock);
1678 1726
1679 1727 sl->sl_trans_op = SL_OP_NONE;
1680 1728 return (0);
1681 1729 }
1682 1730
1683 1731 int
1684 1732 sbd_close_delete_lu(sbd_lu_t *sl, int ret)
1685 1733 {
1686 1734
1687 1735 /*
1688 1736 * acquire the writer lock here to ensure we're not pulling
1689 1737 * the rug from the vn_rdwr to the backing store
1690 1738 */
1691 1739 rw_enter(&sl->sl_access_state_lock, RW_WRITER);
1692 1740 sbd_close_lu(sl);
1693 1741 rw_exit(&sl->sl_access_state_lock);
1694 1742
1695 1743 if (sl->sl_flags & SL_LINKED)
1696 1744 sbd_unlink_lu(sl);
1697 1745 mutex_destroy(&sl->sl_metadata_lock);
1698 1746 mutex_destroy(&sl->sl_lock);
1699 1747 rw_destroy(&sl->sl_pgr->pgr_lock);
1700 1748 rw_destroy(&sl->sl_access_state_lock);
1701 1749 if (sl->sl_serial_no_alloc_size) {
1702 1750 kmem_free(sl->sl_serial_no, sl->sl_serial_no_alloc_size);
1703 1751 }
1704 1752 if (sl->sl_data_fname_alloc_size) {
1705 1753 kmem_free(sl->sl_data_filename, sl->sl_data_fname_alloc_size);
1706 1754 }
1707 1755 if (sl->sl_alias_alloc_size) {
1708 1756 kmem_free(sl->sl_alias, sl->sl_alias_alloc_size);
1709 1757 }
1710 1758 if (sl->sl_mgmt_url_alloc_size) {
1711 1759 kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size);
1712 1760 }
1713 1761 stmf_free(sl->sl_lu);
1714 1762 return (ret);
1715 1763 }
1716 1764
1717 1765 int
1718 1766 sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
1719 1767 uint32_t *err_ret)
1720 1768 {
1721 1769 char *namebuf;
1722 1770 sbd_lu_t *sl;
1723 1771 stmf_lu_t *lu;
1724 1772 char *p;
1725 1773 int sz;
1726 1774 int alloc_sz;
1727 1775 int ret = EIO;
1728 1776 int flag;
1729 1777 int wcd = 0;
1730 1778 uint32_t hid = 0;
1731 1779 enum vtype vt;
1732 1780
1733 1781 sz = struct_sz - sizeof (sbd_create_and_reg_lu_t) + 8 + 1;
1734 1782
1735 1783 *err_ret = 0;
1736 1784
1737 1785 /* Lets validate various offsets */
1738 1786 if (((slu->slu_meta_fname_valid) &&
1739 1787 (slu->slu_meta_fname_off >= sz)) ||
1740 1788 (slu->slu_data_fname_off >= sz) ||
1741 1789 ((slu->slu_alias_valid) &&
1742 1790 (slu->slu_alias_off >= sz)) ||
1743 1791 ((slu->slu_mgmt_url_valid) &&
1744 1792 (slu->slu_mgmt_url_off >= sz)) ||
1745 1793 ((slu->slu_serial_valid) &&
1746 1794 ((slu->slu_serial_off + slu->slu_serial_size) >= sz))) {
1747 1795 return (EINVAL);
1748 1796 }
1749 1797
1750 1798 namebuf = kmem_zalloc(sz, KM_SLEEP);
1751 1799 bcopy(slu->slu_buf, namebuf, sz - 1);
1752 1800 namebuf[sz - 1] = 0;
1753 1801
1754 1802 alloc_sz = sizeof (sbd_lu_t) + sizeof (sbd_pgr_t);
1755 1803 if (slu->slu_meta_fname_valid) {
1756 1804 alloc_sz += strlen(namebuf + slu->slu_meta_fname_off) + 1;
1757 1805 }
1758 1806 alloc_sz += strlen(namebuf + slu->slu_data_fname_off) + 1;
1759 1807 if (slu->slu_alias_valid) {
1760 1808 alloc_sz += strlen(namebuf + slu->slu_alias_off) + 1;
1761 1809 }
1762 1810 if (slu->slu_mgmt_url_valid) {
1763 1811 alloc_sz += strlen(namebuf + slu->slu_mgmt_url_off) + 1;
1764 1812 }
1765 1813 if (slu->slu_serial_valid) {
1766 1814 alloc_sz += slu->slu_serial_size;
1767 1815 }
1768 1816
1769 1817 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, alloc_sz, 0);
1770 1818 if (lu == NULL) {
1771 1819 kmem_free(namebuf, sz);
1772 1820 return (ENOMEM);
1773 1821 }
1774 1822 sl = (sbd_lu_t *)lu->lu_provider_private;
1775 1823 bzero(sl, alloc_sz);
1776 1824 sl->sl_lu = lu;
1777 1825 sl->sl_alloc_size = alloc_sz;
1778 1826 sl->sl_pgr = (sbd_pgr_t *)(sl + 1);
1779 1827 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL);
1780 1828 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL);
1781 1829 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL);
1782 1830 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL);
1783 1831 p = ((char *)sl) + sizeof (sbd_lu_t) + sizeof (sbd_pgr_t);
1784 1832 sl->sl_data_filename = p;
1785 1833 (void) strcpy(sl->sl_data_filename, namebuf + slu->slu_data_fname_off);
1786 1834 p += strlen(sl->sl_data_filename) + 1;
1787 1835 sl->sl_meta_offset = SBD_META_OFFSET;
1788 1836 sl->sl_access_state = SBD_LU_ACTIVE;
1789 1837 if (slu->slu_meta_fname_valid) {
1790 1838 sl->sl_alias = sl->sl_name = sl->sl_meta_filename = p;
1791 1839 (void) strcpy(sl->sl_meta_filename, namebuf +
1792 1840 slu->slu_meta_fname_off);
1793 1841 p += strlen(sl->sl_meta_filename) + 1;
1794 1842 } else {
1795 1843 sl->sl_alias = sl->sl_name = sl->sl_data_filename;
1796 1844 if (sbd_is_zvol(sl->sl_data_filename)) {
1797 1845 sl->sl_flags |= SL_ZFS_META;
1798 1846 sl->sl_meta_offset = 0;
1799 1847 } else {
1800 1848 sl->sl_flags |= SL_SHARED_META;
1801 1849 sl->sl_data_offset = SHARED_META_DATA_SIZE;
1802 1850 sl->sl_total_meta_size = SHARED_META_DATA_SIZE;
1803 1851 sl->sl_meta_size_used = 0;
1804 1852 }
1805 1853 }
1806 1854 if (slu->slu_alias_valid) {
1807 1855 sl->sl_alias = p;
1808 1856 (void) strcpy(p, namebuf + slu->slu_alias_off);
1809 1857 p += strlen(sl->sl_alias) + 1;
1810 1858 }
1811 1859 if (slu->slu_mgmt_url_valid) {
1812 1860 sl->sl_mgmt_url = p;
1813 1861 (void) strcpy(p, namebuf + slu->slu_mgmt_url_off);
1814 1862 p += strlen(sl->sl_mgmt_url) + 1;
1815 1863 }
1816 1864 if (slu->slu_serial_valid) {
1817 1865 sl->sl_serial_no = (uint8_t *)p;
1818 1866 bcopy(namebuf + slu->slu_serial_off, sl->sl_serial_no,
1819 1867 slu->slu_serial_size);
1820 1868 sl->sl_serial_no_size = slu->slu_serial_size;
1821 1869 p += slu->slu_serial_size;
1822 1870 }
1823 1871 kmem_free(namebuf, sz);
1824 1872 if (slu->slu_vid_valid) {
1825 1873 bcopy(slu->slu_vid, sl->sl_vendor_id, 8);
1826 1874 sl->sl_flags |= SL_VID_VALID;
1827 1875 }
1828 1876 if (slu->slu_pid_valid) {
1829 1877 bcopy(slu->slu_pid, sl->sl_product_id, 16);
|
↓ open down ↓ |
256 lines elided |
↑ open up ↑ |
1830 1878 sl->sl_flags |= SL_PID_VALID;
1831 1879 }
1832 1880 if (slu->slu_rev_valid) {
1833 1881 bcopy(slu->slu_rev, sl->sl_revision, 4);
1834 1882 sl->sl_flags |= SL_REV_VALID;
1835 1883 }
1836 1884 if (slu->slu_write_protected) {
1837 1885 sl->sl_flags |= SL_WRITE_PROTECTED;
1838 1886 }
1839 1887 if (slu->slu_blksize_valid) {
1840 - if (!ISP2(slu->slu_blksize) ||
1888 + if ((slu->slu_blksize & (slu->slu_blksize - 1)) ||
1841 1889 (slu->slu_blksize > (32 * 1024)) ||
1842 1890 (slu->slu_blksize == 0)) {
1843 1891 *err_ret = SBD_RET_INVALID_BLKSIZE;
1844 1892 ret = EINVAL;
1845 1893 goto scm_err_out;
1846 1894 }
1847 1895 while ((1 << sl->sl_data_blocksize_shift) != slu->slu_blksize) {
1848 1896 sl->sl_data_blocksize_shift++;
1849 1897 }
1850 1898 } else {
1851 1899 sl->sl_data_blocksize_shift = 9; /* 512 by default */
1852 1900 slu->slu_blksize = 512;
1853 1901 }
1854 1902
1855 1903 /* Now lets start creating meta */
1856 1904 sl->sl_trans_op = SL_OP_CREATE_REGISTER_LU;
1857 1905 if (sbd_link_lu(sl) != SBD_SUCCESS) {
1858 1906 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED;
1859 1907 ret = EALREADY;
1860 1908 goto scm_err_out;
1861 1909 }
1862 1910
1863 1911 /* 1st focus on the data store */
1864 1912 if (slu->slu_lu_size_valid) {
1865 1913 sl->sl_lu_size = slu->slu_lu_size;
1866 1914 }
1867 1915 ret = sbd_open_data_file(sl, err_ret, slu->slu_lu_size_valid, 0, 0);
1868 1916 slu->slu_ret_filesize_nbits = sl->sl_data_fs_nbits;
1869 1917 slu->slu_lu_size = sl->sl_lu_size;
1870 1918 if (ret) {
1871 1919 goto scm_err_out;
1872 1920 }
1873 1921
1874 1922 /*
1875 1923 * Check if we were explicitly asked to disable/enable write
1876 1924 * cache on the device, otherwise get current device setting.
1877 1925 */
1878 1926 if (slu->slu_writeback_cache_disable_valid) {
1879 1927 if (slu->slu_writeback_cache_disable) {
1880 1928 /*
1881 1929 * Set write cache disable on the device. If it fails,
1882 1930 * we'll support it using sync/flush.
1883 1931 */
1884 1932 (void) sbd_wcd_set(1, sl);
1885 1933 wcd = 1;
1886 1934 } else {
1887 1935 /*
1888 1936 * Set write cache enable on the device. If it fails,
1889 1937 * return an error.
1890 1938 */
1891 1939 if (sbd_wcd_set(0, sl) != SBD_SUCCESS) {
1892 1940 *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED;
1893 1941 ret = EFAULT;
1894 1942 goto scm_err_out;
1895 1943 }
1896 1944 }
1897 1945 } else {
1898 1946 sbd_wcd_get(&wcd, sl);
1899 1947 }
1900 1948
1901 1949 if (wcd) {
1902 1950 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE |
1903 1951 SL_SAVED_WRITE_CACHE_DISABLE;
1904 1952 }
1905 1953
1906 1954 if (sl->sl_flags & SL_SHARED_META) {
1907 1955 goto over_meta_open;
1908 1956 }
1909 1957 if (sl->sl_flags & SL_ZFS_META) {
1910 1958 if (sbd_create_zfs_meta_object(sl) != SBD_SUCCESS) {
1911 1959 *err_ret = SBD_RET_ZFS_META_CREATE_FAILED;
1912 1960 ret = ENOMEM;
1913 1961 goto scm_err_out;
1914 1962 }
1915 1963 sl->sl_meta_blocksize_shift = 0;
1916 1964 goto over_meta_create;
1917 1965 }
1918 1966 if ((ret = lookupname(sl->sl_meta_filename, UIO_SYSSPACE, FOLLOW,
1919 1967 NULLVPP, &sl->sl_meta_vp)) != 0) {
1920 1968 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED;
1921 1969 goto scm_err_out;
1922 1970 }
1923 1971 sl->sl_meta_vtype = vt = sl->sl_meta_vp->v_type;
1924 1972 VN_RELE(sl->sl_meta_vp);
1925 1973 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) {
1926 1974 *err_ret = SBD_RET_WRONG_META_FILE_TYPE;
1927 1975 ret = EINVAL;
1928 1976 goto scm_err_out;
1929 1977 }
1930 1978 if (vt == VREG) {
1931 1979 sl->sl_meta_blocksize_shift = 0;
1932 1980 } else {
1933 1981 sl->sl_meta_blocksize_shift = 9;
1934 1982 }
1935 1983 flag = FREAD | FWRITE | FOFFMAX | FEXCL;
1936 1984 if ((ret = vn_open(sl->sl_meta_filename, UIO_SYSSPACE, flag, 0,
1937 1985 &sl->sl_meta_vp, 0, 0)) != 0) {
1938 1986 *err_ret = SBD_RET_META_FILE_OPEN_FAILED;
1939 1987 goto scm_err_out;
1940 1988 }
1941 1989 over_meta_create:
1942 1990 sl->sl_total_meta_size = sl->sl_meta_offset + sizeof (sbd_meta_start_t);
1943 1991 sl->sl_total_meta_size +=
1944 1992 (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1;
1945 1993 sl->sl_total_meta_size &=
1946 1994 ~((((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1);
1947 1995 sl->sl_meta_size_used = 0;
1948 1996 over_meta_open:
1949 1997 sl->sl_flags |= SL_META_OPENED;
1950 1998
1951 1999 sl->sl_device_id[3] = 16;
1952 2000 if (slu->slu_guid_valid) {
1953 2001 sl->sl_device_id[0] = 0xf1;
1954 2002 sl->sl_device_id[1] = 3;
1955 2003 sl->sl_device_id[2] = 0;
1956 2004 bcopy(slu->slu_guid, sl->sl_device_id + 4, 16);
1957 2005 } else {
1958 2006 if (slu->slu_host_id_valid)
1959 2007 hid = slu->slu_host_id;
1960 2008 if (!slu->slu_company_id_valid)
1961 2009 slu->slu_company_id = COMPANY_ID_SUN;
1962 2010 if (stmf_scsilib_uniq_lu_id2(slu->slu_company_id, hid,
1963 2011 (scsi_devid_desc_t *)&sl->sl_device_id[0]) !=
1964 2012 STMF_SUCCESS) {
1965 2013 *err_ret = SBD_RET_META_CREATION_FAILED;
1966 2014 ret = EIO;
1967 2015 goto scm_err_out;
1968 2016 }
1969 2017 bcopy(sl->sl_device_id + 4, slu->slu_guid, 16);
1970 2018 }
1971 2019
1972 2020 /* Lets create the meta now */
1973 2021 mutex_enter(&sl->sl_metadata_lock);
1974 2022 if (sbd_write_meta_start(sl, sl->sl_total_meta_size,
1975 2023 sizeof (sbd_meta_start_t)) != SBD_SUCCESS) {
1976 2024 mutex_exit(&sl->sl_metadata_lock);
1977 2025 *err_ret = SBD_RET_META_CREATION_FAILED;
1978 2026 ret = EIO;
1979 2027 goto scm_err_out;
1980 2028 }
1981 2029 mutex_exit(&sl->sl_metadata_lock);
1982 2030 sl->sl_meta_size_used = sl->sl_meta_offset + sizeof (sbd_meta_start_t);
1983 2031
1984 2032 if (sbd_write_lu_info(sl) != SBD_SUCCESS) {
1985 2033 *err_ret = SBD_RET_META_CREATION_FAILED;
1986 2034 ret = EIO;
1987 2035 goto scm_err_out;
1988 2036 }
1989 2037
1990 2038 if (sbd_pgr_meta_init(sl) != SBD_SUCCESS) {
1991 2039 *err_ret = SBD_RET_META_CREATION_FAILED;
1992 2040 ret = EIO;
1993 2041 goto scm_err_out;
1994 2042 }
1995 2043
1996 2044 /*
1997 2045 * Update the zvol separately as this need only be called upon
1998 2046 * completion of the metadata initialization.
1999 2047 */
2000 2048 if (sl->sl_flags & SL_ZFS_META) {
2001 2049 if (sbd_update_zfs_prop(sl) != SBD_SUCCESS) {
2002 2050 *err_ret = SBD_RET_META_CREATION_FAILED;
2003 2051 ret = EIO;
2004 2052 goto scm_err_out;
2005 2053 }
2006 2054 }
2007 2055
2008 2056 ret = sbd_populate_and_register_lu(sl, err_ret);
2009 2057 if (ret) {
2010 2058 goto scm_err_out;
2011 2059 }
2012 2060
2013 2061 sl->sl_trans_op = SL_OP_NONE;
2014 2062 atomic_inc_32(&sbd_lu_count);
2015 2063 return (0);
2016 2064
2017 2065 scm_err_out:
2018 2066 return (sbd_close_delete_lu(sl, ret));
2019 2067 }
2020 2068
2021 2069 stmf_status_t
2022 2070 sbd_proxy_msg(uint8_t *luid, void *proxy_arg, uint32_t proxy_arg_len,
2023 2071 uint32_t type)
2024 2072 {
2025 2073 switch (type) {
2026 2074 case STMF_MSG_LU_ACTIVE:
2027 2075 return (sbd_proxy_reg_lu(luid, proxy_arg,
2028 2076 proxy_arg_len));
2029 2077 case STMF_MSG_LU_REGISTER:
2030 2078 return (sbd_proxy_reg_lu(luid, proxy_arg,
2031 2079 proxy_arg_len));
2032 2080 case STMF_MSG_LU_DEREGISTER:
2033 2081 return (sbd_proxy_dereg_lu(luid, proxy_arg,
2034 2082 proxy_arg_len));
2035 2083 default:
2036 2084 return (STMF_INVALID_ARG);
2037 2085 }
2038 2086 }
2039 2087
2040 2088
2041 2089 /*
2042 2090 * register a standby logical unit
2043 2091 * proxy_reg_arg contains the meta filename
2044 2092 */
2045 2093 stmf_status_t
2046 2094 sbd_proxy_reg_lu(uint8_t *luid, void *proxy_reg_arg, uint32_t proxy_reg_arg_len)
2047 2095 {
2048 2096 sbd_lu_t *sl;
2049 2097 sbd_status_t sret;
2050 2098 sbd_create_standby_lu_t *stlu;
2051 2099 int alloc_sz;
2052 2100 uint32_t err_ret = 0;
2053 2101 stmf_status_t stret = STMF_SUCCESS;
2054 2102
2055 2103 if (luid == NULL) {
2056 2104 return (STMF_INVALID_ARG);
2057 2105 }
2058 2106
2059 2107 do {
2060 2108 sret = sbd_find_and_lock_lu(luid, NULL, SL_OP_MODIFY_LU, &sl);
2061 2109 } while (sret == SBD_BUSY);
2062 2110
2063 2111 if (sret == SBD_NOT_FOUND) {
2064 2112 alloc_sz = sizeof (*stlu) + proxy_reg_arg_len - 8;
2065 2113 stlu = (sbd_create_standby_lu_t *)kmem_zalloc(alloc_sz,
2066 2114 KM_SLEEP);
2067 2115 bcopy(luid, stlu->stlu_guid, 16);
2068 2116 if (proxy_reg_arg_len) {
2069 2117 bcopy(proxy_reg_arg, stlu->stlu_meta_fname,
2070 2118 proxy_reg_arg_len);
2071 2119 stlu->stlu_meta_fname_size = proxy_reg_arg_len;
2072 2120 }
2073 2121 if (sbd_create_standby_lu(stlu, &err_ret) != 0) {
2074 2122 cmn_err(CE_WARN,
2075 2123 "Unable to create standby logical unit for %s",
2076 2124 stlu->stlu_meta_fname);
2077 2125 stret = STMF_FAILURE;
2078 2126 }
2079 2127 kmem_free(stlu, alloc_sz);
2080 2128 return (stret);
2081 2129 } else if (sret == SBD_SUCCESS) {
2082 2130 /*
2083 2131 * if the lu is already registered, then the lu should now
2084 2132 * be in standby mode
2085 2133 */
2086 2134 sbd_it_data_t *it;
2087 2135 if (sl->sl_access_state != SBD_LU_STANDBY) {
2088 2136 mutex_enter(&sl->sl_lock);
2089 2137 sl->sl_access_state = SBD_LU_STANDBY;
2090 2138 for (it = sl->sl_it_list; it != NULL;
2091 2139 it = it->sbd_it_next) {
2092 2140 it->sbd_it_ua_conditions |=
2093 2141 SBD_UA_ASYMMETRIC_ACCESS_CHANGED;
2094 2142 it->sbd_it_flags &=
2095 2143 ~SBD_IT_HAS_SCSI2_RESERVATION;
2096 2144 sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION;
2097 2145 }
2098 2146 mutex_exit(&sl->sl_lock);
2099 2147 sbd_pgr_reset(sl);
2100 2148 }
2101 2149 sl->sl_trans_op = SL_OP_NONE;
2102 2150 } else {
2103 2151 cmn_err(CE_WARN, "could not find and lock logical unit");
2104 2152 stret = STMF_FAILURE;
2105 2153 }
2106 2154 out:
2107 2155 return (stret);
2108 2156 }
2109 2157
2110 2158 /* ARGSUSED */
2111 2159 stmf_status_t
2112 2160 sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg,
2113 2161 uint32_t proxy_reg_arg_len)
2114 2162 {
2115 2163 sbd_delete_lu_t dlu = {0};
2116 2164 uint32_t err_ret;
2117 2165
2118 2166 if (luid == NULL) {
2119 2167 cmn_err(CE_WARN, "de-register lu request had null luid");
2120 2168 return (STMF_INVALID_ARG);
2121 2169 }
2122 2170
2123 2171 bcopy(luid, &dlu.dlu_guid, 16);
2124 2172
2125 2173 if (sbd_delete_lu(&dlu, (int)sizeof (dlu), &err_ret) != 0) {
2126 2174 cmn_err(CE_WARN, "failed to delete de-register lu request");
2127 2175 return (STMF_FAILURE);
2128 2176 }
2129 2177
2130 2178 return (STMF_SUCCESS);
2131 2179 }
2132 2180
2133 2181 int
2134 2182 sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret)
2135 2183 {
2136 2184 sbd_lu_t *sl;
2137 2185 stmf_lu_t *lu;
2138 2186 int ret = EIO;
2139 2187 int alloc_sz;
2140 2188
2141 2189 alloc_sz = sizeof (sbd_lu_t) + sizeof (sbd_pgr_t) +
2142 2190 slu->stlu_meta_fname_size;
2143 2191 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, alloc_sz, 0);
2144 2192 if (lu == NULL) {
2145 2193 return (ENOMEM);
2146 2194 }
2147 2195 sl = (sbd_lu_t *)lu->lu_provider_private;
2148 2196 bzero(sl, alloc_sz);
2149 2197 sl->sl_lu = lu;
2150 2198 sl->sl_alloc_size = alloc_sz;
2151 2199
2152 2200 sl->sl_pgr = (sbd_pgr_t *)(sl + 1);
2153 2201 sl->sl_meta_filename = ((char *)sl) + sizeof (sbd_lu_t) +
2154 2202 sizeof (sbd_pgr_t);
2155 2203
2156 2204 if (slu->stlu_meta_fname_size > 0) {
2157 2205 (void) strcpy(sl->sl_meta_filename, slu->stlu_meta_fname);
2158 2206 }
2159 2207 sl->sl_name = sl->sl_meta_filename;
2160 2208
2161 2209 sl->sl_device_id[3] = 16;
2162 2210 sl->sl_device_id[0] = 0xf1;
2163 2211 sl->sl_device_id[1] = 3;
2164 2212 sl->sl_device_id[2] = 0;
2165 2213 bcopy(slu->stlu_guid, sl->sl_device_id + 4, 16);
2166 2214 lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id;
2167 2215 sl->sl_access_state = SBD_LU_STANDBY;
2168 2216
2169 2217 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL);
2170 2218 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL);
2171 2219 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL);
2172 2220 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL);
2173 2221
2174 2222 sl->sl_trans_op = SL_OP_CREATE_REGISTER_LU;
2175 2223
2176 2224 if (sbd_link_lu(sl) != SBD_SUCCESS) {
2177 2225 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED;
2178 2226 ret = EALREADY;
2179 2227 goto scs_err_out;
2180 2228 }
2181 2229
2182 2230 ret = sbd_populate_and_register_lu(sl, err_ret);
2183 2231 if (ret) {
2184 2232 goto scs_err_out;
2185 2233 }
2186 2234
2187 2235 sl->sl_trans_op = SL_OP_NONE;
2188 2236 atomic_inc_32(&sbd_lu_count);
2189 2237 return (0);
2190 2238
2191 2239 scs_err_out:
2192 2240 return (sbd_close_delete_lu(sl, ret));
2193 2241 }
2194 2242
2195 2243 int
2196 2244 sbd_load_sli_1_0(sbd_lu_t *sl, uint32_t *err_ret)
2197 2245 {
2198 2246 sbd_lu_info_1_0_t *sli = NULL;
2199 2247 sbd_status_t sret;
2200 2248
2201 2249 sret = sbd_read_meta_section(sl, (sm_section_hdr_t **)&sli,
2202 2250 SMS_ID_LU_INFO_1_0);
2203 2251
2204 2252 if (sret != SBD_SUCCESS) {
2205 2253 *err_ret = SBD_RET_NO_META;
2206 2254 return (EIO);
2207 2255 }
2208 2256 if (sli->sli_data_order != SMS_DATA_ORDER) {
2209 2257 sbd_swap_lu_info_1_0(sli);
2210 2258 if (sli->sli_data_order != SMS_DATA_ORDER) {
2211 2259 kmem_free(sli, sli->sli_sms_header.sms_size);
2212 2260 *err_ret = SBD_RET_NO_META;
2213 2261 return (EIO);
2214 2262 }
2215 2263 }
2216 2264
2217 2265 sl->sl_flags |= SL_SHARED_META;
2218 2266 sl->sl_data_blocksize_shift = 9;
2219 2267 sl->sl_data_offset = SHARED_META_DATA_SIZE;
2220 2268 sl->sl_lu_size = sli->sli_total_store_size - SHARED_META_DATA_SIZE;
2221 2269 sl->sl_total_data_size = SHARED_META_DATA_SIZE + sl->sl_lu_size;
2222 2270 bcopy(sli->sli_lu_devid, sl->sl_device_id, 20);
2223 2271
2224 2272 kmem_free(sli, sli->sli_sms_header.sms_size);
2225 2273 return (0);
2226 2274 }
2227 2275
2228 2276 int
2229 2277 sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret,
2230 2278 int no_register, sbd_lu_t **slr)
2231 2279 {
2232 2280 stmf_lu_t *lu;
2233 2281 sbd_lu_t *sl;
2234 2282 sbd_lu_info_1_1_t *sli = NULL;
2235 2283 int asz;
2236 2284 int ret = 0;
2237 2285 stmf_status_t stret;
2238 2286 int flag;
2239 2287 int wcd = 0;
2240 2288 int data_opened;
2241 2289 uint16_t sli_buf_sz;
2242 2290 uint8_t *sli_buf_copy = NULL;
2243 2291 enum vtype vt;
2244 2292 int standby = 0;
2245 2293 sbd_status_t sret;
2246 2294
2247 2295 if (no_register && slr == NULL) {
2248 2296 return (EINVAL);
2249 2297 }
2250 2298 ilu->ilu_meta_fname[struct_sz - sizeof (*ilu) + 8 - 1] = 0;
2251 2299 /*
2252 2300 * check whether logical unit is already registered ALUA
2253 2301 * For a standby logical unit, the meta filename is set. Use
2254 2302 * that to search for an existing logical unit.
2255 2303 */
2256 2304 sret = sbd_find_and_lock_lu(NULL, (uint8_t *)&(ilu->ilu_meta_fname),
2257 2305 SL_OP_IMPORT_LU, &sl);
2258 2306
2259 2307 if (sret == SBD_SUCCESS) {
2260 2308 if (sl->sl_access_state != SBD_LU_ACTIVE) {
2261 2309 no_register = 1;
2262 2310 standby = 1;
2263 2311 lu = sl->sl_lu;
2264 2312 if (sl->sl_alias_alloc_size) {
2265 2313 kmem_free(sl->sl_alias,
2266 2314 sl->sl_alias_alloc_size);
2267 2315 sl->sl_alias_alloc_size = 0;
2268 2316 sl->sl_alias = NULL;
2269 2317 lu->lu_alias = NULL;
2270 2318 }
2271 2319 if (sl->sl_meta_filename == NULL) {
2272 2320 sl->sl_meta_filename = sl->sl_data_filename;
2273 2321 } else if (sl->sl_data_fname_alloc_size) {
2274 2322 kmem_free(sl->sl_data_filename,
2275 2323 sl->sl_data_fname_alloc_size);
2276 2324 sl->sl_data_fname_alloc_size = 0;
2277 2325 }
2278 2326 if (sl->sl_serial_no_alloc_size) {
2279 2327 kmem_free(sl->sl_serial_no,
2280 2328 sl->sl_serial_no_alloc_size);
2281 2329 sl->sl_serial_no_alloc_size = 0;
2282 2330 }
2283 2331 if (sl->sl_mgmt_url_alloc_size) {
2284 2332 kmem_free(sl->sl_mgmt_url,
2285 2333 sl->sl_mgmt_url_alloc_size);
2286 2334 sl->sl_mgmt_url_alloc_size = 0;
2287 2335 }
2288 2336 } else {
2289 2337 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED;
2290 2338 bcopy(sl->sl_device_id + 4, ilu->ilu_ret_guid, 16);
2291 2339 sl->sl_trans_op = SL_OP_NONE;
2292 2340 return (EALREADY);
2293 2341 }
2294 2342 } else if (sret == SBD_NOT_FOUND) {
2295 2343 asz = strlen(ilu->ilu_meta_fname) + 1;
2296 2344
2297 2345 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU,
2298 2346 sizeof (sbd_lu_t) + sizeof (sbd_pgr_t) + asz, 0);
2299 2347 if (lu == NULL) {
2300 2348 return (ENOMEM);
2301 2349 }
2302 2350 sl = (sbd_lu_t *)lu->lu_provider_private;
2303 2351 bzero(sl, sizeof (*sl));
2304 2352 sl->sl_lu = lu;
2305 2353 sl->sl_pgr = (sbd_pgr_t *)(sl + 1);
2306 2354 sl->sl_meta_filename = ((char *)sl) + sizeof (*sl) +
2307 2355 sizeof (sbd_pgr_t);
2308 2356 (void) strcpy(sl->sl_meta_filename, ilu->ilu_meta_fname);
2309 2357 sl->sl_name = sl->sl_meta_filename;
2310 2358 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL);
2311 2359 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL);
2312 2360 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL);
2313 2361 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL);
2314 2362 sl->sl_trans_op = SL_OP_IMPORT_LU;
2315 2363 } else {
2316 2364 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED;
2317 2365 return (EIO);
2318 2366 }
2319 2367
2320 2368 /* we're only loading the metadata */
2321 2369 if (!no_register) {
2322 2370 if (sbd_link_lu(sl) != SBD_SUCCESS) {
2323 2371 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED;
2324 2372 bcopy(sl->sl_device_id + 4, ilu->ilu_ret_guid, 16);
2325 2373 ret = EALREADY;
2326 2374 goto sim_err_out;
2327 2375 }
2328 2376 }
2329 2377 if ((ret = lookupname(sl->sl_meta_filename, UIO_SYSSPACE, FOLLOW,
2330 2378 NULLVPP, &sl->sl_meta_vp)) != 0) {
2331 2379 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED;
2332 2380 goto sim_err_out;
2333 2381 }
2334 2382 if (sbd_is_zvol(sl->sl_meta_filename)) {
2335 2383 sl->sl_flags |= SL_ZFS_META;
2336 2384 sl->sl_data_filename = sl->sl_meta_filename;
2337 2385 }
2338 2386 sl->sl_meta_vtype = vt = sl->sl_meta_vp->v_type;
2339 2387 VN_RELE(sl->sl_meta_vp);
2340 2388 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) {
2341 2389 *err_ret = SBD_RET_WRONG_META_FILE_TYPE;
2342 2390 ret = EINVAL;
2343 2391 goto sim_err_out;
2344 2392 }
2345 2393 if (sl->sl_flags & SL_ZFS_META) {
2346 2394 if (sbd_open_zfs_meta(sl) != SBD_SUCCESS) {
2347 2395 /* let see if metadata is in the 64k block */
2348 2396 sl->sl_flags &= ~SL_ZFS_META;
2349 2397 }
2350 2398 }
2351 2399 if (!(sl->sl_flags & SL_ZFS_META)) {
2352 2400 /* metadata is always writable */
2353 2401 flag = FREAD | FWRITE | FOFFMAX | FEXCL;
2354 2402 if ((ret = vn_open(sl->sl_meta_filename, UIO_SYSSPACE, flag, 0,
2355 2403 &sl->sl_meta_vp, 0, 0)) != 0) {
2356 2404 *err_ret = SBD_RET_META_FILE_OPEN_FAILED;
2357 2405 goto sim_err_out;
2358 2406 }
2359 2407 }
2360 2408 if ((sl->sl_flags & SL_ZFS_META) || (vt == VREG)) {
2361 2409 sl->sl_meta_blocksize_shift = 0;
2362 2410 } else {
2363 2411 sl->sl_meta_blocksize_shift = 9;
2364 2412 }
2365 2413 sl->sl_meta_offset = (sl->sl_flags & SL_ZFS_META) ? 0 : SBD_META_OFFSET;
2366 2414 sl->sl_flags |= SL_META_OPENED;
2367 2415
2368 2416 mutex_enter(&sl->sl_metadata_lock);
2369 2417 sret = sbd_load_meta_start(sl);
2370 2418 mutex_exit(&sl->sl_metadata_lock);
2371 2419 if (sret != SBD_SUCCESS) {
2372 2420 if (sret == SBD_META_CORRUPTED) {
2373 2421 *err_ret = SBD_RET_NO_META;
2374 2422 } else if (sret == SBD_NOT_SUPPORTED) {
2375 2423 *err_ret = SBD_RET_VERSION_NOT_SUPPORTED;
2376 2424 } else {
2377 2425 *err_ret = SBD_RET_NO_META;
2378 2426 }
2379 2427 ret = EINVAL;
2380 2428 goto sim_err_out;
2381 2429 }
2382 2430
2383 2431 /* Now lets see if we can read the most recent LU info */
2384 2432 sret = sbd_read_meta_section(sl, (sm_section_hdr_t **)&sli,
2385 2433 SMS_ID_LU_INFO_1_1);
2386 2434 if ((sret == SBD_NOT_FOUND) && ((sl->sl_flags & SL_ZFS_META) == 0)) {
2387 2435 ret = sbd_load_sli_1_0(sl, err_ret);
2388 2436 if (ret) {
2389 2437 goto sim_err_out;
2390 2438 }
2391 2439 goto sim_sli_loaded;
2392 2440 }
2393 2441 if (sret != SBD_SUCCESS) {
2394 2442 *err_ret = SBD_RET_NO_META;
2395 2443 ret = EIO;
2396 2444 goto sim_err_out;
2397 2445 }
2398 2446 /* load sli 1.1 */
2399 2447 if (sli->sli_data_order != SMS_DATA_ORDER) {
2400 2448 sbd_swap_lu_info_1_1(sli);
2401 2449 if (sli->sli_data_order != SMS_DATA_ORDER) {
2402 2450 *err_ret = SBD_RET_NO_META;
2403 2451 ret = EIO;
2404 2452 goto sim_err_out;
2405 2453 }
2406 2454 }
2407 2455
2408 2456 sli_buf_sz = sli->sli_sms_header.sms_size -
2409 2457 sizeof (sbd_lu_info_1_1_t) + 8;
2410 2458 sli_buf_copy = kmem_alloc(sli_buf_sz + 1, KM_SLEEP);
2411 2459 bcopy(sli->sli_buf, sli_buf_copy, sli_buf_sz);
2412 2460 sli_buf_copy[sli_buf_sz] = 0;
2413 2461
2414 2462 /* Make sure all the offsets are within limits */
2415 2463 if (((sli->sli_flags & SLI_META_FNAME_VALID) &&
2416 2464 (sli->sli_meta_fname_offset > sli_buf_sz)) ||
2417 2465 ((sli->sli_flags & SLI_DATA_FNAME_VALID) &&
2418 2466 (sli->sli_data_fname_offset > sli_buf_sz)) ||
2419 2467 ((sli->sli_flags & SLI_MGMT_URL_VALID) &&
2420 2468 (sli->sli_mgmt_url_offset > sli_buf_sz)) ||
2421 2469 ((sli->sli_flags & SLI_SERIAL_VALID) &&
2422 2470 ((sli->sli_serial_offset + sli->sli_serial_size) > sli_buf_sz)) ||
2423 2471 ((sli->sli_flags & SLI_ALIAS_VALID) &&
2424 2472 (sli->sli_alias_offset > sli_buf_sz))) {
2425 2473 *err_ret = SBD_RET_NO_META;
2426 2474 ret = EIO;
2427 2475 goto sim_err_out;
2428 2476 }
2429 2477
2430 2478 sl->sl_lu_size = sli->sli_lu_size;
2431 2479 sl->sl_data_blocksize_shift = sli->sli_data_blocksize_shift;
2432 2480 bcopy(sli->sli_device_id, sl->sl_device_id, 20);
2433 2481 if (sli->sli_flags & SLI_SERIAL_VALID) {
2434 2482 sl->sl_serial_no_size = sl->sl_serial_no_alloc_size =
2435 2483 sli->sli_serial_size;
2436 2484 sl->sl_serial_no = kmem_zalloc(sli->sli_serial_size, KM_SLEEP);
2437 2485 bcopy(sli_buf_copy + sli->sli_serial_offset, sl->sl_serial_no,
2438 2486 sl->sl_serial_no_size);
2439 2487 }
2440 2488 if (sli->sli_flags & SLI_SEPARATE_META) {
2441 2489 sl->sl_total_data_size = sl->sl_lu_size;
2442 2490 if (sli->sli_flags & SLI_DATA_FNAME_VALID) {
2443 2491 sl->sl_data_fname_alloc_size = strlen((char *)
2444 2492 sli_buf_copy + sli->sli_data_fname_offset) + 1;
2445 2493 sl->sl_data_filename = kmem_zalloc(
2446 2494 sl->sl_data_fname_alloc_size, KM_SLEEP);
2447 2495 (void) strcpy(sl->sl_data_filename,
2448 2496 (char *)sli_buf_copy + sli->sli_data_fname_offset);
2449 2497 }
2450 2498 } else {
2451 2499 if (sl->sl_flags & SL_ZFS_META) {
2452 2500 sl->sl_total_data_size = sl->sl_lu_size;
2453 2501 sl->sl_data_offset = 0;
2454 2502 } else {
2455 2503 sl->sl_total_data_size =
2456 2504 sl->sl_lu_size + SHARED_META_DATA_SIZE;
2457 2505 sl->sl_data_offset = SHARED_META_DATA_SIZE;
2458 2506 sl->sl_flags |= SL_SHARED_META;
2459 2507 }
2460 2508 }
2461 2509 if (sli->sli_flags & SLI_ALIAS_VALID) {
2462 2510 sl->sl_alias_alloc_size = strlen((char *)sli_buf_copy +
2463 2511 sli->sli_alias_offset) + 1;
2464 2512 sl->sl_alias = kmem_alloc(sl->sl_alias_alloc_size, KM_SLEEP);
2465 2513 (void) strcpy(sl->sl_alias, (char *)sli_buf_copy +
2466 2514 sli->sli_alias_offset);
2467 2515 }
2468 2516 if (sli->sli_flags & SLI_MGMT_URL_VALID) {
2469 2517 sl->sl_mgmt_url_alloc_size = strlen((char *)sli_buf_copy +
2470 2518 sli->sli_mgmt_url_offset) + 1;
2471 2519 sl->sl_mgmt_url = kmem_alloc(sl->sl_mgmt_url_alloc_size,
2472 2520 KM_SLEEP);
2473 2521 (void) strcpy(sl->sl_mgmt_url, (char *)sli_buf_copy +
2474 2522 sli->sli_mgmt_url_offset);
2475 2523 }
2476 2524 if (sli->sli_flags & SLI_WRITE_PROTECTED) {
2477 2525 sl->sl_flags |= SL_WRITE_PROTECTED;
2478 2526 }
2479 2527 if (sli->sli_flags & SLI_VID_VALID) {
2480 2528 sl->sl_flags |= SL_VID_VALID;
2481 2529 bcopy(sli->sli_vid, sl->sl_vendor_id, 8);
2482 2530 }
2483 2531 if (sli->sli_flags & SLI_PID_VALID) {
2484 2532 sl->sl_flags |= SL_PID_VALID;
2485 2533 bcopy(sli->sli_pid, sl->sl_product_id, 16);
2486 2534 }
2487 2535 if (sli->sli_flags & SLI_REV_VALID) {
2488 2536 sl->sl_flags |= SL_REV_VALID;
2489 2537 bcopy(sli->sli_rev, sl->sl_revision, 4);
2490 2538 }
2491 2539 if (sli->sli_flags & SLI_WRITEBACK_CACHE_DISABLE) {
2492 2540 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE;
2493 2541 }
2494 2542 sim_sli_loaded:
2495 2543 if ((sl->sl_flags & SL_SHARED_META) == 0) {
2496 2544 data_opened = 0;
2497 2545 } else {
2498 2546 data_opened = 1;
2499 2547 sl->sl_data_filename = sl->sl_meta_filename;
2500 2548 sl->sl_data_vp = sl->sl_meta_vp;
2501 2549 sl->sl_data_vtype = sl->sl_meta_vtype;
2502 2550 }
2503 2551
2504 2552 sret = sbd_pgr_meta_load(sl);
2505 2553 if (sret != SBD_SUCCESS) {
2506 2554 *err_ret = SBD_RET_NO_META;
2507 2555 ret = EIO;
2508 2556 goto sim_err_out;
2509 2557 }
2510 2558
2511 2559 ret = sbd_open_data_file(sl, err_ret, 1, data_opened, 0);
2512 2560 if (ret) {
2513 2561 goto sim_err_out;
2514 2562 }
2515 2563
2516 2564 /*
2517 2565 * set write cache disable on the device
2518 2566 * Note: this shouldn't fail on import unless the cache capabilities
2519 2567 * of the device changed. If that happened, modify will need to
2520 2568 * be used to set the cache flag appropriately after import is done.
2521 2569 */
2522 2570 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) {
2523 2571 (void) sbd_wcd_set(1, sl);
2524 2572 wcd = 1;
2525 2573 /*
2526 2574 * if not explicitly set, attempt to set it to enable, if that fails
2527 2575 * get the current setting and use that
2528 2576 */
2529 2577 } else {
2530 2578 sret = sbd_wcd_set(0, sl);
2531 2579 if (sret != SBD_SUCCESS) {
2532 2580 sbd_wcd_get(&wcd, sl);
2533 2581 }
2534 2582 }
2535 2583
2536 2584 if (wcd) {
2537 2585 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE |
2538 2586 SL_SAVED_WRITE_CACHE_DISABLE;
2539 2587 }
2540 2588
2541 2589 /* we're only loading the metadata */
2542 2590 if (!no_register) {
2543 2591 ret = sbd_populate_and_register_lu(sl, err_ret);
2544 2592 if (ret) {
2545 2593 goto sim_err_out;
2546 2594 }
2547 2595 atomic_inc_32(&sbd_lu_count);
2548 2596 }
2549 2597
2550 2598 bcopy(sl->sl_device_id + 4, ilu->ilu_ret_guid, 16);
2551 2599 sl->sl_trans_op = SL_OP_NONE;
2552 2600
2553 2601 if (sli) {
2554 2602 kmem_free(sli, sli->sli_sms_header.sms_size);
2555 2603 sli = NULL;
2556 2604 }
2557 2605 if (sli_buf_copy) {
2558 2606 kmem_free(sli_buf_copy, sli_buf_sz + 1);
2559 2607 sli_buf_copy = NULL;
2560 2608 }
2561 2609 if (no_register && !standby) {
2562 2610 *slr = sl;
2563 2611 }
2564 2612
2565 2613 /*
2566 2614 * if this was imported from standby, set the access state
2567 2615 * to active.
2568 2616 */
2569 2617 if (standby) {
2570 2618 sbd_it_data_t *it;
2571 2619 mutex_enter(&sl->sl_lock);
2572 2620 sl->sl_access_state = SBD_LU_ACTIVE;
2573 2621 for (it = sl->sl_it_list; it != NULL;
2574 2622 it = it->sbd_it_next) {
2575 2623 it->sbd_it_ua_conditions |=
2576 2624 SBD_UA_ASYMMETRIC_ACCESS_CHANGED;
2577 2625 it->sbd_it_ua_conditions |= SBD_UA_POR;
2578 2626 it->sbd_it_flags |= SBD_IT_PGR_CHECK_FLAG;
2579 2627 }
2580 2628 mutex_exit(&sl->sl_lock);
2581 2629 /* call set access state */
2582 2630 stret = stmf_set_lu_access(lu, STMF_LU_ACTIVE);
2583 2631 if (stret != STMF_SUCCESS) {
2584 2632 *err_ret = SBD_RET_ACCESS_STATE_FAILED;
2585 2633 sl->sl_access_state = SBD_LU_STANDBY;
2586 2634 goto sim_err_out;
2587 2635 }
2588 2636 if (sl->sl_alias) {
2589 2637 lu->lu_alias = sl->sl_alias;
2590 2638 } else {
2591 2639 lu->lu_alias = sl->sl_name;
2592 2640 }
2593 2641 }
2594 2642 sl->sl_access_state = SBD_LU_ACTIVE;
2595 2643 return (0);
2596 2644
2597 2645 sim_err_out:
2598 2646 if (sli) {
2599 2647 kmem_free(sli, sli->sli_sms_header.sms_size);
2600 2648 sli = NULL;
2601 2649 }
2602 2650 if (sli_buf_copy) {
2603 2651 kmem_free(sli_buf_copy, sli_buf_sz + 1);
2604 2652 sli_buf_copy = NULL;
2605 2653 }
2606 2654
2607 2655 if (standby) {
2608 2656 *err_ret = SBD_RET_ACCESS_STATE_FAILED;
2609 2657 sl->sl_trans_op = SL_OP_NONE;
2610 2658 return (EIO);
2611 2659 } else {
2612 2660 return (sbd_close_delete_lu(sl, ret));
2613 2661 }
2614 2662 }
2615 2663
2616 2664 int
2617 2665 sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret)
2618 2666 {
2619 2667 sbd_lu_t *sl = NULL;
2620 2668 uint16_t alias_sz;
2621 2669 int ret = 0;
2622 2670 sbd_it_data_t *it;
2623 2671 sbd_status_t sret;
2624 2672 uint64_t old_size;
2625 2673 int modify_unregistered = 0;
2626 2674 int ua = 0;
2627 2675 sbd_import_lu_t *ilu;
2628 2676 stmf_lu_t *lu;
2629 2677 uint32_t ilu_sz;
2630 2678 uint32_t sz;
2631 2679
2632 2680 sz = struct_sz - sizeof (*mlu) + 8 + 1;
2633 2681
2634 2682 /* if there is data in the buf, null terminate it */
2635 2683 if (struct_sz > sizeof (*mlu)) {
2636 2684 mlu->mlu_buf[struct_sz - sizeof (*mlu) + 8 - 1] = 0;
2637 2685 }
2638 2686
2639 2687 *err_ret = 0;
2640 2688
2641 2689 /* Lets validate offsets */
2642 2690 if (((mlu->mlu_alias_valid) &&
2643 2691 (mlu->mlu_alias_off >= sz)) ||
2644 2692 ((mlu->mlu_mgmt_url_valid) &&
2645 2693 (mlu->mlu_mgmt_url_off >= sz)) ||
2646 2694 (mlu->mlu_by_fname) &&
2647 2695 (mlu->mlu_fname_off >= sz)) {
2648 2696 return (EINVAL);
2649 2697 }
2650 2698
2651 2699 /*
2652 2700 * We'll look for the device but if we don't find it registered,
2653 2701 * we'll still try to modify the unregistered device.
2654 2702 */
2655 2703 if (mlu->mlu_by_guid) {
2656 2704 sret = sbd_find_and_lock_lu(mlu->mlu_input_guid, NULL,
2657 2705 SL_OP_MODIFY_LU, &sl);
2658 2706 } else if (mlu->mlu_by_fname) {
2659 2707 sret = sbd_find_and_lock_lu(NULL,
2660 2708 (uint8_t *)&(mlu->mlu_buf[mlu->mlu_fname_off]),
2661 2709 SL_OP_MODIFY_LU, &sl);
2662 2710 } else {
2663 2711 return (EINVAL);
2664 2712 }
2665 2713
2666 2714
2667 2715 if (sret != SBD_SUCCESS) {
2668 2716 if (sret == SBD_BUSY) {
2669 2717 *err_ret = SBD_RET_LU_BUSY;
2670 2718 return (EBUSY);
2671 2719 } else if (sret != SBD_NOT_FOUND) {
2672 2720 return (EIO);
2673 2721 } else if (!mlu->mlu_by_fname) {
2674 2722 return (EINVAL);
2675 2723 }
2676 2724 /* Okay, try to import the device */
2677 2725 struct_sz = max(8, strlen(&(mlu->mlu_buf[mlu->mlu_fname_off]))
2678 2726 + 1);
2679 2727 struct_sz += sizeof (sbd_import_lu_t) - 8;
2680 2728 ilu_sz = struct_sz;
2681 2729 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP);
2682 2730 ilu->ilu_struct_size = struct_sz;
2683 2731 (void) strcpy(ilu->ilu_meta_fname,
2684 2732 &(mlu->mlu_buf[mlu->mlu_fname_off]));
2685 2733 ret = sbd_import_lu(ilu, struct_sz, err_ret, 1, &sl);
2686 2734 kmem_free(ilu, ilu_sz);
2687 2735 if (ret != SBD_SUCCESS) {
2688 2736 return (ENOENT);
2689 2737 }
2690 2738 modify_unregistered = 1;
2691 2739 }
2692 2740
2693 2741 if (sl->sl_access_state != SBD_LU_ACTIVE) {
2694 2742 *err_ret = SBD_RET_ACCESS_STATE_FAILED;
2695 2743 ret = EINVAL;
2696 2744 goto smm_err_out;
2697 2745 }
2698 2746
2699 2747 /* check for write cache change */
2700 2748 if (mlu->mlu_writeback_cache_disable_valid) {
2701 2749 /* set wce on device */
2702 2750 sret = sbd_wcd_set(mlu->mlu_writeback_cache_disable, sl);
2703 2751 if (!mlu->mlu_writeback_cache_disable && sret != SBD_SUCCESS) {
2704 2752 *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED;
2705 2753 ret = EFAULT;
2706 2754 goto smm_err_out;
2707 2755 }
2708 2756 mutex_enter(&sl->sl_lock);
2709 2757 if (!mlu->mlu_writeback_cache_disable) {
2710 2758 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) {
2711 2759 ua = 1;
2712 2760 sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE;
2713 2761 sl->sl_flags &= ~SL_SAVED_WRITE_CACHE_DISABLE;
2714 2762 }
2715 2763 } else {
2716 2764 if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) == 0) {
2717 2765 ua = 1;
2718 2766 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE;
2719 2767 sl->sl_flags |= SL_SAVED_WRITE_CACHE_DISABLE;
2720 2768 }
2721 2769 }
2722 2770 for (it = sl->sl_it_list; ua && it != NULL;
2723 2771 it = it->sbd_it_next) {
2724 2772 it->sbd_it_ua_conditions |=
2725 2773 SBD_UA_MODE_PARAMETERS_CHANGED;
2726 2774 }
2727 2775 mutex_exit(&sl->sl_lock);
2728 2776 }
2729 2777 ua = 0;
2730 2778
2731 2779 if (mlu->mlu_alias_valid) {
2732 2780 alias_sz = strlen((char *)mlu->mlu_buf +
2733 2781 mlu->mlu_alias_off) + 1;
2734 2782 /*
2735 2783 * Use the allocated buffer or alloc a new one.
2736 2784 * Don't copy into sl_alias if sl_alias_alloc_size is 0
2737 2785 * otherwise or you'll be writing over the data/metadata
2738 2786 * filename.
2739 2787 */
2740 2788 mutex_enter(&sl->sl_lock);
2741 2789 if (sl->sl_alias_alloc_size > 0 &&
2742 2790 sl->sl_alias_alloc_size < alias_sz) {
2743 2791 kmem_free(sl->sl_alias,
2744 2792 sl->sl_alias_alloc_size);
2745 2793 sl->sl_alias_alloc_size = 0;
2746 2794 }
2747 2795 if (sl->sl_alias_alloc_size == 0) {
2748 2796 sl->sl_alias = kmem_alloc(alias_sz, KM_SLEEP);
2749 2797 sl->sl_alias_alloc_size = alias_sz;
2750 2798 }
2751 2799 (void) strcpy(sl->sl_alias, (char *)mlu->mlu_buf +
2752 2800 mlu->mlu_alias_off);
2753 2801 lu = sl->sl_lu;
2754 2802 lu->lu_alias = sl->sl_alias;
2755 2803 mutex_exit(&sl->sl_lock);
2756 2804 }
2757 2805
2758 2806 if (mlu->mlu_mgmt_url_valid) {
2759 2807 uint16_t url_sz;
2760 2808
2761 2809 url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off);
2762 2810 if (url_sz > 0)
2763 2811 url_sz++;
2764 2812
2765 2813 mutex_enter(&sl->sl_lock);
2766 2814 if (sl->sl_mgmt_url_alloc_size > 0 &&
2767 2815 (url_sz == 0 || sl->sl_mgmt_url_alloc_size < url_sz)) {
2768 2816 kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size);
2769 2817 sl->sl_mgmt_url = NULL;
2770 2818 sl->sl_mgmt_url_alloc_size = 0;
2771 2819 }
2772 2820 if (url_sz > 0) {
2773 2821 if (sl->sl_mgmt_url_alloc_size == 0) {
2774 2822 sl->sl_mgmt_url = kmem_alloc(url_sz, KM_SLEEP);
2775 2823 sl->sl_mgmt_url_alloc_size = url_sz;
2776 2824 }
2777 2825 (void) strcpy(sl->sl_mgmt_url, (char *)mlu->mlu_buf +
2778 2826 mlu->mlu_mgmt_url_off);
2779 2827 }
2780 2828 for (it = sl->sl_it_list; it != NULL;
2781 2829 it = it->sbd_it_next) {
2782 2830 it->sbd_it_ua_conditions |=
2783 2831 SBD_UA_MODE_PARAMETERS_CHANGED;
2784 2832 }
2785 2833 mutex_exit(&sl->sl_lock);
2786 2834 }
2787 2835
2788 2836 if (mlu->mlu_write_protected_valid) {
2789 2837 mutex_enter(&sl->sl_lock);
2790 2838 if (mlu->mlu_write_protected) {
2791 2839 if ((sl->sl_flags & SL_WRITE_PROTECTED) == 0) {
2792 2840 ua = 1;
2793 2841 sl->sl_flags |= SL_WRITE_PROTECTED;
2794 2842 }
2795 2843 } else {
2796 2844 if (sl->sl_flags & SL_WRITE_PROTECTED) {
2797 2845 ua = 1;
2798 2846 sl->sl_flags &= ~SL_WRITE_PROTECTED;
2799 2847 }
2800 2848 }
2801 2849 for (it = sl->sl_it_list; ua && it != NULL;
2802 2850 it = it->sbd_it_next) {
2803 2851 it->sbd_it_ua_conditions |=
2804 2852 SBD_UA_MODE_PARAMETERS_CHANGED;
2805 2853 }
2806 2854 mutex_exit(&sl->sl_lock);
2807 2855 }
2808 2856
2809 2857 if (mlu->mlu_lu_size_valid) {
2810 2858 /*
2811 2859 * validate lu size and set
2812 2860 * For open file only (registered lu)
2813 2861 */
2814 2862 mutex_enter(&sl->sl_lock);
2815 2863 old_size = sl->sl_lu_size;
2816 2864 sl->sl_lu_size = mlu->mlu_lu_size;
2817 2865 mutex_exit(&sl->sl_lock);
2818 2866 ret = sbd_open_data_file(sl, err_ret, 1, 1, 1);
2819 2867 if (ret) {
2820 2868 mutex_enter(&sl->sl_lock);
2821 2869 sl->sl_lu_size = old_size;
2822 2870 mutex_exit(&sl->sl_lock);
2823 2871 goto smm_err_out;
2824 2872 }
2825 2873 if (old_size != mlu->mlu_lu_size) {
2826 2874 mutex_enter(&sl->sl_lock);
2827 2875 for (it = sl->sl_it_list; it != NULL;
2828 2876 it = it->sbd_it_next) {
2829 2877 it->sbd_it_ua_conditions |=
2830 2878 SBD_UA_CAPACITY_CHANGED;
2831 2879 }
2832 2880 mutex_exit(&sl->sl_lock);
2833 2881 }
2834 2882 }
2835 2883
2836 2884 if (sbd_write_lu_info(sl) != SBD_SUCCESS) {
2837 2885 *err_ret = SBD_RET_META_CREATION_FAILED;
2838 2886 ret = EIO;
2839 2887 }
2840 2888
2841 2889 smm_err_out:
2842 2890 if (modify_unregistered) {
2843 2891 (void) sbd_close_delete_lu(sl, 0);
2844 2892 } else {
2845 2893 sl->sl_trans_op = SL_OP_NONE;
2846 2894 }
2847 2895 return (ret);
2848 2896 }
2849 2897
2850 2898 int
2851 2899 sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz,
2852 2900 uint32_t *err_ret)
2853 2901 {
2854 2902 sbd_lu_t *sl = NULL;
2855 2903 int ret = 0;
2856 2904 sbd_it_data_t *it;
2857 2905 uint32_t sz;
2858 2906
2859 2907 sz = struct_sz - sizeof (*mlu) + 8 + 1;
2860 2908
2861 2909 /* if there is data in the buf, null terminate it */
2862 2910 if (struct_sz > sizeof (*mlu)) {
2863 2911 mlu->mlu_buf[struct_sz - sizeof (*mlu) + 8 - 1] = 0;
2864 2912 }
2865 2913
2866 2914 *err_ret = 0;
2867 2915
2868 2916 /* Lets validate offsets */
2869 2917 if (((mlu->mlu_mgmt_url_valid) &&
2870 2918 (mlu->mlu_mgmt_url_off >= sz))) {
2871 2919 return (EINVAL);
2872 2920 }
2873 2921
2874 2922 if (mlu->mlu_mgmt_url_valid) {
2875 2923 uint16_t url_sz;
2876 2924
2877 2925 url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off);
2878 2926 if (url_sz > 0)
2879 2927 url_sz++;
2880 2928
2881 2929 rw_enter(&sbd_global_prop_lock, RW_WRITER);
2882 2930 if (sbd_mgmt_url_alloc_size > 0 &&
2883 2931 (url_sz == 0 || sbd_mgmt_url_alloc_size < url_sz)) {
2884 2932 kmem_free(sbd_mgmt_url, sbd_mgmt_url_alloc_size);
2885 2933 sbd_mgmt_url = NULL;
2886 2934 sbd_mgmt_url_alloc_size = 0;
2887 2935 }
2888 2936 if (url_sz > 0) {
2889 2937 if (sbd_mgmt_url_alloc_size == 0) {
2890 2938 sbd_mgmt_url = kmem_alloc(url_sz, KM_SLEEP);
2891 2939 sbd_mgmt_url_alloc_size = url_sz;
2892 2940 }
2893 2941 (void) strcpy(sbd_mgmt_url, (char *)mlu->mlu_buf +
2894 2942 mlu->mlu_mgmt_url_off);
2895 2943 }
2896 2944 /*
2897 2945 * check each lu to determine whether a UA is needed.
2898 2946 */
2899 2947 mutex_enter(&sbd_lock);
2900 2948 for (sl = sbd_lu_list; sl; sl = sl->sl_next) {
2901 2949 if (sl->sl_mgmt_url) {
2902 2950 continue;
2903 2951 }
2904 2952 mutex_enter(&sl->sl_lock);
2905 2953 for (it = sl->sl_it_list; it != NULL;
2906 2954 it = it->sbd_it_next) {
2907 2955 it->sbd_it_ua_conditions |=
2908 2956 SBD_UA_MODE_PARAMETERS_CHANGED;
2909 2957 }
2910 2958 mutex_exit(&sl->sl_lock);
2911 2959 }
2912 2960 mutex_exit(&sbd_lock);
2913 2961 rw_exit(&sbd_global_prop_lock);
2914 2962 }
2915 2963 return (ret);
2916 2964 }
2917 2965
2918 2966 /* ARGSUSED */
2919 2967 int
2920 2968 sbd_delete_locked_lu(sbd_lu_t *sl, uint32_t *err_ret,
2921 2969 stmf_state_change_info_t *ssi)
2922 2970 {
2923 2971 int i;
2924 2972 stmf_status_t ret;
2925 2973
2926 2974 if ((sl->sl_state == STMF_STATE_OFFLINE) &&
2927 2975 !sl->sl_state_not_acked) {
2928 2976 goto sdl_do_dereg;
2929 2977 }
2930 2978
2931 2979 if ((sl->sl_state != STMF_STATE_ONLINE) ||
2932 2980 sl->sl_state_not_acked) {
2933 2981 return (EBUSY);
2934 2982 }
2935 2983
2936 2984 ret = stmf_ctl(STMF_CMD_LU_OFFLINE, sl->sl_lu, ssi);
2937 2985 if ((ret != STMF_SUCCESS) && (ret != STMF_ALREADY)) {
2938 2986 return (EBUSY);
2939 2987 }
2940 2988
2941 2989 for (i = 0; i < 500; i++) {
2942 2990 if ((sl->sl_state == STMF_STATE_OFFLINE) &&
2943 2991 !sl->sl_state_not_acked) {
2944 2992 goto sdl_do_dereg;
2945 2993 }
2946 2994 delay(drv_usectohz(10000));
2947 2995 }
2948 2996 return (EBUSY);
2949 2997
2950 2998 sdl_do_dereg:;
2951 2999 if (stmf_deregister_lu(sl->sl_lu) != STMF_SUCCESS)
2952 3000 return (EBUSY);
2953 3001 atomic_dec_32(&sbd_lu_count);
2954 3002
2955 3003 return (sbd_close_delete_lu(sl, 0));
2956 3004 }
2957 3005
2958 3006 int
2959 3007 sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret)
2960 3008 {
2961 3009 sbd_lu_t *sl;
2962 3010 sbd_status_t sret;
2963 3011 stmf_state_change_info_t ssi;
2964 3012 int ret;
2965 3013
2966 3014 if (dlu->dlu_by_meta_name) {
2967 3015 ((char *)dlu)[struct_sz - 1] = 0;
2968 3016 sret = sbd_find_and_lock_lu(NULL, dlu->dlu_meta_name,
2969 3017 SL_OP_DELETE_LU, &sl);
2970 3018 } else {
2971 3019 sret = sbd_find_and_lock_lu(dlu->dlu_guid, NULL,
2972 3020 SL_OP_DELETE_LU, &sl);
2973 3021 }
2974 3022 if (sret != SBD_SUCCESS) {
2975 3023 if (sret == SBD_BUSY) {
2976 3024 *err_ret = SBD_RET_LU_BUSY;
2977 3025 return (EBUSY);
2978 3026 } else if (sret == SBD_NOT_FOUND) {
2979 3027 *err_ret = SBD_RET_NOT_FOUND;
2980 3028 return (ENOENT);
2981 3029 }
2982 3030 return (EIO);
2983 3031 }
2984 3032
2985 3033 ssi.st_rflags = STMF_RFLAG_USER_REQUEST;
2986 3034 ssi.st_additional_info = "sbd_delete_lu call (ioctl)";
2987 3035 ret = sbd_delete_locked_lu(sl, err_ret, &ssi);
2988 3036
2989 3037 if (ret) {
|
↓ open down ↓ |
1139 lines elided |
↑ open up ↑ |
2990 3038 /* Once its locked, no need to grab mutex again */
2991 3039 sl->sl_trans_op = SL_OP_NONE;
2992 3040 }
2993 3041 return (ret);
2994 3042 }
2995 3043
2996 3044 sbd_status_t
2997 3045 sbd_data_read(sbd_lu_t *sl, struct scsi_task *task,
2998 3046 uint64_t offset, uint64_t size, uint8_t *buf)
2999 3047 {
3000 - int ret;
3048 + int ret, ioflag = 0;
3001 3049 long resid;
3050 + hrtime_t xfer_start;
3051 + uint8_t op = task->task_cdb[0];
3002 3052
3003 3053 if ((offset + size) > sl->sl_lu_size) {
3004 3054 return (SBD_IO_PAST_EOF);
3005 3055 }
3006 3056
3007 3057 offset += sl->sl_data_offset;
3008 3058
3059 + /*
3060 + * Check to see if the command is READ(10), READ(12), or READ(16).
3061 + * If it is then check for bit 3 being set to indicate if Forced
3062 + * Unit Access is being requested. If so, the FSYNC flag will be set
3063 + * on the read.
3064 + */
3065 + if (((op == SCMD_READ_G1) || (op == SCMD_READ_G4) ||
3066 + (op == SCMD_READ_G5)) && (task->task_cdb[1] & BIT_3)) {
3067 + ioflag = FSYNC;
3068 + }
3009 3069 if ((offset + size) > sl->sl_data_readable_size) {
3010 3070 uint64_t store_end;
3011 3071 if (offset > sl->sl_data_readable_size) {
3012 3072 bzero(buf, size);
3013 3073 return (SBD_SUCCESS);
3014 3074 }
3015 3075 store_end = sl->sl_data_readable_size - offset;
3016 3076 bzero(buf + store_end, size - store_end);
3017 3077 size = store_end;
3018 3078 }
3019 3079
3080 + xfer_start = gethrtime();
3020 3081 DTRACE_PROBE5(backing__store__read__start, sbd_lu_t *, sl,
3021 3082 uint8_t *, buf, uint64_t, size, uint64_t, offset,
3022 3083 scsi_task_t *, task);
3023 3084
3024 3085 /*
3025 3086 * Don't proceed if the device has been closed
3026 3087 * This can occur on an access state change to standby or
3027 3088 * a delete. The writer lock is acquired before closing the
3028 3089 * lu.
3029 3090 */
3030 3091 rw_enter(&sl->sl_access_state_lock, RW_READER);
3031 3092 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) {
3032 3093 rw_exit(&sl->sl_access_state_lock);
3033 3094 return (SBD_FAILURE);
3034 3095 }
3096 +
3035 3097 ret = vn_rdwr(UIO_READ, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size,
3036 - (offset_t)offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, CRED(),
3098 + (offset_t)offset, UIO_SYSSPACE, ioflag, RLIM64_INFINITY, CRED(),
3037 3099 &resid);
3038 3100 rw_exit(&sl->sl_access_state_lock);
3039 3101
3102 + stmf_lu_xfer_done(task, B_TRUE /* read */,
3103 + (gethrtime() - xfer_start));
3040 3104 DTRACE_PROBE6(backing__store__read__end, sbd_lu_t *, sl,
3041 3105 uint8_t *, buf, uint64_t, size, uint64_t, offset,
3042 3106 int, ret, scsi_task_t *, task);
3043 3107
3044 3108 over_sl_data_read:
3045 3109 if (ret || resid) {
3046 3110 stmf_trace(0, "UIO_READ failed, ret = %d, resid = %d", ret,
3047 3111 resid);
3048 3112 return (SBD_FAILURE);
3049 3113 }
3050 3114
3051 3115 return (SBD_SUCCESS);
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3052 3116 }
3053 3117
3054 3118 sbd_status_t
3055 3119 sbd_data_write(sbd_lu_t *sl, struct scsi_task *task,
3056 3120 uint64_t offset, uint64_t size, uint8_t *buf)
3057 3121 {
3058 3122 int ret;
3059 3123 long resid;
3060 3124 sbd_status_t sret = SBD_SUCCESS;
3061 3125 int ioflag;
3126 + hrtime_t xfer_start;
3127 + uint8_t op = task->task_cdb[0];
3128 + boolean_t fua_bit = B_FALSE;
3062 3129
3063 3130 if ((offset + size) > sl->sl_lu_size) {
3064 3131 return (SBD_IO_PAST_EOF);
3065 3132 }
3066 3133
3067 3134 offset += sl->sl_data_offset;
3068 3135
3069 - if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) &&
3070 - (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) {
3136 + /*
3137 + * Check to see if the command is WRITE(10), WRITE(12), or WRITE(16).
3138 + * If it is then check for bit 3 being set to indicate if Forced
3139 + * Unit Access is being requested. If so, the FSYNC flag will be set
3140 + * on the write.
3141 + */
3142 + if (((op == SCMD_WRITE_G1) || (op == SCMD_WRITE_G4) ||
3143 + (op == SCMD_WRITE_G5)) && (task->task_cdb[1] & BIT_3)) {
3144 + fua_bit = B_TRUE;
3145 + }
3146 + if (((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) &&
3147 + (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) || fua_bit) {
3071 3148 ioflag = FSYNC;
3072 3149 } else {
3073 3150 ioflag = 0;
3074 3151 }
3075 3152
3153 + xfer_start = gethrtime();
3076 3154 DTRACE_PROBE5(backing__store__write__start, sbd_lu_t *, sl,
3077 3155 uint8_t *, buf, uint64_t, size, uint64_t, offset,
3078 3156 scsi_task_t *, task);
3079 3157
3080 3158 /*
3081 3159 * Don't proceed if the device has been closed
3082 3160 * This can occur on an access state change to standby or
3083 3161 * a delete. The writer lock is acquired before closing the
3084 3162 * lu.
3085 3163 */
3086 3164 rw_enter(&sl->sl_access_state_lock, RW_READER);
3087 3165 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) {
3088 3166 rw_exit(&sl->sl_access_state_lock);
3089 3167 return (SBD_FAILURE);
3090 3168 }
3091 3169 ret = vn_rdwr(UIO_WRITE, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size,
3092 3170 (offset_t)offset, UIO_SYSSPACE, ioflag, RLIM64_INFINITY, CRED(),
3093 3171 &resid);
3094 3172 rw_exit(&sl->sl_access_state_lock);
3095 3173
3174 + stmf_lu_xfer_done(task, B_FALSE /* write */,
3175 + (gethrtime() - xfer_start));
3096 3176 DTRACE_PROBE6(backing__store__write__end, sbd_lu_t *, sl,
3097 3177 uint8_t *, buf, uint64_t, size, uint64_t, offset,
3098 3178 int, ret, scsi_task_t *, task);
3099 3179
3100 3180 if ((ret == 0) && (resid == 0) &&
3101 3181 (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) &&
3102 3182 (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) {
3103 3183 sret = sbd_flush_data_cache(sl, 1);
3104 3184 }
3105 3185 over_sl_data_write:
3106 -
3107 3186 if ((ret || resid) || (sret != SBD_SUCCESS)) {
3108 3187 return (SBD_FAILURE);
3109 3188 } else if ((offset + size) > sl->sl_data_readable_size) {
3110 3189 uint64_t old_size, new_size;
3111 3190
3112 3191 do {
3113 3192 old_size = sl->sl_data_readable_size;
3114 3193 if ((offset + size) <= old_size)
3115 3194 break;
3116 3195 new_size = offset + size;
3117 3196 } while (atomic_cas_64(&sl->sl_data_readable_size, old_size,
3118 3197 new_size) != old_size);
3119 3198 }
3120 3199
3121 3200 return (SBD_SUCCESS);
3122 3201 }
3123 3202
3124 3203 int
3125 3204 sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz,
3126 3205 uint32_t *err_ret)
3127 3206 {
3128 3207 uint32_t sz = 0;
3129 3208 uint16_t off;
3130 3209
3131 3210 rw_enter(&sbd_global_prop_lock, RW_READER);
3132 3211 if (sbd_mgmt_url) {
3133 3212 sz += strlen(sbd_mgmt_url) + 1;
3134 3213 }
3135 3214 bzero(oslp, sizeof (*oslp) - 8);
3136 3215 oslp->mlu_buf_size_needed = sz;
3137 3216
3138 3217 if (sz > (oslp_sz - sizeof (*oslp) + 8)) {
3139 3218 *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE;
3140 3219 rw_exit(&sbd_global_prop_lock);
3141 3220 return (ENOMEM);
3142 3221 }
3143 3222
3144 3223 off = 0;
3145 3224 if (sbd_mgmt_url) {
3146 3225 oslp->mlu_mgmt_url_valid = 1;
3147 3226 oslp->mlu_mgmt_url_off = off;
3148 3227 (void) strcpy((char *)&oslp->mlu_buf[off], sbd_mgmt_url);
3149 3228 off += strlen(sbd_mgmt_url) + 1;
3150 3229 }
3151 3230
3152 3231 rw_exit(&sbd_global_prop_lock);
3153 3232 return (0);
3154 3233 }
3155 3234
3156 3235 static int
3157 3236 sbd_get_unmap_props(sbd_unmap_props_t *sup,
3158 3237 sbd_unmap_props_t *osup, uint32_t *err_ret)
3159 3238 {
3160 3239 sbd_status_t sret;
3161 3240 sbd_lu_t *sl = NULL;
3162 3241
3163 3242 if (sup->sup_guid_valid) {
3164 3243 sret = sbd_find_and_lock_lu(sup->sup_guid,
3165 3244 NULL, SL_OP_LU_PROPS, &sl);
3166 3245 } else {
3167 3246 sret = sbd_find_and_lock_lu(NULL,
3168 3247 (uint8_t *)sup->sup_zvol_path, SL_OP_LU_PROPS,
3169 3248 &sl);
3170 3249 }
3171 3250 if (sret != SBD_SUCCESS) {
3172 3251 if (sret == SBD_BUSY) {
3173 3252 *err_ret = SBD_RET_LU_BUSY;
3174 3253 return (EBUSY);
3175 3254 } else if (sret == SBD_NOT_FOUND) {
3176 3255 *err_ret = SBD_RET_NOT_FOUND;
3177 3256 return (ENOENT);
3178 3257 }
3179 3258 return (EIO);
3180 3259 }
3181 3260
3182 3261 sup->sup_found_lu = 1;
3183 3262 sup->sup_guid_valid = 1;
3184 3263 bcopy(sl->sl_device_id + 4, sup->sup_guid, 16);
3185 3264 if (sl->sl_flags & SL_UNMAP_ENABLED)
3186 3265 sup->sup_unmap_enabled = 1;
3187 3266 else
3188 3267 sup->sup_unmap_enabled = 0;
3189 3268
3190 3269 *osup = *sup;
3191 3270 sl->sl_trans_op = SL_OP_NONE;
3192 3271
3193 3272 return (0);
3194 3273 }
3195 3274
3196 3275 int
3197 3276 sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
3198 3277 sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret)
3199 3278 {
3200 3279 sbd_status_t sret;
3201 3280 sbd_lu_t *sl = NULL;
3202 3281 uint32_t sz;
3203 3282 uint16_t off;
3204 3283
3205 3284 if (islp->slp_input_guid) {
3206 3285 sret = sbd_find_and_lock_lu(islp->slp_guid, NULL,
3207 3286 SL_OP_LU_PROPS, &sl);
3208 3287 } else {
3209 3288 ((char *)islp)[islp_sz - 1] = 0;
3210 3289 sret = sbd_find_and_lock_lu(NULL, islp->slp_buf,
3211 3290 SL_OP_LU_PROPS, &sl);
3212 3291 }
3213 3292 if (sret != SBD_SUCCESS) {
3214 3293 if (sret == SBD_BUSY) {
3215 3294 *err_ret = SBD_RET_LU_BUSY;
3216 3295 return (EBUSY);
3217 3296 } else if (sret == SBD_NOT_FOUND) {
3218 3297 *err_ret = SBD_RET_NOT_FOUND;
3219 3298 return (ENOENT);
3220 3299 }
3221 3300 return (EIO);
3222 3301 }
3223 3302
3224 3303 sz = strlen(sl->sl_name) + 1;
3225 3304 if ((sl->sl_flags & (SL_ZFS_META | SL_SHARED_META)) == 0) {
3226 3305 if (sl->sl_data_filename) {
3227 3306 sz += strlen(sl->sl_data_filename) + 1;
3228 3307 }
3229 3308 }
3230 3309 sz += sl->sl_serial_no_size;
3231 3310 if (sl->sl_alias) {
3232 3311 sz += strlen(sl->sl_alias) + 1;
3233 3312 }
3234 3313
3235 3314 rw_enter(&sbd_global_prop_lock, RW_READER);
3236 3315 if (sl->sl_mgmt_url) {
3237 3316 sz += strlen(sl->sl_mgmt_url) + 1;
3238 3317 } else if (sbd_mgmt_url) {
3239 3318 sz += strlen(sbd_mgmt_url) + 1;
3240 3319 }
3241 3320 bzero(oslp, sizeof (*oslp) - 8);
3242 3321 oslp->slp_buf_size_needed = sz;
3243 3322
3244 3323 if (sz > (oslp_sz - sizeof (*oslp) + 8)) {
3245 3324 sl->sl_trans_op = SL_OP_NONE;
3246 3325 *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE;
3247 3326 rw_exit(&sbd_global_prop_lock);
3248 3327 return (ENOMEM);
3249 3328 }
3250 3329
3251 3330 off = 0;
3252 3331 (void) strcpy((char *)oslp->slp_buf, sl->sl_name);
3253 3332 oslp->slp_meta_fname_off = off;
3254 3333 off += strlen(sl->sl_name) + 1;
3255 3334 if ((sl->sl_flags & (SL_ZFS_META | SL_SHARED_META)) == 0) {
3256 3335 oslp->slp_meta_fname_valid = 1;
3257 3336 oslp->slp_separate_meta = 1;
3258 3337 if (sl->sl_data_filename) {
3259 3338 oslp->slp_data_fname_valid = 1;
3260 3339 oslp->slp_data_fname_off = off;
3261 3340 (void) strcpy((char *)&oslp->slp_buf[off],
3262 3341 sl->sl_data_filename);
3263 3342 off += strlen(sl->sl_data_filename) + 1;
3264 3343 }
3265 3344 } else {
3266 3345 oslp->slp_data_fname_valid = 1;
3267 3346 oslp->slp_data_fname_off = oslp->slp_meta_fname_off;
3268 3347 if (sl->sl_flags & SL_ZFS_META) {
3269 3348 oslp->slp_zfs_meta = 1;
3270 3349 }
3271 3350 }
3272 3351 if (sl->sl_alias) {
3273 3352 oslp->slp_alias_valid = 1;
3274 3353 oslp->slp_alias_off = off;
3275 3354 (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_alias);
3276 3355 off += strlen(sl->sl_alias) + 1;
3277 3356 }
3278 3357 if (sl->sl_mgmt_url) {
3279 3358 oslp->slp_mgmt_url_valid = 1;
3280 3359 oslp->slp_mgmt_url_off = off;
3281 3360 (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_mgmt_url);
3282 3361 off += strlen(sl->sl_mgmt_url) + 1;
3283 3362 } else if (sbd_mgmt_url) {
3284 3363 oslp->slp_mgmt_url_valid = 1;
3285 3364 oslp->slp_mgmt_url_off = off;
3286 3365 (void) strcpy((char *)&oslp->slp_buf[off], sbd_mgmt_url);
3287 3366 off += strlen(sbd_mgmt_url) + 1;
3288 3367 }
3289 3368 if (sl->sl_serial_no_size) {
3290 3369 oslp->slp_serial_off = off;
3291 3370 bcopy(sl->sl_serial_no, &oslp->slp_buf[off],
3292 3371 sl->sl_serial_no_size);
3293 3372 oslp->slp_serial_size = sl->sl_serial_no_size;
3294 3373 oslp->slp_serial_valid = 1;
3295 3374 off += sl->sl_serial_no_size;
3296 3375 }
3297 3376
3298 3377 oslp->slp_lu_size = sl->sl_lu_size;
3299 3378 oslp->slp_blksize = ((uint16_t)1) << sl->sl_data_blocksize_shift;
3300 3379
3301 3380 oslp->slp_access_state = sl->sl_access_state;
3302 3381
3303 3382 if (sl->sl_flags & SL_VID_VALID) {
3304 3383 oslp->slp_lu_vid = 1;
3305 3384 bcopy(sl->sl_vendor_id, oslp->slp_vid, 8);
3306 3385 } else {
3307 3386 bcopy(sbd_vendor_id, oslp->slp_vid, 8);
3308 3387 }
3309 3388 if (sl->sl_flags & SL_PID_VALID) {
3310 3389 oslp->slp_lu_pid = 1;
3311 3390 bcopy(sl->sl_product_id, oslp->slp_pid, 16);
3312 3391 } else {
3313 3392 bcopy(sbd_product_id, oslp->slp_pid, 16);
3314 3393 }
3315 3394 if (sl->sl_flags & SL_REV_VALID) {
3316 3395 oslp->slp_lu_rev = 1;
3317 3396 bcopy(sl->sl_revision, oslp->slp_rev, 4);
3318 3397 } else {
3319 3398 bcopy(sbd_revision, oslp->slp_rev, 4);
3320 3399 }
3321 3400 bcopy(sl->sl_device_id + 4, oslp->slp_guid, 16);
3322 3401
3323 3402 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE)
3324 3403 oslp->slp_writeback_cache_disable_cur = 1;
3325 3404 if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE)
3326 3405 oslp->slp_writeback_cache_disable_saved = 1;
3327 3406 if (sl->sl_flags & SL_WRITE_PROTECTED)
3328 3407 oslp->slp_write_protected = 1;
3329 3408
3330 3409 sl->sl_trans_op = SL_OP_NONE;
3331 3410
3332 3411 rw_exit(&sbd_global_prop_lock);
3333 3412 return (0);
3334 3413 }
3335 3414
3336 3415 /*
3337 3416 * Returns an allocated string with the "<pool>/..." form of the zvol name.
3338 3417 */
3339 3418 static char *
3340 3419 sbd_get_zvol_name(sbd_lu_t *sl)
3341 3420 {
3342 3421 char *src;
3343 3422 char *p;
3344 3423
3345 3424 if (sl->sl_data_filename)
3346 3425 src = sl->sl_data_filename;
3347 3426 else
3348 3427 src = sl->sl_meta_filename;
3349 3428 /* There has to be a better way */
3350 3429 if (SBD_IS_ZVOL(src) != 0) {
3351 3430 ASSERT(0);
3352 3431 }
3353 3432 src += 14; /* Past /dev/zvol/dsk/ */
3354 3433 if (*src == '/')
3355 3434 src++; /* or /dev/zvol/rdsk/ */
3356 3435 p = (char *)kmem_alloc(strlen(src) + 1, KM_SLEEP);
3357 3436 (void) strcpy(p, src);
3358 3437 return (p);
3359 3438 }
3360 3439
3361 3440 /*
3362 3441 * this function creates a local metadata zvol property
3363 3442 */
3364 3443 sbd_status_t
3365 3444 sbd_create_zfs_meta_object(sbd_lu_t *sl)
3366 3445 {
3367 3446 /*
3368 3447 * -allocate 1/2 the property size, the zfs property
3369 3448 * is 8k in size and stored as ascii hex string, all
3370 3449 * we needed is 4k buffer to store the binary data.
3371 3450 * -initialize reader/write lock
3372 3451 */
3373 3452 if ((sl->sl_zfs_meta = kmem_zalloc(ZAP_MAXVALUELEN / 2, KM_SLEEP))
3374 3453 == NULL)
3375 3454 return (SBD_FAILURE);
3376 3455 rw_init(&sl->sl_zfs_meta_lock, NULL, RW_DRIVER, NULL);
3377 3456 return (SBD_SUCCESS);
3378 3457 }
3379 3458
3380 3459 char
3381 3460 sbd_ctoi(char c)
3382 3461 {
3383 3462 if ((c >= '0') && (c <= '9'))
3384 3463 c -= '0';
3385 3464 else if ((c >= 'A') && (c <= 'F'))
3386 3465 c = c - 'A' + 10;
3387 3466 else if ((c >= 'a') && (c <= 'f'))
3388 3467 c = c - 'a' + 10;
3389 3468 else
3390 3469 c = -1;
3391 3470 return (c);
3392 3471 }
3393 3472
3394 3473 /*
3395 3474 * read zvol property and convert to binary
3396 3475 */
3397 3476 sbd_status_t
3398 3477 sbd_open_zfs_meta(sbd_lu_t *sl)
3399 3478 {
3400 3479 char *meta = NULL, cl, ch;
3401 3480 int i;
3402 3481 char *tmp, *ptr;
3403 3482 uint64_t rc = SBD_SUCCESS;
3404 3483 int len;
3405 3484 char *file;
3406 3485
3407 3486 if (sl->sl_zfs_meta == NULL) {
3408 3487 if (sbd_create_zfs_meta_object(sl) == SBD_FAILURE)
3409 3488 return (SBD_FAILURE);
3410 3489 } else {
3411 3490 bzero(sl->sl_zfs_meta, (ZAP_MAXVALUELEN / 2));
3412 3491 }
3413 3492
3414 3493 rw_enter(&sl->sl_zfs_meta_lock, RW_WRITER);
3415 3494 file = sbd_get_zvol_name(sl);
3416 3495 if (sbd_zvolget(file, &meta)) {
3417 3496 rc = SBD_FAILURE;
3418 3497 goto done;
3419 3498 }
3420 3499 tmp = meta;
3421 3500 /* convert ascii hex to binary meta */
3422 3501 len = strlen(meta);
3423 3502 ptr = sl->sl_zfs_meta;
3424 3503 for (i = 0; i < len; i += 2) {
3425 3504 ch = sbd_ctoi(*tmp++);
3426 3505 cl = sbd_ctoi(*tmp++);
3427 3506 if (ch == -1 || cl == -1) {
3428 3507 rc = SBD_FAILURE;
3429 3508 break;
3430 3509 }
3431 3510 *ptr++ = (ch << 4) + cl;
3432 3511 }
3433 3512 done:
3434 3513 rw_exit(&sl->sl_zfs_meta_lock);
3435 3514 if (meta)
3436 3515 kmem_free(meta, len + 1);
3437 3516 kmem_free(file, strlen(file) + 1);
3438 3517 return (rc);
3439 3518 }
3440 3519
3441 3520 sbd_status_t
3442 3521 sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, uint64_t off)
3443 3522 {
3444 3523 ASSERT(sl->sl_zfs_meta);
3445 3524 rw_enter(&sl->sl_zfs_meta_lock, RW_READER);
3446 3525 bcopy(&sl->sl_zfs_meta[off], buf, sz);
3447 3526 rw_exit(&sl->sl_zfs_meta_lock);
3448 3527 return (SBD_SUCCESS);
3449 3528 }
3450 3529
3451 3530 sbd_status_t
3452 3531 sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, uint64_t off)
3453 3532 {
3454 3533 ASSERT(sl->sl_zfs_meta);
3455 3534 if ((off + sz) > (ZAP_MAXVALUELEN / 2 - 1)) {
3456 3535 return (SBD_META_CORRUPTED);
3457 3536 }
3458 3537 if ((off + sz) > sl->sl_meta_size_used) {
3459 3538 sl->sl_meta_size_used = off + sz;
3460 3539 if (sl->sl_total_meta_size < sl->sl_meta_size_used) {
3461 3540 uint64_t meta_align =
3462 3541 (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1;
3463 3542 sl->sl_total_meta_size = (sl->sl_meta_size_used +
3464 3543 meta_align) & (~meta_align);
3465 3544 }
3466 3545 }
3467 3546 rw_enter(&sl->sl_zfs_meta_lock, RW_WRITER);
3468 3547 bcopy(buf, &sl->sl_zfs_meta[off], sz);
3469 3548 rw_exit(&sl->sl_zfs_meta_lock);
3470 3549 /*
3471 3550 * During creation of a logical unit, sbd_update_zfs_prop will be
3472 3551 * called separately to avoid multiple calls as each meta section
3473 3552 * create/update will result in a call to sbd_write_zfs_meta().
3474 3553 * We only need to update the zvol once during create.
3475 3554 */
3476 3555 mutex_enter(&sl->sl_lock);
3477 3556 if (sl->sl_trans_op != SL_OP_CREATE_REGISTER_LU) {
3478 3557 mutex_exit(&sl->sl_lock);
3479 3558 return (sbd_update_zfs_prop(sl));
3480 3559 }
3481 3560 mutex_exit(&sl->sl_lock);
3482 3561 return (SBD_SUCCESS);
3483 3562 }
3484 3563
3485 3564 sbd_status_t
3486 3565 sbd_update_zfs_prop(sbd_lu_t *sl)
3487 3566 {
3488 3567 char *ptr, *ah_meta;
3489 3568 char *dp = NULL;
3490 3569 int i, num;
3491 3570 char *file;
3492 3571 sbd_status_t ret = SBD_SUCCESS;
3493 3572
3494 3573 ASSERT(sl->sl_zfs_meta);
3495 3574 ptr = ah_meta = kmem_zalloc(ZAP_MAXVALUELEN, KM_SLEEP);
3496 3575 rw_enter(&sl->sl_zfs_meta_lock, RW_READER);
3497 3576 /* convert local copy to ascii hex */
3498 3577 dp = sl->sl_zfs_meta;
3499 3578 for (i = 0; i < sl->sl_total_meta_size; i++, dp++) {
3500 3579 num = ((*dp) >> 4) & 0xF;
3501 3580 *ah_meta++ = (num < 10) ? (num + '0') : (num + ('a' - 10));
3502 3581 num = (*dp) & 0xF;
3503 3582 *ah_meta++ = (num < 10) ? (num + '0') : (num + ('a' - 10));
3504 3583 }
3505 3584 *ah_meta = NULL;
3506 3585 file = sbd_get_zvol_name(sl);
3507 3586 if (sbd_zvolset(file, (char *)ptr)) {
3508 3587 ret = SBD_META_CORRUPTED;
3509 3588 }
3510 3589 rw_exit(&sl->sl_zfs_meta_lock);
3511 3590 kmem_free(ptr, ZAP_MAXVALUELEN);
3512 3591 kmem_free(file, strlen(file) + 1);
3513 3592 return (ret);
3514 3593 }
3515 3594
3516 3595 int
3517 3596 sbd_is_zvol(char *path)
3518 3597 {
3519 3598 int is_zfs = 0;
3520 3599
3521 3600 if (SBD_IS_ZVOL(path) == 0)
3522 3601 is_zfs = 1;
3523 3602
3524 3603 return (is_zfs);
3525 3604 }
3526 3605
3527 3606 /*
3528 3607 * set write cache disable
3529 3608 * wcd - 1 = disable, 0 = enable
3530 3609 */
3531 3610 sbd_status_t
3532 3611 sbd_wcd_set(int wcd, sbd_lu_t *sl)
3533 3612 {
3534 3613 /* translate to wce bit */
3535 3614 int wce = wcd ? 0 : 1;
3536 3615 int ret;
3537 3616 sbd_status_t sret = SBD_SUCCESS;
3538 3617
3539 3618 mutex_enter(&sl->sl_lock);
3540 3619 sl->sl_flags &= ~SL_WRITEBACK_CACHE_SET_UNSUPPORTED;
3541 3620
3542 3621 if (sl->sl_data_vp->v_type == VREG) {
3543 3622 sl->sl_flags |= SL_FLUSH_ON_DISABLED_WRITECACHE;
3544 3623 goto done;
3545 3624 }
3546 3625
3547 3626 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCSETWCE, (intptr_t)&wce, FKIOCTL,
3548 3627 kcred, NULL, NULL);
3549 3628 if (ret == 0) {
3550 3629 sl->sl_flags &= ~SL_WRITEBACK_CACHE_SET_UNSUPPORTED;
3551 3630 sl->sl_flags &= ~SL_FLUSH_ON_DISABLED_WRITECACHE;
3552 3631 } else {
3553 3632 sl->sl_flags |= SL_WRITEBACK_CACHE_SET_UNSUPPORTED;
3554 3633 sl->sl_flags |= SL_FLUSH_ON_DISABLED_WRITECACHE;
3555 3634 sret = SBD_FAILURE;
3556 3635 goto done;
3557 3636 }
3558 3637
3559 3638 done:
3560 3639 mutex_exit(&sl->sl_lock);
3561 3640 return (sret);
3562 3641 }
3563 3642
3564 3643 /*
3565 3644 * get write cache disable
3566 3645 * wcd - 1 = disable, 0 = enable
3567 3646 */
3568 3647 void
3569 3648 sbd_wcd_get(int *wcd, sbd_lu_t *sl)
3570 3649 {
3571 3650 int wce;
3572 3651 int ret;
3573 3652
3574 3653 if (sl->sl_data_vp->v_type == VREG) {
3575 3654 *wcd = 0;
3576 3655 return;
3577 3656 }
3578 3657
3579 3658 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCGETWCE, (intptr_t)&wce, FKIOCTL,
3580 3659 kcred, NULL, NULL);
3581 3660 /* if write cache get failed, assume disabled */
3582 3661 if (ret) {
3583 3662 *wcd = 1;
3584 3663 } else {
3585 3664 /* translate to wcd bit */
3586 3665 *wcd = wce ? 0 : 1;
3587 3666 }
3588 3667 }
3589 3668
3590 3669 int
3591 3670 sbd_zvolget(char *zvol_name, char **comstarprop)
3592 3671 {
3593 3672 ldi_handle_t zfs_lh;
3594 3673 nvlist_t *nv = NULL, *nv2;
3595 3674 zfs_cmd_t *zc;
3596 3675 char *ptr;
3597 3676 int size = 1024;
3598 3677 int unused;
3599 3678 int rc;
3600 3679
3601 3680 if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred,
3602 3681 &zfs_lh, sbd_zfs_ident)) != 0) {
3603 3682 cmn_err(CE_WARN, "ldi_open %d", rc);
3604 3683 return (ENXIO);
3605 3684 }
3606 3685
3607 3686 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
3608 3687 (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name));
3609 3688 again:
3610 3689 zc->zc_nvlist_dst = (uint64_t)(intptr_t)kmem_alloc(size,
3611 3690 KM_SLEEP);
3612 3691 zc->zc_nvlist_dst_size = size;
3613 3692 rc = ldi_ioctl(zfs_lh, ZFS_IOC_OBJSET_STATS, (intptr_t)zc,
3614 3693 FKIOCTL, kcred, &unused);
3615 3694 /*
3616 3695 * ENOMEM means the list is larger than what we've allocated
3617 3696 * ldi_ioctl will fail with ENOMEM only once
3618 3697 */
3619 3698 if (rc == ENOMEM) {
3620 3699 int newsize;
3621 3700 newsize = zc->zc_nvlist_dst_size;
3622 3701 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
3623 3702 size = newsize;
3624 3703 goto again;
3625 3704 } else if (rc != 0) {
3626 3705 goto out;
3627 3706 }
3628 3707 rc = nvlist_unpack((char *)(uintptr_t)zc->zc_nvlist_dst,
3629 3708 zc->zc_nvlist_dst_size, &nv, 0);
3630 3709 ASSERT(rc == 0); /* nvlist_unpack should not fail */
3631 3710 if ((rc = nvlist_lookup_nvlist(nv, "stmf_sbd_lu", &nv2)) == 0) {
|
↓ open down ↓ |
515 lines elided |
↑ open up ↑ |
3632 3711 rc = nvlist_lookup_string(nv2, ZPROP_VALUE, &ptr);
3633 3712 if (rc != 0) {
3634 3713 cmn_err(CE_WARN, "couldn't get value");
3635 3714 } else {
3636 3715 *comstarprop = kmem_alloc(strlen(ptr) + 1,
3637 3716 KM_SLEEP);
3638 3717 (void) strcpy(*comstarprop, ptr);
3639 3718 }
3640 3719 }
3641 3720 out:
3642 - nvlist_free(nv);
3721 + if (nv != NULL)
3722 + nvlist_free(nv);
3643 3723 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
3644 3724 kmem_free(zc, sizeof (zfs_cmd_t));
3645 3725 (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3646 3726
3647 3727 return (rc);
3648 3728 }
3649 3729
3650 3730 int
3651 3731 sbd_zvolset(char *zvol_name, char *comstarprop)
3652 3732 {
3653 3733 ldi_handle_t zfs_lh;
3654 3734 nvlist_t *nv;
3655 3735 char *packed = NULL;
3656 3736 size_t len;
3657 3737 zfs_cmd_t *zc;
3658 3738 int unused;
3659 3739 int rc;
3660 3740
3661 3741 if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred,
3662 3742 &zfs_lh, sbd_zfs_ident)) != 0) {
3663 3743 cmn_err(CE_WARN, "ldi_open %d", rc);
3664 3744 return (ENXIO);
3665 3745 }
3666 3746 (void) nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP);
3667 3747 (void) nvlist_add_string(nv, "stmf_sbd_lu", comstarprop);
3668 3748 if ((rc = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, KM_SLEEP))) {
3669 3749 goto out;
3670 3750 }
3671 3751
3672 3752 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
3673 3753 (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name));
3674 3754 zc->zc_nvlist_src = (uint64_t)(intptr_t)packed;
3675 3755 zc->zc_nvlist_src_size = len;
3676 3756 rc = ldi_ioctl(zfs_lh, ZFS_IOC_SET_PROP, (intptr_t)zc,
3677 3757 FKIOCTL, kcred, &unused);
3678 3758 if (rc != 0) {
3679 3759 cmn_err(CE_NOTE, "ioctl failed %d", rc);
3680 3760 }
3681 3761 kmem_free(zc, sizeof (zfs_cmd_t));
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
3682 3762 if (packed)
3683 3763 kmem_free(packed, len);
3684 3764 out:
3685 3765 nvlist_free(nv);
3686 3766 (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3687 3767 return (rc);
3688 3768 }
3689 3769
3690 3770 /*
3691 3771 * Unmap a region in a volume. Currently only supported for zvols.
3772 + * The list of extents to be freed is passed in a dkioc_free_list_t
3773 + * which the caller is responsible for destroying.
3692 3774 */
3693 3775 int
3694 -sbd_unmap(sbd_lu_t *sl, uint64_t offset, uint64_t length)
3776 +sbd_unmap(sbd_lu_t *sl, dkioc_free_list_t *dfl)
3695 3777 {
3696 3778 vnode_t *vp;
3697 - int unused;
3698 - dkioc_free_t df;
3779 + int unused, ret;
3699 3780
3700 - /* Right now, we only support UNMAP on zvols. */
3701 - if (!(sl->sl_flags & SL_ZFS_META))
3702 - return (EIO);
3781 + /* Nothing to do */
3782 + if (dfl->dfl_num_exts == 0)
3783 + return (0);
3703 3784
3704 - df.df_flags = (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) ?
3785 + /*
3786 + * TODO: unmap performance may be improved by not doing the synchronous
3787 + * removal of the blocks and writing of the metadata. The
3788 + * transaction is in the zil so the state should be stable.
3789 + */
3790 + dfl->dfl_flags = (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) ?
3705 3791 DF_WAIT_SYNC : 0;
3706 - df.df_start = offset;
3707 - df.df_length = length;
3708 3792
3709 3793 /* Use the data vnode we have to send a fop_ioctl(). */
3710 3794 vp = sl->sl_data_vp;
3711 3795 if (vp == NULL) {
3712 3796 cmn_err(CE_WARN, "Cannot unmap - no vnode pointer.");
3713 3797 return (EIO);
3714 3798 }
3715 3799
3716 - return (VOP_IOCTL(vp, DKIOCFREE, (intptr_t)(&df), FKIOCTL, kcred,
3717 - &unused, NULL));
3800 + ret = VOP_IOCTL(vp, DKIOCFREE, (intptr_t)dfl, FKIOCTL, kcred,
3801 + &unused, NULL);
3802 +
3803 + return (ret);
3804 +}
3805 +
3806 +/*
3807 + * Check if this lu belongs to sbd or some other lu
3808 + * provider. A simple check for one of the module
3809 + * entry points is sufficient.
3810 + */
3811 +int
3812 +sbd_is_valid_lu(stmf_lu_t *lu)
3813 +{
3814 + if (lu->lu_new_task == sbd_new_task)
3815 + return (1);
3816 + return (0);
3817 +}
3818 +
3819 +uint8_t
3820 +sbd_get_lbasize_shift(stmf_lu_t *lu)
3821 +{
3822 + sbd_lu_t *sl = (sbd_lu_t *)lu->lu_provider_private;
3823 +
3824 + return (sl->sl_data_blocksize_shift);
3718 3825 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX