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
Reviewed-on: http://gerrit.openafs.org/2533
Tested-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Andrew Deason 2010-08-10 14:16:39 -05:00 committed by Derrick Brashear
parent 72da1d2eb2
commit 3daf18a3cb
5 changed files with 37 additions and 13 deletions

View File

@ -554,6 +554,7 @@ vol_state_to_string(VolState state)
ENUMCASE(VOL_STATE_VNODE_CLOSE); ENUMCASE(VOL_STATE_VNODE_CLOSE);
ENUMCASE(VOL_STATE_VNODE_RELEASE); ENUMCASE(VOL_STATE_VNODE_RELEASE);
ENUMCASE(VOL_STATE_VLRU_ADD); ENUMCASE(VOL_STATE_VLRU_ADD);
ENUMCASE(VOL_STATE_DELETED);
ENUMCASE(VOL_STATE_FREED); ENUMCASE(VOL_STATE_FREED);
default: default:
return "**UNKNOWN**"; return "**UNKNOWN**";

View File

@ -1185,10 +1185,8 @@ static afs_int32
FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res) FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res)
{ {
afs_int32 code = SYNC_FAILED; afs_int32 code = SYNC_FAILED;
#ifdef AFS_DEMAND_ATTACH_FS
Error error; Error error;
Volume * vp; Volume * vp;
#endif
if (SYNC_verifyProtocolString(vcom->vop->partName, sizeof(vcom->vop->partName))) { if (SYNC_verifyProtocolString(vcom->vop->partName, sizeof(vcom->vop->partName))) {
res->hdr.reason = SYNC_REASON_MALFORMED_PACKET; res->hdr.reason = SYNC_REASON_MALFORMED_PACKET;
@ -1201,19 +1199,33 @@ FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res)
if (vcom->v) if (vcom->v)
vcom->v->volumeID = 0; vcom->v->volumeID = 0;
#ifdef AFS_DEMAND_ATTACH_FS
vp = VLookupVolume_r(&error, vcom->vop->volume, NULL); vp = VLookupVolume_r(&error, vcom->vop->volume, NULL);
if (vp) { if (vp) {
if (FSYNC_partMatch(vcom, vp, 1)) { if (FSYNC_partMatch(vcom, vp, 1)) {
#ifdef AFS_DEMAND_ATTACH_FS
if ((V_attachState(vp) == VOL_STATE_UNATTACHED) || if ((V_attachState(vp) == VOL_STATE_UNATTACHED) ||
(V_attachState(vp) == VOL_STATE_PREATTACHED)) { (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); 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; code = SYNC_OK;
} else { } else {
code = SYNC_DENIED; code = SYNC_DENIED;
res->hdr.reason = FSYNC_BAD_STATE; 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 { } else {
code = SYNC_OK; /* XXX is this really a good idea? */ code = SYNC_OK; /* XXX is this really a good idea? */
res->hdr.reason = FSYNC_WRONG_PART; res->hdr.reason = FSYNC_WRONG_PART;
@ -1221,7 +1233,6 @@ FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res)
} else { } else {
res->hdr.reason = FSYNC_UNKNOWN_VOLID; res->hdr.reason = FSYNC_UNKNOWN_VOLID;
} }
#endif
done: done:
return code; return code;

View File

@ -1780,6 +1780,7 @@ ShutdownVolumeWalk_r(struct DiskPartition64 * dp, int pass,
case 0: case 0:
if ((V_attachState(vp) != VOL_STATE_UNATTACHED) && if ((V_attachState(vp) != VOL_STATE_UNATTACHED) &&
(V_attachState(vp) != VOL_STATE_ERROR) && (V_attachState(vp) != VOL_STATE_ERROR) &&
(V_attachState(vp) != VOL_STATE_DELETED) &&
(V_attachState(vp) != VOL_STATE_PREATTACHED)) { (V_attachState(vp) != VOL_STATE_PREATTACHED)) {
break; break;
} }
@ -1835,6 +1836,7 @@ VShutdownVolume_r(Volume * vp)
case VOL_STATE_ERROR: case VOL_STATE_ERROR:
VChangeState_r(vp, VOL_STATE_UNATTACHED); VChangeState_r(vp, VOL_STATE_UNATTACHED);
case VOL_STATE_UNATTACHED: case VOL_STATE_UNATTACHED:
case VOL_STATE_DELETED:
break; break;
case VOL_STATE_GOING_OFFLINE: case VOL_STATE_GOING_OFFLINE:
case VOL_STATE_SHUTTING_DOWN: case VOL_STATE_SHUTTING_DOWN:
@ -2133,7 +2135,8 @@ VPreAttachVolumeByVp_r(Error * ec,
/* check to see if pre-attach already happened */ /* check to see if pre-attach already happened */
if (vp && 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) && (V_attachState(vp) != VOL_STATE_PREATTACHED) &&
!VIsErrorState(V_attachState(vp))) { !VIsErrorState(V_attachState(vp))) {
/* /*
@ -2285,6 +2288,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
* - GOING_OFFLINE * - GOING_OFFLINE
* - SALVAGING * - SALVAGING
* - ERROR * - ERROR
* - DELETED
*/ */
if (vp->specialStatus == VBUSY) 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 */ /* pre-attach volume if it hasn't been done yet */
if (!vp || 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_ERROR)) { (V_attachState(vp) == VOL_STATE_ERROR)) {
svp = vp; svp = vp;
vp = VPreAttachVolumeByVp_r(ec, partp, vp, volumeId); 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 */ /* pre-attach volume if it hasn't been done yet */
if (!vp || 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_ERROR)) { (V_attachState(vp) == VOL_STATE_ERROR)) {
nvp = VPreAttachVolumeByVp_r(ec, partp, vp, volumeId); nvp = VPreAttachVolumeByVp_r(ec, partp, vp, volumeId);
if (*ec) { 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: * short circuit with VOFFLINE for VOL_STATE_UNATTACHED and
* * VNOVOL for VOL_STATE_DELETED
* - VOL_STATE_UNATTACHED
*/ */
if (V_attachState(vp) == VOL_STATE_UNATTACHED) { if ((V_attachState(vp) == VOL_STATE_UNATTACHED) ||
(V_attachState(vp) == VOL_STATE_DELETED)) {
if (vp->specialStatus) { if (vp->specialStatus) {
*ec = vp->specialStatus; *ec = vp->specialStatus;
} else if (V_attachState(vp) == VOL_STATE_DELETED) {
*ec = VNOVOL;
} else { } else {
*ec = VOFFLINE; *ec = VOFFLINE;
} }
@ -4556,7 +4564,8 @@ VCheckOffline(register Volume * vp)
assert((V_attachState(vp) != VOL_STATE_ATTACHED) && assert((V_attachState(vp) != VOL_STATE_ATTACHED) &&
(V_attachState(vp) != VOL_STATE_FREED) && (V_attachState(vp) != VOL_STATE_FREED) &&
(V_attachState(vp) != VOL_STATE_PREATTACHED) && (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: /* valid states:
* *
@ -7192,6 +7201,7 @@ VSoftDetachVolume_r(Volume * vp, afs_uint32 thresh)
case VOL_STATE_GOING_OFFLINE: case VOL_STATE_GOING_OFFLINE:
case VOL_STATE_SHUTTING_DOWN: case VOL_STATE_SHUTTING_DOWN:
case VOL_STATE_SALVAGING: case VOL_STATE_SALVAGING:
case VOL_STATE_DELETED:
volume_LRU.q[vp->vlru.idx].len--; volume_LRU.q[vp->vlru.idx].len--;
/* create and cancel a reservation to /* create and cancel a reservation to

View File

@ -177,9 +177,10 @@ typedef enum {
VOL_STATE_VNODE_CLOSE = 17, /**< volume is busy closing vnodes */ VOL_STATE_VNODE_CLOSE = 17, /**< volume is busy closing vnodes */
VOL_STATE_VNODE_RELEASE = 18, /**< volume is busy releasing 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_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 */ /* please add new states directly above this line */
VOL_STATE_FREED = 20, /**< debugging aid */ VOL_STATE_FREED = 21, /**< debugging aid */
VOL_STATE_COUNT = 21, /**< total number of valid states */ VOL_STATE_COUNT = 22, /**< total number of valid states */
} VolState; } VolState;
/** /**

View File

@ -315,6 +315,7 @@ VIsOfflineState(VolState state)
case VOL_STATE_UNATTACHED: case VOL_STATE_UNATTACHED:
case VOL_STATE_ERROR: case VOL_STATE_ERROR:
case VOL_STATE_SALVAGING: case VOL_STATE_SALVAGING:
case VOL_STATE_DELETED:
return 1; return 1;
default: default:
return 0; return 0;