afs: Avoid panics on failed return from afs_CFileOpen
[openafs.git] / src / afs / afs_disconnected.c
index 4f4ce80..3b88585 100644 (file)
@@ -72,13 +72,15 @@ afs_FindDCacheByFid(struct VenusFid *afid)
     for (index = afs_dvhashTbl[i]; index != NULLIDX;) {
        if (afs_indexUnique[index] == afid->Fid.Unique) {
            tdc = afs_GetValidDSlot(index);
-           if (tdc) {
-               ReleaseReadLock(&tdc->tlock);
-               if (!FidCmp(&tdc->f.fid, afid)) {
-                   break;              /* leaving refCount high for caller */
-               }
-               afs_PutDCache(tdc);
-           }
+           if (!tdc) {
+                index = NULLIDX;
+                break;
+            }
+            ReleaseReadLock(&tdc->tlock);
+            if (!FidCmp(&tdc->f.fid, afid)) {
+                break;         /* leaving refCount high for caller */
+            }
+            afs_PutDCache(tdc);
        }
        index = afs_dvnextTbl[index];
     }
@@ -264,7 +266,7 @@ afs_GetVnodeName(struct vcache *avc, struct VenusFid *afid, char *aname,
        parent_vc = afs_FindVCache(&parent_fid, 0, 1);
        ReleaseSharedLock(&afs_xvcache);
        if (!parent_vc) {
-           return ENOENT;
+           return ENETDOWN;
        }
 
        shadow_fid.Cell = parent_vc->f.fid.Cell;
@@ -293,7 +295,7 @@ afs_GetVnodeName(struct vcache *avc, struct VenusFid *afid, char *aname,
            code = ENOENT;
     } else {
        /* printf("Directory dcache not found!\n"); */
-        code = ENOENT;
+        code = ENETDOWN;
     }
 
     return code;
@@ -507,7 +509,7 @@ afs_GetParentVCache(struct vcache *avc, int deleted, struct VenusFid *afid,
 
     if (afs_GetParentDirFid(avc, afid)) {
        /* printf("afs_GetParentVCache: Couldn't find parent dir's FID.\n"); */
-       return ENOENT;
+       return ENETDOWN;
     }
 
     code = afs_GetVnodeName(avc, afid, aname, deleted);
@@ -521,7 +523,7 @@ afs_GetParentVCache(struct vcache *avc, int deleted, struct VenusFid *afid,
     ReleaseSharedLock(&afs_xvcache);
     if (!*adp) {
        /* printf("afs_GetParentVCache: Couldn't find parent dir's vcache\n"); */
-       code = ENOENT;
+       code = ENETDOWN;
        goto end;
     }
 
@@ -593,7 +595,7 @@ afs_ProcessOpRename(struct vcache *avc, struct vrequest *areq)
        /* Get parent dir's FID.*/
        if (afs_GetParentDirFid(avc, &new_pdir_fid)) {
            /* printf("afs_ProcessOpRename: Couldn't find new parent dir FID.\n"); */
-           code = ENOENT;
+           code = ENETDOWN;
            goto done;
         }
     }
@@ -671,6 +673,7 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq,
     tname = afs_osi_Alloc(AFSNAMEMAX);
     if (!tname)
        return ENOMEM;
+    memset(&InStatus, 0, sizeof(InStatus));
 
     code = afs_GetParentVCache(avc, 0, &pdir_fid, tname, &tdp);
     if (code)
@@ -687,7 +690,7 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq,
 
        tdc = afs_GetDCache(avc, 0, areq, &offset, &tlen, 0);
        if (!tdc) {
-           code = ENOENT;
+           code = ENETDOWN;
            goto end;
        }
 
@@ -701,10 +704,17 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq,
        ttargetName = afs_osi_Alloc(tlen);
        if (!ttargetName) {
            afs_PutDCache(tdc);
-           return ENOMEM;
+           code = ENOMEM;
+           goto end;
        }
        ObtainReadLock(&tdc->lock);
        tfile = afs_CFileOpen(&tdc->f.inode);
+       if (!tfile) {
+           ReleaseReadLock(&tdc->lock);
+           afs_PutDCache(tdc);
+           code = EIO;
+           goto end;
+       }
        code = afs_CFileRead(tfile, 0, ttargetName, tlen);
        ttargetName[tlen-1] = '\0';
        afs_CFileClose(tfile);
@@ -856,6 +866,11 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq,
     for (index = afs_dvhashTbl[hash]; index != NULLIDX; index = hash) {
         hash = afs_dvnextTbl[index];
         tdc = afs_GetValidDSlot(index);
+        if (!tdc) {
+            ReleaseWriteLock(&afs_xdcache);
+            code = EIO;
+            goto end;
+        }
         ReleaseReadLock(&tdc->tlock);
        if (afs_indexUnique[index] == avc->f.fid.Fid.Unique) {
             if (!FidCmp(&tdc->f.fid, &avc->f.fid)) {
@@ -876,8 +891,7 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq,
                memcpy(&tdc->f.fid, &newFid, sizeof(struct VenusFid));
            }                   /* if fid match */
        }                       /* if uniquifier match */
-       if (tdc)
-           afs_PutDCache(tdc);
+        afs_PutDCache(tdc);
     }                           /* for all dcaches in this hash bucket */
     ReleaseWriteLock(&afs_xdcache);
 
@@ -1150,34 +1164,6 @@ afs_ResyncDisconFiles(struct vrequest *areq, afs_ucred_t *acred)
            tvc->f.ddirty_flags &= ~VDisconCreate;
            tvc->f.ddirty_flags |= VDisconCreated;
        }
-#if 0
-       /* Get server write lock. */
-       do {
-           tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
-           if (tc) {
-               XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
-               RX_AFS_GUNLOCK();
-               code = RXAFS_SetLock(rxconn,
-                                       (struct AFSFid *)&tvc->f.fid.Fid,
-                                       LockWrite,
-                                       &tsync);
-               RX_AFS_GLOCK();
-               XSTATS_END_TIME;
-          } else
-               code = -1;
-
-       } while (afs_Analyze(tc,
-                       rxconn,
-                       code,
-                       &tvc->f.fid,
-                       areq,
-                       AFS_STATS_FS_RPCIDX_SETLOCK,
-                       SHARED_LOCK,
-                       NULL));
-
-       if (code)
-           goto next_file;
-#endif
        if (tvc->f.ddirty_flags & VDisconRename) {
            /* If we're renaming the file, do so now */
            code = afs_ProcessOpRename(tvc, areq);
@@ -1241,29 +1227,9 @@ afs_ResyncDisconFiles(struct vrequest *areq, afs_ucred_t *acred)
        }               /* if DV match or client wins policy */
 
 unlock_srv_file:
-       /* Release server write lock. */
-#if 0
-       do {
-           tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
-           if (tc) {
-               XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
-               RX_AFS_GUNLOCK();
-               ucode = RXAFS_ReleaseLock(rxconn,
-                               (struct AFSFid *) &tvc->f.fid.Fid,
-                               &tsync);
-               RX_AFS_GLOCK();
-               XSTATS_END_TIME;
-           } else
-               ucode = -1;
-       } while (afs_Analyze(tc,
-                       rxconn,
-                       ucode,
-                       &tvc->f.fid,
-                       areq,
-                       AFS_STATS_FS_RPCIDX_RELEASELOCK,
-                       SHARED_LOCK,
-                       NULL));
-#endif
+       /* If we ever lock files while replaying changes, we should unlock the
+        * file here. */
+
 next_file:
        ObtainWriteLock(&afs_disconDirtyLock, 710);
        if (code == 0) {
@@ -1505,6 +1471,7 @@ afs_GenDisconStatus(struct vcache *adp, struct vcache *avc,
                    struct VenusFid *afid, struct vattr *attrs,
                    struct vrequest *areq, int file_type)
 {
+    afs_hyper_t zero;
     memcpy(&avc->f.fid, afid, sizeof(struct VenusFid));
     avc->f.m.Mode = attrs->va_mode;
     /* Used to do this:
@@ -1515,7 +1482,8 @@ afs_GenDisconStatus(struct vcache *adp, struct vcache *avc,
      */
     avc->f.m.Group = adp->f.m.Group;
     avc->f.m.Owner = adp->f.m.Owner;
-    hset64(avc->f.m.DataVersion, 0, 0);
+    hzero(zero);
+    afs_SetDataVersion(avc, &zero);
     avc->f.m.Length = attrs->va_size;
     avc->f.m.Date = osi_Time();
     switch(file_type) {
@@ -1535,7 +1503,7 @@ afs_GenDisconStatus(struct vcache *adp, struct vcache *avc,
        vSetType(avc, VLNK);
        avc->f.m.Mode |= S_IFLNK;
        if ((avc->f.m.Mode & 0111) == 0)
-           avc->mvstat = 1;
+           avc->mvstat = AFS_MVSTAT_MTPT;
        avc->f.parent.vnode = adp->f.fid.Fid.Vnode;
        avc->f.parent.unique = adp->f.fid.Fid.Unique;
        break;