diff options
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/file.c | 52 |
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 | */ |
452 | static void sync_write_commit(struct ceph_osd_request *req, | 460 | static 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); |