macos: fix race in afs_root
[openafs.git] / src / afs / DARWIN / osi_vnodeops.c
index fb9627b..1d8a163 100644 (file)
@@ -281,7 +281,7 @@ afs_vop_lookup(ap)
     int error;
     struct vcache *vcp;
     struct vnode *vp, *dvp;
-    register int flags = ap->a_cnp->cn_flags;
+    int flags = ap->a_cnp->cn_flags;
     int lockparent;            /* 1 => lockparent flag is set */
     int wantparent;            /* 1 => wantparent or lockparent flag */
     struct proc *p;
@@ -402,7 +402,7 @@ afs_vop_create(ap)
 {
     int error = 0;
     struct vcache *vcp;
-    register struct vnode *dvp = ap->a_dvp;
+    struct vnode *dvp = ap->a_dvp;
     struct proc *p;
     GETNAME();
     p = vop_cn_proc;
@@ -812,7 +812,7 @@ afs_vop_read(ap)
 #endif
     AFS_GLOCK();
     osi_FlushPages(avc, vop_cred);     /* hold bozon lock, but not basic vnode lock */
-    code = afs_read(avc, ap->a_uio, vop_cred, 0, 0, 0);
+    code = afs_read(avc, ap->a_uio, vop_cred, 0);
     AFS_GUNLOCK();
     return code;
 }
@@ -829,7 +829,7 @@ afs_vop_pagein(ap)
                                 * int a_flags;
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
     upl_t pl = ap->a_pl;
     size_t size = ap->a_size;
     off_t f_offset = ap->a_f_offset;
@@ -898,7 +898,7 @@ afs_vop_pagein(ap)
 #endif
     AFS_GLOCK();
     osi_FlushPages(tvc, vop_cred);     /* hold bozon lock, but not basic vnode lock */
-    code = afs_read(tvc, uio, cred, 0, 0, 0);
+    code = afs_read(tvc, uio, cred, 0);
     if (code == 0) {
        ObtainWriteLock(&tvc->lock, 2);
        tvc->f.states |= CMAPPED;
@@ -974,7 +974,7 @@ afs_vop_pageout(ap)
                                 * int           a_flags
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
     upl_t pl = ap->a_pl;
     size_t size = ap->a_size;
     off_t f_offset = ap->a_f_offset;
@@ -1207,9 +1207,13 @@ afs_vop_fsync(ap)
 {
     int wait = ap->a_waitfor == MNT_WAIT;
     int error;
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
     int haveGlock = ISAFS_GLOCK();
 
+    /* in order to recycle faked vnodes for bulkstat */
+    if (VTOAFS(vp) == NULL)
+       return ENOTSUP;
+
     /* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */
     if (!haveGlock) AFS_GLOCK();
     if (vop_cred)
@@ -1245,8 +1249,8 @@ afs_vop_remove(ap)
                                 * } */ *ap;
 {
     int error = 0;
-    register struct vnode *vp = ap->a_vp;
-    register struct vnode *dvp = ap->a_dvp;
+    struct vnode *vp = ap->a_vp;
+    struct vnode *dvp = ap->a_dvp;
 
 #ifdef AFS_DARWIN80_ENV
     if (ap->a_flags & VNODE_REMOVE_NODELETEBUSY) {
@@ -1310,8 +1314,8 @@ afs_vop_link(ap)
                                 * } */ *ap;
 {
     int error = 0;
-    register struct vnode *dvp = ap->a_tdvp;
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *dvp = ap->a_tdvp;
+    struct vnode *vp = ap->a_vp;
     struct proc *p;
 
     GETNAME();
@@ -1362,9 +1366,9 @@ afs_vop_rename(ap)
     struct componentname *tcnp = ap->a_tcnp;
     char *tname;
     struct vnode *tvp = ap->a_tvp;
-    register struct vnode *tdvp = ap->a_tdvp;
+    struct vnode *tdvp = ap->a_tdvp;
     struct vnode *fvp = ap->a_fvp;
-    register struct vnode *fdvp = ap->a_fdvp;
+    struct vnode *fdvp = ap->a_fdvp;
     struct proc *p; 
 
     p = cn_proc(fcnp);
@@ -1562,8 +1566,8 @@ afs_vop_mkdir(ap)
                                 * struct vattr *a_vap;
                                 * } */ *ap;
 {
-    register struct vnode *dvp = ap->a_dvp;
-    register struct vattr *vap = ap->a_vap;
+    struct vnode *dvp = ap->a_dvp;
+    struct vattr *vap = ap->a_vap;
     int error = 0;
     struct vcache *vcp;
     struct proc *p;
@@ -1613,8 +1617,8 @@ afs_vop_rmdir(ap)
                                 * } */ *ap;
 {
     int error = 0;
-    register struct vnode *vp = ap->a_vp;
-    register struct vnode *dvp = ap->a_dvp;
+    struct vnode *vp = ap->a_vp;
+    struct vnode *dvp = ap->a_dvp;
 
     GETNAME();
     if (dvp == vp) {
@@ -1650,7 +1654,7 @@ afs_vop_symlink(ap)
                                 * char *a_target;
                                 * } */ *ap;
 {
-    register struct vnode *dvp = ap->a_dvp;
+    struct vnode *dvp = ap->a_dvp;
     int error = 0;
     /* NFS ignores a_vpp; so do we. */
 
@@ -1750,7 +1754,7 @@ afs_vop_inactive(ap)
                                 * struct proc *a_p;
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
     struct vcache *tvc = VTOAFS(vp);
 #ifndef AFS_DARWIN80_ENV
     if (prtactive && vp->v_usecount != 0)
@@ -1784,7 +1788,7 @@ afs_vop_reclaim(ap)
 {
     int error = 0;
     int sl, writelocked;
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
     struct vcache *tvc = VTOAFS(vp);
 
     osi_Assert(!ISAFS_GLOCK());
@@ -1959,8 +1963,8 @@ afs_vop_lock(ap)
                                 * struct vnode *a_vp;
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
-    register struct vcache *avc = VTOAFS(vp);
+    struct vnode *vp = ap->a_vp;
+    struct vcache *avc = VTOAFS(vp);
 
     if (vp->v_tag == VT_NON)
        return (ENOENT);
@@ -1994,7 +1998,7 @@ afs_vop_truncate(ap)
                                 * } */ *ap;
 {
     /* printf("stray afs_vop_truncate\n"); */
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
@@ -2007,7 +2011,7 @@ afs_vop_update(ap)
                                 * } */ *ap;
 {
     /* printf("stray afs_vop_update\n"); */
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 int
@@ -2057,8 +2061,8 @@ afs_vop_print(ap)
                                 * struct vnode *a_vp;
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
-    register struct vcache *vc = VTOAFS(ap->a_vp);
+    struct vnode *vp = ap->a_vp;
+    struct vcache *vc = VTOAFS(ap->a_vp);
     int s = vc->f.states;
     printf("tag %d, fid: %ld.%x.%x.%x, opens %d, writers %d", vp->v_tag,
           vc->f.fid.Cell, vc->f.fid.Fid.Volume, vc->f.fid.Fid.Vnode,
@@ -2109,7 +2113,7 @@ afs_vop_cmap(ap)
 #endif
 
 int
-afs_darwin_getnewvnode(struct vcache *avc, int recycle)
+afs_darwin_getnewvnode(struct vcache *avc)
 {
 #ifdef AFS_DARWIN80_ENV
     vnode_t vp;
@@ -2128,8 +2132,7 @@ afs_darwin_getnewvnode(struct vcache *avc, int recycle)
       vnode_addfsref(vp);
       vnode_ref(vp);
       avc->v = vp;
-      if (recycle)
-         vnode_recycle(vp); /* terminate as soon as iocount drops */
+      vnode_recycle(vp); /* terminate as soon as iocount drops */
       avc->f.states |= CDeadVnode;
     }
     return error;
@@ -2145,20 +2148,23 @@ afs_darwin_getnewvnode(struct vcache *avc, int recycle)
 #ifdef AFS_DARWIN80_ENV
 /* if this fails, then tvc has been unrefed and may have been freed. 
    Don't touch! */
-int 
-afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot, int locked)
+int
+afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp,
+                        struct componentname *cnp, int isroot, int locked)
 {
     vnode_t ovp;
     vnode_t nvp;
     int error;
     struct vnode_fsparam par;
+
     if (!locked) {
        AFS_GLOCK();
        ObtainWriteLock(&avc->lock,325);
     }
     ovp = AFSTOV(avc);
+
     if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) {
-        AFS_GUNLOCK();
+       AFS_GUNLOCK();
 #if 0 /* unsupported */
         if (dvp && cnp)
            vnode_update_identity(ovp, dvp, cnp->cn_nameptr, cnp->cn_namelen,
@@ -2166,14 +2172,15 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
                                  VNODE_UPDATE_PARENT|VNODE_UPDATE_NAME);
 #endif
        /* Can end up in reclaim... drop GLOCK */
-        vnode_rele(ovp);
+       vnode_rele(ovp);
        AFS_GLOCK();
        if (!locked) {
            ReleaseWriteLock(&avc->lock);
            AFS_GUNLOCK();
        }
-        return 0;
+       return 0;
     }
+
     if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
        panic("vcache %p should not be CDeadVnode", avc);
     AFS_GUNLOCK();
@@ -2196,13 +2203,13 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
        if ((avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)
            printf("vcache %p should not be CDeadVnode", avc);
        if (avc->v == ovp) {
-           if (avc->f.states & CBulkFetching) {
-               vnode_recycle(ovp);
-           }
            if (!(avc->f.states & CVInit)) {
                vnode_clearfsnode(ovp);
                vnode_removefsref(ovp);
            }
+           /* we're discarding on a fixup. mark for recycle */
+           if (!(avc->f.states & CDeadVnode))
+               vnode_recycle(ovp);
        }
        avc->v = nvp;
        avc->f.states &=~ CDeadVnode;
@@ -2227,6 +2234,10 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct component
        vnode_put(ovp);
        vnode_rele(ovp);
     }
+    /* If it's ref'd still, unmark stat'd to force new lookup */
+    if ((vnode_vtype(ovp) != avc->f.m.Type) && VREFCOUNT_GT(avc, 1))
+       avc->f.states &= ~CStatd;
+
     vnode_put(ovp);
     vnode_rele(ovp);
     AFS_GLOCK();