rdc_diskq.h revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _RDC_DISKQ_H
#define _RDC_DISKQ_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _KERNEL
#define RDC_DISKQ_HEADER_OFF 0 /* beginning of disk */
typedef struct qentry {
int magic;
int type; /* special data ? io? bitmap? */
int flag;
int iostatus;
void *next;
} q_data;
typedef union io_dat {
char dummy[512];
} io_hdr;
/* type */
#define RDC_QUEUEIO 0x02
#define RDC_DISKQ_MAGIC 0x44534B51
#define RDC_DISKQ_VER_ORIG 0x01
#define RDC_DISKQ_VER_64BIT 0x02
#ifdef NSC_MULTI_TERABYTE
#define RDC_DISKQ_VERS RDC_DISKQ_VER_64BIT
#else
#define RDC_DISKQ_VERS RDC_DISKQ_VER_ORIG
#endif
typedef struct diskqheader1 {
int magic;
int vers;
int state;
int head_offset; /* offset of meta-info of head (fbas) */
int tail_offset; /* addr of next write (fbas) */
int disk_size; /* allow growing ? (fbas) */
long nitems; /* items */
long blocks; /* fbas */
int qwrap; /* where the tail wrapped */
int auxqwrap; /* if the tail wraps again, before head wraps once */
typedef struct diskqheader2 {
int magic;
int vers;
int state;
#ifdef NSC_MULTI_TERABYTE
typedef diskq_header2 diskq_header;
#ifdef _LP64
#define RDC_DQFMT "lu"
#else
#define RDC_DQFMT "llu"
#endif
#else
typedef diskq_header1 diskq_header;
#define RDC_DQFMT "ld"
#endif
typedef union headr {
diskq_header h;
char dummy[512];
} dqheader;
/* flags for the state field in the header */
#define RDC_SHUTDOWN_OK 0x01
#define RDC_SHUTDOWN_BAD 0x02
#define QNXTIOWRAPD 0x04
#define QHEADWRAPD 0x08
#define RDC_STOPPINGFLUSH 0x80
typedef struct diskqueue { /* the incore info about the diskq */
long nitems_hwm;
long blocks_hwm;
long throttle_delay;
volatile int inflbls; /* number of inflight blocks */
volatile int inflitems; /* number of inflight blocks */
/* and all things in dqheader */
int busycnt;
int hdrcnt; /* number of io_hdrs on list */
} disk_queue;
/* diskq macros (gets) */
#define QCOALBOUNDS(q) q->coalesc_bounds
/* diskq macros (sets) */
#define INC_QNXTIO(q, n) q->nxt_io += n
#define DEC_QNXTIO(q, n) q->nxt_io -= n
#define SET_QNXTIO(q, n) q->nxt_io = n
#define SET_QHDRCNT(q, n) q->hdrcnt = n
#define SET_LASTQTAIL(q, n) q->last_tail = n
#define SET_LASTQWRITE(q, w) q->last_qwrite = w
#define SET_QCOALBOUNDS(q, n) q->coalesc_bounds = n
#define WRAPQTAIL(q) \
do { \
if (QWRAP(q)) { \
SET_AUXQWRAP(q, QTAIL(q)); \
} else { \
} \
SET_QTAIL(q, RDC_DISKQ_DATA_OFF); \
} while (0)
#define DO_AUXQWRAP(q) \
do { \
SET_AUXQWRAP(q, 0); \
} while (0)
/* these can be wrapped by different threads, avoid the race */
#define WRAPQHEAD(q) \
do { \
if (IS_QSTATE(q, QNXTIOWRAPD)) { \
if (AUXQWRAP(q)) { \
DO_AUXQWRAP(q); \
} else { \
SET_QWRAP(q, 0); \
} \
CLR_QSTATE(q, QNXTIOWRAPD); \
} else { \
SET_QSTATE(q, QHEADWRAPD); \
} \
SET_QHEAD(q, RDC_DISKQ_DATA_OFF); \
} while (0)
#define WRAPQNXTIO(q) \
do { \
if (IS_QSTATE(q, QHEADWRAPD)) { \
if (AUXQWRAP(q)) { \
DO_AUXQWRAP(q); \
} else { \
SET_QWRAP(q, 0); \
} \
CLR_QSTATE(q, QHEADWRAPD); \
} else { \
SET_QSTATE(q, QNXTIOWRAPD); \
} \
SET_QNXTIO(q, RDC_DISKQ_DATA_OFF); \
} while (0)
#define FITSONQ(q, n) \
#define RDC_NOLOG 0x00
#define RDC_WAIT 0x01
#define RDC_NOWAIT 0x02
/* CSTYLED */
#define RDC_BETWEEN(a,b,c) (a<b?((c>=a)&&(c<=b)):((a!=b)&&((c<b)||(c>=a))))
/* CSTYLED */
QCOALBOUNDS(q))):\
#define QLOCK(q) &q->disk_qlock
#define QDISPLAY(q) "qmagic: %x qvers: %d qstate: %x qhead: %" \
" a: %" NSC_SZFMT, \
/* Disk queue flusher state */
#define RDC_QFILL_AWAKE (0)
#define RDC_QFILL_ASLEEP (1)
#define RDC_QFILL_DEAD (-1)
/* functions */
int rdc_lookup_diskq(char *path);
void rdc_dump_iohdrs(disk_queue *q);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _RDC_DISKQ_H */