From 5640c4a1b5bea4e61ff2e6c2da02265c3e1ba612 Mon Sep 17 00:00:00 2001 From: Kevin McBride Date: Fri, 4 Apr 2008 20:58:35 +0000 Subject: [PATCH] volser-preclude-alternate-partition-clones-20080404 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 | 9 +++------ src/vol/volume.h | 3 ++- src/vol/vutil.c | 12 ++++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/vol/volume.c b/src/vol/volume.c index e1fbe7aaf..e5227be6c 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -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]; diff --git a/src/vol/volume.h b/src/vol/volume.h index cbf088175..779ec0011 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -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); diff --git a/src/vol/vutil.c b/src/vol/vutil.c index 789f0e33c..1ad0bb849 100644 --- a/src/vol/vutil.c +++ b/src/vol/vutil.c @@ -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; -- 2.39.5