OpenSolaris_b135/cmd/iscsi/iscsitgtd/t10_spc_pr.h

/*
 * 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
 * or http://www.opensolaris.org/os/licensing.
 * 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 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _T10_SPC_PR_H
#define	_T10_SPC_PR_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * SPC-3 Persistent Reservation specific structures and defines
 */

/*
 * Key Linked Lists
 */
typedef struct key_link {
	union {
		uint64_t	align;
		struct {
			struct key_link *_lnk_fwd;	/* Forward element */
			struct key_link *_lnk_bwd;	/* Backward element */
		} key_ptr;
	} key_link;
} key_link_t;
#define	lnk_fwd	key_link.key_ptr._lnk_fwd
#define	lnk_bwd	key_link.key_ptr._lnk_bwd
#define	insque(a, b) \
	((key_link_t *)(a))->lnk_fwd = (key_link_t *)(b); \
	((key_link_t *)(a))->lnk_bwd = ((key_link_t *)(b))->lnk_bwd; \
	((key_link_t *)(b))->lnk_bwd = (key_link_t *)(a); \
	((key_link_t *)(a))->lnk_bwd->lnk_fwd = (key_link_t *)(a);

#define	remque(A) \
	((key_link_t *)(A))->lnk_bwd->lnk_fwd = ((key_link_t *)(A))->lnk_fwd; \
	((key_link_t *)(A))->lnk_fwd->lnk_bwd = ((key_link_t *)(A))->lnk_bwd;

/*
 * Reservation Types (res_type).
 */
typedef enum {
	RT_NONE = 0,			/* None */
	RT_PGR,				/* SCSI-3 Persistent Reservation */
	RT_NPR				/* SCSI-2 Non-Persistent Reservation */
} spc_reserve_types;

/*
 * Persistent reservation data.
 */
typedef struct spc_pr_key {
	key_link_t	k_link;			/* Key linked list */
	uint64_t	k_key;			/* registration key */
	char		*k_i_name;		/* initiator name */
	char		*k_transportID;		/* transport ID */
} spc_pr_key_t;

typedef struct spc_pr_rsrv {
	key_link_t	r_link;			/* Key linked list */
	uint64_t	r_key;			/* reservation key */
	char		*r_i_name;		/* initiator name */
	char		*r_transportID;		/* transport ID */
	uint8_t		r_scope;		/* reservation scope */
	uint8_t		r_type;			/* reservation type */
} spc_pr_rsrv_t;

/*
 * Persistent Reservation data
 */
typedef struct scsi3_pgr {
	uint32_t	pgr_generation;		/* PGR PRgeneration value */
	uint16_t	pgr_unused;
	uint16_t	pgr_bits	: 15,
			pgr_aptpl	: 1;	/* persistence data exists */
	int32_t		pgr_numkeys;		/* # entries in key list */
	int32_t		pgr_numrsrv;		/* # entries in rsrv list */
	key_link_t	pgr_keylist;		/* Registration key list */
	key_link_t	pgr_rsrvlist;		/* reservation list */
} scsi3_pgr_t;

typedef struct sbc_reserve {
	spc_reserve_types	res_type;	/* standard or pr active */
	pthread_rwlock_t	res_rwlock;	/* Lock for coordination */
	scsi3_pgr_t		res_scsi_3_pgr;	/* SCSI-3 PGR */
	t10_lu_impl_t		*res_owner;	/* SCSI-2 Reservation */
} sbc_reserve_t;

/*
 * On-disk PGR data.
 *
 * NOTE: The following three structures should be rounded up to 512 bytes each
 *	to prevent potential problems with on-disk data skew
 */
typedef struct spc_pr_diskkey {
	uint64_t	key;			/* registration key (8) */
	uint32_t	rectype;		/* record type (4) */
	char		i_name[224];		/* initiator name (224) */
	char		filler1[20];		/* filler to 256 bytes */
	char		transportID[228];	/* transport ID (228) */
	char		filler2[28];		/* filler to 512 bytes */
} spc_pr_diskkey_t;

typedef struct spc_pr_diskrsrv {
	uint64_t	key;			/* reservation key (8) */
	uint32_t	rectype;		/* record type (4) */
	uint8_t		scope;			/* reservation scope (1) */
	uint8_t		type;			/* reservation type (1) */
	char		i_name[224]; 		/* initiator name (224) */
	char		filler1[18];		/* filler to 256 bytes */
	char		transportID[228];	/* Transport ID (228) */
	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 */