Windows: Add buf_FindAll() and buf_FindAllLocked()
[openafs.git] / src / WINNT / afsd / cm_buf.c
index 9e7e7ce..5b37eed 100644 (file)
@@ -684,6 +684,54 @@ cm_buf_t *buf_Find(struct cm_scache *scp, osi_hyper_t *offsetp)
     return bp;
 }       
 
+/* find a buffer, if any, for a particular file ID and offset.  Assumes
+ * that buf_globalLock is write locked when called.  Uses the all buffer
+ * list.
+ */
+cm_buf_t *buf_FindAllLocked(struct cm_scache *scp, osi_hyper_t *offsetp, afs_uint32 flags)
+{
+    cm_buf_t *bp;
+
+    if (flags == 0) {
+        for(bp = cm_data.buf_allp; bp; bp=bp->allp) {
+            if (cm_FidCmp(&scp->fid, &bp->fid) == 0
+                 && offsetp->LowPart == bp->offset.LowPart
+                 && offsetp->HighPart == bp->offset.HighPart) {
+                buf_HoldLocked(bp);
+                break;
+            }
+        }
+    } else {
+        for(bp = cm_data.buf_allp; bp; bp=bp->allp) {
+            if (cm_FidCmp(&scp->fid, &bp->fid) == 0) {
+                char * fileOffset;
+                
+                fileOffset = offsetp->QuadPart + cm_data.baseAddress;
+                if (fileOffset == bp->datap) {
+                    buf_HoldLocked(bp);
+                    break;
+                }
+            }
+        }
+    }
+    /* return whatever we found, if anything */
+    return bp;
+}
+
+/* find a buffer with offset *offsetp for vnode *scp.  Called
+ * with no locks held.  Use the all buffer list.
+ */
+cm_buf_t *buf_FindAll(struct cm_scache *scp, osi_hyper_t *offsetp, afs_uint32 flags)
+{
+    cm_buf_t *bp;
+
+    lock_ObtainRead(&buf_globalLock);
+    bp = buf_FindAllLocked(scp, offsetp, flags);
+    lock_ReleaseRead(&buf_globalLock);
+
+    return bp;
+}       
+
 /* start cleaning I/O on this buffer.  Buffer must be write locked, and is returned
  * write-locked.
  *
@@ -861,14 +909,11 @@ void buf_Recycle(cm_buf_t *bp)
  * space from the buffer pool.  In that case, the buffer will be returned
  * without being hashed into the hash table.
  */
-long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
+long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf_t **bufpp)
 {
     cm_buf_t *bp;      /* buffer we're dealing with */
     cm_buf_t *nextBp;  /* next buffer in file hash chain */
     afs_uint32 i;      /* temp */
-    cm_req_t req;
-
-    cm_InitReq(&req);  /* just in case */
 
 #ifdef TESTING
     buf_ValidateBufQueues();
@@ -969,7 +1014,7 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bu
                  * have the WRITING flag set, so we won't get
                  * back here.
                  */
-                buf_CleanAsync(bp, &req, NULL);
+                buf_CleanAsync(bp, reqp, NULL);
 
                 /* now put it back and go around again */
                 buf_Release(bp);
@@ -1061,7 +1106,7 @@ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bu
 /* get a page, returning it held but unlocked.  Doesn't fill in the page
  * with I/O, since we're going to write the whole thing new.
  */
-long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
+long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf_t **bufpp)
 {
     cm_buf_t *bp;
     long code;
@@ -1080,7 +1125,7 @@ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
         }
 
         /* otherwise, we have to create a page */
-        code = buf_GetNewLocked(scp, &pageOffset, &bp);
+        code = buf_GetNewLocked(scp, &pageOffset, reqp, &bp);
 
         /* check if the buffer was created in a race condition branch.
          * If so, go around so we can hold a reference to it. 
@@ -1113,7 +1158,7 @@ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
 
 /* get a page, returning it held but unlocked.  Make sure it is complete */
 /* The scp must be unlocked when passed to this function */
-long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
+long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_req_t *reqp, cm_buf_t **bufpp)
 {
     cm_buf_t *bp;
     long code;
@@ -1147,7 +1192,7 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
         }
 
         /* otherwise, we have to create a page */
-        code = buf_GetNewLocked(scp, &pageOffset, &bp);
+        code = buf_GetNewLocked(scp, &pageOffset, reqp, &bp);
        /* bp->mx is now held */
 
         /* check if the buffer was created in a race condition branch.