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 | |
| 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')
| -rw-r--r-- | fs/ceph/caps.c | 48 | ||||
| -rw-r--r-- | fs/ceph/snap.c | 2 | ||||
| -rw-r--r-- | fs/ceph/super.h | 1 |
3 files changed, 36 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 | ||
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 20d5b0cdf655..c3b03ae1976c 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
| @@ -601,6 +601,8 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, | |||
| 601 | capsnap->dirty_pages); | 601 | capsnap->dirty_pages); |
| 602 | return 0; | 602 | return 0; |
| 603 | } | 603 | } |
| 604 | |||
| 605 | ci->i_ceph_flags |= CEPH_I_FLUSH_SNAPS; | ||
| 604 | dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n", | 606 | dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n", |
| 605 | inode, capsnap, capsnap->context, | 607 | inode, capsnap, capsnap->context, |
| 606 | capsnap->context->seq, ceph_cap_string(capsnap->dirty), | 608 | capsnap->context->seq, ceph_cap_string(capsnap->dirty), |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 16068787afb4..63fdb57606fe 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
| @@ -469,6 +469,7 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, | |||
| 469 | #define CEPH_I_SEC_INITED (1 << 7) /* security initialized */ | 469 | #define CEPH_I_SEC_INITED (1 << 7) /* security initialized */ |
| 470 | #define CEPH_I_CAP_DROPPED (1 << 8) /* caps were forcibly dropped */ | 470 | #define CEPH_I_CAP_DROPPED (1 << 8) /* caps were forcibly dropped */ |
| 471 | #define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */ | 471 | #define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */ |
| 472 | #define CEPH_I_FLUSH_SNAPS (1 << 10) /* need flush snapss */ | ||
| 472 | 473 | ||
| 473 | static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci, | 474 | static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci, |
| 474 | long long release_count, | 475 | long long release_count, |
