From b924e7827dbca97accb6a90da24264858e9a2964 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 16 Jan 2019 23:46:34 -0600 Subject: [PATCH] afs: Throw EIO in DRead on empty dir blob 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 Reviewed-by: Benjamin Kaduk (cherry picked from commit 86d04ea70fd2e99606b1d1b5b68d980d92e7a3cd) Change-Id: I067aae1f949051169225a3cc0bdba35ad76a4ec2 Reviewed-on: https://gerrit.openafs.org/13590 Reviewed-by: Cheyenne Wills Reviewed-by: Michael Meffie Reviewed-by: Mark Vitale Reviewed-by: Andrew Deason Tested-by: BuildBot Reviewed-by: Stephan Wiesand --- src/afs/afs_buffer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/afs/afs_buffer.c b/src/afs/afs_buffer.c index 8a1141d53..cb99d07fb 100644 --- a/src/afs/afs_buffer.c +++ b/src/afs/afs_buffer.c @@ -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); -- 2.39.5