From: Marc Dionne Date: Sun, 7 Nov 2010 20:06:16 +0000 (-0500) Subject: Cache bypass: release and unlock pages when we get 0-length reply X-Git-Tag: upstream/1.6.0.pre2^2~149 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=8cc17dde65f0ce42802fb29f07e9e98001764fec;p=packages%2Fo%2Fopenafs.git Cache bypass: release and unlock pages when we get 0-length reply In some cases, such as reading past the end of file as known to the server, fetchdata will get a 0 length reply. Deal gracefully by unlocking and releasing any pages reserved by readpages. Failure to do so here leads to deadlocks later as we can exit with some pages still locked. Reviewed-on: http://gerrit.openafs.org/3283 Reviewed-by: Matt Benjamin Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry picked from commit e4250dc64eb26b5da1480e9f5bd58d016f81847f) Change-Id: I54dc4ef040b816596cf48edf866976943220d988 Reviewed-on: http://gerrit.openafs.org/3644 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c index ed12e0ed0..a636915f8 100644 --- a/src/afs/afs_bypasscache.c +++ b/src/afs/afs_bypasscache.c @@ -284,18 +284,18 @@ done: ciov = auio->uio_iov; \ iovmax = auio->uio_iovcnt - 1; \ pp = (struct page*) ciov->iov_base; \ - afs_warn("BYPASS: Unlocking pages..."); \ while(1) { \ - if(pp != NULL && PageLocked(pp)) \ - UnlockPage(pp); \ - put_page(pp); /* decrement refcount */ \ + if (pp) { \ + if (PageLocked(pp)) \ + UnlockPage(pp); \ + put_page(pp); /* decrement refcount */ \ + } \ iovno++; \ if(iovno > iovmax) \ break; \ ciov = (auio->uio_iov + iovno); \ pp = (struct page*) ciov->iov_base; \ } \ - afs_warn("Pages Unlocked.\n"); \ } while(0) #else #ifdef UKERNEL @@ -350,6 +350,13 @@ afs_NoCacheFetchProc(struct rx_call *acall, goto done; } + /* If we get a 0 length reply, time to cleanup and return */ + if (length == 0) { + unlock_and_release_pages(auio); + result = 0; + goto done; + } + /* * The fetch protocol is extended for the AFS/DFS translator * to allow multiple blocks of data, each with its own length,