--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h Fri May 08 13:31:23 2009 -0700
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h Fri May 08 16:22:42 2009 -0600
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,64 +30,251 @@
extern "C" {
#endif
+typedef stmf_status_t sbd_status_t;
+extern char sbd_vendor_id[];
+extern char sbd_product_id[];
+extern char sbd_revision[];
+/*
+ * Error codes
+ */
+#define SBD_SUCCESS STMF_SUCCESS
#define SBD_FAILURE STMF_LU_FAILURE
-#define SBD_FILEIO_FAILURE (SBD_FAILURE | STMF_FSC(1))
+
+#define SBD_ALREADY (SBD_FAILURE | STMF_FSC(1))
+#define SBD_NOT_SUPPORTED (SBD_FAILURE | STMF_FSC(2))
+#define SBD_META_CORRUPTED (SBD_FAILURE | STMF_FSC(3))
+#define SBD_INVALID_ARG (SBD_FAILURE | STMF_FSC(4))
+#define SBD_NOT_FOUND (SBD_FAILURE | STMF_FSC(5))
+#define SBD_ALLOC_FAILURE (SBD_FAILURE | STMF_FSC(6))
+#define SBD_FILEIO_FAILURE (SBD_FAILURE | STMF_FSC(7))
+#define SBD_IO_PAST_EOF (SBD_FAILURE | STMF_FSC(8))
+#define SBD_BUSY (SBD_FAILURE | STMF_FSC(9))
+
+#define SHARED_META_DATA_SIZE 65536
+#define SBD_META_OFFSET 4096
+#define SBD_MIN_LU_SIZE (1024 * 1024)
+
+/*
+ * sms endianess
+ */
+#define SMS_BIG_ENDIAN 0x00
+#define SMS_LITTLE_ENDIAN 0xFF
+
+#ifdef _BIG_ENDIAN
+#define SMS_DATA_ORDER SMS_BIG_ENDIAN
+#else
+#define SMS_DATA_ORDER SMS_LITTLE_ENDIAN
+#endif
+
+#define SBD_MAGIC 0x53554e5342444c55
+
+#define SBD_VER_MAJOR 1
+#define SBD_VER_MINOR 1
+#define SBD_VER_SUBMINOR 0
+
+#if 0
+typedef struct sbd_meta_start {
+ uint64_t sm_magic;
+ uint64_t sm_meta_size;
+ uint64_t sm_meta_size_used;
+ uint64_t sm_rsvd1; /* Defaults to zero */
+ uint64_t sm_rsvd2;
+ uint16_t sm_ver_major;
+ uint16_t sm_ver_minor;
+ uint16_t sm_ver_subminor;
+ uint8_t sm_flags;
+ uint8_t sm_chksum;
+} sbd_meta_start_t;
+#endif
+
+typedef struct sm_section_hdr {
+ uint64_t sms_offset; /* Offset of this section */
+ uint32_t sms_size; /* Includes the header and padding */
+ uint16_t sms_id; /* Section identifier */
+ uint8_t sms_data_order; /* 0x00 or 0xff */
+ uint8_t sms_chksum;
+} sm_section_hdr_t;
/*
- * if the function pointers to write metadata are NULL, then sbd assumes that
- * metadata and LU data share the same store. In that case sbd sets aside
- * some space for metadata and adjusts the LU size reported to initiators
- * accordingly.
+ * sbd meta section identifiers
*/
-typedef struct sbd_store {
- void *sst_sbd_private;
- void *sst_store_private;
- char *sst_alias;
+#define SMS_ID_LU_INFO_1_0 0
+#define SMS_ID_LU_INFO_1_1 1
+#define SMS_ID_PGR_INFO 2
+#define SMS_ID_UNUSED 0x1000
- stmf_status_t (*sst_online)(struct sbd_store *sst);
- stmf_status_t (*sst_offline)(struct sbd_store *sst);
- stmf_status_t (*sst_deregister_lu)(struct sbd_store *sst);
+typedef struct sbd_lu_info_1_0 {
+ sm_section_hdr_t sli_sms_header;
+ uint64_t sli_total_store_size;
+ uint64_t sli_total_meta_size;
+ uint64_t sli_lu_data_offset;
+ uint64_t sli_lu_data_size;
+ uint32_t sli_flags;
+ uint16_t sli_blocksize;
+ uint8_t sli_data_order;
+ uint8_t rsvd1;
+ uint8_t sli_lu_devid[20];
+ uint32_t rsvd2;
+} sbd_lu_info_1_0_t;
- stmf_status_t (*sst_data_read)(struct sbd_store *sst,
- uint64_t offset, uint64_t size, uint8_t *buf);
- stmf_status_t (*sst_data_write)(struct sbd_store *sst,
- uint64_t offset, uint64_t size, uint8_t *buf);
- stmf_status_t (*sst_data_flush)(struct sbd_store *sst);
+typedef struct sbd_lu_info_1_1 {
+ sm_section_hdr_t sli_sms_header;
+ uint32_t sli_flags;
+ char sli_rev[4];
+ char sli_vid[8];
+ char sli_pid[16];
+ uint64_t sli_lu_size; /* Read capacity size */
+
+ /*
+ * Essetially zfs volume name for zvols to verify that the
+ * metadata is coming in from the correct zvol and not from a
+ * clone. Has no meaning in any other case.
+ */
+ uint16_t sli_meta_fname_offset;
- stmf_status_t (*sst_meta_read)(struct sbd_store *sst,
- uint64_t offset, uint64_t size, uint8_t *buf);
- stmf_status_t (*sst_meta_write)(struct sbd_store *sst,
- uint64_t offset, uint64_t size, uint8_t *buf);
-} sbd_store_t;
-
-typedef struct sst_init_data {
- uint64_t sst_store_size; /* Total size of the store */
+ /*
+ * Data filename or the media filename when the metadata is in
+ * a separate file. Its not needed if the metadata is shared
+ * with data as the user supplied name is the data filename.
+ */
+ uint64_t sli_data_fname_offset;
+ uint64_t sli_serial_offset;
+ uint64_t sli_alias_offset;
+ uint8_t sli_data_blocksize_shift;
+ uint8_t sli_data_order;
+ uint8_t sli_serial_size;
+ uint8_t sli_rsvd1;
+ uint8_t sli_device_id[20];
+ uint8_t sli_rsvd2[256];
/*
- * This is the metadat for the store implementation itself
- * that needs to be persisted.
+ * In case there is no separate meta, sli_meta_fname_offset wont
+ * be valid. The same is true for zfs based metadata. The data_fname
+ * is the zvol.
*/
- uint64_t sst_store_meta_data_size;
-
- /* This is returned to the caller */
- uint8_t sst_guid[16];
-
- uint32_t sst_flags;
- uint16_t sst_blocksize; /* To expose to initiators */
-} sst_init_data_t;
+ uint8_t sli_buf[8];
+} sbd_lu_info_1_1_t;
/*
- * sst_flags.
+ * sli flags
*/
-#define SST_NOT_PERSISTENT 0x0001
-#define SST_READONLY_DATA 0x0002
+#define SLI_SEPARATE_META 0x0001
+#define SLI_WRITE_PROTECTED 0x0002
+#define SLI_VID_VALID 0x0004
+#define SLI_PID_VALID 0x0008
+#define SLI_REV_VALID 0x0010
+#define SLI_META_FNAME_VALID 0x0020
+#define SLI_DATA_FNAME_VALID 0x0040
+#define SLI_SERIAL_VALID 0x0080
+#define SLI_ALIAS_VALID 0x0100
+#define SLI_WRITEBACK_CACHE_DISABLE 0x0200
+#define SLI_ZFS_META 0x0400
+
+struct sbd_it_data;
+
+typedef struct sbd_lu {
+ struct sbd_lu *sl_next;
+ stmf_lu_t *sl_lu;
+ uint32_t sl_alloc_size;
+
+ /* Current LU state */
+ kmutex_t sl_lock;
+ uint32_t sl_flags;
+ uint8_t sl_trans_op;
+ uint8_t sl_state:7,
+ sl_state_not_acked:1;
+
+ char *sl_name; /* refers to meta or data */
+
+ /* Metadata */
+ char *sl_alias;
+ char *sl_meta_filename; /* If applicable */
+ vnode_t *sl_meta_vp;
+ vtype_t sl_meta_vtype;
+ uint8_t sl_device_id[20]; /* 4(hdr) + 16(GUID) */
+ uint8_t sl_meta_blocksize_shift; /* Left shift multiplier */
+ uint8_t sl_data_blocksize_shift;
+ uint8_t sl_data_fs_nbits;
+ uint8_t sl_serial_no_size;
+ uint64_t sl_total_meta_size;
+ uint64_t sl_meta_size_used;
+ uint8_t *sl_serial_no; /* optional */
+ char sl_vendor_id[8];
+ char sl_product_id[16];
+ char sl_revision[4];
+ uint32_t sl_data_fname_alloc_size; /* for an explicit alloc */
+ uint32_t sl_alias_alloc_size;
+ uint8_t sl_serial_no_alloc_size;
+
+ /* zfs metadata */
+ vnode_t *sl_zfs_meta_vp;
-sbd_store_t *sbd_sst_alloc(uint32_t additional_size, uint32_t flags);
-void sbd_sst_free(sbd_store_t *sst);
-stmf_status_t sbd_create_meta(sbd_store_t *sst, sst_init_data_t *sst_idata);
-stmf_status_t sbd_modify_meta(sbd_store_t *sst, sst_init_data_t *sst_idata);
-stmf_status_t sbd_register_sst(sbd_store_t *sst, sst_init_data_t *sst_idata);
-stmf_status_t sbd_deregister_sst(sbd_store_t *sst);
+ /* Backing store */
+ char *sl_data_filename;
+ vnode_t *sl_data_vp;
+ vtype_t sl_data_vtype;
+ uint64_t sl_total_data_size;
+ uint64_t sl_data_readable_size; /* read() fails after this */
+ uint64_t sl_data_offset; /* After the metadata,if any */
+ uint64_t sl_lu_size; /* READ CAPACITY size */
+
+ struct sbd_it_data *sl_it_list;
+ struct sbd_pgr *sl_pgr;
+ uint64_t sl_rs_owner_session_id;
+} sbd_lu_t;
+
+/*
+ * sl_flags
+ */
+#define SL_LINKED 0x00001
+#define SL_META_OPENED 0x00002
+#define SL_REGISTERED 0x00004
+#define SL_META_NEEDS_FLUSH 0x00008
+#define SL_DATA_NEEDS_FLUSH 0x00010
+#define SL_VID_VALID 0x00020
+#define SL_PID_VALID 0x00040
+#define SL_REV_VALID 0x00080
+#define SL_WRITE_PROTECTED 0x00100
+#define SL_MEDIA_LOADED 0x00200
+#define SL_LU_HAS_SCSI2_RESERVATION 0x00400
+#define SL_WRITEBACK_CACHE_DISABLE 0x00800
+#define SL_SAVED_WRITE_CACHE_DISABLE 0x01000
+#define SL_MEDIUM_REMOVAL_PREVENTED 0x02000
+#define SL_NO_DATA_DKIOFLUSH 0x04000
+#define SL_SHARED_META 0x08000
+#define SL_ZFS_META 0x10000
+#define SL_WRITEBACK_CACHE_SET_UNSUPPORTED 0x20000
+#define SL_FLUSH_ON_DISABLED_WRITECACHE 0x40000
+
+/*
+ * sl_trans_op. LU is undergoing some transition and this field
+ * tells what kind of transition that is.
+ */
+#define SL_OP_NONE 0
+#define SL_OP_CREATE_REGISTER_LU 1
+#define SL_OP_IMPORT_LU 2
+#define SL_OP_DELETE_LU 3
+#define SL_OP_MODIFY_LU 4
+#define SL_OP_LU_PROPS 5
+
+sbd_status_t sbd_data_read(sbd_lu_t *sl, uint64_t offset, uint64_t size,
+ uint8_t *buf);
+sbd_status_t sbd_data_write(sbd_lu_t *sl, uint64_t offset, uint64_t size,
+ uint8_t *buf);
+stmf_status_t sbd_task_alloc(struct scsi_task *task);
+void sbd_new_task(struct scsi_task *task, struct stmf_data_buf *initial_dbuf);
+void sbd_dbuf_xfer_done(struct scsi_task *task, struct stmf_data_buf *dbuf);
+void sbd_send_status_done(struct scsi_task *task);
+void sbd_task_free(struct scsi_task *task);
+stmf_status_t sbd_abort(struct stmf_lu *lu, int abort_cmd, void *arg,
+ uint32_t flags);
+void sbd_ctl(struct stmf_lu *lu, int cmd, void *arg);
+stmf_status_t sbd_info(uint32_t cmd, stmf_lu_t *lu, void *arg, uint8_t *buf,
+ uint32_t *bufsizep);
+sbd_status_t sbd_write_lu_info(sbd_lu_t *sl);
+sbd_status_t sbd_flush_data_cache(sbd_lu_t *sl, int fsync_done);
+sbd_status_t sbd_wcd_set(int wcd, sbd_lu_t *sl);
+void sbd_wcd_get(int *wcd, sbd_lu_t *sl);
#ifdef __cplusplus
}