aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/addr.c
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2010-02-18 19:07:01 -0500
committerSage Weil <sage@newdream.net>2010-02-19 17:34:18 -0500
commite63dc5c780ba32d6d8b3662eecce2b8d96489b41 (patch)
treeed6ee7f557c479934b6d8a70b7ccba86b13ae670 /fs/ceph/addr.c
parent5ecad6fd7bfd30b3eaea51345f546b81de7a6473 (diff)
ceph: remove page upon writeback completion if lost cache cap
This page should have been removed earlier when the cache cap was revoked, but a writeback was in flight, so it was skipped. We truncate it here just as the writeback finishes, while it's still locked. Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/addr.c')
-rw-r--r--fs/ceph/addr.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 71f5ad1c1e26..25360d517d1b 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -514,6 +514,7 @@ static void writepages_finish(struct ceph_osd_request *req,
514 u64 bytes = 0; 514 u64 bytes = 0;
515 struct ceph_client *client = ceph_inode_to_client(inode); 515 struct ceph_client *client = ceph_inode_to_client(inode);
516 long writeback_stat; 516 long writeback_stat;
517 unsigned issued = __ceph_caps_issued(ci, NULL);
517 518
518 /* parse reply */ 519 /* parse reply */
519 replyhead = msg->front.iov_base; 520 replyhead = msg->front.iov_base;
@@ -559,6 +560,16 @@ static void writepages_finish(struct ceph_osd_request *req,
559 ceph_put_snap_context(snapc); 560 ceph_put_snap_context(snapc);
560 dout("unlocking %d %p\n", i, page); 561 dout("unlocking %d %p\n", i, page);
561 end_page_writeback(page); 562 end_page_writeback(page);
563
564 /*
565 * We lost the cache cap, need to truncate the page before
566 * it is unlocked, otherwise we'd truncate it later in the
567 * page truncation thread, possibly losing some data that
568 * raced its way in
569 */
570 if ((issued & CEPH_CAP_FILE_CACHE) == 0)
571 generic_error_remove_page(inode->i_mapping, page);
572
562 unlock_page(page); 573 unlock_page(page);
563 } 574 }
564 dout("%p wrote+cleaned %d pages\n", inode, wrote); 575 dout("%p wrote+cleaned %d pages\n", inode, wrote);