libceph: Unlock unprocessed pages in start_read() error path
authorDavid Zafman <david.zafman@inktank.com>
Tue, 4 Dec 2012 03:14:05 +0000 (19:14 -0800)
committerAlex Elder <elder@inktank.com>
Thu, 13 Dec 2012 14:13:09 +0000 (08:13 -0600)
Function start_read() can get an error before processing all pages.
It must not only release the remaining pages, but unlock them too.

This fixes http://tracker.newdream.net/issues/3370

Signed-off-by: David Zafman <david.zafman@inktank.com>
Reviewed-by: Alex Elder <elder@inktank.com>
fs/ceph/addr.c

index 21a07187df05c1b234b3cd5e4aff854b47d97c77..8e8a818cba07155096f4eb2019a4332e97ba3ad3 100644 (file)
@@ -267,6 +267,14 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg)
        kfree(req->r_pages);
 }
 
+static void ceph_unlock_page_vector(struct page **pages, int num_pages)
+{
+       int i;
+
+       for (i = 0; i < num_pages; i++)
+               unlock_page(pages[i]);
+}
+
 /*
  * start an async read(ahead) operation.  return nr_pages we submitted
  * a read for on success, or negative error code.
@@ -347,6 +355,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
        return nr_pages;
 
 out_pages:
+       ceph_unlock_page_vector(pages, nr_pages);
        ceph_release_page_vector(pages, nr_pages);
 out:
        ceph_osdc_put_request(req);