From e2b42e2cde170102c07937d55db376416cb3965c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 31 Dec 2011 16:04:27 -0500 Subject: [PATCH] Windows: avoid deadlock if bulk error during enum If the cache manager has a valid callback at the start of a directory enumeration, the service can begin a bulk status rpc which can fail. The error code from the rpc is never propagated to the caller, therefore the caller loops forever attempting to complete the enumeration with status info. Fix it by returning the error. Change-Id: I53892ddf338152d53c533ef31c3b1047c96bfbf2 Reviewed-on: http://gerrit.openafs.org/6461 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_btree.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/WINNT/afsd/cm_btree.c b/src/WINNT/afsd/cm_btree.c index c9bb06817..a07ff5307 100644 --- a/src/WINNT/afsd/cm_btree.c +++ b/src/WINNT/afsd/cm_btree.c @@ -2709,6 +2709,8 @@ cm_BPlusDirEnumBulkStatNext(cm_direnum_t *enump) long cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp) { + long code; + if (enump == NULL || entrypp == NULL || enump->next >= enump->count) { if (entrypp) *entrypp = NULL; @@ -2717,8 +2719,11 @@ cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp) } if (enump->fetchStatus && - !(enump->entry[enump->next].flags & CM_DIRENUM_FLAG_GOT_STATUS)) - cm_BPlusDirEnumBulkStatNext(enump); + !(enump->entry[enump->next].flags & CM_DIRENUM_FLAG_GOT_STATUS)) { + code = cm_BPlusDirEnumBulkStatNext(enump); + if (code) + return code; + } *entrypp = &enump->entry[enump->next++]; if ( enump->next == enump->count ) { @@ -2734,6 +2739,8 @@ cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp) long cm_BPlusDirPeekNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp) { + long code; + if (enump == NULL || entrypp == NULL || enump->next >= enump->count) { if (entrypp) *entrypp = NULL; @@ -2742,8 +2749,11 @@ cm_BPlusDirPeekNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp) } if (enump->fetchStatus && - !(enump->entry[enump->next].flags & CM_DIRENUM_FLAG_GOT_STATUS)) - cm_BPlusDirEnumBulkStatNext(enump); + !(enump->entry[enump->next].flags & CM_DIRENUM_FLAG_GOT_STATUS)) { + code = cm_BPlusDirEnumBulkStatNext(enump); + if (code) + return code; + } *entrypp = &enump->entry[enump->next]; if ( enump->next == enump->count ) { -- 2.39.5