struct volume *tvp = 0;
struct VenusFid tfid;
struct cell *tcell;
- char *cpos, *volnamep;
+ char *cpos, *volnamep = NULL;
char *buf, *endptr;
afs_int32 prefetch; /* 1=>None 2=>RO 3=>BK */
afs_int32 mtptCell, assocCell = 0, hac = 0;
* in the dynamic mount directory.
*/
if (volid && !avolpp) {
- if (*cpos)
+ if (cpos)
*cpos = ':';
goto done;
}
if (!afs_nfsexporter)
strcpy(bufp, (*sysnamelist)[0]);
else {
- au = afs_GetUser(areq->uid, adp->f.fid.Cell, 0);
+ au = afs_GetUser(areq->uid, adp->f.fid.Cell, READ_LOCK);
if (au->exporter) {
error = EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, num, 0);
if (error) {
strcpy(bufp, "@sys");
- afs_PutUser(au, 0);
+ afs_PutUser(au, READ_LOCK);
return -1;
} else {
strcpy(bufp, (*sysnamelist)[0]);
}
} else
strcpy(bufp, afs_sysname);
- afs_PutUser(au, 0);
+ afs_PutUser(au, READ_LOCK);
}
return 0;
}
*sysnamelist = afs_sysnamelist;
if (afs_nfsexporter) {
- au = afs_GetUser(areq->uid, avc->f.fid.Cell, 0);
+ au = afs_GetUser(areq->uid, avc->f.fid.Cell, READ_LOCK);
if (au->exporter) {
error =
EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, &num, 0);
if (error) {
- afs_PutUser(au, 0);
+ afs_PutUser(au, READ_LOCK);
return 0;
}
}
- afs_PutUser(au, 0);
+ afs_PutUser(au, READ_LOCK);
}
if (++(state->index) >= num || !(*sysnamelist)[(unsigned int)state->index])
return 0; /* end of list */
long startTime; /* time we started the call,
* for callback expiration base
*/
+ int ftype[4] = {VNON, VREG, VDIR, VLNK}; /* verify type is as expected */
afs_size_t statSeqNo = 0; /* Valued of file size to detect races */
int code; /* error code */
long newIndex; /* new index in the dir */
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;
dotdot.Fid.Unique = 0;
tvcp = afs_NewBulkVCache(&tfid, hostp, statSeqNo);
if (tvcp)
{
- ObtainWriteLock(&tvcp->lock, 505);
- ReleaseWriteLock(&afs_xvcache);
- afs_RemoveVCB(&tfid);
- ReleaseWriteLock(&tvcp->lock);
+ ObtainWriteLock(&tvcp->lock, 505);
+#ifdef AFS_DARWIN80_ENV
+ /* use even/odd hack to guess file versus dir.
+ let links be reaped. oh well. */
+ if (dirEntryp->fid.vnode & 1)
+ tvcp->f.m.Type = VDIR;
+ else
+ tvcp->f.m.Type = VREG;
+ /* finalize to a best guess */
+ afs_darwin_finalizevnode(tvcp, VTOAFS(adp), NULL, 0, 1);
+ /* re-acquire usecount that finalizevnode disposed of */
+ vnode_ref(AFSTOV(tvcp));
+#endif
+ ReleaseWriteLock(&afs_xvcache);
+ afs_RemoveVCB(&tfid);
+ ReleaseWriteLock(&tvcp->lock);
} else {
- ReleaseWriteLock(&afs_xvcache);
+ ReleaseWriteLock(&afs_xvcache);
}
} else {
ReleaseWriteLock(&afs_xvcache);
/* start the timer; callback expirations are relative to this */
startTime = osi_Time();
- tcp = afs_Conn(&adp->f.fid, areqp, SHARED_LOCK);
+ tcp = afs_Conn(&adp->f.fid, areqp, SHARED_LOCK, &rxconn);
if (tcp) {
- hostp = tcp->srvr->server;
+ hostp = tcp->parent->srvr->server;
+
+ for (i = 0; i < fidIndex; i++) {
+ /* we must set tvcp->callback before the BulkStatus call, so
+ * we can detect concurrent InitCallBackState's */
+
+ afid.Cell = adp->f.fid.Cell;
+ afid.Fid.Volume = adp->f.fid.Fid.Volume;
+ afid.Fid.Vnode = fidsp[i].Vnode;
+ afid.Fid.Unique = fidsp[i].Unique;
+
+ do {
+ retry = 0;
+ ObtainReadLock(&afs_xvcache);
+ tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */);
+ ReleaseReadLock(&afs_xvcache);
+ } while (tvcp && retry);
+
+ if (!tvcp) {
+ continue;
+ }
+
+ if ((tvcp->f.states & CBulkFetching) &&
+ (tvcp->f.m.Length == statSeqNo)) {
+ tvcp->callback = hostp;
+ }
+
+ afs_PutVCache(tvcp);
+ tvcp = NULL;
+ }
+
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_BULKSTATUS);
- RX_AFS_GUNLOCK();
- if (!(tcp->srvr->server->flags & SNO_INLINEBULK)) {
+ if (!(tcp->parent->srvr->server->flags & SNO_INLINEBULK)) {
retryonce:
+ RX_AFS_GUNLOCK();
code =
- RXAFS_InlineBulkStatus(tcp->id, &fidParm, &statParm,
+ RXAFS_InlineBulkStatus(rxconn, &fidParm, &statParm,
&cbParm, &volSync);
+ RX_AFS_GLOCK();
if (code == RXGEN_OPCODE) {
- tcp->srvr->server->flags |= SNO_INLINEBULK;
+ tcp->parent->srvr->server->flags |= SNO_INLINEBULK;
inlinebulk = 0;
+ RX_AFS_GUNLOCK();
code =
- RXAFS_BulkStatus(tcp->id, &fidParm, &statParm,
+ RXAFS_BulkStatus(rxconn, &fidParm, &statParm,
&cbParm, &volSync);
+ RX_AFS_GLOCK();
} else {
inlinebulk = 1;
if (!code && ((&statsp[0])->errorCode)) {
* Retryable errors are all whole-volume or
* whole-server.
*/
- if (afs_Analyze(tcp, (&statsp[0])->errorCode,
+ if (afs_Analyze(tcp, rxconn, (&statsp[0])->errorCode,
&adp->f.fid, areqp,
AFS_STATS_FS_RPCIDX_BULKSTATUS,
SHARED_LOCK, NULL) != 0)
}
} else {
inlinebulk = 0;
+ RX_AFS_GUNLOCK();
code =
- RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm,
+ RXAFS_BulkStatus(rxconn, &fidParm, &statParm, &cbParm,
&volSync);
+ RX_AFS_GLOCK();
}
- RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tcp, code, &adp->f.fid, areqp, AFS_STATS_FS_RPCIDX_BULKSTATUS,
+ (tcp, rxconn, code, &adp->f.fid, areqp, AFS_STATS_FS_RPCIDX_BULKSTATUS,
SHARED_LOCK, NULL));
/* now, if we didnt get the info, bail out. */
do {
retry = 0;
ObtainReadLock(&afs_xvcache);
- tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
+ tvcp = afs_FindVCache(&afid, &retry, 0/* !stats&!lru */);
ReleaseReadLock(&afs_xvcache);
} while (tvcp && retry);
* matches the value we placed there when we set the CBulkFetching
* flag, then someone else has done something with this node,
* and we may not have the latest status information for this
- * file. Leave the entry alone.
+ * file. Leave the entry alone. There's also a file type
+ * change here, for OSX bulkstat support.
*/
- if (!(tvcp->f.states & CBulkFetching) || (tvcp->f.m.Length != statSeqNo)) {
+ if (!(tvcp->f.states & CBulkFetching)
+ || (tvcp->f.m.Length != statSeqNo)
+ || (ftype[(&statsp[i])->FileType] != vType(tvcp))) {
flagIndex++;
ReleaseWriteLock(&tvcp->lock);
afs_PutVCache(tvcp);
afs_DequeueCallback(tvcp);
if ((tvcp->f.states & CForeign) || (vType(tvcp) == VDIR))
osi_dnlc_purgedp(tvcp); /* if it (could be) a directory */
- } else {
+ } else
/* re-acquire the usecount that finalizevnode disposed of */
vnode_ref(AFSTOV(tvcp));
- }
} else
#endif
ReleaseWriteLock(&afs_xcbhash);
do {
retry = 0;
ObtainReadLock(&afs_xvcache);
- tvcp = afs_FindVCache(&afid, &retry, FIND_CDEAD /* !stats&!lru */);
+ tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */);
ReleaseReadLock(&afs_xvcache);
} while (tvcp && retry);
if (tvcp != NULL) {
/* If we did the InlineBulk RPC pull out the return code */
if (inlinebulk && code == 0) {
if ((&statsp[0])->errorCode) {
- afs_Analyze(tcp, (&statsp[0])->errorCode, &adp->f.fid, areqp,
+ afs_Analyze(tcp, rxconn, (&statsp[0])->errorCode, &adp->f.fid, areqp,
AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK, NULL);
code = (&statsp[0])->errorCode;
}
}
/* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */
+#ifdef AFS_DARWIN80_ENV
+int AFSDOBULK = 1;
+#else
static int AFSDOBULK = 1;
+#endif
static_inline int
osi_lookup_isdot(const char *aname)