Windows: Add cm_req_t parameter to buf_Get* functions
[openafs.git] / src / WINNT / afsd / cm_dir.c
index d501255..c28edef 100644 (file)
@@ -98,7 +98,7 @@ static int
 cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * buffer, int flags);
 
 static long
-cm_DirCheckStatus(cm_dirOp_t * op, afs_uint32 locked);
+cm_DirCheckStatus(cm_dirOp_t * op, int locked);
 
 static long
 cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified);
@@ -116,12 +116,14 @@ cm_DirAddPage(cm_dirOp_t * op, int pageno);
 static long
 cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs);
 
+static long
+cm_DirPrefetchBuffers(cm_dirOp_t * op);
 
 /* compute how many 32 byte entries an AFS 3 dir requires for storing
  * the specified name.
  */
 long 
-cm_NameEntries(char *namep, long *lenp)
+cm_NameEntries(char *namep, size_t *lenp)
 {
     long i;
         
@@ -134,10 +136,10 @@ cm_NameEntries(char *namep, long *lenp)
    entry is a string name.
 
    On entry:
-       op->scp->mx is unlocked
+       op->scp->rw is unlocked
 
    On exit:
-       op->scp->mx is unlocked
+       op->scp->rw is unlocked
 
    None of the directory buffers for op->scp should be locked by the
    calling thread.
@@ -232,10 +234,10 @@ cm_DirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid)
 /* Return the length of a directory in pages
 
    On entry:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    On exit:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    The first directory page for op->scp should not be locked by the
    calling thread.
@@ -269,10 +271,10 @@ cm_DirLength(cm_dirOp_t * op)
 /* Delete a directory entry.
 
    On entry:
-       op->scp->mx is unlocked
+       op->scp->rw is unlocked
 
    On exit:
-       op->scp->mx is unlocked
+       op->scp->rw is unlocked
 
    None of the directory buffers for op->scp should be locked by the
    calling thread.
@@ -338,7 +340,7 @@ cm_DirDeleteEntry(cm_dirOp_t * op, char *entry)
 
 /* Find a bunch of contiguous entries; at least nblobs in a row.
 
-   Called with op->scp->mx */
+   Called with op->scp->rw */
 static long
 cm_DirFindBlobs(cm_dirOp_t * op, int nblobs)
 {
@@ -393,6 +395,9 @@ cm_DirFindBlobs(cm_dirOp_t * op, int nblobs)
                 dhpModified = TRUE;
            }
 
+            /* the create flag is not set for the GetPage call below
+               since the page should have been added if necessary
+               above. */
             code = cm_DirGetPage(op, i, &pagebuf, &pp);
             if (code) {
                 cm_DirReleasePage(op, &dhpbuf, dhpModified);
@@ -442,7 +447,7 @@ cm_DirFindBlobs(cm_dirOp_t * op, int nblobs)
 
 /* Add a page to a directory. 
 
-   Called with op->scp->mx
+   Called with op->scp->rw
 */
 static long
 cm_DirAddPage(cm_dirOp_t * op, int pageno)
@@ -475,7 +480,7 @@ cm_DirAddPage(cm_dirOp_t * op, int pageno)
 
 /* Free a whole bunch of directory entries.
 
-   Called with op->scp->mx
+   Called with op->scp->rw
 */
 static long
 cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs)
@@ -526,7 +531,7 @@ cm_DirFreeBlobs(cm_dirOp_t * op, int firstblob, int nblobs)
  * directory header page are allocated, 1 to the page header, 4 to the
  * allocation map and 8 to the hash table.
  *
- * Called with op->scp->mx unlocked
+ * Called with op->scp->rw unlocked
  */
 int
 cm_DirMakeDir(cm_dirOp_t * op, cm_fid_t * me, cm_fid_t * parent)
@@ -572,13 +577,14 @@ cm_DirMakeDir(cm_dirOp_t * op, cm_fid_t * me, cm_fid_t * parent)
     return rc;
 }
 
