From 941f7e728ec459a3572302f99fa26db8d1c319c3 Mon Sep 17 00:00:00 2001 From: Kevin McBride Date: Fri, 4 Apr 2008 20:58:45 +0000 Subject: [PATCH] DEVEL15-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 (cherry picked from commit 5640c4a1b5bea4e61ff2e6c2da02265c3e1ba612) --- 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 f7f1083cf..df93eb3a3 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -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]; 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