/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <sys/sysmacros.h>
#include <sys/byteorder.h>
#include <sys/pathname.h>
#include <sys/zfs_ioctl.h>
#include <sys/stmf_ioctl.h>
#include <sys/stmf_sbd_ioctl.h>
#include "stmf_sbd.h"
#include "sbd_impl.h"
void **result);
static char *sbd_get_zvol_name(sbd_lu_t *);
int sbd_is_zvol(char *path);
char sbd_ctoi(char c);
/* Global property settings for the logical unit */
sbd_open, /* open */
sbd_close, /* close */
nodev, /* strategy */
nodev, /* print */
nodev, /* dump */
nodev, /* read */
nodev, /* write */
stmf_sbd_ioctl, /* ioctl */
nodev, /* devmap */
nodev, /* mmap */
nodev, /* segmap */
nochpoll, /* chpoll */
ddi_prop_op, /* cb_prop_op */
0, /* streamtab */
CB_REV, /* rev */
nodev, /* aread */
nodev /* awrite */
};
0,
nulldev, /* identify */
nulldev, /* probe */
nodev, /* reset */
NULL, /* bus_ops */
NULL /* power */
};
};
&modldrv,
};
int
_init(void)
{
int ret;
if (ret)
return (ret);
0, 0);
sbd_lp->lp_instance = 0;
(void) mod_remove(&modlinkage);
return (EINVAL);
}
return (0);
}
int
_fini(void)
{
int ret;
/*
* If we have registered lus, then make sure they are all offline
* if so then deregister them. This should drop the sbd_lu_count
* to zero.
*/
if (sbd_lu_count) {
/* See if all of them are offline */
return (EBUSY);
}
}
#if 0
/* ok start deregistering them */
while (sbd_lu_list) {
return (EBUSY);
}
#endif
return (EBUSY);
}
return (EBUSY);
if (ret != 0) {
(void) stmf_register_lu_provider(sbd_lp);
return (ret);
}
return (0);
}
int
{
}
/* ARGSUSED */
static int
{
switch (cmd) {
case DDI_INFO_DEVT2DEVINFO:
break;
case DDI_INFO_DEVT2INSTANCE:
break;
default:
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
static int
{
switch (cmd) {
case DDI_ATTACH:
DDI_NT_STMF_LP, 0) != DDI_SUCCESS) {
break;
}
return (DDI_SUCCESS);
}
return (DDI_FAILURE);
}
static int
{
switch (cmd) {
case DDI_DETACH:
ddi_remove_minor_node(dip, 0);
return (DDI_SUCCESS);
}
return (DDI_FAILURE);
}
/* ARGSUSED */
static int
{
return (EINVAL);
return (0);
}
/* ARGSUSED */
static int
{
return (0);
}
/* ARGSUSED */
static int
{
int i;
int ret;
return (EPERM);
}
if (ret)
return (ret);
iocd->stmf_error = 0;
switch (cmd) {
if (iocd->stmf_ibuf_size <
(sizeof (sbd_create_and_reg_lu_t) - 8)) {
break;
}
if ((iocd->stmf_obuf_size == 0) ||
break;
}
break;
case SBD_IOCTL_SET_LU_STANDBY:
break;
}
if (iocd->stmf_obuf_size) {
break;
}
&iocd->stmf_error);
break;
case SBD_IOCTL_IMPORT_LU:
if (iocd->stmf_ibuf_size <
(sizeof (sbd_import_lu_t) - 8)) {
break;
}
if ((iocd->stmf_obuf_size == 0) ||
break;
}
break;
case SBD_IOCTL_DELETE_LU:
break;
}
if (iocd->stmf_obuf_size) {
break;
}
break;
case SBD_IOCTL_MODIFY_LU:
break;
}
if (iocd->stmf_obuf_size) {
break;
}
break;
case SBD_IOCTL_SET_GLOBAL_LU:
break;
}
if (iocd->stmf_obuf_size) {
break;
}
break;
case SBD_IOCTL_GET_GLOBAL_LU:
if (iocd->stmf_ibuf_size) {
break;
}
break;
}
break;
case SBD_IOCTL_GET_LU_PROPS:
break;
}
break;
}
break;
case SBD_IOCTL_GET_LU_LIST:
}
ret = 0;
iocd->stmf_error = 0;
break;
break;
}
break;
}
break;
default:
}
if (ret == 0) {
} else if (iocd->stmf_error) {
}
if (obuf) {
}
if (ibuf) {
}
return (ret);
}
/* ARGSUSED */
void
{
char *s;
int iret;
return;
}
return;
}
ilu_sz = 1024;
continue;
}
if (nvpair_value_string(np, &s) != 0) {
continue;
}
}
if (iret) {
stmf_trace(0, "sbd_lp_cb: import_lu failed, ret = %d, "
} else {
}
}
if (ilu) {
}
}
{
return (SBD_ALREADY);
}
break;
}
if (nsl) {
return (SBD_ALREADY);
}
sbd_lu_list = sl;
return (SBD_SUCCESS);
}
void
{
break;
}
}
{
int found = 0;
if (guid) {
} else {
}
if (found)
break;
}
if (!found) {
return (SBD_NOT_FOUND);
}
sret = SBD_SUCCESS;
} else {
}
return (sret);
}
{
int vret;
} else {
}
}
return (SBD_SUCCESS);
}
(~meta_align);
}
}
/*
* Don't proceed if the device has been closed
* This can occur on an access state change to standby or
* a delete. The writer lock is acquired before closing the
* lu. If importing, reading the metadata is valid, hence
* the check on SL_OP_IMPORT_LU.
*/
goto sbd_read_meta_failure;
}
starting_off)) != SBD_SUCCESS) {
goto sbd_read_meta_failure;
}
} else {
goto sbd_read_meta_failure;
}
}
ret = SBD_SUCCESS;
return (ret);
}
{
int vret;
} else {
}
}
if (ret != SBD_SUCCESS) {
goto sbd_write_meta_failure;
}
/*
* Don't proceed if the device has been closed
* This can occur on an access state change to standby or
* a delete. The writer lock is acquired before closing the
* lu. If importing, reading the metadata is valid, hence
* the check on SL_OP_IMPORT_LU.
*/
goto sbd_write_meta_failure;
}
starting_off)) != SBD_SUCCESS) {
goto sbd_write_meta_failure;
}
} else {
goto sbd_write_meta_failure;
}
}
ret = SBD_SUCCESS;
return (ret);
}
{
uint8_t s = 0;
while (size > 0)
return (s);
}
{
uint8_t s, o;
o = sm->sms_chksum;
sm->sms_chksum = 0;
sm->sms_chksum = o;
return (s);
}
{
uint32_t i;
for (i = 0; i < maxlen; i++) {
if (str[i] == 0)
return (i);
}
return (i);
}
void
{
return;
}
void
{
return;
}
void
{
return;
}
void
{
return;
}
{
(uint8_t *)&h)) != SBD_SUCCESS) {
return (ret);
}
if (h.sms_data_order != SMS_DATA_ORDER) {
sbd_swap_section_hdr(&h);
}
if ((h.sms_data_order != SMS_DATA_ORDER) ||
return (SBD_META_CORRUPTED);
}
return (SBD_SUCCESS);
}
}
return (SBD_NOT_FOUND);
}
{
/* Fake meta params initially */
if (ret != SBD_SUCCESS) {
goto load_meta_start_failed;
}
}
goto load_meta_start_failed;
}
goto load_meta_start_failed;
}
ret = SBD_SUCCESS;
return (ret);
}
{
KM_SLEEP);
return (ret);
}
{
int alloced = 0;
return (ret);
} else {
alloced = 1;
}
}
}
if (ret == SBD_SUCCESS) {
uint8_t s;
if (s != (*ppsms)->sms_chksum)
}
}
return (ret);
}
{
/*
* Bypass buffering and re-read the meta data from permanent storage.
*/
return (ret);
}
}
/* Re-get the meta sizes into sl */
return (ret);
}
}
{
int meta_size_changed = 0;
if (sms->sms_offset) {
/*
* If the section already exists and the size is the
* same as this new data then overwrite in place. If
* the sizes are different then mark the existing as
* unused and look for free space.
*/
(uint8_t *)&t);
if (ret != SBD_SUCCESS) {
return (ret);
}
if (t.sms_data_order != SMS_DATA_ORDER) {
sbd_swap_section_hdr(&t);
}
return (SBD_INVALID_ARG);
}
return (ret);
}
sms_before_unused = t;
t.sms_id = SMS_ID_UNUSED;
/*
* For unused sections we only use chksum of the header. for
* all other sections, the chksum is for the entire section.
*/
t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t));
(uint8_t *)&t);
if (ret != SBD_SUCCESS) {
return (ret);
}
sms->sms_offset = 0;
} else {
/* Section location is unknown, search for it. */
if (ret == SBD_SUCCESS) {
sms->sms_chksum =
goto write_meta_section_again;
} else if (ret != SBD_NOT_FOUND) {
return (ret);
}
}
/*
* At this point we know that section does not already exist.
* Find space large enough to hold the section or grow meta if
* possible.
*/
unused_start = 0;
s = 0; /* size of space found */
/*
* Search all sections for unused space of sufficient size.
* The first one found is taken. Contiguous unused sections
* will be combined.
*/
if (ret != SBD_SUCCESS) {
return (ret);
}
if (t.sms_data_order != SMS_DATA_ORDER)
sbd_swap_section_hdr(&t);
if (t.sms_size == 0) {
return (SBD_META_CORRUPTED);
}
if (t.sms_id == SMS_ID_UNUSED) {
if (unused_start == 0)
unused_start = off;
/*
* Calculate size of the unused space, break out
* if it satisfies the requirement.
*/
sizeof (t)))) {
break;
} else {
s = 0;
}
} else {
unused_start = 0;
}
}
/*
* If none found, how much room is at the end?
* See if the data can be expanded.
*/
if (s == 0) {
meta_size_changed = 1;
} else {
s = 0;
}
}
if (s == 0) {
return (SBD_ALLOC_FAILURE);
}
/*
* Since we may have to write more than one section (current +
* any unused), use a combined buffer.
*/
t.sms_id = SMS_ID_UNUSED;
t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t));
}
/*
* Two write events & statuses take place. Failure writing the
* meta section takes precedence, can possibly be rolled back,
* & gets reported. Else return status from writing the meta start.
*/
if (meta_size_changed) {
if (write_meta_ret == SBD_SUCCESS) {
(((uint64_t)1) <<
(~meta_align);
}
if (ret != SBD_SUCCESS) {
}
} else {
}
} else {
}
if ((write_meta_ret != SBD_SUCCESS) &&
(sms_before_unused.sms_offset != 0)) {
/*
* On failure writing the meta section attempt to undo
* the change to unused.
* Re-read the meta data from permanent storage.
* The section id can't exist for undo to be possible.
* Read what should be the entire old section data and
* insure the old data's still present by validating
* against it's old checksum.
*/
goto done;
}
goto done;
}
}
goto done;
}
goto done;
}
goto done;
}
sizeof (sm_section_hdr_t)) !=
sizeof (sm_section_hdr_t))) {
goto done;
}
goto done;
}
}
done:
if (write_meta_ret != SBD_SUCCESS) {
return (write_meta_ret);
}
return (ret);
}
{
int s;
uint8_t *p;
s = sl->sl_serial_no_size;
if (sl->sl_data_filename) {
}
}
}
}
if (sl->sl_mgmt_url) {
}
}
}
}
if (sl->sl_mgmt_url) {
}
}
}
}
}
}
if (sl->sl_serial_no_size) {
p += sli->sli_serial_size;
}
return (ret);
}
/*
* Will scribble SL_UNMAP_ENABLED into sl_flags if we succeed.
*/
static void
{
return; /* No UNMAP for you. */
}
int
{
} else {
}
/* call set access state */
if (ret != STMF_SUCCESS) {
return (EIO);
}
}
/* set proxy_reg_cb_arg to meta filename */
if (sl->sl_meta_filename) {
} else {
}
stmf_trace(0, "Failed to register with framework, ret=%llx",
ret);
if (ret == STMF_ALREADY) {
}
return (EIO);
}
*err_ret = 0;
return (0);
}
int
{
int ret;
int flag;
int unused;
if (vp_valid) {
goto odf_over_open;
}
return (EINVAL);
}
return (ret);
}
return (EINVAL);
}
} else {
}
&sl->sl_data_vp, 0, 0)) != 0) {
return (ret);
}
goto odf_close_data_and_exit;
}
/*
* Its a zero byte block or char device. This cannot be
* a raw disk.
*/
goto odf_close_data_and_exit;
}
/* sl_data_readable size includes any metadata. */
nbits = 0;
}
/* nbits cannot be greater than 64 */
if (lu_size_valid) {
}
/*
* The expression below is correct only if nbits is
* positive and less than 64.
*/
goto odf_close_data_and_exit;
}
}
} else {
} else {
goto odf_close_data_and_exit;
}
} else {
}
}
goto odf_close_data_and_exit;
}
if (sl->sl_lu_size &
goto odf_close_data_and_exit;
}
/*
* Get the minor device for direct zvol access
*/
/* zvol reserves 0, so this would fail later */
sl->sl_zvol_minor = 0;
} else {
if (sbd_zvol_get_volume_params(sl) == 0)
}
}
return (0);
if (!keep_open) {
}
return (ret);
}
void
{
int flag;
if (sl->sl_zfs_meta) {
}
} else {
}
}
} else {
}
}
}
}
int
{
SL_OP_MODIFY_LU, &sl);
if (sret != SBD_SUCCESS) {
return (EBUSY);
} else if (sret == SBD_NOT_FOUND) {
return (ENOENT);
}
return (EIO);
}
if (stret != STMF_SUCCESS) {
return (EIO);
}
/*
* acquire the writer lock here to ensure we're not pulling
* the rug from the vn_rdwr to the backing store
*/
return (0);
}
int
{
/*
* acquire the writer lock here to ensure we're not pulling
* the rug from the vn_rdwr to the backing store
*/
if (sl->sl_serial_no_alloc_size) {
}
if (sl->sl_data_fname_alloc_size) {
}
if (sl->sl_alias_alloc_size) {
}
if (sl->sl_mgmt_url_alloc_size) {
}
return (ret);
}
int
{
char *namebuf;
char *p;
int sz;
int alloc_sz;
int flag;
int wcd = 0;
*err_ret = 0;
/* Lets validate various offsets */
if (((slu->slu_meta_fname_valid) &&
((slu->slu_alias_valid) &&
((slu->slu_mgmt_url_valid) &&
((slu->slu_serial_valid) &&
return (EINVAL);
}
if (slu->slu_meta_fname_valid) {
}
if (slu->slu_alias_valid) {
}
if (slu->slu_mgmt_url_valid) {
}
if (slu->slu_serial_valid) {
}
return (ENOMEM);
}
sl->sl_data_filename = p;
if (slu->slu_meta_fname_valid) {
} else {
sl->sl_meta_offset = 0;
} else {
sl->sl_meta_size_used = 0;
}
}
if (slu->slu_alias_valid) {
}
if (slu->slu_mgmt_url_valid) {
sl->sl_mgmt_url = p;
}
if (slu->slu_serial_valid) {
p += slu->slu_serial_size;
}
if (slu->slu_vid_valid) {
}
if (slu->slu_pid_valid) {
}
if (slu->slu_rev_valid) {
}
if (slu->slu_write_protected) {
}
if (slu->slu_blksize_valid) {
(slu->slu_blksize == 0)) {
goto scm_err_out;
}
}
} else {
}
/* Now lets start creating meta */
goto scm_err_out;
}
/* 1st focus on the data store */
if (slu->slu_lu_size_valid) {
}
if (ret) {
goto scm_err_out;
}
/*
* cache on the device, otherwise get current device setting.
*/
if (slu->slu_writeback_cache_disable_valid) {
if (slu->slu_writeback_cache_disable) {
/*
* Set write cache disable on the device. If it fails,
*/
wcd = 1;
} else {
/*
* Set write cache enable on the device. If it fails,
* return an error.
*/
goto scm_err_out;
}
}
} else {
}
if (wcd) {
}
goto over_meta_open;
}
goto scm_err_out;
}
sl->sl_meta_blocksize_shift = 0;
goto over_meta_create;
}
goto scm_err_out;
}
goto scm_err_out;
}
sl->sl_meta_blocksize_shift = 0;
} else {
}
&sl->sl_meta_vp, 0, 0)) != 0) {
goto scm_err_out;
}
sl->sl_total_meta_size +=
sl->sl_total_meta_size &=
sl->sl_meta_size_used = 0;
if (slu->slu_guid_valid) {
} else {
if (slu->slu_host_id_valid)
if (!slu->slu_company_id_valid)
STMF_SUCCESS) {
goto scm_err_out;
}
}
/* Lets create the meta now */
sizeof (sbd_meta_start_t)) != SBD_SUCCESS) {
goto scm_err_out;
}
goto scm_err_out;
}
goto scm_err_out;
}
/*
* Update the zvol separately as this need only be called upon
* completion of the metadata initialization.
*/
goto scm_err_out;
}
}
if (ret) {
goto scm_err_out;
}
return (0);
}
{
switch (type) {
case STMF_MSG_LU_ACTIVE:
case STMF_MSG_LU_REGISTER:
case STMF_MSG_LU_DEREGISTER:
default:
return (STMF_INVALID_ARG);
}
}
/*
* register a standby logical unit
* proxy_reg_arg contains the meta filename
*/
{
int alloc_sz;
return (STMF_INVALID_ARG);
}
do {
if (sret == SBD_NOT_FOUND) {
KM_SLEEP);
if (proxy_reg_arg_len) {
}
"Unable to create standby logical unit for %s",
}
return (stret);
} else if (sret == SBD_SUCCESS) {
/*
* if the lu is already registered, then the lu should now
* be in standby mode
*/
it->sbd_it_flags &=
}
}
} else {
}
out:
return (stret);
}
/* ARGSUSED */
{
return (STMF_INVALID_ARG);
}
return (STMF_FAILURE);
}
return (STMF_SUCCESS);
}
int
{
int alloc_sz;
return (ENOMEM);
}
sizeof (sbd_pgr_t);
if (slu->stlu_meta_fname_size > 0) {
}
goto scs_err_out;
}
if (ret) {
goto scs_err_out;
}
return (0);
}
int
{
if (sret != SBD_SUCCESS) {
return (EIO);
}
return (EIO);
}
}
return (0);
}
int
{
int asz;
int ret = 0;
int flag;
int wcd = 0;
int data_opened;
int standby = 0;
return (EINVAL);
}
/*
* check whether logical unit is already registered ALUA
* For a standby logical unit, the meta filename is set. Use
* that to search for an existing logical unit.
*/
SL_OP_IMPORT_LU, &sl);
if (sret == SBD_SUCCESS) {
no_register = 1;
standby = 1;
if (sl->sl_alias_alloc_size) {
sl->sl_alias_alloc_size = 0;
}
} else if (sl->sl_data_fname_alloc_size) {
sl->sl_data_fname_alloc_size = 0;
}
if (sl->sl_serial_no_alloc_size) {
sl->sl_serial_no_alloc_size = 0;
}
if (sl->sl_mgmt_url_alloc_size) {
sl->sl_mgmt_url_alloc_size = 0;
}
} else {
return (EALREADY);
}
} else if (sret == SBD_NOT_FOUND) {
return (ENOMEM);
}
sizeof (sbd_pgr_t);
} else {
return (EIO);
}
/* we're only loading the metadata */
if (!no_register) {
goto sim_err_out;
}
}
goto sim_err_out;
}
}
goto sim_err_out;
}
/* let see if metadata is in the 64k block */
}
}
/* metadata is always writable */
&sl->sl_meta_vp, 0, 0)) != 0) {
goto sim_err_out;
}
}
sl->sl_meta_blocksize_shift = 0;
} else {
}
if (sret != SBD_SUCCESS) {
if (sret == SBD_META_CORRUPTED) {
} else if (sret == SBD_NOT_SUPPORTED) {
} else {
}
goto sim_err_out;
}
/* Now lets see if we can read the most recent LU info */
if (ret) {
goto sim_err_out;
}
goto sim_sli_loaded;
}
if (sret != SBD_SUCCESS) {
goto sim_err_out;
}
/* load sli 1.1 */
goto sim_err_out;
}
}
sizeof (sbd_lu_info_1_1_t) + 8;
sli_buf_copy[sli_buf_sz] = 0;
/* Make sure all the offsets are within limits */
goto sim_err_out;
}
}
}
} else {
sl->sl_data_offset = 0;
} else {
}
}
}
KM_SLEEP);
}
}
}
}
}
}
data_opened = 0;
} else {
data_opened = 1;
}
if (sret != SBD_SUCCESS) {
goto sim_err_out;
}
if (ret) {
goto sim_err_out;
}
/*
* set write cache disable on the device
* Note: this shouldn't fail on import unless the cache capabilities
* of the device changed. If that happened, modify will need to
* be used to set the cache flag appropriately after import is done.
*/
wcd = 1;
/*
* if not explicitly set, attempt to set it to enable, if that fails
* get the current setting and use that
*/
} else {
if (sret != SBD_SUCCESS) {
}
}
if (wcd) {
}
/* we're only loading the metadata */
if (!no_register) {
if (ret) {
goto sim_err_out;
}
}
if (sli) {
}
if (sli_buf_copy) {
sli_buf_copy = NULL;
}
if (no_register && !standby) {
}
/*
* if this was imported from standby, set the access state
* to active.
*/
if (standby) {
}
/* call set access state */
if (stret != STMF_SUCCESS) {
goto sim_err_out;
}
} else {
}
}
return (0);
if (sli) {
}
if (sli_buf_copy) {
sli_buf_copy = NULL;
}
if (standby) {
return (EIO);
} else {
}
}
int
{
int ret = 0;
int modify_unregistered = 0;
int ua = 0;
/* if there is data in the buf, null terminate it */
}
*err_ret = 0;
/* Lets validate offsets */
if (((mlu->mlu_alias_valid) &&
((mlu->mlu_mgmt_url_valid) &&
(mlu->mlu_by_fname) &&
return (EINVAL);
}
/*
* We'll look for the device but if we don't find it registered,
* we'll still try to modify the unregistered device.
*/
if (mlu->mlu_by_guid) {
SL_OP_MODIFY_LU, &sl);
} else if (mlu->mlu_by_fname) {
SL_OP_MODIFY_LU, &sl);
} else {
return (EINVAL);
}
if (sret != SBD_SUCCESS) {
return (EBUSY);
} else if (sret != SBD_NOT_FOUND) {
return (EIO);
} else if (!mlu->mlu_by_fname) {
return (EINVAL);
}
/* Okay, try to import the device */
+ 1);
if (ret != SBD_SUCCESS) {
return (ENOENT);
}
modify_unregistered = 1;
}
goto smm_err_out;
}
/* check for write cache change */
if (mlu->mlu_writeback_cache_disable_valid) {
/* set wce on device */
goto smm_err_out;
}
if (!mlu->mlu_writeback_cache_disable) {
ua = 1;
}
} else {
ua = 1;
}
}
}
}
ua = 0;
if (mlu->mlu_alias_valid) {
/*
* Use the allocated buffer or alloc a new one.
* Don't copy into sl_alias if sl_alias_alloc_size is 0
* filename.
*/
if (sl->sl_alias_alloc_size > 0 &&
sl->sl_alias_alloc_size = 0;
}
if (sl->sl_alias_alloc_size == 0) {
}
mlu->mlu_alias_off);
}
if (mlu->mlu_mgmt_url_valid) {
if (url_sz > 0)
url_sz++;
if (sl->sl_mgmt_url_alloc_size > 0 &&
sl->sl_mgmt_url_alloc_size = 0;
}
if (url_sz > 0) {
if (sl->sl_mgmt_url_alloc_size == 0) {
}
}
}
}
if (mlu->mlu_write_protected_valid) {
if (mlu->mlu_write_protected) {
ua = 1;
}
} else {
ua = 1;
}
}
}
}
if (mlu->mlu_lu_size_valid) {
/*
* validate lu size and set
* For open file only (registered lu)
*/
if (ret) {
goto smm_err_out;
}
}
}
}
}
if (modify_unregistered) {
(void) sbd_close_delete_lu(sl, 0);
} else {
}
return (ret);
}
int
{
int ret = 0;
/* if there is data in the buf, null terminate it */
}
*err_ret = 0;
/* Lets validate offsets */
if (((mlu->mlu_mgmt_url_valid) &&
return (EINVAL);
}
if (mlu->mlu_mgmt_url_valid) {
if (url_sz > 0)
url_sz++;
if (sbd_mgmt_url_alloc_size > 0 &&
sbd_mgmt_url = NULL;
}
if (url_sz > 0) {
if (sbd_mgmt_url_alloc_size == 0) {
}
}
/*
* check each lu to determine whether a UA is needed.
*/
if (sl->sl_mgmt_url) {
continue;
}
}
}
}
return (ret);
}
/* ARGSUSED */
int
{
int i;
!sl->sl_state_not_acked) {
goto sdl_do_dereg;
}
sl->sl_state_not_acked) {
return (EBUSY);
}
return (EBUSY);
}
for (i = 0; i < 500; i++) {
!sl->sl_state_not_acked) {
goto sdl_do_dereg;
}
}
return (EBUSY);
return (EBUSY);
return (sbd_close_delete_lu(sl, 0));
}
int
{
int ret;
if (dlu->dlu_by_meta_name) {
SL_OP_DELETE_LU, &sl);
} else {
SL_OP_DELETE_LU, &sl);
}
if (sret != SBD_SUCCESS) {
return (EBUSY);
} else if (sret == SBD_NOT_FOUND) {
return (ENOENT);
}
return (EIO);
}
if (ret) {
/* Once its locked, no need to grab mutex again */
}
return (ret);
}
{
int ret;
long resid;
return (SBD_IO_PAST_EOF);
}
return (SBD_SUCCESS);
}
}
scsi_task_t *, task);
/*
* Don't proceed if the device has been closed
* This can occur on an access state change to standby or
* a delete. The writer lock is acquired before closing the
* lu.
*/
return (SBD_FAILURE);
}
&resid);
resid);
return (SBD_FAILURE);
}
return (SBD_SUCCESS);
}
{
int ret;
long resid;
int ioflag;
return (SBD_IO_PAST_EOF);
}
} else {
ioflag = 0;
}
scsi_task_t *, task);
/*
* Don't proceed if the device has been closed
* This can occur on an access state change to standby or
* a delete. The writer lock is acquired before closing the
* lu.
*/
return (SBD_FAILURE);
}
&resid);
}
return (SBD_FAILURE);
do {
break;
}
return (SBD_SUCCESS);
}
int
{
if (sbd_mgmt_url) {
}
return (ENOMEM);
}
off = 0;
if (sbd_mgmt_url) {
}
return (0);
}
static int
{
if (sup->sup_guid_valid) {
} else {
&sl);
}
if (sret != SBD_SUCCESS) {
return (EBUSY);
} else if (sret == SBD_NOT_FOUND) {
return (ENOENT);
}
return (EIO);
}
else
sup->sup_unmap_enabled = 0;
return (0);
}
int
{
if (islp->slp_input_guid) {
SL_OP_LU_PROPS, &sl);
} else {
SL_OP_LU_PROPS, &sl);
}
if (sret != SBD_SUCCESS) {
return (EBUSY);
} else if (sret == SBD_NOT_FOUND) {
return (ENOENT);
}
return (EIO);
}
if (sl->sl_data_filename) {
}
}
}
if (sl->sl_mgmt_url) {
} else if (sbd_mgmt_url) {
}
return (ENOMEM);
}
off = 0;
if (sl->sl_data_filename) {
}
} else {
}
}
}
if (sl->sl_mgmt_url) {
} else if (sbd_mgmt_url) {
}
if (sl->sl_serial_no_size) {
}
} else {
}
} else {
}
} else {
}
return (0);
}
/*
* Returns an allocated string with the "<pool>/..." form of the zvol name.
*/
static char *
{
char *src;
char *p;
if (sl->sl_data_filename)
else
/* There has to be a better way */
if (SBD_IS_ZVOL(src) != 0) {
ASSERT(0);
}
if (*src == '/')
return (p);
}
/*
* this function creates a local metadata zvol property
*/
{
/*
* -allocate 1/2 the property size, the zfs property
* is 8k in size and stored as ascii hex string, all
* we needed is 4k buffer to store the binary data.
*/
== NULL)
return (SBD_FAILURE);
return (SBD_SUCCESS);
}
char
sbd_ctoi(char c)
{
if ((c >= '0') && (c <= '9'))
c -= '0';
else if ((c >= 'A') && (c <= 'F'))
c = c - 'A' + 10;
else if ((c >= 'a') && (c <= 'f'))
c = c - 'a' + 10;
else
c = -1;
return (c);
}
/*
* read zvol property and convert to binary
*/
{
int i;
int len;
char *file;
return (SBD_FAILURE);
} else {
}
rc = SBD_FAILURE;
goto done;
}
/* convert ascii hex to binary meta */
for (i = 0; i < len; i += 2) {
rc = SBD_FAILURE;
break;
}
}
done:
if (meta)
return (rc);
}
{
return (SBD_SUCCESS);
}
{
return (SBD_META_CORRUPTED);
}
meta_align) & (~meta_align);
}
}
/*
* During creation of a logical unit, sbd_update_zfs_prop will be
* called separately to avoid multiple calls as each meta section
* We only need to update the zvol once during create.
*/
return (sbd_update_zfs_prop(sl));
}
return (SBD_SUCCESS);
}
{
int i, num;
char *file;
/* convert local copy to ascii hex */
}
}
return (ret);
}
int
{
int is_zfs = 0;
if (SBD_IS_ZVOL(path) == 0)
is_zfs = 1;
return (is_zfs);
}
/*
* set write cache disable
* wcd - 1 = disable, 0 = enable
*/
{
/* translate to wce bit */
int ret;
goto done;
}
if (ret == 0) {
} else {
sret = SBD_FAILURE;
goto done;
}
done:
return (sret);
}
/*
* get write cache disable
* wcd - 1 = disable, 0 = enable
*/
void
{
int wce;
int ret;
*wcd = 0;
return;
}
/* if write cache get failed, assume disabled */
if (ret) {
*wcd = 1;
} else {
/* translate to wcd bit */
}
}
int
{
char *ptr;
int unused;
int rc;
&zfs_lh, sbd_zfs_ident)) != 0) {
return (ENXIO);
}
KM_SLEEP);
/*
* ENOMEM means the list is larger than what we've allocated
* ldi_ioctl will fail with ENOMEM only once
*/
int newsize;
goto again;
} else if (rc != 0) {
goto out;
}
if (rc != 0) {
} else {
KM_SLEEP);
}
}
out:
return (rc);
}
int
{
int unused;
int rc;
&zfs_lh, sbd_zfs_ident)) != 0) {
return (ENXIO);
}
goto out;
}
if (rc != 0) {
}
if (packed)
out:
return (rc);
}
/*
* Unmap a region in a volume. Currently only supported for zvols.
*/
int
{
int unused;
/* Right now, we only support UNMAP on zvols. */
return (EIO);
DF_WAIT_SYNC : 0;
/* Use the data vnode we have to send a fop_ioctl(). */
return (EIO);
}
}