+
 /* Look up a file name in directory.
 
    On entry:
-       op->scp->mx is unlocked
+       op->scp->rw is unlocked
 
    On exit:
-       op->scp->mx is unlocked
+       op->scp->rw is unlocked
 
    None of the directory buffers for op->scp should be locked by the
    calling thread.
@@ -594,6 +600,8 @@ cm_DirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid)
     LARGE_INTEGER       start;
     LARGE_INTEGER       end;
 
+    lock_AssertNone(&op->scp->rw);
+
     QueryPerformanceCounter(&start);
 
     osi_Log2(afsd_logp, "cm_DirLookup for op 0x%p, entry[%s]",
@@ -602,6 +610,14 @@ cm_DirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid)
     code = cm_DirFindItem(op, entry,
                           &itembuf, &firstitem,
                           &pibuf, &previtem);
+
+    if (code == CM_ERROR_NOTINCACHE) {
+        code = cm_DirPrefetchBuffers(op);
+        if (code == 0)
+            code = cm_DirFindItem(op, entry, &itembuf, &firstitem,
+                                  &pibuf, &previtem);
+    }
+
     if (code != 0) {
         dir_lookup_misses++;
         code = ENOENT;
@@ -634,10 +650,10 @@ cm_DirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid)
 /* Look up a file name in directory.
 
    On entry:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    On exit:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    None of the directory buffers for op->scp should be locked by the
    calling thread.
@@ -692,10 +708,10 @@ cm_DirLookupOffset(cm_dirOp_t * op, char *entry, cm_fid_t *cfid, osi_hyper_t *of
 /* Apply a function to every directory entry in a directory.
 
    On entry:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    On exit:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    None of the directory buffers for op->scp should be locked by the
    calling thread.
@@ -747,10 +763,10 @@ cm_DirApply(cm_dirOp_t * op, int (*hookproc) (void *, char *, long, long), void
 /* Check if a directory is empty
 
    On entry:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    On exit:
-       op->scp->mx is locked
+       op->scp->rw is locked
 
    None of the directory buffers for op->scp should be locked by the
    calling thread.
@@ -800,15 +816,15 @@ cm_DirIsEmpty(cm_dirOp_t * op)
 /* Return a pointer to an entry, given its number.
 
    On entry:
-     scp->mx locked
+     scp->rw locked
      if *bufferpp != NULL, then *bufferpp->mx is locked
 
    During:
-     scp->mx may be unlocked
+     scp->rw may be unlocked
      *bufferpp may be released
 
    On exit:
-     scp->mx locked
+     scp->rw locked
      if *bufferpp != NULL, then *bufferpp->mx is locked
 
      *bufferpp should be released via cm_DirReleasePage() or any other
@@ -838,9 +854,9 @@ int
 cm_DirHash(char *string)
 {
     /* Hash a string to a number between 0 and NHASHENT. */
