]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
afs: Throw EIO in DRead on empty dir blob
authorAndrew Deason <adeason@sinenomine.net>
Thu, 17 Jan 2019 05:46:34 +0000 (23:46 -0600)
committerStephan Wiesand <stephan.wiesand@desy.de>
Mon, 10 Jun 2019 12:06:22 +0000 (08:06 -0400)
DRead currently returns ENOENT if we try to read a page beyond the end
of the given dir blob. We do this to indicate we've hit EOF, but we do
this even if the dir blob is completely empty (which is not a valid
dir blob).

If a dir blob in the cache is truncated due to cache corruption
issues, that means we'll indicate a normal EOF condition in that
directory for most code paths. If someone is trying to list the
directory's entries, for instance, we'll just return that there are no
entries in the dir, even though the dir itself is just invalid.

To avoid this for at least some cases, return an EIO error instead if
the dir blob is completely empty.

Reviewed-on: https://gerrit.openafs.org/13429
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit 86d04ea70fd2e99606b1d1b5b68d980d92e7a3cd)

Change-Id: I067aae1f949051169225a3cc0bdba35ad76a4ec2
Reviewed-on: https://gerrit.openafs.org/13590
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
src/afs/afs_buffer.c

index 8a1141d53b8a825dc2ab8b0e1ee0ddc3895b1909..cb99d07fb91b219d06593a28c766aae6978bea49 100644 (file)
@@ -231,12 +231,20 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
     ObtainWriteLock(&tb->lock, 260);
     tb->lockers++;
     ReleaseWriteLock(&afs_bufferLock);
-    if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) {
+    code = 0;
+    if (adc->f.chunk == 0 && adc->f.chunkBytes == 0) {
+        /* The directory blob is empty, apparently. This is not a valid dir
+         * blob, so throw an error. */
+        code = EIO;
+    } else if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) {
+        code = ENOENT; /* past the end */
+    }
+    if (code) {
        tb->fid = NULLIDX;
        afs_reset_inode(&tb->inode);
        tb->lockers--;
        ReleaseWriteLock(&tb->lock);
-       return ENOENT; /* past the end */
+       return code;
     }
     tfile = afs_CFileOpen(&adc->f.inode);
     osi_Assert(tfile);