NFS: Simplify O_DIRECT page referencing
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 30 Apr 2012 17:27:31 +0000 (13:27 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 30 Apr 2012 18:33:52 +0000 (14:33 -0400)
The O_DIRECT code shouldn't need to hold 2 references to each page. The
reference held by the struct nfs_page should suffice.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Fred Isaman <iisaman@netapp.com>
fs/nfs/direct.c

index af02bde7741ebcab706939c84e52bc63dce7924a..78d1ead8bc30e470f532bc879cc7405a0ac669d9 100644 (file)
@@ -268,10 +268,9 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
                        }
                        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)) {
@@ -281,7 +280,6 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
                                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);
                }
@@ -375,8 +373,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *de
                                                 pagevec[i],
                                                 pgbase, req_len);
                        if (IS_ERR(req)) {
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                result = PTR_ERR(req);
                                break;
                        }
@@ -385,8 +381,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *de
                        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;
@@ -396,6 +390,8 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *de
                        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);
@@ -509,7 +505,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
        nfs_pageio_complete(&desc);
 
        while (!list_empty(&failed)) {
-               page_cache_release(req->wb_page);
                nfs_release_request(req);
                nfs_unlock_request(req);
        }
@@ -542,10 +537,8 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
                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);
        }
 
@@ -678,8 +671,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_pageio_descriptor *d
                                                 pagevec[i],
                                                 pgbase, req_len);
                        if (IS_ERR(req)) {
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                result = PTR_ERR(req);
                                break;
                        }
@@ -690,8 +681,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_pageio_descriptor *d
                                result = desc->pg_error;
                                nfs_unlock_request(req);
                                nfs_release_request(req);
-                               nfs_direct_release_pages(pagevec + i,
-                                                        npages - i);
                                break;
                        }
                        pgbase = 0;
@@ -701,6 +690,8 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_pageio_descriptor *d
                        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);
@@ -763,7 +754,6 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
                        nfs_mark_request_commit(req, hdr->lseg, &cinfo);
                        break;
                default:
-                       page_cache_release(req->wb_page);
                        nfs_release_request(req);
                }
                nfs_unlock_request(req);