diff --git a/src/vol/volume.c b/src/vol/volume.c index d1d6f9fc95..1a1a895575 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -2418,7 +2418,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) if (mode == V_PEEK) { vp->needsPutBack = 0; } else { - vp->needsPutBack = 1; + vp->needsPutBack = VOL_PUTBACK; } #else /* !AFS_DEMAND_ATTACH_FS */ /* duplicate computation in fssync.c about whether the server @@ -2429,7 +2429,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) || (!VolumeWriteable(vp) && (mode == V_CLONE || mode == V_DUMP))) vp->needsPutBack = 0; else - vp->needsPutBack = 1; + vp->needsPutBack = VOL_PUTBACK; #endif /* !AFS_DEMAND_ATTACH_FS */ } #ifdef FSSYNC_BUILD_CLIENT @@ -4180,7 +4180,7 @@ VDetachVolume_r(Error * ec, Volume * vp) if (VCanUseFSSYNC()) { notifyServer = vp->needsPutBack; if (V_destroyMe(vp) == DESTROY_ME) - useDone = FSYNC_VOL_DONE; + useDone = FSYNC_VOL_LEAVE_OFF; #ifdef AFS_DEMAND_ATTACH_FS else if (!V_blessed(vp) || !V_inService(vp)) useDone = FSYNC_VOL_LEAVE_OFF; @@ -4209,6 +4209,12 @@ VDetachVolume_r(Error * ec, Volume * vp) */ #ifdef FSSYNC_BUILD_CLIENT if (VCanUseFSSYNC() && notifyServer) { + if (notifyServer == VOL_PUTBACK_DELETE) { + /* Only send FSYNC_VOL_DONE if the volume was actually deleted. + * volserver code will set needsPutBack to VOL_PUTBACK_DELETE + * to signify a deleted volume. */ + useDone = FSYNC_VOL_DONE; + } /* * Note: The server is not notified in the case of a bogus volume * explicitly to make it possible to create a volume, do a partial diff --git a/src/vol/volume.h b/src/vol/volume.h index bd7b1e7b4b..da961a6284 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -654,10 +654,15 @@ typedef struct Volume { bit32 cacheCheck; /* Online sequence number to be used to invalidate vnode cache entries * that stayed around while a volume was offline */ short nUsers; /* Number of users of this volume header */ - byte needsPutBack; /* For a volume utility, this flag is set if we need - * to give the volume back when we detach it. The server has +#define VOL_PUTBACK 1 +#define VOL_PUTBACK_DELETE 2 + byte needsPutBack; /* For a volume utility, this flag is set to VOL_PUTBACK if we + * need to give the volume back when we detach it. The server has * certain modes where it doesn't detach the volume, and - * if we give it back spuriously, the server aborts. This field + * if we give it back spuriously, the server aborts. If set to + * VOL_PUTBACK_DELETE, it indicates that we need to tell the + * fileserver that the volume is gone entirely, instead of just + * giving the volume back to the fileserver. This field * is meaningless on the file server */ byte specialStatus; /* An error code to return on VGetVolume: the * volume is unavailable for the reason quoted, diff --git a/src/volser/volprocs.c b/src/volser/volprocs.c index f212dd905a..a2d6d921a4 100644 --- a/src/volser/volprocs.c +++ b/src/volser/volprocs.c @@ -633,7 +633,10 @@ VolDeleteVolume(struct rx_call *acid, afs_int32 atrans) Log("%s is executing Delete Volume %u\n", caller, tt->volid); TSetRxCall(tt, acid, "DeleteVolume"); VPurgeVolume(&error, tt->volume); /* don't check error code, it is not set! */ - V_destroyMe(tt->volume) = DESTROY_ME; /* so endtrans does the right fssync opcode */ + V_destroyMe(tt->volume) = DESTROY_ME; + if (tt->volume->needsPutBack) { + tt->volume->needsPutBack = VOL_PUTBACK_DELETE; /* so endtrans does the right fssync opcode */ + } VTRANS_OBJ_LOCK(tt); tt->vflags |= VTDeleted; /* so we know not to do anything else to it */ TClearRxCall_r(tt);