Fix build for FreeBSD 10.0
[openafs.git] / src / afs / FBSD / osi_misc.c
index 00d91cf..9dd1e11 100644 (file)
 /* 
  * osi_misc.c
  *
- * Implements:
- * afs_suser
  */
 
-#include "../afs/param.h"      /* Should be always first */
-#include "../afs/sysincludes.h"        /* Standard vendor system headers */
-#include "../afs/afsincludes.h"        /* Afs-based standard headers */
+#include <afsconfig.h>
+#include "afs/param.h"
+
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afsincludes.h"       /* Afs-based standard headers */
+#include <sys/namei.h>
+
+int
+osi_lookupname(char *aname, enum uio_seg seg, int followlink,
+              struct vnode **vpp)
+{
+    struct nameidata n;
+    int flags, error, glocked;
+
+    glocked = ISAFS_GLOCK();
+    if (glocked)
+       AFS_GUNLOCK();
+
+#if __FreeBSD_version >= 1000021 /* MPSAFE is gone for good! */
+    flags = LOCKLEAF;
+#else
+    flags = LOCKLEAF | MPSAFE; /* namei must take Giant if needed */
+#endif
+    if (followlink)
+       flags |= FOLLOW;
+    else
+       flags |= NOFOLLOW;
+    NDINIT(&n, LOOKUP, flags, seg, aname, curthread);
+    if ((error = namei(&n)) != 0) {
+       if (glocked)
+           AFS_GLOCK();
+       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);*/
+#else
+    VOP_UNLOCK(n.ni_vp, 0, curthread);
+#endif
+    NDFREE(&n, NDF_ONLY_PNBUF);
+    if (glocked)
+       AFS_GLOCK();
+    return 0;
+}
+
+/*
+ * does not implement security features of kern_time.c:settime()
+ */
+void
+afs_osi_SetTime(osi_timeval_t * atv)
+{
+    printf("afs attempted to set clock; use \"afsd -nosettime\"\n");
+}
 
 /*
- * afs_suser() returns true if the caller is superuser, false otherwise.
+ * Replace all of the bogus special-purpose memory allocators...
+ */
+void *
+osi_fbsd_alloc(size_t size, int dropglobal)
+{
+       void *rv;
+       int glocked;
+
+       if (dropglobal) {
+           glocked = ISAFS_GLOCK();
+           if (glocked)
+               AFS_GUNLOCK();
+           rv = malloc(size, M_AFS, M_WAITOK);
+           if (glocked)
+               AFS_GLOCK();
+       } else
+           rv = malloc(size, M_AFS, M_NOWAIT);
+
+       return (rv);
+}
+
+void
+osi_fbsd_free(void *p)
+{
+       free(p, M_AFS);
+}
+
+/**
+ * check if a vcache is in use
  *
- * Note that it must NOT set errno.
+ * @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;
+    }
 
-afs_suser() {
-    int error;
+    /* 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 (suser(curproc) == 0) {
-       return(1);
+    /* if a lock is held, give up */
+    if (CheckLock(&avc->lock)) {
+       return EBUSY;
     }
-    return(0);
+
+    return 0;
 }