diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-07-06 04:21:30 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-07-27 21:00:43 -0400 |
commit | 70220ac8c220495b2a335868293be80a31dfdd4a (patch) | |
tree | 160ae75e585aee36d5a6000355ccbeca2aa59e1b /fs/ceph/caps.c | |
parent | 13c2b57d81ec27716b9c943fd4077264b9804e55 (diff) |
ceph: introduce an inode flag to indicates if snapflush is needed
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index f12d59d26a04..45fe7a3658dc 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1368,6 +1368,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) | |||
1368 | { | 1368 | { |
1369 | spin_lock(&ci->i_ceph_lock); | 1369 | spin_lock(&ci->i_ceph_lock); |
1370 | __ceph_flush_snaps(ci, NULL); | 1370 | __ceph_flush_snaps(ci, NULL); |
1371 | ci->i_ceph_flags &= ~CEPH_I_FLUSH_SNAPS; | ||
1371 | spin_unlock(&ci->i_ceph_lock); | 1372 | spin_unlock(&ci->i_ceph_lock); |
1372 | } | 1373 | } |
1373 | 1374 | ||
@@ -1563,8 +1564,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1563 | flags |= CHECK_CAPS_FLUSH; | 1564 | flags |= CHECK_CAPS_FLUSH; |
1564 | 1565 | ||
1565 | /* flush snaps first time around only */ | 1566 | /* flush snaps first time around only */ |
1566 | if (!list_empty(&ci->i_cap_snaps)) | 1567 | if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS) { |
1567 | __ceph_flush_snaps(ci, &session); | 1568 | __ceph_flush_snaps(ci, &session); |
1569 | ci->i_ceph_flags &= ~CEPH_I_FLUSH_SNAPS; | ||
1570 | } | ||
1568 | goto retry_locked; | 1571 | goto retry_locked; |
1569 | retry: | 1572 | retry: |
1570 | spin_lock(&ci->i_ceph_lock); | 1573 | spin_lock(&ci->i_ceph_lock); |
@@ -2498,7 +2501,8 @@ void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps) | |||
2498 | * drop cap_snap that is not associated with any snapshot. | 2501 | * drop cap_snap that is not associated with any snapshot. |
2499 | * we don't need to send FLUSHSNAP message for it. | 2502 | * we don't need to send FLUSHSNAP message for it. |
2500 | */ | 2503 | */ |
2501 | static int ceph_try_drop_cap_snap(struct ceph_cap_snap *capsnap) | 2504 | static int ceph_try_drop_cap_snap(struct ceph_inode_info *ci, |
2505 | struct ceph_cap_snap *capsnap) | ||
2502 | { | 2506 | { |
2503 | if (!capsnap->need_flush && | 2507 | if (!capsnap->need_flush && |
2504 | !capsnap->writing && !capsnap->dirty_pages) { | 2508 | !capsnap->writing && !capsnap->dirty_pages) { |
@@ -2506,6 +2510,9 @@ static int ceph_try_drop_cap_snap(struct ceph_cap_snap *capsnap) | |||
2506 | capsnap, capsnap->follows); | 2510 | capsnap, capsnap->follows); |
2507 | BUG_ON(capsnap->cap_flush.tid > 0); | 2511 | BUG_ON(capsnap->cap_flush.tid > 0); |
2508 | ceph_put_snap_context(capsnap->context); | 2512 | ceph_put_snap_context(capsnap->context); |
2513 | if (!list_is_last(&capsnap->ci_item, &ci->i_cap_snaps)) | ||
2514 | ci->i_ceph_flags |= CEPH_I_FLUSH_SNAPS; | ||
2515 | |||
2509 | list_del(&capsnap->ci_item); | 2516 | list_del(&capsnap->ci_item); |
2510 | ceph_put_cap_snap(capsnap); | 2517 | ceph_put_cap_snap(capsnap); |
2511 | return 1; | 2518 | return 1; |
@@ -2553,7 +2560,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) | |||
2553 | struct ceph_cap_snap, | 2560 | struct ceph_cap_snap, |
2554 | ci_item); | 2561 | ci_item); |
2555 | capsnap->writing = 0; | 2562 | capsnap->writing = 0; |
2556 | if (ceph_try_drop_cap_snap(capsnap)) | 2563 | if (ceph_try_drop_cap_snap(ci, capsnap)) |
2557 | put++; | 2564 | put++; |
2558 | else if (__ceph_finish_cap_snap(ci, capsnap)) | 2565 | else if (__ceph_finish_cap_snap(ci, capsnap)) |
2559 | flushsnaps = 1; | 2566 | flushsnaps = 1; |
@@ -2596,15 +2603,19 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2596 | struct ceph_snap_context *snapc) | 2603 | struct ceph_snap_context *snapc) |
2597 | { | 2604 | { |
2598 | struct inode *inode = &ci->vfs_inode; | 2605 | struct inode *inode = &ci->vfs_inode; |
2599 | int last = 0; | ||
2600 | int complete_capsnap = 0; | ||
2601 | int drop_capsnap = 0; | ||
2602 | int found = 0; | ||
2603 | struct ceph_cap_snap *capsnap = NULL; | 2606 | struct ceph_cap_snap *capsnap = NULL; |
2607 | int put = 0; | ||
2608 | bool last = false; | ||
2609 | bool found = false; | ||
2610 | bool flush_snaps = false; | ||
2611 | bool complete_capsnap = false; | ||
2604 | 2612 | ||
2605 | spin_lock(&ci->i_ceph_lock); | 2613 | spin_lock(&ci->i_ceph_lock); |
2606 | ci->i_wrbuffer_ref -= nr; | 2614 | ci->i_wrbuffer_ref -= nr; |
2607 | last = !ci->i_wrbuffer_ref; | 2615 | if (ci->i_wrbuffer_ref == 0) { |
2616 | last = true; | ||
2617 | put++; | ||
2618 | } | ||
2608 | 2619 | ||
2609 | if (ci->i_head_snapc == snapc) { | 2620 | if (ci->i_head_snapc == snapc) { |
2610 | ci->i_wrbuffer_ref_head -= nr; | 2621 | ci->i_wrbuffer_ref_head -= nr; |
@@ -2624,15 +2635,22 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2624 | } else { | 2635 | } else { |
2625 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { | 2636 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { |
2626 | if (capsnap->context == snapc) { | 2637 | if (capsnap->context == snapc) { |
2627 | found = 1; | 2638 | found = true; |
2628 | break; | 2639 | break; |
2629 | } | 2640 | } |
2630 | } | 2641 | } |
2631 | BUG_ON(!found); | 2642 | BUG_ON(!found); |
2632 | capsnap->dirty_pages -= nr; | 2643 | capsnap->dirty_pages -= nr; |
2633 | if (capsnap->dirty_pages == 0) { | 2644 | if (capsnap->dirty_pages == 0) { |
2634 | complete_capsnap = 1; | 2645 | complete_capsnap = true; |
2635 | drop_capsnap = ceph_try_drop_cap_snap(capsnap); | 2646 | if (!capsnap->writing) { |
2647 | if (ceph_try_drop_cap_snap(ci, capsnap)) { | ||
2648 | put++; | ||
2649 | } else { | ||
2650 | ci->i_ceph_flags |= CEPH_I_FLUSH_SNAPS; | ||
2651 | flush_snaps = true; | ||
2652 | } | ||
2653 | } | ||
2636 | } | 2654 | } |
2637 | dout("put_wrbuffer_cap_refs on %p cap_snap %p " | 2655 | dout("put_wrbuffer_cap_refs on %p cap_snap %p " |
2638 | " snap %lld %d/%d -> %d/%d %s%s\n", | 2656 | " snap %lld %d/%d -> %d/%d %s%s\n", |
@@ -2647,12 +2665,12 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2647 | 2665 | ||
2648 | if (last) { | 2666 | if (last) { |
2649 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); | 2667 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); |
2650 | iput(inode); | 2668 | } else if (flush_snaps) { |
2651 | } else if (complete_capsnap) { | ||
2652 | ceph_flush_snaps(ci); | 2669 | ceph_flush_snaps(ci); |
2653 | wake_up_all(&ci->i_cap_wq); | ||
2654 | } | 2670 | } |
2655 | if (drop_capsnap) | 2671 | if (complete_capsnap) |
2672 | wake_up_all(&ci->i_cap_wq); | ||
2673 | while (put-- > 0) | ||
2656 | iput(inode); | 2674 | iput(inode); |
2657 | } | 2675 | } |
2658 | 2676 | ||