LINUX vcache lock ordering in afs_linux_readdir
[openafs.git] / src / afs / LINUX / osi_vnodeops.c
index ca1998a..57dc081 100644 (file)
@@ -296,8 +296,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
        code = -ENOENT;
        goto out;
     }
-    ObtainSharedLock(&avc->lock, 810);
-    UpgradeSToWLock(&avc->lock, 811);
+    ObtainWriteLock(&avc->lock, 811);
     ObtainReadLock(&tdc->lock);
     /*
      * Make sure that the data in the cache is current. There are two
@@ -309,15 +308,15 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
           && (tdc->dflags & DFFetching)
           && hsame(avc->f.m.DataVersion, tdc->f.versionNo)) {
        ReleaseReadLock(&tdc->lock);
-       ReleaseSharedLock(&avc->lock);
+       ReleaseWriteLock(&avc->lock);
        afs_osi_Sleep(&tdc->validPos);
-       ObtainSharedLock(&avc->lock, 812);
+       ObtainWriteLock(&avc->lock, 812);
        ObtainReadLock(&tdc->lock);
     }
     if (!(avc->f.states & CStatd)
        || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) {
        ReleaseReadLock(&tdc->lock);
-       ReleaseSharedLock(&avc->lock);
+       ReleaseWriteLock(&avc->lock);
        afs_PutDCache(tdc);
        goto tagain;
     }
@@ -340,7 +339,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
        if (!dirpos)
            break;
 
-       code = afs_dir_GetVerifiedBlob(tdc, dirpos, &de);
+       code = afs_dir_GetVerifiedBlob(tdc, dirpos, &entry);
        if (code) {
            afs_warn("Corrupt directory (inode %lx, dirpos %d)",
                     (unsigned long)&tdc->f.inode, dirpos);
@@ -350,6 +349,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
            goto out;
         }
 
+       de = (struct DirEntry *)entry.data;
        ino = afs_calc_inum (avc->f.fid.Cell, avc->f.fid.Fid.Volume,
                             ntohl(de->fid.vnode));
        len = strlen(de->name);