afs: clarify cold and warm shutdown logic
[openafs.git] / src / afs / DARWIN / osi_vfsops.c
index 84dd3ca..e9b4383 100644 (file)
@@ -28,7 +28,7 @@ int afs_vfs_typenum;
 int
 afs_quotactl()
 {
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
@@ -196,7 +196,7 @@ afs_unmount(struct mount *mp, int flags, CTX_TYPE ctx)
                vflush(mp, NULLVP, FORCECLOSE/*0*/);
                AFS_GLOCK();
                afs_globalVFS = 0;
-               afs_shutdown();
+               afs_shutdown(AFS_WARM);
            } else {
                AFS_GUNLOCK();
                return EBUSY;
@@ -222,9 +222,10 @@ afs_root(struct mount *mp, struct vnode **vpp)
     int error;
     struct vrequest treq;
     struct vcache *tvp = 0;
+    struct vcache *gvp;
+    int needref=0;
 #ifdef AFS_DARWIN80_ENV
     struct ucred *cr = vfs_context_ucred(ctx);
-    int needref=0;
 #else
     struct proc *p = current_proc();
     struct ucred _cr;
@@ -236,13 +237,13 @@ afs_root(struct mount *mp, struct vnode **vpp)
 #endif
     AFS_GLOCK();
     AFS_STATCNT(afs_root);
+
+again:
     if (mdata == NULL && afs_globalVp
        && (afs_globalVp->f.states & CStatd)) {
        tvp = afs_globalVp;
        error = 0;
-#ifdef AFS_DARWIN80_ENV
         needref=1;
-#endif
     } else if (mdata == (qaddr_t) - 1) {
        error = ENOENT;
     } else {
@@ -250,7 +251,7 @@ afs_root(struct mount *mp, struct vnode **vpp)
            ? &afs_rootFid : (struct VenusFid *)mdata;
 
        if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
-           tvp = afs_GetVCache(rootFid, &treq, NULL, NULL);
+           tvp = afs_GetVCache(rootFid, &treq);
 #ifdef AFS_DARWIN80_ENV
             if (tvp) {
                AFS_GUNLOCK();
@@ -258,7 +259,7 @@ afs_root(struct mount *mp, struct vnode **vpp)
                AFS_GLOCK();
                 if (error)
                    tvp = NULL;
-                else 
+                else
                    /* re-acquire the usecount that finalizevnode disposed of */
                    vnode_ref(AFSTOV(tvp));
             }
@@ -266,36 +267,46 @@ afs_root(struct mount *mp, struct vnode **vpp)
            /* we really want this to stay around */
            if (tvp) {
                if (mdata == NULL) {
-                   if (afs_globalVp) {
-                       afs_PutVCache(afs_globalVp);
-                       afs_globalVp = NULL;
-                   }
+                   gvp = afs_globalVp;
                    afs_globalVp = tvp;
-#ifdef AFS_DARWIN80_ENV
+                   if (gvp) {
+                       afs_PutVCache(gvp);
+                       if (tvp != afs_globalVp) {
+                           /* someone else got there before us! */
+                           afs_PutVCache(tvp);
+                           tvp = 0;
+                           goto again;
+                       }
+                   }
                     needref=1;
-#endif
                 }
            } else
-               error = ENOENT;
+               error = EIO;
        }
     }
     if (tvp) {
-#ifndef AFS_DARWIN80_ENV /* DARWIN80 caller does not need a usecount reference */
-       osi_vnhold(tvp, 0);
+#ifndef AFS_DARWIN80_ENV /* KPI callers don't need a usecount reference */
+       osi_Assert(osi_vnhold(tvp) == 0);
        AFS_GUNLOCK();
        vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
        AFS_GLOCK();
 #endif
+
+        if (needref)
 #ifdef AFS_DARWIN80_ENV
-        if (needref) /* this iocount is for the caller. the initial iocount
-                        is for the eventual afs_PutVCache. for mdata != null,
-                        there will not be a PutVCache, so the caller gets the
-                        initial (from GetVCache or finalizevnode) iocount*/
-           vnode_get(AFSTOV(tvp));
+           /* This iocount is for the caller. the initial iocount
+            * is for the eventual afs_PutVCache. for mdata != null,
+            * there will not be a PutVCache, so the caller gets the
+            * initial (from GetVCache or finalizevnode) iocount
+            */
+           vnode_get(AFSTOV(tvp));
+#else
+           ;
 #endif
-       if (mdata == NULL) {
+
+       if (mdata == NULL)
            afs_globalVFS = mp;
-       }
+
        *vpp = AFSTOV(tvp);
 #ifndef AFS_DARWIN80_ENV 
        AFSTOV(tvp)->v_flag |= VROOT;
@@ -346,16 +357,9 @@ afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx)
     abp->f_bsize = mp->vfs_bsize;
     abp->f_iosize = mp->vfs_bsize;
 #endif
-#if 0
-    abp->f_type = MOUNT_AFS;
-#endif
 
-    /* Fake a high number below to satisfy programs that use the statfs call
-     * to make sure that there's enough space in the device partition before
-     * storing something there.
-     */
     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
-      abp->f_ffree = 0x7fffffff;
+      abp->f_ffree = AFS_VFS_FAKEFREE;
 
     if (abp != sysstat) {
         abp->f_fsid.val[0] = sysstat->f_fsid.val[0];
@@ -395,6 +399,8 @@ afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs,
                    VOL_CAP_FMT_ZERO_RUNS |
                    VOL_CAP_FMT_CASE_SENSITIVE |
                    VOL_CAP_FMT_CASE_PRESERVING |
+                  VOL_CAP_FMT_PERSISTENTOBJECTIDS |
+                  VOL_CAP_FMT_2TB_FILESIZE |
                    VOL_CAP_FMT_FAST_STATFS;
          vcapattrptr->capabilities[VOL_CAPABILITIES_INTERFACES] = 
                    VOL_CAP_INT_ADVLOCK | 
@@ -414,6 +420,8 @@ afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs,
                  VOL_CAP_FMT_ZERO_RUNS |
                  VOL_CAP_FMT_CASE_SENSITIVE |
                  VOL_CAP_FMT_CASE_PRESERVING |
+                VOL_CAP_FMT_PERSISTENTOBJECTIDS |
+                VOL_CAP_FMT_2TB_FILESIZE |
                  VOL_CAP_FMT_FAST_STATFS;
          vcapattrptr->valid[VOL_CAPABILITIES_INTERFACES] =
                  VOL_CAP_INT_SEARCHFS |
@@ -448,6 +456,7 @@ afs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
 
 u_int32_t afs_darwin_realmodes = 0;
 u_int32_t afs_darwin_fsevents = 0;
+extern int AFSDOBULK;
 
 int
 afs_sysctl_int(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
@@ -504,13 +513,16 @@ afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
            case AFS_SC_DARWIN_ALL_FSEVENTS:
                return afs_sysctl_int(name, namelen, oldp, oldlenp,
                                      newp, newlen, &afs_darwin_fsevents);
+           case AFS_SC_DARWIN_ALL_BULKSTAT:
+               return afs_sysctl_int(name, namelen, oldp, oldlenp,
+                                     newp, newlen, &AFSDOBULK);
            }
            break;
            /* darwin version specific sysctl's goes here */
        }
        break;
     }
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 typedef (*PFI) ();