-    register unsigned char tc;
-    register int hval;
-    register int tval;
+    unsigned char tc;
+    int hval;
+    int tval;
     hval = 0;
     while ((tc = (*string++))) {
        hval *= 173;
@@ -861,10 +877,10 @@ cm_DirHash(char *string)
  * pointer is returned instead.
  *
  * On entry:
- *  scp->mx locked
+ *  scp->rw locked
  *
  * On exit:
- *  scp->mx locked
+ *  scp->rw locked
  */
 static long
 cm_DirFindItem(cm_dirOp_t * op,
@@ -957,7 +973,7 @@ cm_DirFindItem(cm_dirOp_t * op,
 }
 
 /* Begin a sequence of directory operations.  
- * Called with scp->mx unlocked.
+ * Called with scp->rw unlocked.
  */
 long
 cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
@@ -975,7 +991,7 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
     op->scp = scp;
     cm_HoldUser(userp);
     op->userp = userp;
-    cm_InitReq(&op->req);
+    op->req = *reqp;            /* copy the values from the input */
 
     op->dirtyBufCount = 0;
     op->nBuffers = 0;
@@ -991,7 +1007,7 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
         lock_ObtainRead(&scp->dirlock);
         haveWrite = 0;
     }
-    lock_ObtainMutex(&scp->mx);
+    lock_ObtainWrite(&scp->rw);
     mxheld = 1;
     code = cm_DirCheckStatus(op, 1);
     if (code == 0) {
@@ -1027,15 +1043,14 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
               repeat:
                 if (!haveWrite) {
                     if (mxheld) {
-                        lock_ReleaseMutex(&scp->mx);
+                        lock_ReleaseWrite(&scp->rw);
                         mxheld = 0;
                     }
-                    lock_ReleaseRead(&scp->dirlock);
-                    lock_ObtainWrite(&scp->dirlock);
+                    lock_ConvertRToW(&scp->dirlock);
                     haveWrite = 1;
                 }
                 if (!mxheld) {
-                    lock_ObtainMutex(&scp->mx);
+                    lock_ObtainWrite(&scp->rw);
                     mxheld = 1;
                 }
                 if (scp->dirBplus && 
@@ -1045,17 +1060,17 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
                     bplus_free_tree++;
                     freeBtree(scp->dirBplus);
                     scp->dirBplus = NULL;
-                    scp->dirDataVersion = -1;
+                    scp->dirDataVersion = CM_SCACHE_VERSION_BAD;
                 }
 
                 if (!scp->dirBplus) {
                     if (mxheld) {
-                        lock_ReleaseMutex(&scp->mx);
+                        lock_ReleaseWrite(&scp->rw);
                         mxheld = 0;
                     }
                     cm_BPlusDirBuildTree(scp, userp, reqp);
                     if (!mxheld) {
-                        lock_ObtainMutex(&scp->mx);
+                        lock_ObtainWrite(&scp->rw);
                         mxheld = 1;
                     }
                     if (op->dataVersion != scp->dataVersion) {
@@ -1106,14 +1121,14 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
 #endif
         op->lockType = lockType;
         if (mxheld)
-            lock_ReleaseMutex(&scp->mx);
+            lock_ReleaseWrite(&scp->rw);
     } else {
         if (haveWrite)
             lock_ReleaseWrite(&scp->dirlock);
         else
             lock_ReleaseRead(&scp->dirlock);
         if (mxheld)
-            lock_ReleaseMutex(&scp->mx);
+            lock_ReleaseWrite(&scp->rw);
         cm_EndDirOp(op);
     }
 
@@ -1121,7 +1136,7 @@ cm_BeginDirOp(cm_scache_t * scp, cm_user_t * userp, cm_req_t * reqp,
 }
 
 /* Check if it is safe for us to perform local directory updates.
-   Called with scp->mx unlocked. */
+   Called with op->scp->rw unlocked. */
 int
 cm_CheckDirOpForSingleChange(cm_dirOp_t * op)
 {
@@ -1131,7 +1146,7 @@ cm_CheckDirOpForSingleChange(cm_dirOp_t * op)
     if (op->scp == NULL)
         return 0;
 
-    lock_ObtainMutex(&op->scp->mx);
+    lock_ObtainWrite(&op->scp->rw);
     code = cm_DirCheckStatus(op, 1);
 
     if (code == 0 &&
@@ -1144,19 +1159,19 @@ cm_CheckDirOpForSingleChange(cm_dirOp_t * op)
 
         rc = 1;
     }
-    lock_ReleaseMutex(&op->scp->mx); 
+    lock_ReleaseWrite(&op->scp->rw); 
     
     if (rc)
         osi_Log0(afsd_logp, "cm_CheckDirOpForSingleChange succeeded");
     else
         osi_Log3(afsd_logp,
-                 "cm_CheckDirOpForSingleChange failed.  code=0x%x, old dv=%I64d, new dv=%I64d",
+                 "cm_CheckDirOpForSingleChange failed.  code=0x%x, old dv=%d, new dv=%d",
                  code, op->dataVersion, op->scp->dataVersion);
     return rc;
 }
 
 /* End a sequence of directory operations.  
- * Called with op->scp->mx unlocked.*/
+ * Called with op->scp->rw unlocked.*/
 long
 cm_EndDirOp(cm_dirOp_t * op)
 {
@@ -1192,9 +1207,10 @@ cm_EndDirOp(cm_dirOp_t * op)
 
         /* we made changes.  We should go through the list of buffers
          * and update the dataVersion for each. */
-        lock_ObtainMutex(&op->scp->mx);
+        lock_ObtainWrite(&op->scp->rw);
         code = buf_ForceDataVersion(op->scp, op->dataVersion, op->newDataVersion);
-        lock_ReleaseMutex(&op->scp->mx);
+        op->scp->flags |= CM_SCACHEFLAG_LOCAL;
+        lock_ReleaseWrite(&op->scp->rw);
     }
 
     switch (op->lockType) {
@@ -1221,7 +1237,7 @@ cm_EndDirOp(cm_dirOp_t * op)
     return code;
 }
 
-/* NOTE: Called without scp->mx and without bufferp->mx */
+/* NOTE: Called without scp->rw and without bufferp->mx */
 static long
 cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
 {
@@ -1260,7 +1276,7 @@ cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
         osi_assert(i < CM_DIROP_MAXBUFFERS);
 
         lock_ObtainMutex(&bufferp->mx);
-        lock_ObtainMutex(&op->scp->mx);
+        lock_ObtainWrite(&op->scp->rw);
 
         /* Make sure we are synchronized. */
         osi_assert(op->lockType != CM_DIRLOCK_NONE);
@@ -1271,18 +1287,18 @@ cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
                          CM_SCACHESYNC_BUFLOCKED);
 
         if (code == 0 && bufferp->dataVersion != op->dataVersion) {
-            osi_Log2(afsd_logp, "cm_DirOpAddBuffer: buffer data version mismatch. buf dv = %I64d. needs %I64d", 
-                     bufferp->dataVersion, op->dataVersion);
-
-            cm_SyncOpDone(op->scp, bufferp,
-                          CM_SCACHESYNC_NEEDCALLBACK |
-                         (op->lockType == CM_DIRLOCK_WRITE ? CM_SCACHESYNC_WRITE : CM_SCACHESYNC_READ) |
-                          CM_SCACHESYNC_BUFLOCKED);
-
-            code = CM_ERROR_INVAL;
+                osi_Log2(afsd_logp,
+                         "cm_DirOpAddBuffer: buffer data version mismatch. buf dv = %d. needs %d", 
+                         bufferp->dataVersion, op->dataVersion);
+
+                cm_SyncOpDone(op->scp, bufferp,
+                              CM_SCACHESYNC_NEEDCALLBACK |
+                              (op->lockType == CM_DIRLOCK_WRITE ? CM_SCACHESYNC_WRITE : CM_SCACHESYNC_READ) |
+                              CM_SCACHESYNC_BUFLOCKED);
+            code = CM_ERROR_NOTINCACHE;
         }
 
-        lock_ReleaseMutex(&op->scp->mx);
+        lock_ReleaseWrite(&op->scp->rw);
         lock_ReleaseMutex(&bufferp->mx);
 
         if (code) {
@@ -1304,7 +1320,7 @@ cm_DirOpAddBuffer(cm_dirOp_t * op, cm_buf_t * bufferp)
     }
 }
 
-/* Note: Called without op->scp->mx */
+/* Note: Called without op->scp->rw */
 static int
 cm_DirOpFindBuffer(cm_dirOp_t * op, osi_hyper_t offset, cm_buf_t ** bufferpp)
 {
@@ -1333,7 +1349,7 @@ cm_DirOpFindBuffer(cm_dirOp_t * op, osi_hyper_t offset, cm_buf_t ** bufferpp)
 }
 
 
-/* NOTE: called with scp->mx held or not depending on the flags */
+/* NOTE: called with scp->rw held or not depending on the flags */
 static int
 cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
 {
@@ -1365,7 +1381,7 @@ cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
                version of the buffer with the data version of the
                scp. */
             if (!(flags & DIROP_SCPLOCKED)) {
-                lock_ObtainMutex(&op->scp->mx);
+                lock_ObtainWrite(&op->scp->rw);
             }
 
             /* first make sure that the buffer is idle.  It should
@@ -1382,12 +1398,12 @@ cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
             osi_assert(bufferp->dataVersion == op->dataVersion);
 #endif
 
-            lock_ReleaseMutex(&op->scp->mx);
+            lock_ReleaseWrite(&op->scp->rw);
 
             lock_ObtainMutex(&bufferp->mx);
 
             if (flags & DIROP_SCPLOCKED) {
-                lock_ObtainMutex(&op->scp->mx);
+                lock_ObtainWrite(&op->scp->rw);
             }
 
             if (flags & DIROP_MODIFIED) {
@@ -1432,25 +1448,25 @@ cm_DirOpDelBuffer(cm_dirOp_t * op, cm_buf_t * bufferp, int flags)
    This should be called before cm_DirGetPage() is called per scp.
 
    On entry:
-     scp->mx locked state indicated by parameter
+     scp->rw locked state indicated by parameter
 
    On exit:
-     scp->mx same state as upon entry
+     scp->rw same state as upon entry
 
    During:
-     scp->mx may be released
+     scp->rw may be released
  */
 static long
-cm_DirCheckStatus(cm_dirOp_t * op, afs_uint32 locked)
+cm_DirCheckStatus(cm_dirOp_t * op, int scp_locked)
 {
     long code;
 
-    if (!locked)
-        lock_ObtainMutex(&op->scp->mx);
+    if (!scp_locked)
+        lock_ObtainWrite(&op->scp->rw);
     code = cm_SyncOp(op->scp, NULL, op->userp, &op->req, PRSFS_LOOKUP,
                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-    if (!locked)
-        lock_ReleaseMutex(&op->scp->mx);
+    if (!scp_locked)
+        lock_ReleaseWrite(&op->scp->rw);
 
     osi_Log2(afsd_logp, "cm_DirCheckStatus for op 0x%p returning code 0x%x",
              op, code);
@@ -1458,11 +1474,92 @@ cm_DirCheckStatus(cm_dirOp_t * op, afs_uint32 locked)
     return code;
 }
 
+/* Attempt to prefetch all the buffers for this operation.
+
+   Called with scp->rw unlocked
+ */
+static long
+cm_DirPrefetchBuffers(cm_dirOp_t * op)
+{
+    long code = 0;
+    osi_hyper_t offset;
+    cm_buf_t *bufferp = NULL;
+
+    osi_Log1(afsd_logp, "cm_DirPrefetchBuffers for op 0x%p", op);
+
+    /* prefetching is only done on read operations where we don't
+       expect the data version to change. */
+    if (op->dataVersion != op->newDataVersion) {
+        osi_Log0(afsd_logp, "Skipping prefetch for write operation.");
+        return CM_ERROR_INVAL;
+    }
+
+    lock_ObtainWrite(&op->scp->rw);
+
+    /* When we are prefetching a file, we first flush out any of its
+       contents just to make sure that we don't end up with buffers
+       that was locally modified. */
+
+    if (op->scp->flags & CM_SCACHEFLAG_LOCAL)
+        op->scp->bufDataVersionLow = op->scp->dataVersion;
+
+    offset = ConvertLongToLargeInteger(0);
+    while (LargeIntegerLessThan(offset, op->scp->length)) {
+        osi_Log2(afsd_logp, "Trying prefetch for offset %08x:%08x",
+                 offset.HighPart, offset.LowPart);
+        lock_ReleaseWrite(&op->scp->rw);
+
+        code = buf_Get(op->scp, &offset, &op->req, &bufferp);
+
+        lock_ObtainWrite(&op->scp->rw);
+
+        if (code)
+            break;
+
+        while (1) {
+
+            code = cm_SyncOp(op->scp, bufferp, op->userp, &op->req, PRSFS_LOOKUP,
+                             CM_SCACHESYNC_NEEDCALLBACK |
+                             (op->lockType == CM_DIRLOCK_WRITE ? CM_SCACHESYNC_WRITE : CM_SCACHESYNC_READ));
+
+            if (code)
+                break;
+
+            cm_SyncOpDone(op->scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK |
+                          (op->lockType == CM_DIRLOCK_WRITE ? CM_SCACHESYNC_WRITE : CM_SCACHESYNC_READ));
+
+            if (cm_HaveBuffer(op->scp, bufferp, 0))
+                break;
+
+            code = cm_GetBuffer(op->scp, bufferp, NULL, op->userp, &op->req);
+            if (code)
+                break;
+        }
+
+        if (code)
+            break;
+
+        if (bufferp) {
+            buf_Release(bufferp);
+            bufferp = NULL;
+        }
+
+        offset = LargeIntegerAdd(offset, ConvertLongToLargeInteger(cm_data.buf_blockSize));
+    }
+
+ done:
+    lock_ReleaseWrite(&op->scp->rw);
+
+    osi_Log1(afsd_logp, "cm_DirPrefetchBuffers returning code 0x%x", code);
+
+    return code;
+}
+
 /* Release a directory buffer that was obtained via a call to
    cm_DirGetPage() or any other function that returns a locked, held,
    directory page buffer.
 
-   Called with scp->mx unlocked
+   Called with scp->rw unlocked
  */
 static long
 cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified)
@@ -1497,20 +1594,23 @@ cm_DirReleasePage(cm_dirOp_t * op, cm_buf_t ** bufferpp, int modified)
    released and a new buffer returned that contains the requested
    page.
 
+   If the specified page exists beyond the EOF for the scp, a new
+   buffer will be allocated only if create is set to TRUE.
+
    Note: If a buffer is specified on entry via bufferpp, it is assumed
    that the buffer is unmodified.  If the buffer is modified, it
    should be released via cm_DirReleasePage().
 
    On entry:
-     scp->mx unlocked.
+     scp->rw unlocked.
      If *bufferpp is non-NULL, then *bufferpp->mx is locked.
 
    On exit:
-     scp->mx unlocked
+     scp->rw unlocked
      If *bufferpp is non-NULL, then *bufferpp->mx is locked.
 
    During:
-     scp->mx will be obtained and released
+     scp->rw will be obtained and released
 
  */
 static long
@@ -1557,7 +1657,7 @@ cm_DirGetPage(cm_dirOp_t * op,
             goto _has_buffer;
         }
 
-        code = buf_Get(op->scp, &bufferOffset, &bufferp);
+        code = buf_Get(op->scp, &bufferOffset, &op->req, &bufferp);
         if (code) {
             osi_Log1(afsd_logp, "    buf_Get returned code 0x%x", code);
             bufferp = NULL;
@@ -1577,50 +1677,6 @@ cm_DirGetPage(cm_dirOp_t * op,
             bufferp = NULL;
             goto _exit;
         }
-
-#if 0
-        /* The code below is for making sure the buffer contains
-           current data.  This is a bad idea, since the whole point of
-           doing directory updates locally is to avoid fetching all
-           the data from the server. */
-        while (1) {
-            lock_ObtainMutex(&op->scp->mx);
-            code = cm_SyncOp(op->scp, bufferp, op->userp, &op->req, PRSFS_LOOKUP,
-                             CM_SCACHESYNC_NEEDCALLBACK |
-                             CM_SCACHESYNC_READ |
-                             CM_SCACHESYNC_BUFLOCKED);
-
-            if (code) {
-                lock_ReleaseMutex(&op->scp->mx);
-                break;
-            }
-
-            cm_SyncOpDone(op->scp, bufferp,
-                          CM_SCACHESYNC_NEEDCALLBACK |
-                          CM_SCACHESYNC_READ |
-                          CM_SCACHESYNC_BUFLOCKED);
-
-            if (cm_HaveBuffer(op->scp, bufferp, 1)) {
-                lock_ReleaseMutex(&op->scp->mx);
-                break;
-            }
-
-            lock_ReleaseMutex(&bufferp->mx);
-            code = cm_GetBuffer(op->scp, bufferp, NULL, op->userp, &op->req);
-            lock_ReleaseMutex(&op->scp->mx);
-            lock_ObtainMutex(&bufferp->mx);
-
-            if (code)
-                break;
-        }
-
-        if (code) {
-            cm_DirOpDelBuffer(op, bufferp, 0);
-            buf_Release(bufferp);
-            bufferp = NULL;
-            goto _exit;
-        }
-#endif
     }
 
  _has_buffer: