/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
#include <afsconfig.h>
#include <afs/param.h>
-#define MAXINT (~(1<<((sizeof(int)*8)-1)))
-RCSID
- ("$Header$");
+#include <roken.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
-#else /* AFS_PTHREAD_ENV */
-#include <afs/assert.h>
-#endif /* AFS_PTHREAD_ENV */
+#include <limits.h>
+
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
-#include <rx/xdr.h>
+#include <afs/opr.h>
+#ifdef AFS_PTHREAD_ENV
+#include <opr/lock.h>
+#endif
#include "rx/rx_queue.h"
#include <afs/afsint.h>
#include "nfs.h"
#include "vnode_inline.h"
#include "partition.h"
#include "salvsync.h"
-#if defined(AFS_SGI_ENV)
-#include "sys/types.h"
-#include "fcntl.h"
-#undef min
-#undef max
-#include "stdlib.h"
-#endif
+#include "common.h"
#ifdef AFS_NT40_ENV
-#include <fcntl.h>
#include "ntops.h"
-#else
-#include <sys/file.h>
-#ifdef AFS_SUN5_ENV
-#include <sys/fcntl.h>
#endif
-#include <unistd.h>
-#endif /* AFS_NT40_ENV */
-#include <sys/stat.h>
-
-/*@printflike@*/ extern void Log(const char *format, ...);
-
-/*@printflike@*/ extern void Abort(const char *format, ...);
-
struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
void
VNLog(afs_int32 aop, afs_int32 anparms, ... )
{
- register afs_int32 temp;
+ afs_int32 temp;
va_list ap;
va_start(ap, anparms);
* @internal volume package internal use only
*/
void
-DeleteFromVVnList(register Vnode * vnp)
+DeleteFromVVnList(Vnode * vnp)
{
Vn_volume(vnp) = NULL;
if (vnp == vcp->lruHead)
vcp->lruHead = vcp->lruHead->lruNext;
- if ((vnp == vcp->lruHead) ||
+ if ((vnp == vcp->lruHead) ||
(vcp->lruHead == NULL))
Abort("DeleteFromVnLRU: lru chain addled!\n");
* @internal vnode package internal use only
*/
void
-VInvalidateVnode_r(register struct Vnode *avnode)
+VInvalidateVnode_r(struct Vnode *avnode)
{
avnode->changed_newTime = 0; /* don't let it get flushed out again */
avnode->changed_oldTime = 0;
VInitVnodes(VnodeClass class, int nVnodes)
{
byte *va;
- register struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
+ struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
vcp->allocs = vcp->gets = vcp->reads = vcp->writes = 0;
vcp->cacheSize = nVnodes;
switch (class) {
case vSmall:
- assert(CHECKSIZE_SMALLVNODE);
+ opr_Assert(CHECKSIZE_SMALLVNODE);
vcp->lruHead = NULL;
vcp->residentSize = SIZEOF_SMALLVNODE;
vcp->diskSize = SIZEOF_SMALLDISKVNODE;
return 0;
va = (byte *) calloc(nVnodes, vcp->residentSize);
- assert(va != NULL);
+ opr_Assert(va != NULL);
while (nVnodes--) {
Vnode *vnp = (Vnode *) va;
Vn_refcount(vnp) = 0; /* no context switches */
Vn_stateFlags(vnp) |= VN_ON_LRU;
#ifdef AFS_DEMAND_ATTACH_FS
- assert(pthread_cond_init(&Vn_stateCV(vnp), NULL) == 0);
+ CV_INIT(&Vn_stateCV(vnp), "vnode state", CV_DEFAULT, 0);
Vn_state(vnp) = VN_STATE_INVALID;
Vn_readers(vnp) = 0;
#else /* !AFS_DEMAND_ATTACH_FS */
* allocate an unused vnode from the lru chain.
*
* @param[in] vcp vnode class info object pointer
+ * @param[in] vp volume pointer
+ * @param[in] vnodeNumber new vnode number that the vnode will be used for
*
* @pre VOL_LOCK is held
*
- * @post vnode object is removed from lru, and vnode hash table.
- * vnode is disassociated from volume object.
+ * @post vnode object is removed from lru
+ * vnode is disassociated with its old volume, and associated with its
+ * new volume
+ * vnode is removed from its old vnode hash table, and for DAFS, it is
+ * added to its new hash table
* state is set to VN_STATE_INVALID.
* inode handle is released.
+ * a reservation is held on the vnode object
*
- * @note we traverse backwards along the lru circlist. It shouldn't
- * be necessary to specify that nUsers == 0 since if it is in the list,
- * nUsers should be 0. Things shouldn't be in lruq unless no one is
+ * @note we traverse backwards along the lru circlist. It shouldn't
+ * be necessary to specify that nUsers == 0 since if it is in the list,
+ * nUsers should be 0. Things shouldn't be in lruq unless no one is
* using them.
*
* @warning DAFS: VOL_LOCK is dropped while doing inode handle release
*
+ * @warning for non-DAFS, the vnode is _not_ hashed on the vnode hash table;
+ * non-DAFS must hash the vnode itself after loading data
+ *
* @return vnode object pointer
*/
Vnode *
-VGetFreeVnode_r(struct VnodeClassInfo * vcp)
+VGetFreeVnode_r(struct VnodeClassInfo * vcp, struct Volume *vp,
+ VnodeId vnodeNumber)
{
- register Vnode *vnp;
+ Vnode *vnp;
vnp = vcp->lruHead->lruPrev;
#ifdef AFS_DEMAND_ATTACH_FS
if (Vn_refcount(vnp) != 0 || CheckLock(&vnp->lock))
Abort("VGetFreeVnode_r: locked vnode in lruq");
#endif
- VNLog(1, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+ VNLog(1, 2, Vn_id(vnp), (intptr_t)vnp, 0, 0);
- /*
+ /*
* it's going to be overwritten soon enough.
- * remove from LRU, delete hash entry, and
+ * remove from LRU, delete hash entry, and
* disassociate from old parent volume before
* we have a chance to drop the vol glock
*/
DeleteFromVVnList(vnp);
}
+ /* we must re-hash the vnp _before_ we drop the glock again; otherwise,
+ * someone else might try to grab the same vnode id, and we'll both alloc
+ * a vnode object for the same vn id, bypassing vnode locking */
+ Vn_id(vnp) = vnodeNumber;
+ VnCreateReservation_r(vnp);
+ AddToVVnList(vp, vnp);
+#ifdef AFS_DEMAND_ATTACH_FS
+ AddToVnHash(vnp);
+#endif
+
/* drop the file descriptor */
if (vnp->handle) {
#ifdef AFS_DEMAND_ATTACH_FS
* - ihandle package lock contention
* - closing file descriptor(s) associated with ih
*
- * Hance, we perform outside of the volume package lock in order to
+ * Hance, we perform outside of the volume package lock in order to
* reduce the probability of contention.
*/
IH_RELEASE(vnp->handle);
newHash = VNODE_HASH(vp, vnodeId);
for (vnp = VnodeHashTable[newHash];
- (vnp &&
- ((Vn_id(vnp) != vnodeId) ||
+ (vnp &&
+ ((Vn_id(vnp) != vnodeId) ||
(Vn_volume(vnp) != vp) ||
(vp->cacheCheck != Vn_cacheCheck(vnp))));
vnp = vnp->hashNext);
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)
{
- register Vnode *vnp;
+ Vnode *vnp;
VnodeId vnodeNumber;
int bitNumber;
- register struct VnodeClassInfo *vcp;
+ 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) {
+ int rollover = 0;
+
+ unique = vp->nextVnodeUnique++;
+ if (unique == 0) {
+ rollover = 1; /* nextVnodeUnique rolled over */
+ vp->nextVnodeUnique = 2; /* 1 is reserved for the root vnode */
+ unique = vp->nextVnodeUnique++;
+ }
+
+ if (vp->nextVnodeUnique > V_uniquifier(vp) || rollover) {
+ 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:
if (vnp) {
/* slot already exists. May even not be in lruq (consider store file locking a file being deleted)
* so we may have to wait for it below */
- VNLog(3, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+ VNLog(3, 2, vnodeNumber, (intptr_t)vnp, 0, 0);
VnCreateReservation_r(vnp);
if (Vn_refcount(vnp) == 1) {
/* This won't block */
VnLock(vnp, WRITE_LOCK, VOL_LOCK_HELD, WILL_NOT_DEADLOCK);
} else {
- /* other users present; follow locking hierarchy */
- VnLock(vnp, WRITE_LOCK, VOL_LOCK_HELD, MIGHT_DEADLOCK);
-
#ifdef AFS_DEMAND_ATTACH_FS
/*
* DAFS:
}
#endif
+ /* other users present; follow locking hierarchy */
+ VnLock(vnp, WRITE_LOCK, VOL_LOCK_HELD, MIGHT_DEADLOCK);
+
/*
* verify state of the world hasn't changed
*
}
}
+ /* sanity check: vnode should be blank if it was deleted. If it's
+ * not blank, it is still in use somewhere; but the bitmap told us
+ * this vnode number was free, so something is wrong. */
+ if (vnp->disk.type != vNull) {
+ Error tmp;
+ Log("VAllocVnode: addled bitmap or vnode object! (vol %" AFS_VOLID_FMT ", "
+ "vnode %p, number %ld, type %ld)\n", afs_printable_VolumeId_lu(vp->hashid), vnp,
+ (long)Vn_id(vnp), (long)vnp->disk.type);
+ *ec = EIO;
+ VFreeBitMapEntry_r(&tmp, vp, &vp->vnodeIndex[class], bitNumber,
+ VOL_FREE_BITMAP_WAIT);
+ VInvalidateVnode_r(vnp);
+ VnUnlock(vnp, WRITE_LOCK);
+ VnCancelReservation_r(vnp);
+#ifdef AFS_DEMAND_ATTACH_FS
+ VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, 0);
+#else
+ VForceOffline_r(vp, 0);
+#endif
+ return NULL;
+ }
+
} else {
/* no such vnode in the cache */
- vnp = VGetFreeVnode_r(vcp);
-
- /* Initialize the header fields so noone allocates another
- * vnode with the same number */
- Vn_id(vnp) = vnodeNumber;
- VnCreateReservation_r(vnp);
- AddToVVnList(vp, vnp);
-#ifdef AFS_DEMAND_ATTACH_FS
- AddToVnHash(vnp);
-#endif
+ vnp = VGetFreeVnode_r(vcp, vp, vnodeNumber);
/* This will never block (guaranteed by check in VGetFreeVnode_r() */
VnLock(vnp, WRITE_LOCK, VOL_LOCK_HELD, WILL_NOT_DEADLOCK);
/* Sanity check: is this vnode really not in use? */
{
- int size;
+ afs_sfsize_t size;
IHandle_t *ihP = vp->vnodeIndex[class].handle;
FdHandle_t *fdP;
- off_t off = vnodeIndexOffset(vcp, vnodeNumber);
+ afs_foff_t off = vnodeIndexOffset(vcp, vnodeNumber);
+ Error tmp;
/* XXX we have a potential race here if two threads
* allocate new vnodes at the same time, and they
*
* if this becomes a bottleneck, there are ways to
* improve parallelism for this code path
- * -- tkeiser 11/28/2007
+ * -- tkeiser 11/28/2007
*/
VCreateReservation_r(vp);
VWaitExclusiveState_r(vp);
fdP = IH_OPEN(ihP);
if (fdP == NULL) {
Log("VAllocVnode: can't open index file!\n");
+ *ec = ENOENT;
goto error_encountered;
}
if ((size = FDH_SIZE(fdP)) < 0) {
Log("VAllocVnode: can't stat index file!\n");
- goto error_encountered;
- }
- if (FDH_SEEK(fdP, off, SEEK_SET) < 0) {
- Log("VAllocVnode: can't seek on index file!\n");
+ *ec = EIO;
goto error_encountered;
}
if (off + vcp->diskSize <= size) {
- if (FDH_READ(fdP, &vnp->disk, vcp->diskSize) != vcp->diskSize) {
+ if (FDH_PREAD(fdP, &vnp->disk, vcp->diskSize, off) != vcp->diskSize) {
Log("VAllocVnode: can't read index file!\n");
+ *ec = EIO;
goto error_encountered;
}
if (vnp->disk.type != vNull) {
Log("VAllocVnode: addled bitmap or index!\n");
+ *ec = EIO;
goto error_encountered;
}
} else {
/* growing file - grow in a reasonable increment */
- char *buf = (char *)malloc(16 * 1024);
- if (!buf)
- Abort("VAllocVnode: malloc failed\n");
+ char *buf = malloc(16 * 1024);
+ if (!buf) {
+ Log("VAllocVnode: can't grow vnode index: out of memory\n");
+ *ec = ENOMEM;
+ goto error_encountered;
+ }
memset(buf, 0, 16 * 1024);
- (void)FDH_WRITE(fdP, buf, 16 * 1024);
+ if ((FDH_PWRITE(fdP, buf, 16 * 1024, off)) != 16 * 1024) {
+ Log("VAllocVnode: can't grow vnode index: write failed\n");
+ *ec = EIO;
+ free(buf);
+ goto error_encountered;
+ }
free(buf);
}
FDH_CLOSE(fdP);
error_encountered:
-#ifdef AFS_DEMAND_ATTACH_FS
- /*
+ /*
* close the file handle
* acquire VOL_LOCK
* invalidate the vnode
if (fdP)
FDH_CLOSE(fdP);
VOL_LOCK;
- VFreeBitMapEntry_r(ec, &vp->vnodeIndex[class], bitNumber);
+ VFreeBitMapEntry_r(&tmp, vp, &vp->vnodeIndex[class], bitNumber, 0 /*flags*/);
VInvalidateVnode_r(vnp);
VnUnlock(vnp, WRITE_LOCK);
VnCancelReservation_r(vnp);
+#ifdef AFS_DEMAND_ATTACH_FS
VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, 0);
VCancelReservation_r(vp);
- return NULL;
#else
- assert(1 == 2);
+ VForceOffline_r(vp, 0);
#endif
-
+ return NULL;
}
sane:
- VNLog(4, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+ VNLog(4, 2, vnodeNumber, (intptr_t)vnp, 0, 0);
#ifndef AFS_DEMAND_ATTACH_FS
AddToVnHash(vnp);
#endif
}
- VNLog(5, 1, (afs_int32) vnp, 0, 0, 0);
+ VNLog(5, 1, (intptr_t)vnp, 0, 0, 0);
memset(&vnp->disk, 0, sizeof(vnp->disk));
vnp->changed_newTime = 0; /* set this bit when vnode is updated */
vnp->changed_oldTime = 0; /* set this on CopyOnWrite. */
vnp->disk.uniquifier = unique;
vnp->handle = NULL;
vcp->allocs++;
- vp->header->diskstuff.filecount++;
+ V_filecount(vp)++;
#ifdef AFS_DEMAND_ATTACH_FS
VnChangeState_r(vnp, VN_STATE_EXCLUSIVE);
#endif
* @internal vnode package internal use only
*/
static void
-VnLoad(Error * ec, Volume * vp, Vnode * vnp,
+VnLoad(Error * ec, Volume * vp, Vnode * vnp,
struct VnodeClassInfo * vcp, VnodeClass class)
{
/* vnode not cached */
Error error;
- int n, dosalv = 1;
+ int dosalv = 1;
+ ssize_t nBytes;
IHandle_t *ihP = vp->vnodeIndex[class].handle;
FdHandle_t *fdP;
+ afs_ino_str_t stmp;
*ec = 0;
vcp->reads++;
fdP = IH_OPEN(ihP);
if (fdP == NULL) {
Log("VnLoad: can't open index dev=%u, i=%s\n", vp->device,
- PrintInode(NULL, vp->vnodeIndex[class].handle->ih_ino));
+ PrintInode(stmp, vp->vnodeIndex[class].handle->ih_ino));
*ec = VIO;
goto error_encountered_nolock;
- } else if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, Vn_id(vnp)), SEEK_SET)
- < 0) {
- Log("VnLoad: can't seek on index file vn=%u\n", Vn_id(vnp));
- *ec = VIO;
- goto error_encountered_nolock;
- } else if ((n = FDH_READ(fdP, (char *)&vnp->disk, vcp->diskSize))
+ } else if ((nBytes = FDH_PREAD(fdP, (char *)&vnp->disk, vcp->diskSize, vnodeIndexOffset(vcp, Vn_id(vnp))))
!= vcp->diskSize) {
/* Don't take volume off line if the inumber is out of range
* or the inode table is full. */
- if (n == BAD_IGET) {
+ if (nBytes == BAD_IGET) {
Log("VnLoad: bad inumber %s\n",
- PrintInode(NULL, vp->vnodeIndex[class].handle->ih_ino));
+ PrintInode(stmp, vp->vnodeIndex[class].handle->ih_ino));
*ec = VIO;
dosalv = 0;
- } else if (n == -1 && errno == EIO) {
+ } else if (nBytes == -1 && errno == EIO) {
/* disk error; salvage */
- Log("VnLoad: Couldn't read vnode %u, volume %u (%s); volume needs salvage\n", Vn_id(vnp), V_id(vp), V_name(vp));
+ Log("VnLoad: Couldn't read vnode %u, volume %" AFS_VOLID_FMT " (%s); volume needs salvage\n", Vn_id(vnp), afs_printable_VolumeId_lu(V_id(vp)), V_name(vp));
} else {
/* vnode is not allocated */
- if (LogLevel >= 5)
- Log("VnLoad: Couldn't read vnode %u, volume %u (%s); read %d bytes, errno %d\n",
- Vn_id(vnp), V_id(vp), V_name(vp), n, errno);
- *ec = VIO;
+ if (LogLevel >= 5)
+ Log("VnLoad: Couldn't read vnode %u, volume %" AFS_VOLID_FMT " (%s); read %d bytes, errno %d\n",
+ Vn_id(vnp), afs_printable_VolumeId_lu(V_id(vp)), V_name(vp), (int)nBytes, errno);
+ *ec = VNOVNODE;
dosalv = 0;
}
goto error_encountered_nolock;
unsigned int bitNumber = vnodeIdToBitNumber(Vn_id(vnp));
unsigned int offset = bitNumber >> 3;
+#ifdef AFS_DEMAND_ATTACH_FS
+ /* Make sure the volume bitmap isn't getting updated while we are
+ * checking it */
+ VWaitExclusiveState_r(vp);
+#endif
+
/* Test to see if vnode number is valid. */
if ((offset >= index->bitmapSize)
|| ((*(index->bitmap + offset) & (1 << (bitNumber & 0x7)))
== 0)) {
- Log("VnLoad: Request for unallocated vnode %u, volume %u (%s) denied.\n", Vn_id(vnp), V_id(vp), V_name(vp));
+ Log("VnLoad: Request for unallocated vnode %u, volume %" AFS_VOLID_FMT " (%s) denied.\n", Vn_id(vnp), afs_printable_VolumeId_lu(V_id(vp)), V_name(vp));
*ec = VNOVNODE;
dosalv = 0;
} else {
- Log("VnLoad: Bad magic number, vnode %u, volume %u (%s); volume needs salvage\n", Vn_id(vnp), V_id(vp), V_name(vp));
+ Log("VnLoad: Bad magic number, vnode %u, volume %" AFS_VOLID_FMT " (%s); volume needs salvage\n", Vn_id(vnp), afs_printable_VolumeId_lu(V_id(vp)), V_name(vp));
}
}
goto error_encountered;
}
- IH_INIT(vnp->handle, V_device(vp), V_parentId(vp), VN_GET_INO(vnp));
+ IH_INIT(vnp->handle, V_device(vp), afs_printable_VolumeId_lu(V_parentId(vp)), VN_GET_INO(vnp));
VnUnlock(vnp, WRITE_LOCK);
#ifdef AFS_DEMAND_ATTACH_FS
VnChangeState_r(vnp, VN_STATE_ONLINE);
* @internal vnode package internal use only
*/
static void
-VnStore(Error * ec, Volume * vp, Vnode * vnp,
+VnStore(Error * ec, Volume * vp, Vnode * vnp,
struct VnodeClassInfo * vcp, VnodeClass class)
{
- int offset, code;
+ ssize_t nBytes;
+ afs_foff_t offset;
IHandle_t *ihP = vp->vnodeIndex[class].handle;
FdHandle_t *fdP;
+ afs_ino_str_t stmp;
#ifdef AFS_DEMAND_ATTACH_FS
VnState vn_state_save;
#endif
Log("VnStore: can't open index file!\n");
goto error_encountered;
}
- if (FDH_SEEK(fdP, offset, SEEK_SET) < 0) {
- Log("VnStore: can't seek on index file! fdp=0x%x offset=%d, errno=%d\n",
- fdP, offset, errno);
- goto error_encountered;
- }
-
- code = FDH_WRITE(fdP, &vnp->disk, vcp->diskSize);
- if (code != vcp->diskSize) {
+ nBytes = FDH_PWRITE(fdP, &vnp->disk, vcp->diskSize, offset);
+ if (nBytes != vcp->diskSize) {
/* Don't force volume offline if the inumber is out of
* range or the inode table is full.
*/
FDH_REALLYCLOSE(fdP);
- if (code == BAD_IGET) {
+ if (nBytes == BAD_IGET) {
Log("VnStore: bad inumber %s\n",
- PrintInode(NULL,
+ PrintInode(stmp,
vp->vnodeIndex[class].handle->ih_ino));
*ec = VIO;
VOL_LOCK;
VnChangeState_r(vnp, VN_STATE_ERROR);
#endif
} else {
- Log("VnStore: Couldn't write vnode %u, volume %u (%s) (error %d)\n", Vn_id(vnp), V_id(Vn_volume(vnp)), V_name(Vn_volume(vnp)), code);
+ Log("VnStore: Couldn't write vnode %u, volume %" AFS_VOLID_FMT " (%s) (error %d)\n", Vn_id(vnp), afs_printable_VolumeId_lu(V_id(Vn_volume(vnp))), V_name(Vn_volume(vnp)), (int)nBytes);
#ifdef AFS_DEMAND_ATTACH_FS
goto error_encountered;
#else
VnChangeState_r(vnp, vn_state_save);
#endif
return;
-
+
error_encountered:
#ifdef AFS_DEMAND_ATTACH_FS
/* XXX instead of dumping core, let's try to request a salvage
VnChangeState_r(vnp, VN_STATE_ERROR);
VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, 0);
#else
- assert(1 == 2);
+ opr_abort();
#endif
}
Vnode *
VGetVnode_r(Error * ec, Volume * vp, VnodeId vnodeNumber, int locktype)
{ /* READ_LOCK or WRITE_LOCK, as defined in lock.h */
- register Vnode *vnp;
+ Vnode *vnp;
VnodeClass class;
struct VnodeClassInfo *vcp;
if (vnp) {
/* vnode is in cache */
- VNLog(101, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+ VNLog(101, 2, vnodeNumber, (intptr_t)vnp, 0, 0);
VnCreateReservation_r(vnp);
#ifdef AFS_DEMAND_ATTACH_FS
/* Not in cache; tentatively grab most distantly used one from the LRU
* chain */
vcp->reads++;
- vnp = VGetFreeVnode_r(vcp);
+ vnp = VGetFreeVnode_r(vcp, vp, vnodeNumber);
/* Initialize */
vnp->changed_newTime = vnp->changed_oldTime = 0;
vnp->delete = 0;
- Vn_id(vnp) = vnodeNumber;
- VnCreateReservation_r(vnp);
- AddToVVnList(vp, vnp);
-#ifdef AFS_DEMAND_ATTACH_FS
- AddToVnHash(vnp);
-#endif
/*
* XXX for non-DAFS, there is a serious
/* Check that the vnode hasn't been removed while we were obtaining
* the lock */
- VNLog(102, 2, vnodeNumber, (afs_int32) vnp, 0, 0);
+ VNLog(102, 2, vnodeNumber, (intptr_t) vnp, 0, 0);
if ((vnp->disk.type == vNull) || (Vn_cacheCheck(vnp) == 0)) {
VnUnlock(vnp, locktype);
VnCancelReservation_r(vnp);
/* This variable is bogus--when it's set to 0, the hash chains fill
up with multiple versions of the same vnode. Should fix this!! */
void
-VPutVnode(Error * ec, register Vnode * vnp)
+VPutVnode(Error * ec, Vnode * vnp)
{
VOL_LOCK;
VPutVnode_r(ec, vnp);
* @internal volume package internal use only
*/
void
-VPutVnode_r(Error * ec, register Vnode * vnp)
+VPutVnode_r(Error * ec, Vnode * vnp)
{
int writeLocked;
VnodeClass class;
struct VnodeClassInfo *vcp;
*ec = 0;
- assert(Vn_refcount(vnp) != 0);
+ opr_Assert(Vn_refcount(vnp) != 0);
class = vnodeIdToClass(Vn_id(vnp));
vcp = &VnodeClassInfo[class];
- assert(vnp->disk.vnodeMagic == vcp->magic);
- VNLog(200, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+ opr_Assert(vnp->disk.vnodeMagic == vcp->magic);
+ VNLog(200, 2, Vn_id(vnp), (intptr_t) vnp, 0, 0);
#ifdef AFS_DEMAND_ATTACH_FS
writeLocked = (Vn_state(vnp) == VN_STATE_EXCLUSIVE);
PROCESS thisProcess;
LWP_CurrentProcess(&thisProcess);
#endif /* AFS_PTHREAD_ENV */
- VNLog(201, 2, (afs_int32) vnp,
+ VNLog(201, 2, (intptr_t) vnp,
((vnp->changed_newTime) << 1) | ((vnp->
changed_oldTime) << 1) | vnp->
delete, 0, 0);
if (thisProcess != vnp->writer)
- Abort("VPutVnode: Vnode at 0x%x locked by another process!\n",
+ Abort("VPutVnode: Vnode at %"AFS_PTR_FMT" locked by another process!\n",
vnp);
if (vnp->changed_oldTime || vnp->changed_newTime || vnp->delete) {
Volume *vp = Vn_volume(vnp);
afs_uint32 now = FT_ApproxTime();
- assert(Vn_cacheCheck(vnp) == vp->cacheCheck);
+ opr_Assert(Vn_cacheCheck(vnp) == vp->cacheCheck);
if (vnp->delete) {
/* No longer any directory entries for this vnode. Free the Vnode */
memset(&vnp->disk, 0, sizeof(vnp->disk));
/* delete flag turned off further down */
- VNLog(202, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+ VNLog(202, 2, Vn_id(vnp), (intptr_t) vnp, 0, 0);
} else if (vnp->changed_newTime) {
vnp->disk.serverModifyTime = now;
}
if (vnp->changed_newTime)
{
V_updateDate(vp) = vp->updateTime = now;
- if(V_volUpCounter(vp)<MAXINT)
+ if(V_volUpCounter(vp)< UINT_MAX)
V_volUpCounter(vp)++;
}
#ifdef AFS_DEMAND_ATTACH_FS
VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, 0);
#else
- assert(V_needsSalvaged(vp));
+ opr_Assert(V_needsSalvaged(vp));
*ec = VSALVAGE;
#endif
} else {
* (doing so could cause a "addled bitmap" message).
*/
if (vnp->delete && !*ec) {
- if (Vn_volume(vnp)->header->diskstuff.filecount-- < 1)
- Vn_volume(vnp)->header->diskstuff.filecount = 0;
- VFreeBitMapEntry_r(ec, &vp->vnodeIndex[class],
- vnodeIdToBitNumber(Vn_id(vnp)));
+ if (V_filecount(Vn_volume(vnp))-- < 1)
+ V_filecount(Vn_volume(vnp)) = 0;
+ VFreeBitMapEntry_r(ec, vp, &vp->vnodeIndex[class],
+ vnodeIdToBitNumber(Vn_id(vnp)),
+ VOL_FREE_BITMAP_WAIT);
}
}
vcp->writes++;
} else { /* Not write locked */
if (vnp->changed_newTime || vnp->changed_oldTime || vnp->delete)
Abort
- ("VPutVnode: Change or delete flag for vnode 0x%x is set but vnode is not write locked!\n",
+ ("VPutVnode: Change or delete flag for vnode "
+ "%"AFS_PTR_FMT" is set but vnode is not write locked!\n",
vnp);
#ifdef AFS_DEMAND_ATTACH_FS
VnEndRead_r(vnp);
* been deleted.
*/
int
-VVnodeWriteToRead(Error * ec, register Vnode * vnp)
+VVnodeWriteToRead(Error * ec, Vnode * vnp)
{
int retVal;
VOL_LOCK;
* @internal volume package internal use only
*/
int
-VVnodeWriteToRead_r(Error * ec, register Vnode * vnp)
+VVnodeWriteToRead_r(Error * ec, Vnode * vnp)
{
int writeLocked;
VnodeClass class;
#endif /* AFS_PTHREAD_ENV */
*ec = 0;
- assert(Vn_refcount(vnp) != 0);
+ opr_Assert(Vn_refcount(vnp) != 0);
class = vnodeIdToClass(Vn_id(vnp));
vcp = &VnodeClassInfo[class];
- assert(vnp->disk.vnodeMagic == vcp->magic);
- VNLog(300, 2, Vn_id(vnp), (afs_int32) vnp, 0, 0);
+ opr_Assert(vnp->disk.vnodeMagic == vcp->magic);
+ VNLog(300, 2, Vn_id(vnp), (intptr_t) vnp, 0, 0);
#ifdef AFS_DEMAND_ATTACH_FS
writeLocked = (Vn_state(vnp) == VN_STATE_EXCLUSIVE);
}
- VNLog(301, 2, (afs_int32) vnp,
+ VNLog(301, 2, (intptr_t) vnp,
((vnp->changed_newTime) << 1) | ((vnp->
changed_oldTime) << 1) | vnp->
delete, 0, 0);
LWP_CurrentProcess(&thisProcess);
#endif /* AFS_PTHREAD_ENV */
if (thisProcess != vnp->writer)
- Abort("VPutVnode: Vnode at 0x%x locked by another process!\n",
- (int)vnp);
+ Abort("VPutVnode: Vnode at %"AFS_PTR_FMT
+ " locked by another process!\n", vnp);
if (vnp->delete) {
return 0;
if (vnp->changed_oldTime || vnp->changed_newTime) {
Volume *vp = Vn_volume(vnp);
afs_uint32 now = FT_ApproxTime();
- assert(Vn_cacheCheck(vnp) == vp->cacheCheck);
+ opr_Assert(Vn_cacheCheck(vnp) == vp->cacheCheck);
if (vnp->changed_newTime)
vnp->disk.serverModifyTime = now;
if (vnp->changed_newTime)
#ifdef AFS_DEMAND_ATTACH_FS
VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, 0);
#else
- assert(V_needsSalvaged(vp));
+ opr_Assert(V_needsSalvaged(vp));
*ec = VSALVAGE;
#endif
} else {
return 0;
}
-/**
+/**
* initial size of ihandle pointer vector.
*
* @see VInvalidateVnodesByVolume_r
if (ih_vec == NULL)
return ENOMEM;
- /*
- * Traverse the volume's vnode list. Pull all the ihandles out into a
+ /*
+ * Traverse the volume's vnode list. Pull all the ihandles out into a
* thread-private array for later asynchronous processing.
*/
- restart_traversal:
+#ifdef AFS_DEMAND_ATTACH_FS
+restart_traversal:
+#endif
for (queue_Scan(&vp->vnode_list, vnp, nvnp, Vnode)) {
if (vnp->handle != NULL) {
if (i == vec_len) {
ih_vec = ih_vec_new;
#ifdef AFS_DEMAND_ATTACH_FS
/*
- * Theoretically, the volume's VVn list should not change
+ * Theoretically, the volume's VVn list should not change
* because the volume is in an exclusive state. For the
* sake of safety, we will restart the traversal from the
* the beginning (which is not expensive because we're
#endif /* AFS_DEMAND_ATTACH_FS */
/* XXX need better error handling here */
- assert(VInvalidateVnodesByVolume_r(vp,
- &ih_vec,
- &vec_len) == 0);
+ opr_Verify(VInvalidateVnodesByVolume_r(vp, &ih_vec,
+ &vec_len) == 0);
/*
* DAFS:
* during this exclusive operation. This is due to the fact that we are
* generally called during the refcount 1->0 transition.
*
- * @todo we should handle failures in VInvalidateVnodesByVolume_r more
+ * @todo we should handle failures in VInvalidateVnodesByVolume_r more
* gracefully.
*
* @see VInvalidateVnodesByVolume_r
#endif /* AFS_DEMAND_ATTACH_FS */
/* XXX need better error handling here */
- assert(VInvalidateVnodesByVolume_r(vp,
- &ih_vec,
- &vec_len) == 0);
+ opr_Verify(VInvalidateVnodesByVolume_r(vp, &ih_vec,
+ &vec_len) == 0);
/*
* DAFS: