From c9cd05263b478d116e9c240953827e34fe2559b4 Mon Sep 17 00:00:00 2001 From: Jeffrey Hutzelman Date: Wed, 12 Jun 2013 16:22:36 -0400 Subject: [PATCH] libafs/LINUX: avoid leaks due to corrupt dir 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. Reviewed-on: http://gerrit.openafs.org/9971 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit a2bfa0e853fb4954fd06a00ea6fbc55c39e76b8a) Change-Id: Id648822cd45087e5c0d320e8cfdcd6659bb33559 Reviewed-on: http://gerrit.openafs.org/11707 Reviewed-by: Perry Ruiter Reviewed-by: Daria Brashear Reviewed-by: Benjamin Kaduk Tested-by: BuildBot Reviewed-by: Stephan Wiesand --- src/afs/LINUX/osi_vnodeops.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 959e3209c..ea274f6d0 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -392,10 +392,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; } ino = afs_calc_inum(avc->f.fid.Cell, avc->f.fid.Fid.Volume, @@ -461,7 +459,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); @@ -469,7 +469,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); -- 2.39.5