From: Marc Dionne Date: Sat, 21 Jan 2012 19:42:01 +0000 (-0500) Subject: vol: Allow VAllocVnode of specific vnodes X-Git-Tag: openafs-stable-1_8_0pre1~2551 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=74e5f32aaca5313f153f13c7ce9442527b758a0a vol: Allow VAllocVnode of specific vnodes Add parameters to VAllocVnode to allow the caller to specifiy the vnode and unique numbers to use. This will be used by the RW replication code to keep vnode numbers in sync between the master volume and the replicas. Adapted from code by Vishal Powar and Derrick Brashear. Change-Id: Ibaf79aad2b3e7a52802f5e01f7e4c7730c3f5090 Reviewed-on: http://gerrit.openafs.org/6672 Reviewed-by: Derrick Brashear Tested-by: BuildBot --- diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index c2658ff..43039f4 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -1806,7 +1806,7 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr, return VSALVAGE; } - *targetptr = VAllocVnode(&errorCode, volptr, FileType); + *targetptr = VAllocVnode(&errorCode, volptr, FileType, 0, 0); if (errorCode != 0) { VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0); return (errorCode); diff --git a/src/vol/vnode.c b/src/vol/vnode.c index 37b697f..39e7978 100644 --- a/src/vol/vnode.c +++ b/src/vol/vnode.c @@ -556,11 +556,11 @@ VLookupVnode(Volume * vp, VnodeId vnodeId) Vnode * -VAllocVnode(Error * ec, Volume * vp, VnodeType type) +VAllocVnode(Error * ec, Volume * vp, VnodeType type, VnodeId in_vnode, Unique in_unique) { Vnode *retVal; VOL_LOCK; - retVal = VAllocVnode_r(ec, vp, type); + retVal = VAllocVnode_r(ec, vp, type, in_vnode, in_unique); VOL_UNLOCK; return retVal; } @@ -571,6 +571,8 @@ VAllocVnode(Error * ec, Volume * vp, VnodeType type) * @param[out] ec error code return * @param[in] vp volume object pointer * @param[in] type desired vnode type + * @param[in] type desired vnode ID (optional) + * @param[in] type desired vnode Unique (optional) * * @return vnode object pointer * @@ -580,7 +582,7 @@ VAllocVnode(Error * ec, Volume * vp, VnodeType type) * @post vnode allocated and returned */ Vnode * -VAllocVnode_r(Error * ec, Volume * vp, VnodeType type) +VAllocVnode_r(Error * ec, Volume * vp, VnodeType type, VnodeId in_vnode, Unique in_unique) { Vnode *vnp; VnodeId vnodeNumber; @@ -588,6 +590,9 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type) struct VnodeClassInfo *vcp; VnodeClass class; Unique unique; + struct vnodeIndex *index; + unsigned int offset; + #ifdef AFS_DEMAND_ATTACH_FS VolState vol_state_save; #endif @@ -624,10 +629,6 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type) return NULL; } - unique = vp->nextVnodeUnique++; - if (!unique) - unique = vp->nextVnodeUnique++; - if (vp->nextVnodeUnique > V_uniquifier(vp)) { VUpdateVolume_r(ec, vp, 0); if (*ec) @@ -640,12 +641,63 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type) return NULL; } - /* Find a slot in the bit map */ - bitNumber = VAllocBitmapEntry_r(ec, vp, &vp->vnodeIndex[class], - VOL_ALLOC_BITMAP_WAIT); - if (*ec) - return NULL; - vnodeNumber = bitNumberToVnodeNumber(bitNumber, class); + /* + * If in_vnode and in_unique are specified, we are asked to + * allocate a specifc vnode slot. Used by RW replication to + * keep vnode IDs consistent with the master. + */ + + if (!in_vnode) { + unique = vp->nextVnodeUnique++; + if (!unique) + unique = vp->nextVnodeUnique++; + + if (vp->nextVnodeUnique > V_uniquifier(vp)) { + VUpdateVolume_r(ec, vp, 0); + if (*ec) + return NULL; + } + + /* Find a slot in the bit map */ + bitNumber = VAllocBitmapEntry_r(ec, vp, &vp->vnodeIndex[class], + VOL_ALLOC_BITMAP_WAIT); + + if (*ec) + return NULL; + vnodeNumber = bitNumberToVnodeNumber(bitNumber, class); + } else { + index = &vp->vnodeIndex[class]; + if (!in_unique) { + *ec = VNOVNODE; + return NULL; + } + /* Catch us up to where the master is */ + if (in_unique > vp->nextVnodeUnique) + vp->nextVnodeUnique = in_unique+1; + + if (vp->nextVnodeUnique > V_uniquifier(vp)) { + VUpdateVolume_r(ec, vp, 0); + if (*ec) + return NULL; + } + + unique = in_unique; + bitNumber = vnodeIdToBitNumber(in_vnode); + offset = bitNumber >> 3; + + /* Mark vnode in use. Grow bitmap if needed. */ + if ((offset >= index->bitmapSize) + || ((*(index->bitmap + offset) & (1 << (bitNumber & 0x7))) == 0)) + VGrowBitmap(index); + /* Should not happen */ + if (*(index->bitmap + offset) & (1 << (bitNumber & 0x7))) { + *ec = VNOVNODE; + return NULL; + } + + *(index->bitmap + offset) |= (1 << (bitNumber & 0x7)); + vnodeNumber = in_vnode; + } /* * DAFS: diff --git a/src/vol/vnode.h b/src/vol/vnode.h index a374258..d0f2c1d 100644 --- a/src/vol/vnode.h +++ b/src/vol/vnode.h @@ -271,8 +271,11 @@ extern void VPutVnode(Error * ec, Vnode * vnp); extern void VPutVnode_r(Error * ec, Vnode * vnp); extern int VVnodeWriteToRead(Error * ec, Vnode * vnp); extern int VVnodeWriteToRead_r(Error * ec, Vnode * vnp); -extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type); -extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type); +extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type, + VnodeId in_vnode, Unique in_unique); +extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type, + VnodeId in_vnode, Unique in_unique); + /*extern VFreeVnode();*/ extern Vnode *VGetFreeVnode_r(struct VnodeClassInfo *vcp, struct Volume *vp, VnodeId vnodeNumber); diff --git a/src/vol/volume.c b/src/vol/volume.c index d846092..4dd8658 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -180,9 +180,6 @@ pthread_t vol_glock_holder = 0; #endif -#define VOLUME_BITMAP_GROWSIZE 16 /* bytes, => 128vnodes */ - /* Must be a multiple of 4 (1 word) !! */ - /* this parameter needs to be tunable at runtime. * 128 was really inadequate for largish servers -- at 16384 volumes this * puts average chain length at 128, thus an average 65 deref's to find a volptr. @@ -6201,6 +6198,25 @@ VChildProcReconnectFS(void) /* volume bitmap routines */ /***************************************************/ +/* + * Grow the bitmap by the defined increment + */ +void +VGrowBitmap(struct vnodeIndex *index) +{ + byte *bp; + + bp = realloc(index->bitmap, index->bitmapSize + VOLUME_BITMAP_GROWSIZE); + osi_Assert(bp != NULL); + index->bitmap = bp; + bp += index->bitmapSize; + memset(bp, 0, VOLUME_BITMAP_GROWSIZE); + index->bitmapOffset = index->bitmapSize; + index->bitmapSize += VOLUME_BITMAP_GROWSIZE; + + return; +} + /** * allocate a vnode bitmap number for the vnode * @@ -6322,14 +6338,8 @@ VAllocBitmapEntry_r(Error * ec, Volume * vp, bp += sizeof(bit32) /* i.e. 4 */ ; } /* No bit map entry--must grow bitmap */ - bp = (byte *) - realloc(index->bitmap, index->bitmapSize + VOLUME_BITMAP_GROWSIZE); - osi_Assert(bp != NULL); - index->bitmap = bp; - bp += index->bitmapSize; - memset(bp, 0, VOLUME_BITMAP_GROWSIZE); - index->bitmapOffset = index->bitmapSize; - index->bitmapSize += VOLUME_BITMAP_GROWSIZE; + VGrowBitmap(index); + bp = index->bitmap; *bp = 1; ret = index->bitmapOffset * 8; #ifdef AFS_DEMAND_ATTACH_FS diff --git a/src/vol/volume.h b/src/vol/volume.h index f9b6473..f5f24e5 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -807,6 +807,7 @@ extern Volume *VCreateVolume(Error * ec, char *partname, VolId volumeId, VolId parentId); extern Volume *VCreateVolume_r(Error * ec, char *partname, VolId volumeId, VolId parentId); +extern void VGrowBitmap(struct vnodeIndex *index); extern int VAllocBitmapEntry(Error * ec, Volume * vp, struct vnodeIndex *index); extern int VAllocBitmapEntry_r(Error * ec, Volume * vp, @@ -1021,6 +1022,8 @@ extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath, #define VOL_SALVAGE_NO_OFFLINE 0x1 /* we do not need to wait to offline the volume; it has * not been fully attached */ +#define VOLUME_BITMAP_GROWSIZE 16 /* bytes, => 128vnodes */ + /* Must be a multiple of 4 (1 word) !! */ #if defined(NEARINODE_HINT) #define V_pref(vp,nearInode) nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)->f_files