Print this page
7938 Port ZOL #3712 disable LBA weighting on files and SSDs


   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         }