}
static void
-FlushAllVCBs(struct rx_connection **rxconns, int nconns, int nservers,
- struct afs_conn **conns, struct srvAddr **addrs)
+FlushAllVCBs(int nconns, struct rx_connection **rxconns,
+ struct afs_conn **conns)
{
afs_int32 *results;
afs_int32 i;
- results = afs_osi_Alloc(nservers * sizeof (afs_int32));
+ results = afs_osi_Alloc(nconns * sizeof (afs_int32));
osi_Assert(results != NULL);
AFS_GUNLOCK();
for ( i = 0 ; i < nconns ; i++ ) {
if (results[i] == 0) {
/* Unchain all of them */
- while (addrs[i]->server->cbrs)
- afs_FreeCBR(addrs[i]->server->cbrs);
+ while (conns[i]->parent->srvr->server->cbrs)
+ afs_FreeCBR(conns[i]->parent->srvr->server->cbrs);
}
}
- afs_osi_Free(results, nservers * sizeof(afs_int32));
+ afs_osi_Free(results, nconns * sizeof(afs_int32));
}
/*!
for (safety3 = 0; safety3 < AFS_MAXHOSTS * 2; safety3++) {
tc = afs_ConnByHost(tsp, tsp->cell->fsport,
tsp->cell->cellNum, &treq, 0,
- SHARED_LOCK, &rxconn);
+ SHARED_LOCK, 0, &rxconn);
if (tc) {
XSTATS_START_TIME
(AFS_STATS_FS_RPCIDX_GIVEUPCALLBACKS);
struct AFSFetchStatus *astat, struct vrequest *areq)
{
afs_size_t length;
-#ifdef AFS_DARWIN80_ENV
- int fixup = 0;
-#endif
AFS_STATCNT(afs_ProcessFS);
#ifdef AFS_64BIT_CLIENT
avc->f.m.Group = astat->Group;
avc->f.m.LinkCount = astat->LinkCount;
if (astat->FileType == File) {
-#ifdef AFS_DARWIN80_ENV
- if (avc->f.m.Type != VREG)
- fixup = 1;
-#endif
vSetType(avc, VREG);
avc->f.m.Mode |= S_IFREG;
} else if (astat->FileType == Directory) {
-#ifdef AFS_DARWIN80_ENV
- if (avc->f.m.Type != VDIR)
- fixup = 1;
-#endif
vSetType(avc, VDIR);
avc->f.m.Mode |= S_IFDIR;
} else if (astat->FileType == SymbolicLink) {
if (afs_fakestat_enable && (avc->f.m.Mode & 0111) == 0) {
-#ifdef AFS_DARWIN80_ENV
- if (avc->f.m.Type != VDIR)
- fixup = 1;
-#endif
vSetType(avc, VDIR);
avc->f.m.Mode |= S_IFDIR;
} else {
-#ifdef AFS_DARWIN80_ENV
- if (avc->f.m.Type != VLNK)
- fixup = 1;
-#endif
vSetType(avc, VLNK);
avc->f.m.Mode |= S_IFLNK;
}
avc->mvstat = 1;
}
}
-#ifdef AFS_DARWIN80_ENV
- if (fixup) {
- /* perform type correction on underlying vnode */
- afs_darwin_finalizevnode(avc, NULL, NULL, 0, 1);
- /* re-acquire the usecount that finalizevnode disposed of */
- vnode_ref(AFSTOV(avc));
- }
-#endif
avc->f.anyAccess = astat->AnonymousAccess;
#ifdef badidea
if ((astat->CallerAccess & ~astat->AnonymousAccess))
afs_PutVolume(volp, READ_LOCK);
}
+void
+afs_BadFetchStatus(struct afs_conn *tc)
+{
+ int addr = ntohl(tc->parent->srvr->sa_ip);
+ afs_warn("afs: Invalid AFSFetchStatus from server %u.%u.%u.%u\n",
+ (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff,
+ (addr) & 0xff);
+ afs_warn("afs: This suggests the server may be sending bad data that "
+ "can lead to availability issues or data corruption. The "
+ "issue has been avoided for now, but it may not always be "
+ "detectable. Please upgrade the server if possible.\n");
+}
+
+/**
+ * Check if a given AFSFetchStatus structure is sane.
+ *
+ * @param[in] tc The server from which we received the status
+ * @param[in] status The status we received
+ *
+ * @return whether the given structure is valid or not
+ * @retval 0 the structure is fine
+ * @retval nonzero the structure looks like garbage; act as if we received
+ * the returned error code from the server
+ */
+int
+afs_CheckFetchStatus(struct afs_conn *tc, struct AFSFetchStatus *status)
+{
+ if (status->errorCode ||
+ status->InterfaceVersion != 1 ||
+ !(status->FileType > Invalid && status->FileType <= SymbolicLink) ||
+ status->ParentVnode == 0 || status->ParentUnique == 0) {
+
+ afs_warn("afs: FetchStatus ec %u iv %u ft %u pv %u pu %u\n",
+ (unsigned)status->errorCode, (unsigned)status->InterfaceVersion,
+ (unsigned)status->FileType, (unsigned)status->ParentVnode,
+ (unsigned)status->ParentUnique);
+ afs_BadFetchStatus(tc);
+
+ return VBUSY;
+ }
+ return 0;
+}
+
/*!
* Must be called with avc write-locked
* don't absolutely have to invalidate the hint unless the dv has
XSTATS_END_TIME;
+ if (code == 0) {
+ code = afs_CheckFetchStatus(tc, Outsp);
+ }
+
} else
code = -1;
} while (afs_Analyze