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>
20 # include <afs/errors.h>
22 # ifdef AFS_PTHREAD_ENV
24 # endif /* AFS_PTHREAD_ENV */
27 # define EDQUOT WSAEDQUOT
29 # endif /* AFS_NT40_ENV */
33 * We currently only include below the errors that
34 * affect us the most. We should add to this list
35 * more code mappings, as necessary.
39 * Convert from the local (host) to the standard
40 * (network) system error code.
43 hton_syserr_conv(afs_int32 code)
50 else if (code == EDQUOT)
60 * Convert from the standard (Network) format to the
61 * local (host) system error code.
64 ntoh_syserr_conv(int code)
68 if (code == VDISKFULL)
70 else if (code == VOVERQUOTA)
84 * We provide the following because some systems (like aix) would fail if we pass
89 static const char memZero;
91 osi_alloc(afs_int32 x)
94 * 0-length allocs may return NULL ptr from osi_kalloc, so we special-case
95 * things so that NULL returned iff an error occurred
98 return (char *)&memZero;
99 return (char *)(mem_alloc(x));
103 osi_free(char *x, afs_int32 size)
105 if ((x == &memZero) || !x)
113 #if defined(RX_ENABLE_LOCKS) && defined(RX_REFCOUNT_CHECK)
114 int rx_callHoldType = 0;
119 /* What follows is a lock database for RX. There is currently room for 400
120 * locks to be held. Routines panic if there is an error. To port, add
121 * RX_LOCKS_DB versions of MUTEX_{ENTER, EXIT, TRYENTER} and CV_*WAIT to
122 * rx_kmutex.h and define lock macros below.
124 #if (defined(AFS_AIX41_ENV) || (defined(AFS_SGI53_ENV) && defined(MP))) && defined(KERNEL)
127 Simple_lock rxdb_lock;
128 #define RXDB_LOCK_INIT() lock_alloc(&rxdb_lock, LOCK_ALLOC_PIN, 1, 0), \
129 simple_lock_init(&rxdb_lock)
130 #define RXDB_LOCK_ENTER() simple_lock(&rxdb_lock)
131 #define RXDB_LOCK_EXIT() simple_unlock(&rxdb_lock)
132 #else /* AFS_AIX41_ENV */
134 afs_kmutex_t rxdb_lock;
135 #define RXDB_LOCK_INIT() mutex_init(&rxdb_lock, "rxdb lock", 0, 0)
136 #define RXDB_LOCK_ENTER() AFS_MUTEX_ENTER(&rxdb_lock)
137 #define RXDB_LOCK_EXIT() mutex_exit(&rxdb_lock)
138 #endif /* AFS_SGI53_ENV */
139 #endif /* AFS_AIX41_ENV */
142 int RXDB_LockPos = 0;
144 #define RXDB_NLOCKS 32
146 afs_int32 id; /* id of lock holder. */
147 void *a; /* address of lock. */
148 u_short fileId; /* fileID# of RX file. */
154 #define RXDB_HASHSIZE 8
157 struct rxdb_lock_t rxdb_lockList[RXDB_NLOCKS];
158 short rxdb_idHash[RXDB_HASHSIZE];
159 #define RXDB_IDHASH(id) ((((u_long)id)>>1) & (RXDB_HASHSIZE-1))
161 /* Record locations of all locks we enter/exit. */
162 struct rxdb_lockloc_t {
163 u_short fileId; /* fileID# of RX file. */
168 #ifdef RX_LOCKS_COVERAGE
169 #define RXDB_NlockLocs 512
170 #define RXDB_LOCHASHSIZE 256
171 struct rxdb_lockloc_t rxdb_lockLocs[RXDB_NlockLocs];
172 short rxdb_lockLocHash[RXDB_LOCHASHSIZE];
173 #define RXDB_LOCHASH(a) ((((u_long)a)) & (RXDB_LOCHASHSIZE-1))
174 #endif /* RX_LOCKS_COVERAGE */
176 /* Element 0 of each of the above arrays serves as the pointer to the list of
182 static int initted = 0;
193 for (i = 1; i < RXDB_NLOCKS - 1; i++) {
194 rxdb_lockList[i].next = i + 1;
195 rxdb_lockList[i].prev = i - 1;
197 rxdb_lockList[0].next = 1;
198 rxdb_lockList[0].prev = 0;
199 rxdb_lockList[RXDB_NLOCKS - 1].next = 0;
200 rxdb_lockList[RXDB_NLOCKS - 1].prev = RXDB_NLOCKS - 2;
202 #ifdef RX_LOCKS_COVERAGE
203 for (i = 1; i < RXDB_NlockLocs - 1; i++) {
204 rxdb_lockLocs[i].next = i + 1;
205 rxdb_lockLocs[i].prev = i - 1;
207 rxdb_lockLocs[0].next = 1;
208 rxdb_lockLocs[0].prev = 0;
209 rxdb_lockLocs[RXDB_NlockLocs - 1].next = 0;
210 rxdb_lockLocs[RXDB_NlockLocs - 1].prev = RXDB_NlockLocs - 2;
211 #endif /* RX_LOCKS_COVERAGE */
216 #ifdef RX_LOCKS_COVERAGE
218 rxdb_RecordLockLocation(fileId, line)
219 afs_int32 fileId, line;
223 i = RXDB_LOCHASH(line);
225 /* Only enter lock location into list once. */
226 for (j = rxdb_lockLocHash[i]; j; j = rxdb_lockLocs[j].next) {
227 if ((rxdb_lockLocs[j].line == line)
228 && (rxdb_lockLocs[j].fileId == fileId))
232 /* Add lock to list. */
233 j = rxdb_lockLocs[0].next;
235 osi_Panic("rxdb_initLock: used up all the lock locations.\n");
238 /* Fix up free list. */
239 rxdb_lockLocs[0].next = rxdb_lockLocs[j].next;
241 /* Put new element at head of list. */
242 rxdb_lockLocs[j].next = rxdb_lockLocHash[i];
243 rxdb_lockLocs[j].prev = 0;
244 if (rxdb_lockLocHash[i]) {
245 rxdb_lockLocs[rxdb_lockLocHash[i]].prev = j;
247 rxdb_lockLocHash[i] = j;
249 /* Set data in element. */
250 rxdb_lockLocs[j].fileId = fileId;
251 rxdb_lockLocs[j].line = line;
254 #endif /* RX_LOCKS_COVERAGE */
257 /* Set lock as possessed by me. */
259 rxdb_grablock(a, id, fileId, line)
268 #ifdef RX_LOCKS_COVERAGE
269 rxdb_RecordLockLocation(fileId, line);
270 #endif /* RX_LOCKS_COVERAGE */
271 /* Is lock already held by anyone? */
272 for (i = 0; i < RXDB_HASHSIZE; i++) {
273 for (j = rxdb_idHash[i]; j; j = rxdb_lockList[j].next) {
274 if (rxdb_lockList[j].a == a) {
276 osi_Panic("rxdb_grablock: lock already held.");
282 j = rxdb_lockList[0].next;
284 osi_Panic("rxdb_grablock: rxdb_lockList is full.");
286 rxdb_lockList[0].next = rxdb_lockList[j].next;
288 /* Put element at head of list. */
289 rxdb_lockList[j].next = rxdb_idHash[i];
290 rxdb_lockList[j].prev = 0;
291 if (rxdb_idHash[i]) {
292 rxdb_lockList[rxdb_idHash[i]].prev = j;
296 /* Set data into element. */
297 rxdb_lockList[j].a = a;
298 rxdb_lockList[j].id = id;
299 rxdb_lockList[j].fileId = fileId;
300 rxdb_lockList[j].line = line;
306 rxdb_droplock(a, id, fileId, line)
316 #ifdef RX_LOCKS_COVERAGE
317 rxdb_RecordLockLocation(fileId, line);
318 #endif /* RX_LOCKS_COVERAGE */
321 /* Do I have the lock? */
322 i = rxdb_idHash[RXDB_IDHASH(id)];
323 for (j = i; j; j = rxdb_lockList[j].next) {
324 if (rxdb_lockList[j].a == a) {
331 osi_Panic("rxdb_unlock: lock not held by me.\n");
334 /* delete lock from queue. */
338 rxdb_idHash[i] = rxdb_lockList[j].next;
339 rxdb_lockList[rxdb_lockList[j].next].prev = 0;
341 if (rxdb_lockList[j].next)
342 rxdb_lockList[rxdb_lockList[j].next].prev = rxdb_lockList[j].prev;
343 rxdb_lockList[rxdb_lockList[j].prev].next = rxdb_lockList[j].next;
345 /* Put back on free list. */
346 rxdb_lockList[j].next = rxdb_lockList[0].next;
347 rxdb_lockList[j].prev = 0;
348 rxdb_lockList[0].next = j;
353 #endif /* (AIX41 || SGI53) && KERNEL */
355 #endif /* RX_LOCKS_DB */