diff options
author | Yehuda Sadeh <yehuda@hq.newdream.net> | 2010-02-18 19:07:01 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-19 17:34:18 -0500 |
commit | e63dc5c780ba32d6d8b3662eecce2b8d96489b41 (patch) | |
tree | ed6ee7f557c479934b6d8a70b7ccba86b13ae670 /fs | |
parent | 5ecad6fd7bfd30b3eaea51345f546b81de7a6473 (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')
-rw-r--r-- | fs/ceph/addr.c | 11 |
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); |