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 /net/ceph | |
| 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>
Diffstat (limited to 'net/ceph')
| -rw-r--r-- | net/ceph/messenger.c | 46 |
1 files changed, 31 insertions, 15 deletions
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; | 3234 | m->data_length = 0; |
| 3219 | 3235 | ||
| 3220 | if (m->pool) | 3236 | if (m->pool) |
| @@ -3227,7 +3243,7 @@ EXPORT_SYMBOL(ceph_msg_last_put); | |||
| 3227 | void ceph_msg_dump(struct ceph_msg *msg) | 3243 | void ceph_msg_dump(struct ceph_msg *msg) |
| 3228 | { | 3244 | { |
| 3229 | pr_debug("msg_dump %p (front_max %d length %zd)\n", msg, | 3245 | pr_debug("msg_dump %p (front_max %d length %zd)\n", msg, |
| 3230 | msg->front_max, msg->data->length); | 3246 | msg->front_max, msg->data_length); |
| 3231 | print_hex_dump(KERN_DEBUG, "header: ", | 3247 | print_hex_dump(KERN_DEBUG, "header: ", |
| 3232 | DUMP_PREFIX_OFFSET, 16, 1, | 3248 | DUMP_PREFIX_OFFSET, 16, 1, |
| 3233 | &msg->hdr, sizeof(msg->hdr), true); | 3249 | &msg->hdr, sizeof(msg->hdr), true); |
