volser-preclude-alternate-partition-clones-20080404
authorKevin McBride <klm@endpoint.com>
Fri, 4 Apr 2008 20:58:35 +0000 (20:58 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 4 Apr 2008 20:58:35 +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

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

index e1fbe7a..e5227be 100644 (file)
@@ -188,8 +188,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);
@@ -2533,7 +2531,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;
@@ -4708,10 +4706,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 cbf0881..779ec00 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 789f0e3..1ad0bb8 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;