lock_page(pp);
}
+ /* increment page refcount--our original design assumed
+ * that locking it would effectively pin it; protect
+ * ourselves from the possiblity that this assumption is
+ * is faulty, at low cost (provided we do not fail to
+ * do the corresponding decref on the other side) */
+ get_page(pp);
+
/* save the page for background map */
iovecp[page_ix].iov_base = (void*) pp;
* to be unlocked.
*/
#if defined(AFS_LINUX24_ENV)
-#define unlock_pages(auio) \
+#define unlock_and_release_pages(auio) \
do { \
struct iovec *ciov; \
struct page *pp; \
while(1) { \
if(pp != NULL && PageLocked(pp)) \
UnlockPage(pp); \
+ put_page(pp); /* decrement refcount */ \
iovno++; \
if(iovno > iovmax) \
break; \
} while(0)
#else
#ifdef UKERNEL
-#define unlock_pages(auio) \
+#define unlock_and_release_pages(auio) \
do { } while(0)
#else
#error AFS_CACHE_BYPASS not implemented on this platform
result = 0;
afs_warn("Preread error. code: %d instead of %d\n",
code, sizeof(afs_int32));
- unlock_pages(auio);
+ unlock_and_release_pages(auio);
goto done;
} else
length = ntohl(length);
result = EIO;
afs_warn("Preread error. Got length %d, which is greater than size %d\n",
length, size);
- unlock_pages(auio);
+ unlock_and_release_pages(auio);
goto done;
}
if (code < 0) {
afs_warn("afs_NoCacheFetchProc: rx_Read error. Return code was %d\n", code);
result = 0;
- unlock_pages(auio);
+ unlock_and_release_pages(auio);
goto done;
} else if (code == 0) {
result = 0;
afs_warn("afs_NoCacheFetchProc: rx_Read returned zero. Aborting.\n");
- unlock_pages(auio);
+ unlock_and_release_pages(auio);
goto done;
}
length -= code;
/* this is appropriate when no caller intends to unlock
* and release the page */
#ifdef AFS_LINUX24_ENV
- SetPageUptodate(pp);
- if(PageLocked(pp))
- UnlockPage(pp);
- else
- afs_warn("afs_NoCacheFetchProc: page not locked at iovno %d!\n", iovno);
+ SetPageUptodate(pp);
+ if(PageLocked(pp))
+ UnlockPage(pp);
+ else
+ afs_warn("afs_NoCacheFetchProc: page not locked at iovno %d!\n", iovno);
+ put_page(pp); /* decrement refcount */
#ifndef AFS_KMAP_ATOMIC
- kunmap(pp);
+ kunmap(pp);
#endif
#else
#ifndef UKERNEL
* processed, like unlocking the pages and freeing memory.
*/
#ifdef AFS_LINUX24_ENV
- unlock_pages(bparms->auio);
+ unlock_and_release_pages(bparms->auio);
#else
#ifndef UKERNEL
#error AFS_CACHE_BYPASS not implemented on this platform
bparms->length);
} else {
afs_warn("BYPASS: StartRXAFS_FetchData failed: %d\n", code);
- unlock_pages(auio);
+ unlock_and_release_pages(auio);
goto done;
}
if (code == 0) {
afs_warn("BYPASS: No connection.\n");
code = -1;
#ifdef AFS_LINUX24_ENV
- unlock_pages(auio);
+ unlock_and_release_pages(auio);
#else
#ifndef UKERNEL
#error AFS_CACHE_BYPASS not implemented on this platform