diff options
author | Yan, Zheng <zyan@redhat.com> | 2014-11-14 08:29:55 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@redhat.com> | 2014-12-17 12:09:52 -0500 |
commit | fb01d1f8b0343f1b19be878cee89d089f06e9f38 (patch) | |
tree | c2cb02b48b5cf4df6d5a4bb59be63f07c5409b0b /fs | |
parent | 715e4cd405cfd67bd058e410b3e599bab2072645 (diff) |
ceph: parse inline data in MClientReply and MClientCaps
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/caps.c | 34 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 10 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 3 |
3 files changed, 36 insertions, 11 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index eb1bf1f35e0e..b88ae601f309 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -2383,6 +2383,8 @@ static void invalidate_aliases(struct inode *inode) | |||
2383 | static void handle_cap_grant(struct ceph_mds_client *mdsc, | 2383 | static void handle_cap_grant(struct ceph_mds_client *mdsc, |
2384 | struct inode *inode, struct ceph_mds_caps *grant, | 2384 | struct inode *inode, struct ceph_mds_caps *grant, |
2385 | void *snaptrace, int snaptrace_len, | 2385 | void *snaptrace, int snaptrace_len, |
2386 | u64 inline_version, | ||
2387 | void *inline_data, int inline_len, | ||
2386 | struct ceph_buffer *xattr_buf, | 2388 | struct ceph_buffer *xattr_buf, |
2387 | struct ceph_mds_session *session, | 2389 | struct ceph_mds_session *session, |
2388 | struct ceph_cap *cap, int issued) | 2390 | struct ceph_cap *cap, int issued) |
@@ -2996,11 +2998,12 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2996 | u64 cap_id; | 2998 | u64 cap_id; |
2997 | u64 size, max_size; | 2999 | u64 size, max_size; |
2998 | u64 tid; | 3000 | u64 tid; |
3001 | u64 inline_version = 0; | ||
3002 | void *inline_data = NULL; | ||
3003 | u32 inline_len = 0; | ||
2999 | void *snaptrace; | 3004 | void *snaptrace; |
3000 | size_t snaptrace_len; | 3005 | size_t snaptrace_len; |
3001 | void *flock; | 3006 | void *p, *end; |
3002 | void *end; | ||
3003 | u32 flock_len; | ||
3004 | 3007 | ||
3005 | dout("handle_caps from mds%d\n", mds); | 3008 | dout("handle_caps from mds%d\n", mds); |
3006 | 3009 | ||
@@ -3021,30 +3024,37 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3021 | 3024 | ||
3022 | snaptrace = h + 1; | 3025 | snaptrace = h + 1; |
3023 | snaptrace_len = le32_to_cpu(h->snap_trace_len); | 3026 | snaptrace_len = le32_to_cpu(h->snap_trace_len); |
3027 | p = snaptrace + snaptrace_len; | ||
3024 | 3028 | ||
3025 | if (le16_to_cpu(msg->hdr.version) >= 2) { | 3029 | if (le16_to_cpu(msg->hdr.version) >= 2) { |
3026 | void *p = snaptrace + snaptrace_len; | 3030 | u32 flock_len; |
3027 | ceph_decode_32_safe(&p, end, flock_len, bad); | 3031 | ceph_decode_32_safe(&p, end, flock_len, bad); |
3028 | if (p + flock_len > end) | 3032 | if (p + flock_len > end) |
3029 | goto bad; | 3033 | goto bad; |
3030 | flock = p; | 3034 | p += flock_len; |
3031 | } else { | ||
3032 | flock = NULL; | ||
3033 | flock_len = 0; | ||
3034 | } | 3035 | } |
3035 | 3036 | ||
3036 | if (le16_to_cpu(msg->hdr.version) >= 3) { | 3037 | if (le16_to_cpu(msg->hdr.version) >= 3) { |
3037 | if (op == CEPH_CAP_OP_IMPORT) { | 3038 | if (op == CEPH_CAP_OP_IMPORT) { |
3038 | void *p = flock + flock_len; | ||
3039 | if (p + sizeof(*peer) > end) | 3039 | if (p + sizeof(*peer) > end) |
3040 | goto bad; | 3040 | goto bad; |
3041 | peer = p; | 3041 | peer = p; |
3042 | p += sizeof(*peer); | ||
3042 | } else if (op == CEPH_CAP_OP_EXPORT) { | 3043 | } else if (op == CEPH_CAP_OP_EXPORT) { |
3043 | /* recorded in unused fields */ | 3044 | /* recorded in unused fields */ |
3044 | peer = (void *)&h->size; | 3045 | peer = (void *)&h->size; |
3045 | } | 3046 | } |
3046 | } | 3047 | } |
3047 | 3048 | ||
3049 | if (le16_to_cpu(msg->hdr.version) >= 4) { | ||
3050 | ceph_decode_64_safe(&p, end, inline_version, bad); | ||
3051 | ceph_decode_32_safe(&p, end, inline_len, bad); | ||
3052 | if (p + inline_len > end) | ||
3053 | goto bad; | ||
3054 | inline_data = p; | ||
3055 | p += inline_len; | ||
3056 | } | ||
3057 | |||
3048 | /* lookup ino */ | 3058 | /* lookup ino */ |
3049 | inode = ceph_find_inode(sb, vino); | 3059 | inode = ceph_find_inode(sb, vino); |
3050 | ci = ceph_inode(inode); | 3060 | ci = ceph_inode(inode); |
@@ -3085,6 +3095,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3085 | handle_cap_import(mdsc, inode, h, peer, session, | 3095 | handle_cap_import(mdsc, inode, h, peer, session, |
3086 | &cap, &issued); | 3096 | &cap, &issued); |
3087 | handle_cap_grant(mdsc, inode, h, snaptrace, snaptrace_len, | 3097 | handle_cap_grant(mdsc, inode, h, snaptrace, snaptrace_len, |
3098 | inline_version, inline_data, inline_len, | ||
3088 | msg->middle, session, cap, issued); | 3099 | msg->middle, session, cap, issued); |
3089 | goto done_unlocked; | 3100 | goto done_unlocked; |
3090 | } | 3101 | } |
@@ -3105,8 +3116,9 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3105 | case CEPH_CAP_OP_GRANT: | 3116 | case CEPH_CAP_OP_GRANT: |
3106 | __ceph_caps_issued(ci, &issued); | 3117 | __ceph_caps_issued(ci, &issued); |
3107 | issued |= __ceph_caps_dirty(ci); | 3118 | issued |= __ceph_caps_dirty(ci); |
3108 | handle_cap_grant(mdsc, inode, h, NULL, 0, msg->middle, | 3119 | handle_cap_grant(mdsc, inode, h, NULL, 0, |
3109 | session, cap, issued); | 3120 | inline_version, inline_data, inline_len, |
3121 | msg->middle, session, cap, issued); | ||
3110 | goto done_unlocked; | 3122 | goto done_unlocked; |
3111 | 3123 | ||
3112 | case CEPH_CAP_OP_FLUSH_ACK: | 3124 | case CEPH_CAP_OP_FLUSH_ACK: |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 387a48993d34..d2171f4a6980 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -89,6 +89,16 @@ static int parse_reply_info_in(void **p, void *end, | |||
89 | ceph_decode_need(p, end, info->xattr_len, bad); | 89 | ceph_decode_need(p, end, info->xattr_len, bad); |
90 | info->xattr_data = *p; | 90 | info->xattr_data = *p; |
91 | *p += info->xattr_len; | 91 | *p += info->xattr_len; |
92 | |||
93 | if (features & CEPH_FEATURE_MDS_INLINE_DATA) { | ||
94 | ceph_decode_64_safe(p, end, info->inline_version, bad); | ||
95 | ceph_decode_32_safe(p, end, info->inline_len, bad); | ||
96 | ceph_decode_need(p, end, info->inline_len, bad); | ||
97 | info->inline_data = *p; | ||
98 | *p += info->inline_len; | ||
99 | } else | ||
100 | info->inline_version = CEPH_INLINE_NONE; | ||
101 | |||
92 | return 0; | 102 | return 0; |
93 | bad: | 103 | bad: |
94 | return err; | 104 | return err; |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 230bda791d4f..01f5e4cfd684 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -41,6 +41,9 @@ struct ceph_mds_reply_info_in { | |||
41 | char *symlink; | 41 | char *symlink; |
42 | u32 xattr_len; | 42 | u32 xattr_len; |
43 | char *xattr_data; | 43 | char *xattr_data; |
44 | u64 inline_version; | ||
45 | u32 inline_len; | ||
46 | char *inline_data; | ||
44 | }; | 47 | }; |
45 | 48 | ||
46 | /* | 49 | /* |