[OpenAFS-port-freebsd] Making more progress....
Garrett Wollman
wollman@khavrinen.lcs.mit.edu
Wed, 8 Oct 2003 01:40:52 -0400 (EDT)
Updated patch available at
<http://lcs.mit.edu/~wollman/openafs-fbsd52.patch>. Changes in this
version:
- Doesn't crash when doing heavy recycling (e.g., listing
/afs/sipb.mit.edu/users with a small cache).
- I've rebroken shutdown (will investigate when I am sufficiently
awake again).
- Redundant vop_lock family routines eliminated (the standard ones are
just fine for our purposes).
- Includes correct fix for vop_symlink.
- Includes preliminary autoconf glue to test for POSIX regex(3),
eliminating need for libcompat. (Same change should be made for
OpenBSD.) Jim Rees, feel free to commit these parts.
-GAWollman
(Patch included below for ease of review/commentary....)
Index: acinclude.m4
===================================================================
RCS file: /cvs/openafs/acinclude.m4,v
retrieving revision 1.90
diff -u -r1.90 acinclude.m4
--- acinclude.m4 25 Sep 2003 16:26:10 -0000 1.90
+++ acinclude.m4 8 Oct 2003 05:09:20 -0000
@@ -806,7 +806,7 @@
AC_CHECK_HEADERS(mntent.h sys/vfs.h sys/param.h sys/fs_types.h sys/fstyp.h)
AC_CHECK_HEADERS(sys/mount.h strings.h termios.h signal.h)
AC_CHECK_HEADERS(windows.h malloc.h winsock2.h direct.h io.h)
-AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h)
+AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h regex.h)
if test "$ac_cv_header_security_pam_modules_h" = "yes"; then
HAVE_PAM="yes"
@@ -817,6 +817,19 @@
AC_CHECK_FUNCS(utimes random srandom getdtablesize snprintf strlcat strlcpy re_comp re_exec)
AC_CHECK_FUNCS(setprogname getprogname sigaction mkstemp vsnprintf strerror)
+
+AC_CHECK_FUNCS(regcomp regexec regerror)
+AC_MSG_CHECKING([if you have the complete POSIX regex library])
+if test "$ac_cv_header_regex_h" = "yes" && \
+ test "$ac_cv_func_regcomp" = "yes" && \
+ test "$ac_cv_func_regexec" = "yes" && \
+ test "$ac_cv_func_regerror" = "yes"; then
+ AC_DEFINE(HAVE_POSIX_REGEX)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
AC_CHECK_TYPE(ssize_t, int)
AC_SIZEOF_TYPE(long)
Index: src/afs/afs.h
===================================================================
RCS file: /cvs/openafs/src/afs/afs.h,v
retrieving revision 1.42
diff -u -r1.42 afs.h
--- src/afs/afs.h 29 Aug 2003 22:00:04 -0000 1.42
+++ src/afs/afs.h 8 Oct 2003 05:09:34 -0000
@@ -545,15 +545,11 @@
#define VPageCleaning 0x2 /* Solaris - Cache Trunc Daemon sez keep out */
#define CPSIZE 2
-#if defined(AFS_FBSD_ENV)
-#define vrefCount v.v_usecount
-#else
-#if defined(AFS_OBSD_ENV)
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
#define vrefCount v->v_usecount
#else
#define vrefCount v.v_count
-#endif /* AFS_OBSD_ENV */
-#endif /* AFS_FBSD_ENV */
+#endif /* AFS_[OF]BSD_ENV */
#ifdef AFS_LINUX24_ENV
#define VREFCOUNT(v) atomic_read(&((vnode_t *) v)->v_count)
@@ -598,7 +594,7 @@
extern afs_uint32 afs_stampValue; /* stamp for pair's usage */
#define MakeStamp() (++afs_stampValue)
-#if defined(AFS_OBSD_ENV)
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
#define VTOAFS(v) ((struct vcache *)(v)->v_data)
#define AFSTOV(vc) ((vc)->v)
#else
@@ -616,7 +612,7 @@
* !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
*/
struct vcache {
-#if defined(AFS_OBSD_ENV)
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
struct vnode *v;
#else
struct vnode v; /* Has reference count in v.v_count */
Index: src/afs/afs_call.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_call.c,v
retrieving revision 1.62
diff -u -r1.62 afs_call.c
--- src/afs/afs_call.c 8 Aug 2003 21:54:34 -0000 1.62
+++ src/afs/afs_call.c 8 Oct 2003 05:09:36 -0000
@@ -64,13 +64,12 @@
struct lock__bsd__ afs_global_lock;
#endif
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD50_ENV)
struct lock afs_global_lock;
-#ifdef AFS_FBSD50_ENV
-struct thread *afs_global_owner;
-#else
struct proc *afs_global_owner;
#endif
+#ifdef AFS_FBSD50_ENV
+struct mtx afs_global_mtx;
#endif
#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
Index: src/afs/afs_init.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_init.c,v
retrieving revision 1.26
diff -u -r1.26 afs_init.c
--- src/afs/afs_init.c 15 Jul 2003 23:14:12 -0000 1.26
+++ src/afs/afs_init.c 8 Oct 2003 05:09:37 -0000
@@ -41,7 +41,7 @@
int afs_sysnamecount = 0;
struct volume *Initialafs_freeVolList;
int afs_memvolumes = 0;
-#ifdef AFS_OBSD_ENV
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
static struct vnode *volumeVnode;
#endif
@@ -295,7 +295,7 @@
struct osi_file *tfile;
AFS_STATCNT(afs_InitVolumeInfo);
-#if defined(AFS_OBSD_ENV)
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
/*
* On Open/NetBSD, we can get into big trouble if we don't hold the volume file
* vnode. SetupVolume holds afs_xvolume lock exclusive.
@@ -428,19 +428,24 @@
cacheInode = filevp->i_ino;
afs_cacheSBp = filevp->i_sb;
#else
-#ifdef AFS_OBSD_ENV
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
cacheInode = VTOI(filevp)->i_number;
cacheDev.mp = filevp->v_mount;
cacheDev.held_vnode = filevp;
+#ifdef AFS_OBSD_ENV
AFS_HOLD(filevp); /* Make sure mount point stays busy. XXX */
#else
+ vref(filevp);
+ afs_cacheVfsp = filevp->v_vfsp;
+#endif
+#else
#if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
afs_InitDualFSCacheOps(filevp);
#endif
cacheInode = afs_vnodeToInumber(filevp);
cacheDev.dev = afs_vnodeToDev(filevp);
afs_cacheVfsp = filevp->v_vfsp;
-#endif /* AFS_OBSD_ENV */
+#endif /* !AFS_[FO]BSD_ENV */
#endif /* AFS_LINUX20_ENV */
AFS_RELE(filevp);
#endif /* AFS_LINUX22_ENV */
@@ -494,10 +499,12 @@
RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock");
RWLOCK_INIT(&afs_xinterface, "afs_xinterface");
LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
+#ifndef AFS_FBSD_ENV
#ifndef AFS_AIX32_ENV
LOCK_INIT(&osi_fsplock, "osi_fsplock");
#endif
LOCK_INIT(&osi_flplock, "osi_flplock");
+#endif
RWLOCK_INIT(&afs_xconn, "afs_xconn");
afs_CellInit();
@@ -669,11 +676,19 @@
afs_cacheFiles = afs_cacheBlocks = 0;
pag_epoch = maxIHint = nihints = usedihint = 0;
pagCounter = 0;
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
#ifdef AFS_OBSD_ENV
AFS_RELE(volumeVnode); /* let it go, finally. */
+#else
+ vrele(volumeVnode);
+#endif
volumeVnode = NULL;
if (cacheDev.held_vnode) {
+#ifdef AFS_OBSD_ENV
AFS_RELE(cacheDev.held_vnode);
+#else
+ vrele(cacheDev.held_vnode);
+#endif
cacheDev.held_vnode = NULL;
}
#endif
Index: src/afs/afs_osi.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_osi.c,v
retrieving revision 1.38
diff -u -r1.38 afs_osi.c
--- src/afs/afs_osi.c 27 Aug 2003 21:43:16 -0000 1.38
+++ src/afs/afs_osi.c 8 Oct 2003 05:09:38 -0000
@@ -57,6 +57,8 @@
#elif defined(AFS_OSF_ENV)
usimple_lock_init(&afs_global_lock);
afs_global_owner = (thread_t) 0;
+#elif defined(AFS_FBSD50_ENV)
+ mtx_init(&afs_global_mtx, "AFS global lock", NULL, MTX_DEF);
#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0);
afs_global_owner = 0;
@@ -433,6 +435,8 @@
AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
#ifdef AFS_LINUX20_ENV
return osi_linux_alloc(x, 1);
+#elif defined(AFS_FBSD_ENV)
+ return osi_fbsd_alloc(x, 1);
#else
size = x;
tm = (struct osimem *)AFS_KALLOC(size);
@@ -479,6 +483,8 @@
AFS_STATS(afs_stats_cmperf.OutStandingMemUsage -= asize);
#if defined(AFS_LINUX20_ENV)
osi_linux_free(x);
+#elif defined(AFS_FBSD_ENV)
+ osi_fbsd_free(x);
#else
AFS_KFREE((struct osimem *)x, asize);
#endif
Index: src/afs/afs_osi.h
===================================================================
RCS file: /cvs/openafs/src/afs/afs_osi.h,v
retrieving revision 1.19
diff -u -r1.19 afs_osi.h
--- src/afs/afs_osi.h 29 Aug 2003 22:00:04 -0000 1.19
+++ src/afs/afs_osi.h 8 Oct 2003 05:09:38 -0000
@@ -13,6 +13,10 @@
#include "h/types.h"
#include "h/param.h"
+#ifdef AFS_FBSD50_ENV
+#include <sys/condvar.h>
+#endif
+
#ifdef AFS_LINUX20_ENV
#ifndef _LINUX_CODA_FS_I
#define _LINUX_CODA_FS_I
@@ -68,11 +72,13 @@
};
struct osi_dev {
-#ifdef AFS_OBSD_ENV
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
struct mount *mp;
struct vnode *held_vnode;
+/* see if we need this...
#elif defined(AFS_FBSD50_ENV)
struct cdev *dev;
+*/
#elif defined(AFS_AIX42_ENV)
dev_t dev;
#else
@@ -81,7 +87,12 @@
};
struct afs_osi_WaitHandle {
+#ifdef AFS_FBSD50_ENV
+ struct cv wh_condvar;
+ int wh_inited; /* XXX */
+#else
caddr_t proc; /* process waiting */
+#endif
};
#define osi_SetFileProc(x,p) ((x)->proc=(p))
Index: src/afs/afs_osi_alloc.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_osi_alloc.c,v
retrieving revision 1.9
diff -u -r1.9 afs_osi_alloc.c
--- src/afs/afs_osi_alloc.c 15 Jul 2003 23:14:12 -0000 1.9
+++ src/afs/afs_osi_alloc.c 8 Oct 2003 05:09:39 -0000
@@ -19,6 +19,7 @@
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
+#ifndef AFS_FBSD_ENV
#ifdef AFS_AIX41_ENV
#include "sys/lockl.h"
#include "sys/sleep.h"
@@ -368,3 +369,4 @@
LOCK_INIT(&osi_flplock, "osi_flplock");
}
}
+#endif
Index: src/afs/afs_prototypes.h
===================================================================
RCS file: /cvs/openafs/src/afs/afs_prototypes.h,v
retrieving revision 1.42
diff -u -r1.42 afs_prototypes.h
--- src/afs/afs_prototypes.h 15 Jul 2003 23:14:12 -0000 1.42
+++ src/afs/afs_prototypes.h 8 Oct 2003 05:09:39 -0000
@@ -465,8 +465,12 @@
extern void afs_osi_MaskSignals(void);
extern void afs_osi_UnmaskRxkSignals(void);
extern void *afs_osi_Alloc(size_t x);
+#ifndef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t x);
+#endif
+#ifndef afs_osi_Free
extern void afs_osi_Free(void *x, size_t asize);
+#endif
extern void afs_osi_FreeStr(char *x);
extern void osi_Init(void);
extern int osi_Active(register struct vcache *avc);
@@ -503,9 +507,11 @@
extern afs_int32 PagInCred(const struct AFS_UCRED *cred);
/* afs_osi_alloc.c */
+#ifndef AFS_FBSD_ENV
extern afs_int32 afs_preallocs;
extern afs_lock_t osi_fsplock;
extern afs_lock_t osi_flplock;
+#endif
extern void osi_FreeLargeSpace(void *adata);
extern void osi_FreeMediumSpace(void *adata);
extern void osi_FreeSmallSpace(void *adata);
Index: src/afs/afs_vcache.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_vcache.c,v
retrieving revision 1.55
diff -u -r1.55 afs_vcache.c
--- src/afs/afs_vcache.c 3 Sep 2003 16:47:15 -0000 1.55
+++ src/afs/afs_vcache.c 8 Oct 2003 05:09:42 -0000
@@ -153,7 +153,7 @@
afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
avc->linkData = NULL;
}
-#if defined(AFS_OBSD_ENV)
+#if defined(AFS_XBSD_ENV)
/* OK, there are no internal vrefCounts, so there shouldn't
* be any more refs here. */
if (avc->v) {
@@ -801,36 +801,6 @@
continue; /* start over - may have raced. */
}
}
-#elif defined(AFS_FBSD50_ENV)
- if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
- && (tvc->states & CUnlinkedDel) == 0) {
- if (!(VOP_LOCK(&tvc->v, LK_EXCLUSIVE, curthread))) {
- if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
- && (tvc->states & CUnlinkedDel) == 0) {
- VREFCOUNT_DEC(tvc);
- AFS_GUNLOCK(); /* perhaps inline inactive for locking */
- VOP_INACTIVE(&tvc->v, curthread);
- AFS_GLOCK();
- } else {
- VOP_UNLOCK(&tvc->v, 0, curthread);
- }
- }
- }
-#elif defined(AFS_FBSD_ENV) && !defined(AFS_FBSD50_ENV)
- if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
- && (tvc->states & CUnlinkedDel) == 0) {
- if (!(VOP_LOCK(&tvc->v, LK_EXCLUSIVE, curproc))) {
- if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
- && (tvc->states & CUnlinkedDel) == 0) {
- VREFCOUNT_DEC(tvc);
- AFS_GUNLOCK(); /* perhaps inline inactive for locking */
- VOP_INACTIVE(&tvc->v, curproc);
- AFS_GLOCK();
- } else {
- VOP_UNLOCK(&tvc->v, 0, curproc);
- }
- }
- }
#elif defined(AFS_LINUX22_ENV)
if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0)
afs_TryFlushDcacheChildren(tvc);
@@ -838,12 +808,13 @@
if (VREFCOUNT(tvc) == 0 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
-#ifdef AFS_OBSD_ENV
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
/*
* vgone() reclaims the vnode, which calls afs_FlushVCache(),
* then it puts the vnode on the free list.
* If we don't do this we end up with a cleaned vnode that's
* not on the free list.
+ * XXX assume FreeBSD is the same for now.
*/
vgone(AFSTOV(tvc));
code = fv_slept = 0;
@@ -907,7 +878,7 @@
vm_info_ptr = tvc->v.v_vm_info;
#endif /* AFS_MACH_ENV */
-#if defined(AFS_OBSD_ENV)
+#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
if (tvc->v)
panic("afs_NewVCache(): free vcache with vnode attached");
#endif
@@ -931,6 +902,32 @@
afs_nbsd_getnewvnode(tvc); /* includes one refcount */
lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
#endif
+#ifdef AFS_FBSD_ENV
+ {
+ struct vnode *vp;
+
+ AFS_GUNLOCK();
+ if (getnewvnode("afs", afs_globalVFS, afs_vnodeop_p, &vp))
+ panic("afs getnewvnode"); /* can't happen */
+ AFS_GLOCK();
+ if (tvc->v != NULL) {
+ /* I'd like to know if this ever happens...
+ We don't drop global for the rest of this function,
+ so if we do lose the race, the other thread should
+ have found the same vnode and finished initializing
+ the vcache entry. Is it conceivable that this vcache
+ entry could be recycled during this interval? If so,
+ then there probably needs to be some sort of additional
+ mutual exclusion (an Embryonic flag would suffice).
+ -GAW */
+ printf("afs_NewVCache: lost the race\n");
+ return (tvc);
+ }
+ tvc->v = vp;
+ tvc->v->v_data = tvc;
+ lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
+ }
+#endif
tvc->parentVnode = 0;
tvc->mvid = NULL;
tvc->linkData = NULL;
@@ -955,9 +952,9 @@
/* Hold it for the LRU (should make count 2) */
VN_HOLD(AFSTOV(tvc));
#else /* AFS_OSF_ENV */
-#ifndef AFS_OBSD_ENV
+#if !defined(AFS_OBSD_ENV) && !defined(AFS_FBSD_ENV)
VREFCOUNT_SET(tvc, 1); /* us */
-#endif /* AFS_OBSD_ENV */
+#endif /* AFS_[FO]BSD_ENV */
#endif /* AFS_OSF_ENV */
#ifdef AFS_AIX32_ENV
LOCK_INIT(&tvc->pvmlock, "vcache pvmlock");
@@ -1038,14 +1035,6 @@
tvc->v.v_freelist.tqe_prev = (struct vnode **)0xdeadb;
/*tvc->vrefCount++; */
#endif
-#ifdef AFS_FBSD_ENV
- lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0);
- cache_purge(AFSTOV(tvc));
- tvc->v.v_data = tvc;
- tvc->v.v_tag = VT_AFS;
- tvc->v.v_usecount++; /* steal an extra ref for now so vfree never happens */
- /* This extra ref is dealt with above... */
-#endif
/*
* The proper value for mvstat (for root fids) is setup by the caller.
*/
@@ -1798,6 +1787,40 @@
VOP_LOCK(AFSTOV(tvc), LK_EXCLUSIVE | LK_RETRY, curproc);
uvm_vnp_uncache(AFSTOV(tvc));
VOP_UNLOCK(AFSTOV(tvc), 0, curproc);
+#endif
+#ifdef AFS_FBSD_ENV
+ /*
+ * XXX - I really don't like this. Should try to understand better.
+ * It seems that sometimes, when we get called, we already hold the
+ * lock on the vnode (e.g., from afs_getattr via afs_VerifyVCache).
+ * We can't drop the vnode lock, because that could result in a race.
+ * Sometimes, though, we get here and don't hold the vnode lock.
+ * I hate code paths that sometimes hold locks and sometimes don't.
+ * In any event, the dodge we use here is to check whether the vnode
+ * is locked, and if it isn't, then we gain and drop it around the call
+ * to vinvalbuf; otherwise, we leave it alone.
+ */
+ {
+ struct vnode *vp;
+ int iheldthelock;
+
+ vp = AFSTOV(tvc);
+#ifdef AFS_FBSD50_ENV
+ iheldthelock = VOP_ISLOCKED(vp, curthread);
+ if (!iheldthelock)
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
+ vinvalbuf(vp, V_SAVE, curthread->td_ucred, curthread, PINOD, 0);
+ if (!iheldthelock)
+ VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
+#else
+ iheldthelock = VOP_ISLOCKED(vp, curproc);
+ if (!iheldthelock)
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
+ vinvalbuf(vp, V_SAVE, curthread->td_ucred, curproc, PINOD, 0);
+ if (!iheldthelock)
+ VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
+#endif
+ }
#endif
ObtainWriteLock(&afs_xcbhash, 464);
Index: src/afs/FBSD/osi_file.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_file.c,v
retrieving revision 1.12
diff -u -r1.12 osi_file.c
--- src/afs/FBSD/osi_file.c 9 Sep 2003 21:14:34 -0000 1.12
+++ src/afs/FBSD/osi_file.c 8 Oct 2003 05:09:43 -0000
@@ -73,7 +73,9 @@
MObtainWriteLock(&afs_xosi, 320);
AFS_GUNLOCK();
#if defined(AFS_FBSD50_ENV)
+ vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY, curthread);
code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
+ VOP_UNLOCK(afile->vnode, LK_EXCLUSIVE, curthread);
#else
code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
#endif
@@ -104,25 +106,41 @@
osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
{
struct vattr tvattr;
+ struct vnode *vp;
register afs_int32 code;
- struct osi_stat tstat;
AFS_STATCNT(osi_Truncate);
- /* This routine only shrinks files, and most systems
+ MObtainWriteLock(&afs_xosi, 321);
+ vp = afile->vnode;
+ /*
+ * This routine only shrinks files, and most systems
* have very slow truncates, even when the file is already
* small enough. Check now and save some time.
*/
- code = afs_osi_Stat(afile, &tstat);
- if (code || tstat.size <= asize)
- return code;
- MObtainWriteLock(&afs_xosi, 321);
+ AFS_GUNLOCK();
+#if defined(AFS_FBSD50_ENV)
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
+ code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
+#else
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
+ code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
+#endif
+ if (code != 0 || tvattr.va_size <= asize)
+ goto out;
+
VATTR_NULL(&tvattr);
tvattr.va_size = asize;
- AFS_GUNLOCK();
#if defined(AFS_FBSD50_ENV)
- code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
+ code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curthread);
+#else
+ code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curproc);
+#endif
+
+out:
+#if defined(AFS_FBSD50_ENV)
+ VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
#else
- code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
+ VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
#endif
AFS_GLOCK();
MReleaseWriteLock(&afs_xosi);
Index: src/afs/FBSD/osi_machdep.h
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_machdep.h,v
retrieving revision 1.7
diff -u -r1.7 osi_machdep.h
--- src/afs/FBSD/osi_machdep.h 15 Jul 2003 23:14:19 -0000 1.7
+++ src/afs/FBSD/osi_machdep.h 8 Oct 2003 05:09:43 -0000
@@ -21,6 +21,7 @@
#include <sys/lock.h>
#include <sys/time.h>
+#include <sys/mutex.h>
/* #include <kern/sched_prim.h> */
/* #include <sys/unix_defs.h> */
@@ -42,7 +43,13 @@
#define iodone biodone
#endif
-#define osi_vnhold(avc,r) do { VN_HOLD((struct vnode *)(avc)); } while (0)
+#define osi_vnhold(avc,r) vref(AFSTOV(avc))
+#undef vSetVfsp
+#define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp)
+#undef vSetType
+#define vSetType(vc, type) AFSTOV(vc)->v_type = (type)
+#undef vType
+#define vType(vc) AFSTOV(vc)->v_type
#undef gop_lookupname
#define gop_lookupname osi_lookupname
@@ -52,7 +59,9 @@
#define afs_strcat(s1, s2) strcat((s1), (s2))
#ifdef KERNEL
-extern struct lock afs_global_lock;
+
+#undef afs_osi_Alloc_NoSleep
+#define afs_osi_Alloc_NoSleep(size) osi_fbsd_alloc((size), 0)
#if defined(AFS_FBSD50_ENV)
#define VT_AFS "afs"
@@ -64,24 +73,13 @@
#define simple_unlock(x) mtx_unlock(x)
#define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(cred),(aresid), curthread)
-extern struct thread *afs_global_owner;
-#define AFS_GLOCK() \
- do { \
- osi_Assert(curthread); \
- lockmgr(&afs_global_lock, LK_EXCLUSIVE, 0, curthread); \
- osi_Assert(afs_global_owner == 0); \
- afs_global_owner = curthread; \
- } while (0)
-#define AFS_GUNLOCK() \
- do { \
- osi_Assert(curthread); \
- osi_Assert(afs_global_owner == curthread); \
- afs_global_owner = 0; \
- lockmgr(&afs_global_lock, LK_RELEASE, 0, curthread); \
- } while(0)
-#define ISAFS_GLOCK() (afs_global_owner == curthread && curthread)
+extern struct mtx afs_global_mtx;
+#define AFS_GLOCK() mtx_lock(&afs_global_mtx)
+#define AFS_GUNLOCK() mtx_unlock(&afs_global_mtx)
+#define ISAFS_GLOCK() (mtx_owned(&afs_global_mtx))
#else /* FBSD50 */
+extern struct lock afs_global_lock;
#define osi_curcred() (curproc->p_cred->pc_ucred)
#define getpid() curproc
Index: src/afs/FBSD/osi_misc.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_misc.c,v
retrieving revision 1.8
diff -u -r1.8 osi_misc.c
--- src/afs/FBSD/osi_misc.c 15 Jul 2003 23:14:19 -0000 1.8
+++ src/afs/FBSD/osi_misc.c 8 Oct 2003 05:09:43 -0000
@@ -53,7 +53,12 @@
struct vnode **dirvpp, struct vnode **vpp)
{
struct nameidata n;
- int flags, error;
+ int flags, error, wasowned;
+
+ wasowned = mtx_owned(&afs_global_mtx);
+ if (wasowned)
+ mtx_unlock(&afs_global_mtx);
+
flags = 0;
flags = LOCKLEAF;
if (followlink)
@@ -62,8 +67,11 @@
flags |= NOFOLLOW;
/* if (dirvpp) flags|=WANTPARENT; *//* XXX LOCKPARENT? */
NDINIT(&n, LOOKUP, flags, seg, aname, curproc);
- if (error = namei(&n))
+ if ((error = namei(&n)) != 0) {
+ if (wasowned)
+ mtx_lock(&afs_global_mtx);
return error;
+ }
*vpp = n.ni_vp;
/*
if (dirvpp)
@@ -72,6 +80,8 @@
/* should we do this? */
VOP_UNLOCK(n.ni_vp, 0, curproc);
NDFREE(&n, NDF_ONLY_PNBUF);
+ if (wasowned)
+ mtx_lock(&afs_global_mtx);
return 0;
}
@@ -102,4 +112,73 @@
resettodr();
AFS_GLOCK();
#endif
+}
+
+/*
+ * Replace all of the bogus special-purpose memory allocators...
+ */
+void *
+osi_fbsd_alloc(size_t size, int dropglobal)
+{
+ void *rv;
+ int wasowned;
+
+ if (dropglobal) {
+ wasowned = mtx_owned(&afs_global_mtx);
+ if (wasowned)
+ mtx_unlock(&afs_global_mtx);
+ rv = malloc(size, M_AFS, M_WAITOK);
+ if (wasowned)
+ mtx_lock(&afs_global_mtx);
+ } else
+ rv = malloc(size, M_AFS, M_NOWAIT);
+
+ return (rv);
+}
+
+void
+osi_fbsd_free(void *p)
+{
+
+ free(p, M_AFS);
+}
+
+void
+osi_AllocMoreSSpace(afs_int32 preallocs)
+{
+ ;
+}
+
+void
+osi_FreeLargeSpace(void *p)
+{
+ osi_fbsd_free(p);
+}
+
+void
+osi_FreeSmallSpace(void *p)
+{
+ osi_fbsd_free(p);
+}
+
+void *
+osi_AllocLargeSpace(size_t size)
+{
+ AFS_ASSERT_GLOCK();
+ AFS_STATCNT(osi_AllocLargeSpace);
+ return (osi_fbsd_alloc(size, 1));
+}
+
+void *
+osi_AllocSmallSpace(size_t size)
+{
+ AFS_ASSERT_GLOCK();
+ AFS_STATCNT(osi_AllocSmallSpace);
+ return (osi_fbsd_alloc(size, 1));
+}
+
+void
+shutdown_osinet(void)
+{
+ ;
}
Index: src/afs/FBSD/osi_module.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_module.c,v
retrieving revision 1.4
diff -u -r1.4 osi_module.c
--- src/afs/FBSD/osi_module.c 15 Jul 2003 23:14:20 -0000 1.4
+++ src/afs/FBSD/osi_module.c 8 Oct 2003 05:09:43 -0000
@@ -60,8 +60,10 @@
vfs_register(&afs_vfsconf); /* doesn't fail */
vfs_add_vnodeops(&afs_vnodeop_opv_desc);
osi_Init();
+#ifdef DO_NOT_EVER_EVER_DO_THIS
sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
sysent[SYS_ioctl].sy_call = afs_xioctl;
+#endif
old_handler = sysent[AFS_SYSCALL].sy_call;
sysent[AFS_SYSCALL].sy_call = afs3_syscall;
sysent[AFS_SYSCALL].sy_narg = 5;
Index: src/afs/FBSD/osi_prototypes.h
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_prototypes.h,v
retrieving revision 1.4
diff -u -r1.4 osi_prototypes.h
--- src/afs/FBSD/osi_prototypes.h 15 Jul 2003 23:14:20 -0000 1.4
+++ src/afs/FBSD/osi_prototypes.h 8 Oct 2003 05:09:43 -0000
@@ -20,8 +20,14 @@
/* osi_misc.c */
extern int osi_lookupname(char *aname, enum uio_seg seg, int followlink,
struct vnode **dirvpp, struct vnode **vpp);
+extern void *osi_fbsd_alloc(size_t size, int dropglobal);
+extern void osi_fbsd_free(void *p);
/* osi_vfsops.c */
+#ifdef AFS_FBSD50_ENV
+extern int afs_statfs(struct mount *mp, struct statfs *abp, struct thread *th);
+#else
extern int afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p);
+#endif
#endif /* _OSI_PROTO_H_ */
Index: src/afs/FBSD/osi_sleep.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_sleep.c,v
retrieving revision 1.10
diff -u -r1.10 osi_sleep.c
--- src/afs/FBSD/osi_sleep.c 15 Jul 2003 23:14:20 -0000 1.10
+++ src/afs/FBSD/osi_sleep.c 8 Oct 2003 05:09:43 -0000
@@ -18,32 +18,31 @@
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
-
-
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
-static char waitV;
-
-
void
afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
{
AFS_STATCNT(osi_InitWaitHandle);
- achandle->proc = (caddr_t) 0;
+ cv_init(&achandle->wh_condvar, "afscondvar");
+ achandle->wh_inited = 1;
}
/* cancel osi_Wait */
+/* XXX
+ * I can't tell -- is this supposed to be cv_signal() or cv_waitq_remove()?
+ * Or perhaps cv_broadcast()?
+ * Assuming cv_signal() is the desired meaning. -GAW
+ */
void
afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
{
- caddr_t proc;
AFS_STATCNT(osi_CancelWait);
- proc = achandle->proc;
- if (proc == 0)
+ /* XXX should not be necessary */
+ if (!achandle->wh_inited)
return;
- achandle->proc = (caddr_t) 0; /* so dude can figure out he was signalled */
- afs_osi_Wakeup(&waitV);
+
+ AFS_ASSERT_GLOCK();
+ cv_signal(&achandle->wh_condvar);
}
/* afs_osi_Wait
@@ -54,31 +53,36 @@
afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
{
int code;
- afs_int32 endTime;
+ struct timeval tv;
+ int ticks;
AFS_STATCNT(osi_Wait);
- endTime = osi_Time() + (ams / 1000);
- if (ahandle)
- ahandle->proc = (caddr_t) curproc;
- do {
- AFS_ASSERT_GLOCK();
- code = 0;
- code = osi_TimedSleep(&waitV, ams, aintok);
- if (code)
- break; /* if something happened, quit now */
- /* if we we're cancelled, quit now */
- if (ahandle && (ahandle->proc == (caddr_t) 0)) {
- /* we've been signalled */
- break;
- }
- } while (osi_Time() < endTime);
+ tv.tv_sec = ams / 1000;
+ tv.tv_usec = (ams % 1000) * 1000;
+ ticks = tvtohz(&tv);
+
+ AFS_ASSERT_GLOCK();
+ if (ahandle == NULL) {
+ /* This is nasty and evil and rude. */
+ code = msleep(&tv, &afs_global_mtx, (aintok ? PPAUSE|PCATCH : PVFS),
+ "afswait", ticks);
+ } else {
+ if (!ahandle->wh_inited)
+ afs_osi_InitWaitHandle(ahandle); /* XXX should not be needed */
+
+ if (aintok)
+ code = cv_timedwait_sig(&ahandle->wh_condvar, &afs_global_mtx,
+ ticks);
+ else
+ code = cv_timedwait(&ahandle->wh_condvar, &afs_global_mtx, ticks);
+ }
return code;
}
-
-
-
+/*
+ * All this gluck should probably also be replaced with CVs.
+ */
typedef struct afs_event {
struct afs_event *next; /* next in hash chain */
char *event; /* lwp event: an address */
@@ -140,9 +144,7 @@
seq = evp->seq;
while (seq == evp->seq) {
AFS_ASSERT_GLOCK();
- AFS_GUNLOCK();
- tsleep(event, PVFS, "afs_osi_Sleep", 0);
- AFS_GLOCK();
+ msleep(event, &afs_global_mtx, PVFS, "afsslp", 0);
}
relevent(evp);
}
@@ -153,42 +155,6 @@
afs_osi_Sleep(event);
return 0;
}
-
-/* osi_TimedSleep
- *
- * Arguments:
- * event - event to sleep on
- * ams --- max sleep time in milliseconds
- * aintok - 1 if should sleep interruptibly
- *
- * Returns 0 if timeout and EINTR if signalled.
- */
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
-{
- int code = 0;
- struct afs_event *evp;
- int ticks;
- int seq, prio;
-
- ticks = (ams * afs_hz) / 1000;
-
-
- evp = afs_getevent(event);
- seq = evp->seq;
- AFS_GUNLOCK();
- if (aintok)
- prio = PCATCH | PPAUSE;
- else
- prio = PVFS;
- code = tsleep(event, prio, "afs_osi_TimedSleep", ticks);
- AFS_GLOCK();
- if (seq == evp->seq)
- code = EINTR;
- relevent(evp);
- return code;
-}
-
int
afs_osi_Wakeup(void *event)
Index: src/afs/FBSD/osi_vfsops.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_vfsops.c,v
retrieving revision 1.14
diff -u -r1.14 osi_vfsops.c
--- src/afs/FBSD/osi_vfsops.c 15 Jul 2003 23:14:20 -0000 1.14
+++ src/afs/FBSD/osi_vfsops.c 8 Oct 2003 05:09:43 -0000
@@ -16,48 +16,42 @@
struct mount *afs_globalVFS = 0;
int afs_pbuf_freecnt = -1;
+#ifdef AFS_FBSD50_ENV
+#define THREAD_OR_PROC struct thread *p
+#else
+#define THREAD_OR_PROC struct proc *p
+#endif
+
int
-afs_quotactl()
+afs_quotactl(struct mount *mp, int c, uid_t u, caddr_t data, THREAD_OR_PROC)
{
return EOPNOTSUPP;
}
int
-afs_fhtovp(mp, fhp, vpp)
- struct mount *mp;
- struct fid *fhp;
- struct vnode **vpp;
+afs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
{
return (EINVAL);
}
int
-afs_vptofh(vp, fhp)
- struct vnode *vp;
- struct fid *fhp;
+afs_vptofh(struct vnode *vp, struct fid *fhp)
{
return (EINVAL);
}
int
-afs_start(mp, flags, p)
- struct mount *mp;
- int flags;
- struct proc *p;
+afs_start(struct mount *mp, int flags, THREAD_OR_PROC)
{
afs_pbuf_freecnt = nswbuf / 2 + 1;
return (0); /* nothing to do. ? */
}
int
-afs_mount(mp, path, data, ndp, p)
- register struct mount *mp;
- char *path;
- caddr_t data;
- struct nameidata *ndp;
- struct proc *p;
+afs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
+ THREAD_OR_PROC)
{
/* ndp contains the mounted-from device. Just ignore it.
* we also don't care about our proc struct. */
@@ -91,12 +85,16 @@
}
int
-afs_unmount(mp, flags, p)
- struct mount *mp;
- int flags;
- struct proc *p;
+afs_unmount(struct mount *mp, int flags, THREAD_OR_PROC)
{
+ /*
+ * Releaase any remaining vnodes on this mount point.
+ * The `1' means that we hold one extra reference on
+ * the root vnode (this is just a guess right now).
+ * This has to be done outside the global lock.
+ */
+ vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0);
AFS_GLOCK();
AFS_STATCNT(afs_unmount);
afs_globalVFS = 0;
@@ -114,10 +112,10 @@
register struct vcache *tvp = 0;
#ifdef AFS_FBSD50_ENV
struct thread *td = curthread;
- struct ucred cr = *td->td_ucred;
+ struct ucred *cr = crhold(td->td_ucred);
#else
struct proc *p = curproc;
- struct ucred cr = *p->p_cred->pc_ucred;
+ struct ucred *cr = crhold(p->p_cred->pc_ucred);
#endif
AFS_GLOCK();
@@ -126,12 +124,14 @@
tvp = afs_globalVp;
error = 0;
} else {
+tryagain:
if (afs_globalVp) {
afs_PutVCache(afs_globalVp);
+ /* vrele() needed here or not? */
afs_globalVp = NULL;
}
- if (!(error = afs_InitReq(&treq, &cr)) && !(error = afs_CheckInit())) {
+ if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
/* we really want this to stay around */
if (tvp)
@@ -141,34 +141,41 @@
}
}
if (tvp) {
- osi_vnhold(tvp, 0);
+ struct vnode *vp = AFSTOV(tvp);
+
+ ASSERT_VI_UNLOCKED(vp, "afs_root");
AFS_GUNLOCK();
+ /*
+ * I'm uncomfortable about this. Shouldn't this happen at a
+ * higher level, and shouldn't we busy the top-level directory
+ * to prevent recycling?
+ */
#ifdef AFS_FBSD50_ENV
- vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, td);
+ error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
+ vp->v_vflag |= VV_ROOT;
#else
- vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
+ error = vget(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ vp->v_flag |= VROOT;
#endif
AFS_GLOCK();
+ if (error != 0)
+ goto tryagain;
+
afs_globalVFS = mp;
- *vpp = AFSTOV(tvp);
- tvp->v.v_flag |= VROOT;
+ *vpp = vp;
}
afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
ICL_TYPE_INT32, error);
AFS_GUNLOCK();
+ crfree(cr);
return error;
}
+#ifndef AFS_FBSD50_ENV
int
-afs_vget(mp, lfl, vp)
- struct mount *mp;
- struct vnode *vp;
- int lfl;
+afs_vget(struct mount *mp, ino_t ino, int flags, struct vnode *vp)
{
-#ifdef AFS_FBSD50_ENV
- return EOPNOTSUPP;
-#else
int error;
printf("vget called. help!\n");
@@ -180,11 +187,11 @@
if (!error)
insmntque(vp, afs_globalVFS); /* take off free list */
return error;
-#endif
}
+#endif
int
-afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p)
+afs_statfs(struct mount *mp, struct statfs *abp, THREAD_OR_PROC)
{
AFS_GLOCK();
AFS_STATCNT(afs_statfs);
@@ -217,23 +224,12 @@
}
int
-afs_sync(mp, waitfor, cred, p)
- struct mount *mp;
- int waitfor;
- struct ucred *cred;
- struct prioc *p;
+afs_sync(struct mount *mp, int waitfor, struct ucred *cred, THREAD_OR_PROC)
{
return 0;
}
int
-afs_sysctl()
-{
- return EOPNOTSUPP;
-}
-
-
-int
afs_init(struct vfsconf *vfc)
{
return 0;
@@ -247,7 +243,11 @@
afs_quotactl,
afs_statfs,
afs_sync,
+#ifdef AFS_FBSD50_ENV
+ NULL,
+#else
afs_vget,
+#endif
afs_fhtovp,
#ifdef AFS_FBSD50_ENV
vfs_stdcheckexp,
@@ -255,7 +255,6 @@
afs_vptofh,
afs_init,
#ifdef AFS_FBSD50_ENV
- vfs_stduninit,
+ vfs_stduninit
#endif
- afs_sysctl
};
Index: src/afs/FBSD/osi_vm.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_vm.c,v
retrieving revision 1.10
diff -u -r1.10 osi_vm.c
--- src/afs/FBSD/osi_vm.c 15 Jul 2003 23:14:20 -0000 1.10
+++ src/afs/FBSD/osi_vm.c 8 Oct 2003 05:09:43 -0000
@@ -32,6 +32,31 @@
#include <limits.h>
#include <float.h>
+/*
+ * FreeBSD implementation notes:
+ * Most of these operations require us to frob vm_objects. Most
+ * functions require that the object be locked (with VM_OBJECT_LOCK)
+ * on entry and leave it locked on exit. In order to get the
+ * vm_object itself we call VOP_GETVOBJECT on the vnode; the
+ * locking protocol requires that we do so with the heavy vnode lock
+ * held and the vnode interlock unlocked, and it returns the same
+ * way.
+ *
+ * The locking protocol for vnodes is defined in
+ * kern/vnode_if.src and sys/vnode.h; the locking is still a work in
+ * progress, so some fields are (as of 5.1) still protected by Giant
+ * rather than an explicit lock.
+ */
+
+#define lock_vnode(v) vn_lock((v), LK_EXCLUSIVE | LK_RETRY, curthread)
+#define unlock_vnode(v) VOP_UNLOCK((v), 0, curthread)
+
+#ifndef AFS_FBSD50_ENV
+/* need splvm() protection? */
+#define VM_OBJECT_LOCK(o)
+#define VM_OBJECT_UNLOCK(o)
+#endif
+
/* Try to discard pages, in order to recycle a vcache entry.
*
* We also make some sanity checks: ref count, open count, held locks.
@@ -47,6 +72,8 @@
* therefore obsolescent.
*
* OSF/1 Locking: VN_LOCK has been called.
+ * XXX - should FreeBSD have done this, too? Certainly looks like it.
+ * Maybe better to just call vnode_pager_setsize()?
*/
int
osi_VM_FlushVCache(struct vcache *avc, int *slept)
@@ -65,8 +92,9 @@
AFS_GUNLOCK();
vp = AFSTOV(avc);
- simple_lock(&vp->v_interlock);
+ lock_vnode(vp);
if (VOP_GETVOBJECT(vp, &obj) == 0) {
+ VM_OBJECT_LOCK(obj);
vm_object_page_remove(obj, 0, 0, FALSE);
#if 0
if (obj->ref_count == 0) {
@@ -76,8 +104,9 @@
SetAfsVnode(vp);
}
#endif
+ VM_OBJECT_UNLOCK(obj);
}
- simple_unlock(&vp->v_interlock);
+ unlock_vnode(vp);
AFS_GLOCK();
return 0;
@@ -99,25 +128,37 @@
AFS_GUNLOCK();
tries = 5;
vp = AFSTOV(avc);
+
+ /*
+ * I don't understand this. Why not just call vm_object_page_clean()
+ * and be done with it? I particularly don't understand why we're calling
+ * vget() here. Is there some reason to believe that the vnode might
+ * be being recycled at this point? I don't think there's any need for
+ * this loop, either -- if we keep the vnode locked all the time,
+ * that and the object lock will prevent any new pages from appearing.
+ * The loop is what causes the race condition. -GAW
+ */
do {
anyio = 0;
- simple_lock(&vp->v_interlock);
+ lock_vnode(vp);
if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
+ /* XXX - obj locking? */
+ unlock_vnode(vp);
#ifdef AFS_FBSD50_ENV
- if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread)) {
+ if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
#else
- if (!vget
- (vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ,
- curproc)) {
+ if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) {
#endif
if (VOP_GETVOBJECT(vp, &obj) == 0) {
+ VM_OBJECT_LOCK(obj);
vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_UNLOCK(obj);
anyio = 1;
}
vput(vp);
}
} else
- simple_unlock(&vp->v_interlock);
+ unlock_vnode(vp);
} while (anyio && (--tries > 0));
AFS_GLOCK();
ObtainWriteLock(&avc->lock, 94);
@@ -145,29 +186,41 @@
vp = AFSTOV(avc);
do {
anyio = 0;
- simple_lock(&vp->v_interlock);
+ lock_vnode(vp);
+ /* See the comments above. */
if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
+ /* XXX - obj locking */
+ unlock_vnode(vp);
#ifdef AFS_FBSD50_ENV
- if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread)) {
+ if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
#else
- if (!vget
- (vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ,
- curproc)) {
+ if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) {
#endif
if (VOP_GETVOBJECT(vp, &obj) == 0) {
+ VM_OBJECT_LOCK(obj);
+ /*
+ * Do we really want OBJPC_SYNC? OBJPC_INVAL would be
+ * faster, if invalidation is really what we are being
+ * asked to do. (It would make more sense, too, since
+ * otherwise this function is practically identical to
+ * osi_VM_StoreAllSegments().) -GAW
+ */
vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
+ VM_OBJECT_UNLOCK(obj);
anyio = 1;
}
vput(vp);
}
} else
- simple_unlock(&vp->v_interlock);
+ unlock_vnode(vp);
} while (anyio && (--tries > 0));
- simple_lock(&vp->v_interlock);
+ lock_vnode(vp);
if (VOP_GETVOBJECT(vp, &obj) == 0) {
+ VM_OBJECT_LOCK(obj);
vm_object_page_remove(obj, 0, 0, FALSE);
+ VM_OBJECT_UNLOCK(obj);
}
- simple_unlock(&vp->v_interlock);
+ unlock_vnode(vp);
/*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */
AFS_GLOCK();
ObtainWriteLock(&avc->lock, 59);
@@ -184,11 +237,12 @@
struct vm_object *obj;
vp = AFSTOV(avc);
- simple_lock(&vp->v_interlock);
+ ASSERT_VOP_LOCKED(vp, __func__);
if (VOP_GETVOBJECT(vp, &obj) == 0) {
+ VM_OBJECT_LOCK(obj);
vm_object_page_remove(obj, 0, 0, FALSE);
+ VM_OBJECT_UNLOCK(obj);
}
- simple_unlock(&vp->v_interlock);
/*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */
}
Index: src/afs/FBSD/osi_vnodeops.c
===================================================================
RCS file: /cvs/openafs/src/afs/FBSD/osi_vnodeops.c,v
retrieving revision 1.16
diff -u -r1.16 osi_vnodeops.c
--- src/afs/FBSD/osi_vnodeops.c 27 Aug 2003 21:43:17 -0000 1.16
+++ src/afs/FBSD/osi_vnodeops.c 8 Oct 2003 05:09:44 -0000
@@ -1,3 +1,49 @@
+/*
+ * A large chunk of this file appears to be copied directly from
+ * sys/nfsclient/nfs_bio.c, which has the following license:
+ */
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
+ */
+/*
+ * Pursuant to a statement of U.C. Berkeley dated 1999-07-22, this license
+ * is amended to drop clause (3) above.
+ */
+
#include <afsconfig.h>
#include <afs/param.h>
@@ -9,6 +55,7 @@
#include <afs/afs_stats.h> /* statistics */
#include <sys/malloc.h>
#include <sys/namei.h>
+#include <sys/unistd.h>
#ifndef AFS_FBSD50_ENV
#include <vm/vm_zone.h>
#endif
@@ -31,6 +78,7 @@
int afs_vop_getpages(struct vop_getpages_args *);
int afs_vop_putpages(struct vop_putpages_args *);
int afs_vop_ioctl(struct vop_ioctl_args *);
+static int afs_vop_pathconf(struct vop_pathconf_args *);
int afs_vop_poll(struct vop_poll_args *);
#ifndef AFS_FBSD50_ENV
int afs_vop_mmap(struct vop_mmap_args *);
@@ -59,7 +107,7 @@
/* Global vfs data structures for AFS. */
vop_t **afs_vnodeop_p;
struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
- {&vop_default_desc, (vop_t *) vop_eopnotsupp},
+ {&vop_default_desc, (vop_t *) vop_defaultop},
{&vop_access_desc, (vop_t *) afs_vop_access}, /* access */
{&vop_advlock_desc, (vop_t *) afs_vop_advlock}, /* advlock */
{&vop_bmap_desc, (vop_t *) afs_vop_bmap}, /* bmap */
@@ -76,10 +124,8 @@
{&vop_getvobject_desc, (vop_t *) vop_stdgetvobject},
{&vop_putpages_desc, (vop_t *) afs_vop_putpages}, /* write */
{&vop_inactive_desc, (vop_t *) afs_vop_inactive}, /* inactive */
- {&vop_islocked_desc, (vop_t *) afs_vop_islocked}, /* islocked */
{&vop_lease_desc, (vop_t *) vop_null},
{&vop_link_desc, (vop_t *) afs_vop_link}, /* link */
- {&vop_lock_desc, (vop_t *) afs_vop_lock}, /* lock */
{&vop_lookup_desc, (vop_t *) afs_vop_lookup}, /* lookup */
{&vop_mkdir_desc, (vop_t *) afs_vop_mkdir}, /* mkdir */
{&vop_mknod_desc, (vop_t *) afs_vop_mknod}, /* mknod */
@@ -87,6 +133,7 @@
{&vop_mmap_desc, (vop_t *) afs_vop_mmap}, /* mmap */
#endif
{&vop_open_desc, (vop_t *) afs_vop_open}, /* open */
+ {&vop_pathconf_desc, (vop_t *) afs_vop_pathconf}, /* pathconf */
{&vop_poll_desc, (vop_t *) afs_vop_poll}, /* select */
{&vop_print_desc, (vop_t *) afs_vop_print}, /* print */
{&vop_read_desc, (vop_t *) afs_vop_read}, /* read */
@@ -99,7 +146,6 @@
{&vop_setattr_desc, (vop_t *) afs_vop_setattr}, /* setattr */
{&vop_strategy_desc, (vop_t *) afs_vop_strategy}, /* strategy */
{&vop_symlink_desc, (vop_t *) afs_vop_symlink}, /* symlink */
- {&vop_unlock_desc, (vop_t *) afs_vop_unlock}, /* unlock */
{&vop_write_desc, (vop_t *) afs_vop_write}, /* write */
{&vop_ioctl_desc, (vop_t *) afs_vop_ioctl}, /* XXX ioctl */
/*{ &vop_seek_desc, afs_vop_seek }, *//* seek */
@@ -122,7 +168,98 @@
#define a_p a_td
#endif
+/*
+ * Mosty copied from sys/ufs/ufs/ufs_vnops.c:ufs_pathconf().
+ * We should know the correct answers to these questions with
+ * respect to the AFS protocol (which may differ from the UFS
+ * values) but for the moment this will do.
+ */
+static int
+afs_vop_pathconf(struct vop_pathconf_args *ap)
+{
+ int error;
+ error = 0;
+ switch (ap->a_name) {
+ case _PC_LINK_MAX:
+ *ap->a_retval = LINK_MAX;
+ break;
+ case _PC_NAME_MAX:
+ *ap->a_retval = NAME_MAX;
+ break;
+ case _PC_PATH_MAX:
+ *ap->a_retval = PATH_MAX;
+ break;
+ case _PC_PIPE_BUF:
+ *ap->a_retval = PIPE_BUF;
+ break;
+ case _PC_CHOWN_RESTRICTED:
+ *ap->a_retval = 1;
+ break;
+ case _PC_NO_TRUNC:
+ *ap->a_retval = 1;
+ break;
+#ifdef _PC_ACL_EXTENDED
+ case _PC_ACL_EXTENDED:
+ *ap->a_retval = 0;
+ break;
+ case _PC_ACL_PATH_MAX:
+ *ap->a_retval = 3;
+ break;
+#endif
+#ifdef _PC_MAC_PRESENT
+ case _PC_MAC_PRESENT:
+ *ap->a_retval = 0;
+ break;
+#endif
+#ifdef _PC_ASYNC_IO
+ case _PC_ASYNC_IO:
+ /* _PC_ASYNC_IO should have been handled by upper layers. */
+ KASSERT(0, ("_PC_ASYNC_IO should not get here"));
+ error = EINVAL;
+ break;
+ case _PC_PRIO_IO:
+ *ap->a_retval = 0;
+ break;
+ case _PC_SYNC_IO:
+ *ap->a_retval = 0;
+ break;
+#endif
+#ifdef _PC_ALLOC_SIZE_MIN
+ case _PC_ALLOC_SIZE_MIN:
+ *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize;
+ break;
+#endif
+#ifdef _PC_FILESIZEBITS
+ case _PC_FILESIZEBITS:
+ *ap->a_retval = 32; /* XXX */
+ break;
+#endif
+#ifdef _PC_REC_INCR_XFER_SIZE
+ case _PC_REC_INCR_XFER_SIZE:
+ *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
+ break;
+ case _PC_REC_MAX_XFER_SIZE:
+ *ap->a_retval = -1; /* means ``unlimited'' */
+ break;
+ case _PC_REC_MIN_XFER_SIZE:
+ *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
+ break;
+ case _PC_REC_XFER_ALIGN:
+ *ap->a_retval = PAGE_SIZE;
+ break;
+#endif
+#ifdef _PC_SYMLINK_MAX
+ case _PC_SYMLINK_MAX:
+ *ap->a_retval = MAXPATHLEN;
+ break;
+#endif
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
int
afs_vop_lookup(ap)
@@ -397,15 +534,16 @@
return code;
}
+/* struct vop_getpages_args {
+ * struct vnode *a_vp;
+ * vm_page_t *a_m;
+ * int a_count;
+ * int a_reqpage;
+ * vm_oofset_t a_offset;
+ * };
+ */
int
-afs_vop_getpages(ap)
- struct vop_getpages_args /* {
- * struct vnode *a_vp;
- * vm_page_t *a_m;
- * int a_count;
- * int a_reqpage;
- * vm_oofset_t a_offset;
- * } */ *ap;
+afs_vop_getpages(struct vop_getpages_args *ap)
{
int code;
int i, nextoff, size, toff, npages;
@@ -413,9 +551,16 @@
struct iovec iov;
struct buf *bp;
vm_offset_t kva;
- struct vcache *avc = VTOAFS(ap->a_vp);
+ vm_object_t object;
+ struct vnode *vp;
+ struct vcache *avc;
- if (avc->v.v_object == NULL) {
+#ifdef AFS_FBSD50_ENV
+ GIANT_REQUIRED;
+#endif
+ vp = ap->a_vp;
+ avc = VTOAFS(vp);
+ if ((object = vp->v_object) == NULL) {
printf("afs_getpages: called with non-merged cache vnode??\n");
return VM_PAGER_ERROR;
}
@@ -429,6 +574,10 @@
{
vm_page_t m = ap->a_m[ap->a_reqpage];
+#ifdef AFS_FBSD50_ENV
+ VM_OBJECT_LOCK(object);
+ vm_page_lock_queues();
+#endif
if (m->valid != 0) {
/* handled by vm_fault now */
/* vm_page_zero_invalid(m, TRUE); */
@@ -436,12 +585,24 @@
if (i != ap->a_reqpage)
vm_page_free(ap->a_m[i]);
}
+#ifdef AFS_FBSD50_ENV
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
+#endif
return (0);
}
+#ifdef AFS_FBSD50_ENV
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
+#endif
}
bp = getpbuf(&afs_pbuf_freecnt);
+
kva = (vm_offset_t) bp->b_data;
pmap_qenter(kva, ap->a_m, npages);
+ cnt.v_vnodein++;
+ cnt.v_vnodepgsin += npages;
+
iov.iov_base = (caddr_t) kva;
iov.iov_len = ap->a_count;
uio.uio_iov = &iov;
@@ -455,6 +616,7 @@
#else
uio.uio_procp = curproc;
#endif
+
AFS_GLOCK();
afs_BozonLock(&avc->pvnLock, avc);
osi_FlushPages(avc, osi_curcred()); /* hold bozon lock, but not basic vnode lock */
@@ -464,14 +626,28 @@
pmap_qremove(kva, npages);
relpbuf(bp, &afs_pbuf_freecnt);
+
if (code && (uio.uio_resid == ap->a_count)) {
+#ifdef AFS_FBSD50_ENV
+ VM_OBJECT_LOCK(object);
+ vm_page_lock_queues();
+#endif
for (i = 0; i < npages; ++i) {
if (i != ap->a_reqpage)
vm_page_free(ap->a_m[i]);
}
+#ifdef AFS_FBSD50_ENV
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
+#endif
return VM_PAGER_ERROR;
}
+
size = ap->a_count - uio.uio_resid;
+#ifdef AFS_FBSD50_ENV
+ VM_OBJECT_LOCK(object);
+ vm_page_lock_queues();
+#endif
for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
vm_page_t m;
nextoff = toff + PAGE_SIZE;
@@ -519,6 +695,10 @@
}
}
}
+#ifdef AFS_FBSD50_ENV
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
+#endif
return 0;
}
@@ -543,16 +723,22 @@
return code;
}
+/*-
+ * struct vop_putpages_args {
+ * struct vnode *a_vp;
+ * vm_page_t *a_m;
+ * int a_count;
+ * int a_sync;
+ * int *a_rtvals;
+ * vm_oofset_t a_offset;
+ * };
+ */
+/*
+ * All of the pages passed to us in ap->a_m[] are already marked as busy,
+ * so there is no additional locking required to set their flags. -GAW
+ */
int
-afs_vop_putpages(ap)
- struct vop_putpages_args /* {
- * struct vnode *a_vp;
- * vm_page_t *a_m;
- * int a_count;
- * int a_sync;
- * int *a_rtvals;
- * vm_oofset_t a_offset;
- * } */ *ap;
+afs_vop_putpages(struct vop_putpages_args *ap)
{
int code;
int i, size, npages, sync;
@@ -560,22 +746,34 @@
struct iovec iov;
struct buf *bp;
vm_offset_t kva;
- struct vcache *avc = VTOAFS(ap->a_vp);
+ struct vnode *vp;
+ struct vcache *avc;
+
+#ifdef AFS_FBSD50_ENV
+ GIANT_REQUIRED;
+#endif
- if (avc->v.v_object == NULL) {
+ vp = ap->a_vp;
+ avc = VTOAFS(vp);
+ /* Perhaps these two checks should just be KASSERTs instead... */
+ if (vp->v_object == NULL) {
printf("afs_putpages: called with non-merged cache vnode??\n");
- return VM_PAGER_ERROR;
+ return VM_PAGER_ERROR; /* XXX I think this is insufficient */
}
if (vType(avc) != VREG) {
printf("afs_putpages: not VREG");
- return VM_PAGER_ERROR;
+ return VM_PAGER_ERROR; /* XXX I think this is insufficient */
}
npages = btoc(ap->a_count);
for (i = 0; i < npages; i++)
ap->a_rtvals[i] = VM_PAGER_AGAIN;
bp = getpbuf(&afs_pbuf_freecnt);
+
kva = (vm_offset_t) bp->b_data;
pmap_qenter(kva, ap->a_m, npages);
+ cnt.v_vnodeout++;
+ cnt.v_vnodepgsout += ap->a_count;
+
iov.iov_base = (caddr_t) kva;
iov.iov_len = ap->a_count;
uio.uio_iov = &iov;
@@ -600,16 +798,16 @@
code = afs_write(avc, &uio, sync, osi_curcred(), 0);
afs_BozonUnlock(&avc->pvnLock, avc);
AFS_GUNLOCK();
- pmap_qremove(kva, npages);
+ pmap_qremove(kva, npages);
relpbuf(bp, &afs_pbuf_freecnt);
+
if (!code) {
size = ap->a_count - uio.uio_resid;
for (i = 0; i < round_page(size) / PAGE_SIZE; i++) {
ap->a_rtvals[i] = VM_PAGER_OK;
- ap->a_m[i]->dirty = 0;
+ vm_page_undirty(ap->a_m[i]);
}
- return VM_PAGER_ERROR;
}
return ap->a_rtvals[0];
}
@@ -933,26 +1131,44 @@
return error;
}
+/* struct vop_symlink_args {
+ * struct vnode *a_dvp;
+ * struct vnode **a_vpp;
+ * struct componentname *a_cnp;
+ * struct vattr *a_vap;
+ * char *a_target;
+ * };
+ */
int
-afs_vop_symlink(ap)
- struct vop_symlink_args /* {
- * struct vnode *a_dvp;
- * struct vnode **a_vpp;
- * struct componentname *a_cnp;
- * struct vattr *a_vap;
- * char *a_target;
- * } */ *ap;
+afs_vop_symlink(struct vop_symlink_args *ap)
{
- register struct vnode *dvp = ap->a_dvp;
- int error = 0;
- /* NFS ignores a_vpp; so do we. */
+ struct vnode *dvp;
+ struct vnode *newvp;
+ struct vcache *vcp;
+ int error;
+
+ dvp = ap->a_dvp;
+ newvp = NULL;
+ error = 0;
GETNAME();
AFS_GLOCK();
error =
afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
+ if (error == 0) {
+ error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
+ if (error == 0) {
+ newvp = AFSTOV(vcp);
+#ifdef AFS_FBSD50_ENV
+ vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
+#else
+ vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_proc);
+#endif
+ }
+ }
AFS_GUNLOCK();
DROPNAME();
+ *(ap->a_vpp) = newvp;
return error;
}
@@ -1043,69 +1259,36 @@
return 0;
}
+/*
+ * struct vop_reclaim_args {
+ * struct vnode *a_vp;
+ * };
+ */
int
-afs_vop_reclaim(ap)
- struct vop_reclaim_args /* {
- * struct vnode *a_vp;
- * } */ *ap;
-{
-#ifdef AFS_DO_FLUSH_IN_RECLAIM
- int error, sl;
-#endif
- register struct vnode *vp = ap->a_vp;
-
- cache_purge(vp); /* just in case... */
-
-#ifdef AFS_DO_FLUSH_IN_RECLAIM
- AFS_GLOCK();
- error = afs_FlushVCache(VTOAFS(vp), &sl); /* tosses our stuff from vnode */
- AFS_GUNLOCK();
- ubc_unlink(vp);
- if (!error && vp->v_data)
- panic("afs_reclaim: vnode not cleaned");
- return error;
-#else
- if (vp->v_usecount == 2) {
- vprint("reclaim count==2", vp);
- } else if (vp->v_usecount == 1) {
- vprint("reclaim count==1", vp);
- } else
- vprint("reclaim bad count", vp);
-
- return 0;
-#endif
-}
-
-int
-afs_vop_lock(ap)
- struct vop_lock_args /* {
- * struct vnode *a_vp;
- * } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct vcache *avc = VTOAFS(vp);
-
-#ifdef AFS_FBSD50_ENV
- if (!strcmp(vp->v_tag, "none"))
-#else
- if (vp->v_tag == VT_NON)
-#endif
- return (ENOENT);
- return (lockmgr(&avc->rwlock, ap->a_flags, &vp->v_interlock, ap->a_p));
-}
-
-int
-afs_vop_unlock(ap)
- struct vop_unlock_args /* {
- * struct vnode *a_vp;
- * } */ *ap;
+afs_vop_reclaim(struct vop_reclaim_args *ap)
{
+ /* copied from ../OBSD/osi_vnodeops.c:afs_nbsd_reclaim() */
+ int code, slept;
struct vnode *vp = ap->a_vp;
struct vcache *avc = VTOAFS(vp);
- return (lockmgr
- (&avc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
- ap->a_p));
+ int haveGlock = ISAFS_GLOCK();
+ int haveVlock = CheckLock(&afs_xvcache);
+ if (!haveGlock)
+ AFS_GLOCK();
+ if (!haveVlock)
+ ObtainWriteLock(&afs_xvcache, 901);
+#ifndef AFS_DISCON_ENV
+ code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
+#else
+ /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
+ code = afs_FlushVS(avc);
+#endif
+ if (!haveVlock)
+ ReleaseWriteLock(&afs_xvcache);
+ if (!haveGlock)
+ AFS_GUNLOCK();
+ return code;
}
int
@@ -1173,16 +1356,6 @@
(s & CVFlushed) ? " flush in progress" : "");
printf("\n");
return 0;
-}
-
-int
-afs_vop_islocked(ap)
- struct vop_islocked_args /* {
- * struct vnode *a_vp;
- * } */ *ap;
-{
- struct vcache *vc = VTOAFS(ap->a_vp);
- return lockstatus(&vc->rwlock, ap->a_p);
}
/*
Index: src/cf/osconf.m4
===================================================================
RCS file: /cvs/openafs/src/cf/osconf.m4,v
retrieving revision 1.39
diff -u -r1.39 osconf.m4
--- src/cf/osconf.m4 1 Jul 2003 19:30:30 -0000 1.39
+++ src/cf/osconf.m4 8 Oct 2003 05:09:47 -0000
@@ -191,7 +191,7 @@
SHLIB_LDFLAGS="-shared -Xlinker -x"
TXLIBS="-lncurses"
XCFLAGS="-O2 -pipe"
- XLIBS="${LIB_AFSDB} -lcompat"
+ XLIBS="${LIB_AFSDB}"
YACC="byacc"
;;
@@ -203,7 +203,7 @@
SHLIB_LDFLAGS="-shared -Xlinker -x"
TXLIBS="-lncurses"
XCFLAGS="-O2 -pipe"
- XLIBS="${LIB_AFSDB} -lcompat"
+ XLIBS="${LIB_AFSDB}"
YACC="byacc"
;;
Index: src/config/param.i386_fbsd_42.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_42.h,v
retrieving revision 1.9
diff -u -r1.9 param.i386_fbsd_42.h
--- src/config/param.i386_fbsd_42.h 15 Jul 2003 23:14:55 -0000 1.9
+++ src/config/param.i386_fbsd_42.h 8 Oct 2003 05:09:48 -0000
@@ -79,8 +79,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_43.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_43.h,v
retrieving revision 1.6
diff -u -r1.6 param.i386_fbsd_43.h
--- src/config/param.i386_fbsd_43.h 15 Jul 2003 23:14:55 -0000 1.6
+++ src/config/param.i386_fbsd_43.h 8 Oct 2003 05:09:48 -0000
@@ -81,8 +81,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_44.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_44.h,v
retrieving revision 1.6
diff -u -r1.6 param.i386_fbsd_44.h
--- src/config/param.i386_fbsd_44.h 15 Jul 2003 23:14:55 -0000 1.6
+++ src/config/param.i386_fbsd_44.h 8 Oct 2003 05:09:48 -0000
@@ -83,8 +83,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_45.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_45.h,v
retrieving revision 1.7
diff -u -r1.7 param.i386_fbsd_45.h
--- src/config/param.i386_fbsd_45.h 15 Jul 2003 23:14:55 -0000 1.7
+++ src/config/param.i386_fbsd_45.h 8 Oct 2003 05:09:48 -0000
@@ -84,8 +84,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_46.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_46.h,v
retrieving revision 1.6
diff -u -r1.6 param.i386_fbsd_46.h
--- src/config/param.i386_fbsd_46.h 15 Jul 2003 23:14:55 -0000 1.6
+++ src/config/param.i386_fbsd_46.h 8 Oct 2003 05:09:48 -0000
@@ -85,8 +85,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_47.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_47.h,v
retrieving revision 1.4
diff -u -r1.4 param.i386_fbsd_47.h
--- src/config/param.i386_fbsd_47.h 15 Jul 2003 23:14:55 -0000 1.4
+++ src/config/param.i386_fbsd_47.h 8 Oct 2003 05:09:48 -0000
@@ -87,8 +87,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_50.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_50.h,v
retrieving revision 1.6
diff -u -r1.6 param.i386_fbsd_50.h
--- src/config/param.i386_fbsd_50.h 15 Jul 2003 23:14:55 -0000 1.6
+++ src/config/param.i386_fbsd_50.h 8 Oct 2003 05:09:49 -0000
@@ -88,8 +88,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
Index: src/config/param.i386_fbsd_51.h
===================================================================
RCS file: /cvs/openafs/src/config/param.i386_fbsd_51.h,v
retrieving revision 1.1
diff -u -r1.1 param.i386_fbsd_51.h
--- src/config/param.i386_fbsd_51.h 17 Jul 2003 16:00:56 -0000 1.1
+++ src/config/param.i386_fbsd_51.h 8 Oct 2003 05:09:49 -0000
@@ -79,7 +79,7 @@
#ifdef _KERNEL
#define AFS_GLOBAL_SUNLOCK 1
#define AFS_VFS34 1 /* What is VFS34??? */
-#define AFS_SHORTGID 1 /* are group id's short? */
+#define AFS_SHORTGID 0 /* are group id's short? */
#define afsio_iov uio_iov
#define afsio_iovcnt uio_iovcnt
#define afsio_offset uio_offset
@@ -89,8 +89,10 @@
#define AFS_UIOUSER UIO_USERSPACE
#define AFS_CLBYTES CLBYTES
#define osi_GetTime(x) microtime(x)
-#define AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK)
-#define AFS_KFREE(x,y) free(x,M_AFS)
+#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1)
+#undef AFS_KALLOC_NOSLEEP
+#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
+#define AFS_KFREE(x,y) osi_fbsd_free((x))
#define v_count v_usecount
#define v_vfsp v_mount
#define vfs_bsize mnt_stat.f_bsize
@@ -169,7 +171,7 @@
#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_51
#define AFSLITTLE_ENDIAN 1
#define AFS_HAVE_FFS 1 /* Use system's ffs. */
-#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */
+#define AFS_HAVE_STATVFS 1 /* System doesn't support statvfs */
#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */
#define afsio_iov uio_iov
Index: src/libafs/MakefileProto.FBSD.in
===================================================================
RCS file: /cvs/openafs/src/libafs/MakefileProto.FBSD.in,v
retrieving revision 1.22
diff -u -r1.22 MakefileProto.FBSD.in
--- src/libafs/MakefileProto.FBSD.in 1 Jul 2003 18:06:40 -0000 1.22
+++ src/libafs/MakefileProto.FBSD.in 8 Oct 2003 05:09:51 -0000
@@ -34,9 +34,11 @@
<i386_fbsd_42 i386_fbsd_43 i386_fbsd_44 i386_fbsd_45 i386_fbsd_46 i386_fbsd_47>
-fformat-extensions
<all -i386_fbsd_42 -i386_fbsd_43 -i386_fbsd_44 -i386_fbsd_45 -i386_fbsd_46 -i386_fbsd_47>
- -mno-align-long-strings -fformat-extensions -fno-common -ffreestanding
+ -mno-align-long-strings -fformat-extensions -fno-common -ffreestanding \
+ -I/sys/i386/compile/AFS -include opt_global.h -fno-strict-aliasing
+
<all>
-DBUG = -O2
+DBUG = -O -g
DEFINES= -DAFSDEBUG -DKERNEL -DAFS -DVICE -DNFS -DUFS -DINET -DQUOTA -DGETMOUNT
OPTF=${OPT}
OPTF2=${OPT2}
Index: src/libuafs/MakefileProto.FBSD.in
===================================================================
RCS file: /cvs/openafs/src/libuafs/MakefileProto.FBSD.in,v
retrieving revision 1.9
diff -u -r1.9 MakefileProto.FBSD.in
--- src/libuafs/MakefileProto.FBSD.in 10 Mar 2003 01:59:40 -0000 1.9
+++ src/libuafs/MakefileProto.FBSD.in 8 Oct 2003 05:09:51 -0000
@@ -10,16 +10,16 @@
# System specific build commands and flags
-CC = gcc
+CC = @CC@
DEFINES= -D_REENTRANT -DKERNEL -DUKERNEL
KOPTS=
CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KOPTS) ${DBUG}
OPTF=-O
# WEBOPTS = -I../nsapi -DNETSCAPE_NSAPI -DNET_SSL -DXP_UNIX -DMCC_HTTPD
-TEST_CFLAGS=-pthread -D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
+TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
TEST_LDFLAGS=
-TEST_LIBS=
+TEST_LIBS=-lc_r
LIBUAFS = libuafs.a
LIBJUAFS = libjuafs.a
Index: src/rx/rx_kcommon.c
===================================================================
RCS file: /cvs/openafs/src/rx/rx_kcommon.c,v
retrieving revision 1.37
diff -u -r1.37 rx_kcommon.c
--- src/rx/rx_kcommon.c 27 Aug 2003 21:43:19 -0000 1.37
+++ src/rx/rx_kcommon.c 8 Oct 2003 05:09:53 -0000
@@ -776,6 +776,8 @@
#if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) && defined(KERNEL_FUNNEL)
thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
#endif
+ AFS_ASSERT_GLOCK();
+ AFS_GUNLOCK();
#if defined(AFS_HPUX102_ENV)
#if defined(AFS_HPUX110_ENV)
/* blocking socket */
@@ -796,6 +798,7 @@
if (code)
goto bad;
+ memset(&myaddr, 0, sizeof myaddr);
myaddr.sin_family = AF_INET;
myaddr.sin_port = aport;
myaddr.sin_addr.s_addr = 0;
@@ -841,6 +844,7 @@
if (code) {
printf("sobind fails (%d)\n", (int)code);
soclose(newSocket);
+ AFS_GLOCK();
goto bad;
}
#else /* defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) */
@@ -875,12 +879,14 @@
#endif /* else AFS_DARWIN_ENV */
#endif /* else AFS_HPUX110_ENV */
+ AFS_GLOCK();
#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
#endif
return (struct osi_socket *)newSocket;
bad:
+ AFS_GLOCK();
#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
#endif
Index: src/rx/rx_prototypes.h
===================================================================
RCS file: /cvs/openafs/src/rx/rx_prototypes.h,v
retrieving revision 1.12
diff -u -r1.12 rx_prototypes.h
--- src/rx/rx_prototypes.h 15 Jul 2003 23:16:10 -0000 1.12
+++ src/rx/rx_prototypes.h 8 Oct 2003 05:09:53 -0000
@@ -561,9 +561,15 @@
/* EXTERNAL PROTOTYPES - include here cause it causes too many issues to
include the afs_prototypes.h file - just make sure they match */
+#ifndef afs_osi_Alloc
extern void *afs_osi_Alloc(size_t x);
+#endif
+#ifndef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t x);
+#endif
+#ifndef afs_osi_Free
extern void afs_osi_Free(void *x, size_t asize);
+#endif
#ifndef afs_osi_Wakeup
extern int afs_osi_Wakeup(void *event);
#endif
Index: src/rx/xdr.h
===================================================================
RCS file: /cvs/openafs/src/rx/xdr.h,v
retrieving revision 1.10
diff -u -r1.10 xdr.h
--- src/rx/xdr.h 15 Jul 2003 23:16:12 -0000 1.10
+++ src/rx/xdr.h 8 Oct 2003 05:09:54 -0000
@@ -96,7 +96,9 @@
/* keep here for now, 64 bit issues */
extern void *afs_osi_Alloc(size_t x);
+#ifndef afs_osi_Alloc_NoSleep
extern void *afs_osi_Alloc_NoSleep(size_t x);
+#endif
extern void afs_osi_Free(void *x, size_t asize);
#endif
Index: src/rx/FBSD/rx_knet.c
===================================================================
RCS file: /cvs/openafs/src/rx/FBSD/rx_knet.c,v
retrieving revision 1.13
diff -u -r1.13 rx_knet.c
--- src/rx/FBSD/rx_knet.c 15 Jul 2003 23:16:18 -0000 1.13
+++ src/rx/FBSD/rx_knet.c 8 Oct 2003 05:09:56 -0000
@@ -83,10 +83,20 @@
{
struct proc *p;
+ /*
+ * Have to drop global lock to safely do this.
+ * soclose() is currently protected by Giant,
+ * but pfind and psignal are MPSAFE.
+ */
+ AFS_GUNLOCK();
soclose(rx_socket);
p = pfind(rxk_ListenerPid);
if (p)
psignal(p, SIGUSR1);
+#ifdef AFS_FBSD50_ENV
+ PROC_UNLOCK(p);
+#endif
+ AFS_GLOCK();
}
int
Index: src/vlserver/vlprocs.c
===================================================================
RCS file: /cvs/openafs/src/vlserver/vlprocs.c,v
retrieving revision 1.10
diff -u -r1.10 vlprocs.c
--- src/vlserver/vlprocs.c 15 Jul 2003 23:17:34 -0000 1.10
+++ src/vlserver/vlprocs.c 8 Oct 2003 05:10:02 -0000
@@ -38,6 +38,12 @@
#ifndef AFS_NT40_ENV
#include <unistd.h>
#endif
+#ifdef AFS_FBSD_ENV /* XXX for now */
+#define HAVE_REGEX_H
+#endif
+#ifdef HAVE_REGEX_H /* use POSIX regexp library */
+#include <regex.h>
+#endif
extern int smallMem;
extern extent_mod;
@@ -1376,6 +1382,10 @@
int pollcount = 0;
int namematchRWBK, namematchRO, thismatch, matchtype;
char volumename[VL_MAXNAMELEN];
+#ifdef HAVE_REGEX_H
+ regex_t re;
+ int need_regfree = 0;
+#endif
COUNT_REQ(VLLISTATTRIBUTESN2);
vldbentries->nbulkentries_val = 0;
@@ -1433,11 +1443,19 @@
findflag = ((attributes->Mask & VLLIST_FLAG) ? 1 : 0);
if (name && (strcmp(name, ".*") != 0) && (strcmp(name, "") != 0)) {
sprintf(volumename, "^%s$", name);
+#ifdef HAVE_REGEX_H
+ if (regcomp(&re, volumename, REG_BASIC | REG_NOSUB) != 0) {
+ errorcode = VL_BADNAME;
+ goto done;
+ }
+ need_regfree = 1;
+#else
t = (char *)re_comp(volumename);
if (t) {
errorcode = VL_BADNAME;
goto done;
}
+#endif
findname = 1;
}
@@ -1468,9 +1486,15 @@
if (tentry.flags & VLF_RWEXISTS) {
if (findname) {
sprintf(volumename, "%s", tentry.name);
+#ifdef HAVE_REGEX_H
+ if (regexec(&re, volumename, 0, NULL, 0) == 0) {
+ thismatch = VLSF_RWVOL;
+ }
+#else
if (re_exec(volumename)) {
thismatch = VLSF_RWVOL;
}
+#endif
} else {
thismatch = VLSF_RWVOL;
}
@@ -1480,9 +1504,15 @@
if (!thismatch && (tentry.flags & VLF_BACKEXISTS)) {
if (findname) {
sprintf(volumename, "%s.backup", tentry.name);
+#ifdef HAVE_REGEX_H
+ if (regexec(&re, volumename, 0, NULL, 0) == 0) {
+ thismatch = VLSF_BACKVOL;
+ }
+#else
if (re_exec(volumename)) {
thismatch = VLSF_BACKVOL;
}
+#endif
} else {
thismatch = VLSF_BACKVOL;
}
@@ -1504,8 +1534,14 @@
} else {
sprintf(volumename, "%s.readonly",
tentry.name);
+#ifdef HAVE_REGEX_H
+ if (regexec(&re, volumename, 0, NULL, 0) == 0) {
+ thismatch = VLSF_ROVOL;
+ }
+#else
if (re_exec(volumename))
thismatch = VLSF_ROVOL;
+#endif
}
} else {
thismatch = VLSF_ROVOL;
@@ -1566,6 +1602,9 @@
}
done:
+ if (need_regfree)
+ regfree(&re);
+
if (errorcode) {
COUNT_ABO;
ubik_AbortTrans(trans);
Index: src/volser/vos.c
===================================================================
RCS file: /cvs/openafs/src/volser/vos.c,v
retrieving revision 1.28
diff -u -r1.28 vos.c
--- src/volser/vos.c 15 Sep 2003 21:39:10 -0000 1.28
+++ src/volser/vos.c 8 Oct 2003 05:10:05 -0000
@@ -62,6 +62,13 @@
#endif
#include "volser_prototypes.h"
+#ifdef AFS_FBSD_ENV
+#define HAVE_REGEX_H
+#endif
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
struct tqElem {
afs_int32 volid;
struct tqElem *next;
@@ -3928,6 +3935,20 @@
if (seenprefix) {
for (ti = as->parms[0].items; ti; ti = ti->next) {
if (strncmp(ti->data, "^", 1) == 0) {
+#ifdef HAVE_REGEX_H
+ regex_t re;
+ char errbuf[256];
+
+ code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
+ if (code != 0) {
+ regerror(code, &re, errbuf, sizeof errbuf);
+ fprintf(STDERR,
+ "Unrecognizable -prefix regular expression: '%s': %s\n",
+ ti->data, errbuf);
+ exit(1);
+ }
+ regfree(&re);
+#else
ccode = (char *)re_comp(ti->data);
if (ccode) {
fprintf(STDERR,
@@ -3935,12 +3956,27 @@
ti->data, ccode);
exit(1);
}
+#endif
}
}
}
if (seenxprefix) {
for (ti = as->parms[4].items; ti; ti = ti->next) {
if (strncmp(ti->data, "^", 1) == 0) {
+#ifdef HAVE_REGEX_H
+ regex_t re;
+ char errbuf[256];
+
+ code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
+ if (code != 0) {
+ regerror(code, &re, errbuf, sizeof errbuf);
+ fprintf(STDERR,
+ "Unrecognizable -xprefix regular expression: '%s': %s\n",
+ ti->data, errbuf);
+ exit(1);
+ }
+ regfree(&re);
+#else
ccode = (char *)re_comp(ti->data);
if (ccode) {
fprintf(STDERR,
@@ -3948,6 +3984,7 @@
ti->data, ccode);
exit(1);
}
+#endif
}
}
}
@@ -4012,6 +4049,22 @@
if (seenprefix) {
for (ti = as->parms[0].items; ti; ti = ti->next) {
if (strncmp(ti->data, "^", 1) == 0) {
+#ifdef HAVE_REGEX_H
+ regex_t re;
+ char errbuf[256];
+
+ /* XXX -- should just do the compile once! */
+ code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
+ if (code != 0) {
+ regerror(code, &re, errbuf, sizeof errbuf);
+ fprintf(STDERR,
+ "Error in -prefix regular expression: '%s': %s\n",
+ ti->data, errbuf);
+ exit(1);
+ }
+ match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
+ regfree(&re);
+#else
ccode = (char *)re_comp(ti->data);
if (ccode) {
fprintf(STDERR,
@@ -4020,6 +4073,7 @@
exit(1);
}
match = (re_exec(vllist->name) == 1);
+#endif
} else {
match =
(strncmp(vllist->name, ti->data, strlen(ti->data)) ==
@@ -4040,6 +4094,23 @@
if (match && seenxprefix) {
for (ti = as->parms[4].items; ti; ti = ti->next) {
if (strncmp(ti->data, "^", 1) == 0) {
+#ifdef HAVE_REGEX_H
+ regex_t re;
+ char errbuf[256];
+
+ /* XXX -- should just do the compile once! */
+ code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
+ if (code != 0) {
+ regerror(code, &re, errbuf, sizeof errbuf);
+ fprintf(STDERR,
+ "Error in -xprefix regular expression: '%s': %s\n",
+ ti->data, errbuf);
+ exit(1);
+ }
+ if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
+ match = 0;
+ regfree(&re);
+#else
ccode = (char *)re_comp(ti->data);
if (ccode) {
fprintf(STDERR,
@@ -4051,6 +4122,7 @@
match = 0;
break;
}
+#endif
} else {
if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
0) {