* afs_index
*/
-#include "../afs/param.h" /* Should be always first */
+#include <afsconfig.h>
+#include "../afs/param.h"
+
+RCSID("$Header$");
+
#include "../afs/sysincludes.h" /* Standard vendor system headers */
#include "../afs/afsincludes.h" /* Afs-based standard headers */
#include "../afs/afs_stats.h" /* statistics */
volnamep = &avc->linkData[1];
tcell = afs_GetCell(avc->fid.Cell, READ_LOCK);
}
- if (!tcell) return ENOENT;
+ if (!tcell) return ENODEV;
mtptCell = tcell->cell; /* The cell for the mountpoint */
if (tcell->lcellp) {
* CForeign bit set.
*/
struct vcache * BStvc = (struct vcache *) 0;
-void afs_DoBulkStat(adp, dirCookie, areqp)
+int afs_DoBulkStat(adp, dirCookie, areqp)
struct vcache *adp;
long dirCookie;
struct vrequest *areqp;
struct volume *volp=0; /* volume ptr */
struct VenusFid dotdot;
int flagIndex; /* First file with bulk fetch flag set */
+ int inlinebulk=0; /* Did we use InlineBulk RPC or not? */
XSTATS_DECLS
/* first compute some basic parameters. We dont want to prefetch more
* preserve the value of the file size. We could
* flush the pages, but it wouldn't be worthwhile.
*/
- bcopy((char *) &tfid.Fid, (char *)(fidsp+fidIndex),
- sizeof(*fidsp));
+ memcpy((char *)(fidsp+fidIndex), (char *) &tfid.Fid, sizeof(*fidsp));
tvcp->states |= CBulkFetching;
tvcp->m.Length = statSeqNo;
fidIndex++;
#ifdef RX_ENABLE_LOCKS
AFS_GUNLOCK();
#endif /* RX_ENABLE_LOCKS */
- code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm,
- &volSync);
+ code = RXAFS_InlineBulkStatus(tcp->id, &fidParm, &statParm,
+ &cbParm, &volSync);
+ if (code == RXGEN_OPCODE) {
+ code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm,
+ &volSync);
+ inlinebulk=0;
+ } else {
+ inlinebulk=1;
+ }
+
#ifdef RX_ENABLE_LOCKS
AFS_GLOCK();
#endif /* RX_ENABLE_LOCKS */
* We also have to take into account racing token revocations.
*/
for(i=0; i<fidIndex; i++) {
+ if ((&statsp[i])->errorCode)
+ continue;
afid.Cell = adp->fid.Cell;
afid.Fid.Volume = adp->fid.Fid.Volume;
afid.Fid.Vnode = fidsp[i].Vnode;
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;
+ }
osi_FreeLargeSpace(statMemp);
osi_FreeLargeSpace(cbfMemp);
+ return code;
}
/* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */
int flags;
struct vnode *rdir;
#else
+#if defined(UKERNEL)
+afs_lookup(adp, aname, avcp, acred, flags)
+ int flags;
+#else
afs_lookup(adp, aname, avcp, acred)
-#endif
+#endif /* UKERNEL */
+#endif /* SUN5 || SGI */
OSI_VC_DECL(adp);
struct vcache **avcp;
char *aname;
char *tname = (char *)0;
register struct vcache *tvc=0;
register afs_int32 code;
+ register afs_int32 bulkcode = 0;
int pass = 0, hit = 0;
long dirCookie;
extern afs_int32 afs_mariner; /*Writing activity to log?*/
AFS_STATCNT(afs_lookup);
#ifdef AFS_OSF_ENV
ndp->ni_dvp = (struct vnode *)adp;
- bcopy(ndp->ni_ptr, aname, ndp->ni_namelen);
+ memcpy(aname, ndp->ni_ptr, ndp->ni_namelen);
aname[ndp->ni_namelen] = '\0';
#endif /* AFS_OSF_ENV */
*avcp = (struct vcache *) 0; /* Since some callers don't initialize it */
if (code = afs_InitReq(&treq, acred)) {
- goto done;
+ goto done;
}
/* come back to here if we encounter a non-existent object in a read-only
redo:
*avcp = (struct vcache *) 0; /* Since some callers don't initialize it */
+ bulkcode = 0;
if (!(adp->states & CStatd)) {
- if (code = afs_VerifyVCache2(adp, &treq))
- goto done;
+ if (code = afs_VerifyVCache2(adp, &treq)) {
+ goto done;
+ }
}
else code = 0;
ObtainReadLock(&afs_xvcache);
osi_vnhold(adp, 0);
ReleaseReadLock(&afs_xvcache);
- code = 0;
- *avcp = tvc = adp;
- hit = 1;
+ code = 0;
+ *avcp = tvc = adp;
+ hit = 1;
if (adp && !adp->vrefCount) {
osi_Panic("TT2");
}
- goto done;
+ goto done;
}
Check_AtSys(adp, aname, &sysState, &treq);
tvc = osi_dnlc_lookup (adp, tname, WRITE_LOCK);
*avcp = tvc; /* maybe wasn't initialized, but it is now */
if (tvc) {
- if (no_read_access && vType(tvc) != VDIR) {
- /* need read access on dir to stat non-directory */
+ if (no_read_access && vType(tvc) != VDIR && vType(tvc) != VLNK) {
+ /* need read access on dir to stat non-directory / non-link */
afs_PutVCache(tvc, WRITE_LOCK);
*avcp = (struct vcache *)0;
code = EACCES;
ReleaseReadLock(&afs_xvcache);
} while (tvc && retry);
- if (!tvc || !(tvc->states & CStatd)) {
- afs_DoBulkStat(adp, dirCookie, &treq);
- }
+ if (!tvc || !(tvc->states & CStatd))
+ bulkcode = afs_DoBulkStat(adp, dirCookie, &treq);
+ else
+ bulkcode = 0;
/* if the vcache isn't usable, release it */
if (tvc && !(tvc->states & CStatd)) {
afs_PutVCache(tvc);
tvc = (struct vcache *) 0;
}
+ } else {
+ tvc = (struct vcache *) 0;
+ bulkcode = 0;
}
- else tvc = (struct vcache *) 0;
-
+
/* now get the status info, if we don't already have it */
/* This is kind of weird, but we might wind up accidentally calling
* RXAFS_Lookup because we happened upon a file which legitimately
* has a 0 uniquifier. That is the result of allowing unique to wrap
- * to 0. This was fixed in AFS 3.4. For CForeigh, Unique == 0 means that
+ * to 0. This was fixed in AFS 3.4. For CForeign, Unique == 0 means that
* the file has not yet been looked up.
*/
if (!tvc) {
tvc = afs_LookupVCache(&tfid, &treq, &cached, WRITE_LOCK,
adp, tname);
}
- if (!tvc) { /* lookup failed or wasn't called */
- tvc = afs_GetVCache(&tfid, &treq, &cached, (struct vcache*)0,
- WRITE_LOCK);
- }
+ if (!tvc && !bulkcode) { /* lookup failed or wasn't called */
+ tvc = afs_GetVCache(&tfid, &treq, &cached, (struct vcache*)0,
+ WRITE_LOCK);
+ }
} /* if !tvc */
} /* sub-block just to reduce stack usage */
tvc->parentVnode = adp->fid.Fid.Vnode;
tvc->parentUnique = adp->fid.Fid.Unique;
tvc->states &= ~CBulkStat;
+
+#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+ if (!(flags & AFS_LOOKUP_NOEVAL))
+ /* don't eval mount points */
+#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
if (tvc->mvstat == 1) {
/* a mt point, possibly unevaluated */
struct volume *tvolp;
ReleaseWriteLock(&tvc->lock);
if (code) {
+ afs_PutVCache(tvc, WRITE_LOCK);
if (tvolp) afs_PutVolume(tvolp, WRITE_LOCK);
goto done;
}
if (afs_mariner)
afs_AddMarinerName(aname, tvc);
+
+#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+ if (!(flags & AFS_LOOKUP_NOEVAL))
+ /* Here we don't enter the name into the DNLC because we want the
+ evaluated mount dir to be there (the vcache for the mounted volume)
+ rather than the vc of the mount point itself. we can still find the
+ mount point's vc in the vcache by its fid. */
+#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
if (!hit) {
osi_dnlc_enter (adp, aname, tvc, &versionNo);
}
#endif
}
}
+ if (bulkcode) code = bulkcode; else
code = afs_CheckCode(code, &treq, 19);
if (code) {
/* If there is an error, make sure *avcp is null.