#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/stds.h"
#include "afs/sysincludes.h" /* Standard vendor system headers */
#ifdef AFS_SGI62_ENV
#include "h/hashing.h"
#endif
-#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN60_ENV)
+#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV)
#include <netinet/in_var.h>
#endif /* ! AFS_HPUX110_ENV */
#endif /* !defined(UKERNEL) */
#endif /* vlserver error base define */
/* Exported variables */
-#if defined(LINUX_USE_FH)
-struct fid volumeinfo_fh; /* File handle for VolumeItems file */
-int volumeinfo_fh_type;
-#else
-ino_t volumeInode; /* Inode for VolumeItems file */
-#endif
+afs_dcache_id_t volumeInode; /* Inode for VolumeItems file */
afs_rwlock_t afs_xvolume; /** allocation lock for volumes */
struct volume *afs_freeVolList;
struct volume *afs_volumes[NVOLS];
struct volume *
afs_UFSGetVolSlot(void)
{
- register struct volume *tv, **lv;
+ register struct volume *tv = NULL, **lv;
struct osi_file *tfile;
- register afs_int32 i, code;
+ register afs_int32 i = -1, code;
afs_int32 bestTime;
- struct volume *bestVp, **bestLp;
+ struct volume *bestVp, *oldLp = NULL, **bestLp = NULL;
+ char *oldname = NULL;
+ afs_int32 oldvtix = -2; /* Initialize to a value that doesn't occur */
AFS_STATCNT(afs_UFSGetVolSlot);
if (!afs_freeVolList) {
}
}
}
- if (!bestVp)
- osi_Panic("getvolslot none");
+ if (!bestVp) {
+ afs_warn("afs_UFSGetVolSlot: no vol slots available\n");
+ goto error;
+ }
tv = bestVp;
+
+ oldLp = *bestLp;
*bestLp = tv->next;
- if (tv->name)
- afs_osi_Free(tv->name, strlen(tv->name) + 1);
+
+ oldname = tv->name;
tv->name = NULL;
+
+ oldvtix = tv->vtix;
/* now write out volume structure to file */
if (tv->vtix < 0) {
tv->vtix = afs_volCounter++;
* next chain
*/
if (afs_FVIndex != tv->vtix) {
-#if defined(LINUX_USE_FH)
- tfile = osi_UFSOpen_fh(&volumeinfo_fh, volumeinfo_fh_type);
-#else
- tfile = osi_UFSOpen(volumeInode);
-#endif
+ tfile = osi_UFSOpen(&volumeInode);
code =
afs_osi_Read(tfile, sizeof(struct fvolume) * tv->vtix,
&staticFVolume, sizeof(struct fvolume));
- if (code != sizeof(struct fvolume))
- osi_Panic("read volumeinfo");
osi_UFSClose(tfile);
+ if (code != sizeof(struct fvolume)) {
+ afs_warn("afs_UFSGetVolSlot: error %d reading volumeinfo\n",
+ (int)code);
+ goto error;
+ }
afs_FVIndex = tv->vtix;
}
}
staticFVolume.dotdot = tv->dotdot;
staticFVolume.rootVnode = tv->rootVnode;
staticFVolume.rootUnique = tv->rootUnique;
-#if defined(LINUX_USE_FH)
- tfile = osi_UFSOpen_fh(&volumeinfo_fh, volumeinfo_fh_type);
-#else
- tfile = osi_UFSOpen(volumeInode);
-#endif
+ tfile = osi_UFSOpen(&volumeInode);
code =
afs_osi_Write(tfile, sizeof(struct fvolume) * afs_FVIndex,
&staticFVolume, sizeof(struct fvolume));
- if (code != sizeof(struct fvolume))
- osi_Panic("write volumeinfo");
osi_UFSClose(tfile);
+ if (code != sizeof(struct fvolume)) {
+ afs_warn("afs_UFSGetVolSlot: error %d writing volumeinfo\n",
+ (int)code);
+ goto error;
+ }
+ if (oldname) {
+ afs_osi_Free(oldname, strlen(oldname) + 1);
+ oldname = NULL;
+ }
} else {
tv = afs_freeVolList;
afs_freeVolList = tv->next;
}
return tv;
+ error:
+ if (tv) {
+ if (oldtvix == -2) {
+ afs_warn("afs_UFSGetVolSlot: oldvtix is uninitialized\n");
+ return NULL;
+ }
+ if (oldname) {
+ tv->name = oldname;
+ oldname = NULL;
+ }
+ if (oldvtix < 0) {
+ afs_volCounter--;
+ fvTable[i] = staticFVolume.next;
+ }
+ if (bestLp) {
+ *bestLp = oldLp;
+ }
+ tv->vtix = oldvtix;
+ /* we messed with staticFVolume, so make sure someone else
+ * doesn't think it's fine to use */
+ afs_FVIndex = -1;
+ }
+ return NULL;
} /*afs_UFSGetVolSlot */
/* Find any volumes residing on this server and flush their state */
for (j = 0; j < NVOLS; j++) {
for (vp = afs_volumes[j]; vp; vp = vp->next) {
- for (k = 0; k < MAXHOSTS; k++) {
+ for (k = 0; k < AFS_MAXHOSTS; k++) {
if (!srvp || (vp->serverHost[k] == srvp)) {
vp->serverHost[k] = 0;
afs_ResetVolumeInfo(vp);
}
/* ??? */
if (flags & (AFS_VOLCHECK_BUSY | AFS_VOLCHECK_FORCE)) {
- for (j = 0; j < MAXHOSTS; j++)
+ for (j = 0; j < AFS_MAXHOSTS; j++)
tv->status[j] = not_busy;
}
if ((flags & (AFS_VOLCHECK_FORCE | AFS_VOLCHECK_MTPTS))
|| (tvc->mvid
&& inVolList(tvc->mvid, nvols, volumeID, cellID)))
- tvc->states &= ~CMValid;
+ tvc->f.states &= ~CMValid;
/* If the volume that this file belongs to was reset earlier,
* then we should remove its callback.
* Again, if forced, always do it.
*/
- if ((tvc->states & CRO)
- && (inVolList(&tvc->fid, nvols, volumeID, cellID)
+ if ((tvc->f.states & CRO)
+ && (inVolList(&tvc->f.fid, nvols, volumeID, cellID)
|| (flags & AFS_VOLCHECK_FORCE))) {
- if (tvc->states & CVInit) {
+ if (tvc->f.states & CVInit) {
ReleaseReadLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->states);
+ afs_osi_Sleep(&tvc->f.states);
goto loop;
}
#ifdef AFS_DARWIN80_ENV
- if (tvc->states & CDeadVnode) {
+ if (tvc->f.states & CDeadVnode) {
ReleaseReadLock(&afs_xvcache);
- afs_osi_Sleep(&tvc->states);
+ afs_osi_Sleep(&tvc->f.states);
goto loop;
}
tvp = AFSTOV(tvc);
ObtainWriteLock(&afs_xcbhash, 485);
/* LOCKXXX: We aren't holding tvc write lock? */
afs_DequeueCallback(tvc);
- tvc->states &= ~CStatd;
+ tvc->f.states &= ~CStatd;
ReleaseWriteLock(&afs_xcbhash);
- if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
+ if (tvc->f.fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))
osi_dnlc_purgedp(tvc);
#ifdef AFS_DARWIN80_ENV
struct fvolume *tf = 0;
tv = afs_GetVolSlot();
- memset((char *)tv, 0, sizeof(struct volume));
+ if (!tv) {
+ ReleaseWriteLock(&afs_xvolume);
+ return NULL;
+ }
+ memset(tv, 0, sizeof(struct volume));
tv->cell = tcell->cellNum;
AFS_RWLOCK_INIT(&tv->lock, "volume lock");
tv->next = afs_volumes[i]; /* thread into list */
for (j = fvTable[FVHash(tv->cell, volid)]; j != 0; j = tf->next) {
if (afs_FVIndex != j) {
struct osi_file *tfile;
-#if defined(LINUX_USE_FH)
- tfile = osi_UFSOpen_fh(&volumeinfo_fh, volumeinfo_fh_type);
-#else
- tfile = osi_UFSOpen(volumeInode);
-#endif
+ tfile = osi_UFSOpen(&volumeInode);
err =
afs_osi_Read(tfile, sizeof(struct fvolume) * j,
&staticFVolume, sizeof(struct fvolume));
int i;
struct server *sp;
struct srvAddr *sap;
- for (i = 0; i < MAXCELLHOSTS; i++) {
+ for (i = 0; i < AFS_MAXCELLHOSTS; i++) {
if ((sp = tcell->cellHosts[i]) == NULL)
break;
for (sap = sp->addr; sap; sap = sap->next_sa)
else
ve = (char *)tve;
tv = afs_SetupVolume(0, aname, ve, tcell, agood, type, areq);
- if ((agood == 3) && tv->backVol) {
+ if ((agood == 3) && tv && tv->backVol) {
/*
* This means that very soon we'll ask for the BK volume so
* we'll prefetch it (well we did already.)
*/
tv1 =
afs_SetupVolume(tv->backVol, (char *)0, ve, tcell, 0, type, areq);
- tv1->refCount--;
+ if (tv1) {
+ tv1->refCount--;
+ }
}
- if ((agood >= 2) && tv->roVol) {
+ if ((agood >= 2) && tv && tv->roVol) {
/*
* This means that very soon we'll ask for the RO volume so
* we'll prefetch it (well we did already.)
*/
tv1 = afs_SetupVolume(tv->roVol, NULL, ve, tcell, 0, type, areq);
- tv1->refCount--;
+ if (tv1) {
+ tv1->refCount--;
+ }
}
osi_FreeLargeSpace(tbuffer);
afs_PutCell(tcell, READ_LOCK);
* struct, we don't deadlock trying to afs_ResetVolumeInfo()
* this volume.
*/
- for (j = 0; j < MAXHOSTS; j++) {
+ for (j = 0; j < AFS_MAXHOSTS; j++) {
av->serverHost[j] = 0;
}
afs_PutServer(ts, WRITE_LOCK);
j++;
}
- if (j < MAXHOSTS) {
+ if (j < AFS_MAXHOSTS) {
av->serverHost[j++] = 0;
}
- afs_SortServers(av->serverHost, MAXHOSTS);
+ afs_SortServers(av->serverHost, AFS_MAXHOSTS);
} /*InstallVolumeEntry */
* struct, we don't deadlock trying to afs_ResetVolumeInfo()
* this volume.
*/
- for (j = 0; j < MAXHOSTS; j++) {
+ for (j = 0; j < AFS_MAXHOSTS; j++) {
av->serverHost[j] = 0;
}
afs_PutServer(ts, WRITE_LOCK);
j++;
}
- if (j < MAXHOSTS) {
+ if (j < AFS_MAXHOSTS) {
av->serverHost[j++] = 0;
}
- afs_SortServers(av->serverHost, MAXHOSTS);
+ afs_SortServers(av->serverHost, AFS_MAXHOSTS);
} /*InstallNVolumeEntry */
* struct, we don't deadlock trying to afs_ResetVolumeInfo()
* this volume.
*/
- for (j = 0; j < MAXHOSTS; j++) {
+ for (j = 0; j < AFS_MAXHOSTS; j++) {
av->serverHost[j] = 0;
}
&& ts->addr) {
/* uuid, uniquifier, and portal are the same */
} else {
- afs_uint32 *addrp, nentries, code, unique;
+ afs_uint32 *addrp, code;
+ afs_int32 nentries, unique;
bulkaddrs addrs;
ListAddrByAttributes attrs;
afsUUID uuid;
- memset((char *)&attrs, 0, sizeof(attrs));
+ memset(&attrs, 0, sizeof(attrs));
attrs.Mask = VLADDR_UUID;
attrs.uuid = ve->serverNumber[i];
- memset((char *)&uuid, 0, sizeof(uuid));
- memset((char *)&addrs, 0, sizeof(addrs));
+ memset(&uuid, 0, sizeof(uuid));
+ memset(&addrs, 0, sizeof(addrs));
do {
tconn =
afs_ConnByMHosts(tcell->cellHosts, tcell->vlport,
ts = afs_GetServer(addrp, nentries, acell, cellp->fsport,
WRITE_LOCK, &ve->serverNumber[i],
ve->serverUnique[i]);
- afs_osi_Free(addrs.bulkaddrs_val,
- addrs.bulkaddrs_len * sizeof(*addrp));
+ xdr_free((xdrproc_t) xdr_bulkaddrs, &addrs);
}
}
av->serverHost[j] = ts;
j++;
}
- afs_SortServers(av->serverHost, MAXHOSTS);
+ afs_SortServers(av->serverHost, AFS_MAXHOSTS);
} /*InstallVolumeEntry */
AFS_STATCNT(afs_ResetVolumeInfo);
ObtainWriteLock(&tv->lock, 117);
tv->states |= VRecheck;
- for (i = 0; i < MAXHOSTS; i++)
+ for (i = 0; i < AFS_MAXHOSTS; i++)
tv->status[i] = not_busy;
if (tv->name) {
afs_osi_Free(tv->name, strlen(tv->name) + 1);