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>
17 #include <afs/sysincludes.h>
18 #include <afsincludes.h>
24 #include <sys/param.h>
27 #include <afs/errors.h>
29 #ifdef AFS_PTHREAD_ENV
31 #endif /* AFS_PTHREAD_ENV */
46 * We currently only include below the errors that
47 * affect us the most. We should add to this list
48 * more code mappings, as necessary.
52 * Convert from the local (host) to the standard
53 * (network) system error code.
56 hton_syserr_conv(register afs_int32 code)
58 register afs_int32 err;
62 #if !defined(AFS_SUN5_ENV) && !defined(AFS_NT40_ENV) && !defined(AFS_DJGPP_ENV)
63 /* EDQUOT doesn't exist on solaris */
64 else if (code == EDQUOT)
74 * Convert from the standard (Network) format to the
75 * local (host) system error code.
78 ntoh_syserr_conv(int code)
80 register afs_int32 err;
82 if (code == VDISKFULL)
84 else if (code == VOVERQUOTA)
85 #if defined(AFS_SUN5_ENV) || defined(AFS_NT40_ENV) || defined(AFS_DJGPP_ENV)
98 * We provide the following because some systems (like aix) would fail if we pass
103 #ifdef AFS_PTHREAD_ENV
105 * This mutex protects the following global variables:
111 pthread_mutex_t osi_malloc_mutex;
112 #define LOCK_MALLOC_STATS assert(pthread_mutex_lock(&osi_malloc_mutex)==0)
113 #define UNLOCK_MALLOC_STATS assert(pthread_mutex_unlock(&osi_malloc_mutex)==0)
115 #define LOCK_MALLOC_STATS
116 #define UNLOCK_MALLOC_STATS
117 #endif /* AFS_PTHREAD_ENV */
118 long osi_alloccnt = 0, osi_allocsize = 0;
119 static const char memZero;
121 osi_alloc(afs_int32 x)
124 * 0-length allocs may return NULL ptr from osi_kalloc, so we special-case
125 * things so that NULL returned iff an error occurred
128 return (char *)&memZero;
133 return (char *)(mem_alloc(x));
137 osi_free(char *x, afs_int32 size)
139 if ((x == &memZero) || !x)
143 osi_allocsize -= size;
151 #if defined(RX_ENABLE_LOCKS) && defined(RX_REFCOUNT_CHECK)
152 int rx_callHoldType = 0;
157 /* What follows is a lock database for RX. There is currently room for 400
158 * locks to be held. Routines panic if there is an error. To port, add
159 * RX_LOCKS_DB versions of MUTEX_{ENTER, EXIT, TRYENTER} and CV_*WAIT to
160 * rx_kmutex.h and define lock macros below.
162 #if (defined(AFS_AIX41_ENV) || (defined(AFS_SGI53_ENV) && defined(MP))) && defined(KERNEL)
165 Simple_lock rxdb_lock;
166 #define RXDB_LOCK_INIT() lock_alloc(&rxdb_lock, LOCK_ALLOC_PIN, 1, 0), \
167 simple_lock_init(&rxdb_lock)
168 #define RXDB_LOCK_ENTER() simple_lock(&rxdb_lock)
169 #define RXDB_LOCK_EXIT() simple_unlock(&rxdb_lock)
170 #else /* AFS_AIX41_ENV */
172 afs_kmutex_t rxdb_lock;
173 #define RXDB_LOCK_INIT() mutex_init(&rxdb_lock, "rxdb lock", 0, 0)
174 #define RXDB_LOCK_ENTER() AFS_MUTEX_ENTER(&rxdb_lock)
175 #define RXDB_LOCK_EXIT() mutex_exit(&rxdb_lock)
176 #endif /* AFS_SGI53_ENV */
177 #endif /* AFS_AIX41_ENV */
180 int RXDB_LockPos = 0;
182 #define RXDB_NLOCKS 32
184 afs_int32 id; /* id of lock holder. */
185 void *a; /* address of lock. */
186 u_short fileId; /* fileID# of RX file. */
192 #define RXDB_HASHSIZE 8
195 struct rxdb_lock_t rxdb_lockList[RXDB_NLOCKS];
196 short rxdb_idHash[RXDB_HASHSIZE];
197 #define RXDB_IDHASH(id) ((((u_long)id)>>1) & (RXDB_HASHSIZE-1))
199 /* Record locations of all locks we enter/exit. */
200 struct rxdb_lockloc_t {
201 u_short fileId; /* fileID# of RX file. */
206 #ifdef RX_LOCKS_COVERAGE
207 #define RXDB_NlockLocs 512
208 #define RXDB_LOCHASHSIZE 256
209 struct rxdb_lockloc_t rxdb_lockLocs[RXDB_NlockLocs];
210 short rxdb_lockLocHash[RXDB_LOCHASHSIZE];
211 #define RXDB_LOCHASH(a) ((((u_long)a)) & (RXDB_LOCHASHSIZE-1))
212 #endif /* RX_LOCKS_COVERAGE */
214 /* Element 0 of each of the above arrays serves as the pointer to the list of
220 static int initted = 0;
231 for (i = 1; i < RXDB_NLOCKS - 1; i++) {
232 rxdb_lockList[i].next = i + 1;
233 rxdb_lockList[i].prev = i - 1;
235 rxdb_lockList[0].next = 1;
236 rxdb_lockList[0].prev = 0;
237 rxdb_lockList[RXDB_NLOCKS - 1].next = 0;
238 rxdb_lockList[RXDB_NLOCKS - 1].prev = RXDB_NLOCKS - 2;
240 #ifdef RX_LOCKS_COVERAGE
241 for (i = 1; i < RXDB_NlockLocs - 1; i++) {
242 rxdb_lockLocs[i].next = i + 1;
243 rxdb_lockLocs[i].prev = i - 1;
245 rxdb_lockLocs[0].next = 1;
246 rxdb_lockLocs[0].prev = 0;
247 rxdb_lockLocs[RXDB_NlockLocs - 1].next = 0;
248 rxdb_lockLocs[RXDB_NlockLocs - 1].prev = RXDB_NlockLocs - 2;
249 #endif /* RX_LOCKS_COVERAGE */
254 #ifdef RX_LOCKS_COVERAGE
256 rxdb_RecordLockLocation(fileId, line)
257 afs_int32 fileId, line;
261 i = RXDB_LOCHASH(line);
263 /* Only enter lock location into list once. */
264 for (j = rxdb_lockLocHash[i]; j; j = rxdb_lockLocs[j].next) {
265 if ((rxdb_lockLocs[j].line == line)
266 && (rxdb_lockLocs[j].fileId == fileId))
270 /* Add lock to list. */
271 j = rxdb_lockLocs[0].next;
273 osi_Panic("rxdb_initLock: used up all the lock locations.\n");
276 /* Fix up free list. */
277 rxdb_lockLocs[0].next = rxdb_lockLocs[j].next;
279 /* Put new element at head of list. */
280 rxdb_lockLocs[j].next = rxdb_lockLocHash[i];
281 rxdb_lockLocs[j].prev = 0;
282 if (rxdb_lockLocHash[i]) {
283 rxdb_lockLocs[rxdb_lockLocHash[i]].prev = j;
285 rxdb_lockLocHash[i] = j;
287 /* Set data in element. */
288 rxdb_lockLocs[j].fileId = fileId;
289 rxdb_lockLocs[j].line = line;
292 #endif /* RX_LOCKS_COVERAGE */
295 /* Set lock as possessed by me. */
297 rxdb_grablock(a, id, fileId, line)
306 #ifdef RX_LOCKS_COVERAGE
307 rxdb_RecordLockLocation(fileId, line);
308 #endif /* RX_LOCKS_COVERAGE */
309 /* Is lock already held by anyone? */
310 for (i = 0; i < RXDB_HASHSIZE; i++) {
311 for (j = rxdb_idHash[i]; j; j = rxdb_lockList[j].next) {
312 if (rxdb_lockList[j].a == a) {
314 osi_Panic("rxdb_grablock: lock already held.");
320 j = rxdb_lockList[0].next;
322 osi_Panic("rxdb_grablock: rxdb_lockList is full.");
324 rxdb_lockList[0].next = rxdb_lockList[j].next;
326 /* Put element at head of list. */
327 rxdb_lockList[j].next = rxdb_idHash[i];
328 rxdb_lockList[j].prev = 0;
329 if (rxdb_idHash[i]) {
330 rxdb_lockList[rxdb_idHash[i]].prev = j;
334 /* Set data into element. */
335 rxdb_lockList[j].a = a;
336 rxdb_lockList[j].id = id;
337 rxdb_lockList[j].fileId = fileId;
338 rxdb_lockList[j].line = line;
344 rxdb_droplock(a, id, fileId, line)
354 #ifdef RX_LOCKS_COVERAGE
355 rxdb_RecordLockLocation(fileId, line);
356 #endif /* RX_LOCKS_COVERAGE */
359 /* Do I have the lock? */
360 i = rxdb_idHash[RXDB_IDHASH(id)];
361 for (j = i; j; j = rxdb_lockList[j].next) {
362 if (rxdb_lockList[j].a == a) {
369 osi_Panic("rxdb_unlock: lock not held by me.\n");
372 /* delete lock from queue. */
376 rxdb_idHash[i] = rxdb_lockList[j].next;
377 rxdb_lockList[rxdb_lockList[j].next].prev = 0;
379 if (rxdb_lockList[j].next)
380 rxdb_lockList[rxdb_lockList[j].next].prev = rxdb_lockList[j].prev;
381 rxdb_lockList[rxdb_lockList[j].prev].next = rxdb_lockList[j].next;
383 /* Put back on free list. */
384 rxdb_lockList[j].next = rxdb_lockList[0].next;
385 rxdb_lockList[j].prev = 0;
386 rxdb_lockList[0].next = j;
391 #endif /* (AIX41 || SGI53) && KERNEL */
393 #endif /* RX_LOCKS_DB */