if (!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING)))
break;
- /* otherwise I/O is happening, but some other thread is waiting for
- * the I/O already. Wait for that guy to figure out what happened,
- * and then check again.
- */
- bp->flags |= CM_BUF_WAITING;
- osi_SleepM((long) bp, &bp->mx);
- lock_ObtainMutex(&bp->mx);
+ /* otherwise I/O is happening, but some other thread is waiting for
+ * the I/O already. Wait for that guy to figure out what happened,
+ * and then check again.
+ */
+ if ( bp->flags & CM_BUF_WAITING )
+ osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING already set for 0x%x", bp);
+
+ bp->flags |= CM_BUF_WAITING;
+ osi_SleepM((long) bp, &bp->mx);
+ lock_ObtainMutex(&bp->mx);
osi_Log1(buf_logp, "buf_WaitIO conflict wait done for 0x%x", bp);
- }
+ }
- /* if we get here, the IO is done, but we may have to wakeup people waiting for
- * the I/O to complete. Do so.
- */
- if (bp->flags & CM_BUF_WAITING) {
+ /* if we get here, the IO is done, but we may have to wakeup people waiting for
+ * the I/O to complete. Do so.
+ */
+ if (bp->flags & CM_BUF_WAITING) {
bp->flags &= ~CM_BUF_WAITING;
- osi_Wakeup((long) bp);
- }
- osi_Log1(buf_logp, "WaitIO finished wait for bp 0x%x", (long) bp);
+ osi_Wakeup((long) bp);
+ }
+ osi_Log1(buf_logp, "WaitIO finished wait for bp 0x%x", (long) bp);
}
/* code to drop reference count while holding buf_globalLock */
{
cm_server_t *tsp;
cm_serverRef_t *tsrp;
- cm_cell_t *cellp;
+ cm_cell_t *cellp;
cellp = rockp;
|| (cp && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout))
#endif
) {
- if (!cp) cp = malloc(sizeof(*cp));
- memset(cp, 0, sizeof(*cp));
+ int dns_expired = 0;
+ if (!cp) {
+ cp = malloc(sizeof(*cp));
+ memset(cp, 0, sizeof(*cp));
+ }
+ else {
+ dns_expired = 1;
+ /* must empty cp->vlServersp */
+ cm_FreeServerList(&cp->vlServersp);
+ cp->vlServersp = NULL;
+ }
+
code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
if (code) {
afsi_log("in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s",
#ifdef AFS_AFSDB_ENV
if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/) {
code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
- if ( code )
+ if ( code ) {
afsi_log("in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
namep, code, fullname);
+ if (dns_expired) {
+ if ( cm_allCellsp == cp )
+ cm_allCellsp = cp->nextp;
+ else {
+ cm_cell_t *tcp;
+
+ for(tcp = cm_allCellsp; tcp->nextp; tcp=tcp->nextp) {
+ if ( tcp->nextp == cp ) {
+ tcp->nextp = cp->nextp;
+ break;
+ }
+ }
+ }
+
+ lock_FinalizeMutex(&cp->mx);
+ free(cp->namep);
+ }
+ }
+ else { /* got cell from DNS */
+ cp->flags |= CM_CELLFLAG_DNS;
+ cp->timeout = time(0) + ttl;
+ }
}
#endif
if (code) {
cp = NULL;
goto done;
}
-#ifdef AFS_AFSDB_ENV
- else { /* got cell from DNS */
- cp->flags |= CM_CELLFLAG_DNS;
- cp->timeout = time(0) + ttl;
- }
-#endif
}
/* randomise among those vlservers having the same rank*/
cm_RandomizeServer(&cp->vlServersp);
+#ifdef AFS_AFSDB_ENV
+ if (dns_expired) {
+ /* we want to preserve the full name and mutex.
+ * also, cp is already in the cm_allCellsp list
+ */
+ goto done;
+ }
+#endif /* AFS_AFSDB_ENV */
+
/* otherwise we found the cell, and so we're nearly done */
lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
done:
/* fullname is not valid if cp == NULL */
if (cp && newnamep)
- strcpy(newnamep, fullname);
+ strcpy(newnamep, fullname);
lock_ReleaseWrite(&cm_cellLock);
- return cp;
+ return cp;
}
cm_cell_t *cm_FindCellByID(long cellID)
lock_ObtainWrite(&cm_cellLock);
for(cp = cm_allCellsp; cp; cp=cp->nextp) {
- if (cellID == cp->cellID) break;
- }
+ if (cellID == cp->cellID)
+ break;
+ }
#ifdef AFS_AFSDB_ENV
/* if it's from DNS, see if it has expired */
#endif /* AFS_AFSDB_ENV */
lock_ReleaseWrite(&cm_cellLock);
-
- return cp;
+ return cp;
}
void cm_InitCell(void)
osi_EndOnce(&once);
}
}
-void cm_ChangeRankCellVLServer(cm_server_t *tsp)
+void cm_ChangeRankCellVLServer(cm_server_t *tsp)
{
cm_cell_t *cp;
int code;
#include "afsd_init.h"
#include "smb.h"
+#include "cm_server.h"
#ifndef DJGPP
#include <rx/rxkad.h>
* cell list will be cm_CellLock and cm_ServerLock will be held for write.
*/
- cm_cell_t *tcellp;
+ cm_cell_t *cp;
+ cm_cell_t *tcp;
cm_SkipIoctlPath(ioctlp);
lock_ObtainWrite(&cm_cellLock);
- for(tcellp = cm_allCellsp; tcellp; tcellp=tcellp->nextp)
+ for(cp = cm_allCellsp; cp; cp=cp->nextp)
{
+ long code;
+ top:
/* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
- cm_FreeServerList(&tcellp->vlServersp);
- tcellp->vlServersp = NULL;
- cm_SearchCellFile(tcellp->namep, tcellp->namep, cm_AddCellProc, tcellp);
- cm_RandomizeServer(&tcellp->vlServersp);
+ cm_FreeServerList(&cp->vlServersp);
+ cp->vlServersp = NULL;
+ code = cm_SearchCellFile(cp->namep, cp->namep, cm_AddCellProc, cp);
+ if (code) {
+#ifdef AFS_AFSDB_ENV
+ if (cm_dnsEnabled) {
+ int ttl;
+ code = cm_SearchCellByDNS(cp->namep, cp->namep, &ttl, cm_AddCellProc, cp);
+ if ( code ) {
+ if ( cm_allCellsp == cp )
+ cm_allCellsp = cp->nextp;
+ else {
+ for(tcp = cm_allCellsp; tcp->nextp; tcp=tcp->nextp) {
+ if ( tcp->nextp == cp ) {
+ tcp->nextp = cp->nextp;
+ break;
+ }
+ }
+ }
+
+ lock_FinalizeMutex(&cp->mx);
+ free(cp->namep);
+ }
+ else { /* got cell from DNS */
+ cp->flags |= CM_CELLFLAG_DNS;
+ cp->timeout = time(0) + ttl;
+ }
+ }
+#endif /* AFS_AFSDB_ENV */
+ }
+ if (code) {
+ tcp = cp;
+ cp = cp->nextp;
+ free(tcp);
+ goto top;
+ }
+ else
+ cm_RandomizeServer(&cp->vlServersp);
}
lock_ReleaseWrite(&cm_cellLock);
/* wait here, then try again */
osi_Log1(afsd_logp, "CM SyncOp sleeping scp %x", (long) scp);
+ if ( scp->flags & CM_SCACHEFLAG_WAITING )
+ osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING already set for 0x%x", scp);
scp->flags |= CM_SCACHEFLAG_WAITING;
if (bufLocked) lock_ReleaseMutex(&bufp->mx);
osi_SleepM((long) &scp->flags, &scp->mx);
lock_ReleaseWrite(&cm_serverLock);
}
+void cm_FreeServer(cm_server_t* server)
+{
+ lock_ObtainWrite(&cm_serverLock);
+ if (--(server->refCount) == 0)
+ {
+ /* we need to check to ensure that all of the connections
+ * for this server have a 0 refCount; otherwise, they will
+ * not be garbage collected
+ */
+ cm_GCConnections(&server); /* connsp */
+
+ lock_FinalizeMutex(&server->mx);
+ if ( cm_allServersp == server )
+ cm_allServersp = server->allNextp;
+ else {
+ cm_server_t *tsp;
+
+ for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) {
+ if ( tsp->allNextp == server ) {
+ tsp->allNextp = server->allNextp;
+ break;
+ }
+ }
+ }
+ }
+ lock_ReleaseWrite(&cm_serverLock);
+}
+
void cm_FreeServerList(cm_serverRef_t** list)
{
cm_serverRef_t *current = *list;
while (current)
{
- next = current->next;
- free(current);
- current = next;
+ next = current->next;
+ cm_FreeServer(current->server);
+ free(current);
+ current = next;
}
lock_ReleaseWrite(&cm_serverLock);
extern void cm_RandomizeServer(cm_serverRef_t** list);
+extern void cm_FreeServer(cm_server_t* server);
+
+extern void cm_FreeServerList(cm_serverRef_t** list);
+
#endif /* __CM_SERVER_H_ENV__ */
int smb_NumServerThreads;
-int numNCBs, numSessions;
+int numNCBs, numSessions, numVCs;
int smb_maxVCPerServer;
int smb_maxMpxRequests;
if (!vcp && (flags & SMB_FLAG_CREATE)) {
vcp = malloc(sizeof(*vcp));
memset(vcp, 0, sizeof(*vcp));
+ vcp->vcID = numVCs++;
vcp->refCount = 1;
vcp->tidCounter = 1;
vcp->fidCounter = 1;
* we run out.
*/
- osi_assert(i < Sessionmax);
- osi_assert(numNCBs < NCBmax);
+ osi_assert(i < Sessionmax - 1);
+ osi_assert(numNCBs < NCBmax - 1); /* if we pass this test we can allocate one more */
LSNs[i] = ncbp->ncb_lsn;
lanas[i] = ncbp->ncb_lana_num;
smb_NetbiosInit();
/* Initialize listener and server structures */
+ numVCs = 0;
memset(dead_sessions, 0, sizeof(dead_sessions));
sprintf(eventName, "SessionEvents[0]");
SessionEvents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
count = smb_GetSMBParm(inp, 5);
userp = smb_GetUser(vcp, inp);
+ osi_assert(userp != 0);
{
smb_user_t *uidp;