vol: Avoid getting stuck in ATTACHING in attach2
[openafs.git] / src / vol / volume.c
index 791cd53..6a4fb17 100644 (file)
@@ -708,7 +708,7 @@ VInitAttachVolumes(ProgramType pt)
 
        /* create partition work queue */
        for (parts=0, diskP = DiskPartitionList; diskP; diskP = diskP->next, parts++) {
-           dpq = (diskpartition_queue_t *) malloc(sizeof(struct diskpartition_queue_t));
+           dpq = malloc(sizeof(struct diskpartition_queue_t));
            osi_Assert(dpq != NULL);
            dpq->diskP = diskP;
            queue_Append(&params,dpq);
@@ -830,7 +830,7 @@ VInitAttachVolumes(ProgramType pt)
        MUTEX_INIT(&(pq.mutex), "partq", MUTEX_DEFAULT, 0);
        for (parts = 0, diskP = DiskPartitionList; diskP; diskP = diskP->next, parts++) {
            struct diskpartition_queue_t *dp;
-           dp = (struct diskpartition_queue_t*)malloc(sizeof(struct diskpartition_queue_t));
+           dp = malloc(sizeof(struct diskpartition_queue_t));
            osi_Assert(dp != NULL);
            dp->diskP = diskP;
            queue_Append(&pq, dp);
@@ -856,7 +856,7 @@ VInitAttachVolumes(ProgramType pt)
            struct vinitvolumepackage_thread_param *params;
             AFS_SIGSET_DECL;
 
-            params = (struct vinitvolumepackage_thread_param *)malloc(sizeof(struct vinitvolumepackage_thread_param));
+            params = malloc(sizeof(struct vinitvolumepackage_thread_param));
             osi_Assert(params);
             params->pq = &pq;
             params->vq = &vq;
@@ -907,7 +907,7 @@ VInitVolumePackageThread(void *args)
     osi_Assert(pq);
     osi_Assert(vq);
 
-    vb = (struct volume_init_batch*)malloc(sizeof(struct volume_init_batch));
+    vb = malloc(sizeof(struct volume_init_batch));
     osi_Assert(vb);
     vb->thread = params->thread;
     vb->last = 0;
@@ -925,9 +925,8 @@ VInitVolumePackageThread(void *args)
             continue;
         }
         while ((vid = VInitNextVolumeId(dirp))) {
-            Volume *vp = (Volume*)malloc(sizeof(Volume));
+            Volume *vp = calloc(1, sizeof(Volume));
             osi_Assert(vp);
-            memset(vp, 0, sizeof(Volume));
             vp->device = partition->device;
             vp->partition = partition;
             vp->hashid = vid;
@@ -942,7 +941,7 @@ VInitVolumePackageThread(void *args)
                CV_BROADCAST(&vq->cv);
                MUTEX_EXIT(&vq->mutex);
 
-                vb = (struct volume_init_batch*)malloc(sizeof(struct volume_init_batch));
+                vb = malloc(sizeof(struct volume_init_batch));
                 osi_Assert(vb);
                 vb->thread = params->thread;
                 vb->size = 0;
@@ -1247,7 +1246,7 @@ VShutdown_r(void)
 
 
            /* build up the pass 0 shutdown work queue */
-           dpq = (struct diskpartition_queue_t *) malloc(sizeof(struct diskpartition_queue_t));
+           dpq = malloc(sizeof(struct diskpartition_queue_t));
            osi_Assert(dpq != NULL);
            dpq->diskP = diskP;
            queue_Prepend(&params, dpq);
@@ -2215,9 +2214,8 @@ VPreAttachVolumeByVp_r(Error * ec,
        VOL_UNLOCK;
 
        /* allocate the volume structure */
-       vp = nvp = (Volume *) malloc(sizeof(Volume));
+       vp = nvp = calloc(1, sizeof(Volume));
        osi_Assert(vp != NULL);
-       memset(vp, 0, sizeof(Volume));
        queue_Init(&vp->vnode_list);
        queue_Init(&vp->rx_call_list);
        CV_INIT(&V_attachCV(vp), "vp attach", CV_DEFAULT, 0);
@@ -3000,6 +2998,9 @@ attach_volume_header(Error *ec, Volume *vp, struct DiskPartition64 *partp,
     }
 
     if (*ec) {
+       VOL_LOCK;
+       FreeVolumeHeader(vp);
+       VOL_UNLOCK;
        return;
     }
     if (retry) {
@@ -3162,8 +3163,7 @@ attach2(Error * ec, VolId volumeId, char *path, struct DiskPartition64 *partp,
     if (*ec == VNOVOL) {
        /* if the volume doesn't exist, skip straight to 'error' so we don't
         * request a salvage */
-       VOL_LOCK;
-       goto error_notbroken;
+       goto unlocked_error;
     }
 
     if (!*ec) {
@@ -3256,6 +3256,9 @@ attach2(Error * ec, VolId volumeId, char *path, struct DiskPartition64 *partp,
     } else if (*ec) {
        /* volume operation in progress */
        VOL_LOCK;
+       /* we have already transitioned the vp away from ATTACHING state, so we
+        * can go right to the end of attach2, and we do not need to transition
+        * to ERROR. */
        goto error_notbroken;
     }
 #else /* AFS_DEMAND_ATTACH_FS */
@@ -3455,10 +3458,7 @@ attach2(Error * ec, VolId volumeId, char *path, struct DiskPartition64 *partp,
 
     return vp;
 
-#ifndef AFS_DEMAND_ATTACH_FS
 unlocked_error:
-#endif
-
     VOL_LOCK;
 locked_error:
 #ifdef AFS_DEMAND_ATTACH_FS
@@ -3475,8 +3475,8 @@ locked_error:
        VReleaseVolumeHandles_r(vp);
     }
 
- error_notbroken:
 #ifdef AFS_DEMAND_ATTACH_FS
+ error_notbroken:
     VCheckSalvage(vp);
     if (forcefree) {
        FreeVolume(vp);
@@ -4105,12 +4105,18 @@ GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint,
                case VSALVAGING:
                    break;
                case VOFFLINE:
-                   if (!vp->pending_vol_op) {
-                       endloop = 1;
+                   endloop = 1;
+                   if (vp->specialStatus) {
+                       *ec = vp->specialStatus;
                    }
                    break;
+
                default:
-                   *ec = VNOVOL;
+                   if (vp->specialStatus) {
+                       *ec = vp->specialStatus;
+                   } else {
+                       *ec = VNOVOL;
+                   }
                    endloop = 1;
                }
                if (endloop) {
@@ -4147,46 +4153,12 @@ GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint,
        }
 
        /*
-        * this test MUST happen after VAttachVolymeByVp, so vol_op_state is
-        * not VolOpRunningUnknown (attach2 would have converted it to Online
-        * or Offline)
+        * this test MUST happen after VAttachVolymeByVp, so we have no
+        * conflicting vol op. (attach2 would have errored out if we had one;
+        * specifically attach_check_vop must have detected a conflicting vop)
         */
+         osi_Assert(!vp->pending_vol_op || vp->pending_vol_op->vol_op_state == FSSYNC_VolOpRunningOnline);
 
-         /* only valid before/during demand attachment */
-         osi_Assert(!vp->pending_vol_op || vp->pending_vol_op->vol_op_state != FSSYNC_VolOpRunningUnknown);
-
-         /* deny getvolume due to running mutually exclusive vol op */
-         if (vp->pending_vol_op && vp->pending_vol_op->vol_op_state==FSSYNC_VolOpRunningOffline) {
-          /*
-           * volume cannot remain online during this volume operation.
-           * notify client.
-           */
-          if (vp->specialStatus) {
-              /*
-               * special status codes outrank normal VOFFLINE code
-               */
-              *ec = vp->specialStatus;
-              if (client_ec) {
-                  *client_ec = vp->specialStatus;
-              }
-          } else {
-              if (client_ec) {
-                  /* see CheckVnode() in afsfileprocs.c for an explanation
-                   * of this error code logic */
-                  afs_uint32 now = FT_ApproxTime();
-                  if ((vp->stats.last_vol_op + (10 * 60)) >= now) {
-                      *client_ec = VBUSY;
-                  } else {
-                      *client_ec = VRESTARTING;
-                  }
-              }
-              *ec = VOFFLINE;
-          }
-          VChangeState_r(vp, VOL_STATE_UNATTACHED);
-          FreeVolumeHeader(vp);
-          vp = NULL;
-          break;
-       }
 #endif /* AFS_DEMAND_ATTACH_FS */
 
        LoadVolumeHeader(ec, vp);
@@ -5281,7 +5253,7 @@ VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo)
     FSSYNC_VolOp_info * info;
 
     /* attach a vol op info node to the volume struct */
-    info = (FSSYNC_VolOp_info *) malloc(sizeof(FSSYNC_VolOp_info));
+    info = malloc(sizeof(FSSYNC_VolOp_info));
     osi_Assert(info != NULL);
     memcpy(info, vopinfo, sizeof(FSSYNC_VolOp_info));
     vp->pending_vol_op = info;
@@ -6447,7 +6419,7 @@ VGetBitmap_r(Error * ec, Volume * vp, VnodeClass class)
     osi_Assert(fdP != NULL);
     file = FDH_FDOPEN(fdP, "r");
     osi_Assert(file != NULL);
-    vnode = (VnodeDiskObject *) malloc(vcp->diskSize);
+    vnode = malloc(vcp->diskSize);
     osi_Assert(vnode != NULL);
     size = OS_SIZE(fdP->fd_fd);
     osi_Assert(size != -1);
@@ -6514,7 +6486,7 @@ VGetBitmap_r(Error * ec, Volume * vp, VnodeClass class)
        vip->bitmap = BitMap;
        vip->bitmapOffset = 0;
     } else
-       free((byte *) BitMap);
+       free(BitMap);
 #endif /* BITMAP_LATER */
 #ifdef AFS_DEMAND_ATTACH_FS
     VChangeState_r(vp, state_save);
@@ -6848,7 +6820,7 @@ VAddToVolumeUpdateList_r(Error * ec, Volume * vp)
        return;
     if (UpdateList == NULL) {
        updateSize = UPDATE_LIST_SIZE;
-       UpdateList = (VolumeId *) malloc(sizeof(VolumeId) * updateSize);
+       UpdateList = malloc(sizeof(VolumeId) * updateSize);
     } else {
        if (nUpdatedVolumes == updateSize) {
            updateSize <<= 1;
@@ -6856,9 +6828,8 @@ VAddToVolumeUpdateList_r(Error * ec, Volume * vp)
                Log("warning: there is likely a bug in the volume update scanner\n");
                return;
            }
-           UpdateList =
-               (VolumeId *) realloc(UpdateList,
-                                    sizeof(VolumeId) * updateSize);
+           UpdateList = realloc(UpdateList,
+                                sizeof(VolumeId) * updateSize);
        }
     }
     osi_Assert(UpdateList != NULL);
@@ -7631,7 +7602,7 @@ VLRU_Demote_r(int idx)
 
     /* no big deal if this allocation fails */
     if (volume_LRU.q[idx].len) {
-       salv_flag_vec = (Volume **) malloc(volume_LRU.q[idx].len * sizeof(Volume *));
+       salv_flag_vec = malloc(volume_LRU.q[idx].len * sizeof(Volume *));
     }
 
     now = FT_ApproxTime();
@@ -8081,7 +8052,7 @@ GetVolumeHeader(Volume * vp)
     if (programType != fileServer) {
        /* for volume utilities, we allocate volHeaders as needed */
        if (!vp->header) {
-           hd = (struct volHeader *)calloc(1, sizeof(*vp->header));
+           hd = calloc(1, sizeof(*vp->header));
            osi_Assert(hd != NULL);
            vp->header = hd;
            hd->back = vp;
@@ -8105,7 +8076,7 @@ GetVolumeHeader(Volume * vp)
            if (!hd) {
                /* LRU is empty, so allocate a new volHeader
                 * this is probably indicative of a leak, so let the user know */
-               hd = (struct volHeader *)calloc(1, sizeof(struct volHeader));
+               hd = calloc(1, sizeof(struct volHeader));
                osi_Assert(hd != NULL);
                if (!everLogged) {
                    Log("****Allocated more volume headers, probably leak****\n");