From: Kevin McBride Date: Thu, 4 Sep 2008 19:17:23 +0000 (+0000) Subject: STABLE14-volser-preclude-alternate-partition-clones-20080404 X-Git-Tag: openafs-stable-1_4_8pre1~14 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=a8ba6f28bc271986aea6f0258d190714a26e46b0;p=packages%2Fo%2Fopenafs.git STABLE14-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) --- diff --git a/src/vol/volume.c b/src/vol/volume.c index 23e4ebd0a..d4eae594f 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -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]; diff --git a/src/vol/volume.h b/src/vol/volume.h index 44401b6e5..63314cb05 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -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 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;