]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-volser-preclude-alternate-partition-clones-20080404
authorKevin McBride <klm@endpoint.com>
Thu, 4 Sep 2008 19:17:23 +0000 (19:17 +0000)
committerDerrick Brashear <shadow@dementia.org>
Thu, 4 Sep 2008 19:17:23 +0000 (19:17 +0000)
LICENSE IPL10

patch based on work from shadow@dementia.org

the idea is to preclude multiple copies of a volume replica on a server,
as there's nothing to indicate which copy is correct and you can end up serving
stale data when you think you've just released and are serving something good

(cherry picked from commit 5640c4a1b5bea4e61ff2e6c2da02265c3e1ba612)

src/vol/volume.c
src/vol/volume.h
src/vol/vutil.c

index 23e4ebd0a77917323d45539db6089a7a1f0ebe67..d4eae594ff53cc264422f01f0c9414f84ce12981 100644 (file)
@@ -176,10 +176,9 @@ static void DeleteVolumeFromHashTable(register Volume * vp);
 static int VHold(Volume * vp);
 static int VHold_r(Volume * vp);
 static void GetBitmap(Error * ec, Volume * vp, VnodeClass class);
-static void GetVolumePath(Error * ec, VolId volumeId, char **partitionp,
-                         char **namep);
 static void VReleaseVolumeHandles_r(Volume * vp);
 static void VCloseVolumeHandles_r(Volume * vp);
+void VGetVolumePath(Error * ec, VolId volumeId, char **partitionp, char **namep);
 
 int LogLevel;                  /* Vice loglevel--not defined as extern so that it will be
                                 * defined when not linked with vice, XXXX */
@@ -1008,7 +1007,7 @@ Volume *
 VAttachVolume_r(Error * ec, VolumeId volumeId, int mode)
 {
     char *part, *name;
-    GetVolumePath(ec, volumeId, &part, &name);
+    VGetVolumePath(ec, volumeId, &part, &name);
     if (*ec) {
        register Volume *vp;
        Error error;
@@ -1670,8 +1669,8 @@ GetBitmap(Error * ec, Volume * vp, VnodeClass class)
 #endif /* BITMAP_LATER */
 }
 
-static void
-GetVolumePath(Error * ec, VolId volumeId, char **partitionp, char **namep)
+void 
+VGetVolumePath(Error * ec, VolId volumeId, char **partitionp, char **namep)
 {
     static char partition[VMAXPATHLEN], name[VMAXPATHLEN];
     char path[VMAXPATHLEN];
index 44401b6e5efe245efac99cdb3b3e554c53e4e1bb..63314cb0543378a8e6c9b63ae08d90442e91693f 100644 (file)
@@ -463,7 +463,8 @@ extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
 extern void VTakeOffline_r(register Volume * vp);
 extern void VTakeOffline(register Volume * vp);
-
+extern void VGetVolumePath(Error * ec, VolId volumeId, char **partitionp,
+                          char **namep);
 
 /* Naive formula relating number of file size to number of 1K blocks in file */
 /* Note:  we charge 1 block for 0 length files so the user can't store
index 789f0e33c4cff94fb5522186da1c43c4da702c31..1ad0bb84989b957b6165e9cdf3cf6346709de9dc 100644 (file)
@@ -128,6 +128,7 @@ VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
     IHandle_t *handle;
     FdHandle_t *fdP;
     Inode nearInode = 0;
+    char *part, *name;
 
     *ec = 0;
     memset(&vol, 0, sizeof(vol));
@@ -150,6 +151,17 @@ VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId)
     nearInodeHash(volumeId, nearInode);
     nearInode %= partition->f_files;
 #endif
+    VGetVolumePath(ec, vol.id, &part, &name);
+    if (*ec == VNOVOL || !strcmp(partition->name, part)) {
+       /* this case is ok */
+    } else {
+       /* return EXDEV if it's a clone to an alternate partition
+        * otherwise assume it's a move */
+       if (vol.parentId != vol.id) {
+           *ec = EXDEV;
+           return NULL;
+       }
+    }
     VLockPartition_r(partname);
     memset(&tempHeader, 0, sizeof(tempHeader));
     tempHeader.stamp.magic = VOLUMEHEADERMAGIC;