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/abd.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
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
276 /*
277 * We must have a pathname, and it must be absolute.
278 */
279 if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
280 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
281 return (SET_ERROR(EINVAL));
282 }
283
284 /*
285 * Reopen the device if it's not currently open. Otherwise,
286 * just update the physical size of the device.
287 */
288 if (dvd != NULL) {
289 if (dvd->vd_ldi_offline && dvd->vd_lh == NULL) {
290 /*
291 * If we are opening a device in its offline notify
292 * context, the LDI handle was just closed. Clean
293 * up the LDI event callbacks and free vd->vdev_tsd.
294 */
527
528 if (error == 0) {
529 /*
530 * If we have the capability to expand, we'd have
531 * found out via success from DKIOCGMEDIAINFO{,EXT}.
532 * Adjust max_psize upward accordingly since we know
533 * we own the whole disk now.
534 */
535 *max_psize = capacity * blksz;
536 }
537
538 /*
539 * Since we own the whole disk, try to enable disk write
540 * caching. We ignore errors because it's OK if we can't do it.
541 */
542 (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
543 FKIOCTL, kcred, NULL);
544 }
545
546 /*
547 * Clear the nowritecache bit, so that on a vdev_reopen() we will
548 * try again.
549 */
550 vd->vdev_nowritecache = B_FALSE;
551
552 return (0);
553 }
554
555 static void
556 vdev_disk_close(vdev_t *vd)
557 {
558 vdev_disk_t *dvd = vd->vdev_tsd;
559
560 if (vd->vdev_reopening || dvd == NULL)
561 return;
562
563 if (dvd->vd_minor != NULL) {
564 ddi_devid_str_free(dvd->vd_minor);
565 dvd->vd_minor = NULL;
566 }
|
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/abd.h>
35 #include <sys/fs/zfs.h>
36 #include <sys/zio.h>
37 #include <sys/sunldi.h>
38 #include <sys/efi_partition.h>
39 #include <sys/fm/fs/zfs.h>
40
41 /*
42 * Virtual device vector for disks.
43 */
44
45 extern ldi_ident_t zfs_li;
46
256 static int
257 vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
258 uint64_t *ashift)
259 {
260 spa_t *spa = vd->vdev_spa;
261 vdev_disk_t *dvd = vd->vdev_tsd;
262 ldi_ev_cookie_t ecookie;
263 vdev_disk_ldi_cb_t *lcb;
264 union {
265 struct dk_minfo_ext ude;
266 struct dk_minfo ud;
267 } dks;
268 struct dk_minfo_ext *dkmext = &dks.ude;
269 struct dk_minfo *dkm = &dks.ud;
270 int error;
271 dev_t dev;
272 int otyp;
273 boolean_t validate_devid = B_FALSE;
274 ddi_devid_t devid;
275 uint64_t capacity = 0, blksz = 0, pbsize;
276 int device_rotational;
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 */
551 device_rotational = ldi_prop_get_int(dvd->vd_lh, LDI_DEV_T_ANY,
552 "device-rotational", 0);
553 vd->vdev_nonrot = (device_rotational ? B_FALSE : B_TRUE);
554
555 cmn_err(CE_NOTE, "![vdev_disk_open] %s :: vd->vdev_nonrot == %d\n",
556 vd->vdev_path, (int) vd->vdev_nonrot);
557
558 /*
559 * Clear the nowritecache bit, so that on a vdev_reopen() we will
560 * try again.
561 */
562 vd->vdev_nowritecache = B_FALSE;
563
564 return (0);
565 }
566
567 static void
568 vdev_disk_close(vdev_t *vd)
569 {
570 vdev_disk_t *dvd = vd->vdev_tsd;
571
572 if (vd->vdev_reopening || dvd == NULL)
573 return;
574
575 if (dvd->vd_minor != NULL) {
576 ddi_devid_str_free(dvd->vd_minor);
577 dvd->vd_minor = NULL;
578 }
|