From bb9caf9822a53ad07cd3a5d6cea7f6b7eeeedd59 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Tue, 10 Aug 2010 14:16:39 -0500 Subject: [PATCH] viced: VNOVOL on deleted volumes When the volserver deletes a volume, the fileserver should respond to future access to that volume with VNOVOL and not VOFFLINE, since the volume doesn't exist anymore. Do this in DAFS via a new state, VOL_STATE_DELETED, and in non-DAFS by just setting specialStatus to VNOVOL. In the future we should also make sure the vp's for deleted volumes get freed after a couple of hours, but not yet. Change-Id: I6dec3e0a5e9e54f6ad09fad9f2355b513cce3bf6 --- src/vol/fssync-debug.c | 1 + src/vol/fssync-server.c | 21 ++++++++++++++++----- src/vol/volume.c | 22 ++++++++++++++++------ src/vol/volume.h | 5 +++-- src/vol/volume_inline.h | 1 + 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/vol/fssync-debug.c b/src/vol/fssync-debug.c index 0f4ced910f..ec02d3101e 100644 --- a/src/vol/fssync-debug.c +++ b/src/vol/fssync-debug.c @@ -554,6 +554,7 @@ vol_state_to_string(VolState state) ENUMCASE(VOL_STATE_VNODE_CLOSE); ENUMCASE(VOL_STATE_VNODE_RELEASE); ENUMCASE(VOL_STATE_VLRU_ADD); + ENUMCASE(VOL_STATE_DELETED); ENUMCASE(VOL_STATE_FREED); default: return "**UNKNOWN**"; diff --git a/src/vol/fssync-server.c b/src/vol/fssync-server.c index c54ad3712e..b56eff6c2a 100644 --- a/src/vol/fssync-server.c +++ b/src/vol/fssync-server.c @@ -1185,10 +1185,8 @@ static afs_int32 FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res) { afs_int32 code = SYNC_FAILED; -#ifdef AFS_DEMAND_ATTACH_FS Error error; Volume * vp; -#endif if (SYNC_verifyProtocolString(vcom->vop->partName, sizeof(vcom->vop->partName))) { res->hdr.reason = SYNC_REASON_MALFORMED_PACKET; @@ -1201,19 +1199,33 @@ FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res) if (vcom->v) vcom->v->volumeID = 0; -#ifdef AFS_DEMAND_ATTACH_FS vp = VLookupVolume_r(&error, vcom->vop->volume, NULL); if (vp) { if (FSYNC_partMatch(vcom, vp, 1)) { +#ifdef AFS_DEMAND_ATTACH_FS if ((V_attachState(vp) == VOL_STATE_UNATTACHED) || (V_attachState(vp) == VOL_STATE_PREATTACHED)) { - VChangeState_r(vp, VOL_STATE_UNATTACHED); + + /* Change state to DELETED, not UNATTACHED, so clients get + * a VNOVOL error when they try to access from now on. */ + + VChangeState_r(vp, VOL_STATE_DELETED); VDeregisterVolOp_r(vp); + + /* Someday we should free the vp, too, after about 2 hours, + * possibly by putting the vp back on the VLRU. */ + code = SYNC_OK; } else { code = SYNC_DENIED; res->hdr.reason = FSYNC_BAD_STATE; } +#else /* AFS_DEMAND_ATTACH_FS */ + if (!vp->specialStatus) { + vp->specialStatus = VNOVOL; + } + code = SYNC_OK; +#endif /* !AFS_DEMAND_ATTACH_FS */ } else { code = SYNC_OK; /* XXX is this really a good idea? */ res->hdr.reason = FSYNC_WRONG_PART; @@ -1221,7 +1233,6 @@ FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res) } else { res->hdr.reason = FSYNC_UNKNOWN_VOLID; } -#endif done: return code; diff --git a/src/vol/volume.c b/src/vol/volume.c index 2fc88ab2e2..289921ceec 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -1780,6 +1780,7 @@ ShutdownVolumeWalk_r(struct DiskPartition64 * dp, int pass, case 0: if ((V_attachState(vp) != VOL_STATE_UNATTACHED) && (V_attachState(vp) != VOL_STATE_ERROR) && + (V_attachState(vp) != VOL_STATE_DELETED) && (V_attachState(vp) != VOL_STATE_PREATTACHED)) { break; } @@ -1835,6 +1836,7 @@ VShutdownVolume_r(Volume * vp) case VOL_STATE_ERROR: VChangeState_r(vp, VOL_STATE_UNATTACHED); case VOL_STATE_UNATTACHED: + case VOL_STATE_DELETED: break; case VOL_STATE_GOING_OFFLINE: case VOL_STATE_SHUTTING_DOWN: @@ -2133,7 +2135,8 @@ VPreAttachVolumeByVp_r(Error * ec, /* check to see if pre-attach already happened */ if (vp && - (V_attachState(vp) != VOL_STATE_UNATTACHED) && + (V_attachState(vp) != VOL_STATE_UNATTACHED) && + (V_attachState(vp) != VOL_STATE_DELETED) && (V_attachState(vp) != VOL_STATE_PREATTACHED) && !VIsErrorState(V_attachState(vp))) { /* @@ -2285,6 +2288,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) * - GOING_OFFLINE * - SALVAGING * - ERROR + * - DELETED */ if (vp->specialStatus == VBUSY) @@ -2317,6 +2321,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) /* pre-attach volume if it hasn't been done yet */ if (!vp || (V_attachState(vp) == VOL_STATE_UNATTACHED) || + (V_attachState(vp) == VOL_STATE_DELETED) || (V_attachState(vp) == VOL_STATE_ERROR)) { svp = vp; vp = VPreAttachVolumeByVp_r(ec, partp, vp, volumeId); @@ -2561,6 +2566,7 @@ VAttachVolumeByVp_r(Error * ec, Volume * vp, int mode) /* pre-attach volume if it hasn't been done yet */ if (!vp || (V_attachState(vp) == VOL_STATE_UNATTACHED) || + (V_attachState(vp) == VOL_STATE_DELETED) || (V_attachState(vp) == VOL_STATE_ERROR)) { nvp = VPreAttachVolumeByVp_r(ec, partp, vp, volumeId); if (*ec) { @@ -3699,13 +3705,15 @@ GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int nowa } /* - * short circuit with VOFFLINE in the following circumstances: - * - * - VOL_STATE_UNATTACHED + * short circuit with VOFFLINE for VOL_STATE_UNATTACHED and + * VNOVOL for VOL_STATE_DELETED */ - if (V_attachState(vp) == VOL_STATE_UNATTACHED) { + if ((V_attachState(vp) == VOL_STATE_UNATTACHED) || + (V_attachState(vp) == VOL_STATE_DELETED)) { if (vp->specialStatus) { *ec = vp->specialStatus; + } else if (V_attachState(vp) == VOL_STATE_DELETED) { + *ec = VNOVOL; } else { *ec = VOFFLINE; } @@ -4556,7 +4564,8 @@ VCheckOffline(register Volume * vp) assert((V_attachState(vp) != VOL_STATE_ATTACHED) && (V_attachState(vp) != VOL_STATE_FREED) && (V_attachState(vp) != VOL_STATE_PREATTACHED) && - (V_attachState(vp) != VOL_STATE_UNATTACHED)); + (V_attachState(vp) != VOL_STATE_UNATTACHED) && + (V_attachState(vp) != VOL_STATE_DELETED)); /* valid states: * @@ -7192,6 +7201,7 @@ VSoftDetachVolume_r(Volume * vp, afs_uint32 thresh) case VOL_STATE_GOING_OFFLINE: case VOL_STATE_SHUTTING_DOWN: case VOL_STATE_SALVAGING: + case VOL_STATE_DELETED: volume_LRU.q[vp->vlru.idx].len--; /* create and cancel a reservation to diff --git a/src/vol/volume.h b/src/vol/volume.h index 426a40a74c..f7d271261a 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -177,9 +177,10 @@ typedef enum { VOL_STATE_VNODE_CLOSE = 17, /**< volume is busy closing vnodes */ VOL_STATE_VNODE_RELEASE = 18, /**< volume is busy releasing vnodes */ VOL_STATE_VLRU_ADD = 19, /**< volume is busy being added to a VLRU queue */ + VOL_STATE_DELETED = 20, /**< volume has been deleted by the volserver */ /* please add new states directly above this line */ - VOL_STATE_FREED = 20, /**< debugging aid */ - VOL_STATE_COUNT = 21, /**< total number of valid states */ + VOL_STATE_FREED = 21, /**< debugging aid */ + VOL_STATE_COUNT = 22, /**< total number of valid states */ } VolState; /** diff --git a/src/vol/volume_inline.h b/src/vol/volume_inline.h index 3049fc33cb..1ce7bafa3f 100644 --- a/src/vol/volume_inline.h +++ b/src/vol/volume_inline.h @@ -315,6 +315,7 @@ VIsOfflineState(VolState state) case VOL_STATE_UNATTACHED: case VOL_STATE_ERROR: case VOL_STATE_SALVAGING: + case VOL_STATE_DELETED: return 1; default: return 0;