Windows: buf_GetNewLocked should use cleaned cm_buf

buf_GetNewLocked() searches the free buffer list for a buffer
that has a 0 refcnt, is not in the chunk that is being populated,
is not actively having I/O performed on it and is not dirty.
If it comes across a dirty buffer, it calls buf_Clean() with
the assumption that buf_CleanAsync() (as it was previously called)
was in fact asynchronous and would return immediately.  Instead
buf_Clean() is synchronous and when it completes the buffer will
in most cases be clean.  buf_GetNewLocked() should use the newly
cleaned buffer if it is still available and not continue the
search from the next entry in the free buffer list.

Change-Id: Iae629df57b9d27a813f7f4c6740be23bd33fe039
Reviewed-on: http://gerrit.openafs.org/6174
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
This commit is contained in:
Jeffrey Altman 2011-12-02 11:21:46 -05:00 committed by Jeffrey Altman
parent 7dccf17840
commit 500ffccfd6

View File

@ -1321,8 +1321,11 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *req
* a clean buffer, we rehash it, lock it and return it.
*/
for (bp = cm_data.buf_freeListEndp; bp; bp=(cm_buf_t *) osi_QPrev(&bp->q)) {
int cleaned = 0;
n_bufs++;
retry_2:
/* check to see if it really has zero ref count. This
* code can bump refcounts, at least, so it may not be
* zero.
@ -1366,6 +1369,10 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *req
if (bp->qFlags & CM_BUF_QREDIR)
continue;
/* protect against cleaning the same buffer more than once. */
if (cleaned)
continue;
/* if the buffer is dirty, start cleaning it and
* move on to the next buffer. We do this with
* just the lock required to minimize contention
@ -1405,7 +1412,16 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *req
lock_ReleaseRead(&scp->bufCreateLock);
return CM_BUF_EXISTS;
}
continue;
/*
* We just cleaned this buffer so we need to
* restart the loop with this buffer so it
* can be retested. Set 'cleaned' so we
* do not attempt another call to buf_Clean()
* if the prior attempt failed.
*/
cleaned = 1;
goto retry_2;
}
osi_Log3(afsd_logp, "buf_GetNewLocked: scp 0x%p examined %u buffers before recycling bufp 0x%p",