Print this page
NEX-4433 Deadlock among txg_wait_synced(), sbd_pgr_remove_it_handle(), and ppt_sess_lookup_create() after HA failover
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-3111 Comstar does not pass cstyle and hdrchk
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Tony Nguyen <tony.nguyen@nexenta.com>
SUP-765 When a Windows Clustered Shared Volume is placed on a pool under Nexenta HA Cluster control the clustered shared disk looses its PGR3 reservation to the presented zvol.
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Tony Nguyen <tony.nguyen@nexenta.com>
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
Re #6790 backspace should perform delete on console
VAAI (XXX ATS support for COMSTAR, YYY Block-copy support for COMSTAR)
*** 18,27 ****
--- 18,29 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/atomic.h>
#include <sys/conf.h>
#include <sys/byteorder.h>
*** 37,47 ****
#include "stmf_sbd.h"
#include "sbd_impl.h"
#define MAX_PGR_PARAM_LIST_LENGTH (256 * 1024)
! int sbd_pgr_reservation_conflict(scsi_task_t *);
void sbd_pgr_reset(sbd_lu_t *);
void sbd_pgr_initialize_it(scsi_task_t *, sbd_it_data_t *);
void sbd_handle_pgr_in_cmd(scsi_task_t *, stmf_data_buf_t *);
void sbd_handle_pgr_out_cmd(scsi_task_t *, stmf_data_buf_t *);
void sbd_handle_pgr_out_data(scsi_task_t *, stmf_data_buf_t *);
--- 39,49 ----
#include "stmf_sbd.h"
#include "sbd_impl.h"
#define MAX_PGR_PARAM_LIST_LENGTH (256 * 1024)
! int sbd_pgr_reservation_conflict(scsi_task_t *, struct sbd_lu *sl);
void sbd_pgr_reset(sbd_lu_t *);
void sbd_pgr_initialize_it(scsi_task_t *, sbd_it_data_t *);
void sbd_handle_pgr_in_cmd(scsi_task_t *, stmf_data_buf_t *);
void sbd_handle_pgr_out_cmd(scsi_task_t *, stmf_data_buf_t *);
void sbd_handle_pgr_out_data(scsi_task_t *, stmf_data_buf_t *);
*** 80,89 ****
--- 82,92 ----
static void sbd_pgr_do_unregister(sbd_lu_t *, sbd_it_data_t *, sbd_pgr_key_t *);
static void sbd_pgr_do_release(sbd_lu_t *, sbd_it_data_t *, uint8_t);
static void sbd_pgr_do_reserve(sbd_pgr_t *, sbd_pgr_key_t *, sbd_it_data_t *it,
stmf_scsi_session_t *, scsi_cdb_prout_t *);
+ static boolean_t sbd_pgr_should_save(sbd_lu_t *);
extern sbd_status_t sbd_write_meta_section(sbd_lu_t *, sm_section_hdr_t *);
extern sbd_status_t sbd_read_meta_section(sbd_lu_t *, sm_section_hdr_t **,
uint16_t);
extern void sbd_swap_section_hdr(sm_section_hdr_t *);
extern void sbd_handle_short_write_transfers(scsi_task_t *task,
*** 293,302 ****
--- 296,321 ----
ret = sbd_write_meta_section(slu, (sm_section_hdr_t *)spi);
kmem_free(spi, sz);
return (ret);
}
+ /*
+ * Evaluate common cases where a PERSISTENT RESERVE OUT CDB handler should call
+ * sbd_pgr_meta_write().
+ */
+ static boolean_t
+ sbd_pgr_should_save(sbd_lu_t *slu)
+ {
+ sbd_pgr_t *pgr = slu->sl_pgr;
+
+ if (stmf_is_pgr_aptpl_always() == B_TRUE ||
+ (pgr->pgr_flags & (SBD_PGR_APTPL)))
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+ }
+
sbd_status_t
sbd_pgr_meta_load(sbd_lu_t *slu)
{
sbd_pgr_t *pgr = slu->sl_pgr;
sbd_pgr_info_t *spi = NULL;
*** 321,331 ****
if (spi->pgr_data_order != SMS_DATA_ORDER) {
sbd_swap_pgr_info(spi);
}
pgr->pgr_flags = spi->pgr_flags;
! if (pgr->pgr_flags & SBD_PGR_APTPL) {
pgr->pgr_rsv_type = spi->pgr_rsv_type;
pgr->pgr_rsv_scope = spi->pgr_rsv_scope;
} else {
PGR_CLEAR_RSV_FLAG(pgr->pgr_flags);
}
--- 340,355 ----
if (spi->pgr_data_order != SMS_DATA_ORDER) {
sbd_swap_pgr_info(spi);
}
pgr->pgr_flags = spi->pgr_flags;
! /*
! * We reload APTPL reservations when:
! * 1. Global override is enabled
! * 2. APTPL was explicitly asserted in the PERSISTENT RESERVE OUT CDB
! */
! if (stmf_is_pgr_aptpl_always() || (pgr->pgr_flags & SBD_PGR_APTPL)) {
pgr->pgr_rsv_type = spi->pgr_rsv_type;
pgr->pgr_rsv_scope = spi->pgr_rsv_scope;
} else {
PGR_CLEAR_RSV_FLAG(pgr->pgr_flags);
}
*** 411,420 ****
--- 435,445 ----
kmem_free(spi, spi->pgr_sms_header.sms_size);
return (ret);
sbd_pgr_meta_load_failed:
+ /* CSTYLED */
{
char *lun_name = sbd_get_devid_string(slu);
sbd_pgr_keylist_dealloc(slu);
kmem_free(spi, spi->pgr_sms_header.sms_size);
cmn_err(CE_WARN, "sbd_pgr_meta_load: Failed to load PGR meta data "
*** 434,444 ****
sbd_status_t ret = SBD_SUCCESS;
uint32_t sz, totalsz;
/* Calculate total pgr meta section size needed */
sz = sizeof (sbd_pgr_info_t);
! if (pgr->pgr_flags & SBD_PGR_APTPL) {
key = pgr->pgr_keylist;
while (key != NULL) {
sz = ALIGNED_TO_8BYTE_BOUNDARY(sz +
sizeof (sbd_pgr_key_info_t) - 1 +
key->pgr_key_lpt_len + key->pgr_key_rpt_len);
--- 459,469 ----
sbd_status_t ret = SBD_SUCCESS;
uint32_t sz, totalsz;
/* Calculate total pgr meta section size needed */
sz = sizeof (sbd_pgr_info_t);
! if ((pgr->pgr_flags & SBD_PGR_APTPL) || stmf_is_pgr_aptpl_always()) {
key = pgr->pgr_keylist;
while (key != NULL) {
sz = ALIGNED_TO_8BYTE_BOUNDARY(sz +
sizeof (sbd_pgr_key_info_t) - 1 +
key->pgr_key_lpt_len + key->pgr_key_rpt_len);
*** 456,466 ****
spi->pgr_sms_header.sms_size = totalsz;
spi->pgr_sms_header.sms_id = SMS_ID_PGR_INFO;
spi->pgr_sms_header.sms_data_order = SMS_DATA_ORDER;
! if (pgr->pgr_flags & SBD_PGR_APTPL) {
uint8_t *ptr;
key = pgr->pgr_keylist;
sz = sizeof (sbd_pgr_info_t);
while (key != NULL) {
spi_key = (sbd_pgr_key_info_t *)((uint8_t *)spi + sz);
--- 481,491 ----
spi->pgr_sms_header.sms_size = totalsz;
spi->pgr_sms_header.sms_id = SMS_ID_PGR_INFO;
spi->pgr_sms_header.sms_data_order = SMS_DATA_ORDER;
! if ((pgr->pgr_flags & SBD_PGR_APTPL) || stmf_is_pgr_aptpl_always()) {
uint8_t *ptr;
key = pgr->pgr_keylist;
sz = sizeof (sbd_pgr_info_t);
while (key != NULL) {
spi_key = (sbd_pgr_key_info_t *)((uint8_t *)spi + sz);
*** 482,493 ****
sizeof (sbd_pgr_key_info_t) - 1 +
key->pgr_key_lpt_len + key->pgr_key_rpt_len);
key = key->pgr_key_next;
}
}
!
ret = sbd_write_meta_section(slu, (sm_section_hdr_t *)spi);
kmem_free(spi, totalsz);
if (ret != SBD_SUCCESS) {
sbd_pgr_key_t *tmp_list;
tmp_list = pgr->pgr_keylist;
pgr->pgr_keylist = NULL;
--- 507,522 ----
sizeof (sbd_pgr_key_info_t) - 1 +
key->pgr_key_lpt_len + key->pgr_key_rpt_len);
key = key->pgr_key_next;
}
}
! rw_downgrade(&pgr->pgr_lock);
ret = sbd_write_meta_section(slu, (sm_section_hdr_t *)spi);
+ if (!rw_tryupgrade(&pgr->pgr_lock)) {
+ rw_exit(&pgr->pgr_lock);
+ rw_enter(&pgr->pgr_lock, RW_WRITER);
+ }
kmem_free(spi, totalsz);
if (ret != SBD_SUCCESS) {
sbd_pgr_key_t *tmp_list;
tmp_list = pgr->pgr_keylist;
pgr->pgr_keylist = NULL;
*** 576,586 ****
sbd_pgr_reset(sbd_lu_t *slu)
{
sbd_pgr_t *pgr = slu->sl_pgr;
rw_enter(&pgr->pgr_lock, RW_WRITER);
! if (!(pgr->pgr_flags & SBD_PGR_APTPL)) {
sbd_pgr_keylist_dealloc(slu);
pgr->pgr_PRgeneration = 0;
pgr->pgr_rsvholder = NULL;
pgr->pgr_rsv_type = 0;
pgr->pgr_flags = 0;
--- 605,616 ----
sbd_pgr_reset(sbd_lu_t *slu)
{
sbd_pgr_t *pgr = slu->sl_pgr;
rw_enter(&pgr->pgr_lock, RW_WRITER);
! if (!(pgr->pgr_flags & SBD_PGR_APTPL) &&
! stmf_is_pgr_aptpl_always() == B_FALSE) {
sbd_pgr_keylist_dealloc(slu);
pgr->pgr_PRgeneration = 0;
pgr->pgr_rsvholder = NULL;
pgr->pgr_rsv_type = 0;
pgr->pgr_flags = 0;
*** 810,822 ****
/*
* Check for any PGR Reservation conflict. return 0 if access allowed
*/
int
! sbd_pgr_reservation_conflict(scsi_task_t *task)
{
- sbd_lu_t *slu = (sbd_lu_t *)task->task_lu->lu_provider_private;
sbd_pgr_t *pgr = slu->sl_pgr;
sbd_it_data_t *it = (sbd_it_data_t *)task->task_lu_itl_handle;
/* If Registered */
if (pgr->pgr_flags & SBD_PGR_RSVD_ALL_REGISTRANTS && it->pgr_key_ptr)
--- 840,851 ----
/*
* Check for any PGR Reservation conflict. return 0 if access allowed
*/
int
! sbd_pgr_reservation_conflict(scsi_task_t *task, sbd_lu_t *slu)
{
sbd_pgr_t *pgr = slu->sl_pgr;
sbd_it_data_t *it = (sbd_it_data_t *)task->task_lu_itl_handle;
/* If Registered */
if (pgr->pgr_flags & SBD_PGR_RSVD_ALL_REGISTRANTS && it->pgr_key_ptr)
*** 1384,1394 ****
(void) sbd_pgr_do_register(slu, it, lpt, &rport, keyflag, svc_key);
sbd_pgr_reg_done:
! if (pgr->pgr_flags & SBD_PGR_APTPL || plist->aptpl) {
if (plist->aptpl)
PGR_SET_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
else
PGR_CLEAR_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
--- 1413,1423 ----
(void) sbd_pgr_do_register(slu, it, lpt, &rport, keyflag, svc_key);
sbd_pgr_reg_done:
! if (plist->aptpl || (sbd_pgr_should_save(slu) == B_TRUE)) {
if (plist->aptpl)
PGR_SET_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
else
PGR_CLEAR_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
*** 1489,1499 ****
}
/* In case there is no reservation exist */
} else {
sbd_pgr_do_reserve(pgr, key, it, ses, pr_out);
! if (pgr->pgr_flags & SBD_PGR_APTPL) {
if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INSUFFICIENT_REG_RESOURCES);
return;
}
--- 1518,1528 ----
}
/* In case there is no reservation exist */
} else {
sbd_pgr_do_reserve(pgr, key, it, ses, pr_out);
! if (sbd_pgr_should_save(slu) == B_TRUE) {
if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INSUFFICIENT_REG_RESOURCES);
return;
}
*** 1546,1555 ****
--- 1575,1589 ----
sbd_pgr_t *pgr = slu->sl_pgr;
sbd_pgr_key_t *key = it->pgr_key_ptr;
ASSERT(key);
+ /*
+ * XXX this does not honor APTPL
+ * (i.e., changes made to a formerly-persistent reservation are not
+ * updated here!!!)
+ */
if (SBD_PGR_RSVD(pgr)) {
if (pgr->pgr_flags & SBD_PGR_RSVD_ALL_REGISTRANTS ||
pgr->pgr_rsvholder == key) {
if (pgr->pgr_rsv_type != pr_out->type ||
pgr->pgr_rsv_scope != pr_out->scope) {
*** 1557,1568 ****
--- 1591,1623 ----
STMF_SAA_INVALID_RELEASE_OF_PR);
return;
}
sbd_pgr_do_release(slu, it,
SBD_UA_RESERVATIONS_RELEASED);
+
+ /*
+ * XXX T10 SPC-3 5.6.10.2 says nothing about what to
+ * do in the event of a failure updating the
+ * PGR nvram store for a reservation associated with
+ * an APTPL-enabled (see SPC-3 5.6.4.1) I_T
+ * registration during a RELEASE service action.
+ *
+ * Technically, the CDB completed successfully, as per
+ * the spec, but at some point we may need to enter
+ * a recovery mode on the initiator(s) if we power cycle
+ * the target at the wrong instant...
+ */
+ if (sbd_pgr_should_save(slu) == B_TRUE) {
+ if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
+ stmf_scsilib_send_status(task,
+ STATUS_CHECK, /* CSTYLED */
+ STMF_SAA_INSUFFICIENT_REG_RESOURCES);
+ return;
}
}
+ }
+ }
stmf_scsilib_send_status(task, STATUS_GOOD, 0);
}
static void
sbd_pgr_do_release(sbd_lu_t *slu, sbd_it_data_t *it, uint8_t ua_condition)
*** 1600,1610 ****
it->pgr_key_ptr = NULL;
}
mutex_exit(&slu->sl_lock);
sbd_pgr_keylist_dealloc(slu);
sbd_pgr_set_ua_conditions(slu, it, SBD_UA_RESERVATIONS_PREEMPTED);
! if (pgr->pgr_flags & SBD_PGR_APTPL) {
if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INSUFFICIENT_REG_RESOURCES);
return;
}
--- 1655,1665 ----
it->pgr_key_ptr = NULL;
}
mutex_exit(&slu->sl_lock);
sbd_pgr_keylist_dealloc(slu);
sbd_pgr_set_ua_conditions(slu, it, SBD_UA_RESERVATIONS_PREEMPTED);
! if (sbd_pgr_should_save(slu) == B_TRUE) {
if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INSUFFICIENT_REG_RESOURCES);
return;
}
*** 1715,1725 ****
return;
}
}
}
! if (pgr->pgr_flags & SBD_PGR_APTPL) {
if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INSUFFICIENT_REG_RESOURCES);
return;
}
--- 1770,1780 ----
return;
}
}
}
! if (sbd_pgr_should_save(slu) == B_TRUE) {
if (sbd_pgr_meta_write(slu) != SBD_SUCCESS) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INSUFFICIENT_REG_RESOURCES);
return;
}
*** 1829,1840 ****
if (plist->unreg) {
sbd_pgr_do_unregister(slu, it, key);
}
! /* Write to disk if currenty aptpl is set or given task is setting it */
! if (pgr->pgr_flags & SBD_PGR_APTPL || plist->aptpl) {
if (plist->aptpl)
PGR_SET_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
else
PGR_CLEAR_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
--- 1884,1895 ----
if (plist->unreg) {
sbd_pgr_do_unregister(slu, it, key);
}
! /* Write to disk if aptpl is currently set or this task is setting it */
! if (plist->aptpl || (sbd_pgr_should_save(slu) == B_TRUE)) {
if (plist->aptpl)
PGR_SET_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);
else
PGR_CLEAR_FLAG(pgr->pgr_flags, SBD_PGR_APTPL);