diff options
| -rw-r--r-- | fs/ceph/caps.c | 21 | ||||
| -rw-r--r-- | fs/ceph/mds_client.c | 6 | ||||
| -rw-r--r-- | fs/ceph/super.h | 8 |
3 files changed, 14 insertions, 21 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 13976c33332e..d2d6e40e7345 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
| @@ -897,7 +897,7 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci) | |||
| 897 | * caller should hold i_ceph_lock. | 897 | * caller should hold i_ceph_lock. |
| 898 | * caller will not hold session s_mutex if called from destroy_inode. | 898 | * caller will not hold session s_mutex if called from destroy_inode. |
| 899 | */ | 899 | */ |
| 900 | void __ceph_remove_cap(struct ceph_cap *cap) | 900 | void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) |
| 901 | { | 901 | { |
| 902 | struct ceph_mds_session *session = cap->session; | 902 | struct ceph_mds_session *session = cap->session; |
| 903 | struct ceph_inode_info *ci = cap->ci; | 903 | struct ceph_inode_info *ci = cap->ci; |
| @@ -909,6 +909,10 @@ void __ceph_remove_cap(struct ceph_cap *cap) | |||
| 909 | 909 | ||
| 910 | /* remove from session list */ | 910 | /* remove from session list */ |
| 911 | spin_lock(&session->s_cap_lock); | 911 | spin_lock(&session->s_cap_lock); |
| 912 | if (queue_release) | ||
| 913 | __queue_cap_release(session, ci->i_vino.ino, cap->cap_id, | ||
| 914 | cap->mseq, cap->issue_seq); | ||
| 915 | |||
| 912 | if (session->s_cap_iterator == cap) { | 916 | if (session->s_cap_iterator == cap) { |
| 913 | /* not yet, we are iterating over this very cap */ | 917 | /* not yet, we are iterating over this very cap */ |
| 914 | dout("__ceph_remove_cap delaying %p removal from session %p\n", | 918 | dout("__ceph_remove_cap delaying %p removal from session %p\n", |
| @@ -1023,7 +1027,6 @@ void __queue_cap_release(struct ceph_mds_session *session, | |||
| 1023 | struct ceph_mds_cap_release *head; | 1027 | struct ceph_mds_cap_release *head; |
| 1024 | struct ceph_mds_cap_item *item; | 1028 | struct ceph_mds_cap_item *item; |
| 1025 | 1029 | ||
| 1026 | spin_lock(&session->s_cap_lock); | ||
| 1027 | BUG_ON(!session->s_num_cap_releases); | 1030 | BUG_ON(!session->s_num_cap_releases); |
| 1028 | msg = list_first_entry(&session->s_cap_releases, | 1031 | msg = list_first_entry(&session->s_cap_releases, |
| 1029 | struct ceph_msg, list_head); | 1032 | struct ceph_msg, list_head); |
| @@ -1052,7 +1055,6 @@ void __queue_cap_release(struct ceph_mds_session *session, | |||
| 1052 | (int)CEPH_CAPS_PER_RELEASE, | 1055 | (int)CEPH_CAPS_PER_RELEASE, |
| 1053 | (int)msg->front.iov_len); | 1056 | (int)msg->front.iov_len); |
| 1054 | } | 1057 | } |
| 1055 | spin_unlock(&session->s_cap_lock); | ||
| 1056 | } | 1058 | } |
| 1057 | 1059 | ||
| 1058 | /* | 1060 | /* |
| @@ -1067,12 +1069,8 @@ void ceph_queue_caps_release(struct inode *inode) | |||
| 1067 | p = rb_first(&ci->i_caps); | 1069 | p = rb_first(&ci->i_caps); |
| 1068 | while (p) { | 1070 | while (p) { |
| 1069 | struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); | 1071 | struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); |
| 1070 | struct ceph_mds_session *session = cap->session; | ||
| 1071 | |||
| 1072 | __queue_cap_release(session, ceph_ino(inode), cap->cap_id, | ||
| 1073 | cap->mseq, cap->issue_seq); | ||
| 1074 | p = rb_next(p); | 1072 | p = rb_next(p); |
| 1075 | __ceph_remove_cap(cap); | 1073 | __ceph_remove_cap(cap, true); |
| 1076 | } | 1074 | } |
| 1077 | } | 1075 | } |
| 1078 | 1076 | ||
| @@ -2791,7 +2789,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, | |||
| 2791 | } | 2789 | } |
| 2792 | spin_unlock(&mdsc->cap_dirty_lock); | 2790 | spin_unlock(&mdsc->cap_dirty_lock); |
| 2793 | } | 2791 | } |
| 2794 | __ceph_remove_cap(cap); | 2792 | __ceph_remove_cap(cap, false); |
| 2795 | } | 2793 | } |
| 2796 | /* else, we already released it */ | 2794 | /* else, we already released it */ |
| 2797 | 2795 | ||
| @@ -2931,9 +2929,12 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
| 2931 | if (!inode) { | 2929 | if (!inode) { |
| 2932 | dout(" i don't have ino %llx\n", vino.ino); | 2930 | dout(" i don't have ino %llx\n", vino.ino); |
| 2933 | 2931 | ||
| 2934 | if (op == CEPH_CAP_OP_IMPORT) | 2932 | if (op == CEPH_CAP_OP_IMPORT) { |
| 2933 | spin_lock(&session->s_cap_lock); | ||
| 2935 | __queue_cap_release(session, vino.ino, cap_id, | 2934 | __queue_cap_release(session, vino.ino, cap_id, |
| 2936 | mseq, seq); | 2935 | mseq, seq); |
| 2936 | spin_unlock(&session->s_cap_lock); | ||
| 2937 | } | ||
| 2937 | goto flush_cap_releases; | 2938 | goto flush_cap_releases; |
| 2938 | } | 2939 | } |
| 2939 | 2940 | ||
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index f51ab2627b41..8f8f5c043c37 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
| @@ -986,7 +986,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
| 986 | dout("removing cap %p, ci is %p, inode is %p\n", | 986 | dout("removing cap %p, ci is %p, inode is %p\n", |
| 987 | cap, ci, &ci->vfs_inode); | 987 | cap, ci, &ci->vfs_inode); |
| 988 | spin_lock(&ci->i_ceph_lock); | 988 | spin_lock(&ci->i_ceph_lock); |
| 989 | __ceph_remove_cap(cap); | 989 | __ceph_remove_cap(cap, false); |
| 990 | if (!__ceph_is_any_real_caps(ci)) { | 990 | if (!__ceph_is_any_real_caps(ci)) { |
| 991 | struct ceph_mds_client *mdsc = | 991 | struct ceph_mds_client *mdsc = |
| 992 | ceph_sb_to_client(inode->i_sb)->mdsc; | 992 | ceph_sb_to_client(inode->i_sb)->mdsc; |
| @@ -1231,9 +1231,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) | |||
| 1231 | session->s_trim_caps--; | 1231 | session->s_trim_caps--; |
| 1232 | if (oissued) { | 1232 | if (oissued) { |
| 1233 | /* we aren't the only cap.. just remove us */ | 1233 | /* we aren't the only cap.. just remove us */ |
| 1234 | __queue_cap_release(session, ceph_ino(inode), cap->cap_id, | 1234 | __ceph_remove_cap(cap, true); |
| 1235 | cap->mseq, cap->issue_seq); | ||
| 1236 | __ceph_remove_cap(cap); | ||
| 1237 | } else { | 1235 | } else { |
| 1238 | /* try to drop referring dentries */ | 1236 | /* try to drop referring dentries */ |
| 1239 | spin_unlock(&ci->i_ceph_lock); | 1237 | spin_unlock(&ci->i_ceph_lock); |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 6014b0a3c405..ef4ac38bb614 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
| @@ -741,13 +741,7 @@ extern int ceph_add_cap(struct inode *inode, | |||
| 741 | int fmode, unsigned issued, unsigned wanted, | 741 | int fmode, unsigned issued, unsigned wanted, |
| 742 | unsigned cap, unsigned seq, u64 realmino, int flags, | 742 | unsigned cap, unsigned seq, u64 realmino, int flags, |
| 743 | struct ceph_cap_reservation *caps_reservation); | 743 | struct ceph_cap_reservation *caps_reservation); |
| 744 | extern void __ceph_remove_cap(struct ceph_cap *cap); | 744 | extern void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release); |
| 745 | static inline void ceph_remove_cap(struct ceph_cap *cap) | ||
| 746 | { | ||
| 747 | spin_lock(&cap->ci->i_ceph_lock); | ||
| 748 | __ceph_remove_cap(cap); | ||
| 749 | spin_unlock(&cap->ci->i_ceph_lock); | ||
| 750 | } | ||
| 751 | extern void ceph_put_cap(struct ceph_mds_client *mdsc, | 745 | extern void ceph_put_cap(struct ceph_mds_client *mdsc, |
| 752 | struct ceph_cap *cap); | 746 | struct ceph_cap *cap); |
| 753 | 747 | ||
