2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
14 # include <afs/sysincludes.h>
15 # include <afsincludes.h>
18 # include <afs/errors.h>
20 # ifdef AFS_PTHREAD_ENV
22 # endif /* AFS_PTHREAD_ENV */
25 # define EDQUOT WSAEDQUOT
27 # endif /* AFS_NT40_ENV */
31 * We currently only include below the errors that
32 * affect us the most. We should add to this list
33 * more code mappings, as necessary.
37 * Convert from the local (host) to the standard
38 * (network) system error code.
41 hton_syserr_conv(afs_int32 code)
48 else if (code == EDQUOT)
58 * Convert from the standard (Network) format to the
59 * local (host) system error code.
62 ntoh_syserr_conv(int code)
66 if (code == VDISKFULL)
68 else if (code == VOVERQUOTA)
82 * We provide the following because some systems (like aix) would fail if we pass
87 static const char memZero;
89 osi_alloc(afs_int32 x)
92 * 0-length allocs may return NULL ptr from osi_kalloc, so we special-case
93 * things so that NULL returned iff an error occurred
96 return (char *)&memZero;
97 return (char *)(mem_alloc(x));
101 osi_free(char *x, afs_int32 size)
103 if ((x == &memZero) || !x)
111 #if defined(RX_ENABLE_LOCKS) && defined(RX_REFCOUNT_CHECK)
112 int rx_callHoldType = 0;
117 /* What follows is a lock database for RX. There is currently room for 400
118 * locks to be held. Routines panic if there is an error. To port, add
119 * RX_LOCKS_DB versions of MUTEX_{ENTER, EXIT, TRYENTER} and CV_*WAIT to
120 * rx_kmutex.h and define lock macros below.
122 #if (defined(AFS_AIX41_ENV) || (defined(AFS_SGI53_ENV) && defined(MP))) && defined(KERNEL)
125 Simple_lock rxdb_lock;
126 #define RXDB_LOCK_INIT() lock_alloc(&rxdb_lock, LOCK_ALLOC_PIN, 1, 0), \
127 simple_lock_init(&rxdb_lock)
128 #define RXDB_LOCK_ENTER() simple_lock(&rxdb_lock)
129 #define RXDB_LOCK_EXIT() simple_unlock(&rxdb_lock)
130 #else /* AFS_AIX41_ENV */
132 afs_kmutex_t rxdb_lock;
133 #define RXDB_LOCK_INIT() mutex_init(&rxdb_lock, "rxdb lock", 0, 0)
134 #define RXDB_LOCK_ENTER() AFS_MUTEX_ENTER(&rxdb_lock)
135 #define RXDB_LOCK_EXIT() mutex_exit(&rxdb_lock)
136 #endif /* AFS_SGI53_ENV */
137 #endif /* AFS_AIX41_ENV */
140 int RXDB_LockPos = 0;
142 #define RXDB_NLOCKS 32
144 afs_int32 id; /* id of lock holder. */
145 void *a; /* address of lock. */
146 u_short fileId; /* fileID# of RX file. */
152 #define RXDB_HASHSIZE 8
155 struct rxdb_lock_t rxdb_lockList[RXDB_NLOCKS];
156 short rxdb_idHash[RXDB_HASHSIZE];
157 #define RXDB_IDHASH(id) ((((u_long)id)>>1) & (RXDB_HASHSIZE-1))
159 /* Record locations of all locks we enter/exit. */
160 struct rxdb_lockloc_t {
161 u_short fileId; /* fileID# of RX file. */
166 #ifdef RX_LOCKS_COVERAGE
167 #define RXDB_NlockLocs 512
168 #define RXDB_LOCHASHSIZE 256
169 struct rxdb_lockloc_t rxdb_lockLocs[RXDB_NlockLocs];
170 short rxdb_lockLocHash[RXDB_LOCHASHSIZE];
171 #define RXDB_LOCHASH(a) ((((u_long)a)) & (RXDB_LOCHASHSIZE-1))
172 #endif /* RX_LOCKS_COVERAGE */
174 /* Element 0 of each of the above arrays serves as the pointer to the list of
180 static int initted = 0;
191 for (i = 1; i < RXDB_NLOCKS - 1; i++) {
192 rxdb_lockList[i].next = i + 1;
193 rxdb_lockList[i].prev = i - 1;
195 rxdb_lockList[0].next = 1;
196 rxdb_lockList[0].prev = 0;
197 rxdb_lockList[RXDB_NLOCKS - 1].next = 0;
198 rxdb_lockList[RXDB_NLOCKS - 1].prev = RXDB_NLOCKS - 2;
200 #ifdef RX_LOCKS_COVERAGE
201 for (i = 1; i < RXDB_NlockLocs - 1; i++) {
202 rxdb_lockLocs[i].next = i + 1;
203 rxdb_lockLocs[i].prev = i - 1;
205 rxdb_lockLocs[0].next = 1;
206 rxdb_lockLocs[0].prev = 0;
207 rxdb_lockLocs[RXDB_NlockLocs - 1].next = 0;
208 rxdb_lockLocs[RXDB_NlockLocs - 1].prev = RXDB_NlockLocs - 2;
209 #endif /* RX_LOCKS_COVERAGE */
214 #ifdef RX_LOCKS_COVERAGE
216 rxdb_RecordLockLocation(fileId, line)
217 afs_int32 fileId, line;
221 i = RXDB_LOCHASH(line);
223 /* Only enter lock location into list once. */
224 for (j = rxdb_lockLocHash[i]; j; j = rxdb_lockLocs[j].next) {
225 if ((rxdb_lockLocs[j].line == line)
226 && (rxdb_lockLocs[j].fileId == fileId))
230 /* Add lock to list. */
231 j = rxdb_lockLocs[0].next;
233 osi_Panic("rxdb_initLock: used up all the lock locations.\n");
236 /* Fix up free list. */
237 rxdb_lockLocs[0].next = rxdb_lockLocs[j].next;
239 /* Put new element at head of list. */
240 rxdb_lockLocs[j].next = rxdb_lockLocHash[i];
241 rxdb_lockLocs[j].prev = 0;
242 if (rxdb_lockLocHash[i]) {
243 rxdb_lockLocs[rxdb_lockLocHash[i]].prev = j;
245 rxdb_lockLocHash[i] = j;
247 /* Set data in element. */
248 rxdb_lockLocs[j].fileId = fileId;
249 rxdb_lockLocs[j].line = line;
252 #endif /* RX_LOCKS_COVERAGE */
255 /* Set lock as possessed by me. */
257 rxdb_grablock(a, id, fileId, line)
266 #ifdef RX_LOCKS_COVERAGE
267 rxdb_RecordLockLocation(fileId, line);
268 #endif /* RX_LOCKS_COVERAGE */
269 /* Is lock already held by anyone? */
270 for (i = 0; i < RXDB_HASHSIZE; i++) {
271 for (j = rxdb_idHash[i]; j; j = rxdb_lockList[j].next) {
272 if (rxdb_lockList[j].a == a) {
274 osi_Panic("rxdb_grablock: lock already held.");
280 j = rxdb_lockList[0].next;
282 osi_Panic("rxdb_grablock: rxdb_lockList is full.");
284 rxdb_lockList[0].next = rxdb_lockList[j].next;
286 /* Put element at head of list. */
287 rxdb_lockList[j].next = rxdb_idHash[i];
288 rxdb_lockList[j].prev = 0;
289 if (rxdb_idHash[i]) {
290 rxdb_lockList[rxdb_idHash[i]].prev = j;
294 /* Set data into element. */
295 rxdb_lockList[j].a = a;
296 rxdb_lockList[j].id = id;
297 rxdb_lockList[j].fileId = fileId;
298 rxdb_lockList[j].line = line;
304 rxdb_droplock(a, id, fileId, line)
314 #ifdef RX_LOCKS_COVERAGE
315 rxdb_RecordLockLocation(fileId, line);
316 #endif /* RX_LOCKS_COVERAGE */
319 /* Do I have the lock? */
320 i = rxdb_idHash[RXDB_IDHASH(id)];
321 for (j = i; j; j = rxdb_lockList[j].next) {
322 if (rxdb_lockList[j].a == a) {
329 osi_Panic("rxdb_unlock: lock not held by me.\n");
332 /* delete lock from queue. */
336 rxdb_idHash[i] = rxdb_lockList[j].next;
337 rxdb_lockList[rxdb_lockList[j].next].prev = 0;
339 if (rxdb_lockList[j].next)
340 rxdb_lockList[rxdb_lockList[j].next].prev = rxdb_lockList[j].prev;
341 rxdb_lockList[rxdb_lockList[j].prev].next = rxdb_lockList[j].next;
343 /* Put back on free list. */
344 rxdb_lockList[j].next = rxdb_lockList[0].next;
345 rxdb_lockList[j].prev = 0;
346 rxdb_lockList[0].next = j;
351 #endif /* (AIX41 || SGI53) && KERNEL */
353 #endif /* RX_LOCKS_DB */