From f6d2a279b9f4899f2ab072d949f0d4ff11a517f6 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 16 Apr 2010 22:52:20 -0400 Subject: [PATCH] Windows: cm_UpdateCell must hold cell lock across server random cm_UpdateCell fails to hold the cell lock across the server randomization. As a result the vlserver list can be destroyed while randomization is taking place. LICENSE MIT Change-Id: I7753e7e9f8a7d536ce0e2082aaca7b62ab745504 Reviewed-on: http://gerrit.openafs.org/1767 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_cell.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index bb08f7a92..b1094c6b1 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -76,11 +76,13 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags) { long code = 0; cm_cell_rock_t rock; + afs_uint32 mxheld = 0; if (cp == NULL) return NULL; lock_ObtainMutex(&cp->mx); + mxheld = 1; if ((cp->vlServersp == NULL #ifdef AFS_FREELANCE_CLIENT && !(cp->flags & CM_CELLFLAG_FREELANCE) @@ -90,14 +92,15 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags) ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID))) ) { - lock_ReleaseMutex(&cp->mx); - /* must empty cp->vlServersp */ if (cp->vlServersp) { cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE); cp->vlServersp = NULL; } + lock_ReleaseMutex(&cp->mx); + mxheld = 0; + rock.cellp = cp; rock.flags = flags; code = cm_SearchCellRegistry(1, cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock); @@ -105,8 +108,8 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags) code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock); if (code == 0) { lock_ObtainMutex(&cp->mx); + mxheld = 1; cp->timeout = time(0) + 7200; - lock_ReleaseMutex(&cp->mx); } else { if (cm_dnsEnabled) { @@ -115,10 +118,10 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags) code = cm_SearchCellByDNS(cp->name, NULL, &ttl, cm_AddCellProc, &rock); if (code == 0) { /* got cell from DNS */ lock_ObtainMutex(&cp->mx); + mxheld = 1; cp->flags |= CM_CELLFLAG_DNS; cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID; cp->timeout = time(0) + ttl; - lock_ReleaseMutex(&cp->mx); #ifdef DEBUG fprintf(stderr, "cell %s: ttl=%d\n", cp->name, ttl); #endif @@ -127,18 +130,19 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags) * current entry alone */ lock_ObtainMutex(&cp->mx); + mxheld = 1; cp->flags |= CM_CELLFLAG_VLSERVER_INVALID; - lock_ReleaseMutex(&cp->mx); } } } - } else { - lock_ReleaseMutex(&cp->mx); } if (code == 0) cm_RandomizeServer(&cp->vlServersp); + if (mxheld) + lock_ReleaseMutex(&cp->mx); + return code ? NULL : cp; } -- 2.39.5