/*
* osi_misc.c
*
- * Implements:
- * afs_suser
*/
#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/sysincludes.h" /* Standard vendor system headers */
#include "afsincludes.h" /* Afs-based standard headers */
#include <sys/namei.h>
-#ifdef AFS_FBSD50_ENV
-/* serious cheating */
-#undef curproc
-#define curproc curthread
-#endif
-
int
osi_lookupname(char *aname, enum uio_seg seg, int followlink,
struct vnode **vpp)
struct nameidata n;
int flags, error, glocked;
-#ifdef AFS_FBSD50_ENV
glocked = ISAFS_GLOCK();
if (glocked)
AFS_GUNLOCK();
-#endif
+#if __FreeBSD_version >= 1000021 /* MPSAFE is gone for good! */
flags = 0;
- flags = LOCKLEAF;
+#else
+ flags = MPSAFE; /* namei must take Giant if needed */
+#endif
if (followlink)
flags |= FOLLOW;
else
flags |= NOFOLLOW;
-#ifdef AFS_FBSD80_ENV
- flags |= MPSAFE; /* namei must take GIANT if needed */
-#endif
- NDINIT(&n, LOOKUP, flags, seg, aname, curproc);
+ NDINIT(&n, LOOKUP, flags, seg, aname, curthread);
if ((error = namei(&n)) != 0) {
-#ifdef AFS_FBSD50_ENV
if (glocked)
AFS_GLOCK();
-#endif
return error;
}
*vpp = n.ni_vp;
/* XXX should we do this? Usually NOT (matt) */
#if defined(AFS_FBSD80_ENV)
/*VOP_UNLOCK(n.ni_vp, 0);*/
-#elif defined(AFS_FBSD50_ENV)
- VOP_UNLOCK(n.ni_vp, 0, curthread);
#else
- VOP_UNLOCK(n.ni_vp, 0, curproc);
+ VOP_UNLOCK(n.ni_vp, 0, curthread);
#endif
NDFREE(&n, NDF_ONLY_PNBUF);
-#ifdef AFS_FBSD50_ENV
if (glocked)
AFS_GLOCK();
-#endif
return 0;
}
void
afs_osi_SetTime(osi_timeval_t * atv)
{
-#ifdef AFS_FBSD50_ENV
printf("afs attempted to set clock; use \"afsd -nosettime\"\n");
-#else
- struct timespec ts;
- struct timeval tv, delta;
- int s;
-
- AFS_GUNLOCK();
- s = splclock();
- microtime(&tv);
- delta = *atv;
- timevalsub(&delta, &tv);
- ts.tv_sec = atv->tv_sec;
- ts.tv_nsec = atv->tv_usec * 1000;
- set_timecounter(&ts);
- (void)splsoftclock();
- lease_updatetime(delta.tv_sec);
- splx(s);
- resettodr();
- AFS_GLOCK();
-#endif
}
/*
osi_fbsd_alloc(size_t size, int dropglobal)
{
void *rv;
-#ifdef AFS_FBSD50_ENV
int glocked;
if (dropglobal) {
if (glocked)
AFS_GLOCK();
} else
-#endif
rv = malloc(size, M_AFS, M_NOWAIT);
return (rv);
{
free(p, M_AFS);
}
+
+/**
+ * check if a vcache is in use
+ *
+ * @return status
+ * @retcode 0 success
+ * @retcode EBUSY vcache is in use by someone else
+ * @retcode otherwise other error
+ *
+ * @pre The caller must hold the vnode interlock for the associated vnode
+ * @post The vnode interlock for the associated vnode will still be held
+ * and must be VI_UNLOCK'd by the caller
+ */
+int
+osi_fbsd_checkinuse(struct vcache *avc)
+{
+ struct vnode *vp = AFSTOV(avc);
+
+ ASSERT_VI_LOCKED(vp, "osi_fbsd_checkinuse");
+
+ /* The interlock is needed to check the usecount. */
+ if (vp->v_usecount > 0) {
+ return EBUSY;
+ }
+
+ /* XXX
+ * The value of avc->opens here came to be, at some point,
+ * typically -1. This was caused by incorrectly performing afs_close
+ * processing on vnodes being recycled */
+ if (avc->opens) {
+ return EBUSY;
+ }
+
+ /* if a lock is held, give up */
+ if (CheckLock(&avc->lock)) {
+ return EBUSY;
+ }
+
+ return 0;
+}