aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/file.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index ae23e31a8f38..a65acf355384 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -446,19 +446,35 @@ done:
446} 446}
447 447
448/* 448/*
449 * Write commit callback, called if we requested both an ACK and 449 * Write commit request unsafe callback, called to tell us when a
450 * ONDISK commit reply from the OSD. 450 * request is unsafe (that is, in flight--has been handed to the
451 * messenger to send to its target osd). It is called again when
452 * we've received a response message indicating the request is
453 * "safe" (its CEPH_OSD_FLAG_ONDISK flag is set), or when a request
454 * is completed early (and unsuccessfully) due to a timeout or
455 * interrupt.
456 *
457 * This is used if we requested both an ACK and ONDISK commit reply
458 * from the OSD.
451 */ 459 */
452static void sync_write_commit(struct ceph_osd_request *req, 460static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe)
453 struct ceph_msg *msg)
454{ 461{
455 struct ceph_inode_info *ci = ceph_inode(req->r_inode); 462 struct ceph_inode_info *ci = ceph_inode(req->r_inode);
456 463
457 dout("sync_write_commit %p tid %llu\n", req, req->r_tid); 464 dout("%s %p tid %llu %ssafe\n", __func__, req, req->r_tid,
458 spin_lock(&ci->i_unsafe_lock); 465 unsafe ? "un" : "");
459 list_del_init(&req->r_unsafe_item); 466 if (unsafe) {
460 spin_unlock(&ci->i_unsafe_lock); 467 ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
461 ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR); 468 spin_lock(&ci->i_unsafe_lock);
469 list_add_tail(&req->r_unsafe_item,
470 &ci->i_unsafe_writes);
471 spin_unlock(&ci->i_unsafe_lock);
472 } else {
473 spin_lock(&ci->i_unsafe_lock);
474 list_del_init(&req->r_unsafe_item);
475 spin_unlock(&ci->i_unsafe_lock);
476 ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR);
477 }
462} 478}
463 479
464/* 480/*
@@ -570,7 +586,8 @@ more:
570 586
571 if ((file->f_flags & O_SYNC) == 0) { 587 if ((file->f_flags & O_SYNC) == 0) {
572 /* get a second commit callback */ 588 /* get a second commit callback */
573 req->r_safe_callback = sync_write_commit; 589 req->r_unsafe_callback = ceph_sync_write_unsafe;
590 req->r_inode = inode;
574 own_pages = true; 591 own_pages = true;
575 } 592 }
576 } 593 }
@@ -581,21 +598,8 @@ more:
581 ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime); 598 ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
582 599
583 ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); 600 ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
584 if (!ret) { 601 if (!ret)
585 if (req->r_safe_callback) {
586 /*
587 * Add to inode unsafe list only after we
588 * start_request so that a tid has been assigned.
589 */
590 spin_lock(&ci->i_unsafe_lock);
591 list_add_tail(&req->r_unsafe_item,
592 &ci->i_unsafe_writes);
593 spin_unlock(&ci->i_unsafe_lock);
594 ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
595 }
596
597 ret = ceph_osdc_wait_request(&fsc->client->osdc, req); 602 ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
598 }
599 603
600 if (file->f_flags & O_DIRECT) 604 if (file->f_flags & O_DIRECT)
601 ceph_put_page_vector(pages, num_pages, false); 605 ceph_put_page_vector(pages, num_pages, false);