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>
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);