summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-04-17 21:57:11 -0400
committerYan, Zheng <zheng.z.yan@intel.com>2014-06-05 21:29:53 -0400
commitd9df2783507943316b305e177e5b1c157200c76f (patch)
treea351bc67fc9ae0b3d367d232657cf28136888f66 /fs/ceph/caps.c
parentf98a128a55ff85d0087de89f304f10bd75e792aa (diff)
ceph: pre-allocate ceph_cap struct for ceph_add_cap()
So that ceph_add_cap() can be used while i_ceph_lock is locked. This simplifies the code that handle cap import/export. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 5f6d24ede794..73a42f504357 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -221,8 +221,8 @@ int ceph_unreserve_caps(struct ceph_mds_client *mdsc,
221 return 0; 221 return 0;
222} 222}
223 223
224static struct ceph_cap *get_cap(struct ceph_mds_client *mdsc, 224struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc,
225 struct ceph_cap_reservation *ctx) 225 struct ceph_cap_reservation *ctx)
226{ 226{
227 struct ceph_cap *cap = NULL; 227 struct ceph_cap *cap = NULL;
228 228
@@ -508,15 +508,14 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
508 * it is < 0. (This is so we can atomically add the cap and add an 508 * it is < 0. (This is so we can atomically add the cap and add an
509 * open file reference to it.) 509 * open file reference to it.)
510 */ 510 */
511int ceph_add_cap(struct inode *inode, 511void ceph_add_cap(struct inode *inode,
512 struct ceph_mds_session *session, u64 cap_id, 512 struct ceph_mds_session *session, u64 cap_id,
513 int fmode, unsigned issued, unsigned wanted, 513 int fmode, unsigned issued, unsigned wanted,
514 unsigned seq, unsigned mseq, u64 realmino, int flags, 514 unsigned seq, unsigned mseq, u64 realmino, int flags,
515 struct ceph_cap_reservation *caps_reservation) 515 struct ceph_cap **new_cap)
516{ 516{
517 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; 517 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
518 struct ceph_inode_info *ci = ceph_inode(inode); 518 struct ceph_inode_info *ci = ceph_inode(inode);
519 struct ceph_cap *new_cap = NULL;
520 struct ceph_cap *cap; 519 struct ceph_cap *cap;
521 int mds = session->s_mds; 520 int mds = session->s_mds;
522 int actual_wanted; 521 int actual_wanted;
@@ -531,20 +530,10 @@ int ceph_add_cap(struct inode *inode,
531 if (fmode >= 0) 530 if (fmode >= 0)
532 wanted |= ceph_caps_for_mode(fmode); 531 wanted |= ceph_caps_for_mode(fmode);
533 532
534retry:
535 spin_lock(&ci->i_ceph_lock);
536 cap = __get_cap_for_mds(ci, mds); 533 cap = __get_cap_for_mds(ci, mds);
537 if (!cap) { 534 if (!cap) {
538 if (new_cap) { 535 cap = *new_cap;
539 cap = new_cap; 536 *new_cap = NULL;
540 new_cap = NULL;
541 } else {
542 spin_unlock(&ci->i_ceph_lock);
543 new_cap = get_cap(mdsc, caps_reservation);
544 if (new_cap == NULL)
545 return -ENOMEM;
546 goto retry;
547 }
548 537
549 cap->issued = 0; 538 cap->issued = 0;
550 cap->implemented = 0; 539 cap->implemented = 0;
@@ -562,9 +551,6 @@ retry:
562 session->s_nr_caps++; 551 session->s_nr_caps++;
563 spin_unlock(&session->s_cap_lock); 552 spin_unlock(&session->s_cap_lock);
564 } else { 553 } else {
565 if (new_cap)
566 ceph_put_cap(mdsc, new_cap);
567
568 /* 554 /*
569 * auth mds of the inode changed. we received the cap export 555 * auth mds of the inode changed. we received the cap export
570 * message, but still haven't received the cap import message. 556 * message, but still haven't received the cap import message.
@@ -626,7 +612,6 @@ retry:
626 ci->i_auth_cap = cap; 612 ci->i_auth_cap = cap;
627 cap->mds_wanted = wanted; 613 cap->mds_wanted = wanted;
628 } 614 }
629 ci->i_cap_exporting_issued = 0;
630 } else { 615 } else {
631 WARN_ON(ci->i_auth_cap == cap); 616 WARN_ON(ci->i_auth_cap == cap);
632 } 617 }
@@ -648,9 +633,6 @@ retry:
648 633
649 if (fmode >= 0) 634 if (fmode >= 0)
650 __ceph_get_fmode(ci, fmode); 635 __ceph_get_fmode(ci, fmode);
651 spin_unlock(&ci->i_ceph_lock);
652 wake_up_all(&ci->i_cap_wq);
653 return 0;
654} 636}
655 637
656/* 638/*
@@ -685,7 +667,7 @@ static int __cap_is_valid(struct ceph_cap *cap)
685 */ 667 */
686int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) 668int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented)
687{ 669{
688 int have = ci->i_snap_caps | ci->i_cap_exporting_issued; 670 int have = ci->i_snap_caps;
689 struct ceph_cap *cap; 671 struct ceph_cap *cap;
690 struct rb_node *p; 672 struct rb_node *p;
691 673
@@ -900,7 +882,7 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci)
900 */ 882 */
901static int __ceph_is_any_caps(struct ceph_inode_info *ci) 883static int __ceph_is_any_caps(struct ceph_inode_info *ci)
902{ 884{
903 return !RB_EMPTY_ROOT(&ci->i_caps) || ci->i_cap_exporting_issued; 885 return !RB_EMPTY_ROOT(&ci->i_caps);
904} 886}
905 887
906int ceph_is_any_caps(struct inode *inode) 888int ceph_is_any_caps(struct inode *inode)
@@ -2796,7 +2778,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
2796{ 2778{
2797 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; 2779 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
2798 struct ceph_mds_session *tsession = NULL; 2780 struct ceph_mds_session *tsession = NULL;
2799 struct ceph_cap *cap, *tcap; 2781 struct ceph_cap *cap, *tcap, *new_cap = NULL;
2800 struct ceph_inode_info *ci = ceph_inode(inode); 2782 struct ceph_inode_info *ci = ceph_inode(inode);
2801 u64 t_cap_id; 2783 u64 t_cap_id;
2802 unsigned mseq = le32_to_cpu(ex->migrate_seq); 2784 unsigned mseq = le32_to_cpu(ex->migrate_seq);
@@ -2858,15 +2840,14 @@ retry:
2858 } 2840 }
2859 __ceph_remove_cap(cap, false); 2841 __ceph_remove_cap(cap, false);
2860 goto out_unlock; 2842 goto out_unlock;
2861 } 2843 } else if (tsession) {
2862
2863 if (tsession) {
2864 int flag = (cap == ci->i_auth_cap) ? CEPH_CAP_FLAG_AUTH : 0;
2865 spin_unlock(&ci->i_ceph_lock);
2866 /* add placeholder for the export tagert */ 2844 /* add placeholder for the export tagert */
2845 int flag = (cap == ci->i_auth_cap) ? CEPH_CAP_FLAG_AUTH : 0;
2867 ceph_add_cap(inode, tsession, t_cap_id, -1, issued, 0, 2846 ceph_add_cap(inode, tsession, t_cap_id, -1, issued, 0,
2868 t_seq - 1, t_mseq, (u64)-1, flag, NULL); 2847 t_seq - 1, t_mseq, (u64)-1, flag, &new_cap);
2869 goto retry; 2848
2849 __ceph_remove_cap(cap, false);
2850 goto out_unlock;
2870 } 2851 }
2871 2852
2872 spin_unlock(&ci->i_ceph_lock); 2853 spin_unlock(&ci->i_ceph_lock);
@@ -2885,6 +2866,7 @@ retry:
2885 SINGLE_DEPTH_NESTING); 2866 SINGLE_DEPTH_NESTING);
2886 } 2867 }
2887 ceph_add_cap_releases(mdsc, tsession); 2868 ceph_add_cap_releases(mdsc, tsession);
2869 new_cap = ceph_get_cap(mdsc, NULL);
2888 } else { 2870 } else {
2889 WARN_ON(1); 2871 WARN_ON(1);
2890 tsession = NULL; 2872 tsession = NULL;
@@ -2899,6 +2881,8 @@ out_unlock:
2899 mutex_unlock(&tsession->s_mutex); 2881 mutex_unlock(&tsession->s_mutex);
2900 ceph_put_mds_session(tsession); 2882 ceph_put_mds_session(tsession);
2901 } 2883 }
2884 if (new_cap)
2885 ceph_put_cap(mdsc, new_cap);
2902} 2886}
2903 2887
2904/* 2888/*
@@ -2914,7 +2898,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
2914 void *snaptrace, int snaptrace_len) 2898 void *snaptrace, int snaptrace_len)
2915{ 2899{
2916 struct ceph_inode_info *ci = ceph_inode(inode); 2900 struct ceph_inode_info *ci = ceph_inode(inode);
2917 struct ceph_cap *cap; 2901 struct ceph_cap *cap, *new_cap = NULL;
2918 int mds = session->s_mds; 2902 int mds = session->s_mds;
2919 unsigned issued = le32_to_cpu(im->caps); 2903 unsigned issued = le32_to_cpu(im->caps);
2920 unsigned wanted = le32_to_cpu(im->wanted); 2904 unsigned wanted = le32_to_cpu(im->wanted);
@@ -2936,7 +2920,20 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
2936 dout("handle_cap_import inode %p ci %p mds%d mseq %d peer %d\n", 2920 dout("handle_cap_import inode %p ci %p mds%d mseq %d peer %d\n",
2937 inode, ci, mds, mseq, peer); 2921 inode, ci, mds, mseq, peer);
2938 2922
2923retry:
2939 spin_lock(&ci->i_ceph_lock); 2924 spin_lock(&ci->i_ceph_lock);
2925 cap = __get_cap_for_mds(ci, mds);
2926 if (!cap) {
2927 if (!new_cap) {
2928 spin_unlock(&ci->i_ceph_lock);
2929 new_cap = ceph_get_cap(mdsc, NULL);
2930 goto retry;
2931 }
2932 }
2933
2934 ceph_add_cap(inode, session, cap_id, -1, issued, wanted, seq, mseq,
2935 realmino, CEPH_CAP_FLAG_AUTH, &new_cap);
2936
2940 cap = peer >= 0 ? __get_cap_for_mds(ci, peer) : NULL; 2937 cap = peer >= 0 ? __get_cap_for_mds(ci, peer) : NULL;
2941 if (cap && cap->cap_id == p_cap_id) { 2938 if (cap && cap->cap_id == p_cap_id) {
2942 dout(" remove export cap %p mds%d flags %d\n", 2939 dout(" remove export cap %p mds%d flags %d\n",
@@ -2951,7 +2948,6 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
2951 cap->mseq, mds, le32_to_cpu(ph->seq), 2948 cap->mseq, mds, le32_to_cpu(ph->seq),
2952 le32_to_cpu(ph->mseq)); 2949 le32_to_cpu(ph->mseq));
2953 } 2950 }
2954 ci->i_cap_exporting_issued = cap->issued;
2955 __ceph_remove_cap(cap, (ph->flags & CEPH_CAP_FLAG_RELEASE)); 2951 __ceph_remove_cap(cap, (ph->flags & CEPH_CAP_FLAG_RELEASE));
2956 } 2952 }
2957 2953
@@ -2960,16 +2956,17 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
2960 ci->i_requested_max_size = 0; 2956 ci->i_requested_max_size = 0;
2961 spin_unlock(&ci->i_ceph_lock); 2957 spin_unlock(&ci->i_ceph_lock);
2962 2958
2959 wake_up_all(&ci->i_cap_wq);
2960
2963 down_write(&mdsc->snap_rwsem); 2961 down_write(&mdsc->snap_rwsem);
2964 ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len, 2962 ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len,
2965 false); 2963 false);
2966 downgrade_write(&mdsc->snap_rwsem); 2964 downgrade_write(&mdsc->snap_rwsem);
2967 ceph_add_cap(inode, session, cap_id, -1,
2968 issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH,
2969 NULL /* no caps context */);
2970 kick_flushing_inode_caps(mdsc, session, inode); 2965 kick_flushing_inode_caps(mdsc, session, inode);
2971 up_read(&mdsc->snap_rwsem); 2966 up_read(&mdsc->snap_rwsem);
2972 2967
2968 if (new_cap)
2969 ceph_put_cap(mdsc, new_cap);
2973} 2970}
2974 2971
2975/* 2972/*