1 /*	$OpenBSD: rf_stripelocks.h,v 1.3 2002/12/16 07:01:05 tdeval Exp $	*/
2 /*	$NetBSD: rf_stripelocks.h,v 1.3 1999/02/05 00:06:18 oster Exp $	*/
3 
4 /*
5  * Copyright (c) 1995 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Mark Holland
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 
31 /*****************************************************************************
32  *
33  * stripelocks.h -- Header file for locking stripes.
34  *
35  * Note that these functions are called from the execution routines of certain
36  * DAG Nodes, and so they must be NON-BLOCKING to assure maximum parallelism
37  * in the DAG. Accordingly, when a node wants to acquire a lock, it calls
38  * AcquireStripeLock, supplying a pointer to a callback function. If the lock
39  * is free at the time of the call, 0 is returned, indicating that the lock
40  * has been acquired. If the lock is not free, 1 is returned, and a copy of
41  * the function pointer and argument are held in the lock table. When the
42  * lock becomes free, the callback function is invoked.
43  *
44  *****************************************************************************/
45 
46 #ifndef	_RF__RF_STRIPELOCKS_H_
47 #define	_RF__RF_STRIPELOCKS_H_
48 
49 #include <sys/buf.h>
50 
51 #include "rf_types.h"
52 #include "rf_threadstuff.h"
53 #include "rf_general.h"
54 
55 struct RF_LockReqDesc_s {
56 	RF_IoType_t		  type;		/* Read or write. */
57 	RF_int64		  start, stop;	/*
58 						 * Start and end of range to
59 						 * be locked.
60 						 */
61 	RF_int64		  start2, stop2;/*
62 						 * Start and end of 2nd range
63 						 * to be locked.
64 						 */
65 	void			(*cbFunc) (struct buf *);
66 						/* Callback function. */
67 	void			 *cbArg;	/*
68 						 * Argument to callback
69 						 * function.
70 						 */
71 	RF_LockReqDesc_t	 *next;		/* Next element in chain. */
72 	RF_LockReqDesc_t	 *templink;	/*
73 						 * For making short-lived lists
74 						 * of request descriptors.
75 						 */
76 };
77 
78 #define	RF_ASSERT_VALID_LOCKREQ(_lr_)	do {				\
79 	RF_ASSERT(RF_IO_IS_R_OR_W((_lr_)->type));			\
80 } while (0)
81 
82 struct RF_StripeLockDesc_s {
83 	RF_StripeNum_t		 stripeID;	/* The stripe ID. */
84 	RF_LockReqDesc_t	*granted;	/*
85 						 * Unordered list of granted
86 						 * requests.
87 						 */
88 	RF_LockReqDesc_t	*waitersH;	/* FIFO queue of all waiting
89 						 * reqs, both read and write
90 						 * (Head and Tail).
91 						 */
92 	RF_LockReqDesc_t	*waitersT;
93 	int			 nWriters;	/*
94 						 * Number of writers either
95 						 * granted or waiting.
96 						 */
97 	RF_StripeLockDesc_t	*next;		/*
98 						 * For hash table collision
99 						 * resolution.
100 						 */
101 };
102 
103 struct RF_LockTableEntry_s {
104 	RF_DECLARE_MUTEX	(mutex);	/* Mutex on this hash chain. */
105 	RF_StripeLockDesc_t	*descList;	/*
106 						 * Hash chain of lock
107 						 * descriptors.
108 						 */
109 };
110 
111 /*
112  * Initializes a stripe lock descriptor. _defSize is the number of sectors
113  * that we lock when there is no parity information in the ASM (e.g. RAID0).
114  */
115 
116 #define RF_INIT_LOCK_REQ_DESC(_lrd, _typ, _cbf, _cba, _asm, _defSize)	\
117 do {									\
118 	(_lrd).type    = _typ;						\
119 	(_lrd).start2  = -1;						\
120 	(_lrd).stop2   = -1;						\
121 	if ((_asm)->parityInfo) {					\
122 		(_lrd).start = (_asm)->parityInfo->startSector;		\
123 		(_lrd).stop  = (_asm)->parityInfo->startSector +	\
124 		    (_asm)->parityInfo->numSector-1;			\
125 		if ((_asm)->parityInfo->next) {				\
126 			(_lrd).start2  =				\
127 			    (_asm)->parityInfo->next->startSector;	\
128 			(_lrd).stop2   =				\
129 			    (_asm)->parityInfo->next->startSector +	\
130 			    (_asm)->parityInfo->next->numSector-1;	\
131 		}							\
132 	} else {							\
133 		(_lrd).start = 0;					\
134 		(_lrd).stop  = (_defSize);				\
135 	}								\
136 	(_lrd).templink= NULL;						\
137 	(_lrd).cbFunc  = (_cbf);					\
138 	(_lrd).cbArg   = (void *) (_cba);				\
139 } while (0)
140 
141 int  rf_ConfigureStripeLockFreeList(RF_ShutdownList_t **);
142 RF_LockTableEntry_t *rf_MakeLockTable(void);
143 void rf_ShutdownStripeLocks(RF_LockTableEntry_t *);
144 int  rf_ConfigureStripeLocks(RF_ShutdownList_t **, RF_Raid_t *, RF_Config_t *);
145 int  rf_AcquireStripeLock(RF_LockTableEntry_t *, RF_StripeNum_t,
146 	RF_LockReqDesc_t *);
147 void rf_ReleaseStripeLock(RF_LockTableEntry_t *, RF_StripeNum_t,
148 	RF_LockReqDesc_t *);
149 
150 #endif	/* !_RF__RF_STRIPELOCKS_H_ */
151