t10_spc_pr.h revision 68941780f0da57f6844d5666a8528421c53133bc
2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#ifndef _T10_SPC_PR_H
2N/A#define _T10_SPC_PR_H
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#ifdef __cplusplus
2N/Aextern "C" {
2N/A#endif
2N/A
2N/A/*
2N/A * SPC-3 Persistent Reservation specific structures and defines
2N/A */
2N/A
2N/A/*
2N/A * Key Linked Lists
2N/A */
2N/Atypedef struct key_link {
2N/A union {
2N/A uint64_t align;
2N/A struct {
2N/A struct key_link *_lnk_fwd; /* Forward element */
2N/A struct key_link *_lnk_bwd; /* Backward element */
2N/A } key_ptr;
2N/A } key_link;
2N/A} key_link_t;
2N/A#define lnk_fwd key_link.key_ptr._lnk_fwd
2N/A#define lnk_bwd key_link.key_ptr._lnk_bwd
2N/A#define insque(a, b) \
2N/A ((key_link_t *)(a))->lnk_fwd = (key_link_t *)(b); \
2N/A ((key_link_t *)(a))->lnk_bwd = ((key_link_t *)(b))->lnk_bwd; \
2N/A ((key_link_t *)(b))->lnk_bwd = (key_link_t *)(a); \
2N/A ((key_link_t *)(a))->lnk_bwd->lnk_fwd = (key_link_t *)(a);
2N/A
2N/A#define remque(A) \
2N/A ((key_link_t *)(A))->lnk_bwd->lnk_fwd = ((key_link_t *)(A))->lnk_fwd; \
2N/A ((key_link_t *)(A))->lnk_fwd->lnk_bwd = ((key_link_t *)(A))->lnk_bwd;
2N/A
2N/A/*
2N/A * Reservation Types (res_type).
2N/A */
2N/Atypedef enum {
2N/A RT_NONE = 0, /* None */
2N/A RT_PGR /* SCSI-3 Persistent Reservation */
2N/A} spc_reserve_types;
2N/A
2N/A/*
2N/A * Persistent reservation data.
2N/A */
2N/Atypedef struct spc_pr_key {
2N/A key_link_t k_link; /* Key linked list */
2N/A uint64_t k_key; /* registration key */
2N/A char *k_i_name; /* initiator name */
2N/A char *k_transportID; /* transport ID */
2N/A} spc_pr_key_t;
2N/A
2N/Atypedef struct spc_pr_rsrv {
2N/A key_link_t r_link; /* Key linked list */
2N/A uint64_t r_key; /* reservation key */
2N/A char *r_i_name; /* initiator name */
2N/A char *r_transportID; /* transport ID */
2N/A uint8_t r_scope; /* reservation scope */
2N/A uint8_t r_type; /* reservation type */
2N/A} spc_pr_rsrv_t;
2N/A
2N/A/*
2N/A * Persistent Reservation data
2N/A */
2N/Atypedef struct scsi3_pgr {
2N/A uint32_t pgr_generation; /* PGR PRgeneration value */
2N/A uint16_t pgr_unused;
2N/A uint16_t pgr_bits : 15,
2N/A pgr_aptpl : 1; /* persistence data exists */
2N/A int32_t pgr_numkeys; /* # entries in key list */
2N/A int32_t pgr_numrsrv; /* # entries in rsrv list */
2N/A key_link_t pgr_keylist; /* Registration key list */
2N/A key_link_t pgr_rsrvlist; /* reservation list */
2N/A} scsi3_pgr_t;
2N/A
2N/Atypedef struct sbc_reserve {
2N/A spc_reserve_types res_type; /* standard or pr active */
2N/A pthread_rwlock_t res_rwlock; /* Lock for coordination */
2N/A scsi3_pgr_t res_scsi_3_pgr; /* SCSI-3 PGR */
2N/A} sbc_reserve_t;
2N/A
2N/A/*
2N/A * On-disk PGR data.
2N/A *
2N/A * NOTE: The following three structures should be rounded up to 512 bytes each
2N/A * to prevent potential problems with on-disk data skew
2N/A */
2N/Atypedef struct spc_pr_diskkey {
2N/A uint64_t key; /* registration key (8) */
2N/A uint32_t rectype; /* record type (4) */
2N/A char i_name[224]; /* initiator name (224) */
2N/A char filler1[20]; /* filler to 256 bytes */
2N/A char transportID[228]; /* transport ID (228) */
2N/A char filler2[28]; /* filler to 512 bytes */
2N/A} spc_pr_diskkey_t;
2N/A
2N/Atypedef struct spc_pr_diskrsrv {
2N/A uint64_t key; /* reservation key (8) */
2N/A uint32_t rectype; /* record type (4) */
2N/A uint8_t scope; /* reservation scope (1) */
2N/A uint8_t type; /* reservation type (1) */
2N/A char i_name[224]; /* initiator name (224) */
2N/A char filler1[18]; /* filler to 256 bytes */
2N/A char transportID[228]; /* Transport ID (228) */
2N/A char filler2[28]; /* filler to 512 bytes */
} spc_pr_diskrsrv_t;
typedef struct spc_pr_persist_disk {
uint64_t magic; /* magic number (8) */
uint32_t revision; /* header format revision (4) */
uint32_t generation; /* pgr generation count (4) */
int32_t numkeys; /* # items in key list (4) */
int32_t numrsrv; /* # items in rsrv list (4) */
char filler[488]; /* 8+4+4+4+4 */
/*
* After the header the data is laid out as follows:
* spc_pr_diskkey_t keylist[];
* spc_pr_diskrsrv_t rsrvlist[];
*/
spc_pr_diskkey_t keylist[1];
} spc_pr_persist_disk_t;
#define SPC_PGR_PERSIST_DATA_REVISION 0x01 /* REVISON = 1 */
#define PGRMAGIC 0x5047524D41474943LL /* "PGRMAGIC" */
#define PGRDISKKEY 0x5047526B /* "PGRk" */
#define PGRDISKRSRV 0x50475272 /* "PGRr" */
#ifdef __cplusplus
}
#endif
#endif /* _T10_SPC_PR_H */