return VSALVAGE;
}
- *targetptr = VAllocVnode(&errorCode, volptr, FileType);
+ *targetptr = VAllocVnode(&errorCode, volptr, FileType, 0, 0);
if (errorCode != 0) {
VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
return (errorCode);
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;
}
* @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
*
* @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;
struct VnodeClassInfo *vcp;
VnodeClass class;
Unique unique;
+ struct vnodeIndex *index;
+ unsigned int offset;
+
#ifdef AFS_DEMAND_ATTACH_FS
VolState vol_state_save;
#endif
return NULL;
}
- 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);
+ /*
+ * 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:
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);
#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.
/* 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
*
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
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,
#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