DAFS: Preattach, not attach, in FSYNC_Drop
[openafs.git] / src / vol / fssync-server.c
index f6e9c2f..c90d86e 100644 (file)
@@ -674,6 +674,7 @@ FSYNC_com_VolOn(FSSYNC_VolOp_command * vcom, SYNC_response * res)
     Volume * vp;
     Error error;
 
+    /* Verify the partition name is null terminated. */
     if (SYNC_verifyProtocolString(vcom->vop->partName, sizeof(vcom->vop->partName))) {
        res->hdr.reason = SYNC_REASON_MALFORMED_PACKET;
        code = SYNC_FAILED;
@@ -683,6 +684,13 @@ FSYNC_com_VolOn(FSSYNC_VolOp_command * vcom, SYNC_response * res)
     /* so, we need to attach the volume */
 
 #ifdef AFS_DEMAND_ATTACH_FS
+    /* Verify the partition name is not empty. */
+    if (*vcom->vop->partName == 0) {
+       res->hdr.reason = FSYNC_BAD_PART;
+       code = SYNC_FAILED;
+       goto done;
+    }
+
     /* check DAFS permissions */
     vp = VLookupVolume_r(&error, vcom->vop->volume, NULL);
     if (vp &&
@@ -743,10 +751,25 @@ FSYNC_com_VolOn(FSSYNC_VolOp_command * vcom, SYNC_response * res)
     }
 
 #ifdef AFS_DEMAND_ATTACH_FS
-    /* first, check to see whether we have such a volume defined */
-    vp = VPreAttachVolumeById_r(&error,
-                               vcom->vop->partName,
-                               vcom->vop->volume);
+
+    if (vp &&
+        FSYNC_partMatch(vcom, vp, 0) &&
+        vp->pending_vol_op &&
+        vp->pending_vol_op->vol_op_state == FSSYNC_VolOpRunningOnline &&
+        V_attachState(vp) == VOL_STATE_ATTACHED) {
+
+       /* noop; the volume stayed online for the volume operation and we were
+        * simply told that the vol op is done. The vp we already have is fine,
+        * so avoid confusing volume routines with trying to preattach an
+        * attached volume. */
+
+    } else {
+       /* first, check to see whether we have such a volume defined */
+       vp = VPreAttachVolumeById_r(&error,
+                                   vcom->vop->partName,
+                                   vcom->vop->volume);
+    }
+
     if (vp) {
        VCreateReservation_r(vp);
        VWaitExclusiveState_r(vp);
@@ -763,11 +786,11 @@ FSYNC_com_VolOn(FSSYNC_VolOp_command * vcom, SYNC_response * res)
                               V_VOLUPD);
     if (vp)
        VPutVolume_r(vp);
+#endif /* !AFS_DEMAND_ATTACH_FS */
     if (error) {
        code = SYNC_DENIED;
        res->hdr.reason = error;
     }
-#endif /* !AFS_DEMAND_ATTACH_FS */
 
  done:
     return code;
@@ -1963,21 +1986,32 @@ FSYNC_Drop(osi_socket fd)
     struct offlineInfo *p;
     int i;
     Error error;
+#ifndef AFS_DEMAND_ATTACH_FS
     char tvolName[VMAXPATHLEN];
+#endif
 
     VOL_LOCK;
     p = OfflineVolumes[FindHandler(fd)];
     for (i = 0; i < MAXOFFLINEVOLUMES; i++) {
        if (p[i].volumeID) {
-
            Volume *vp;
 
+#ifdef AFS_DEMAND_ATTACH_FS
+           vp = VPreAttachVolumeById_r(&error, p[i].partName, p[i].volumeID);
+           if (vp) {
+               VCreateReservation_r(vp);
+               VWaitExclusiveState_r(vp);
+               VDeregisterVolOp_r(vp);
+               VCancelReservation_r(vp);
+           }
+#else
            tvolName[0] = OS_DIRSEPC;
            sprintf(&tvolName[1], VFORMAT, afs_printable_uint32_lu(p[i].volumeID));
            vp = VAttachVolumeByName_r(&error, p[i].partName, tvolName,
                                       V_VOLUPD);
            if (vp)
                VPutVolume_r(vp);
+#endif /* !AFS_DEMAND_ATTACH_FS */
            p[i].volumeID = 0;
        }
     }