DAFS: Fix VOL_QUERY_VOP error codes
authorAndrew Deason <adeason@sinenomine.net>
Wed, 8 Dec 2010 18:41:44 +0000 (12:41 -0600)
committerDerrick Brashear <shadow@dementia.org>
Fri, 10 Dec 2010 21:01:52 +0000 (13:01 -0800)
Volumes in the VOL_STATE_DELETED state effectively do not exist. So,
when receiving an FSYNC_VOL_QUERY_VOP request for a volume, report
FSYNC_UNKNOWN_VOLID for a volume in the VOL_STATE_DELETED state.
Similarly, if the volume exists but on a different partition, we
should return the FSYNC_WRONG_PART reason code.

This allows volumes to be usable by the volume server in some corner
cases. For example, when a volume X exists on partitions A and B, and
the volserver deletes X on B. The fileserver then puts volume X in the
DELETED state, allowing checkouts over fsync, but FSYNC_VOL_QUERY_VOP
reports that no vop exists.

With this change, FSYNC_VOL_QUERY_VOP will instead report that the
volume does not exist, and so FSYNC_VerifyCheckout can succeed for
such volumes.

Change-Id: I6c4f7deead745ddba44963a9f66a9f2ef25686a5
Reviewed-on: http://gerrit.openafs.org/3493
Reviewed-by: Tom Keiser <tkeiser@sinenomine.net>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/vol/fssync-client.c
src/vol/fssync-server.c

index fc3b6c0..0aff910 100644 (file)
@@ -249,9 +249,11 @@ FSYNC_VerifyCheckout(VolumeId volume, char * partition,
            return SYNC_DENIED;
        }
 
-       if (res.hdr.reason == FSYNC_UNKNOWN_VOLID) {
-           /* if the fileserver does not know about this volume, there's no
-            * way it could have attached it, so we're fine */
+       if (res.hdr.reason == FSYNC_UNKNOWN_VOLID ||
+           res.hdr.reason == FSYNC_WRONG_PART) {
+           /* if the fileserver does not know about this volume on this
+            * partition, there's no way it could have attached it, so we're
+            * fine */
            return SYNC_OK;
        }
 
index 1479b73..b9bb6e6 100644 (file)
@@ -1517,10 +1517,12 @@ FSYNC_com_VolOpQuery(FSSYNC_VolOp_command * vcom, SYNC_response * res)
        memcpy(res->payload.buf, vp->pending_vol_op, sizeof(FSSYNC_VolOp_info));
        res->hdr.response_len += sizeof(FSSYNC_VolOp_info);
     } else {
-       if (vp) {
-           res->hdr.reason = FSYNC_NO_PENDING_VOL_OP;
-       } else {
+       if (!vp || V_attachState(vp) == VOL_STATE_DELETED) {
            res->hdr.reason = FSYNC_UNKNOWN_VOLID;
+       } else if (!FSYNC_partMatch(vcom, vp, 1)) {
+           res->hdr.reason = FSYNC_WRONG_PART;
+       } else {
+           res->hdr.reason = FSYNC_NO_PENDING_VOL_OP;
        }
        code = SYNC_FAILED;
     }