]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: writepages work in progress
authorSage Weil <sage@newdream.net>
Thu, 3 Apr 2008 16:41:42 +0000 (09:41 -0700)
committerSage Weil <sage@newdream.net>
Thu, 3 Apr 2008 16:41:42 +0000 (09:41 -0700)
src/kernel/addr.c
src/kernel/osd_client.c

index ef35e941d155a5af30d4c4c052a2c41e3a3d15e3..0702946fc8076e2b6f73b138e3858c0eea989af7 100644 (file)
@@ -152,16 +152,28 @@ static int ceph_writepages(struct address_space *mapping,
        pgoff_t index, end;
        int range_whole = 0;
        int should_loop = 1;
+       struct page *pages;
+       int nr_pages = 0, max_pages;
        struct pagevec pvec;
        int done = 0;
        int rc = 0;
 
        dout(10, "writepages on %p\n", inode);
 
-       /* if wsize is small, write 1 page at a time */
-       if (client->mount_args.wsize &&
-           client->mount_args.wsize < PAGE_CACHE_SIZE)
-               return generic_writepages(mapping, wbc);
+       if (client->mount_args.wsize) {
+               /* if wsize is small, write 1 page at a time */
+               if (client->mount_args.wsize < PAGE_CACHE_SIZE)
+                       return generic_writepages(mapping, wbc);
+       
+               /* larger page vector? */
+               max_pages = (client->mount_args.wsize >> PAGE_CACHE_SHIFT);
+               if (pages > PAGEVEC_SIZE) {
+                       pages = kmalloc(max_pages * sizeof(void *), GFP_KERNEL);
+                       if (!pages) 
+                               return generic_writepages(mapping, wbc);
+               }
+       }
+       pagevec_init(&pvec, 0);
 
        /* ?? from cifs. */
        /*
@@ -172,7 +184,6 @@ static int ceph_writepages(struct address_space *mapping,
        */
 
        /* where to start? */
-       pagevec_init(&pvec, 0);
        if (wbc->range_cyclic) {
                index = mapping->writeback_index; /* Start from prev offset */
                end = -1;
@@ -193,20 +204,19 @@ retry:
                unsigned i;
                pgoff_t next;
                struct page *page;
-               int nr_pages, locked_pages;
-
-               nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-                             PAGECACHE_TAG_DIRTY,
-                             min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1);
-               dout(30, "lookup_tag got %d pages\n", nr_pages);
-               if (!nr_pages)
-                       break;
-
+               int got_pages, locked_pages;
+               
                first = -1;
                next = 0;
                locked_pages = 0;
-               
-               for (i = 0; i < nr_pages; i++) {
+
+       get_more_pages:
+               got_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+                             PAGECACHE_TAG_DIRTY,
+                             min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1);
+               dout(30, "lookup_tag got %d pages\n", got_pages);
+       
+               for (i = 0; i < got_pages; i++) {
                        page = pvec.pages[i];
                        if (first < 0)
                                lock_page(page);
@@ -253,6 +263,15 @@ retry:
                        next = page->index + 1;
                }
 
+               if (pages && got_pages && locked_pages < max_pages) {
+                       /* move pagevec into big pagevec */
+                       memcpy(pages + nr_pages, pvec.pages,
+                              pvec.nr * sizeof(struct page *));
+                       nr_pages += pvec.nr;
+                       pagevec_reinit(pvec);
+                       goto get_more_pages;
+               }
+
                /* did we get anything? */
                if (first >= 0) {
                        loff_t offset = pvec.pages[first]->index <<
@@ -302,6 +321,7 @@ retry:
        if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
                mapping->writeback_index = index;
 
+       kfree(pvec);
        dout(10, "writepages done, rc = %d\n", rc);
        return rc;
 }
index 46ed855ed9d9db73d808555791114567aaa3d01d..1b5e30eae0c5d5c180421969d85b403f637fadfb 100644 (file)
@@ -636,7 +636,7 @@ int ceph_osdc_sync_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
 int ceph_osdc_writepages(struct ceph_osd_client *osdc, ceph_ino_t ino,
                         struct ceph_file_layout *layout, 
                         loff_t off, loff_t len,
-                        struct page **pagevec, int nr_pages)
+                        struct page **pages, int nr_pages)
 {
        struct ceph_msg *reqm;
        struct ceph_osd_request_head *reqhead;
@@ -660,8 +660,8 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, ceph_ino_t ino,
        nr_pages = calc_pages_for(off, len);
        dout(10, "writepages %llu~%llu -> %d pages\n", off, len, nr_pages);
        
-       /* copy pagevec */
-       memcpy(req->r_pages, pagevec, nr_pages * sizeof(struct page *));
+       /* copy pages */
+       memcpy(req->r_pages, pages, nr_pages * sizeof(struct page *));
        reqm->pages = req->r_pages;
        reqm->nr_pages = req->r_nr_pages = nr_pages;
        reqm->hdr.data_len = len;