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
This commit is contained in:
Andrew Deason 2010-08-10 14:16:39 -05:00
parent ce52c0dbc6
commit bb9caf9822
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_RELEASE);
ENUMCASE(VOL_STATE_VLRU_ADD);
ENUMCASE(VOL_STATE_DELETED);
ENUMCASE(VOL_STATE_FREED);
default:
return "**UNKNOWN**";

View File

@ -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;

View File

@ -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

View File

@ -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;
/**

View File

@ -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;