}
                        bytes += req->wb_bytes;
                        nfs_list_remove_request(req);
-                       nfs_direct_readpage_release(req);
                        if (!PageCompound(page))
                                set_page_dirty(page);
-                       page_cache_release(page);
+                       nfs_direct_readpage_release(req);
                }
        } else {
                while (!list_empty(&hdr->pages)) {
                                if (!PageCompound(req->wb_page))
                                        set_page_dirty(req->wb_page);
                        bytes += req->wb_bytes;
-                       page_cache_release(req->wb_page);
                        nfs_list_remove_request(req);
                        nfs_direct_readpage_release(req);
                }
                                                 pagevec[i],
                                                 pgbase, req_len);
                        if (IS_ERR(req)) {
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                result = PTR_ERR(req);
                                break;
                        }
                        if (!nfs_pageio_add_request(desc, req)) {
                                result = desc->pg_error;
                                nfs_release_request(req);
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                break;
                        }
                        pgbase = 0;
                        pos += req_len;
                        count -= req_len;
                }
+               /* The nfs_page now hold references to these pages */
+               nfs_direct_release_pages(pagevec, npages);
        } while (count != 0 && result >= 0);
 
        kfree(pagevec);
        nfs_pageio_complete(&desc);
 
        while (!list_empty(&failed)) {
-               page_cache_release(req->wb_page);
                nfs_release_request(req);
                nfs_unlock_request(req);
        }
                if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) {
                        /* Note the rewrite will go through mds */
                        nfs_mark_request_commit(req, NULL, &cinfo);
-               } else {
-                       page_cache_release(req->wb_page);
+               } else
                        nfs_release_request(req);
-               }
                nfs_unlock_request(req);
        }
 
                                                 pagevec[i],
                                                 pgbase, req_len);
                        if (IS_ERR(req)) {
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                result = PTR_ERR(req);
                                break;
                        }
                                result = desc->pg_error;
                                nfs_unlock_request(req);
                                nfs_release_request(req);
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                break;
                        }
                        pgbase = 0;
                        pos += req_len;
                        count -= req_len;
                }
+               /* The nfs_page now hold references to these pages */
+               nfs_direct_release_pages(pagevec, npages);
        } while (count != 0 && result >= 0);
 
        kfree(pagevec);
                        nfs_mark_request_commit(req, hdr->lseg, &cinfo);
                        break;
                default:
-                       page_cache_release(req->wb_page);
                        nfs_release_request(req);
                }
                nfs_unlock_request(req);