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.

Change-Id: Ic9e496c8c64d5e94f2cf9976d160ef5873f27249
Reviewed-on: http://gerrit.openafs.org/3283
Reviewed-by: Matt Benjamin <matt@linuxbox.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Marc Dionne 2010-11-07 15:06:16 -05:00 committed by Derrick Brashear
parent f78b29b900
commit e4250dc64e

View File

@ -285,18 +285,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
@ -355,6 +355,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,