libafs/LINUX: avoid leaks due to corrupt dir
authorJeffrey Hutzelman <jhutz@cmu.edu>
Wed, 12 Jun 2013 20:22:36 +0000 (16:22 -0400)
committerDerrick Brashear <shadow@your-file-system.com>
Fri, 12 Jul 2013 15:45:00 +0000 (08:45 -0700)
When a corrupt directory is discovered, scanning stops immediately and
readdir returns ENOENT.  Currently, the vcache lock is unlocked and the
dcache containing the directory is released, but that's not enough.
It's also necessary to unlock the dcache, on which we hold a read lock,
and to clear the vcache state which records an in-progress readdir.

Change-Id: I408e8bc8b1f4a0ebc1740410da5d760f30b4c875
Reviewed-on: http://gerrit.openafs.org/9971
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>

src/afs/LINUX/osi_vnodeops.c

index 25cbac2..ce59f6e 100644 (file)
@@ -368,10 +368,8 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
        if (code) {
            afs_warn("Corrupt directory (inode %lx, dirpos %d)",
                     (unsigned long)&tdc->f.inode, dirpos);
-           ReleaseSharedLock(&avc->lock);
-           afs_PutDCache(tdc);
            code = -ENOENT;
-           goto out;
+           goto unlock_out;
         }
 
        de = (struct DirEntry *)entry.data;
@@ -438,7 +436,9 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
 #else
     fp->f_pos = (loff_t) offset;
 #endif
+    code = 0;
 
+unlock_out:
     ReleaseReadLock(&tdc->lock);
     afs_PutDCache(tdc);
     UpgradeSToWLock(&avc->lock, 813);
@@ -446,7 +446,6 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
     avc->dcreaddir = 0;
     avc->readdir_pid = 0;
     ReleaseSharedLock(&avc->lock);
-    code = 0;
 
 out:
     afs_PutFakeStat(&fakestat);