Print this page
701 UNMAP support for COMSTAR
Contributed by: Sumit Gupta <sumit.gupta@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@nexenta.com>
Rich Lowe's comments


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.


  23  */
  24 
  25 #include <sys/conf.h>
  26 #include <sys/file.h>
  27 #include <sys/ddi.h>
  28 #include <sys/sunddi.h>
  29 #include <sys/modctl.h>
  30 #include <sys/scsi/scsi.h>
  31 #include <sys/scsi/impl/scsi_reset_notify.h>
  32 #include <sys/disp.h>
  33 #include <sys/byteorder.h>
  34 #include <sys/pathname.h>
  35 #include <sys/atomic.h>
  36 #include <sys/nvpair.h>
  37 #include <sys/fs/zfs.h>
  38 #include <sys/sdt.h>
  39 #include <sys/dkio.h>
  40 #include <sys/zfs_ioctl.h>
  41 
  42 #include <sys/stmf.h>


  66     uint32_t proxy_reg_arg_len);
  67 stmf_status_t sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg,
  68     uint32_t proxy_reg_arg_len);
  69 stmf_status_t sbd_proxy_msg(uint8_t *luid, void *proxy_arg,
  70     uint32_t proxy_arg_len, uint32_t type);
  71 int sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
  72     uint32_t *err_ret);
  73 int sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret);
  74 int sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret);
  75 int sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret,
  76     int no_register, sbd_lu_t **slr);
  77 int sbd_import_active_lu(sbd_import_lu_t *ilu, sbd_lu_t *sl, uint32_t *err_ret);
  78 int sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret);
  79 int sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret);
  80 int sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz,
  81     uint32_t *err_ret);
  82 int sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz,
  83     uint32_t *err_ret);
  84 int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
  85     sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret);
  86 char *sbd_get_zvol_name(sbd_lu_t *sl);

  87 sbd_status_t sbd_create_zfs_meta_object(sbd_lu_t *sl);
  88 sbd_status_t sbd_open_zfs_meta(sbd_lu_t *sl);
  89 sbd_status_t sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz,
  90     uint64_t off);
  91 sbd_status_t sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz,
  92     uint64_t off);
  93 sbd_status_t sbd_update_zfs_prop(sbd_lu_t *sl);
  94 int sbd_is_zvol(char *path);
  95 int sbd_zvolget(char *zvol_name, char **comstarprop);
  96 int sbd_zvolset(char *zvol_name, char *comstarprop);
  97 char sbd_ctoi(char c);
  98 void sbd_close_lu(sbd_lu_t *sl);


  99 
 100 static ldi_ident_t      sbd_zfs_ident;
 101 static stmf_lu_provider_t *sbd_lp;
 102 static sbd_lu_t         *sbd_lu_list = NULL;
 103 static kmutex_t         sbd_lock;
 104 static dev_info_t       *sbd_dip;
 105 static uint32_t         sbd_lu_count = 0;
 106 
 107 /* Global property settings for the logical unit */
 108 char sbd_vendor_id[]    = "SUN     ";
 109 char sbd_product_id[]   = "COMSTAR         ";
 110 char sbd_revision[]     = "1.0 ";
 111 char *sbd_mgmt_url = NULL;
 112 uint16_t sbd_mgmt_url_alloc_size = 0;
 113 krwlock_t sbd_global_prop_lock;
 114 
 115 static char sbd_name[] = "sbd";
 116 
 117 static struct cb_ops sbd_cb_ops = {
 118         sbd_open,                       /* open */


 431                         break;
 432                 }
 433                 ret = sbd_get_lu_props((sbd_lu_props_t *)ibuf,
 434                     iocd->stmf_ibuf_size, (sbd_lu_props_t *)obuf,
 435                     iocd->stmf_obuf_size, &iocd->stmf_error);
 436                 break;
 437         case SBD_IOCTL_GET_LU_LIST:
 438                 mutex_enter(&sbd_lock);
 439                 iocd->stmf_obuf_max_nentries = sbd_lu_count;
 440                 iocd->stmf_obuf_nentries = min((iocd->stmf_obuf_size >> 4),
 441                     sbd_lu_count);
 442                 for (nsl = sbd_lu_list, i = 0; nsl &&
 443                     (i < iocd->stmf_obuf_nentries); i++, nsl = nsl->sl_next) {
 444                         bcopy(nsl->sl_device_id + 4,
 445                             &(((uint8_t *)obuf)[i << 4]), 16);
 446                 }
 447                 mutex_exit(&sbd_lock);
 448                 ret = 0;
 449                 iocd->stmf_error = 0;
 450                 break;












 451         default:
 452                 ret = ENOTTY;
 453         }
 454 
 455         if (ret == 0) {
 456                 ret = stmf_copyout_iocdata(data, mode, iocd, obuf);
 457         } else if (iocd->stmf_error) {
 458                 (void) stmf_copyout_iocdata(data, mode, iocd, obuf);
 459         }
 460         if (obuf) {
 461                 kmem_free(obuf, iocd->stmf_obuf_size);
 462                 obuf = NULL;
 463         }
 464         if (ibuf) {
 465                 kmem_free(ibuf, iocd->stmf_ibuf_size);
 466                 ibuf = NULL;
 467         }
 468         kmem_free(iocd, sizeof (stmf_iocdata_t));
 469         return (ret);
 470 }


1355                 sli->sli_serial_offset =
1356                     (uintptr_t)p - (uintptr_t)sli->sli_buf;
1357                 sli->sli_flags |= SLI_SERIAL_VALID;
1358                 p += sli->sli_serial_size;
1359         }
1360         sli->sli_lu_size = sl->sl_lu_size;
1361         sli->sli_data_blocksize_shift = sl->sl_data_blocksize_shift;
1362         sli->sli_data_order = SMS_DATA_ORDER;
1363         bcopy(sl->sl_device_id, sli->sli_device_id, 20);
1364 
1365         sli->sli_sms_header.sms_size = sizeof (*sli) + s;
1366         sli->sli_sms_header.sms_id = SMS_ID_LU_INFO_1_1;
1367         sli->sli_sms_header.sms_data_order = SMS_DATA_ORDER;
1368 
1369         mutex_exit(&sl->sl_lock);
1370         ret = sbd_write_meta_section(sl, (sm_section_hdr_t *)sli);
1371         kmem_free(sli, sizeof (*sli) + s);
1372         return (ret);
1373 }
1374 































































1375 int
1376 sbd_populate_and_register_lu(sbd_lu_t *sl, uint32_t *err_ret)
1377 {
1378         stmf_lu_t *lu = sl->sl_lu;
1379         stmf_status_t ret;
1380 


1381         lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id;
1382         if (sl->sl_alias) {
1383                 lu->lu_alias = sl->sl_alias;
1384         } else {
1385                 lu->lu_alias = sl->sl_name;
1386         }
1387         if (sl->sl_access_state == SBD_LU_STANDBY) {
1388                 /* call set access state */
1389                 ret = stmf_set_lu_access(lu, STMF_LU_STANDBY);
1390                 if (ret != STMF_SUCCESS) {
1391                         *err_ret = SBD_RET_ACCESS_STATE_FAILED;
1392                         return (EIO);
1393                 }
1394         }
1395         /* set proxy_reg_cb_arg to meta filename */
1396         if (sl->sl_meta_filename) {
1397                 lu->lu_proxy_reg_arg = sl->sl_meta_filename;
1398                 lu->lu_proxy_reg_arg_len = strlen(sl->sl_meta_filename) + 1;
1399         } else {
1400                 lu->lu_proxy_reg_arg = sl->sl_data_filename;


3115         oslp->mlu_buf_size_needed = sz;
3116 
3117         if (sz > (oslp_sz - sizeof (*oslp) + 8)) {
3118                 *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE;
3119                 rw_exit(&sbd_global_prop_lock);
3120                 return (ENOMEM);
3121         }
3122 
3123         off = 0;
3124         if (sbd_mgmt_url) {
3125                 oslp->mlu_mgmt_url_valid = 1;
3126                 oslp->mlu_mgmt_url_off = off;
3127                 (void) strcpy((char *)&oslp->mlu_buf[off], sbd_mgmt_url);
3128                 off += strlen(sbd_mgmt_url) + 1;
3129         }
3130 
3131         rw_exit(&sbd_global_prop_lock);
3132         return (0);
3133 }
3134 








































3135 int
3136 sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
3137     sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret)
3138 {
3139         sbd_status_t sret;
3140         sbd_lu_t *sl = NULL;
3141         uint32_t sz;
3142         uint16_t off;
3143 
3144         if (islp->slp_input_guid) {
3145                 sret = sbd_find_and_lock_lu(islp->slp_guid, NULL,
3146                     SL_OP_LU_PROPS, &sl);
3147         } else {
3148                 ((char *)islp)[islp_sz - 1] = 0;
3149                 sret = sbd_find_and_lock_lu(NULL, islp->slp_buf,
3150                     SL_OP_LU_PROPS, &sl);
3151         }
3152         if (sret != SBD_SUCCESS) {
3153                 if (sret == SBD_BUSY) {
3154                         *err_ret = SBD_RET_LU_BUSY;


3605         if ((rc = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, KM_SLEEP))) {
3606                 goto out;
3607         }
3608 
3609         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
3610         (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name));
3611         zc->zc_nvlist_src = (uint64_t)(intptr_t)packed;
3612         zc->zc_nvlist_src_size = len;
3613         rc = ldi_ioctl(zfs_lh, ZFS_IOC_SET_PROP, (intptr_t)zc,
3614             FKIOCTL, kcred, &unused);
3615         if (rc != 0) {
3616                 cmn_err(CE_NOTE, "ioctl failed %d", rc);
3617         }
3618         kmem_free(zc, sizeof (zfs_cmd_t));
3619         if (packed)
3620                 kmem_free(packed, len);
3621 out:
3622         nvlist_free(nv);
3623         (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3624         return (rc);




















































































3625 }


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #include <sys/conf.h>
  28 #include <sys/file.h>
  29 #include <sys/ddi.h>
  30 #include <sys/sunddi.h>
  31 #include <sys/modctl.h>
  32 #include <sys/scsi/scsi.h>
  33 #include <sys/scsi/impl/scsi_reset_notify.h>
  34 #include <sys/disp.h>
  35 #include <sys/byteorder.h>
  36 #include <sys/pathname.h>
  37 #include <sys/atomic.h>
  38 #include <sys/nvpair.h>
  39 #include <sys/fs/zfs.h>
  40 #include <sys/sdt.h>
  41 #include <sys/dkio.h>
  42 #include <sys/zfs_ioctl.h>
  43 
  44 #include <sys/stmf.h>


  68     uint32_t proxy_reg_arg_len);
  69 stmf_status_t sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg,
  70     uint32_t proxy_reg_arg_len);
  71 stmf_status_t sbd_proxy_msg(uint8_t *luid, void *proxy_arg,
  72     uint32_t proxy_arg_len, uint32_t type);
  73 int sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
  74     uint32_t *err_ret);
  75 int sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret);
  76 int sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret);
  77 int sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret,
  78     int no_register, sbd_lu_t **slr);
  79 int sbd_import_active_lu(sbd_import_lu_t *ilu, sbd_lu_t *sl, uint32_t *err_ret);
  80 int sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret);
  81 int sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret);
  82 int sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz,
  83     uint32_t *err_ret);
  84 int sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz,
  85     uint32_t *err_ret);
  86 int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
  87     sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret);
  88 static int sbd_get_unmap_props(sbd_unmap_props_t *sup, sbd_unmap_props_t *osup,
  89     uint32_t *err_ret);
  90 sbd_status_t sbd_create_zfs_meta_object(sbd_lu_t *sl);
  91 sbd_status_t sbd_open_zfs_meta(sbd_lu_t *sl);
  92 sbd_status_t sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz,
  93     uint64_t off);
  94 sbd_status_t sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz,
  95     uint64_t off);
  96 sbd_status_t sbd_update_zfs_prop(sbd_lu_t *sl);
  97 int sbd_is_zvol(char *path);
  98 int sbd_zvolget(char *zvol_name, char **comstarprop);
  99 int sbd_zvolset(char *zvol_name, char *comstarprop);
 100 char sbd_ctoi(char c);
 101 void sbd_close_lu(sbd_lu_t *sl);
 102 static nvlist_t *sbd_zvol_get_props(char *zvol_name);
 103 static int sbd_zvol_set_props(char *zvol_name, nvlist_t *nv);
 104 
 105 static ldi_ident_t      sbd_zfs_ident;
 106 static stmf_lu_provider_t *sbd_lp;
 107 static sbd_lu_t         *sbd_lu_list = NULL;
 108 static kmutex_t         sbd_lock;
 109 static dev_info_t       *sbd_dip;
 110 static uint32_t         sbd_lu_count = 0;
 111 
 112 /* Global property settings for the logical unit */
 113 char sbd_vendor_id[]    = "SUN     ";
 114 char sbd_product_id[]   = "COMSTAR         ";
 115 char sbd_revision[]     = "1.0 ";
 116 char *sbd_mgmt_url = NULL;
 117 uint16_t sbd_mgmt_url_alloc_size = 0;
 118 krwlock_t sbd_global_prop_lock;
 119 
 120 static char sbd_name[] = "sbd";
 121 
 122 static struct cb_ops sbd_cb_ops = {
 123         sbd_open,                       /* open */


 436                         break;
 437                 }
 438                 ret = sbd_get_lu_props((sbd_lu_props_t *)ibuf,
 439                     iocd->stmf_ibuf_size, (sbd_lu_props_t *)obuf,
 440                     iocd->stmf_obuf_size, &iocd->stmf_error);
 441                 break;
 442         case SBD_IOCTL_GET_LU_LIST:
 443                 mutex_enter(&sbd_lock);
 444                 iocd->stmf_obuf_max_nentries = sbd_lu_count;
 445                 iocd->stmf_obuf_nentries = min((iocd->stmf_obuf_size >> 4),
 446                     sbd_lu_count);
 447                 for (nsl = sbd_lu_list, i = 0; nsl &&
 448                     (i < iocd->stmf_obuf_nentries); i++, nsl = nsl->sl_next) {
 449                         bcopy(nsl->sl_device_id + 4,
 450                             &(((uint8_t *)obuf)[i << 4]), 16);
 451                 }
 452                 mutex_exit(&sbd_lock);
 453                 ret = 0;
 454                 iocd->stmf_error = 0;
 455                 break;
 456         case SBD_IOCTL_GET_UNMAP_PROPS:
 457                 if (iocd->stmf_ibuf_size < sizeof (sbd_unmap_props_t)) {
 458                         ret = EFAULT;
 459                         break;
 460                 }
 461                 if (iocd->stmf_obuf_size < sizeof (sbd_unmap_props_t)) {
 462                         ret = EINVAL;
 463                         break;
 464                 }
 465                 ret = sbd_get_unmap_props((sbd_unmap_props_t *)ibuf,
 466                     (sbd_unmap_props_t *)obuf, &iocd->stmf_error);
 467                 break;
 468         default:
 469                 ret = ENOTTY;
 470         }
 471 
 472         if (ret == 0) {
 473                 ret = stmf_copyout_iocdata(data, mode, iocd, obuf);
 474         } else if (iocd->stmf_error) {
 475                 (void) stmf_copyout_iocdata(data, mode, iocd, obuf);
 476         }
 477         if (obuf) {
 478                 kmem_free(obuf, iocd->stmf_obuf_size);
 479                 obuf = NULL;
 480         }
 481         if (ibuf) {
 482                 kmem_free(ibuf, iocd->stmf_ibuf_size);
 483                 ibuf = NULL;
 484         }
 485         kmem_free(iocd, sizeof (stmf_iocdata_t));
 486         return (ret);
 487 }


1372                 sli->sli_serial_offset =
1373                     (uintptr_t)p - (uintptr_t)sli->sli_buf;
1374                 sli->sli_flags |= SLI_SERIAL_VALID;
1375                 p += sli->sli_serial_size;
1376         }
1377         sli->sli_lu_size = sl->sl_lu_size;
1378         sli->sli_data_blocksize_shift = sl->sl_data_blocksize_shift;
1379         sli->sli_data_order = SMS_DATA_ORDER;
1380         bcopy(sl->sl_device_id, sli->sli_device_id, 20);
1381 
1382         sli->sli_sms_header.sms_size = sizeof (*sli) + s;
1383         sli->sli_sms_header.sms_id = SMS_ID_LU_INFO_1_1;
1384         sli->sli_sms_header.sms_data_order = SMS_DATA_ORDER;
1385 
1386         mutex_exit(&sl->sl_lock);
1387         ret = sbd_write_meta_section(sl, (sm_section_hdr_t *)sli);
1388         kmem_free(sli, sizeof (*sli) + s);
1389         return (ret);
1390 }
1391 
1392 /*
1393  * Will scribble SL_UNMAP_ENABLED into sl_flags if we succeed.
1394  */
1395 static void
1396 do_unmap_setup(sbd_lu_t *sl)
1397 {
1398         char *file = NULL;
1399         nvlist_t *nv = NULL, *nv2 = NULL;
1400         boolean_t already_compressing = B_FALSE;
1401         uint64_t val;
1402 
1403         ASSERT((sl->sl_flags & SL_UNMAP_ENABLED) == 0);
1404 
1405         if ((sl->sl_flags & SL_ZFS_META) == 0)
1406                 return; /* No UNMAP for you. */
1407 
1408         file = sbd_get_zvol_name(sl);
1409         if (file == NULL) {
1410                 cmn_err(CE_WARN, "sbd has zfs meta but no zvol name");
1411                 return; /* No UNMAP for you. */
1412         }
1413         nv = sbd_zvol_get_props(file);
1414         if (nv == NULL) {
1415                 cmn_err(CE_WARN, "unable to get zvol props");
1416                 kmem_free(file, strlen(file) + 1);
1417                 return; /* No UNMAP for you. */
1418         }
1419 
1420         /* See if compression is supported, but turned off on this dataset. */
1421         if (nvlist_lookup_nvlist(nv, "compression", &nv2) == 0 &&
1422             nvlist_lookup_uint64(nv2, ZPROP_VALUE, &val) == 0) {
1423                 already_compressing = (val != ZIO_COMPRESS_OFF);
1424         } else {
1425                 cmn_err(CE_WARN, "prop lookup for compression failed");
1426         }
1427 
1428         /*
1429          * Check refreservation because no refreservation means this is a
1430          * sparse zvol and we can enable SCSI unmap.
1431          */
1432         if (nvlist_lookup_nvlist(nv, "refreservation", &nv2) != 0) {
1433                 cmn_err(CE_WARN, "lookup for refreservation nvlist failed");
1434         } else if (nvlist_lookup_uint64(nv2, ZPROP_VALUE, &val) != 0) {
1435                 cmn_err(CE_WARN, "prop lookup for refreservation failed");
1436         } else if (val == 0) {
1437                 sl->sl_flags |= SL_UNMAP_ENABLED;
1438                 if (!already_compressing) {
1439                         nvlist_free(nv);
1440                         nv = NULL;
1441                         if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0 ||
1442                             nvlist_add_uint64(nv, "compression",
1443                             ZIO_COMPRESS_ZLE) != 0 ||
1444                             sbd_zvol_set_props(file, nv)) {
1445                                 cmn_err(CE_WARN, "Setting zle compression "
1446                                     "failed for zvol %s", file);
1447                         }
1448                 }
1449         }
1450 
1451         nvlist_free(nv);
1452         kmem_free(file, strlen(file) + 1);
1453 }
1454 
1455 int
1456 sbd_populate_and_register_lu(sbd_lu_t *sl, uint32_t *err_ret)
1457 {
1458         stmf_lu_t *lu = sl->sl_lu;
1459         stmf_status_t ret;
1460 
1461         do_unmap_setup(sl);
1462 
1463         lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id;
1464         if (sl->sl_alias) {
1465                 lu->lu_alias = sl->sl_alias;
1466         } else {
1467                 lu->lu_alias = sl->sl_name;
1468         }
1469         if (sl->sl_access_state == SBD_LU_STANDBY) {
1470                 /* call set access state */
1471                 ret = stmf_set_lu_access(lu, STMF_LU_STANDBY);
1472                 if (ret != STMF_SUCCESS) {
1473                         *err_ret = SBD_RET_ACCESS_STATE_FAILED;
1474                         return (EIO);
1475                 }
1476         }
1477         /* set proxy_reg_cb_arg to meta filename */
1478         if (sl->sl_meta_filename) {
1479                 lu->lu_proxy_reg_arg = sl->sl_meta_filename;
1480                 lu->lu_proxy_reg_arg_len = strlen(sl->sl_meta_filename) + 1;
1481         } else {
1482                 lu->lu_proxy_reg_arg = sl->sl_data_filename;


3197         oslp->mlu_buf_size_needed = sz;
3198 
3199         if (sz > (oslp_sz - sizeof (*oslp) + 8)) {
3200                 *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE;
3201                 rw_exit(&sbd_global_prop_lock);
3202                 return (ENOMEM);
3203         }
3204 
3205         off = 0;
3206         if (sbd_mgmt_url) {
3207                 oslp->mlu_mgmt_url_valid = 1;
3208                 oslp->mlu_mgmt_url_off = off;
3209                 (void) strcpy((char *)&oslp->mlu_buf[off], sbd_mgmt_url);
3210                 off += strlen(sbd_mgmt_url) + 1;
3211         }
3212 
3213         rw_exit(&sbd_global_prop_lock);
3214         return (0);
3215 }
3216 
3217 static int
3218 sbd_get_unmap_props(sbd_unmap_props_t *sup,
3219     sbd_unmap_props_t *osup, uint32_t *err_ret)
3220 {
3221         sbd_status_t sret;
3222         sbd_lu_t *sl = NULL;
3223 
3224         if (sup->sup_guid_valid) {
3225                 sret = sbd_find_and_lock_lu(sup->sup_guid,
3226                     NULL, SL_OP_LU_PROPS, &sl);
3227         } else {
3228                 sret = sbd_find_and_lock_lu(NULL,
3229                     (uint8_t *)sup->sup_zvol_path, SL_OP_LU_PROPS,
3230                     &sl);
3231         }
3232         if (sret != SBD_SUCCESS) {
3233                 if (sret == SBD_BUSY) {
3234                         *err_ret = SBD_RET_LU_BUSY;
3235                         return (EBUSY);
3236                 } else if (sret == SBD_NOT_FOUND) {
3237                         *err_ret = SBD_RET_NOT_FOUND;
3238                         return (ENOENT);
3239                 }
3240                 return (EIO);
3241         }
3242 
3243         sup->sup_found_lu = 1;
3244         sup->sup_guid_valid = 1;
3245         bcopy(sl->sl_device_id + 4, sup->sup_guid, 16);
3246         if (sl->sl_flags & SL_UNMAP_ENABLED)
3247                 sup->sup_unmap_enabled = 1;
3248         else
3249                 sup->sup_unmap_enabled = 0;
3250 
3251         *osup = *sup;
3252         sl->sl_trans_op = SL_OP_NONE;
3253 
3254         return (0);
3255 }
3256 
3257 int
3258 sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
3259     sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret)
3260 {
3261         sbd_status_t sret;
3262         sbd_lu_t *sl = NULL;
3263         uint32_t sz;
3264         uint16_t off;
3265 
3266         if (islp->slp_input_guid) {
3267                 sret = sbd_find_and_lock_lu(islp->slp_guid, NULL,
3268                     SL_OP_LU_PROPS, &sl);
3269         } else {
3270                 ((char *)islp)[islp_sz - 1] = 0;
3271                 sret = sbd_find_and_lock_lu(NULL, islp->slp_buf,
3272                     SL_OP_LU_PROPS, &sl);
3273         }
3274         if (sret != SBD_SUCCESS) {
3275                 if (sret == SBD_BUSY) {
3276                         *err_ret = SBD_RET_LU_BUSY;


3727         if ((rc = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, KM_SLEEP))) {
3728                 goto out;
3729         }
3730 
3731         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
3732         (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name));
3733         zc->zc_nvlist_src = (uint64_t)(intptr_t)packed;
3734         zc->zc_nvlist_src_size = len;
3735         rc = ldi_ioctl(zfs_lh, ZFS_IOC_SET_PROP, (intptr_t)zc,
3736             FKIOCTL, kcred, &unused);
3737         if (rc != 0) {
3738                 cmn_err(CE_NOTE, "ioctl failed %d", rc);
3739         }
3740         kmem_free(zc, sizeof (zfs_cmd_t));
3741         if (packed)
3742                 kmem_free(packed, len);
3743 out:
3744         nvlist_free(nv);
3745         (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3746         return (rc);
3747 }
3748 
3749 static nvlist_t *
3750 sbd_zvol_get_props(char *zvol_name)
3751 {
3752         ldi_handle_t    zfs_lh;
3753         nvlist_t        *nv = NULL;
3754         zfs_cmd_t       *zc;
3755         int size = 4096;
3756         int unused;
3757         int rc;
3758 
3759         if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred,
3760             &zfs_lh, sbd_zfs_ident)) != 0) {
3761                 cmn_err(CE_WARN, "ldi_open %d", rc);
3762                 return (NULL);
3763         }
3764 
3765         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
3766         (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name));
3767 szg_again:
3768         zc->zc_nvlist_dst = (uint64_t)(intptr_t)kmem_alloc(size,
3769             KM_SLEEP);
3770         zc->zc_nvlist_dst_size = size;
3771         rc = ldi_ioctl(zfs_lh, ZFS_IOC_OBJSET_STATS, (intptr_t)zc,
3772             FKIOCTL, kcred, &unused);
3773         /*
3774          * ENOMEM means the list is larger than what we've allocated
3775          * ldi_ioctl will fail with ENOMEM only once
3776          */
3777         if (rc == ENOMEM) {
3778                 int newsize;
3779                 newsize = zc->zc_nvlist_dst_size;
3780                 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
3781                 size = newsize;
3782                 goto szg_again;
3783         } else if (rc != 0) {
3784                 goto szg_out;
3785         }
3786         rc = nvlist_unpack((char *)(uintptr_t)zc->zc_nvlist_dst,
3787             zc->zc_nvlist_dst_size, &nv, 0);
3788         ASSERT(rc == 0);        /* nvlist_unpack should not fail */
3789 szg_out:
3790         kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size);
3791         kmem_free(zc, sizeof (zfs_cmd_t));
3792         (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3793 
3794         return (nv);
3795 }
3796 
3797 static int
3798 sbd_zvol_set_props(char *zvol_name, nvlist_t *nv)
3799 {
3800         ldi_handle_t    zfs_lh;
3801         char            *packed = NULL;
3802         size_t          len;
3803         zfs_cmd_t       *zc;
3804         int unused;
3805         int rc;
3806 
3807         if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred,
3808             &zfs_lh, sbd_zfs_ident)) != 0) {
3809                 cmn_err(CE_WARN, "ldi_open %d", rc);
3810                 return (ENXIO);
3811         }
3812         if ((rc = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, KM_SLEEP))) {
3813                 goto szs_out;
3814         }
3815 
3816         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
3817         (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name));
3818         zc->zc_nvlist_src = (uint64_t)(intptr_t)packed;
3819         zc->zc_nvlist_src_size = len;
3820         rc = ldi_ioctl(zfs_lh, ZFS_IOC_SET_PROP, (intptr_t)zc,
3821             FKIOCTL, kcred, &unused);
3822         if (rc != 0) {
3823                 cmn_err(CE_NOTE, "ioctl failed %d", rc);
3824         }
3825         kmem_free(zc, sizeof (zfs_cmd_t));
3826         if (packed)
3827                 kmem_free(packed, len);
3828 szs_out:
3829         (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred);
3830         return (rc);
3831 }