6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2013 Joyent, Inc. All rights reserved.
26 */
27
28 #include <sys/zfs_context.h>
29 #include <sys/spa_impl.h>
30 #include <sys/refcount.h>
31 #include <sys/vdev_disk.h>
32 #include <sys/vdev_impl.h>
33 #include <sys/fs/zfs.h>
34 #include <sys/zio.h>
35 #include <sys/sunldi.h>
36 #include <sys/efi_partition.h>
37 #include <sys/fm/fs/zfs.h>
38
39 /*
40 * Virtual device vector for disks.
41 */
42
43 extern ldi_ident_t zfs_li;
44
45 static void vdev_disk_close(vdev_t *);
254 static int
255 vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
256 uint64_t *ashift)
257 {
258 spa_t *spa = vd->vdev_spa;
259 vdev_disk_t *dvd = vd->vdev_tsd;
260 ldi_ev_cookie_t ecookie;
261 vdev_disk_ldi_cb_t *lcb;
262 union {
263 struct dk_minfo_ext ude;
264 struct dk_minfo ud;
265 } dks;
266 struct dk_minfo_ext *dkmext = &dks.ude;
267 struct dk_minfo *dkm = &dks.ud;
268 int error;
269 dev_t dev;
270 int otyp;
271 boolean_t validate_devid = B_FALSE;
272 ddi_devid_t devid;
273 uint64_t capacity = 0, blksz = 0, pbsize;
274
275 /*
276 * We must have a pathname, and it must be absolute.
277 */
278 if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
279 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
280 return (SET_ERROR(EINVAL));
281 }
282
283 /*
284 * Reopen the device if it's not currently open. Otherwise,
285 * just update the physical size of the device.
286 */
287 if (dvd != NULL) {
288 if (dvd->vd_ldi_offline && dvd->vd_lh == NULL) {
289 /*
290 * If we are opening a device in its offline notify
291 * context, the LDI handle was just closed. Clean
292 * up the LDI event callbacks and free vd->vdev_tsd.
293 */
526
527 if (error == 0) {
528 /*
529 * If we have the capability to expand, we'd have
530 * found out via success from DKIOCGMEDIAINFO{,EXT}.
531 * Adjust max_psize upward accordingly since we know
532 * we own the whole disk now.
533 */
534 *max_psize = capacity * blksz;
535 }
536
537 /*
538 * Since we own the whole disk, try to enable disk write
539 * caching. We ignore errors because it's OK if we can't do it.
540 */
541 (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
542 FKIOCTL, kcred, NULL);
543 }
544
545 /*
546 * Clear the nowritecache bit, so that on a vdev_reopen() we will
547 * try again.
548 */
549 vd->vdev_nowritecache = B_FALSE;
550
551 return (0);
552 }
553
554 static void
555 vdev_disk_close(vdev_t *vd)
556 {
557 vdev_disk_t *dvd = vd->vdev_tsd;
558
559 if (vd->vdev_reopening || dvd == NULL)
560 return;
561
562 if (dvd->vd_minor != NULL) {
563 ddi_devid_str_free(dvd->vd_minor);
564 dvd->vd_minor = NULL;
565 }
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2013 Joyent, Inc. All rights reserved.
26 * Copyright (c) 2017 James S Blachly, MD <james.blachly@gmail.com>
27 */
28
29 #include <sys/zfs_context.h>
30 #include <sys/spa_impl.h>
31 #include <sys/refcount.h>
32 #include <sys/vdev_disk.h>
33 #include <sys/vdev_impl.h>
34 #include <sys/fs/zfs.h>
35 #include <sys/zio.h>
36 #include <sys/sunldi.h>
37 #include <sys/efi_partition.h>
38 #include <sys/fm/fs/zfs.h>
39
40 /*
41 * Virtual device vector for disks.
42 */
43
44 extern ldi_ident_t zfs_li;
45
46 static void vdev_disk_close(vdev_t *);
255 static int
256 vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
257 uint64_t *ashift)
258 {
259 spa_t *spa = vd->vdev_spa;
260 vdev_disk_t *dvd = vd->vdev_tsd;
261 ldi_ev_cookie_t ecookie;
262 vdev_disk_ldi_cb_t *lcb;
263 union {
264 struct dk_minfo_ext ude;
265 struct dk_minfo ud;
266 } dks;
267 struct dk_minfo_ext *dkmext = &dks.ude;
268 struct dk_minfo *dkm = &dks.ud;
269 int error;
270 dev_t dev;
271 int otyp;
272 boolean_t validate_devid = B_FALSE;
273 ddi_devid_t devid;
274 uint64_t capacity = 0, blksz = 0, pbsize;
275 int device_solid_state;
276 char *vendorp; /* will point to inquiry-vendor-id */
277
278 /*
279 * We must have a pathname, and it must be absolute.
280 */
281 if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
282 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
283 return (SET_ERROR(EINVAL));
284 }
285
286 /*
287 * Reopen the device if it's not currently open. Otherwise,
288 * just update the physical size of the device.
289 */
290 if (dvd != NULL) {
291 if (dvd->vd_ldi_offline && dvd->vd_lh == NULL) {
292 /*
293 * If we are opening a device in its offline notify
294 * context, the LDI handle was just closed. Clean
295 * up the LDI event callbacks and free vd->vdev_tsd.
296 */
529
530 if (error == 0) {
531 /*
532 * If we have the capability to expand, we'd have
533 * found out via success from DKIOCGMEDIAINFO{,EXT}.
534 * Adjust max_psize upward accordingly since we know
535 * we own the whole disk now.
536 */
537 *max_psize = capacity * blksz;
538 }
539
540 /*
541 * Since we own the whole disk, try to enable disk write
542 * caching. We ignore errors because it's OK if we can't do it.
543 */
544 (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
545 FKIOCTL, kcred, NULL);
546 }
547
548 /*
549 * Inform the ZIO pipeline if we are non-rotational:
550 * 1. Check if device is SSD
551 * 2. If not SSD, check if device is Virtio
552 */
553 device_solid_state = ldi_prop_get_int(dvd->vd_lh, LDI_DEV_T_ANY,
554 "device-solid-state", 0);
555 vd->vdev_nonrot = (device_solid_state ? B_TRUE : B_FALSE);
556
557 if (device_solid_state == 0 &&
558 ldi_prop_exists(dvd->vd_lh, LDI_DEV_T_ANY, "inquiry-vendor-id")) {
559 ldi_prop_lookup_string(dvd->vd_lh, LDI_DEV_T_ANY,
560 "inquiry-vendor-id", &vendorp);
561 if (strncmp(vendorp, "Virtio", 6) == 0)
562 vd->vdev_nonrot = B_TRUE;
563 ddi_prop_free(vendorp);
564 }
565
566 cmn_err(CE_NOTE, "[vdev_disk_open] %s :: device-solid-state "
567 "== %d :: vd->vdev_nonrot == %d\n", vd->vdev_path,
568 device_solid_state, (int) vd->vdev_nonrot);
569
570 /*
571 * Clear the nowritecache bit, so that on a vdev_reopen() we will
572 * try again.
573 */
574 vd->vdev_nowritecache = B_FALSE;
575
576 return (0);
577 }
578
579 static void
580 vdev_disk_close(vdev_t *vd)
581 {
582 vdev_disk_t *dvd = vd->vdev_tsd;
583
584 if (vd->vdev_reopening || dvd == NULL)
585 return;
586
587 if (dvd->vd_minor != NULL) {
588 ddi_devid_str_free(dvd->vd_minor);
589 dvd->vd_minor = NULL;
590 }
|