diff options
-rw-r--r-- | fs/ceph/addr.c | 45 |
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 | */ | ||
639 | static 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 | |||
657 | static struct ceph_osd_request * | 634 | static struct ceph_osd_request * |
658 | ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len, | 635 | ceph_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 */ |