]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: avoid deadlock if bulk error during enum
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 31 Dec 2011 21:04:27 +0000 (16:04 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 31 Dec 2011 21:22:35 +0000 (13:22 -0800)
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 <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
src/WINNT/afsd/cm_btree.c

index c9bb068177071e79d86a062f5f1b535341fe2e28..a07ff53071b3260c9d0f89b4563f088f32d2d49c 100644 (file)
@@ -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 ) {