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;
nextLeafNode = getnextnode(leafNode);
}
+ enump->dscp = scp;
+
done:
if (!locked)
lock_ReleaseRead(&scp->dirlock);
/* 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);
}
}
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;
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);
}
} 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);