diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2013-09-21 22:15:58 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-11-23 14:00:59 -0500 |
commit | a096b09aeec6ff99edfdfd8cee24d6f25377d585 (patch) | |
tree | d32a4a15cd391c2c84205c855e7d997070279cc6 /fs/ceph | |
parent | 81c6aea5275eae453719d7f3924da07e668265c5 (diff) |
ceph: queue cap release in __ceph_remove_cap()
call __queue_cap_release() in __ceph_remove_cap(), this avoids
acquiring s_cap_lock twice.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph')
-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 | ||