afs: fix for return an error from afs_readdir when out of buffers
authorMichael Meffie <mmeffie@sinenomine.net>
Tue, 13 Oct 2015 02:16:54 +0000 (22:16 -0400)
committerBenjamin Kaduk <kaduk@mit.edu>
Wed, 11 Nov 2015 15:26:59 +0000 (10:26 -0500)
Commit 9b0d5f274fe79ccc5dd0e4bba86b3f52b27d3586 added a return code to
BlobScan to allow afs_readdir to return an error when afs_newslot failed
to allocate a buffer.  Unfortunately, that change introduced a false
EIO error.

Originally, BlobScan would return a blob number of 0 to indicate the end
of the file has been reached while traversing the directory blobs.
Restore that behavior by changing the cache manager's DRead function to
return ENOENT instead of the generic EIO error to indicate the page to
be read is out of bounds, and change BlobScan to return a blob of zero
to indicate to callers the last blob has been reached.  All callers
already check for a blob number of zero, which is out of range.

Change-Id: I5baae8e5377dd49dcca6765b7a4ddc89cca70738
Reviewed-on: http://gerrit.openafs.org/12058
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Tested-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/VNOPS/afs_vnop_readdir.c
src/afs/afs_buffer.c

index 83e76dd..9efe8eb 100644 (file)
@@ -53,7 +53,9 @@
  *
  * Note that BlobScan switches pages if necessary.  BlobScan may
  * return either 0 for success or an error code.  Upon successful
- * return, the new blob value is assigned to *ablobOut.
+ * return, the new blob value is assigned to *ablobOut.  The new
+ * blob value (*ablobOut) is set to 0 when the end of the file has
+ * been reached.
  *
  * BlobScan is used by the Linux port in a separate file, so it should not
  * become static.
@@ -73,6 +75,10 @@ BlobScan(struct dcache * afile, afs_int32 ablob, int *ablobOut)
     while (1) {
        pageBlob = ablob & ~(EPP - 1);  /* base blob in same page */
        code = afs_dir_GetBlob(afile, pageBlob, &headerbuf);
+       if (code == ENOENT) {
+           *ablobOut = 0; /* past the end of file */
+           return 0;      /* not an error */
+       }
        if (code)
            return code;
        tpe = (struct PageHeader *)headerbuf.data;
index 2810d9d..4399473 100644 (file)
@@ -236,7 +236,7 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
        afs_reset_inode(&tb->inode);
        tb->lockers--;
        ReleaseWriteLock(&tb->lock);
-       return EIO;
+       return ENOENT; /* past the end */
     }
     tfile = afs_CFileOpen(&adc->f.inode);
     code =