do {
tc = afs_Conn(&adp->f.fid, &treq, SHARED_LOCK);
if (tc) {
- hostp = tc->srvr->server; /* remember for callback processing */
+ hostp = tc->parent->srvr->server; /* remember for callback processing */
now = osi_Time();
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_CREATEFILE);
RX_AFS_GUNLOCK();
tcp = afs_Conn(&adp->f.fid, areqp, SHARED_LOCK);
if (tcp) {
- hostp = tcp->srvr->server;
+ hostp = tcp->parent->srvr->server;
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_BULKSTATUS);
- if (!(tcp->srvr->server->flags & SNO_INLINEBULK)) {
+ if (!(tcp->parent->srvr->server->flags & SNO_INLINEBULK)) {
retryonce:
RX_AFS_GUNLOCK();
code =
&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 =
do {
tc = afs_Conn(&adp->f.fid, &treq, SHARED_LOCK);
if (tc) {
- hostp = tc->srvr->server;
+ hostp = tc->parent->srvr->server;
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SYMLINK);
if (adp->f.states & CForeign) {
now = osi_Time();
void *cellinfo; /* pointer to cell info (PAG manager only) */
};
+#define CVEC_LEN 3 /* per-user connection pool */
+
+struct sa_conn_vector;
+typedef struct sa_conn_vector * p_sa_conn_vector; /* forward decl */
+
struct afs_conn {
- /* Per-connection block. */
- struct afs_conn *next; /* Next dude same server. */
+ int refCount;
+ int activated;
+ char forceConnectFS; /* Should we try again with these tokens? */
+ struct rx_connection *id; /* RPC connid */
+ struct sa_conn_vector *parent; /* the con_vector which contains us */
+};
+
+/* An sa_conn_vector replaces the erstwhile list of conn
+ structures maintained by the cache manager. The sa_conn_vector
+ contains a C array of connections which, if non-zero, represent
+ connections to AFS servers.
+*/
+
+struct sa_conn_vector {
+ /* linked-list machinery */
+ struct sa_conn_vector *next;
+
+ /* AFS conn-identifying info */
struct unixuser *user; /* user validated with respect to. */
- struct rx_connection *id; /* RPC connid. */
struct srvAddr *srvr; /* server associated with this conn */
short refCount; /* reference count for allocation */
unsigned short port; /* port associated with this connection */
- char forceConnectFS; /* Should we try again with these tokens? */
-};
+ /* next connection to return when all in cvec are fully utilized */
+ int select_index;
+
+ /* connections vector */
+ struct afs_conn cvec[CVEC_LEN];
+};
#define SQNULL -1
#define SRVADDR_MH 1
#define SRVADDR_ISDOWN 0x20 /* same as SRVR_ISDOWN */
#define SRVADDR_NOUSE 0x40 /* Don't use this srvAddr */
+
struct srvAddr {
struct srvAddr *next_bkt; /* next item in hash bucket */
struct srvAddr *next_sa; /* another interface on same host */
struct server *server; /* back to parent */
- struct afs_conn *conns; /* All user connections to this server */
+ struct sa_conn_vector *conns; /* All user connections to this server */
afs_int32 sa_ip; /* Host addr in network byte order */
u_short sa_iprank; /* indiv ip address priority */
u_short sa_portal; /* port addr in network byte order */
#define SRV_CAPABILITIES(ts) \
{ if ( !(ts->flags & SCAPS_KNOWN)) afs_GetCapabilities(ts); ts->capabilities; }
-#define afs_serverSetNo64Bit(s) ((s)->srvr->server->flags |= SNO_64BIT)
-#define afs_serverHasNo64Bit(s) ((s)->srvr->server->flags & SNO_64BIT)
+#define afs_serverSetNo64Bit(s) (((struct sa_conn_vector*)(s)->parent)->srvr->server->flags |= SNO_64BIT)
+#define afs_serverHasNo64Bit(s) (((struct sa_conn_vector*)(s)->parent)->srvr->server->flags & SNO_64BIT)
struct server {
union {
#include <inet/ip.h>
#endif
-
/* shouldn't do it this way, but for now will do */
#ifndef ERROR_TABLE_BASE_U
#define ERROR_TABLE_BASE_U (5376L)
afs_ConnByMHosts(tcell->cellHosts, tcell->vlport, tcell->cellNum,
&treq, SHARED_LOCK);
if (tconn) {
- if (tconn->srvr->server->flags & SNO_LHOSTS) {
+ if ( tconn->parent->srvr->server->flags & SNO_LHOSTS) {
type = 0;
RX_AFS_GUNLOCK();
i = VL_GetEntryByNameO(tconn->id, bp, &v->tve);
RX_AFS_GLOCK();
- } else if (tconn->srvr->server->flags & SYES_LHOSTS) {
+ } else if (tconn->parent->srvr->server->flags & SYES_LHOSTS) {
type = 1;
RX_AFS_GUNLOCK();
i = VL_GetEntryByNameN(tconn->id, bp, &v->ntve);
RX_AFS_GUNLOCK();
i = VL_GetEntryByNameU(tconn->id, bp, &v->utve);
RX_AFS_GLOCK();
- if (!(tconn->srvr->server->flags & SVLSRV_UUID)) {
+ if (!(tconn->parent->srvr->server->flags & SVLSRV_UUID)) {
if (i == RXGEN_OPCODE) {
type = 1;
RX_AFS_GUNLOCK();
RX_AFS_GLOCK();
if (i == RXGEN_OPCODE) {
type = 0;
- tconn->srvr->server->flags |= SNO_LHOSTS;
+ tconn->parent->srvr->server->flags |= SNO_LHOSTS;
RX_AFS_GUNLOCK();
i = VL_GetEntryByNameO(tconn->id, bp, &v->tve);
RX_AFS_GLOCK();
} else if (!i)
- tconn->srvr->server->flags |= SYES_LHOSTS;
+ tconn->parent->srvr->server->flags |= SYES_LHOSTS;
} else if (!i)
- tconn->srvr->server->flags |= SVLSRV_UUID;
+ tconn->parent->srvr->server->flags |= SVLSRV_UUID;
}
lastcode = i;
}
return shouldRetry; /* should retry */
}
- if (!aconn || !aconn->srvr) {
+ if (!aconn || !aconn->parent->srvr) {
if (!areq->volumeError) {
if (aerrP)
(aerrP->err_Network)++;
}
/* Find server associated with this connection. */
- sa = aconn->srvr;
+ sa = aconn->parent->srvr;
tsp = sa->server;
address = ntohl(sa->sa_ip);
aconn->forceConnectFS = 1;
} else if (acode == RXKADEXPIRED) {
aconn->forceConnectFS = 0; /* don't check until new tokens set */
- aconn->user->states |= UTokensBad;
+ aconn->parent->user->states |= UTokensBad;
afs_NotifyUser(tu, UTokensDropped);
afs_warnuser
("afs: Tokens for user of AFS id %d for cell %s have expired (server %d.%d.%d.%d)\n",
- tu->viceId, aconn->srvr->server->cell->cellName,
+ tu->viceId, aconn->parent->srvr->server->cell->cellName,
(address >> 24), (address >> 16) & 0xff,
(address >> 8) & 0xff, (address) & 0xff);
} else {
if (serversleft) {
afs_warnuser
("afs: Tokens for user of AFS id %d for cell %s: rxkad error=%d (server %d.%d.%d.%d)\n",
- tu->viceId, aconn->srvr->server->cell->cellName, acode,
+ tu->viceId, aconn->parent->srvr->server->cell->cellName, acode,
(address >> 24), (address >> 16) & 0xff,
(address >> 8) & 0xff, (address) & 0xff);
shouldRetry = 1;
} else {
areq->tokenError = 0;
aconn->forceConnectFS = 0; /* don't check until new tokens set */
- aconn->user->states |= UTokensBad;
+ aconn->parent->user->states |= UTokensBad;
afs_NotifyUser(tu, UTokensDropped);
afs_warnuser
("afs: Tokens for user of AFS id %d for cell %s are discarded (rxkad error=%d, server %d.%d.%d.%d)\n",
- tu->viceId, aconn->srvr->server->cell->cellName, acode,
+ tu->viceId, aconn->parent->srvr->server->cell->cellName, acode,
(address >> 24), (address >> 16) & 0xff,
(address >> 8) & 0xff, (address) & 0xff);
}
aconn->forceConnectFS = 1;
} else if (acode == RXKADEXPIRED) {
aconn->forceConnectFS = 0; /* don't check until new tokens set */
- aconn->user->states |= UTokensBad;
+ aconn->parent->user->states |= UTokensBad;
afs_NotifyUser(tu, UTokensDropped);
afs_warnuser
("afs: Tokens for user %d for cell %s have expired (server %d.%d.%d.%d)\n",
- areq->uid, aconn->srvr->server->cell->cellName,
+ areq->uid, aconn->parent->srvr->server->cell->cellName,
(address >> 24), (address >> 16) & 0xff,
(address >> 8) & 0xff, (address) & 0xff);
} else {
aconn->forceConnectFS = 0; /* don't check until new tokens set */
- aconn->user->states |= UTokensBad;
+ aconn->parent->user->states |= UTokensBad;
afs_NotifyUser(tu, UTokensDropped);
afs_warnuser
("afs: Tokens for user %d for cell %s are discarded (rxkad error = %d, server %d.%d.%d.%d)\n",
- areq->uid, aconn->srvr->server->cell->cellName, acode,
+ areq->uid, aconn->parent->srvr->server->cell->cellName,
+ acode,
(address >> 24), (address >> 16) & 0xff,
(address >> 8) & 0xff, (address) & 0xff);
do {
tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK /* ignored */);
if (tc) {
- avc->callback = tc->srvr->server;
+ avc->callback = tc->parent->srvr->server;
i = osi_Time();
tcall = rx_NewCall(tc->id);
#ifdef AFS_64BIT_CLIENT
afs_rwlock_t afs_xinterface; /* for multiple client address */
afs_int32 cryptall = 0; /* encrypt all communications */
+/* some connection macros */
+
+/* a constructor */
+#define new_conn_vector(xcv) \
+do { \
+ xcv = (struct sa_conn_vector *) \
+ afs_osi_Alloc(sizeof(struct sa_conn_vector)); \
+ if (xcv) { \
+ memset((char *)xcv, 0, sizeof(struct sa_conn_vector)); \
+ } \
+} while (0);
+
+/* select a connection to return (if no connection has lower utilization
+ * than any other) */
+#define conn_vec_select_conn(xcv, bix, conn) \
+do { \
+ (bix) = ((xcv)->select_index)++ % CVEC_LEN; \
+ (conn) = &((xcv)->cvec[bix]); \
+} while (0);
+
+#define struct_conn(s) ((struct afs_conn *)(s))
+
+#define REPORT_CONNECTIONS_ISSUED 0 /* enable to see utilization */
+
+/**
+ * Find a connection with call slots available, allocating one
+ * if nothing is available and we find an allocated slot
+ * @param xcv A connection vector
+ * @param create If set, a new connection may be created
+ */
+static struct afs_conn *
+find_preferred_connection(struct sa_conn_vector *xcv, int create)
+{
+ afs_int32 cix, bix;
+ struct afs_conn *tc = NULL;
+
+ bix = -1;
+ for(cix = 0; cix < CVEC_LEN; ++cix) {
+ tc = &(xcv->cvec[cix]);
+ if (!tc->id) {
+ if (create) {
+ tc->parent = xcv;
+ tc->forceConnectFS = 1;
+ tc->activated = 1;
+ bix = cix;
+ break;
+ } /* create */
+ } else {
+ if (tc->refCount < (RX_MAXCALLS-1)) {
+ bix = cix;
+ goto f_conn;
+ } else if (cix == (CVEC_LEN-1))
+ conn_vec_select_conn(xcv, bix, tc);
+ } /* tc->id */
+ } /* for cix < CVEC_LEN */
+
+ if (bix < 0) {
+ afs_warn("find_preferred_connection: no connection and !create\n");
+ tc = NULL;
+ goto out;
+ }
+
+f_conn:
+ tc->refCount++;
+ xcv->refCount++;
+
+#if REPORT_CONNECTIONS_ISSUED
+ afs_warn("Issuing conn %d refCount=%d parent refCount=%d\n", bix,
+ tc->refCount, xcv->refCount);
+#endif
+
+out:
+ return (tc);
+
+} /* find_preferred_connection */
+
+
+/**
+ * Release all connections for unix user xu at server xs
+ * @param xu
+ * @param xs
+ */
+static void
+release_conns_user_server(struct unixuser *xu, struct server *xs)
+{
+ int cix, glocked;
+ struct srvAddr *sa;
+ struct afs_conn *tc;
+ struct sa_conn_vector *tcv, **lcv;
+ for (sa = (xs)->addr; sa; sa = sa->next_sa) {
+ lcv = &sa->conns;
+ for (tcv = *lcv; tcv; lcv = &tcv->next, tcv = *lcv) {
+ if (tcv->user == (xu) && tcv->refCount == 0) {
+ *lcv = tcv->next;
+ /* our old friend, the GLOCK */
+ glocked = ISAFS_GLOCK();
+ if (glocked)
+ AFS_GUNLOCK();
+ for(cix = 0; cix < CVEC_LEN; ++cix) {
+ tc = &(tcv->cvec[cix]);
+ if (tc->activated)
+ rx_DestroyConnection(tc->id);
+ }
+ if (glocked)
+ AFS_GLOCK();
+ afs_osi_Free(tcv, sizeof(struct sa_conn_vector));
+ break; /* at most one instance per server */
+ } /*Found unreferenced connection for user */
+ }
+ } /*For each connection on the server */
+
+} /* release_conns_user_server */
+
+
+static void
+release_conns_vector(struct sa_conn_vector *xcv)
+{
+ int cix, glocked;
+ struct afs_conn *tc;
+ struct sa_conn_vector *tcv = NULL;
+ struct sa_conn_vector **lcv = NULL;
+ for (tcv = xcv; tcv; lcv = &tcv->next, tcv = *lcv) {
+ *lcv = tcv->next;
+ /* you know it, you love it, the GLOCK */
+ glocked = ISAFS_GLOCK();
+ if (glocked)
+ AFS_GUNLOCK(); \
+ for(cix = 0; cix < CVEC_LEN; ++cix) {
+ tc = &(tcv->cvec[cix]);
+ if (tc->activated)
+ rx_DestroyConnection( tc->id );
+ }
+ if (glocked)
+ AFS_GLOCK();
+ afs_osi_Free(tcv, sizeof(struct sa_conn_vector));
+ }
+
+} /* release_conns_vector */
+
unsigned int VNOSERVERS = 0;
union tokenUnion *token;
/* Do we have tokens ? */
- if (conn->user->states & UHasTokens) {
- token = afs_FindToken(conn->user->tokens, RX_SECIDX_KAD);
+ if (conn->parent->user->states & UHasTokens) {
+ token = afs_FindToken(conn->parent->user->tokens, RX_SECIDX_KAD);
if (token) {
*secLevel = RX_SECIDX_KAD;
/* kerberos tickets on channel 2 */
token->rxkad.clearToken.AuthHandle,
token->rxkad.ticketLen, token->rxkad.ticket);
/* We're going to use this token, so populate the viced */
- conn->user->viceId = token->rxkad.clearToken.ViceId;
+ conn->parent->user->viceId = token->rxkad.clearToken.ViceId;
}
}
if (secObj == NULL) {
struct unixuser *tu, int force_if_down, afs_int32 create,
afs_int32 locktype)
{
- struct afs_conn *tc = 0;
- struct rx_securityClass *csec; /*Security class object */
- int isec; /*Security index */
+ int glocked, foundvec;
+ struct afs_conn *tc = NULL;
+ struct sa_conn_vector *tcv = NULL;
+ struct rx_securityClass *csec; /*Security class object */
+ int isec; /*Security index */
int service;
- if (!sap || ((sap->sa_flags & SRVR_ISDOWN) && !force_if_down)) {
- /* sa is known down, and we don't want to force it. */
- return NULL;
- }
-
+ /* find cached connection */
ObtainSharedLock(&afs_xconn, 15);
- /* Get conn by port and user. */
- for (tc = sap->conns; tc; tc = tc->next) {
- if (tc->user == tu && tc->port == aport) {
- break;
- }
+ foundvec = 0;
+ for (tcv = sap->conns; tcv; tcv = tcv->next) {
+ if (tcv->user == tu && tcv->port == aport) {
+ /* return most eligible conn */
+ if (!foundvec)
+ foundvec = 1;
+ UpgradeSToWLock(&afs_xconn, 37);
+ tc = find_preferred_connection(tcv, create);
+ ConvertWToSLock(&afs_xconn);
+ break;
+ }
}
if (!tc && !create) {
- /* Not found and can't create a new one. */
- ReleaseSharedLock(&afs_xconn);
- return NULL;
+ /* Not found and can't create a new one. */
+ ReleaseSharedLock(&afs_xconn);
+ return NULL;
}
if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) {
return NULL;
}
- if (!tc) {
- /* No such connection structure exists. Create one and splice it in.
+ if (!foundvec && create) {
+ /* No such connection vector exists. Create one and splice it in.
* Make sure the server record has been marked as used (for the purposes
* of calculating up & down times, it's now considered to be an
* ``active'' server). Also make sure the server's lastUpdateEvalTime
* gets set, marking the time of its ``birth''.
*/
UpgradeSToWLock(&afs_xconn, 37);
- tc = afs_osi_Alloc(sizeof(struct afs_conn));
- osi_Assert(tc != NULL);
- memset(tc, 0, sizeof(struct afs_conn));
-
- tc->user = tu;
- tc->port = aport;
- tc->srvr = sap;
- tc->refCount = 0; /* bumped below */
- tc->forceConnectFS = 1;
- tc->id = (struct rx_connection *)0;
- tc->next = sap->conns;
- sap->conns = tc;
+ new_conn_vector(tcv);
+
+ tcv->user = tu;
+ tcv->port = aport;
+ tcv->srvr = sap;
+ tcv->next = sap->conns;
+ sap->conns = tcv;
+
+ /* all struct afs_conn ptrs come from here */
+ tc = find_preferred_connection(tcv, create);
+
afs_ActivateServer(sap);
ConvertWToSLock(&afs_xconn);
- } /* end of if (!tc) */
- tc->refCount++;
+ } /* end of if (!tcv) */
+
+ if (!tc) {
+ /* Not found and no alternatives. */
+ ReleaseSharedLock(&afs_xconn);
+ return NULL;
+ }
if (tu->states & UTokensBad) {
/* we may still have an authenticated RPC connection here,
tu->states &= ~UHasTokens; /* remove the authentication info */
}
+ glocked = ISAFS_GLOCK();
if (tc->forceConnectFS) {
UpgradeSToWLock(&afs_xconn, 38);
csec = (struct rx_securityClass *)0;
if (tc->id) {
- AFS_GUNLOCK();
+ if (glocked)
+ AFS_GUNLOCK();
rx_DestroyConnection(tc->id);
- AFS_GLOCK();
+ if (glocked)
+ AFS_GLOCK();
}
/*
* Stupid hack to determine if using vldb service or file system
csec = afs_pickSecurityObject(tc, &isec);
- AFS_GUNLOCK();
+ if (glocked)
+ AFS_GUNLOCK();
tc->id = rx_NewConnection(sap->sa_ip, aport, service, csec, isec);
- AFS_GLOCK();
+ if (glocked)
+ AFS_GLOCK();
if (service == 52) {
rx_SetConnHardDeadTime(tc->id, afs_rx_harddead);
}
struct vrequest *areq, int aforce, afs_int32 locktype)
{
struct unixuser *tu;
- struct afs_conn *tc = 0;
- struct srvAddr *sa = 0;
+ struct afs_conn *tc = NULL;
+ struct srvAddr *sa = NULL;
AFS_STATCNT(afs_ConnByHost);
{
AFS_STATCNT(afs_PutConn);
ac->refCount--;
+ ac->parent->refCount--;
} /*afs_PutConn */
/**
+ * Free up a connection vector, allowing, eg, code in afs_user.c
+ * to ignore how connections are stored/pooled
+ * @param tcv
+ */
+void
+afs_ReleaseConns(struct sa_conn_vector *tcv) {
+ release_conns_vector(tcv);
+}
+
+
+/**
+ * Free connection vector(s) for a user
+ * @param au
+ */
+void
+afs_ReleaseConnsUser(struct unixuser *au) {
+
+ int i;
+ struct server *ts;
+
+ for (i = 0; i < NSERVERS; i++) {
+ for (ts = afs_servers[i]; ts; ts = ts->next) {
+ release_conns_user_server(au, ts);
+ } /*For each server on chain */
+ } /*For each chain */
+}
+
+
+/**
* For multi homed clients, a RPC may timeout because of a
* client network interface going down. We need to reopen new
* connections in this case.
void
ForceNewConnections(struct srvAddr *sap)
{
- struct afs_conn *tc = 0;
+ int cix;
+ struct afs_conn *tc = NULL;
+ struct sa_conn_vector *tcv = NULL;
if (!sap)
- return; /* defensive check */
+ return; /* defensive check */
ObtainWriteLock(&afs_xconn, 413);
- for (tc = sap->conns; tc; tc = tc->next)
- tc->forceConnectFS = 1;
+ for (tcv = sap->conns; tcv; tcv = tcv->next) {
+ for(cix = 0; cix < CVEC_LEN; ++cix) {
+ tc = &(tcv->cvec[cix]);
+ if (tc->activated)
+ tc->forceConnectFS = 1;
+ }
+ }
ReleaseWriteLock(&afs_xconn);
}
+
+
#endif /* AFS_NOSTATS */
if (!setLocks || slowPass) {
- avc->callback = tc->srvr->server;
+ avc->callback = tc->parent->srvr->server;
} else {
- newCallback = tc->srvr->server;
+ newCallback = tc->parent->srvr->server;
setNewCallback = 1;
}
i = osi_Time();
do {
tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK);
if (tc) {
- tvc->callback = tc->srvr->server;
+ tvc->callback = tc->parent->srvr->server;
start = osi_Time();
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
RX_AFS_GUNLOCK();
shutdown_server(void)
{
int i;
- struct afs_conn *tc, *ntc;
struct afs_cbr *tcbrp, *tbrp;
struct srvAddr *sa;
next = ts->next;
for (sa = ts->addr; sa; sa = sa->next_sa) {
if (sa->conns) {
- /*
- * Free all server's connection structs
- */
- tc = sa->conns;
- while (tc) {
- ntc = tc->next;
-#if 0
- /* we should destroy all connections
- when shutting down Rx, not here */
- AFS_GUNLOCK();
- rx_DestroyConnection(tc->id);
- AFS_GLOCK();
-#endif
- afs_osi_Free(tc, sizeof(struct afs_conn));
- tc = ntc;
- }
+ /* afs_ReleaseConns has been updated to
+ * defer rx_DestroyConnection to Rx
+ * shutdown, as most recently was done
+ * here */
+ afs_ReleaseConns(sa->conns);
}
}
for (tcbrp = ts->cbrs; tcbrp; tcbrp = tbrp) {
{
int i;
struct srvAddr *sa;
- struct afs_conn *tc;
+ struct sa_conn_vector *tcv;
struct unixuser *tu;
afs_int32 retValue;
/* all connections in cell 1 working? */
for (i = 0; i < NSERVERS; i++) {
for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
- for (tc = sa->conns; tc; tc = tc->next) {
- if (tc->user == tu && (tu->states & UTokensBad))
+ for (tcv = sa->conns; tcv; tcv = tcv->next) {
+ if (tcv->user == tu && (tu->states & UTokensBad))
retValue = EACCES;
}
}
struct vrequest *areq, int aforce,
afs_int32 locktype);
extern void afs_PutConn(struct afs_conn *ac, afs_int32 locktype);
+extern void afs_ReleaseConns(struct sa_conn_vector *tcv);
+extern void afs_ReleaseConnsUser(register struct unixuser *au);
extern void ForceNewConnections(struct srvAddr *sap);
* with old vlsevers), then we treat this server as running again
*/
if (code == 0 || (code <= -450 && code >= -470)) {
- if (tc->srvr == sa) {
+ if (tc->parent->srvr == sa) {
afs_MarkServerUpOrDown(sa, 0);
print_internet_address("afs: volume location server ", sa,
" is back up", 2);
continue;
if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(sa->server)
- || (tc->srvr->server == afs_setTimeHost)) {
+ || (tc->parent->srvr->server == afs_setTimeHost)) {
conns[nconns]=tc;
rxconns[nconns]=tc->id;
if (sa->sa_flags & SRVADDR_ISDOWN) {
multi_RXAFS_GetTime(
(afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec);
tc = conns[multi_i];
- sa = tc->srvr;
+ sa = tc->parent->srvr;
if (conntimer[multi_i] == 1)
rx_SetConnDeadTime(tc->id, afs_rx_deadtime);
end = osi_Time();
}
else { /* find and query setTimeHost only */
for ( i = 0 ; i < j ; i++ ) {
- if ( conns[i] == NULL || conns[i]->srvr == NULL )
+ if ( conns[i] == NULL || conns[i]->parent->srvr == NULL )
continue;
- if ( conns[i]->srvr->server == afs_setTimeHost ) {
+ if ( conns[i]->parent->srvr->server == afs_setTimeHost ) {
tv.tv_sec = tv.tv_usec = 0;
results[i] = RXAFS_GetTime(rxconns[i],
(afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec);
for(i=0;i<nconns;i++){
tc = conns[i];
- sa = tc->srvr;
+ sa = tc->parent->srvr;
- if (( results[i] >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
+ if (( results[i] >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->parent->srvr == sa)) {
/* server back up */
print_internet_address("afs: file server ", sa, " is back up", 2);
for (i=0; i<nconns; i++) {
delta = deltas[i];
tc = conns[i];
- sa = tc->srvr;
+ sa = tc->parent->srvr;
- if ((tc->srvr->server == afs_setTimeHost ||
+ if ((tc->parent->srvr->server == afs_setTimeHost ||
/* Sync only to a server in the local cell */
(afs_setTimeHost == (struct server *)0 &&
afs_IsPrimaryCell(sa->server->cell)))) {
char msgbuf[90]; /* strlen("afs: setting clock...") + slop */
delta = end - tv.tv_sec; /* how many secs fast we are */
- afs_setTimeHost = tc->srvr->server;
+ afs_setTimeHost = tc->parent->srvr->server;
/* see if clock has changed enough to make it worthwhile */
if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) {
end = osi_Time();
int i;
struct server *ts, *nts;
struct srvAddr *sa;
- struct afs_conn *tc, *ntc;
ObtainReadLock(&afs_xserver);
ObtainWriteLock(&afs_xconn, 1001);
nts = ts->next;
for (sa = ts->addr; sa; sa = sa->next_sa) {
if (sa->conns) {
- tc = sa->conns;
- while (tc) {
- ntc = tc->next;
- AFS_GUNLOCK();
- rx_DestroyConnection(tc->id);
- AFS_GLOCK();
- afs_osi_Free(tc, sizeof(struct afs_conn));
- tc = ntc;
- }
+ afs_ReleaseConns(sa->conns);
sa->conns = NULL;
}
}
#ifndef AFS_PAG_MANAGER
/* Forward declarations */
void afs_ResetAccessCache(afs_int32 uid, int alock);
-
-/*
- * Called with afs_xuser, afs_xserver and afs_xconn locks held, to delete
- * appropriate conn structures for au
- */
-static void
-RemoveUserConns(struct unixuser *au)
-{
- int i;
- struct server *ts;
- struct srvAddr *sa;
- struct afs_conn *tc, **lc;
-
- AFS_STATCNT(RemoveUserConns);
- for (i = 0; i < NSERVERS; i++) {
- for (ts = afs_servers[i]; ts; ts = ts->next) {
- for (sa = ts->addr; sa; sa = sa->next_sa) {
- lc = &sa->conns;
- for (tc = *lc; tc; lc = &tc->next, tc = *lc) {
- if (tc->user == au && tc->refCount == 0) {
- *lc = tc->next;
- AFS_GUNLOCK();
- rx_DestroyConnection(tc->id);
- AFS_GLOCK();
- afs_osi_Free(tc, sizeof(struct afs_conn));
- break; /* at most one instance per server */
- } /*Found unreferenced connection for user */
- } /*For each connection on the server */
- }
- } /*For each server on chain */
- } /*For each chain */
-
-} /*RemoveUserConns */
#endif /* !AFS_PAG_MANAGER */
if (delFlag) {
*lu = tu->next;
#ifndef AFS_PAG_MANAGER
- RemoveUserConns(tu);
+ afs_ReleaseConnsUser(tu);
#endif
afs_FreeTokens(&tu->tokens);
void
afs_ResetUserConns(struct unixuser *auser)
{
- int i;
+ int i, j;
struct srvAddr *sa;
- struct afs_conn *tc;
+ struct sa_conn_vector *tcv;
AFS_STATCNT(afs_ResetUserConns);
ObtainReadLock(&afs_xsrvAddr);
for (i = 0; i < NSERVERS; i++) {
for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
- for (tc = sa->conns; tc; tc = tc->next) {
- if (tc->user == auser) {
- tc->forceConnectFS = 1;
+ for (tcv = sa->conns; tcv; tcv = tcv->next) {
+ if (tcv->user == auser) {
+ for(j = 0; j < CVEC_LEN; ++j) {
+ (tcv->cvec[j]).forceConnectFS = 1;
+ }
}
}
}
{
struct srvAddr *sa;
struct server *ts;
- struct afs_conn *tc;
+ struct sa_conn_vector *tcv;
for (i = 0; i < NSERVERS; i++) {
for (ts = afs_servers[i]; ts; ts = ts->next) {
if (ts->flags & SRVR_ISDOWN)
afs_warn("Server entry %p is marked down\n", ts);
for (sa = ts->addr; sa; sa = sa->next_sa) {
- for (tc = sa->conns; tc; tc = tc->next) {
- if (tc->refCount)
- afs_warn("conn at %p (server %x) is held\n", tc,
+ for (tcv = sa->conns; tcv; tcv = tcv->next) {
+ if (tcv->refCount)
+ afs_warn("conn at %p (server %x) is held\n", tcv,
sa->sa_ip);
}
}
tc = afs_Conn(afid, areq, SHARED_LOCK);
if (tc) {
if (serverp)
- *serverp = tc->srvr->server;
+ *serverp = tc->parent->srvr->server;
start = osi_Time();
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_XLOOKUP);
RX_AFS_GUNLOCK();
tc = afs_Conn(afid, areq, SHARED_LOCK);
avc->dchint = NULL; /* invalidate hints */
if (tc) {
- avc->callback = tc->srvr->server;
+ avc->callback = tc->parent->srvr->server;
start = osi_Time();
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
RX_AFS_GUNLOCK();
afs_ConnByMHosts(tcell->cellHosts, tcell->vlport, tcell->cellNum,
&treq, SHARED_LOCK);
if (tconn) {
- if (tconn->srvr->server->flags & SNO_LHOSTS) {
+ if (tconn->parent->srvr->server->flags & SNO_LHOSTS) {
type = 0;
RX_AFS_GUNLOCK();
code = VL_GetEntryByNameO(tconn->id, aname, tve);
RX_AFS_GLOCK();
- } else if (tconn->srvr->server->flags & SYES_LHOSTS) {
+ } else if (tconn->parent->srvr->server->flags & SYES_LHOSTS) {
type = 1;
RX_AFS_GUNLOCK();
code = VL_GetEntryByNameN(tconn->id, aname, ntve);
RX_AFS_GUNLOCK();
code = VL_GetEntryByNameU(tconn->id, aname, utve);
RX_AFS_GLOCK();
- if (!(tconn->srvr->server->flags & SVLSRV_UUID)) {
+ if (!(tconn->parent->srvr->server->flags & SVLSRV_UUID)) {
if (code == RXGEN_OPCODE) {
type = 1;
RX_AFS_GUNLOCK();
RX_AFS_GLOCK();
if (code == RXGEN_OPCODE) {
type = 0;
- tconn->srvr->server->flags |= SNO_LHOSTS;
+ tconn->parent->srvr->server->flags |= SNO_LHOSTS;
RX_AFS_GUNLOCK();
code = VL_GetEntryByNameO(tconn->id, aname, tve);
RX_AFS_GLOCK();
} else if (!code)
- tconn->srvr->server->flags |= SYES_LHOSTS;
+ tconn->parent->srvr->server->flags |= SYES_LHOSTS;
} else if (!code)
- tconn->srvr->server->flags |= SVLSRV_UUID;
+ tconn->parent->srvr->server->flags |= SVLSRV_UUID;
}
lastnvcode = code;
}