/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include RCSID("$Header$"); #ifdef KERNEL #include #include #else #ifdef AFS_NT40_ENV #include #include #else #include #endif #include #include #include "xdr.h" #ifdef AFS_PTHREAD_ENV #include "rx.h" #endif /* AFS_PTHREAD_ENV */ #include #ifdef HAVE_STRING_H #include #else #ifdef HAVE_STRINGS_H #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif #endif /* * We currently only include below the errors that * affect us the most. We should add to this list * more code mappings, as necessary. */ /* * Convert from the local (host) to the standard * (network) system error code. */ int hton_syserr_conv(register afs_int32 code) { register afs_int32 err; if (code == ENOSPC) err = VDISKFULL; #if !defined(AFS_SUN5_ENV) && !defined(AFS_NT40_ENV) && !defined(AFS_DJGPP_ENV) /* EDQUOT doesn't exist on solaris */ else if (code == EDQUOT) err = VOVERQUOTA; #endif else err = code; return err; } /* * Convert from the standard (Network) format to the * local (host) system error code. */ int ntoh_syserr_conv(int code) { register afs_int32 err; if (code == VDISKFULL) err = ENOSPC; else if (code == VOVERQUOTA) #if defined(AFS_SUN5_ENV) || defined(AFS_NT40_ENV) || defined(AFS_DJGPP_ENV) err = ENOSPC; #else err = EDQUOT; #endif else err = code; return err; } #ifndef KERNEL /* * We provide the following because some systems (like aix) would fail if we pass * 0 as length. */ #ifndef osi_alloc #ifdef AFS_PTHREAD_ENV /* * This mutex protects the following global variables: * osi_alloccnt * osi_allocsize */ #include pthread_mutex_t osi_malloc_mutex; #define LOCK_MALLOC_STATS assert(pthread_mutex_lock(&osi_malloc_mutex)==0); #define UNLOCK_MALLOC_STATS assert(pthread_mutex_unlock(&osi_malloc_mutex)==0); #else #define LOCK_MALLOC_STATS #define UNLOCK_MALLOC_STATS #endif /* AFS_PTHREAD_ENV */ long osi_alloccnt=0, osi_allocsize=0; static const char memZero; char *osi_alloc(afs_int32 x) { /* * 0-length allocs may return NULL ptr from osi_kalloc, so we special-case * things so that NULL returned iff an error occurred */ if (x == 0) return (char *)&memZero; LOCK_MALLOC_STATS osi_alloccnt++; osi_allocsize += x; UNLOCK_MALLOC_STATS return (char *)(mem_alloc(x)); } int osi_free(char *x, afs_int32 size) { if ((x == &memZero) || !x) return 0; LOCK_MALLOC_STATS osi_alloccnt--; osi_allocsize -= size; UNLOCK_MALLOC_STATS mem_free(x, size); return 0; } #endif #endif /* KERNEL */ #if defined(RX_ENABLE_LOCKS) && defined(RX_REFCOUNT_CHECK) int rx_callHoldType = 0; #endif #ifdef RX_LOCKS_DB /* What follows is a lock database for RX. There is currently room for 400 * locks to be held. Routines panic if there is an error. To port, add * RX_LOCKS_DB versions of MUTEX_{ENTER, EXIT, TRYENTER} and CV_*WAIT to * rx_kmutex.h and define lock macros below. */ #if (defined(AFS_AIX41_ENV) || (defined(AFS_SGI53_ENV) && defined(MP))) && defined(KERNEL) #ifdef AFS_AIX41_ENV Simple_lock rxdb_lock; #define RXDB_LOCK_INIT() lock_alloc(&rxdb_lock, LOCK_ALLOC_PIN, 1, 0), \ simple_lock_init(&rxdb_lock) #define RXDB_LOCK_ENTER() simple_lock(&rxdb_lock) #define RXDB_LOCK_EXIT() simple_unlock(&rxdb_lock) #else /* AFS_AIX41_ENV */ #ifdef AFS_SGI53_ENV afs_kmutex_t rxdb_lock; #define RXDB_LOCK_INIT() mutex_init(&rxdb_lock, "rxdb lock", 0, 0) #define RXDB_LOCK_ENTER() AFS_MUTEX_ENTER(&rxdb_lock) #define RXDB_LOCK_EXIT() mutex_exit(&rxdb_lock) #endif /* AFS_SGI53_ENV */ #endif /* AFS_AIX41_ENV */ int RXDB_LockPos = 0; #define RXDB_NLOCKS 32 struct rxdb_lock_t { afs_int32 id; /* id of lock holder. */ void * a; /* address of lock. */ u_short fileId; /* fileID# of RX file. */ u_short line; u_short next; u_short prev; }; #define RXDB_HASHSIZE 8 struct rxdb_lock_t rxdb_lockList[RXDB_NLOCKS]; short rxdb_idHash[RXDB_HASHSIZE]; #define RXDB_IDHASH(id) ((((u_long)id)>>1) & (RXDB_HASHSIZE-1)) /* Record locations of all locks we enter/exit. */ struct rxdb_lockloc_t { u_short fileId; /* fileID# of RX file. */ u_short line; u_short next; u_short prev; }; #ifdef RX_LOCKS_COVERAGE #define RXDB_NlockLocs 512 #define RXDB_LOCHASHSIZE 256 struct rxdb_lockloc_t rxdb_lockLocs[RXDB_NlockLocs]; short rxdb_lockLocHash[RXDB_LOCHASHSIZE]; #define RXDB_LOCHASH(a) ((((u_long)a)) & (RXDB_LOCHASHSIZE-1)) #endif /* RX_LOCKS_COVERAGE */ /* Element 0 of each of the above arrays serves as the pointer to the list of * free elements. */ void rxdb_init(void) { static int initted = 0; int i; if (initted) return; initted = 1; RXDB_LOCK_INIT(); RXDB_LOCK_ENTER(); for (i=1; i