aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/addr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/addr.c')
-rw-r--r--fs/ceph/addr.c88
1 files changed, 42 insertions, 46 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 38b5c1bc6776..5318a3b704f6 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -439,13 +439,12 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
439 struct ceph_inode_info *ci; 439 struct ceph_inode_info *ci;
440 struct ceph_fs_client *fsc; 440 struct ceph_fs_client *fsc;
441 struct ceph_osd_client *osdc; 441 struct ceph_osd_client *osdc;
442 loff_t page_off = page_offset(page);
443 int len = PAGE_CACHE_SIZE;
444 loff_t i_size;
445 int err = 0;
446 struct ceph_snap_context *snapc, *oldest; 442 struct ceph_snap_context *snapc, *oldest;
447 u64 snap_size = 0; 443 loff_t page_off = page_offset(page);
448 long writeback_stat; 444 long writeback_stat;
445 u64 truncate_size, snap_size = 0;
446 u32 truncate_seq;
447 int err = 0, len = PAGE_CACHE_SIZE;
449 448
450 dout("writepage %p idx %lu\n", page, page->index); 449 dout("writepage %p idx %lu\n", page, page->index);
451 450
@@ -475,13 +474,20 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
475 } 474 }
476 ceph_put_snap_context(oldest); 475 ceph_put_snap_context(oldest);
477 476
477 spin_lock(&ci->i_ceph_lock);
478 truncate_seq = ci->i_truncate_seq;
479 truncate_size = ci->i_truncate_size;
480 if (!snap_size)
481 snap_size = i_size_read(inode);
482 spin_unlock(&ci->i_ceph_lock);
483
478 /* is this a partial page at end of file? */ 484 /* is this a partial page at end of file? */
479 if (snap_size) 485 if (page_off >= snap_size) {
480 i_size = snap_size; 486 dout("%p page eof %llu\n", page, snap_size);
481 else 487 goto out;
482 i_size = i_size_read(inode); 488 }
483 if (i_size < page_off + len) 489 if (snap_size < page_off + len)
484 len = i_size - page_off; 490 len = snap_size - page_off;
485 491
486 dout("writepage %p page %p index %lu on %llu~%u snapc %p\n", 492 dout("writepage %p page %p index %lu on %llu~%u snapc %p\n",
487 inode, page, page->index, page_off, len, snapc); 493 inode, page, page->index, page_off, len, snapc);
@@ -495,7 +501,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
495 err = ceph_osdc_writepages(osdc, ceph_vino(inode), 501 err = ceph_osdc_writepages(osdc, ceph_vino(inode),
496 &ci->i_layout, snapc, 502 &ci->i_layout, snapc,
497 page_off, len, 503 page_off, len,
498 ci->i_truncate_seq, ci->i_truncate_size, 504 truncate_seq, truncate_size,
499 &inode->i_mtime, &page, 1); 505 &inode->i_mtime, &page, 1);
500 if (err < 0) { 506 if (err < 0) {
501 dout("writepage setting page/mapping error %d %p\n", err, page); 507 dout("writepage setting page/mapping error %d %p\n", err, page);
@@ -632,25 +638,6 @@ static void writepages_finish(struct ceph_osd_request *req,
632 ceph_osdc_put_request(req); 638 ceph_osdc_put_request(req);
633} 639}
634 640
635static struct ceph_osd_request *
636ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len,
637 struct ceph_snap_context *snapc, int num_ops)
638{
639 struct ceph_fs_client *fsc;
640 struct ceph_inode_info *ci;
641 struct ceph_vino vino;
642
643 fsc = ceph_inode_to_client(inode);
644 ci = ceph_inode(inode);
645 vino = ceph_vino(inode);
646 /* BUG_ON(vino.snap != CEPH_NOSNAP); */
647
648 return ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
649 vino, offset, len, num_ops, CEPH_OSD_OP_WRITE,
650 CEPH_OSD_FLAG_WRITE|CEPH_OSD_FLAG_ONDISK,
651 snapc, ci->i_truncate_seq, ci->i_truncate_size, true);
652}
653
654/* 641/*
655 * initiate async writeback 642 * initiate async writeback
656 */ 643 */
@@ -659,7 +646,8 @@ static int ceph_writepages_start(struct address_space *mapping,
659{ 646{
660 struct inode *inode = mapping->host; 647 struct inode *inode = mapping->host;
661 struct ceph_inode_info *ci = ceph_inode(inode); 648 struct ceph_inode_info *ci = ceph_inode(inode);
662 struct ceph_fs_client *fsc; 649 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
650 struct ceph_vino vino = ceph_vino(inode);
663 pgoff_t index, start, end; 651 pgoff_t index, start, end;
664 int range_whole = 0; 652 int range_whole = 0;
665 int should_loop = 1; 653 int should_loop = 1;
@@ -671,22 +659,22 @@ static int ceph_writepages_start(struct address_space *mapping,
671 unsigned wsize = 1 << inode->i_blkbits; 659 unsigned wsize = 1 << inode->i_blkbits;
672 struct ceph_osd_request *req = NULL; 660 struct ceph_osd_request *req = NULL;
673 int do_sync; 661 int do_sync;
674 u64 snap_size; 662 u64 truncate_size, snap_size;
663 u32 truncate_seq;
675 664
676 /* 665 /*
677 * Include a 'sync' in the OSD request if this is a data 666 * Include a 'sync' in the OSD request if this is a data
678 * integrity write (e.g., O_SYNC write or fsync()), or if our 667 * integrity write (e.g., O_SYNC write or fsync()), or if our
679 * cap is being revoked. 668 * cap is being revoked.
680 */ 669 */
681 do_sync = wbc->sync_mode == WB_SYNC_ALL; 670 if ((wbc->sync_mode == WB_SYNC_ALL) ||
682 if (ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER)) 671 ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER))
683 do_sync = 1; 672 do_sync = 1;
684 dout("writepages_start %p dosync=%d (mode=%s)\n", 673 dout("writepages_start %p dosync=%d (mode=%s)\n",
685 inode, do_sync, 674 inode, do_sync,
686 wbc->sync_mode == WB_SYNC_NONE ? "NONE" : 675 wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
687 (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD")); 676 (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
688 677
689 fsc = ceph_inode_to_client(inode);
690 if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) { 678 if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) {
691 pr_warning("writepage_start %p on forced umount\n", inode); 679 pr_warning("writepage_start %p on forced umount\n", inode);
692 return -EIO; /* we're in a forced umount, don't write! */ 680 return -EIO; /* we're in a forced umount, don't write! */
@@ -729,6 +717,14 @@ retry:
729 snap_size = i_size_read(inode); 717 snap_size = i_size_read(inode);
730 dout(" oldest snapc is %p seq %lld (%d snaps)\n", 718 dout(" oldest snapc is %p seq %lld (%d snaps)\n",
731 snapc, snapc->seq, snapc->num_snaps); 719 snapc, snapc->seq, snapc->num_snaps);
720
721 spin_lock(&ci->i_ceph_lock);
722 truncate_seq = ci->i_truncate_seq;
723 truncate_size = ci->i_truncate_size;
724 if (!snap_size)
725 snap_size = i_size_read(inode);
726 spin_unlock(&ci->i_ceph_lock);
727
732 if (last_snapc && snapc != last_snapc) { 728 if (last_snapc && snapc != last_snapc) {
733 /* if we switched to a newer snapc, restart our scan at the 729 /* if we switched to a newer snapc, restart our scan at the
734 * start of the original file range. */ 730 * start of the original file range. */
@@ -740,7 +736,6 @@ retry:
740 736
741 while (!done && index <= end) { 737 while (!done && index <= end) {
742 int num_ops = do_sync ? 2 : 1; 738 int num_ops = do_sync ? 2 : 1;
743 struct ceph_vino vino;
744 unsigned i; 739 unsigned i;
745 int first; 740 int first;
746 pgoff_t next; 741 pgoff_t next;
@@ -834,17 +829,18 @@ get_more_pages:
834 * that it will use. 829 * that it will use.
835 */ 830 */
836 if (locked_pages == 0) { 831 if (locked_pages == 0) {
837 size_t size;
838
839 BUG_ON(pages); 832 BUG_ON(pages);
840
841 /* prepare async write request */ 833 /* prepare async write request */
842 offset = (u64)page_offset(page); 834 offset = (u64)page_offset(page);
843 len = wsize; 835 len = wsize;
844 req = ceph_writepages_osd_request(inode, 836 req = ceph_osdc_new_request(&fsc->client->osdc,
845 offset, &len, snapc, 837 &ci->i_layout, vino,
846 num_ops); 838 offset, &len, num_ops,
847 839 CEPH_OSD_OP_WRITE,
840 CEPH_OSD_FLAG_WRITE |
841 CEPH_OSD_FLAG_ONDISK,
842 snapc, truncate_seq,
843 truncate_size, true);
848 if (IS_ERR(req)) { 844 if (IS_ERR(req)) {
849 rc = PTR_ERR(req); 845 rc = PTR_ERR(req);
850 unlock_page(page); 846 unlock_page(page);
@@ -855,8 +851,8 @@ get_more_pages:
855 req->r_inode = inode; 851 req->r_inode = inode;
856 852
857 max_pages = calc_pages_for(0, (u64)len); 853 max_pages = calc_pages_for(0, (u64)len);
858 size = max_pages * sizeof (*pages); 854 pages = kmalloc(max_pages * sizeof (*pages),
859 pages = kmalloc(size, GFP_NOFS); 855 GFP_NOFS);
860 if (!pages) { 856 if (!pages) {
861 pool = fsc->wb_pagevec_pool; 857 pool = fsc->wb_pagevec_pool;
862 pages = mempool_alloc(pool, GFP_NOFS); 858 pages = mempool_alloc(pool, GFP_NOFS);