From 847a200bb90d6de25a01a9eb45497289a4695cd3 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 19 Jun 2007 17:15:59 +0000 Subject: [PATCH] DEVEL15-windows-updatecell-20070619 No longer permit cm_GetCell() or cm_FindCellByID() to return NULL simply because cm_UpdateCell() failed. The cm_cell_t object still exists and is valid even if the vlServersp list is empty. Modify the lock management in cm_GetCell_Gen() to ensure we drop all the locks. In cm_Analyze() update the volume status when one of the servers reports VBUSY or VRESTARTING. (cherry picked from commit 01c3c334d53da95318f54b4085da9b37c79c90b9) --- src/WINNT/afsd/cm_cell.c | 19 ++++++++++--------- src/WINNT/afsd/cm_cell.h | 6 +++--- src/WINNT/afsd/cm_conn.c | 24 +++++++++++++++++++++--- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index 4bd2df637..025036aea 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -115,16 +115,17 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp) } /* load up a cell structure from the cell database, afsdcell.ini */ -cm_cell_t *cm_GetCell(char *namep, long flags) +cm_cell_t *cm_GetCell(char *namep, afs_uint32 flags) { return cm_GetCell_Gen(namep, NULL, flags); } -cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) +cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) { cm_cell_t *cp, *cp2; long code; char fullname[200]=""; + int hasWriteLock = 0; if (!strcmp(namep,SMB_IOCTL_FILENAME_NOSLASH)) return NULL; @@ -139,9 +140,10 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) lock_ReleaseRead(&cm_cellLock); if (cp) { - cp = cm_UpdateCell(cp); + cm_UpdateCell(cp); } else if (flags & CM_FLAG_CREATE) { lock_ObtainWrite(&cm_cellLock); + hasWriteLock = 1; /* when we dropped the lock the cell could have been added * to the list so check again while holding the write lock @@ -153,10 +155,8 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) } } - if (cp) { - lock_ReleaseWrite(&cm_cellLock); + if (cp) goto done; - } if ( cm_data.currentCells >= cm_data.maxCells ) osi_panic("Exceeded Max Cells", __FILE__, __LINE__); @@ -213,7 +213,6 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) if (cp2) { cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE); cp = cp2; - lock_ReleaseWrite(&cm_cellLock); goto done; } @@ -234,10 +233,12 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) /* the cellID cannot be 0 */ cp->cellID = ++cm_data.currentCells; - lock_ReleaseWrite(&cm_cellLock); } done: + if (hasWriteLock) + lock_ReleaseWrite(&cm_cellLock); + /* fullname is not valid if cp == NULL */ if (cp && newnamep) strcpy(newnamep, fullname); @@ -257,7 +258,7 @@ cm_cell_t *cm_FindCellByID(afs_int32 cellID) lock_ReleaseRead(&cm_cellLock); if (cp) - cp = cm_UpdateCell(cp); + cm_UpdateCell(cp); return cp; } diff --git a/src/WINNT/afsd/cm_cell.h b/src/WINNT/afsd/cm_cell.h index 64eb03e04..0652e2ac3 100644 --- a/src/WINNT/afsd/cm_cell.h +++ b/src/WINNT/afsd/cm_cell.h @@ -40,13 +40,13 @@ extern long cm_ShutdownCell(void); extern long cm_ValidateCell(void); -extern cm_cell_t *cm_GetCell(char *namep, long flags); +extern cm_cell_t *cm_GetCell(char *namep, afs_uint32 flags); -extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags); +extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags); extern cm_cell_t *cm_FindCellByID(afs_int32 cellID); -extern void cm_ChangeRankCellVLServer(cm_server_t *tsp); +extern void cm_ChangeRankCellVLServer(cm_server_t *tsp); extern osi_rwlock_t cm_cellLock; diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 1b675b116..32e62abfc 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -164,6 +164,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, cm_serverRef_t *tsrp; cm_cell_t *cellp = NULL; cm_ucell_t *ucellp; + cm_volume_t * volp = NULL; + cm_vol_state_t *statep = NULL; int retry = 0; int free_svr_list = 0; int dead_session; @@ -300,8 +302,6 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, */ osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLBUSY."); if (timeLeft > 7) { - cm_volume_t * volp = NULL; - cm_vol_state_t *statep; thrd_Sleep(5000); @@ -372,12 +372,30 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, lock_ObtainWrite(&cm_serverLock); for (tsrp = serversp; tsrp; tsrp=tsrp->next) { if (tsrp->server == serverp && tsrp->status == srv_not_busy) { - /* REDIRECT */ tsrp->status = srv_busy; + if (fidp) { /* File Server query */ + code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, + CM_GETVOL_FLAG_NO_LRU_UPDATE, + &volp); + if (code == 0) { + if (fidp->volume == volp->rw.ID) + statep = &volp->rw; + else if (fidp->volume == volp->ro.ID) + statep = &volp->ro; + else if (fidp->volume == volp->bk.ID) + statep = &volp->bk; + } + + cm_PutVolume(volp); + } break; } } lock_ReleaseWrite(&cm_serverLock); + + if (statep) + cm_UpdateVolumeStatus(volp, statep->ID); + if (free_svr_list) { cm_FreeServerList(&serversp, 0); *serverspp = serversp; -- 2.39.5