dafs-accurately-track-inuse-20080317
authorTom Keiser <tkeiser@sinenomine.net>
Mon, 17 Mar 2008 17:06:30 +0000 (17:06 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 17 Mar 2008 17:06:30 +0000 (17:06 +0000)
LICENSE IPL10

keep accurate tabs on whether a volume is "in use" so we don't end up with volume state that's nonsensical.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================
LICENSE IPL10

keep accurate tabs on whether a volume is "in use" so we don't end up with volum
e state that's nonsensical.

====================
LICENSE IPL10

keep accurate tabs on whether a volume is "in use" so we don't end up with volum
e state that's nonsensical.

src/vol/fssync-debug.c
src/vol/vol-salvage.c
src/vol/volume.c
src/vol/volume.h

index 1084e6d..47d2ce1 100644 (file)
@@ -759,7 +759,11 @@ VolHdrQuery(struct cmd_syndesc * as, void * rock)
        
        printf("\tid               = %u\n", v.id);
        printf("\tname             = '%s'\n", v.name);
-       printf("\tinUse            = %d\n", v.inUse);
+       if (v.inUse != 0) {
+           printf("\tinUse            = %d (%s)\n", v.inUse, program_type_to_string(v.inUse));
+       } else {
+           printf("\tinUse            = %d (no)\n", v.inUse);
+       }
        printf("\tinService        = %d\n", v.inService);
        printf("\tblessed          = %d\n", v.blessed);
        printf("\tneedsSalvaged    = %d\n", v.needsSalvaged);
index 86445ea..7161272 100644 (file)
@@ -1633,7 +1633,7 @@ QuickCheck(register struct InodeSummary *isp, int nVols)
            && volHeader.stamp.magic == VOLUMEINFOMAGIC
            && volHeader.dontSalvage == DONT_SALVAGE
            && volHeader.needsSalvaged == 0 && volHeader.destroyMe == 0) {
-           if (volHeader.inUse == 1) {
+           if (volHeader.inUse != 0) {
                volHeader.inUse = 0;
                volHeader.inService = 1;
                if (!Testing) {
index e97f7c8..33c7ddd 100644 (file)
@@ -1806,7 +1806,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
            /* 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;
                }
@@ -1876,7 +1876,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
 #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;
@@ -1950,6 +1950,11 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
     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 */
@@ -2093,7 +2098,7 @@ VAttachVolumeByVp_r(Error * ec, Volume * vp, int mode)
     /* 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)
@@ -2487,9 +2492,12 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h
        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));
@@ -2497,7 +2505,7 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h
     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);
@@ -3429,12 +3437,25 @@ static int
 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);
@@ -3449,12 +3470,25 @@ static int
 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) {
index 48c8774..cbf0881 100644 (file)
@@ -113,11 +113,16 @@ extern pthread_t vol_glock_holder;
 #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 */
 
@@ -615,6 +620,7 @@ typedef struct Volume {
     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 */
@@ -649,6 +655,7 @@ struct volHeader {
 #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)