struct dcache *dcp; /* chunk containing the dir block */
char *statMemp; /* status memory block */
char *cbfMemp; /* callback and fid memory block */
- long temp; /* temp for holding chunk length, &c. */
+ afs_size_t temp; /* temp for holding chunk length, &c. */
struct AFSFid *fidsp; /* file IDs were collecting */
struct AFSCallBack *cbsp; /* call back pointers */
struct AFSCallBack *tcbp; /* temp callback ptr */
long startTime; /* time we started the call,
* for callback expiration base
*/
- int statSeqNo; /* Valued of file size to detect races */
+ afs_size_t statSeqNo; /* Valued of file size to detect races */
int code; /* error code */
long newIndex; /* new index in the dir */
struct DirEntry *dirEntryp; /* dir entry we are examining */
code = afs_VerifyVCache(adp, areqp);
if (code) goto done;
- dcp = afs_GetDCache(adp, 0, areqp, &temp, &temp, 1);
+ dcp = afs_GetDCache(adp, (afs_size_t) 0, areqp, &temp, &temp, 1);
if (!dcp) {
code = ENOENT;
goto done;
/* lock the directory cache entry */
ObtainReadLock(&adp->lock);
+ ObtainReadLock(&dcp->lock);
/*
* Make sure that the data in the cache is current. There are two
* 2. The cache data is no longer valid
*/
while ((adp->states & CStatd)
- && (dcp->flags & DFFetching)
+ && (dcp->dflags & DFFetching)
&& hsame(adp->m.DataVersion, dcp->f.versionNo)) {
- dcp->flags |= DFWaiting;
+ afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
+ ICL_TYPE_STRING, __FILE__,
+ ICL_TYPE_INT32, __LINE__,
+ ICL_TYPE_POINTER, dcp,
+ ICL_TYPE_INT32, dcp->dflags);
+ ReleaseReadLock(&dcp->lock);
ReleaseReadLock(&adp->lock);
afs_osi_Sleep(&dcp->validPos);
ObtainReadLock(&adp->lock);
+ ObtainReadLock(&dcp->lock);
}
if (!(adp->states & CStatd)
|| !hsame(adp->m.DataVersion, dcp->f.versionNo)) {
+ ReleaseReadLock(&dcp->lock);
ReleaseReadLock(&adp->lock);
afs_PutDCache(dcp);
goto tagain;
tvcp = afs_FindVCache(&tfid, 0, 0, &retry, 0 /* no stats | LRU */);
if (tvcp && retry) {
ReleaseWriteLock(&afs_xvcache);
- afs_PutVCache(tvcp);
+ afs_PutVCache(tvcp, 0);
}
} while (tvcp && retry);
if (!tvcp) { /* otherwise, create manually */
tvcp->m.Length = statSeqNo;
fidIndex++;
}
- afs_PutVCache(tvcp);
+ afs_PutVCache(tvcp, 0);
} /* if dir vnode has non-zero entry */
/* move to the next dir entry by adding in the # of entries
} /* while loop over all dir entries */
/* now release the dir lock and prepare to make the bulk RPC */
+ ReleaseReadLock(&dcp->lock);
ReleaseReadLock(&adp->lock);
/* release the chunk */
#ifdef RX_ENABLE_LOCKS
AFS_GUNLOCK();
#endif /* RX_ENABLE_LOCKS */
- code = RXAFS_InlineBulkStatus(tcp->id, &fidParm, &statParm,
- &cbParm, &volSync);
- if (code == RXGEN_OPCODE) {
+
+ if (!(tcp->srvr->server->flags & SNO_INLINEBULK)) {
+ code = RXAFS_InlineBulkStatus(tcp->id, &fidParm, &statParm,
+ &cbParm, &volSync);
+ if (code == RXGEN_OPCODE) {
+ tcp->srvr->server->flags |= SNO_INLINEBULK;
+ inlinebulk = 0;
+ code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm,
+ &cbParm, &volSync);
+ } else
+ inlinebulk=1;
+ } else {
+ inlinebulk=0;
code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm,
&volSync);
- inlinebulk=0;
- } else {
- inlinebulk=1;
}
-
#ifdef RX_ENABLE_LOCKS
AFS_GLOCK();
#endif /* RX_ENABLE_LOCKS */
if (!(tvcp->states & CBulkFetching) || (tvcp->m.Length != statSeqNo)) {
flagIndex++;
ReleaseWriteLock(&tvcp->lock);
- afs_PutVCache(tvcp);
+ afs_PutVCache(tvcp, 0);
continue;
}
flagIndex++;
ReleaseWriteLock(&tvcp->lock);
ReleaseWriteLock(&afs_xcbhash);
- afs_PutVCache(tvcp);
+ afs_PutVCache(tvcp, 0);
continue;
}
ReleaseWriteLock(&tvcp->lock);
/* finally, we're done with the entry */
- afs_PutVCache(tvcp);
+ afs_PutVCache(tvcp, 0);
} /* for all files we got back */
/* finally return the pointer into the LRU queue */
- afs_PutVCache(lruvcp);
+ afs_PutVCache(lruvcp, 0);
done:
/* Be sure to turn off the CBulkFetching flags */
tvcp->states &= ~CBulkFetching;
}
if (tvcp != NULL) {
- afs_PutVCache(tvcp);
+ afs_PutVCache(tvcp, 0);
}
}
if ( volp )
afs_PutVolume(volp, READ_LOCK);
/* If we did the InlineBulk RPC pull out the return code */
- if (inlinebulk && (&statsp[0])->errorCode) {
- afs_Analyze(tcp, (&statsp[0])->errorCode, &adp->fid, areqp,
- AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK,
- (struct cell *)0);
- code = (&statsp[0])->errorCode;
+ if (inlinebulk) {
+ if ((&statsp[0])->errorCode) {
+ afs_Analyze(tcp, (&statsp[0])->errorCode, &adp->fid, areqp,
+ AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK,
+ (struct cell *)0);
+ code = (&statsp[0])->errorCode;
+ }
+ } else {
+ code = 0;
}
osi_FreeLargeSpace(statMemp);
osi_FreeLargeSpace(cbfMemp);
afs_hyper_t versionNo;
int no_read_access = 0;
struct sysname_info sysState; /* used only for @sys checking */
+ int dynrootRetry = 1;
AFS_STATCNT(afs_lookup);
#ifdef AFS_OSF_ENV
- ndp->ni_dvp = (struct vnode *)adp;
+ ndp->ni_dvp = AFSTOV(adp);
memcpy(aname, ndp->ni_ptr, ndp->ni_namelen);
aname[ndp->ni_namelen] = '\0';
#endif /* AFS_OSF_ENV */
#ifdef AFS_OSF_ENV
extern struct vcache *afs_globalVp;
if (adp == afs_globalVp) {
- struct vnode *rvp = (struct vnode *)adp;
+ struct vnode *rvp = AFSTOV(adp);
/*
ndp->ni_vp = rvp->v_vfsp->vfs_vnodecovered;
ndp->ni_dvp = ndp->ni_vp;
*avcp = tvc;
code = (tvc ? 0 : ENOENT);
hit = 1;
- if (tvc && !tvc->vrefCount) {
+ if (tvc && !VREFCOUNT(tvc)) {
osi_Panic("TT1");
}
if (code) {
/* Check for read access as well. We need read access in order to
stat files, but not to stat subdirectories. */
- if (!afs_AccessOK(adp, PRSFS_READ, &treq, CHECK_MODE_BITS))
+ if (!afs_AccessOK(adp, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS))
no_read_access = 1;
/* special case lookup of ".". Can we check for it sooner in this code,
code = 0;
*avcp = tvc = adp;
hit = 1;
- if (adp && !adp->vrefCount) {
+ if (adp && !VREFCOUNT(adp)) {
osi_Panic("TT2");
}
goto done;
{
register struct dcache *tdc;
- afs_int32 dirOffset, dirLen;
+ afs_size_t dirOffset, dirLen;
ino_t theDir;
struct VenusFid tfid;
/* now we have to lookup the next fid */
- tdc = afs_GetDCache(adp, 0, &treq, &dirOffset, &dirLen, 1);
+ tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &dirOffset, &dirLen, 1);
if (!tdc) {
*avcp = (struct vcache *)0; /* redundant, but harmless */
code = EIO;
/* now we will just call dir package with appropriate inode.
Dirs are always fetched in their entirety for now */
ObtainReadLock(&adp->lock);
+ ObtainReadLock(&tdc->lock);
/*
* Make sure that the data in the cache is current. There are two
* 2. The cache data is no longer valid
*/
while ((adp->states & CStatd)
- && (tdc->flags & DFFetching)
+ && (tdc->dflags & DFFetching)
&& hsame(adp->m.DataVersion, tdc->f.versionNo)) {
- tdc->flags |= DFWaiting;
+ ReleaseReadLock(&tdc->lock);
ReleaseReadLock(&adp->lock);
afs_osi_Sleep(&tdc->validPos);
ObtainReadLock(&adp->lock);
+ ObtainReadLock(&tdc->lock);
}
if (!(adp->states & CStatd)
|| !hsame(adp->m.DataVersion, tdc->f.versionNo)) {
+ ReleaseReadLock(&tdc->lock);
ReleaseReadLock(&adp->lock);
afs_PutDCache(tdc);
goto redo;
}
tname = sysState.name;
- ReleaseReadLock(&adp->lock);
+ ReleaseReadLock(&tdc->lock);
afs_PutDCache(tdc);
+ if (code == ENOENT && afs_IsDynroot(adp) && dynrootRetry) {
+ struct cell *tcell;
+
+ ReleaseReadLock(&adp->lock);
+ dynrootRetry = 0;
+ if (*tname == '.')
+ tcell = afs_GetCellByName(tname + 1, READ_LOCK);
+ else
+ tcell = afs_GetCellByName(tname, READ_LOCK);
+ if (tcell) {
+ afs_PutCell(tcell, READ_LOCK);
+ afs_RefreshDynroot();
+ if (tname != aname && tname) osi_FreeLargeSpace(tname);
+ goto redo;
+ }
+ } else {
+ ReleaseReadLock(&adp->lock);
+ }
+
/* new fid has same cell and volume */
tfid.Cell = adp->fid.Cell;
tfid.Fid.Volume = adp->fid.Fid.Volume;
/* prefetch some entries, if the dir is currently open. The variable
* dirCookie tells us where to start prefetching from.
*/
- if (AFSDOBULK && adp->opens > 0 && !(adp->states & CForeign)) {
+ if (AFSDOBULK && adp->opens > 0 && !(adp->states & CForeign) && !afs_IsDynroot(adp)) {
afs_int32 retry;
/* if the entry is not in the cache, or is in the cache,
* but hasn't been statd, then do a bulk stat operation.
/* if the vcache isn't usable, release it */
if (tvc && !(tvc->states & CStatd)) {
- afs_PutVCache(tvc);
+ afs_PutVCache(tvc, 0);
tvc = (struct vcache *) 0;
}
} else {
ReleaseWriteLock(&tvc->lock);
if (code) {
+ afs_PutVCache(tvc, WRITE_LOCK);
if (tvolp) afs_PutVolume(tvolp, WRITE_LOCK);
goto done;
}
}
}
*avcp = tvc;
- if (tvc && !tvc->vrefCount) {
+ if (tvc && !VREFCOUNT(tvc)) {
osi_Panic("TT3");
}
code = 0;