VAllocVnode error handling
[openafs.git] / src / vol / vnode.c
index d051bbc..8ed9a89 100644 (file)
 #endif /* AFS_NT40_ENV */
 #include <sys/stat.h>
 
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
 /*@printflike@*/ extern void Log(const char *format, ...);
 
-/*@printflike@*/ extern void Abort(const char *format, ...);
+/*@printflike@*/ extern void Abort(const char *format, ...) AFS_NORETURN;
 
 
 struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
@@ -481,7 +485,7 @@ VGetFreeVnode_r(struct VnodeClassInfo * vcp)
     if (Vn_refcount(vnp) != 0 || CheckLock(&vnp->lock))
        Abort("VGetFreeVnode_r: locked vnode in lruq");
 #endif
-    VNLog(1, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+    VNLog(1, 2, Vn_id(vnp), (intptr_t)vnp, 0, 0);
 
     /* 
      * it's going to be overwritten soon enough.
@@ -662,7 +666,7 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
     if (vnp) {
        /* slot already exists.  May even not be in lruq (consider store file locking a file being deleted)
         * so we may have to wait for it below */
-       VNLog(3, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+       VNLog(3, 2, vnodeNumber, (intptr_t)vnp, 0, 0);
 
        VnCreateReservation_r(vnp);
        if (Vn_refcount(vnp) == 1) {
@@ -727,10 +731,11 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
 
        /* Sanity check:  is this vnode really not in use? */
        {
-           int size;
+           afs_sfsize_t size;
            IHandle_t *ihP = vp->vnodeIndex[class].handle;
            FdHandle_t *fdP;
-           off_t off = vnodeIndexOffset(vcp, vnodeNumber);
+           afs_foff_t off = vnodeIndexOffset(vcp, vnodeNumber);
+           Error tmp;
 
            /* XXX we have a potential race here if two threads
             * allocate new vnodes at the same time, and they
@@ -755,32 +760,44 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
            fdP = IH_OPEN(ihP);
            if (fdP == NULL) {
                Log("VAllocVnode: can't open index file!\n");
+               *ec = ENOENT;
                goto error_encountered;
            }
            if ((size = FDH_SIZE(fdP)) < 0) {
                Log("VAllocVnode: can't stat index file!\n");
+               *ec = EIO;
                goto error_encountered;
            }
            if (FDH_SEEK(fdP, off, SEEK_SET) < 0) {
                Log("VAllocVnode: can't seek on index file!\n");
+               *ec = EIO;
                goto error_encountered;
            }
            if (off + vcp->diskSize <= size) {
                if (FDH_READ(fdP, &vnp->disk, vcp->diskSize) != vcp->diskSize) {
                    Log("VAllocVnode: can't read index file!\n");
+                   *ec = EIO;
                    goto error_encountered;
                }
                if (vnp->disk.type != vNull) {
                    Log("VAllocVnode:  addled bitmap or index!\n");
+                   *ec = EIO;
                    goto error_encountered;
                }
            } else {
                /* growing file - grow in a reasonable increment */
                char *buf = (char *)malloc(16 * 1024);
-               if (!buf)
-                   Abort("VAllocVnode: malloc failed\n");
+               if (!buf) {
+                   *ec = ENOMEM;
+                   goto error_encountered;
+               }
                memset(buf, 0, 16 * 1024);
-               (void)FDH_WRITE(fdP, buf, 16 * 1024);
+               if ((FDH_WRITE(fdP, buf, 16 * 1024)) != 16 * 1024) {
+                   Log("VAllocVnode: can't grow vnode index: out of memory\n");
+                   *ec = EIO;
+                   free(buf);
+                   goto error_encountered;
+               }
                free(buf);
            }
            FDH_CLOSE(fdP);
@@ -794,7 +811,6 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
 
 
        error_encountered:
-#ifdef AFS_DEMAND_ATTACH_FS
            /* 
             * close the file handle
             * acquire VOL_LOCK
@@ -806,26 +822,26 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
            if (fdP)
                FDH_CLOSE(fdP);
            VOL_LOCK;
-           VFreeBitMapEntry_r(ec, &vp->vnodeIndex[class], bitNumber);
+           VFreeBitMapEntry_r(&tmp, &vp->vnodeIndex[class], bitNumber);
            VInvalidateVnode_r(vnp);
            VnUnlock(vnp, WRITE_LOCK);
            VnCancelReservation_r(vnp);
+#ifdef AFS_DEMAND_ATTACH_FS
            VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, 0);
            VCancelReservation_r(vp);
-           return NULL;
 #else
-           assert(1 == 2);
+           VForceOffline_r(vp, 0);
 #endif
-
+           return NULL;
        }
     sane:
-       VNLog(4, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+       VNLog(4, 2, vnodeNumber, (intptr_t)vnp, 0, 0);
 #ifndef AFS_DEMAND_ATTACH_FS
        AddToVnHash(vnp);
 #endif
     }
 
-    VNLog(5, 1, (afs_int32) vnp, 0, 0, 0);
+    VNLog(5, 1, (intptr_t)vnp, 0, 0, 0);
     memset(&vnp->disk, 0, sizeof(vnp->disk));
     vnp->changed_newTime = 0;  /* set this bit when vnode is updated */
     vnp->changed_oldTime = 0;  /* set this on CopyOnWrite. */
@@ -866,7 +882,8 @@ VnLoad(Error * ec, Volume * vp, Vnode * vnp,
 {
     /* vnode not cached */
     Error error;
-    int n, dosalv = 1;
+    int dosalv = 1;
+    ssize_t nBytes;
     IHandle_t *ihP = vp->vnodeIndex[class].handle;
     FdHandle_t *fdP;
 
@@ -892,23 +909,23 @@ VnLoad(Error * ec, Volume * vp, Vnode * vnp,
        Log("VnLoad: can't seek on index file vn=%u\n", Vn_id(vnp));
        *ec = VIO;
        goto error_encountered_nolock;
-    } else if ((n = FDH_READ(fdP, (char *)&vnp->disk, vcp->diskSize))
+    } else if ((nBytes = FDH_READ(fdP, (char *)&vnp->disk, vcp->diskSize))
               != vcp->diskSize) {
        /* Don't take volume off line if the inumber is out of range
         * or the inode table is full. */
-       if (n == BAD_IGET) {
+       if (nBytes == BAD_IGET) {
            Log("VnLoad: bad inumber %s\n",
                PrintInode(NULL, vp->vnodeIndex[class].handle->ih_ino));
            *ec = VIO;
            dosalv = 0;
-       } else if (n == -1 && errno == EIO) {
+       } else if (nBytes == -1 && errno == EIO) {
            /* disk error; salvage */
            Log("VnLoad: Couldn't read vnode %u, volume %u (%s); volume needs salvage\n", Vn_id(vnp), V_id(vp), V_name(vp));
        } else {
            /* vnode is not allocated */
            if (LogLevel >= 5) 
                Log("VnLoad: Couldn't read vnode %u, volume %u (%s); read %d bytes, errno %d\n", 
-                   Vn_id(vnp), V_id(vp), V_name(vp), n, errno);
+                   Vn_id(vnp), V_id(vp), V_name(vp), (int)nBytes, errno);
            *ec = VIO;
            dosalv = 0;
        }
@@ -992,7 +1009,8 @@ static void
 VnStore(Error * ec, Volume * vp, Vnode * vnp, 
        struct VnodeClassInfo * vcp, VnodeClass class)
 {
-    int offset, code;
+    ssize_t nBytes;
+    afs_foff_t offset;
     IHandle_t *ihP = vp->vnodeIndex[class].handle;
     FdHandle_t *fdP;
 #ifdef AFS_DEMAND_ATTACH_FS
@@ -1018,13 +1036,13 @@ VnStore(Error * ec, Volume * vp, Vnode * vnp,
        goto error_encountered;
     }
 
-    code = FDH_WRITE(fdP, &vnp->disk, vcp->diskSize);
-    if (code != vcp->diskSize) {
+    nBytes = FDH_WRITE(fdP, &vnp->disk, vcp->diskSize);
+    if (nBytes != vcp->diskSize) {
        /* Don't force volume offline if the inumber is out of
         * range or the inode table is full.
         */
        FDH_REALLYCLOSE(fdP);
-       if (code == BAD_IGET) {
+       if (nBytes == BAD_IGET) {
            Log("VnStore: bad inumber %s\n",
                PrintInode(NULL,
                           vp->vnodeIndex[class].handle->ih_ino));
@@ -1034,7 +1052,7 @@ VnStore(Error * ec, Volume * vp, Vnode * vnp,
            VnChangeState_r(vnp, VN_STATE_ERROR);
 #endif
        } else {
-           Log("VnStore: Couldn't write vnode %u, volume %u (%s) (error %d)\n", Vn_id(vnp), V_id(Vn_volume(vnp)), V_name(Vn_volume(vnp)), code);
+           Log("VnStore: Couldn't write vnode %u, volume %u (%s) (error %d)\n", Vn_id(vnp), V_id(Vn_volume(vnp)), V_name(Vn_volume(vnp)), (int)nBytes);
 #ifdef AFS_DEMAND_ATTACH_FS
            goto error_encountered;
 #else
@@ -1167,7 +1185,7 @@ VGetVnode_r(Error * ec, Volume * vp, VnodeId vnodeNumber, int locktype)
     if (vnp) {
        /* vnode is in cache */
 
-       VNLog(101, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+       VNLog(101, 2, vnodeNumber, (intptr_t)vnp, 0, 0);
        VnCreateReservation_r(vnp);
 
 #ifdef AFS_DEMAND_ATTACH_FS
@@ -1254,7 +1272,7 @@ VGetVnode_r(Error * ec, Volume * vp, VnodeId vnodeNumber, int locktype)
 
     /* Check that the vnode hasn't been removed while we were obtaining
      * the lock */
-    VNLog(102, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+    VNLog(102, 2, vnodeNumber, (intptr_t) vnp, 0, 0);
     if ((vnp->disk.type == vNull) || (Vn_cacheCheck(vnp) == 0)) {
        VnUnlock(vnp, locktype);
        VnCancelReservation_r(vnp);
@@ -1316,7 +1334,7 @@ VPutVnode_r(Error * ec, register Vnode * vnp)
     class = vnodeIdToClass(Vn_id(vnp));
     vcp = &VnodeClassInfo[class];
     assert(vnp->disk.vnodeMagic == vcp->magic);
-    VNLog(200, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+    VNLog(200, 2, Vn_id(vnp), (intptr_t) vnp, 0, 0);
 
 #ifdef AFS_DEMAND_ATTACH_FS
     writeLocked = (Vn_state(vnp) == VN_STATE_EXCLUSIVE);
@@ -1332,7 +1350,7 @@ VPutVnode_r(Error * ec, register Vnode * vnp)
        PROCESS thisProcess;
        LWP_CurrentProcess(&thisProcess);
 #endif /* AFS_PTHREAD_ENV */
-       VNLog(201, 2, (afs_int32) vnp,
+       VNLog(201, 2, (intptr_t) vnp,
              ((vnp->changed_newTime) << 1) | ((vnp->
                                                changed_oldTime) << 1) | vnp->
              delete, 0, 0);
@@ -1350,7 +1368,7 @@ VPutVnode_r(Error * ec, register Vnode * vnp)
                /* No longer any directory entries for this vnode. Free the Vnode */
                memset(&vnp->disk, 0, sizeof(vnp->disk));
                /* delete flag turned off further down */
-               VNLog(202, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+               VNLog(202, 2, Vn_id(vnp), (intptr_t) vnp, 0, 0);
            } else if (vnp->changed_newTime) {
                vnp->disk.serverModifyTime = now;
            }
@@ -1456,7 +1474,7 @@ VVnodeWriteToRead_r(Error * ec, register Vnode * vnp)
     class = vnodeIdToClass(Vn_id(vnp));
     vcp = &VnodeClassInfo[class];
     assert(vnp->disk.vnodeMagic == vcp->magic);
-    VNLog(300, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+    VNLog(300, 2, Vn_id(vnp), (intptr_t) vnp, 0, 0);
 
 #ifdef AFS_DEMAND_ATTACH_FS
     writeLocked = (Vn_state(vnp) == VN_STATE_EXCLUSIVE);
@@ -1468,7 +1486,7 @@ VVnodeWriteToRead_r(Error * ec, register Vnode * vnp)
     }
 
 
-    VNLog(301, 2, (afs_int32) vnp,
+    VNLog(301, 2, (intptr_t) vnp,
          ((vnp->changed_newTime) << 1) | ((vnp->
                                            changed_oldTime) << 1) | vnp->
          delete, 0, 0);
@@ -1481,7 +1499,7 @@ VVnodeWriteToRead_r(Error * ec, register Vnode * vnp)
 #endif /* AFS_PTHREAD_ENV */
     if (thisProcess != vnp->writer)
        Abort("VPutVnode: Vnode at 0x%x locked by another process!\n",
-             (int)vnp);
+             (intptr_t)vnp);
 
     if (vnp->delete) {
        return 0;