/* if it's already attached, see if we can return it */
if (V_attachState(vp) == VOL_STATE_ATTACHED) {
VGetVolumeByVp_r(ec, vp);
- if (V_inUse(vp)) {
+ if (V_inUse(vp) == fileServer) {
VCancelReservation_r(vp);
return vp;
}
#else /* AFS_DEMAND_ATTACH_FS */
vp = VGetVolume_r(ec, volumeId);
if (vp) {
- if (V_inUse(vp))
+ if (V_inUse(vp) == fileServer)
return vp;
if (vp->specialStatus == VBUSY)
isbusy = 1;
vp = attach2(ec, volumeId, path, &iheader, partp, vp, isbusy, mode);
if (programType == volumeUtility && vp) {
+ if ((mode == V_VOLUPD) || (VolumeWriteable(vp) && (mode == V_CLONE))) {
+ /* mark volume header as in use so that volser crashes lead to a
+ * salvage attempt */
+ VUpdateVolume_r(ec, vp, 0);
+ }
#ifdef AFS_DEMAND_ATTACH_FS
/* for dafs, we should tell the fileserver, except for V_PEEK
* where we know it is not necessary */
/* if it's already attached, see if we can return it */
if (V_attachState(vp) == VOL_STATE_ATTACHED) {
VGetVolumeByVp_r(ec, vp);
- if (V_inUse(vp)) {
+ if (V_inUse(vp) == fileServer) {
return vp;
} else {
if (vp->specialStatus == VBUSY)
if (vp->specialStatus)
vp->specialStatus = 0;
if (V_blessed(vp) && V_inService(vp) && !V_needsSalvaged(vp)) {
- V_inUse(vp) = 1;
+ V_inUse(vp) = fileServer;
V_offlineMessage(vp)[0] = '\0';
}
+ } else {
+ V_inUse(vp) = programType;
+ V_checkoutMode(vp) = mode;
}
AddVolumeToHashTable(vp, V_id(vp));
AddVolumeToVByPList_r(vp);
VLRU_Add_r(vp);
if ((programType != fileServer) ||
- V_inUse(vp)) {
+ (V_inUse(vp) == fileServer)) {
VChangeState_r(vp, VOL_STATE_ATTACHED);
} else {
VChangeState_r(vp, VOL_STATE_UNATTACHED);
VCheckDetach(register Volume * vp)
{
int ret = 0;
+ Error ec = 0;
if (vp->nUsers || vp->nWaiters)
return ret;
if (vp->shuttingDown) {
ret = 1;
+ if ((programType != fileServer) &&
+ (V_inUse(vp) == programType) &&
+ ((V_checkoutMode(vp) == V_VOLUPD) ||
+ ((V_checkoutMode(vp) == V_CLONE) &&
+ (VolumeWriteable(vp))))) {
+ V_inUse(vp) = 0;
+ VUpdateVolume_r(&ec, vp, VOL_UPDATE_NOFORCEOFF);
+ if (ec) {
+ Log("VCheckDetach: failed to clear inUse failed during detachment of volid %u\n",
+ vp->hashid);
+ }
+ }
VReleaseVolumeHandles_r(vp);
VCheckSalvage(vp);
ReallyFreeVolume(vp);
VCheckDetach(register Volume * vp)
{
int ret = 0;
+ Error ec = 0;
if (vp->nUsers)
return ret;
if (vp->shuttingDown) {
ret = 1;
+ if ((programType != fileServer) &&
+ (V_inUse(vp) == programType) &&
+ ((V_checkoutMode(vp) == V_VOLUPD) ||
+ ((V_checkoutMode(vp) == V_CLONE) &&
+ (VolumeWriteable(vp))))) {
+ V_inUse(vp) = 0;
+ VUpdateVolume_r(&ec, vp, VOL_UPDATE_NOFORCEOFF);
+ if (ec) {
+ Log("VCheckDetach: failed to clear inUse failed during detachment of volid %u\n",
+ vp->hashid);
+ }
+ }
VReleaseVolumeHandles_r(vp);
ReallyFreeVolume(vp);
if (programType == fileServer) {
#define VTRANS_UNLOCK
#endif /* AFS_PTHREAD_ENV */
-typedef enum { fileServer, /* the fileserver process */
- volumeUtility, /* volserver, or a single volume salvager (non-dafs) */
- salvager, /* standalone whole-partition salvager */
- salvageServer, /* dafs online salvager */
- debugUtility /* fssync-debug or similar utility */
+/**
+ * volume package program type enumeration.
+ */
+typedef enum {
+ fileServer = 1, /**< the fileserver process */
+ volumeUtility = 2, /**< volserver, or a
+ * single volume salvager (non-dafs) */
+ salvager = 3, /**< standalone whole-partition salvager */
+ salvageServer = 4, /**< dafs online salvager */
+ debugUtility = 5 /**< fssync-debug or similar utility */
} ProgramType;
extern ProgramType programType; /* The type of program using the package */
byte specialStatus; /* An error code to return on VGetVolume: the
* volume is unavailable for the reason quoted,
* currently VBUSY or VMOVED */
+ afs_uint32 checkoutMode; /* for volume utilities, mode number for current checkout */
afs_uint32 updateTime; /* Time that this volume was put on the updated
* volume list--the list of volumes that will be
* salvaged should the file server crash */
#define V_vnodeIndex(vp) ((vp)->vnodeIndex)
#define V_nextVnodeUnique(vp) ((vp)->nextVnodeUnique)
#define V_linkHandle(vp) ((vp)->linkHandle)
+#define V_checkoutMode(vp) ((vp)->checkoutMode)
#ifdef AFS_DEMAND_ATTACH_FS
#define V_attachState(vp) ((vp)->attach_state)
#define V_attachFlags(vp) ((vp)->attach_flags)