aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/addr.c45
1 files changed, 18 insertions, 27 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index f2de9ec27db3..7b6d9b22e254 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -631,29 +631,6 @@ static void writepages_finish(struct ceph_osd_request *req,
631 ceph_osdc_put_request(req); 631 ceph_osdc_put_request(req);
632} 632}
633 633
634/*
635 * allocate a page vec, either directly, or if necessary, via a the
636 * mempool. we avoid the mempool if we can because req->r_data_out.length
637 * may be less than the maximum write size.
638 */
639static void alloc_page_vec(struct ceph_fs_client *fsc,
640 struct ceph_osd_request *req)
641{
642 size_t size;
643 int num_pages;
644
645 num_pages = calc_pages_for((u64)req->r_data_out.alignment,
646 (u64)req->r_data_out.length);
647 size = sizeof (struct page *) * num_pages;
648 req->r_data_out.pages = kmalloc(size, GFP_NOFS);
649 if (!req->r_data_out.pages) {
650 req->r_data_out.pages = mempool_alloc(fsc->wb_pagevec_pool,
651 GFP_NOFS);
652 req->r_data_out.pages_from_pool = 1;
653 WARN_ON(!req->r_data_out.pages);
654 }
655}
656
657static struct ceph_osd_request * 634static struct ceph_osd_request *
658ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len, 635ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len,
659 struct ceph_snap_context *snapc, 636 struct ceph_snap_context *snapc,
@@ -851,6 +828,9 @@ get_more_pages:
851 if (locked_pages == 0) { 828 if (locked_pages == 0) {
852 struct ceph_vino vino; 829 struct ceph_vino vino;
853 int num_ops = do_sync ? 2 : 1; 830 int num_ops = do_sync ? 2 : 1;
831 size_t size;
832 struct page **pages;
833 mempool_t *pool = NULL;
854 834
855 /* prepare async write request */ 835 /* prepare async write request */
856 offset = (u64) page_offset(page); 836 offset = (u64) page_offset(page);
@@ -870,13 +850,24 @@ get_more_pages:
870 num_ops, ops, snapc, vino.snap, 850 num_ops, ops, snapc, vino.snap,
871 &inode->i_mtime); 851 &inode->i_mtime);
872 852
853 req->r_callback = writepages_finish;
854 req->r_inode = inode;
855
856 max_pages = calc_pages_for(0, (u64)len);
857 size = max_pages * sizeof (*pages);
858 pages = kmalloc(size, GFP_NOFS);
859 if (!pages) {
860 pool = fsc->wb_pagevec_pool;
861
862 pages = mempool_alloc(pool, GFP_NOFS);
863 WARN_ON(!pages);
864 }
865
866 req->r_data_out.pages = pages;
867 req->r_data_out.pages_from_pool = !!pool;
873 req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES; 868 req->r_data_out.type = CEPH_OSD_DATA_TYPE_PAGES;
874 req->r_data_out.length = len; 869 req->r_data_out.length = len;
875 req->r_data_out.alignment = 0; 870 req->r_data_out.alignment = 0;
876 max_pages = calc_pages_for(0, (u64)len);
877 alloc_page_vec(fsc, req);
878 req->r_callback = writepages_finish;
879 req->r_inode = inode;
880 } 871 }
881 872
882 /* note position of first page in pvec */ 873 /* note position of first page in pvec */