/* Start by figuring out and finding the cell */
cpos = afs_strchr(data, ':'); /* if cell name present */
if (cpos) {
+ afs_uint32 mtptCellnum;
volnamep = cpos + 1;
*cpos = 0;
- if ((afs_strtoi_r(data, &endptr, &cellnum) == 0) &&
- (endptr == cpos))
- tcell = afs_GetCell(cellnum, READ_LOCK);
- else {
+ if ((afs_strtoi_r(data, &endptr, &mtptCellnum) == 0) &&
+ (endptr == cpos)) {
+ tcell = afs_GetCell(mtptCellnum, READ_LOCK);
+ } else {
tcell = afs_GetCellByName(data, READ_LOCK);
- cellnum = 0;
}
*cpos = ':';
} else if (cellnum) {
* Don't know why we do this. Would have still found it in above call - jpm.
*/
if (!tvp && (prefetch == 2) && len < AFS_SMALLOCSIZ - 10) {
- buf = (char *)osi_AllocSmallSpace(len + 10);
+ buf = osi_AllocSmallSpace(len + 10);
strcpy(buf, volnamep);
afs_strcat(buf, ".readonly");
auniq = 1;
if (avc->mvid == 0)
- avc->mvid =
- (struct VenusFid *)osi_AllocSmallSpace(sizeof(struct VenusFid));
+ avc->mvid = osi_AllocSmallSpace(sizeof(struct VenusFid));
avc->mvid->Cell = (*avolpp)->cell;
avc->mvid->Fid.Volume = (*avolpp)->volume;
avc->mvid->Fid.Vnode = avnoid;
if (AFS_EQ_ATSYS(aname)) {
state->offset = 0;
- state->name = (char *)osi_AllocLargeSpace(MAXSYSNAME);
+ state->name = osi_AllocLargeSpace(MAXSYSNAME);
state->allocked = 1;
state->index =
afs_getsysname(areq, avc, state->name, &num, sysnamelist);
if ((tname > state->name + 4) && (AFS_EQ_ATSYS(tname - 4))) {
state->offset = (tname - 4) - state->name;
- tname = (char *)osi_AllocLargeSpace(AFS_LRALLOCSIZ);
+ tname = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
strncpy(tname, state->name, state->offset);
state->name = tname;
state->allocked = 1;
return 1;
}
+static int
+afs_CheckBulkStatus(struct afs_conn *tc, int nFids, AFSBulkStats *statParm,
+ AFSCBs *cbParm)
+{
+ int i;
+ int code;
+
+ if (statParm->AFSBulkStats_len != nFids || cbParm->AFSCBs_len != nFids) {
+ afs_warn("afs: BulkFetchStatus length %u/%u, expected %u\n",
+ (unsigned)statParm->AFSBulkStats_len,
+ (unsigned)cbParm->AFSCBs_len, nFids);
+ afs_BadFetchStatus(tc);
+ return VBUSY;
+ }
+ for (i = 0; i < nFids; i++) {
+ if (statParm->AFSBulkStats_val[i].errorCode) {
+ continue;
+ }
+ code = afs_CheckFetchStatus(tc, &statParm->AFSBulkStats_val[i]);
+ if (code) {
+ return code;
+ }
+ }
+
+ return 0;
+}
+
extern int BlobScan(struct dcache * afile, afs_int32 ablob);
/* called with an unlocked directory and directory cookie. Areqp
afs_size_t statSeqNo = 0; /* Valued of file size to detect races */
int code; /* error code */
long newIndex; /* new index in the dir */
+ struct DirBuffer entry; /* Buffer for dir manipulation */
struct DirEntry *dirEntryp; /* dir entry we are examining */
int i;
struct VenusFid afid; /* file ID we are using now */
struct volume *volp = 0; /* volume ptr */
struct VenusFid dotdot = {0, {0, 0, 0}};
int flagIndex = 0; /* First file with bulk fetch flag set */
- int inlinebulk = 0; /* Did we use InlineBulk RPC or not? */
struct rx_connection *rxconn;
XSTATS_DECLS;
dotdot.Cell = 0;
* one for fids and callbacks, and one for stat info. Well set
* up our pointers to the memory from there, too.
*/
- statsp = (AFSFetchStatus *)
- osi_Alloc(AFSCBMAX * sizeof(AFSFetchStatus));
- fidsp = (AFSFid *) osi_AllocLargeSpace(nentries * sizeof(AFSFid));
- cbsp = (AFSCallBack *)
- osi_Alloc(AFSCBMAX * sizeof(AFSCallBack));
+ statsp = osi_Alloc(AFSCBMAX * sizeof(AFSFetchStatus));
+ fidsp = osi_AllocLargeSpace(nentries * sizeof(AFSFid));
+ cbsp = osi_Alloc(AFSCBMAX * sizeof(AFSCallBack));
/* next, we must iterate over the directory, starting from the specified
* cookie offset (dirCookie), and counting out nentries file entries.
dirCookie = newIndex << 5;
/* get a ptr to the dir entry */
- dirEntryp =
- (struct DirEntry *)afs_dir_GetBlob(dcp, newIndex);
- if (!dirEntryp)
+ code = afs_dir_GetBlob(dcp, newIndex, &entry);
+ if (code)
break;
+ dirEntryp = (struct DirEntry *)entry.data;
/* dont copy more than we have room for */
if (fidIndex >= nentries) {
- DRelease(dirEntryp, 0);
+ DRelease(&entry, 0);
break;
}
}
if (!tvcp)
{
- DRelease(dirEntryp, 0);
+ DRelease(&entry, 0);
ReleaseReadLock(&dcp->lock);
ReleaseReadLock(&adp->lock);
afs_PutDCache(dcp);
* used by this dir entry.
*/
temp = afs_dir_NameBlobs(dirEntryp->name) << 5;
- DRelease(dirEntryp, 0);
+ DRelease(&entry, 0);
if (temp <= 0)
break;
dirCookie += temp;
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_BULKSTATUS);
if (!(tcp->parent->srvr->server->flags & SNO_INLINEBULK)) {
- retryonce:
RX_AFS_GUNLOCK();
code =
RXAFS_InlineBulkStatus(rxconn, &fidParm, &statParm,
RX_AFS_GLOCK();
if (code == RXGEN_OPCODE) {
tcp->parent->srvr->server->flags |= SNO_INLINEBULK;
- inlinebulk = 0;
RX_AFS_GUNLOCK();
code =
RXAFS_BulkStatus(rxconn, &fidParm, &statParm,
&cbParm, &volSync);
RX_AFS_GLOCK();
- } else {
- inlinebulk = 1;
- if (!code && ((&statsp[0])->errorCode)) {
- /*
- * If this is an error needing retry, do so.
- * Retryable errors are all whole-volume or
- * whole-server.
- */
- if (afs_Analyze(tcp, rxconn, (&statsp[0])->errorCode,
- &adp->f.fid, areqp,
- AFS_STATS_FS_RPCIDX_BULKSTATUS,
- SHARED_LOCK, NULL) != 0)
- goto retryonce;
- }
+ } else if (!code) {
+ /* The InlineBulkStatus call itself succeeded, but we
+ * may have failed to stat the first entry. Use the error
+ * from the first entry for processing. */
+ code = (&statsp[0])->errorCode;
}
} else {
- inlinebulk = 0;
RX_AFS_GUNLOCK();
code =
RXAFS_BulkStatus(rxconn, &fidParm, &statParm, &cbParm,
RX_AFS_GLOCK();
}
XSTATS_END_TIME;
+
+ if (code == 0) {
+ code = afs_CheckBulkStatus(tcp, fidIndex, &statParm, &cbParm);
+ }
} else
code = -1;
} while (afs_Analyze
/* now copy ".." entry back out of volume structure, if necessary */
if (tvcp->mvstat == 2 && (dotdot.Fid.Volume != 0)) {
if (!tvcp->mvid)
- tvcp->mvid = (struct VenusFid *)
- osi_AllocSmallSpace(sizeof(struct VenusFid));
+ tvcp->mvid = osi_AllocSmallSpace(sizeof(struct VenusFid));
*tvcp->mvid = dotdot;
}
if (volp)
afs_PutVolume(volp, READ_LOCK);
- /* If we did the InlineBulk RPC pull out the return code */
- if (inlinebulk && code == 0) {
- if ((&statsp[0])->errorCode) {
- afs_Analyze(tcp, rxconn, (&statsp[0])->errorCode, &adp->f.fid, areqp,
- AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK, NULL);
- code = (&statsp[0])->errorCode;
- }
- } else {
- code = 0;
- }
done2:
osi_FreeLargeSpace((char *)fidsp);
osi_Free((char *)statsp, AFSCBMAX * sizeof(AFSFetchStatus));
}
/* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */
+#ifdef AFS_DARWIN80_ENV
+int AFSDOBULK = 0;
+#else
static int AFSDOBULK = 1;
+#endif
static_inline int
osi_lookup_isdot(const char *aname)
if (tvc->mvstat == 1 && (tvc->f.states & CMValid) && tvc->mvid != NULL)
force_eval = 1; /* This is now almost for free, get it correct */
-#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+#if defined(UKERNEL)
if (!(flags & AFS_LOOKUP_NOEVAL))
/* don't eval mount points */
-#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
+#endif /* UKERNEL */
if (tvc->mvstat == 1 && force_eval) {
/* a mt point, possibly unevaluated */
struct volume *tvolp;
if (tvolp) {
ObtainWriteLock(&tvc->lock, 134);
if (tvc->mvid == NULL) {
- tvc->mvid = (struct VenusFid *)
+ tvc->mvid =
osi_AllocSmallSpace(sizeof(struct VenusFid));
}
/* setup backpointer */
if (afs_mariner)
afs_AddMarinerName(aname, tvc);
-#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+#if defined(UKERNEL)
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 && force_eval) {
+#endif /* UKERNEL */
+ if (!hit && (force_eval || tvc->mvstat != 1)) {
osi_dnlc_enter(adp, aname, tvc, &versionNo);
} else {
#ifdef AFS_LINUX20_ENV
return 0; /* can't have been any errors if hit and !code */
#endif
}
-#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+#if defined(UKERNEL)
}
#endif
}