]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-volser-preclude-alternate-partition-clones-20080404
authorKevin McBride <klm@endpoint.com>
Fri, 4 Apr 2008 20:58:45 +0000 (20:58 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 4 Apr 2008 20:58:45 +0000 (20:58 +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 f7f1083cfb954968d512ffec37d35de095dfc19b..df93eb3a372318b76bbbd1f4ca7e1fbc305ff5c6 100644 (file)
@@ -194,8 +194,6 @@ static void DeleteVolumeFromHashTable(register Volume * vp);
 static int VHold(Volume * vp);
 static int VHold_r(Volume * vp);
 static void VGetBitmap_r(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);
 static void LoadVolumeHeader(Error * ec, Volume * vp);
@@ -2539,7 +2537,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;
@@ -4714,10 +4712,9 @@ VGetBitmap_r(Error * ec, Volume * vp, VnodeClass class)
  *       on a vice partition, it is possible for callers to get the wrong one,
  *       depending on the order of the disk partition linked list.
  *
- * @internal volume package internal use only.
  */
-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 cbf0881752436658f71f07199e04a7fdedb3da63..779ec0011eac2ec0f2959cc9bfbd1a83a353d8b5 100644 (file)
@@ -774,7 +774,8 @@ extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
 extern void VTakeOffline_r(register Volume * vp);
 extern void VTakeOffline(register Volume * vp);
 extern Volume * VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint);
-
+extern void VGetVolumePath(Error * ec, VolId volumeId, char **partitionp,
+                          char **namep);
 #ifdef AFS_DEMAND_ATTACH_FS
 extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name);
 extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name);
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;