diff options
author | Yan, Zheng <zyan@redhat.com> | 2018-04-26 22:29:44 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-06-04 14:45:56 -0400 |
commit | a1c6b8358171c16db0f858a7fbb28aa574b07c09 (patch) | |
tree | d63810202aff8ea136ddfa835b6a1fed08843fe3 /fs/ceph/caps.c | |
parent | 2af54a72b585a7cc46fb28845a121635c2540563 (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.c | 115 |
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 | ||
3027 | struct 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 | */ |
3033 | static void handle_cap_grant(struct ceph_mds_client *mdsc, | 3043 | static 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); |
3928 | done_unlocked: | 3935 | done_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 | ||
3933 | bad: | 3940 | bad: |