From 06597a0e03faf2f5d4cd8d3f72b93017970b28fd Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 12 Jun 2005 12:44:55 +0000 Subject: [PATCH] windows-misc-fixes-20050612 if scp is not known when flushing dirty buffers, find it by fid only free the server list when one was obtained hold the scp mutex until after the associated bufp flags are updated only get the volume by id if there is a server callback map CM_ERROR_ALLOFFLINE to NT Remote Host Down --- src/WINNT/afsd/cm_buf.c | 3 +++ src/WINNT/afsd/cm_conn.c | 40 +++++++++++++++++++++++++------------- src/WINNT/afsd/cm_dcache.c | 2 +- src/WINNT/afsd/cm_scache.c | 14 ++++++++----- src/WINNT/afsd/smb.c | 6 +++++- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 9b28eb4ba..98b63f823 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -463,6 +463,9 @@ void buf_WaitIO(cm_scache_t * scp, cm_buf_t *bp) bp->waitRequests = 0; } + if ( !scp ) { + scp = cm_FindSCache(&bp->fid); + } if ( scp ) { lock_ObtainMutex(&scp->mx); if (scp->flags & CM_SCACHEFLAG_WAITING) { diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 485fa74d4..ff2fb08aa 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -143,14 +143,15 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, cm_serverRef_t * serversp, cm_callbackRequest_t *cbrp, long errorCode) { - cm_server_t *serverp = 0; - cm_serverRef_t **serverspp = 0; + cm_server_t *serverp = NULL; + cm_serverRef_t **serverspp = NULL; cm_serverRef_t *tsrp; cm_ucell_t *ucellp; int retry = 0; int free_svr_list = 0; int dead_session; long timeUsed, timeLeft; + long code; osi_Log2(afsd_logp, "cm_Analyze connp 0x%x, code 0x%x", (long) connp, errorCode); @@ -226,15 +227,18 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, if (timeLeft > 7) { osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLOFFLINE."); thrd_Sleep(5000); + /* cm_ForceUpdateVolume marks all servers as non_busy */ /* No it doesn't and it won't do anything if all of the * the servers are marked as DOWN. So clear the DOWN * flag and reset the busy state as well. */ if (!serversp) { - cm_GetServerList(fidp, userp, reqp, &serverspp); - serversp = *serverspp; - free_svr_list = 1; + code = cm_GetServerList(fidp, userp, reqp, &serverspp); + if (code == 0) { + serversp = *serverspp; + free_svr_list = 1; + } } if (serversp) { lock_ObtainWrite(&cm_serverLock); @@ -253,6 +257,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, if (fidp != NULL) /* Not a VLDB call */ cm_ForceUpdateVolume(fidp, userp, reqp); + else + retry = 0; } } @@ -261,9 +267,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, if (timeLeft > 7) { thrd_Sleep(5000); if (!serversp) { - cm_GetServerList(fidp, userp, reqp, &serverspp); - serversp = *serverspp; - free_svr_list = 1; + code = cm_GetServerList(fidp, userp, reqp, &serverspp); + if (code == 0) { + serversp = *serverspp; + free_svr_list = 1; + } } lock_ObtainWrite(&cm_serverLock); for (tsrp = serversp; tsrp; tsrp=tsrp->next) { @@ -282,9 +290,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, /* special codes: VBUSY and VRESTARTING */ else if (errorCode == VBUSY || errorCode == VRESTARTING) { if (!serversp) { - cm_GetServerList(fidp, userp, reqp, &serverspp); - serversp = *serverspp; - free_svr_list = 1; + code = cm_GetServerList(fidp, userp, reqp, &serverspp); + if (code == 0) { + serversp = *serverspp; + free_svr_list = 1; + } } lock_ObtainWrite(&cm_serverLock); for (tsrp = serversp; tsrp; tsrp=tsrp->next) { @@ -332,9 +342,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, /* Mark server offline for this volume */ if (!serversp) { - cm_GetServerList(fidp, userp, reqp, &serverspp); - serversp = *serverspp; - free_svr_list = 1; + code = cm_GetServerList(fidp, userp, reqp, &serverspp); + if (code == 0) { + serversp = *serverspp; + free_svr_list = 1; + } } for (tsrp = serversp; tsrp; tsrp=tsrp->next) { if (tsrp->server == serverp) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index f7bbb8deb..a2e86533d 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -1089,7 +1089,6 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore) lock_ObtainMutex(&bufp->mx); lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, bufp, flags); - lock_ReleaseMutex(&scp->mx); /* turn off writing and wakeup users */ if (isStore) { @@ -1100,6 +1099,7 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore) bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY); } + lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); } diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 33c7367a3..7b099a62a 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -1027,15 +1027,19 @@ void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp, if (!(flags & CM_MERGEFLAG_FORCE) && statusp->DataVersion < (unsigned long) scp->dataVersion) { struct cm_cell *cellp; - struct cm_volume *volp; cellp = cm_FindCellByID(scp->fid.cell); - cm_GetVolumeByID(cellp, scp->fid.volume, userp, - (cm_req_t *) NULL, &volp); - if (scp->cbServerp) + if (scp->cbServerp) { + struct cm_volume *volp = NULL; + + cm_GetVolumeByID(cellp, scp->fid.volume, userp, + (cm_req_t *) NULL, &volp); osi_Log2(afsd_logp, "old data from server %x volume %s", scp->cbServerp->addr.sin_addr.s_addr, - volp->namep); + volp ? volp->namep : "(unknown)"); + if (volp) + cm_PutVolume(volp); + } osi_Log3(afsd_logp, "Bad merge, scp %x, scp dv %d, RPC dv %d", scp, scp->dataVersion, statusp->DataVersion); /* we have a number of data fetch/store operations running diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 87693ba11..4892c2aa3 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -2433,7 +2433,11 @@ void smb_MapNTError(long code, unsigned long *NTStatusp) } else if (code == CM_ERROR_ALLBUSY) { NTStatus = 0xC00000BFL; /* Network Busy */ - } else { + } + else if (code == CM_ERROR_ALLOFFLINE) { + NTStatus = 0xC0000350L; /* Remote Host Down */ + } + else { NTStatus = 0xC0982001L; /* SMB non-specific error */ } -- 2.39.5