windows-btree-dir-enum-20090126
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 26 Jan 2009 15:50:46 +0000 (15:50 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 26 Jan 2009 15:50:46 +0000 (15:50 +0000)
LICENSE MIT

Modify the cm_BPlusDirEnum interface:

* add the cm_scache_t * of the directory being enumerated to the
  cm_direnum_t object

* remove the cm_scache_t * from the cm_BPlusDirEnumBulkStat call
  now that it is part of the cm_direnum_t object

* maintain a reference to the cm_scache_t for the life of the
  cm_direnum_t object.  This ensures that the object cannot be
  recycled while the enumeration is in use.

src/WINNT/afsd/cm_btree.c
src/WINNT/afsd/cm_btree.h

index 88bd06e..ec5c853 100644 (file)
@@ -2186,6 +2186,12 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked,
     if (!locked)
        lock_ObtainRead(&scp->dirlock);
 
+    /* 
+     * Hold a reference to the directory so that it wont' be
+     * recycled while the enumeration is active. 
+     */
+    cm_HoldSCache(scp);
+
     if (scp->dirBplus == NULL) {
        osi_Log0(afsd_logp, "cm_BPlusDirEnumerate No BPlus Tree");
         rc = CM_ERROR_WOULDBLOCK;
@@ -2285,6 +2291,8 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked,
        nextLeafNode = getnextnode(leafNode);
     }   
 
+    enump->dscp = scp;
+
   done:
     if (!locked)
        lock_ReleaseRead(&scp->dirlock);
@@ -2292,7 +2300,10 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked,
     /* if we failed, cleanup any mess */
     if (rc != 0) {
        osi_Log0(afsd_logp, "cm_BPlusDirEnumerate rc != 0");
-       if (enump) {
+       
+        /* release the directory because we failed to generate an enumeration object */
+        cm_ReleaseSCache(scp);
+        if (enump) {
            for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
                free(enump->entry[count].name);
            }
@@ -2307,8 +2318,9 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked,
 }
 
 long 
-cm_BPlusDirEnumBulkStat(cm_scache_t *dscp, cm_direnum_t *enump, cm_user_t *userp, cm_req_t *reqp)
+cm_BPlusDirEnumBulkStat(cm_direnum_t *enump, cm_user_t *userp, cm_req_t *reqp)
 {
+    cm_scache_t *dscp = enump->dscp;
     cm_bulkStat_t *bsp;
     afs_uint32 count;
     afs_uint32 code;
@@ -2387,6 +2399,9 @@ cm_BPlusDirFreeEnumeration(cm_direnum_t *enump)
     osi_Log0(afsd_logp, "cm_BPlusDirFreeEnumeration");
 
     if (enump) {
+        /* Release the directory object */
+        cm_ReleaseSCache(enump->dscp);
+
        for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
            free(enump->entry[count].name);
        }
index 161e876..5989dfd 100644 (file)
@@ -159,16 +159,17 @@ typedef struct cm_direnum_entry {
 } cm_direnum_entry_t;
 
 typedef struct cm_direnum {
+    cm_scache_t        *dscp;
     afs_uint32         count;
     afs_uint32         next;
     cm_direnum_entry_t         entry[1];
 } cm_direnum_t;
 
-long cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, clientchar_t *maskp, cm_direnum_t **enumpp);
+long cm_BPlusDirEnumerate(cm_scache_t *dscp, afs_uint32 locked, clientchar_t *maskp, cm_direnum_t **enumpp);
 long cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp);
 long cm_BPlusDirFreeEnumeration(cm_direnum_t *enump);
 long cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked);
-long cm_BPlusDirEnumBulkStat(cm_scache_t *dscp, cm_direnum_t *enump, cm_user_t *userp, cm_req_t *reqp);
+long cm_BPlusDirEnumBulkStat(cm_direnum_t *enump, cm_user_t *userp, cm_req_t *reqp);
 
 long cm_InitBPlusDir(void);