#define afs_bufferpages v.v_bufhw
-#define osi_vnhold(avc, r) do { VN_HOLD(AFSTOV(avc)); } while (0)
-
#undef gop_lookupname
#define gop_lookupname(fnamep,segflg,followlink,compvpp) \
lookupvp((fnamep), (followlink), (compvpp), &afs_osi_cred)
avc->v.v_gnode->gn_vnode = &avc->v;
}
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
typedef struct ucred afs_ucred_t;
typedef struct proc afs_proc_t;
-#define osi_vnhold(avc,r) VN_HOLD(AFSTOV(avc))
#define VN_HOLD(vp) darwin_vn_hold(vp)
#define VN_RELE(vp) vrele(vp)
vSetType(avc, VNON);
#endif
}
+
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
}
if (tvp) {
#ifndef AFS_DARWIN80_ENV /* KPI callers don't need a usecount reference */
- osi_vnhold(tvp, 0);
+ osi_Assert(osi_vnhold(tvp) == 0);
AFS_GUNLOCK();
vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
AFS_GLOCK();
#ifndef AFS_DARWIN80_ENV
if (UBCISVALID(vp) && ((avc->f.states & CStatd) || force)) {
if (!UBCINFOEXISTS(vp)) {
- osi_vnhold(avc, 0);
+ osi_Assert(osi_vnhold(avc) == 0);
avc->f.states |= CUBCinit;
AFS_GUNLOCK();
if ((error = ubc_info_init(vp))) {
#define VSUID S_ISUID
#define VSGID S_ISGID
-#define osi_vnhold(avc,r) vref(AFSTOV(avc))
-
#define vType(vc) AFSTOV(vc)->v_type
#define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp)
#define vSetType(vc, type) AFSTOV(vc)->v_type = (type)
vSetType(avc, VREG);
}
+int
+osi_vnhold(struct vcache *avc)
+{
+ vref(AFSTOV(avc));
+ return 0;
+}
typedef struct ucred afs_ucred_t;
typedef proc_t afs_proc_t;
-#define osi_vnhold(avc, r) do { VN_HOLD(AFSTOV(avc)); } while(0)
#define gop_rdwr(rw,gp,base,len,offset,segflg,unit,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(aresid),0)
#define gop_lookupname(fnamep,segflg,followlink,compvpp) \
avc->v.v_vfsp = afs_globalVFS;
vSetType(avc, VREG);
}
+
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
#undef gop_lookupname_user
#define gop_lookupname_user(fnamep,segflg,followlink,compvpp) lookupname((fnamep),(segflg),(followlink),NULL,(compvpp), NULL)
-#define osi_vnhold(avc, r) do { VN_HOLD(AFSTOV(avc)); } while(0)
-
#ifdef AFS_SGI64_ENV
#include <sys/flock.h>
extern flid_t osi_flid;
avc->lastr = 0;
}
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
#undef gop_lookupname_user
#define gop_lookupname_user osi_lookupname
-#define osi_vnhold(V, N) do { VN_HOLD(AFSTOV(V)); } while (0)
#define VN_HOLD(V) osi_Assert(igrab((V)) == (V))
#define VN_RELE(V) iput((V))
&& avc->opens == 0) {
struct inode *ip = AFSTOV(avc);
+ if (osi_vnhold(avc) != 0) {
+ /* Can't grab a ref on avc; bail out. */
+ return 0;
+ }
*slept = 1;
- AFS_FAST_HOLD(avc);
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
crfree(credp);
afs_DestroyReq(treq);
}
+
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
/* vnode */
#define VN_HOLD(vp) (vget(vp, 0))
#define VN_RELE(vp) (vrele(vp))
-#define osi_vnhold(avc, r) (VN_HOLD(AFSTOV(avc)))
#define va_nodeid va_fileid
AFSTOV(avc)->v_mount = afs_globalVFS;
vSetType(avc, VREG);
}
+
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
/* vnode */
#define VN_HOLD(vp) afs_vget((vp), 0)
#define VN_RELE(vp) vrele(vp)
-#define osi_vnhold(avc, r) afs_vget(AFSTOV(avc), 0)
#define va_nodeid va_fileid
#define vnode_t struct vnode
vSetType(avc, VREG);
}
+int
+osi_vnhold(struct vcache *avc)
+{
+ return afs_vget(AFSTOV(avc), 0);
+}
#define osi_Time() (hrestime.tv_sec)
#endif
-#define osi_vnhold(avc, r) do { \
- struct vnode *vp = AFSTOV(avc); \
- uint_t prevcount; \
- \
- mutex_enter(&vp->v_lock); \
- prevcount = vp->v_count++; \
- mutex_exit(&vp->v_lock); \
- \
- if (prevcount == 0) { \
- VFS_HOLD(afs_globalVFS); \
- } \
-} while(0)
-
#define gop_rdwr(rw,gp,base,len,offset,segflg,ioflag,ulimit,cr,aresid) \
vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(ioflag),(ulimit),(cr),(aresid))
#define gop_lookupname(fnamep,segflg,followlink,compvpp) \
* 1 directly. So, we must explicitly VFS_HOLD here. */
VFS_HOLD(afs_globalVFS);
}
+
+int
+osi_vnhold(struct vcache *avc)
+{
+ struct vnode *vp = AFSTOV(avc);
+ uint_t prevcount;
+
+ mutex_enter(&vp->v_lock);
+ prevcount = vp->v_count++;
+ mutex_exit(&vp->v_lock);
+
+ if (prevcount == 0) {
+ VFS_HOLD(afs_globalVFS);
+ }
+ return 0;
+}
}
}
if (tvp) {
- AFS_FAST_HOLD(tvp);
+ osi_Assert(osi_vnhold(tvp) == 0);
mutex_enter(&AFSTOV(tvp)->v_lock);
AFSTOV(tvp)->v_flag |= VROOT;
mutex_exit(&AFSTOV(tvp)->v_lock);
#undef gop_lookupname_user
#define gop_lookupname_user(fnamep,segflg,followlink,compvpp) lookupname((fnamep),(segflg),(followlink),(compvpp))
-#define osi_vnhold(avc, r) do { VN_HOLD(AFSTOV(avc)); } while(0)
-
/*
* Global lock support.
*/
vSetType(avc, VREG);
}
+int
+osi_vnhold(struct vcache *avc)
+{
+ VN_HOLD(AFSTOV(avc));
+ return 0;
+}
addr[0] = (long)avc;
#ifndef AFS_AIX41_ENV
/* No post processing, so don't hold ref count. */
- AFS_FAST_HOLD(avc);
+ osi_Assert(osi_vnhold(avc) == 0);
#endif
}
#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
retry = 1;
}
#else
- osi_vnhold(lruvcp, &retry);
+ if (osi_vnhold(lruvcp) != 0) {
+ retry = 1;
+ }
#endif
ReleaseReadLock(&afs_xvcache); /* could be read lock */
if (retry)
*/
if (osi_lookup_isdot(aname)) { /* special case */
ObtainReadLock(&afs_xvcache);
- osi_vnhold(adp, 0);
+ if (osi_vnhold(adp) != 0) {
+ ReleaseReadLock(&afs_xvcache);
+ code = EIO;
+ goto done;
+ }
ReleaseReadLock(&afs_xvcache);
#ifdef AFS_DARWIN80_ENV
vnode_get(AFSTOV(adp));
aname[0] == '.' && aname[1] == '.' && !aname[2]) {
ObtainReadLock(&afs_xvcache);
- osi_vnhold(afs_globalVp, 0);
+ if (osi_vnhold(afs_globalVp) != 0) {
+ ReleaseReadLock(&afs_xvcache);
+ code = EIO;
+ goto done;
+ }
ReleaseReadLock(&afs_xvcache);
#ifdef AFS_DARWIN80_ENV
vnode_get(AFSTOV(afs_globalVp));
#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV)
VREF(AFSTOV(avc));
#else
- AFS_FAST_HOLD(avc);
+ osi_Assert(osi_vnhold(avc) == 0);
#endif
/* We'll only try this once. If it fails, just release the vnode.
avc->f.states |= CCore; /* causes close to be called later */ \
\
/* The cred and vnode holds will be released in afs_FlushActiveVcaches */ \
- AFS_FAST_HOLD(avc); /* So it won't disappear */ \
+ osi_Assert(osi_vnhold(avc) == 0); /* So it won't disappear */ \
CRKEEP(avc, acred); /* Should use a better place for the creds */ \
} \
else { \
afs_osi_Sleep(&tvc->f.states);
goto loop1;
}
-#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
- AFS_FAST_HOLD(tvc);
-#else
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
ReleaseReadLock(&afs_xvcache);
continue;
}
#else
- AFS_FAST_HOLD(tvc);
-#endif
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
#endif
ReleaseReadLock(&afs_xvcache);
afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
afs_osi_Sleep(&tvc->f.states);
goto loop2;
}
-#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
- AFS_FAST_HOLD(tvc);
-#else
#ifdef AFS_DARWIN80_ENV
if (tvc->f.states & CDeadVnode) {
ReleaseReadLock(&afs_xvcache);
continue;
}
#else
- AFS_FAST_HOLD(tvc);
-#endif
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
#endif
ReleaseReadLock(&afs_xvcache);
afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
crhold(tb->cred);
}
if (avc) {
- AFS_FAST_HOLD(avc);
+ osi_Assert(osi_vnhold(avc) == 0);
}
tb->refCount = ause + 1;
tb->size_parm[0] = asparm0;
extern void osi_PostPopulateVCache(struct vcache *);
extern void osi_AttachVnode(struct vcache *, int seq);
+/**
+ * Increment the refcount on the given vcache.
+ *
+ * @retval 0 Success
+ * @retval nonzero Error obtaining reference; the vcache is no longer valid and
+ * the caller should act as if it doesn't exist.
+ */
+extern int osi_vnhold(struct vcache *);
+
/*
* In IRIX 6.5 and NetBSD we cannot have DEBUG turned on since certain
* system-defined structures are a different size with DEBUG on, the
* (Also, of course, the vnode is assumed to be one of ours. Can't use this
* macro for V-file vnodes.)
*/
-/* osi_vnhold is defined in PLATFORM/osi_machdep.h */
-#define AFS_FAST_HOLD(vp) osi_vnhold((vp), 0)
-
#ifdef AFS_AIX_ENV
#define AFS_FAST_RELE(vp) VREFCOUNT_DEC(vp)
#else
return 0;
}
#else
- osi_vnhold(tvc, 0);
+ if (osi_vnhold(tvc) != 0) {
+ dnlcstats.misses++;
+ osi_dnlc_remove(adp, aname, tvc);
+ tvc = NULL;
+ }
#endif
ReleaseReadLock(&afs_xvcache);
continue;
}
#else
- AFS_FAST_HOLD(tvc);
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
#endif
ReleaseReadLock(&afs_xvcache);
ObtainWriteLock(&tvc->lock, 232);
#if defined(AFS_LINUX22_ENV)
/* Hold it for the LRU (should make count 2) */
- AFS_FAST_HOLD(tvc);
+ osi_Assert(osi_vnhold(tvc) == 0);
#elif !(defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV))
VREFCOUNT_SET(tvc, 1); /* us */
#endif
#endif
if (doflocks && tvc->flockCount != 0) {
struct rx_connection *rxconn;
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
/* if this entry has an flock, send a keep-alive call out */
- osi_vnhold(tvc, 0);
ReleaseReadLock(&afs_xvcache);
ObtainWriteLock(&tvc->lock, 51);
do {
* this code. Also, drop the afs_xvcache lock while
* getting vcache locks.
*/
- osi_vnhold(tvc, 0);
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
ReleaseReadLock(&afs_xvcache);
#if defined(AFS_SGI_ENV)
/*
AFS_GLOCK();
continue;
}
+#else
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
#endif
break;
}
if (!haveStatus && (!tvc || !(tvc->f.states & CStatd))) {
/* Mount point no longer stat'd or unknown. FID may have changed. */
getNewFid = 1;
- ReleaseSharedLock(&afs_xvcache);
#ifdef AFS_DARWIN80_ENV
+ ReleaseSharedLock(&afs_xvcache);
if (tvc) {
AFS_GUNLOCK();
vnode_put(AFSTOV(tvc));
vnode_rele(AFSTOV(tvc));
AFS_GLOCK();
}
+#else
+ if (tvc) {
+ AFS_FAST_RELE(tvc);
+ }
+ ReleaseSharedLock(&afs_xvcache);
#endif
tvc = NULL;
goto newmtpt;
afs_stats_cmperf.vcacheMisses++;
} else {
afs_stats_cmperf.vcacheHits++;
-#if defined(AFS_DARWIN80_ENV)
- /* we already bumped the ref count in the for loop above */
-#else /* AFS_DARWIN80_ENV */
- osi_vnhold(tvc, 0);
-#endif
UpgradeSToWLock(&afs_xvcache, 24);
if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) {
refpanic("GRVC VLRU inconsistent0");
return -1;
}
#else
- osi_vnhold(tvc, 0);
+ if (osi_vnhold(tvc) != 0) {
+ return -1;
+ }
#endif
return 0;
} /*afs_RefVCache */
/* should I have a read lock on the vnode here? */
if (tvc) {
- if (retry)
- *retry = 0;
#if defined(AFS_DARWIN80_ENV)
tvp = AFSTOV(tvc);
if (vnode_get(tvp))
AFS_GLOCK();
tvc->f.states &= ~CUBCinit;
#else
- osi_vnhold(tvc, retry); /* already held, above */
- if (retry && *retry)
- return 0;
+ if (osi_vnhold(tvc) != 0) {
+ tvc = NULL;
+ }
#endif
+ }
+ if (tvc) {
/*
* only move to front of vlru if we have proper vcache locking)
*/
AFS_GLOCK();
continue;
}
+#else
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
#endif /* AFS_DARWIN80_ENV */
count++;
if (found_tvc) {
/* Duplicates */
afs_duplicate_nfs_fids++;
+#ifndef AFS_DARWIN80_ENV
+ AFS_FAST_RELE(tvc);
+ AFS_FAST_RELE(found_tvc);
+#endif
ReleaseSharedLock(&afs_xvcache);
#ifdef AFS_DARWIN80_ENV
/* Drop our reference counts. */
tvc = found_tvc;
/* should I have a read lock on the vnode here? */
if (tvc) {
-#ifndef AFS_DARWIN80_ENV
-# if defined(AFS_SGI_ENV) && !defined(AFS_SGI53_ENV)
- afs_int32 retry = 0;
- osi_vnhold(tvc, &retry);
- if (retry) {
- count = 0;
- found_tvc = (struct vcache *)0;
- ReleaseSharedLock(&afs_xvcache);
- spunlock_psema(tvc->v.v_lock, retry, &tvc->v.v_sync, PINOD);
- goto loop;
- }
-# else
- osi_vnhold(tvc, (int *)0); /* already held, above */
-# endif
-#endif
/*
* We obtained the xvcache lock above.
*/
continue;
}
#else
- AFS_FAST_HOLD(tvc);
+ if (osi_vnhold(tvc) != 0) {
+ continue;
+ }
#endif
ReleaseReadLock(&afs_xvcache);