summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2018-04-26 22:29:44 -0400
committerIlya Dryomov <idryomov@gmail.com>2018-06-04 14:45:56 -0400
commita1c6b8358171c16db0f858a7fbb28aa574b07c09 (patch)
treed63810202aff8ea136ddfa835b6a1fed08843fe3 /fs/ceph/caps.c
parent2af54a72b585a7cc46fb28845a121635c2540563 (diff)
ceph: define argument structure for handle_cap_grant
The data structure includes the versioned feilds of cap message. Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c115
1 files changed, 61 insertions, 54 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 1b9f611c9dfe..de7b7a34195e 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -3024,24 +3024,32 @@ static void invalidate_aliases(struct inode *inode)
3024 dput(prev); 3024 dput(prev);
3025} 3025}
3026 3026
3027struct cap_extra_info {
3028 struct ceph_string *pool_ns;
3029 /* inline data */
3030 u64 inline_version;
3031 void *inline_data;
3032 u32 inline_len;
3033 /* currently issued */
3034 int issued;
3035};
3036
3027/* 3037/*
3028 * Handle a cap GRANT message from the MDS. (Note that a GRANT may 3038 * Handle a cap GRANT message from the MDS. (Note that a GRANT may
3029 * actually be a revocation if it specifies a smaller cap set.) 3039 * actually be a revocation if it specifies a smaller cap set.)
3030 * 3040 *
3031 * caller holds s_mutex and i_ceph_lock, we drop both. 3041 * caller holds s_mutex and i_ceph_lock, we drop both.
3032 */ 3042 */
3033static void handle_cap_grant(struct ceph_mds_client *mdsc, 3043static void handle_cap_grant(struct inode *inode,
3034 struct inode *inode, struct ceph_mds_caps *grant,
3035 struct ceph_string **pns, u64 inline_version,
3036 void *inline_data, u32 inline_len,
3037 struct ceph_buffer *xattr_buf,
3038 struct ceph_mds_session *session, 3044 struct ceph_mds_session *session,
3039 struct ceph_cap *cap, int issued) 3045 struct ceph_cap *cap,
3046 struct ceph_mds_caps *grant,
3047 struct ceph_buffer *xattr_buf,
3048 struct cap_extra_info *extra_info)
3040 __releases(ci->i_ceph_lock) 3049 __releases(ci->i_ceph_lock)
3041 __releases(mdsc->snap_rwsem) 3050 __releases(session->s_mdsc->snap_rwsem)
3042{ 3051{
3043 struct ceph_inode_info *ci = ceph_inode(inode); 3052 struct ceph_inode_info *ci = ceph_inode(inode);
3044 int mds = session->s_mds;
3045 int seq = le32_to_cpu(grant->seq); 3053 int seq = le32_to_cpu(grant->seq);
3046 int newcaps = le32_to_cpu(grant->caps); 3054 int newcaps = le32_to_cpu(grant->caps);
3047 int used, wanted, dirty; 3055 int used, wanted, dirty;
@@ -3057,7 +3065,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
3057 bool fill_inline = false; 3065 bool fill_inline = false;
3058 3066
3059 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", 3067 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
3060 inode, cap, mds, seq, ceph_cap_string(newcaps)); 3068 inode, cap, session->s_mds, seq, ceph_cap_string(newcaps));
3061 dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, 3069 dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
3062 inode->i_size); 3070 inode->i_size);
3063 3071
@@ -3103,7 +3111,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
3103 __check_cap_issue(ci, cap, newcaps); 3111 __check_cap_issue(ci, cap, newcaps);
3104 3112
3105 if ((newcaps & CEPH_CAP_AUTH_SHARED) && 3113 if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
3106 (issued & CEPH_CAP_AUTH_EXCL) == 0) { 3114 (extra_info->issued & CEPH_CAP_AUTH_EXCL) == 0) {
3107 inode->i_mode = le32_to_cpu(grant->mode); 3115 inode->i_mode = le32_to_cpu(grant->mode);
3108 inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid)); 3116 inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
3109 inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid)); 3117 inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
@@ -3113,14 +3121,15 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
3113 } 3121 }
3114 3122
3115 if ((newcaps & CEPH_CAP_AUTH_SHARED) && 3123 if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
3116 (issued & CEPH_CAP_LINK_EXCL) == 0) { 3124 (extra_info->issued & CEPH_CAP_LINK_EXCL) == 0) {
3117 set_nlink(inode, le32_to_cpu(grant->nlink)); 3125 set_nlink(inode, le32_to_cpu(grant->nlink));
3118 if (inode->i_nlink == 0 && 3126 if (inode->i_nlink == 0 &&
3119 (newcaps & (CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL))) 3127 (newcaps & (CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL)))
3120 deleted_inode = true; 3128 deleted_inode = true;
3121 } 3129 }
3122 3130
3123 if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) { 3131 if ((extra_info->issued & CEPH_CAP_XATTR_EXCL) == 0 &&
3132 grant->xattr_len) {
3124 int len = le32_to_cpu(grant->xattr_len); 3133 int len = le32_to_cpu(grant->xattr_len);
3125 u64 version = le64_to_cpu(grant->xattr_version); 3134 u64 version = le64_to_cpu(grant->xattr_version);
3126 3135
@@ -3140,7 +3149,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
3140 ceph_decode_timespec(&mtime, &grant->mtime); 3149 ceph_decode_timespec(&mtime, &grant->mtime);
3141 ceph_decode_timespec(&atime, &grant->atime); 3150 ceph_decode_timespec(&atime, &grant->atime);
3142 ceph_decode_timespec(&ctime, &grant->ctime); 3151 ceph_decode_timespec(&ctime, &grant->ctime);
3143 ceph_fill_file_time(inode, issued, 3152 ceph_fill_file_time(inode, extra_info->issued,
3144 le32_to_cpu(grant->time_warp_seq), 3153 le32_to_cpu(grant->time_warp_seq),
3145 &ctime, &mtime, &atime); 3154 &ctime, &mtime, &atime);
3146 } 3155 }
@@ -3153,15 +3162,16 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
3153 ceph_file_layout_from_legacy(&ci->i_layout, &grant->layout); 3162 ceph_file_layout_from_legacy(&ci->i_layout, &grant->layout);
3154 old_ns = rcu_dereference_protected(ci->i_layout.pool_ns, 3163 old_ns = rcu_dereference_protected(ci->i_layout.pool_ns,
3155 lockdep_is_held(&ci->i_ceph_lock)); 3164 lockdep_is_held(&ci->i_ceph_lock));
3156 rcu_assign_pointer(ci->i_layout.pool_ns, *pns); 3165 rcu_assign_pointer(ci->i_layout.pool_ns, extra_info->pool_ns);
3157 3166
3158 if (ci->i_layout.pool_id != old_pool || *pns != old_ns) 3167 if (ci->i_layout.pool_id != old_pool ||
3168 extra_info->pool_ns != old_ns)
3159 ci->i_ceph_flags &= ~CEPH_I_POOL_PERM; 3169 ci->i_ceph_flags &= ~CEPH_I_POOL_PERM;
3160 3170
3161 *pns = old_ns; 3171 extra_info->pool_ns = old_ns;
3162 3172
3163 /* size/truncate_seq? */ 3173 /* size/truncate_seq? */
3164 queue_trunc = ceph_fill_file_size(inode, issued, 3174 queue_trunc = ceph_fill_file_size(inode, extra_info->issued,
3165 le32_to_cpu(grant->truncate_seq), 3175 le32_to_cpu(grant->truncate_seq),
3166 le64_to_cpu(grant->truncate_size), 3176 le64_to_cpu(grant->truncate_size),
3167 size); 3177 size);
@@ -3240,24 +3250,26 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
3240 } 3250 }
3241 BUG_ON(cap->issued & ~cap->implemented); 3251 BUG_ON(cap->issued & ~cap->implemented);
3242 3252
3243 if (inline_version > 0 && inline_version >= ci->i_inline_version) { 3253 if (extra_info->inline_version > 0 &&
3244 ci->i_inline_version = inline_version; 3254 extra_info->inline_version >= ci->i_inline_version) {
3255 ci->i_inline_version = extra_info->inline_version;
3245 if (ci->i_inline_version != CEPH_INLINE_NONE && 3256 if (ci->i_inline_version != CEPH_INLINE_NONE &&
3246 (newcaps & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO))) 3257 (newcaps & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)))
3247 fill_inline = true; 3258 fill_inline = true;
3248 } 3259 }
3249 3260
3250 if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) { 3261 if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) {
3251 if (newcaps & ~issued) 3262 if (newcaps & ~extra_info->issued)
3252 wake = true; 3263 wake = true;
3253 kick_flushing_inode_caps(mdsc, session, inode); 3264 kick_flushing_inode_caps(session->s_mdsc, session, inode);
3254 up_read(&mdsc->snap_rwsem); 3265 up_read(&session->s_mdsc->snap_rwsem);
3255 } else { 3266 } else {
3256 spin_unlock(&ci->i_ceph_lock); 3267 spin_unlock(&ci->i_ceph_lock);
3257 } 3268 }
3258 3269
3259 if (fill_inline) 3270 if (fill_inline)
3260 ceph_fill_inline_data(inode, NULL, inline_data, inline_len); 3271 ceph_fill_inline_data(inode, NULL, extra_info->inline_data,
3272 extra_info->inline_len);
3261 3273
3262 if (queue_trunc) 3274 if (queue_trunc)
3263 ceph_queue_vmtruncate(inode); 3275 ceph_queue_vmtruncate(inode);
@@ -3722,31 +3734,24 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3722 struct ceph_msg *msg) 3734 struct ceph_msg *msg)
3723{ 3735{
3724 struct ceph_mds_client *mdsc = session->s_mdsc; 3736 struct ceph_mds_client *mdsc = session->s_mdsc;
3725 struct super_block *sb = mdsc->fsc->sb;
3726 struct inode *inode; 3737 struct inode *inode;
3727 struct ceph_inode_info *ci; 3738 struct ceph_inode_info *ci;
3728 struct ceph_cap *cap; 3739 struct ceph_cap *cap;
3729 struct ceph_mds_caps *h; 3740 struct ceph_mds_caps *h;
3730 struct ceph_mds_cap_peer *peer = NULL; 3741 struct ceph_mds_cap_peer *peer = NULL;
3731 struct ceph_snap_realm *realm = NULL; 3742 struct ceph_snap_realm *realm = NULL;
3732 struct ceph_string *pool_ns = NULL; 3743 int op;
3733 int mds = session->s_mds;
3734 int op, issued;
3735 u32 seq, mseq; 3744 u32 seq, mseq;
3736 struct ceph_vino vino; 3745 struct ceph_vino vino;
3737 u64 tid;
3738 u64 inline_version = 0;
3739 void *inline_data = NULL;
3740 u32 inline_len = 0;
3741 void *snaptrace; 3746 void *snaptrace;
3742 size_t snaptrace_len; 3747 size_t snaptrace_len;
3743 void *p, *end; 3748 void *p, *end;
3749 struct cap_extra_info extra_info = {};
3744 3750
3745 dout("handle_caps from mds%d\n", mds); 3751 dout("handle_caps from mds%d\n", session->s_mds);
3746 3752
3747 /* decode */ 3753 /* decode */
3748 end = msg->front.iov_base + msg->front.iov_len; 3754 end = msg->front.iov_base + msg->front.iov_len;
3749 tid = le64_to_cpu(msg->hdr.tid);
3750 if (msg->front.iov_len < sizeof(*h)) 3755 if (msg->front.iov_len < sizeof(*h))
3751 goto bad; 3756 goto bad;
3752 h = msg->front.iov_base; 3757 h = msg->front.iov_base;
@@ -3781,12 +3786,12 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3781 } 3786 }
3782 3787
3783 if (le16_to_cpu(msg->hdr.version) >= 4) { 3788 if (le16_to_cpu(msg->hdr.version) >= 4) {
3784 ceph_decode_64_safe(&p, end, inline_version, bad); 3789 ceph_decode_64_safe(&p, end, extra_info.inline_version, bad);
3785 ceph_decode_32_safe(&p, end, inline_len, bad); 3790 ceph_decode_32_safe(&p, end, extra_info.inline_len, bad);
3786 if (p + inline_len > end) 3791 if (p + extra_info.inline_len > end)
3787 goto bad; 3792 goto bad;
3788 inline_data = p; 3793 extra_info.inline_data = p;
3789 p += inline_len; 3794 p += extra_info.inline_len;
3790 } 3795 }
3791 3796
3792 if (le16_to_cpu(msg->hdr.version) >= 5) { 3797 if (le16_to_cpu(msg->hdr.version) >= 5) {
@@ -3811,13 +3816,14 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3811 ceph_decode_32_safe(&p, end, pool_ns_len, bad); 3816 ceph_decode_32_safe(&p, end, pool_ns_len, bad);
3812 if (pool_ns_len > 0) { 3817 if (pool_ns_len > 0) {
3813 ceph_decode_need(&p, end, pool_ns_len, bad); 3818 ceph_decode_need(&p, end, pool_ns_len, bad);
3814 pool_ns = ceph_find_or_create_string(p, pool_ns_len); 3819 extra_info.pool_ns =
3820 ceph_find_or_create_string(p, pool_ns_len);
3815 p += pool_ns_len; 3821 p += pool_ns_len;
3816 } 3822 }
3817 } 3823 }
3818 3824
3819 /* lookup ino */ 3825 /* lookup ino */
3820 inode = ceph_find_inode(sb, vino); 3826 inode = ceph_find_inode(mdsc->fsc->sb, vino);
3821 ci = ceph_inode(inode); 3827 ci = ceph_inode(inode);
3822 dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino, 3828 dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino,
3823 vino.snap, inode); 3829 vino.snap, inode);
@@ -3850,7 +3856,8 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3850 /* these will work even if we don't have a cap yet */ 3856 /* these will work even if we don't have a cap yet */
3851 switch (op) { 3857 switch (op) {
3852 case CEPH_CAP_OP_FLUSHSNAP_ACK: 3858 case CEPH_CAP_OP_FLUSHSNAP_ACK:
3853 handle_cap_flushsnap_ack(inode, tid, h, session); 3859 handle_cap_flushsnap_ack(inode, le64_to_cpu(msg->hdr.tid),
3860 h, session);
3854 goto done; 3861 goto done;
3855 3862
3856 case CEPH_CAP_OP_EXPORT: 3863 case CEPH_CAP_OP_EXPORT:
@@ -3869,10 +3876,9 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3869 down_read(&mdsc->snap_rwsem); 3876 down_read(&mdsc->snap_rwsem);
3870 } 3877 }
3871 handle_cap_import(mdsc, inode, h, peer, session, 3878 handle_cap_import(mdsc, inode, h, peer, session,
3872 &cap, &issued); 3879 &cap, &extra_info.issued);
3873 handle_cap_grant(mdsc, inode, h, &pool_ns, 3880 handle_cap_grant(inode, session, cap,
3874 inline_version, inline_data, inline_len, 3881 h, msg->middle, &extra_info);
3875 msg->middle, session, cap, issued);
3876 if (realm) 3882 if (realm)
3877 ceph_put_snap_realm(mdsc, realm); 3883 ceph_put_snap_realm(mdsc, realm);
3878 goto done_unlocked; 3884 goto done_unlocked;
@@ -3880,10 +3886,11 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3880 3886
3881 /* the rest require a cap */ 3887 /* the rest require a cap */
3882 spin_lock(&ci->i_ceph_lock); 3888 spin_lock(&ci->i_ceph_lock);
3883 cap = __get_cap_for_mds(ceph_inode(inode), mds); 3889 cap = __get_cap_for_mds(ceph_inode(inode), session->s_mds);
3884 if (!cap) { 3890 if (!cap) {
3885 dout(" no cap on %p ino %llx.%llx from mds%d\n", 3891 dout(" no cap on %p ino %llx.%llx from mds%d\n",
3886 inode, ceph_ino(inode), ceph_snap(inode), mds); 3892 inode, ceph_ino(inode), ceph_snap(inode),
3893 session->s_mds);
3887 spin_unlock(&ci->i_ceph_lock); 3894 spin_unlock(&ci->i_ceph_lock);
3888 goto flush_cap_releases; 3895 goto flush_cap_releases;
3889 } 3896 }
@@ -3892,15 +3899,15 @@ void ceph_handle_caps(struct ceph_mds_session *session,
3892 switch (op) { 3899 switch (op) {
3893 case CEPH_CAP_OP_REVOKE: 3900 case CEPH_CAP_OP_REVOKE:
3894 case CEPH_CAP_OP_GRANT: 3901 case CEPH_CAP_OP_GRANT:
3895 __ceph_caps_issued(ci, &issued); 3902 __ceph_caps_issued(ci, &extra_info.issued);
3896 issued |= __ceph_caps_dirty(ci); 3903 extra_info.issued |= __ceph_caps_dirty(ci);
3897 handle_cap_grant(mdsc, inode, h, &pool_ns, 3904 handle_cap_grant(inode, session, cap,
3898 inline_version, inline_data, inline_len, 3905 h, msg->middle, &extra_info);
3899 msg->middle, session, cap, issued);
3900 goto done_unlocked; 3906 goto done_unlocked;
3901 3907
3902 case CEPH_CAP_OP_FLUSH_ACK: 3908 case CEPH_CAP_OP_FLUSH_ACK:
3903 handle_cap_flush_ack(inode, tid, h, session, cap); 3909 handle_cap_flush_ack(inode, le64_to_cpu(msg->hdr.tid),
3910 h, session, cap);
3904 break; 3911 break;
3905 3912
3906 case CEPH_CAP_OP_TRUNC: 3913 case CEPH_CAP_OP_TRUNC:
@@ -3927,7 +3934,7 @@ done:
3927 mutex_unlock(&session->s_mutex); 3934 mutex_unlock(&session->s_mutex);
3928done_unlocked: 3935done_unlocked:
3929 iput(inode); 3936 iput(inode);
3930 ceph_put_string(pool_ns); 3937 ceph_put_string(extra_info.pool_ns);
3931 return; 3938 return;
3932 3939
3933bad: 3940bad: