[Libsysio-commit] HEAD: libsysio/include smp.h file.h inode.h mount.h sysio-cmn.h
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2008-06-17 17:19:06
|
Update of /cvsroot/libsysio/libsysio/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12543/include Modified Files: file.h inode.h mount.h sysio-cmn.h Added Files: smp.h Log Message: Begin adding support for thread-safe operation. In detail: 1) Add smp.h and smp_posix.c 2) Add a big lock, wrapping the user API with appropriate mutex_lock and mutex_unlock calls. NB; initialization is *not* thread safe. 3) Add support for P_{GET,LOCK}, PB_LOCK, I_{GET,LOCK}, FIL_{GET,LOCK} and alter all related ref/de-ref usage to use get/put or lock/unlock as appropriate. 4) Remedial (no-op) support for MNT_GET. By default, POSIX threads supoprt is not enabled. To enable, use --with-threads, or --with-threads=yes, or --with-threads=posix. --- NEW FILE --- #ifndef __SMP_H__ #define __SMP_H__ /* * Symmetric multi-processing abstraction. * * Allows compilation and execution to take place in two modes, single or * multi threaded. * * In single thread mode (define SINGLE_THREAD) most locking calls are * emulated. Others cause panics. For instance, it is very hard to * wait on a conditional variable with only a single thread -- no thread * to awaken things later. * * Structure: * * The structure of this file is blocks of implementation for a * mode or thread architecture surrounded by ifdef's. In the first part, * "real" thread packages are abstracted to the POSIX interface. In the * second (unsurrounded) part, common usage with asserts to catch errors, * that should never happen, is defined. * * More often than not, the unsurrounded interface should be used. You * can't though if the common usage doesn't match yours. For example, * if you want to take a mutex but are interested in the return code or * can't have the program abort on failure, use the under-score prepended * version of the routine. * * $Id: smp.h,v 1.1 2008/06/17 17:18:57 lward Exp $ */ #include <assert.h> #ifdef THREAD_MODEL_POSIX #include <pthread.h> #include <semaphore.h> #define THREAD_T_FMT "%lu" typedef pthread_t thread_t; #define thread_self() pthread_self() typedef pthread_mutex_t mutex_t; #define MUTEX_NORMAL PTHREAD_MUTEX_FAST_NP #define MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP extern int _posix_mutex_init_helper(mutex_t *mp, int typ); #define _mutex_init(mp, _typ) _posix_mutex_init_helper((mp), (_typ)) #define _mutex_destroy(mp) pthread_mutex_destroy(mp) #define _mutex_lock(mp) pthread_mutex_lock(mp) #define _mutex_trylock(mp) pthread_mutex_trylock(mp) #define _mutex_unlock(mp) pthread_mutex_unlock(mp) typedef pthread_cond_t cond_t; #define COND_INITIALIZER PTHREAD_COND_INITIALIZER #define _cond_init(condp) pthread_cond_init((condp), NULL) #define _cond_destroy(condp) pthread_cond_destroy(condp) #define _cond_wait(condp, mp) pthread_cond_wait((condp), (mp)) #define _cond_timedwait(condp, mp, tsp) \ pthread_cond_timedwait((condp), (mp), (tsp)) #define _cond_signal(condp) pthread_cond_signal(condp) #define _cond_broadcast(condp) pthread_cond_broadcast(condp) typedef pthread_once_t once_t; #define ONCE_INIT PTHREAD_ONCE_INIT #define _thread_once(oncp, f) pthread_once((oncp), (f)) typedef pthread_key_t thread_key_t; #define _thread_key_create(keyp, f) pthread_key_create((keyp), (f)) #define _thread_key_delete(key) pthread_key_delete(key) #define _thread_setspecific(key, p) pthread_setspecific((key), (p)) #define _thread_getspecific(key) pthread_getspecific(key) #define _thread_yield() sched_yield() #else typedef unsigned thread_t; #define thread_self() ((thread_t )(0)) typedef struct { unsigned initialized : 1, typ : 2; unsigned lckcnt; } mutex_t; #define MUTEX_NORMAL (1) #define MUTEX_RECURSIVE (2) #define __MUTEX_IF_INIT(mp, action) \ ((mp)->initialized ? (action) : EINVAL) #define __MUTEX_ON_TYPE(mp, normal, recursive) \ ((mp)->typ == MUTEX_NORMAL \ ? (normal) \ : ((mp)->typ == MUTEX_RECURSIVE \ ? (recursive) \ : EINVAL)) #define _mutex_init(mp, _typ) \ ((mp)->initialized = 1, \ (mp)->typ = (_typ), \ (mp)->lckcnt = 0, \ 0) #define _mutex_destroy(mp) \ __MUTEX_IF_INIT((mp), \ (!(mp)->lckcnt \ ? ((mp)->initialized = 0, 0) \ : EBUSY)) #define _mutex_lock(mp) \ __MUTEX_IF_INIT((mp), \ __MUTEX_ON_TYPE((mp), \ ((mp)->lckcnt \ ? EDEADLK \ : (mp)->lckcnt++), \ (++(mp)->lckcnt \ ? 0 \ : ERANGE))) #define _mutex_trylock(mp) \ __MUTEX_IF_INIT((mp), \ __MUTEX_ON_TYPE((mp), \ ((mp)->lckcnt \ ? EBUSY \ : (mp)->lckcnt++), \ (++(mp)->lckcnt \ ? 0 \ : ERANGE))) #define _mutex_unlock(mp) \ __MUTEX_IF_INIT((mp), ((mp)->lckcnt ? (--(mp)->lckcnt, 0) : ERANGE)) typedef unsigned cond_t; #define COND_INITIALIZER (1) #define __COND_IF_INIT(cond, action) \ (*(cond) == COND_INTIALIZER ? (action) : EINVAL) #define _cond_init(condp) ((int )(*(condp) = COND_INITIALIZER)) #define _cond_destroy(condp) ((int )(*(condp) = 0)) #define _cond_wait(condp, mp) \ (__COND_IF_INIT((condp), \ (__MUTEX_IF_INIT((mp), ENOSUP)))) #define _cond_timedwait(condp, mp, tsp) \ (__COND_IF_INIT((condp), \ (__MUTEX_IF_INIT((mp), ENOSUP)))) #define _cond_signal(condp) (0) #define _cond_broadcast(condp) (0) typedef int once_t; #define ONCE_INIT (0) #define _thread_once(oncp, f) (*(oncp) ? 0 : (*(f))(), *(oncp) = 1, 0) typedef struct _thread_key *thread_key_t; #define _thread_key_create(keyp, f) _single_thread_key_create((keyp), (f)) #define _thread_key_delete(key) _single_thread_key_delete(key) #define _thread_setspecific(key, p) _single_thread_setspecific((key), (p)) #define _thread_getspecific(key) _single_thread_getspecific(key) #define _thread_yield() ((int )0) extern int _single_thread_key_create(thread_key_t *, void (*)(void *)); extern int _single_thread_key_delete(thread_key_t); extern int _single_thread_setspecific(thread_key_t, void *); extern void *_single_thread_getspecific(thread_key_t); #endif /* thread model */ #define mutex_init(mp, _typ) assert(_mutex_init((mp), (_typ)) == 0) #define mutex_destroy(mp) assert(_mutex_destroy(mp) == 0) #define mutex_lock(mp) assert(_mutex_lock(mp) == 0) #define mutex_trylock(mp) _mutex_trylock(mp) #define mutex_unlock(mp) assert(_mutex_unlock(mp) == 0) #define cond_init(condp) assert(_cond_init(condp) == 0) #define cond_destroy(condp) assert(_cond_destroy(condp) == 0) #define cond_wait(condp, mp) assert(_cond_wait((condp), (mp)) == 0) #define cond_timedwait(condp, mp, tsp) \ _cond_timedwait((condp), (mp), (tsp)) #define cond_signal(condp) assert(_cond_signal(condp) == 0) #define cond_broadcast(condp) assert(_cond_broadcast(condp) == 0) #define sema_init(semp, val) assert(_sema_init((semp), (val)) == 0) #define sema_destroy(semp) assert(_sema_destroy(semp) == 0) #define sema_wait(semp) assert(_sema_wait(semp) == 0) #define sema_trywait(semp) _sema_trywait(semp) #define sema_post(semp) assert(_sema_post(semp) == 0) #define sema_getvalue(semp, valp) \ assert(_sema_getvalue((semp), (valp)) == 0) #define thread_once(oncp, f) assert(_thread_once((oncp), (f)) == 0) #define thread_key_create(keyp, f) \ assert(_thread_key_create((keyp), (f)) == 0) #define thread_key_delete(key) assert(_thread_key_delete(key) == 0) #define thread_setspecific(key, p) \ assert(_thread_setspecific((key), (p)) == 0) #define thread_getspecific(key) _thread_getspecific(key) #define thread_yield() assert(_thread_yield() == 0) #endif /* !defined(__SMP_H__) */ Index: file.h =================================================================== RCS file: /cvsroot/libsysio/libsysio/include/file.h,v retrieving revision 1.20 retrieving revision 1.21 diff -u -w -b -B -p -r1.20 -r1.21 --- file.h 20 Nov 2007 17:34:38 -0000 1.20 +++ file.h 17 Jun 2008 17:18:57 -0000 1.21 @@ -41,6 +41,8 @@ * le...@sa... */ +#include "smp.h" + /* * Open file support. */ @@ -49,17 +51,17 @@ * Test whether large file support on this file. */ #ifdef O_LARGEFILE -#define _F_LARGEFILE(fil) \ +#define _FIL_LARGEFILE(fil) \ ((fil)->f_flags & O_LARGEFILE) #else -#define _F_LARGEFILE(fil) \ +#define _FIL_LARGEFILE(fil) \ (1) #endif /* * Return max seek value for this file. */ #define _SEEK_MAX(fil) \ - (_F_LARGEFILE(fil) ? _SYSIO_OFF_T_MAX : LONG_MAX) + (_FIL_LARGEFILE(fil) ? _SYSIO_OFF_T_MAX : LONG_MAX) #ifdef _LARGEFILE64_SOURCE #define _SYSIO_FLOCK flock64 @@ -73,30 +75,97 @@ * operations that may be performed. */ struct file { + mutex_t f_mutex; /* record mutex */ + unsigned f_lckcnt; /* # recursive locks */ struct pnode *f_pno; /* path node */ _SYSIO_OFF_T f_pos; /* current stream pos */ unsigned f_ref; /* ref count */ int f_flags; /* open/fcntl flags */ }; +#ifdef LOCK_DEBUG +#define _FIL_CHECK_LOCK(_fil, _test) \ + (assert(((_test) && (_fil)->f_lckcnt) || \ + !((_test) || (_fil)->f_lckcnt))) +#else +#define _FIL_CHECK_LOCK(_fil, _test) +#endif + +#define FIL_LOCK(_fil) \ + do { \ + mutex_lock(&(_fil)->f_mutex); \ + (_fil)->f_lckcnt++; \ + _FIL_CHECK_LOCK((_fil), 1); \ + } while (0) + +#define FIL_UNLOCK(_fil) \ + do { \ + _FIL_CHECK_LOCK((_fil), 1); \ + (_fil)->f_lckcnt--; \ + if ((_fil)->f_ref) \ + mutex_unlock(&(_fil)->f_mutex); \ + else \ + _sysio_fgone(_fil); \ + } while (0) + +/* + * Reference a file record. + */ +#define _FIL_REF_NO_LOCK(_fil) \ + do { \ + _FIL_CHECK_LOCK((_fil), 1); \ + (_fil)->f_ref++; \ + assert((_fil)->f_ref); \ + } while (0) + /* * Reference a file record. */ -#define F_REF(fil) \ +#define FIL_REF(_fil) \ do { \ - (fil)->f_ref++; \ - assert((fil)->f_ref); \ + FIL_LOCK(_fil); \ + _FIL_REF_NO_LOCK(_fil); \ + FIL_UNLOCK(_fil); \ } while (0) /* * Release reference to a file record. */ -#define F_RELE(fil) \ +#define _FIL_RELE_NO_LOCK(_fil) \ + do { \ + _FIL_CHECK_LOCK((_fil), 1); \ + (_fil)->f_ref--; \ + } while (0) + +/* + * Release reference to a file record. + */ +#define FIL_RELE(_fil) \ + do { \ + FIL_LOCK(_fil); \ + _FIL_RELE_NO_LOCK(_fil); \ + FIL_UNLOCK(_fil); \ + } while (0) + +/* + * Lock and reference file node; Lock associated path node. + */ +#define FIL_GET(_fil) \ + do { \ + FIL_LOCK(_fil); \ + _FIL_REF_NO_LOCK(_fil); \ + P_GET((_fil)->f_pno); \ + } while (0) + +/* + * Unlock and drop reference to file node; Unlock associated path node. + */ +#define FIL_PUT(_fil) \ do { \ - assert((fil)->f_ref); \ - (fil)->f_ref--; \ - if (!(fil)->f_ref) \ - _sysio_fgone(fil); \ + _FIL_CHECK_LOCK((_fil), 1); \ + P_PUT((_fil)->f_pno); \ + _FIL_RELE_NO_LOCK(_fil); \ + FIL_UNLOCK(_fil); \ } while (0) /* @@ -106,6 +175,8 @@ struct file { */ #define _SYSIO_FINIT(fil, pno, flags) \ do { \ + mutex_init(&(fil)->f_mutex, MUTEX_RECURSIVE); \ + (fil)->f_lckcnt = 0; \ (fil)->f_pno = (pno); \ (fil)->f_pos = 0; \ (fil)->f_ref = 0; \ @@ -115,7 +186,7 @@ struct file { /* * Valid file object? */ -#define F_FILEOK(_fil) \ +#define FIL_FILEOK(_fil) \ ((_fil) && (_fil)->f_pno) /* @@ -129,7 +200,7 @@ struct file { * 'w' for write access check */ -#define F_CHKRW(_fil, _c) \ +#define FIL_CHKRW(_fil, _c) \ (((_c) == 'r' && !((_fil)->f_flags & O_WRONLY)) || \ ((_c) == 'w' && ((_fil)->f_flags & (O_WRONLY | O_RDWR)))) @@ -137,8 +208,8 @@ struct file { * Is file object writable? Return 0, if so. Otherwise, the appropriate * (negated) error number. */ -#define F_WRITEOK(_fil) \ - (!(F_FILEOK(_fil) && F_CHKRW((_fil), 'w')) \ +#define FIL_WRITEOK(_fil) \ + (!(FIL_FILEOK(_fil) && FIL_CHKRW((_fil), 'w')) \ ? -EBADF \ : (IS_RDONLY((_fil)->f_pno) ? -EROFS : 0)) Index: inode.h =================================================================== RCS file: /cvsroot/libsysio/libsysio/include/inode.h,v retrieving revision 1.38 retrieving revision 1.39 diff -u -w -b -B -p -r1.38 -r1.39 --- inode.h 23 Apr 2008 16:46:40 -0000 1.38 +++ inode.h 17 Jun 2008 17:18:57 -0000 1.39 @@ -41,6 +41,7 @@ * le...@sa... */ +#include "smp.h" #include "tree.h" #if defined(AUTOMOUNT_FILE_NAME) && !defined(MAX_MOUNT_DEPTH) @@ -133,6 +134,8 @@ struct inode_ops { */ struct inode { LIST_ENTRY(inode) i_link; /* FS i-nodes link */ + mutex_t i_mutex; /* record mutex */ + unsigned i_lckcnt; /* # recursive locks */ unsigned i_immune : 1, /* immune from GC */ i_zombie : 1; /* stale inode */ @@ -150,6 +153,8 @@ struct inode { */ #define I_INIT(ino, fs, stat, ops, fid, immunity, private) \ do { \ + mutex_init(&(ino)->i_mutex, MUTEX_RECURSIVE); \ + (ino)->i_lckcnt = 0; \ (ino)->i_immune = (immunity) ? 1 : 0; \ (ino)->i_zombie = 0; \ (ino)->i_ref = 0; \ @@ -160,34 +165,92 @@ struct inode { (ino)->i_private = (private); \ } while (0) +#ifdef LOCK_DEBUG +#define _I_CHECK_LOCK(_ino, _test) \ + (assert(((_test) && (_ino)->i_lckcnt) || \ + !((_test) || (_ino)->i_lckcnt))) +#else +#define _I_CHECK_LOCK(_ino, _test) +#endif + +#define I_LOCK(_ino) \ + do { \ + mutex_lock(&(_ino)->i_mutex); \ + (_ino)->i_lckcnt++; \ + _I_CHECK_LOCK(_ino, 1); \ + } while (0) + +#define I_UNLOCK(_ino) \ + do { \ + _I_CHECK_LOCK(_ino, 1); \ + --(_ino)->i_lckcnt; \ + mutex_unlock(&(_ino)->i_mutex); \ + } while (0) + /* * Take soft reference to i-node. */ -#define I_REF(ino) \ +#define _I_REF_NO_LOCK(_ino) \ + do { \ + _I_CHECK_LOCK((_ino), 1); \ + TAILQ_REMOVE(&_sysio_inodes, (_ino), i_nodes); \ + TAILQ_INSERT_TAIL(&_sysio_inodes, (_ino), i_nodes); \ + (_ino)->i_ref++; \ + assert((_ino)->i_ref); \ + } while (0) + +#define I_REF(_ino) \ + do { \ + I_LOCK(_ino); \ + _I_REF_NO_LOCK(_ino); \ + I_UNLOCK(_ino); \ + } while (0) + +/* + * Release soft reference to i-node, destroying it if last reference is + * removed. + */ +#define _I_RELE_NO_LOCK(_ino) \ + do { \ + _I_CHECK_LOCK((_ino), 1); \ + assert((_ino)->i_ref); \ + if (!--(_ino)->i_ref && (_ino)->i_zombie) \ + _sysio_i_gone((_ino)); \ + } while (0) + +#define I_RELE(_ino) \ + do { \ + I_LOCK(_ino); \ + _I_RELE_NO_LOCK(_ino); \ + I_UNLOCK(_ino); \ + } while (0) + +/* + * Lock and reference i-node. + */ +#define I_GET(_ino) \ do { \ - TAILQ_REMOVE(&_sysio_inodes, (ino), i_nodes); \ - TAILQ_INSERT_TAIL(&_sysio_inodes, (ino), i_nodes); \ - (ino)->i_ref++; \ - assert((ino)->i_ref); \ + I_LOCK(_ino); \ + _I_REF_NO_LOCK(_ino); \ } while (0) /* - * Release soft reference to i-node. + * Unlock and drop reference to i-node. */ -#define I_RELE(ino) \ +#define I_PUT(_ino) \ do { \ - assert((ino)->i_ref); \ - if (!--(ino)->i_ref && (ino)->i_zombie) \ - _sysio_i_gone(ino); \ + _I_RELE_NO_LOCK(_ino); \ + I_UNLOCK(_ino); \ } while (0) /* * Attempt to kill an inode. */ -#define I_GONE(ino) \ +#define I_GONE(_ino) \ do { \ - _sysio_i_undead(ino); \ - I_RELE(ino); \ + _I_CHECK_LOCK((_ino), 1); \ + _sysio_i_undead(_ino); \ + I_PUT(_ino); \ } while (0) /* @@ -202,11 +265,13 @@ struct qstr { }; /* - * A path node is an entry in a directory. It may have many aliases, one + * A path-base node is an entry in a directory. It may have many aliases, one * for each name space in which it occurs. This record holds the * common information. */ struct pnode_base { + mutex_t pb_mutex; /* record mutex */ + unsigned pb_lckcnt; /* # recursive locks */ struct tree_node pb_tentry; /* cache node entry */ struct pnode_base_key { struct qstr pbk_name; /* entry name */ @@ -222,6 +287,65 @@ struct pnode_base { }; /* + * Init a path-base record. + */ +#define PB_INIT(_pb, _name, _parent, _ino) \ + do { \ + mutex_init(&(_pb)->pb_mutex, MUTEX_RECURSIVE); \ + (_pb)->pb_lckcnt = 0; \ + (_pb)->pb_tentry.tn_key = &(_pb)->pb_key; \ + (_pb)->pb_tentry.tn_left = (_pb)->pb_tentry.tn_right = NULL; \ + (_pb)->pb_key.pbk_name = *(_name); \ + (_pb)->pb_key.pbk_parent = (_parent); \ + (_pb)->pb_ino = (_ino); \ + LIST_INIT(&(_pb)->pb_children); \ + LIST_INIT(&(_pb)->pb_aliases); \ + } while (0) + +#ifdef LOCK_DEBUG +#define _PB_CHECK_LOCK(_pb, _test) \ + (assert(((_test) && (_pb)->pb_lckcnt) || \ + !((_test) || (_pb)->pb_lckcnt))) +#else +#define _PB_CHECK_LOCK(_pb, _test) +#endif + +#define PB_LOCK(_pb) \ + do { \ + mutex_lock(&(_pb)->pb_mutex); \ + (_pb)->pb_lckcnt++; \ + _PB_CHECK_LOCK((_pb), 1); \ + } while (0) + +#define PB_UNLOCK(_pb) \ + do { \ + _PB_CHECK_LOCK((_pb), 1); \ + (_pb)->pb_lckcnt--; \ + mutex_unlock(&(_pb)->pb_mutex); \ + } while (0) + +/* + * Lock path-base node and get associated i-node if present. + */ +#define PB_GET(_pb) \ + do { \ + PB_LOCK(_pb); \ + if ((_pb)->pb_ino) \ + I_GET((_pb)->pb_ino); \ + } while (0) + +/* + * Unlock path-base node and put associated i-node if present. + */ +#define PB_PUT(_pb) \ + do { \ + _PB_CHECK_LOCK((_pb), 1); \ + if ((_pb)->pb_ino) \ + I_PUT((_pb)->pb_ino); \ + PB_UNLOCK(_pb); \ + } while (0) + +/* * Since a file system may be multiply mounted, in different parts of the local * tree, a file system object may appear in different places. We handle that * with aliases. There is one pnode for every alias the system is tracking. @@ -256,6 +380,8 @@ struct pnode_base { * The nodes link is bookkeeping. */ struct pnode { + mutex_t p_mutex; /* record mutex */ + unsigned p_lckcnt; /* # recursive locks */ unsigned p_ref; /* soft ref count */ struct pnode *p_parent; /* parent */ struct pnode_base *p_base; /* base part */ @@ -266,23 +392,97 @@ struct pnode { }; /* + * Init path node record. + */ +#define P_INIT(_pno, _parent, _pb, _mnt, _cover) \ + do { \ + mutex_init(&(_pno)->p_mutex, MUTEX_RECURSIVE); \ + (_pno)->p_lckcnt = 0; \ + (_pno)->p_ref = 0; \ + (_pno)->p_parent = (_parent); \ + (_pno)->p_base = (_pb); \ + (_pno)->p_mount = (_mnt); \ + (_pno)->p_cover = (_cover); \ + } while (0) + +#ifdef LOCK_DEBUG +#define _P_CHECK_LOCK(_pno, _test) \ + (assert(((_test) && (_pno)->p_lckcnt) || \ + !((_test) || (_pno)->p_lckcnt))) +#else +#define _P_CHECK_LOCK(_pno, _test) +#endif + +#define P_LOCK(_pno) \ + do { \ + mutex_lock(&(_pno)->p_mutex); \ + (_pno)->p_lckcnt++; \ + _P_CHECK_LOCK((_pno), 1); \ + } while (0) + +#define P_UNLOCK(_pno) \ + do { \ + _P_CHECK_LOCK((_pno), 1); \ + (_pno)->p_lckcnt--; \ + mutex_unlock(&(_pno)->p_mutex); \ + } while (0) + +/* * Reference path-tree node. */ -#define P_REF(pno) \ +#define _P_REF_NO_LOCK(_pno) \ + do { \ + _P_CHECK_LOCK((_pno), 1); \ + if (!(_pno)->p_ref++) \ + TAILQ_REMOVE(&_sysio_idle_pnodes, (_pno), p_idle); \ + assert((_pno)->p_ref); \ + } while (0) + +#define P_REF(_pno) \ do { \ - if (!(pno)->p_ref++) \ - TAILQ_REMOVE(&_sysio_idle_pnodes, (pno), p_idle); \ - assert((pno)->p_ref); \ + P_LOCK(_pno); \ + _P_REF_NO_LOCK(_pno); \ + P_UNLOCK(_pno); \ } while (0) /* * Release reference to path-tree node. */ -#define P_RELE(pno) \ +#define _P_RELE_NO_LOCK(_pno) \ + do { \ + _P_CHECK_LOCK((_pno), 1); \ + assert((_pno)->p_ref); \ + if (!--(_pno)->p_ref) \ + TAILQ_INSERT_TAIL(&_sysio_idle_pnodes, (_pno), p_idle); \ + } while (0) + +#define P_RELE(_pno) \ + do { \ + P_LOCK(_pno); \ + _P_RELE_NO_LOCK(_pno); \ + P_UNLOCK(_pno); \ + } while (0) + +/* + * Lock and reference pnode and get associated path-base node. + */ +#define P_GET(_pno) \ + do { \ + P_LOCK(_pno); \ + _P_REF_NO_LOCK(_pno); \ + PB_GET((_pno)->p_base); \ + } while (0) + +/* + * Unlock and drop reference to pnode and put associated path-base node. + * i-node. + */ +#define P_PUT(_pno) \ do { \ - assert((pno)->p_ref); \ - if (!--(pno)->p_ref) \ - TAILQ_INSERT_TAIL(&_sysio_idle_pnodes, (pno), p_idle); \ + _P_CHECK_LOCK((_pno), 1); \ + PB_PUT((_pno)->p_base); \ + _P_RELE_NO_LOCK(_pno); \ + P_UNLOCK(_pno); \ } while (0) /* @@ -525,7 +725,7 @@ extern struct pnode *_sysio_p_new_alias( struct mount *mnt); extern void _sysio_p_gone(struct pnode *pno); extern size_t _sysio_p_prune(struct pnode *root); -extern int _sysio_p_kill_all(struct pnode *root); +extern void _sysio_p_get2(struct pnode *pno1, struct pnode *pno2); extern int _sysio_pb_pathof(struct pnode_base *pb, char separator, char **pathp); Index: mount.h =================================================================== RCS file: /cvsroot/libsysio/libsysio/include/mount.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -w -b -B -p -r1.5 -r1.6 --- mount.h 24 Sep 2007 19:00:03 -0000 1.5 +++ mount.h 17 Jun 2008 17:18:57 -0000 1.6 @@ -69,7 +69,38 @@ struct mount { #define MOUNT_F_AUTO 0x02 /* automount enabled */ #endif +/* + * Mount status (internal state) flags. + */ +#define MOUNT_ST_IFST 0xf000 /* st flags bitmask */ #ifdef AUTOMOUNT_FILE_NAME +#define MOUNT_ST_IFAUTO 0x1000 /* automount */ +#endif + +/* + * Test macros for mount status. + */ +#define _MOUNT_ST_ISST(st, mask) \ + (((st) & MOUNT_ST_IFST) == (mask)) + +#ifdef MOUNT_ST_IFAUTO +#define MOUNT_ST_ISAUTO(st) _MOUNT_ST_ISST((st), MOUNT_ST_IFAUTO) +#endif + +/* + * Lock mount record. + */ +#define MNT_GET(_mnt) + +/* + * Unlock mount record. + */ +#define MNT_PUT(_mnt) + +#ifdef AUTOMOUNT_FILE_NAME +/* + * Relative name of file containing automount description. + */ extern struct qstr _sysio_mount_file_name; #endif Index: sysio-cmn.h =================================================================== RCS file: /cvsroot/libsysio/libsysio/include/sysio-cmn.h,v retrieving revision 1.19 retrieving revision 1.20 diff -u -w -b -B -p -r1.19 -r1.20 --- sysio-cmn.h 21 Sep 2007 19:36:59 -0000 1.19 +++ sysio-cmn.h 17 Jun 2008 17:18:57 -0000 1.20 @@ -41,6 +41,8 @@ * le...@sa... */ +#include "smp.h" + /* * System IO common information. */ @@ -248,9 +250,12 @@ extern void _sysio_run_trace_q(void *q, const char *fmt, ...); +extern mutex_t _sysio_biglock; + /* Interface enter/leave hook functions */ #define SYSIO_ENTER(tag, fmt, ...) \ do { \ + mutex_lock(&_sysio_biglock); \ _sysio_run_trace_q(_sysio_entry_trace_q, \ __FILE__, __func__, __LINE__, \ SYSIO_TTAG(tag), \ @@ -265,6 +270,7 @@ extern void _sysio_run_trace_q(void *q, SYSIO_TTAG(tag), \ (fmt), \ __VA_ARGS__); \ + mutex_unlock(&_sysio_biglock); \ } while (0) #else /* !defined(SYSIO_TRACING) */ |