diff options
| author | Alex Elder <elder@inktank.com> | 2013-03-14 15:09:06 -0400 |
|---|---|---|
| committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:18:32 -0400 |
| commit | 5240d9f95dfe0f0701b35fbff1cb5b70825ad23f (patch) | |
| tree | 570f8f274803e56bb86e43180b230f3d70a61649 | |
| parent | 8ae4f4f5c056150d5480710ab356801e84d01a3d (diff) | |
libceph: replace message data pointer with list
In place of the message data pointer, use a list head which links
through message data items. For now we only support a single entry
on that list.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
| -rw-r--r-- | include/linux/ceph/messenger.h | 3 | ||||
| -rw-r--r-- | net/ceph/messenger.c | 46 |
2 files changed, 33 insertions, 16 deletions
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index 8846ff610502..318da0170a1e 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h | |||
| @@ -89,6 +89,7 @@ static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type) | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | struct ceph_msg_data { | 91 | struct ceph_msg_data { |
| 92 | struct list_head links; /* ceph_msg->data */ | ||
| 92 | enum ceph_msg_data_type type; | 93 | enum ceph_msg_data_type type; |
| 93 | union { | 94 | union { |
| 94 | #ifdef CONFIG_BLOCK | 95 | #ifdef CONFIG_BLOCK |
| @@ -143,7 +144,7 @@ struct ceph_msg { | |||
| 143 | struct ceph_buffer *middle; | 144 | struct ceph_buffer *middle; |
| 144 | 145 | ||
| 145 | size_t data_length; | 146 | size_t data_length; |
| 146 | struct ceph_msg_data *data; | 147 | struct list_head data; |
| 147 | struct ceph_msg_data_cursor cursor; | 148 | struct ceph_msg_data_cursor cursor; |
| 148 | 149 | ||
| 149 | struct ceph_connection *con; | 150 | struct ceph_connection *con; |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 3aa0f30c3c5e..8bfe7d34bc85 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
| @@ -985,8 +985,10 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor, | |||
| 985 | static void ceph_msg_data_cursor_init(struct ceph_msg *msg, size_t length) | 985 | static void ceph_msg_data_cursor_init(struct ceph_msg *msg, size_t length) |
| 986 | { | 986 | { |
| 987 | struct ceph_msg_data_cursor *cursor = &msg->cursor; | 987 | struct ceph_msg_data_cursor *cursor = &msg->cursor; |
| 988 | struct ceph_msg_data *data; | ||
| 988 | 989 | ||
| 989 | cursor->data = msg->data; | 990 | data = list_first_entry(&msg->data, struct ceph_msg_data, links); |
| 991 | cursor->data = data; | ||
| 990 | switch (cursor->data->type) { | 992 | switch (cursor->data->type) { |
| 991 | case CEPH_MSG_DATA_PAGELIST: | 993 | case CEPH_MSG_DATA_PAGELIST: |
| 992 | ceph_msg_data_pagelist_cursor_init(cursor, length); | 994 | ceph_msg_data_pagelist_cursor_init(cursor, length); |
| @@ -1410,7 +1412,7 @@ static int write_partial_message_data(struct ceph_connection *con) | |||
| 1410 | 1412 | ||
| 1411 | dout("%s %p msg %p\n", __func__, con, msg); | 1413 | dout("%s %p msg %p\n", __func__, con, msg); |
| 1412 | 1414 | ||
| 1413 | if (WARN_ON(!msg->data)) | 1415 | if (list_empty(&msg->data)) |
| 1414 | return -EINVAL; | 1416 | return -EINVAL; |
| 1415 | 1417 | ||
| 1416 | /* | 1418 | /* |
| @@ -2111,7 +2113,7 @@ static int read_partial_msg_data(struct ceph_connection *con) | |||
| 2111 | int ret; | 2113 | int ret; |
| 2112 | 2114 | ||
| 2113 | BUG_ON(!msg); | 2115 | BUG_ON(!msg); |
| 2114 | if (!msg->data) | 2116 | if (list_empty(&msg->data)) |
| 2115 | return -EIO; | 2117 | return -EIO; |
| 2116 | 2118 | ||
| 2117 | if (do_datacrc) | 2119 | if (do_datacrc) |
| @@ -2963,6 +2965,7 @@ static struct ceph_msg_data *ceph_msg_data_create(enum ceph_msg_data_type type) | |||
| 2963 | data = kzalloc(sizeof (*data), GFP_NOFS); | 2965 | data = kzalloc(sizeof (*data), GFP_NOFS); |
| 2964 | if (data) | 2966 | if (data) |
| 2965 | data->type = type; | 2967 | data->type = type; |
| 2968 | INIT_LIST_HEAD(&data->links); | ||
| 2966 | 2969 | ||
| 2967 | return data; | 2970 | return data; |
| 2968 | } | 2971 | } |
| @@ -2972,6 +2975,7 @@ static void ceph_msg_data_destroy(struct ceph_msg_data *data) | |||
| 2972 | if (!data) | 2975 | if (!data) |
| 2973 | return; | 2976 | return; |
| 2974 | 2977 | ||
| 2978 | WARN_ON(!list_empty(&data->links)); | ||
| 2975 | if (data->type == CEPH_MSG_DATA_PAGELIST) { | 2979 | if (data->type == CEPH_MSG_DATA_PAGELIST) { |
| 2976 | ceph_pagelist_release(data->pagelist); | 2980 | ceph_pagelist_release(data->pagelist); |
| 2977 | kfree(data->pagelist); | 2981 | kfree(data->pagelist); |
| @@ -2987,7 +2991,7 @@ void ceph_msg_data_set_pages(struct ceph_msg *msg, struct page **pages, | |||
| 2987 | BUG_ON(!pages); | 2991 | BUG_ON(!pages); |
| 2988 | BUG_ON(!length); | 2992 | BUG_ON(!length); |
| 2989 | BUG_ON(msg->data_length); | 2993 | BUG_ON(msg->data_length); |
| 2990 | BUG_ON(msg->data != NULL); | 2994 | BUG_ON(!list_empty(&msg->data)); |
| 2991 | 2995 | ||
| 2992 | data = ceph_msg_data_create(CEPH_MSG_DATA_PAGES); | 2996 | data = ceph_msg_data_create(CEPH_MSG_DATA_PAGES); |
| 2993 | BUG_ON(!data); | 2997 | BUG_ON(!data); |
| @@ -2995,8 +2999,9 @@ void ceph_msg_data_set_pages(struct ceph_msg *msg, struct page **pages, | |||
| 2995 | data->length = length; | 2999 | data->length = length; |
| 2996 | data->alignment = alignment & ~PAGE_MASK; | 3000 | data->alignment = alignment & ~PAGE_MASK; |
| 2997 | 3001 | ||
| 2998 | msg->data = data; | 3002 | BUG_ON(!list_empty(&msg->data)); |
| 2999 | msg->data_length = length; | 3003 | list_add_tail(&data->links, &msg->data); |
| 3004 | msg->data_length += length; | ||
| 3000 | } | 3005 | } |
| 3001 | EXPORT_SYMBOL(ceph_msg_data_set_pages); | 3006 | EXPORT_SYMBOL(ceph_msg_data_set_pages); |
| 3002 | 3007 | ||
| @@ -3008,14 +3013,14 @@ void ceph_msg_data_set_pagelist(struct ceph_msg *msg, | |||
| 3008 | BUG_ON(!pagelist); | 3013 | BUG_ON(!pagelist); |
| 3009 | BUG_ON(!pagelist->length); | 3014 | BUG_ON(!pagelist->length); |
| 3010 | BUG_ON(msg->data_length); | 3015 | BUG_ON(msg->data_length); |
| 3011 | BUG_ON(msg->data != NULL); | 3016 | BUG_ON(!list_empty(&msg->data)); |
| 3012 | 3017 | ||
| 3013 | data = ceph_msg_data_create(CEPH_MSG_DATA_PAGELIST); | 3018 | data = ceph_msg_data_create(CEPH_MSG_DATA_PAGELIST); |
| 3014 | BUG_ON(!data); | 3019 | BUG_ON(!data); |
| 3015 | data->pagelist = pagelist; | 3020 | data->pagelist = pagelist; |
| 3016 | 3021 | ||
| 3017 | msg->data = data; | 3022 | list_add_tail(&data->links, &msg->data); |
| 3018 | msg->data_length = pagelist->length; | 3023 | msg->data_length += pagelist->length; |
| 3019 | } | 3024 | } |
| 3020 | EXPORT_SYMBOL(ceph_msg_data_set_pagelist); | 3025 | EXPORT_SYMBOL(ceph_msg_data_set_pagelist); |
| 3021 | 3026 | ||
| @@ -3027,15 +3032,15 @@ void ceph_msg_data_set_bio(struct ceph_msg *msg, struct bio *bio, | |||
| 3027 | 3032 | ||
| 3028 | BUG_ON(!bio); | 3033 | BUG_ON(!bio); |
| 3029 | BUG_ON(msg->data_length); | 3034 | BUG_ON(msg->data_length); |
| 3030 | BUG_ON(msg->data != NULL); | 3035 | BUG_ON(!list_empty(&msg->data)); |
| 3031 | 3036 | ||
| 3032 | data = ceph_msg_data_create(CEPH_MSG_DATA_BIO); | 3037 | data = ceph_msg_data_create(CEPH_MSG_DATA_BIO); |
| 3033 | BUG_ON(!data); | 3038 | BUG_ON(!data); |
| 3034 | data->bio = bio; | 3039 | data->bio = bio; |
| 3035 | data->bio_length = length; | 3040 | data->bio_length = length; |
| 3036 | 3041 | ||
| 3037 | msg->data = data; | 3042 | list_add_tail(&data->links, &msg->data); |
| 3038 | msg->data_length = length; | 3043 | msg->data_length += length; |
| 3039 | } | 3044 | } |
| 3040 | EXPORT_SYMBOL(ceph_msg_data_set_bio); | 3045 | EXPORT_SYMBOL(ceph_msg_data_set_bio); |
| 3041 | #endif /* CONFIG_BLOCK */ | 3046 | #endif /* CONFIG_BLOCK */ |
| @@ -3059,6 +3064,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, | |||
| 3059 | 3064 | ||
| 3060 | INIT_LIST_HEAD(&m->list_head); | 3065 | INIT_LIST_HEAD(&m->list_head); |
| 3061 | kref_init(&m->kref); | 3066 | kref_init(&m->kref); |
| 3067 | INIT_LIST_HEAD(&m->data); | ||
| 3062 | 3068 | ||
| 3063 | /* front */ | 3069 | /* front */ |
| 3064 | m->front_max = front_len; | 3070 | m->front_max = front_len; |
| @@ -3204,6 +3210,9 @@ void ceph_msg_kfree(struct ceph_msg *m) | |||
| 3204 | void ceph_msg_last_put(struct kref *kref) | 3210 | void ceph_msg_last_put(struct kref *kref) |
| 3205 | { | 3211 | { |
| 3206 | struct ceph_msg *m = container_of(kref, struct ceph_msg, kref); | 3212 | struct ceph_msg *m = container_of(kref, struct ceph_msg, kref); |
| 3213 | LIST_HEAD(data); | ||
| 3214 | struct list_head *links; | ||
| 3215 | struct list_head *next; | ||
| 3207 | 3216 | ||
| 3208 | dout("ceph_msg_put last one on %p\n", m); | 3217 | dout("ceph_msg_put last one on %p\n", m); |
| 3209 | WARN_ON(!list_empty(&m->list_head)); | 3218 | WARN_ON(!list_empty(&m->list_head)); |
| @@ -3213,8 +3222,15 @@ void ceph_msg_last_put(struct kref *kref) | |||
| 3213 | ceph_buffer_put(m->middle); | 3222 | ceph_buffer_put(m->middle); |
| 3214 | m->middle = NULL; | 3223 | m->middle = NULL; |
| 3215 | } | 3224 | } |
| 3216 | ceph_msg_data_destroy(m->data); | 3225 | |
| 3217 | m->data = NULL; | 3226 | list_splice_init(&m->data, &data); |
| 3227 | list_for_each_safe(links, next, &data) { | ||
| 3228 | struct ceph_msg_data *data; | ||
| 3229 | |||
| 3230 | data = list_entry(links, struct ceph_msg_data, links); | ||
| 3231 | list_del_init(links); | ||
| 3232 | ceph_msg_data_destroy(data); | ||
| 3233 | } | ||
| 3218 | m->data_length = 0; | ||
