From 470b57cc4a60d18aaab41a58b6a93f8baa3caead Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 7 Mar 2013 09:25:09 -0500 Subject: [PATCH] Windows: cm_BPlusDirEnumBulkStatNext index error In cm_BPlusDirEnumBulkStatNext the 'next' variable was being set even if the FileId was not added to the list of objects added to the cm_bulkStat array. Delay the assignment to ensure that 'next' refers to the first element in the array. In the CM_ERROR_BULKSTAT_FAILURE processing, 'next' is used to obtain a reference to the cm_scache object that is supposed to correlate to the [1] entry in the array. If 'next' == -1, there is no such entry. Add a conditional to ensure that 'next' is not used when its value is -1. Change-Id: I4ebc49de4bf67eee5a28790cd49f0128891cc202 Reviewed-on: http://gerrit.openafs.org/9450 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_btree.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/WINNT/afsd/cm_btree.c b/src/WINNT/afsd/cm_btree.c index f360c52..b6a9f0e 100644 --- a/src/WINNT/afsd/cm_btree.c +++ b/src/WINNT/afsd/cm_btree.c @@ -2753,8 +2753,6 @@ cm_BPlusDirEnumBulkStatNext(cm_direnum_t *enump) continue; } - if (next == -1) - next = count; tscp = cm_FindSCache(&enump->entry[count].fid); if (tscp) { if (lock_TryWrite(&tscp->rw)) { @@ -2775,6 +2773,10 @@ cm_BPlusDirEnumBulkStatNext(cm_direnum_t *enump) cm_ReleaseSCache(tscp); } /* found entry */ + /* 'next' is the enump entry that is stored in the [bsp->counter == 1] element */ + if (next == -1) + next = count; + bsp->fids[bsp->counter].Volume = enump->entry[count].fid.volume; bsp->fids[bsp->counter].Vnode = enump->entry[count].fid.vnode; bsp->fids[bsp->counter].Unique = enump->entry[count].fid.unique; @@ -2792,19 +2794,22 @@ cm_BPlusDirEnumBulkStatNext(cm_direnum_t *enump) *(bs_flagsp[i]) &= ~CM_DIRENUM_FLAG_GOT_STATUS; } - code = cm_GetSCache(&enump->entry[next].fid, NULL, &tscp, userp, &req); - if (code == 0) { - if (lock_TryWrite(&tscp->rw)) { - code = cm_SyncOp(tscp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - lock_ReleaseWrite(&tscp->rw); + /* if next == -1, there is no entry to update the status of */ + if (next != -1) { + code = cm_GetSCache(&enump->entry[next].fid, NULL, &tscp, userp, &req); + if (code == 0) { + if (lock_TryWrite(&tscp->rw)) { + code = cm_SyncOp(tscp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&tscp->rw); + *(bs_errorCodep[1]) = code; + *(bs_flagsp[1]) |= CM_DIRENUM_FLAG_GOT_STATUS; + } + cm_ReleaseSCache(tscp); + } else { *(bs_errorCodep[1]) = code; *(bs_flagsp[1]) |= CM_DIRENUM_FLAG_GOT_STATUS; } - cm_ReleaseSCache(tscp); - } else { - *(bs_errorCodep[1]) = code; - *(bs_flagsp[1]) |= CM_DIRENUM_FLAG_GOT_STATUS; } goto done; } -- 1.9.4