From 11ad1e467f9708f12fe09228cbb827b8f4e1225b Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 16 Mar 2011 02:17:38 -0400 Subject: [PATCH] Windows: avoid recursive cm_CheckOfflineVolume Add a new cm_req_t flag CM_REQ_OFFLINE_VOL_CHK which is used to prevent cm_Analyze() from performing recursive cm_CheckOfflineVolume operations that will exhaust the stack. Change-Id: Ia4ee14307bf812cc2208482a19c1a914aca3e447 Reviewed-on: http://gerrit.openafs.org/4240 Tested-by: BuildBot Reviewed-by: Derrick Brashear Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_conn.c | 6 +++++- src/WINNT/afsd/cm_conn.h | 10 ++++++---- src/WINNT/afsd/cm_volume.c | 5 +++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 2134a96..5baba3f 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -351,7 +351,11 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp); if (code == 0) { - if (timeLeft > 7) { + /* + * Do not perform a cm_CheckOfflineVolume() if cm_Analyze() + * was called by cm_CheckOfflineVolumeState(). + */ + if (!(reqp->flags & CM_REQ_OFFLINE_VOL_CHK) && timeLeft > 7) { thrd_Sleep(5000); /* cm_CheckOfflineVolume() resets the serverRef state */ diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index 32c5c2d..044c054 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -62,10 +62,12 @@ typedef struct cm_req { } cm_req_t; /* flags in cm_req structure */ -#define CM_REQ_NORETRY 0x1 -#define CM_REQ_NEW_CONN_FORCED 0x2 -#define CM_REQ_SOURCE_SMB 0x4 -#define CM_REQ_VOLUME_UPDATED 0x8 +#define CM_REQ_NORETRY 0x01 +#define CM_REQ_NEW_CONN_FORCED 0x02 +#define CM_REQ_SOURCE_SMB 0x04 +#define CM_REQ_VOLUME_UPDATED 0x08 +/* 0x10 and 0x20 are reserved for the afs redirector */ +#define CM_REQ_OFFLINE_VOL_CHK 0x40 /* * Vice2 error codes diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index 6d627d7..5449d23 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -1249,17 +1249,18 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 if (statep->state == vl_busy || statep->state == vl_offline || statep->state == vl_unknown || (!alldown && statep->state == vl_alldown)) { cm_InitReq(&req); + req.flags |= CM_REQ_OFFLINE_VOL_CHK; lock_ReleaseWrite(&volp->rw); do { code = cm_ConnFromVolume(volp, statep->ID, cm_rootUserp, &req, &connp); - if (code) + if (code) continue; rxconnp = cm_GetRxConn(connp); code = RXAFS_GetVolumeStatus(rxconnp, statep->ID, &volStat, &Name, &OfflineMsg, &MOTD); - rx_PutConnection(rxconnp); + rx_PutConnection(rxconnp); } while (cm_Analyze(connp, cm_rootUserp, &req, &fid, NULL, NULL, NULL, code)); code = cm_MapRPCError(code, &req); -- 1.9.4