* [PATCH 1/3] ceph: support multiple class method calls in one ceph_msg
2015-04-23 19:06 [PATCH 0/3] rbd: header read/refresh improvements Douglas Fuller
@ 2015-04-23 19:06 ` Douglas Fuller
2015-04-23 19:06 ` [PATCH 2/3] rbd: combine object method calls in header refresh using fewer ceph_msgs Douglas Fuller
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Douglas Fuller @ 2015-04-23 19:06 UTC (permalink / raw)
To: ceph-devel
Messages are received from the wire directly into destination buffers.
A short read could result in corruption of the following destination
buffers. Allocate a single message buffer for all class method calls
and split them at the osd_client level. This only applies to ceph_msgs
containing multiple op call and may break support for ceph_msgs
containing a mix of class method calls that return data and other ops.
Signed-off-by: Douglas Fuller <dfuller@redhat.com>
---
include/linux/ceph/osd_client.h | 1 +
net/ceph/messenger.c | 4 ++
net/ceph/osd_client.c | 92 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 61b19c4..65fcf80 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -99,6 +99,7 @@ struct ceph_osd_req_op {
struct ceph_osd_data request_info;
struct ceph_osd_data request_data;
struct ceph_osd_data response_data;
+ struct ceph_osd_data chain_data;
__u8 class_len;
__u8 method_len;
__u8 argc;
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 967080a..ec04be4 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -907,6 +907,10 @@ static void ceph_msg_data_pages_cursor_init(struct ceph_msg_data_cursor *cursor,
BUG_ON(!data->pages);
BUG_ON(!data->length);
+ /*
+ * bug here if a short read occurs and length < data->length; see
+ * http://tracker.ceph.com/issues/11424
+ */
cursor->resid = min(length, data->length);
page_count = calc_pages_for(data->alignment, (u64)data->length);
cursor->page_offset = data->alignment & ~PAGE_MASK;
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 41a4abc..3999dfa 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -301,6 +301,73 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
}
}
+static int __build_op_cls_chain(struct ceph_osd_request *osd_req)
+{
+ u64 chain_length = 0;
+ u32 chain_pagecount = 0;
+ struct ceph_osd_req_op *op = NULL;
+ struct ceph_osd_data *osd_data;
+ struct ceph_osd_data *chain_data;
+ struct page **pages;
+ int i;
+
+ chain_data = osd_req_op_data(osd_req, 0, cls, chain_data);
+
+ for (i=0; i<osd_req->r_num_ops; i++)
+ {
+ op = &osd_req->r_ops[i];
+ if (op->op != CEPH_OSD_OP_CALL)
+ break;
+
+ osd_data = osd_req_op_data(osd_req, i, cls, chain_data);
+ osd_data->length = 0;
+
+ osd_data = osd_req_op_data(osd_req, i, cls, response_data);
+ chain_length += osd_data->length;
+ }
+
+ chain_data->length = chain_length;
+ chain_pagecount = (u32)calc_pages_for(0, chain_data->length);
+ pages = ceph_alloc_page_vector(chain_pagecount, GFP_KERNEL);
+ if (IS_ERR(pages))
+ return PTR_ERR(pages);
+ ceph_osd_data_pages_init(chain_data, pages, chain_length, 0, false, false);
+
+ return 0;
+}
+
+static int __split_cls_op_chain(struct ceph_osd_request *osd_req)
+{
+ int i;
+ void * data;
+ void * p;
+ struct ceph_osd_data *osd_data;
+
+ osd_data = osd_req_op_data(osd_req, 0, cls, chain_data);
+
+ if (osd_data->length == 0)
+ return 0;
+
+ data = kzalloc(osd_data->length, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ ceph_copy_from_page_vector(osd_data->pages, data, 0, osd_data->length);
+ ceph_osd_data_release(osd_data);
+
+ p = data;
+ for (i = 0; i < osd_req->r_num_ops; i++)
+ {
+ osd_data = osd_req_op_data(osd_req, i, cls, response_data);
+ ceph_copy_to_page_vector(osd_data->pages, p,
+ 0, osd_req->r_reply_op_len[i]);
+ p += osd_req->r_reply_op_len[i];
+ }
+
+ kfree(data);
+ return 0;
+}
+
/*
* requests
*/
@@ -694,8 +761,20 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
src->payload_len += data_length;
request_data_len += data_length;
}
- osd_data = &src->cls.response_data;
- ceph_osdc_msg_data_add(req->r_reply, osd_data);
+ if (which == 0)
+ {
+ int err;
+
+ err = __build_op_cls_chain(req);
+ if (err == -ENOMEM)
+ {
+ pr_err("error allocating memory for op chain\n");
+ return 0;
+ }
+ osd_data = &src->cls.chain_data;
+ if (osd_data->length)
+ ceph_osdc_msg_data_add(req->r_reply, osd_data);
+ }
break;
case CEPH_OSD_OP_STARTSYNC:
break;
@@ -1825,6 +1904,15 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
for (i = 0; i < numops; i++)
req->r_reply_op_result[i] = ceph_decode_32(&p);
+ if (req->r_ops[0].op == CEPH_OSD_OP_CALL &&
+ req->r_ops[0].cls.chain_data.length)
+ {
+ int err;
+ err = __split_cls_op_chain(req);
+ if (err == -ENOMEM)
+ goto bad_put;
+ }
+
if (le16_to_cpu(msg->hdr.version) >= 6) {
p += 8 + 4; /* skip replay_version */
p += 8; /* skip user_version */
--
1.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/3] rbd: combine object method calls in header refresh using fewer ceph_msgs
2015-04-23 19:06 [PATCH 0/3] rbd: header read/refresh improvements Douglas Fuller
2015-04-23 19:06 ` [PATCH 1/3] ceph: support multiple class method calls in one ceph_msg Douglas Fuller
@ 2015-04-23 19:06 ` Douglas Fuller
2015-04-24 10:14 ` Mike Christie
2015-04-23 19:06 ` [PATCH 3/3] rbd: re-read features during header refresh and detect changes Douglas Fuller
2015-04-24 13:11 ` [PATCH 0/3] rbd: header read/refresh improvements Alex Elder
3 siblings, 1 reply; 10+ messages in thread
From: Douglas Fuller @ 2015-04-23 19:06 UTC (permalink / raw)
To: ceph-devel
Signed-off-by: Douglas Fuller <douglas.fuller@gmail.com>
---
drivers/block/rbd.c | 337 ++++++++++++++++++++++++++++++++++++----
include/linux/ceph/osd_client.h | 2 +-
2 files changed, 312 insertions(+), 27 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 8125233..63771f6 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -4577,6 +4577,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
"rbd", "get_snapcontext", NULL, 0,
reply_buf, size);
dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
+printk(KERN_INFO "%s: rbd_obj_method_sync returned %d\n", __func__, ret);
if (ret < 0)
goto out;
@@ -4667,20 +4668,23 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
bool first_time = rbd_dev->header.object_prefix == NULL;
int ret;
- ret = rbd_dev_v2_image_size(rbd_dev);
- if (ret)
- return ret;
+ if (!first_time)
+ {
+ ret = rbd_dev_v2_image_size(rbd_dev);
+ if (ret)
+ return ret;
- if (first_time) {
+ ret = rbd_dev_v2_snap_context(rbd_dev);
+ dout("rbd_dev_v2_snap_context returned %d\n", ret);
+ return ret;
+ }
+ else
+ {
ret = rbd_dev_v2_header_onetime(rbd_dev);
if (ret)
return ret;
}
-
- ret = rbd_dev_v2_snap_context(rbd_dev);
- dout("rbd_dev_v2_snap_context returned %d\n", ret);
-
- return ret;
+ return ret; /* XXX change logic? */
}
static int rbd_dev_header_info(struct rbd_device *rbd_dev)
@@ -5091,36 +5095,317 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
memset(header, 0, sizeof (*header));
}
-static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
+static struct ceph_osd_request * rbd_obj_header_req_alloc(
+ struct rbd_device *rbd_dev,
+ int num_ops)
+{
+ struct ceph_osd_request *osd_req;
+ struct page ***replies;
+
+ replies = kmalloc(CEPH_OSD_MAX_OP * sizeof(*replies), GFP_KERNEL);
+ if (!replies)
+ return NULL;
+
+ osd_req = ceph_osdc_alloc_request(&rbd_dev->rbd_client->client->osdc,
+ NULL, num_ops, false, GFP_ATOMIC);
+ if (!osd_req)
+ {
+ kfree(replies);
+ return NULL;
+ }
+
+ osd_req->r_flags = CEPH_OSD_FLAG_READ;
+ osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
+ osd_req->r_priv = (void *)replies;
+ ceph_oid_set_name(&osd_req->r_base_oid, rbd_dev->header_name);
+
+ return osd_req;
+}
+
+static int rbd_obj_header_method_add(struct ceph_osd_request *osd_req,
+ int which,
+ const char *class_name,
+ const char *method_name,
+ const void *outbound,
+ size_t outbound_size,
+ size_t inbound_size)
+{
+ u32 page_count;
+ struct page ***replies = (struct page ***)osd_req->r_priv;
+
+ BUG_ON(which >= osd_req->r_num_ops);
+
+ osd_req_op_cls_init(osd_req, which, CEPH_OSD_OP_CALL,
+ class_name, method_name);
+
+ if (outbound_size)
+ {
+ struct ceph_pagelist *pagelist;
+ pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+ /* XXX is this ever freed? */
+ if (!pagelist)
+ return -ENOMEM;
+
+ ceph_pagelist_init(pagelist);
+ ceph_pagelist_append(pagelist, outbound, outbound_size);
+ osd_req_op_cls_request_data_pagelist(osd_req, which, pagelist);
+ }
+
+ page_count = (u32)calc_pages_for(0, inbound_size);
+ replies[which] = ceph_alloc_page_vector(page_count, GFP_KERNEL);
+ if (IS_ERR(replies[which]))
+ return PTR_ERR(replies[which]);
+ osd_req_op_cls_response_data_pages(osd_req, which, replies[which],
+ inbound_size, 0, false, false);
+
+ return 0;
+}
+
+static int rbd_obj_header_req_exec(struct rbd_device * rbd_dev,
+ struct ceph_osd_request *osd_req)
{
int ret;
- ret = rbd_dev_v2_object_prefix(rbd_dev);
+ ceph_osdc_build_request(osd_req, 0, NULL, cpu_to_le64(CEPH_NOSNAP), NULL);
+ ret = ceph_osdc_start_request(&rbd_dev->rbd_client->client->osdc,
+ osd_req, false);
if (ret)
+ {
+ ceph_osdc_put_request(osd_req);
+ return ret;
+ }
+
+ ret = ceph_osdc_wait_request(&rbd_dev->rbd_client->client->osdc, osd_req);
+ if (ret < 0)
+ {
+ ceph_osdc_cancel_request(osd_req);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rbd_obj_header_method_retrieve(struct ceph_osd_request *osd_req,
+ int which, void *buf, size_t length)
+{
+ struct page ***replies = (struct page ***)osd_req->r_priv;
+ size_t reply_length = osd_req->r_reply_op_len[which];
+
+ BUG_ON(reply_length > length);
+
+ ceph_copy_from_page_vector(replies[which], buf, 0, reply_length);
+ ceph_release_page_vector(replies[which], calc_pages_for(0, reply_length));
+
+ return reply_length;
+}
+
+static void rbd_obj_header_req_destroy(struct ceph_osd_request *osd_req)
+{
+ if (osd_req)
+ {
+ kfree(osd_req->r_priv);
+ ceph_osdc_put_request(osd_req);
+ }
+}
+
+static int __extract_prefix(struct rbd_device *rbd_dev,
+ struct ceph_osd_request *osd_req,
+ int which)
+{
+ void *prefix_buf;
+ void * p;
+ size_t prefix_buflen;
+ int ret;
+
+ prefix_buf = kzalloc(RBD_OBJ_PREFIX_LEN_MAX, GFP_KERNEL);
+ if (!prefix_buf)
+ return -ENOMEM;
+
+ prefix_buflen = rbd_obj_header_method_retrieve(osd_req, which,
+ prefix_buf, RBD_OBJ_PREFIX_LEN_MAX);
+ p = prefix_buf;
+ rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
+ p + prefix_buflen, NULL, GFP_NOIO);
+
+ if (IS_ERR(rbd_dev->header.object_prefix))
+ {
+ ret = PTR_ERR(rbd_dev->header.object_prefix);
+ rbd_dev->header.object_prefix = NULL;
goto out_err;
+ }
- /*
- * Get the and check features for the image. Currently the
- * features are assumed to never change.
- */
- ret = rbd_dev_v2_features(rbd_dev);
- if (ret)
+ ret = 0;
+
+out_err:
+ kfree(prefix_buf);
+ return ret;
+}
+
+static int __extract_features(struct rbd_device *rbd_dev,
+ struct ceph_osd_request *osd_req,
+ int which)
+{
+ int ret;
+ struct
+ {
+ __le64 features;
+ __le64 incompat;
+ } __attribute__((packed)) features_buf = { 0 };
+ u64 incompat;
+
+ rbd_obj_header_method_retrieve(osd_req, which,
+ &features_buf, sizeof(features_buf));
+ incompat = le64_to_cpu(features_buf.incompat);
+ if (incompat & ~RBD_FEATURES_SUPPORTED)
+ {
+ ret = -ENXIO;
goto out_err;
+ }
+ rbd_dev->header.features = le64_to_cpu(features_buf.features);
- /* If the image supports fancy striping, get its parameters */
+ ret = 0;
- if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
- ret = rbd_dev_v2_striping_info(rbd_dev);
- if (ret < 0)
- goto out_err;
+out_err:
+ return ret;
+}
+
+static int __extract_snapcontext(struct rbd_device *rbd_dev,
+ struct ceph_osd_request *osd_req,
+ int which)
+{
+ void *snapc_buf;
+ size_t snapc_max;
+ size_t snapc_buflen;
+
+ void *p;
+ void *q;
+
+ struct ceph_snap_context * snapc;
+
+ u32 seq;
+ u32 snap_count;
+
+ int i;
+ int ret;
+
+ snapc_max = sizeof(__le64) + sizeof(__le32) +
+ RBD_MAX_SNAP_COUNT * sizeof(__le64);
+
+ snapc_buf = kzalloc(snapc_max, GFP_KERNEL);
+ BUG_ON(!snapc_buf);
+
+ snapc_buflen = rbd_obj_header_method_retrieve(osd_req, which,
+ snapc_buf, snapc_max);
+
+ p = snapc_buf;
+ q = snapc_buf + snapc_buflen;
+ ret = -ERANGE;
+ ceph_decode_64_safe(&p, q, seq, out_err);
+ ceph_decode_32_safe(&p, q, snap_count, out_err);
+
+ if (snap_count > (SIZE_MAX - sizeof(struct ceph_snap_context)) /
+ sizeof(u64))
+ {
+ ret = -EINVAL;
+ goto out_err;
}
- /* No support for crypto and compression type format 2 images */
+ if (!ceph_has_room(&p, q, snap_count * sizeof(__le64)))
+ goto out_err;
+
+ snapc = ceph_create_snap_context(snap_count, GFP_KERNEL);
+ BUG_ON(!snapc);
+ snapc->seq = seq;
+ for (i=0; i < snap_count; i++)
+ snapc->snaps[i] = ceph_decode_64(&p);
+ ceph_put_snap_context(rbd_dev->header.snapc);
+ rbd_dev->header.snapc = snapc;
+
+ ret = 0;
+out_err:
+ kfree(snapc_buf);
+ return ret;
+}
+
+static int __extract_size(struct rbd_device *rbd_dev,
+ struct ceph_osd_request *osd_req,
+ int which)
+{
+ struct
+ {
+ u8 order;
+ __le64 size;
+ } __attribute((packed)) size_buf = { 0 };
+
+ rbd_obj_header_method_retrieve(osd_req, which, &size_buf, sizeof(size_buf));
+
+ rbd_dev->header.obj_order = size_buf.order;
+ rbd_dev->header.image_size = le64_to_cpu(size_buf.size);
return 0;
+}
+
+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
+{
+ int ret;
+
+ size_t snapc_max;
+ __le64 snapid = cpu_to_le64(CEPH_NOSNAP);
+ struct ceph_osd_request *osd_req;
+
+ snapc_max = sizeof(__le64) + sizeof(__le32) +
+ RBD_MAX_SNAP_COUNT * sizeof(__le64);
+
+ osd_req = rbd_obj_header_req_alloc(rbd_dev, 4);
+
+ if (!osd_req)
+ {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ ret = rbd_obj_header_method_add(osd_req, 0,
+ "rbd", "get_object_prefix",
+ NULL, 0, RBD_OBJ_PREFIX_LEN_MAX);
+ if (ret)
+ goto out_err;
+
+ ret = rbd_obj_header_method_add(osd_req, 1,
+ "rbd", "get_features",
+ &snapid, sizeof(snapid),
+ sizeof(struct{__le64 features;__le64 incompat;} __attribute__((packed))));
+ if (ret)
+ goto out_err;
+
+ ret = rbd_obj_header_method_add(osd_req, 2,
+ "rbd", "get_snapcontext",
+ NULL, 0, snapc_max);
+ if (ret)
+ goto out_err;
+
+ ret = rbd_obj_header_method_add(osd_req, 3,
+ "rbd", "get_size",
+ &snapid, sizeof(snapid),
+ sizeof(struct{u8 order; __le64 size;}__attribute((packed))));
+ if (ret)
+ goto out_err;
+
+ ret = rbd_obj_header_req_exec(rbd_dev, osd_req);
+ if (ret)
+ goto out_err;
+
+ if ((ret = __extract_prefix(rbd_dev, osd_req, 0)))
+ goto out_err;
+ if ((ret = __extract_features(rbd_dev, osd_req, 1)))
+ goto out_err;
+ if ((ret = __extract_snapcontext(rbd_dev, osd_req, 2)))
+ goto out_err;
+ if ((ret = __extract_size(rbd_dev, osd_req, 3)))
+ goto out_err;
+
+ ret = 0;
+
out_err:
- rbd_dev->header.features = 0;
- kfree(rbd_dev->header.object_prefix);
- rbd_dev->header.object_prefix = NULL;
+ rbd_obj_header_req_destroy(osd_req);
return ret;
}
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 65fcf80..71c946d 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -43,7 +43,7 @@ struct ceph_osd {
};
-#define CEPH_OSD_MAX_OP 3
+#define CEPH_OSD_MAX_OP 4
enum ceph_osd_data_type {
CEPH_OSD_DATA_TYPE_NONE = 0,
--
1.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 2/3] rbd: combine object method calls in header refresh using fewer ceph_msgs
2015-04-23 19:06 ` [PATCH 2/3] rbd: combine object method calls in header refresh using fewer ceph_msgs Douglas Fuller
@ 2015-04-24 10:14 ` Mike Christie
0 siblings, 0 replies; 10+ messages in thread
From: Mike Christie @ 2015-04-24 10:14 UTC (permalink / raw)
To: Douglas Fuller, ceph-devel
On 04/23/2015 02:06 PM, Douglas Fuller wrote:
> Signed-off-by: Douglas Fuller <douglas.fuller@gmail.com>
> ---
> drivers/block/rbd.c | 337 ++++++++++++++++++++++++++++++++++++----
> include/linux/ceph/osd_client.h | 2 +-
> 2 files changed, 312 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 8125233..63771f6 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -4577,6 +4577,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
> "rbd", "get_snapcontext", NULL, 0,
> reply_buf, size);
> dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
> +printk(KERN_INFO "%s: rbd_obj_method_sync returned %d\n", __func__, ret);
You probably forgot to remove that debug printk.
> if (ret < 0)
> goto out;
>
> @@ -4667,20 +4668,23 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
> bool first_time = rbd_dev->header.object_prefix == NULL;
> int ret;
>
> - ret = rbd_dev_v2_image_size(rbd_dev);
> - if (ret)
> - return ret;
> + if (!first_time)
> + {
You want to follow the coding style in the existing code or follow the
style in Documentation/CodingStyle. The {} use in your if/elses do not
follow either one.
> + ret = rbd_dev_v2_image_size(rbd_dev);
> + if (ret)
> + return ret;
>
> - if (first_time) {
> + ret = rbd_dev_v2_snap_context(rbd_dev);
> + dout("rbd_dev_v2_snap_context returned %d\n", ret);
> + return ret;
> + }
> + else
> + {
> ret = rbd_dev_v2_header_onetime(rbd_dev);
> if (ret)
> return ret;
> }
> -
> - ret = rbd_dev_v2_snap_context(rbd_dev);
> - dout("rbd_dev_v2_snap_context returned %d\n", ret);
> -
> - return ret;
> + return ret; /* XXX change logic? */
> }
>
> static int rbd_dev_header_info(struct rbd_device *rbd_dev)
> @@ -5091,36 +5095,317 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
> memset(header, 0, sizeof (*header));
> }
>
> -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
> +static struct ceph_osd_request * rbd_obj_header_req_alloc(
> + struct rbd_device *rbd_dev,
> + int num_ops)
> +{
> + struct ceph_osd_request *osd_req;
> + struct page ***replies;
> +
> + replies = kmalloc(CEPH_OSD_MAX_OP * sizeof(*replies), GFP_KERNEL);
> + if (!replies)
> + return NULL;
> +
> + osd_req = ceph_osdc_alloc_request(&rbd_dev->rbd_client->client->osdc,
> + NULL, num_ops, false, GFP_ATOMIC);
I think you can just use GFP_KERNEL here. You used it above and it looks
like we have process context and are not under any locks.
You might have to use GFP_NOIO if we think that these functions are
called from the watch_cb for something like a resize and we need to
update the rbd_dev's size before we can execute IO. I do not think that
is the case though, so I think GFP_KERNEL is ok.
> + if (!osd_req)
> + {
> + kfree(replies);
> + return NULL;
> + }
> +
> + osd_req->r_flags = CEPH_OSD_FLAG_READ;
> + osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
> + osd_req->r_priv = (void *)replies;
No need to cast to a void pointer.
> + ceph_oid_set_name(&osd_req->r_base_oid, rbd_dev->header_name);
> +
> + return osd_req;
> +}
> +
> +static int rbd_obj_header_method_add(struct ceph_osd_request *osd_req,
> + int which,
> + const char *class_name,
> + const char *method_name,
> + const void *outbound,
> + size_t outbound_size,
> + size_t inbound_size)
I think you want to follow the existing code's tab style for function
arguments.
> +{
> + u32 page_count;
> + struct page ***replies = (struct page ***)osd_req->r_priv;
Don't need to cast from a void pointer.
> +
> + BUG_ON(which >= osd_req->r_num_ops);
> +
> + osd_req_op_cls_init(osd_req, which, CEPH_OSD_OP_CALL,
> + class_name, method_name);
> +
> + if (outbound_size)
> + {
> + struct ceph_pagelist *pagelist;
> + pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
I think you can use GFP_KERNEL here. You used it below.
If you cannot use GFP_KERNEL, then you really want to be using GFP_NOIO
instead of GFP_NOFS.
> + /* XXX is this ever freed? */
> + if (!pagelist)
> + return -ENOMEM;
> +
> + ceph_pagelist_init(pagelist);
> + ceph_pagelist_append(pagelist, outbound, outbound_size);
> + osd_req_op_cls_request_data_pagelist(osd_req, which, pagelist);
> + }
> +
> + page_count = (u32)calc_pages_for(0, inbound_size);
> + replies[which] = ceph_alloc_page_vector(page_count, GFP_KERNEL);
> + if (IS_ERR(replies[which]))
> + return PTR_ERR(replies[which]);
> + osd_req_op_cls_response_data_pages(osd_req, which, replies[which],
> + inbound_size, 0, false, false);
> +
> + return 0;
> +}
> +
> +static int rbd_obj_header_req_exec(struct rbd_device * rbd_dev,
> + struct ceph_osd_request *osd_req)
> {
> int ret;
>
> - ret = rbd_dev_v2_object_prefix(rbd_dev);
> + ceph_osdc_build_request(osd_req, 0, NULL, cpu_to_le64(CEPH_NOSNAP), NULL);
> + ret = ceph_osdc_start_request(&rbd_dev->rbd_client->client->osdc,
> + osd_req, false);
> if (ret)
> + {
> + ceph_osdc_put_request(osd_req);
> + return ret;
> + }
> +
> + ret = ceph_osdc_wait_request(&rbd_dev->rbd_client->client->osdc, osd_req);
> + if (ret < 0)
> + {
> + ceph_osdc_cancel_request(osd_req);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int rbd_obj_header_method_retrieve(struct ceph_osd_request *osd_req,
> + int which, void *buf, size_t length)
> +{
> + struct page ***replies = (struct page ***)osd_req->r_priv;
> + size_t reply_length = osd_req->r_reply_op_len[which];
> +
> + BUG_ON(reply_length > length);
> +
> + ceph_copy_from_page_vector(replies[which], buf, 0, reply_length);
> + ceph_release_page_vector(replies[which], calc_pages_for(0, reply_length));
> +
> + return reply_length;
> +}
> +
> +static void rbd_obj_header_req_destroy(struct ceph_osd_request *osd_req)
> +{
> + if (osd_req)
> + {
> + kfree(osd_req->r_priv);
> + ceph_osdc_put_request(osd_req);
> + }
> +}
> +
> +static int __extract_prefix(struct rbd_device *rbd_dev,
> + struct ceph_osd_request *osd_req,
> + int which)
> +{
> + void *prefix_buf;
> + void * p;
> + size_t prefix_buflen;
> + int ret;
> +
> + prefix_buf = kzalloc(RBD_OBJ_PREFIX_LEN_MAX, GFP_KERNEL);
> + if (!prefix_buf)
> + return -ENOMEM;
> +
> + prefix_buflen = rbd_obj_header_method_retrieve(osd_req, which,
> + prefix_buf, RBD_OBJ_PREFIX_LEN_MAX);
> + p = prefix_buf;
> + rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
> + p + prefix_buflen, NULL, GFP_NOIO);
I think this can be GFP_KERNEL like above.
> +
> + if (IS_ERR(rbd_dev->header.object_prefix))
> + {
> + ret = PTR_ERR(rbd_dev->header.object_prefix);
> + rbd_dev->header.object_prefix = NULL;
> goto out_err;
> + }
>
> - /*
> - * Get the and check features for the image. Currently the
> - * features are assumed to never change.
> - */
> - ret = rbd_dev_v2_features(rbd_dev);
> - if (ret)
> + ret = 0;
> +
> +out_err:
> + kfree(prefix_buf);
> + return ret;
> +}
> +
> +static int __extract_features(struct rbd_device *rbd_dev,
> + struct ceph_osd_request *osd_req,
> + int which)
> +{
> + int ret;
> + struct
> + {
> + __le64 features;
> + __le64 incompat;
> + } __attribute__((packed)) features_buf = { 0 };
> + u64 incompat;
> +
> + rbd_obj_header_method_retrieve(osd_req, which,
> + &features_buf, sizeof(features_buf));
> + incompat = le64_to_cpu(features_buf.incompat);
> + if (incompat & ~RBD_FEATURES_SUPPORTED)
> + {
> + ret = -ENXIO;
> goto out_err;
> + }
> + rbd_dev->header.features = le64_to_cpu(features_buf.features);
>
> - /* If the image supports fancy striping, get its parameters */
> + ret = 0;
>
> - if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
> - ret = rbd_dev_v2_striping_info(rbd_dev);
> - if (ret < 0)
> - goto out_err;
> +out_err:
> + return ret;
> +}
> +
> +static int __extract_snapcontext(struct rbd_device *rbd_dev,
> + struct ceph_osd_request *osd_req,
> + int which)
> +{
> + void *snapc_buf;
> + size_t snapc_max;
> + size_t snapc_buflen;
> +
> + void *p;
> + void *q;
> +
> + struct ceph_snap_context * snapc;
> +
> + u32 seq;
> + u32 snap_count;
> +
> + int i;
> + int ret;
> +
> + snapc_max = sizeof(__le64) + sizeof(__le32) +
> + RBD_MAX_SNAP_COUNT * sizeof(__le64);
> +
> + snapc_buf = kzalloc(snapc_max, GFP_KERNEL);
> + BUG_ON(!snapc_buf);
Why a BUG_ON for a allocation failure?
> +
> + snapc_buflen = rbd_obj_header_method_retrieve(osd_req, which,
> + snapc_buf, snapc_max);
> +
> + p = snapc_buf;
> + q = snapc_buf + snapc_buflen;
> + ret = -ERANGE;
> + ceph_decode_64_safe(&p, q, seq, out_err);
> + ceph_decode_32_safe(&p, q, snap_count, out_err);
> +
> + if (snap_count > (SIZE_MAX - sizeof(struct ceph_snap_context)) /
> + sizeof(u64))
> + {
> + ret = -EINVAL;
> + goto out_err;
> }
> - /* No support for crypto and compression type format 2 images */
> + if (!ceph_has_room(&p, q, snap_count * sizeof(__le64)))
> + goto out_err;
> +
> + snapc = ceph_create_snap_context(snap_count, GFP_KERNEL);
> + BUG_ON(!snapc);
Again why a BUG_ON?
I think it is best to handle it gracefully. There is no need to kill the
box for a allocation failure.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] rbd: re-read features during header refresh and detect changes.
2015-04-23 19:06 [PATCH 0/3] rbd: header read/refresh improvements Douglas Fuller
2015-04-23 19:06 ` [PATCH 1/3] ceph: support multiple class method calls in one ceph_msg Douglas Fuller
2015-04-23 19:06 ` [PATCH 2/3] rbd: combine object method calls in header refresh using fewer ceph_msgs Douglas Fuller
@ 2015-04-23 19:06 ` Douglas Fuller
2015-04-24 13:11 ` [PATCH 0/3] rbd: header read/refresh improvements Alex Elder
3 siblings, 0 replies; 10+ messages in thread
From: Douglas Fuller @ 2015-04-23 19:06 UTC (permalink / raw)
To: ceph-devel
From: Douglas Fuller <douglas.fuller@gmail.com>
Add a new header item to track when features have changed since mapping and
return EIO on I/O operations. Clean up and consolidate code path for
header read and update. Remove unused code.
Signed-off-by: Douglas Fuller <douglas.fuller@gmail.com>
---
drivers/block/rbd.c | 209 +++++++++++++++++++---------------------------------
1 file changed, 77 insertions(+), 132 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 63771f6..1ab8c12 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -320,9 +320,17 @@ struct rbd_img_request {
#define for_each_obj_request_safe(ireq, oreq, n) \
list_for_each_entry_safe_reverse(oreq, n, &(ireq)->obj_requests, links)
+enum rbd_mapping_state
+{
+ MAP_STATE_MAPPED,
+ MAP_STATE_DETACHED,
+};
+
+
struct rbd_mapping {
u64 size;
u64 features;
+ enum rbd_mapping_state state;
bool read_only;
};
@@ -527,7 +535,7 @@ static void rbd_img_parent_read(struct rbd_obj_request *obj_request);
static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
static int rbd_dev_refresh(struct rbd_device *rbd_dev);
-static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev);
+static int rbd_dev_v2_header_data(struct rbd_device *rbd_dev);
static int rbd_dev_header_info(struct rbd_device *rbd_dev);
static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev);
static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
@@ -3336,6 +3344,14 @@ static void rbd_queue_workfn(struct work_struct *work)
else
op_type = OBJ_OP_READ;
+ /* If a configuration change was detected, issue EIO. */
+
+ if (rbd_dev->mapping.state == MAP_STATE_DETACHED)
+ {
+ result = -EIO;
+ goto err_rq;
+ }
+
/* Ignore/skip any zero-length requests */
if (!length) {
@@ -3670,12 +3686,23 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev)
static int rbd_dev_refresh(struct rbd_device *rbd_dev)
{
u64 mapping_size;
+ u64 features;
int ret;
down_write(&rbd_dev->header_rwsem);
mapping_size = rbd_dev->mapping.size;
+ features = rbd_dev->mapping.features;
ret = rbd_dev_header_info(rbd_dev);
+
+ if (ret == -ENXIO || (ret && features != rbd_dev->mapping.features))
+ {
+ rbd_dev->mapping.read_only = 1;
+ rbd_dev->mapping.state = MAP_STATE_DETACHED;
+ rbd_warn(rbd_dev,
+ "detected feature change in mapped device, setting read-only");
+ }
+
if (ret)
goto out;
@@ -3698,6 +3725,9 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)
out:
up_write(&rbd_dev->header_rwsem);
+
+ if (rbd_dev->mapping.read_only)
+ set_disk_ro(rbd_dev->disk, 1);
if (!ret && mapping_size != rbd_dev->mapping.size)
rbd_dev_update_size(rbd_dev);
@@ -4111,47 +4141,6 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
return 0;
}
-static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev)
-{
- return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
- &rbd_dev->header.obj_order,
- &rbd_dev->header.image_size);
-}
-
-static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev)
-{
- void *reply_buf;
- int ret;
- void *p;
-
- reply_buf = kzalloc(RBD_OBJ_PREFIX_LEN_MAX, GFP_KERNEL);
- if (!reply_buf)
- return -ENOMEM;
-
- ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name,
- "rbd", "get_object_prefix", NULL, 0,
- reply_buf, RBD_OBJ_PREFIX_LEN_MAX);
- dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
- if (ret < 0)
- goto out;
-
- p = reply_buf;
- rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
- p + ret, NULL, GFP_NOIO);
- ret = 0;
-
- if (IS_ERR(rbd_dev->header.object_prefix)) {
- ret = PTR_ERR(rbd_dev->header.object_prefix);
- rbd_dev->header.object_prefix = NULL;
- } else {
- dout(" object_prefix = %s\n", rbd_dev->header.object_prefix);
- }
-out:
- kfree(reply_buf);
-
- return ret;
-}
-
static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
u64 *snap_features)
{
@@ -4187,12 +4176,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
return 0;
}
-static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
-{
- return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
- &rbd_dev->header.features);
-}
-
static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
{
struct rbd_spec *parent_spec;
@@ -4549,79 +4532,6 @@ out_err:
return ret;
}
-static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
-{
- size_t size;
- int ret;
- void *reply_buf;
- void *p;
- void *end;
- u64 seq;
- u32 snap_count;
- struct ceph_snap_context *snapc;
- u32 i;
-
- /*
- * We'll need room for the seq value (maximum snapshot id),
- * snapshot count, and array of that many snapshot ids.
- * For now we have a fixed upper limit on the number we're
- * prepared to receive.
- */
- size = sizeof (__le64) + sizeof (__le32) +
- RBD_MAX_SNAP_COUNT * sizeof (__le64);
- reply_buf = kzalloc(size, GFP_KERNEL);
- if (!reply_buf)
- return -ENOMEM;
-
- ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name,
- "rbd", "get_snapcontext", NULL, 0,
- reply_buf, size);
- dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
-printk(KERN_INFO "%s: rbd_obj_method_sync returned %d\n", __func__, ret);
- if (ret < 0)
- goto out;
-
- p = reply_buf;
- end = reply_buf + ret;
- ret = -ERANGE;
- ceph_decode_64_safe(&p, end, seq, out);
- ceph_decode_32_safe(&p, end, snap_count, out);
-
- /*
- * Make sure the reported number of snapshot ids wouldn't go
- * beyond the end of our buffer. But before checking that,
- * make sure the computed size of the snapshot context we
- * allocate is representable in a size_t.
- */
- if (snap_count > (SIZE_MAX - sizeof (struct ceph_snap_context))
- / sizeof (u64)) {
- ret = -EINVAL;
- goto out;
- }
- if (!ceph_has_room(&p, end, snap_count * sizeof (__le64)))
- goto out;
- ret = 0;
-
- snapc = ceph_create_snap_context(snap_count, GFP_KERNEL);
- if (!snapc) {
- ret = -ENOMEM;
- goto out;
- }
- snapc->seq = seq;
- for (i = 0; i < snap_count; i++)
- snapc->snaps[i] = ceph_decode_64(&p);
-
- ceph_put_snap_context(rbd_dev->header.snapc);
- rbd_dev->header.snapc = snapc;
-
- dout(" snap context seq = %llu, snap_count = %u\n",
- (unsigned long long)seq, (unsigned int)snap_count);
-out:
- kfree(reply_buf);
-
- return ret;
-}
-
static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
u64 snap_id)
{
@@ -4663,6 +4573,16 @@ out:
return snap_name;
}
+static int rbd_dev_v2_mutable_metadata(struct rbd_device *rbd_dev)
+{
+ return rbd_dev_v2_header_data(rbd_dev);
+}
+
+static int rbd_dev_v2_immutable_metadata(struct rbd_device *rbd_dev)
+{
+ return rbd_dev_v2_header_data(rbd_dev);
+}
+
static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
{
bool first_time = rbd_dev->header.object_prefix == NULL;
@@ -4670,27 +4590,39 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
if (!first_time)
{
- ret = rbd_dev_v2_image_size(rbd_dev);
+ ret = rbd_dev_v2_mutable_metadata(rbd_dev);
if (ret)
- return ret;
-
- ret = rbd_dev_v2_snap_context(rbd_dev);
- dout("rbd_dev_v2_snap_context returned %d\n", ret);
- return ret;
+ goto out_err;
}
else
{
- ret = rbd_dev_v2_header_onetime(rbd_dev);
+ ret = rbd_dev_v2_immutable_metadata(rbd_dev);
if (ret)
- return ret;
+ goto out_err;
}
- return ret; /* XXX change logic? */
+
+ if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2)
+ {
+ ret = rbd_dev_v2_striping_info(rbd_dev);
+ if (ret)
+ goto out_err;
+ }
+
+ ret = 0;
+out_err:
+ rbd_dev->header.features = 0;
+ kfree(rbd_dev->header.object_prefix);
+ rbd_dev->header.object_prefix = NULL;
+
+ return ret;
}
static int rbd_dev_header_info(struct rbd_device *rbd_dev)
{
rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+ /* XXX need to fix 11418 here too? */
+
if (rbd_dev->image_format == 1)
return rbd_dev_v1_header_info(rbd_dev);
@@ -5142,7 +5074,6 @@ static int rbd_obj_header_method_add(struct ceph_osd_request *osd_req,
{
struct ceph_pagelist *pagelist;
pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
- /* XXX is this ever freed? */
if (!pagelist)
return -ENOMEM;
@@ -5288,6 +5219,12 @@ static int __extract_snapcontext(struct rbd_device *rbd_dev,
int i;
int ret;
+ /*
+ * We'll need room for the seq value (maximum snapshot id),
+ * snapshot count, and array of that many snapshot ids.
+ * For now we have a fixed upper limit on the number we're
+ * prepared to receive.
+ */
snapc_max = sizeof(__le64) + sizeof(__le32) +
RBD_MAX_SNAP_COUNT * sizeof(__le64);
@@ -5303,6 +5240,12 @@ static int __extract_snapcontext(struct rbd_device *rbd_dev,
ceph_decode_64_safe(&p, q, seq, out_err);
ceph_decode_32_safe(&p, q, snap_count, out_err);
+ /*
+ * Make sure the reported number of snapshot ids wouldn't go
+ * beyond the end of our buffer. But before checking that,
+ * make sure the computed size of the snapshot context we
+ * allocate is representable in a size_t.
+ */
if (snap_count > (SIZE_MAX - sizeof(struct ceph_snap_context)) /
sizeof(u64))
{
@@ -5344,7 +5287,7 @@ static int __extract_size(struct rbd_device *rbd_dev,
return 0;
}
-static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_header_data(struct rbd_device *rbd_dev)
{
int ret;
@@ -5718,6 +5661,8 @@ static ssize_t do_rbd_add(struct bus_type *bus,
read_only = true;
rbd_dev->mapping.read_only = read_only;
+ rbd_dev->mapping.state = MAP_STATE_MAPPED;
+
rc = rbd_dev_device_setup(rbd_dev);
if (rc) {
/*
--
1.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 0/3] rbd: header read/refresh improvements
2015-04-23 19:06 [PATCH 0/3] rbd: header read/refresh improvements Douglas Fuller
` (2 preceding siblings ...)
2015-04-23 19:06 ` [PATCH 3/3] rbd: re-read features during header refresh and detect changes Douglas Fuller
@ 2015-04-24 13:11 ` Alex Elder
2015-04-24 13:25 ` Douglas Fuller
2015-04-24 14:17 ` Ilya Dryomov
3 siblings, 2 replies; 10+ messages in thread
From: Alex Elder @ 2015-04-24 13:11 UTC (permalink / raw)
To: Douglas Fuller, ceph-devel
On 04/23/2015 02:06 PM, Douglas Fuller wrote:
> Support multiple class op calls in one ceph_msg and consolidate rbd header
> read and refresh processes to use this feature to reduce the number of
> ceph_msgs sent for that process. Refresh features on header refresh and
> begin returning EIO if features have changed since mapping.
>
> Douglas Fuller (3):
> ceph: support multiple class method calls in one ceph_msg
> rbd: combine object method calls in header refresh using fewer
> ceph_msgs
> rbd: re-read features during header refresh and detect changes.
>
> drivers/block/rbd.c | 518 +++++++++++++++++++++++++++++-----------
> include/linux/ceph/osd_client.h | 3 +-
> net/ceph/messenger.c | 4 +
> net/ceph/osd_client.c | 92 ++++++-
> 4 files changed, 470 insertions(+), 147 deletions(-)
>
In case Ilya or others don't get to it soon, I plan to review this
series tomorrow.
-Alex
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/3] rbd: header read/refresh improvements
2015-04-24 13:11 ` [PATCH 0/3] rbd: header read/refresh improvements Alex Elder
@ 2015-04-24 13:25 ` Douglas Fuller
2015-04-24 14:17 ` Ilya Dryomov
1 sibling, 0 replies; 10+ messages in thread
From: Douglas Fuller @ 2015-04-24 13:25 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
> On Apr 24, 2015, at 9:11 AM, Alex Elder <elder@ieee.org> wrote:
>
> On 04/23/2015 02:06 PM, Douglas Fuller wrote:
>> Support multiple class op calls in one ceph_msg and consolidate rbd header
>> read and refresh processes to use this feature to reduce the number of
>> ceph_msgs sent for that process. Refresh features on header refresh and
>> begin returning EIO if features have changed since mapping.
>>
>> Douglas Fuller (3):
>> ceph: support multiple class method calls in one ceph_msg
>> rbd: combine object method calls in header refresh using fewer
>> ceph_msgs
>> rbd: re-read features during header refresh and detect changes.
>>
>> drivers/block/rbd.c | 518 +++++++++++++++++++++++++++++-----------
>> include/linux/ceph/osd_client.h | 3 +-
>> net/ceph/messenger.c | 4 +
>> net/ceph/osd_client.c | 92 ++++++-
>> 4 files changed, 470 insertions(+), 147 deletions(-)
>>
>
> In case Ilya or others don't get to it soon, I plan to review this
> series tomorrow.
>
> -Alex
Much appreciated. I sent an update this morning, as well.
—Doug--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] rbd: header read/refresh improvements
2015-04-24 13:11 ` [PATCH 0/3] rbd: header read/refresh improvements Alex Elder
2015-04-24 13:25 ` Douglas Fuller
@ 2015-04-24 14:17 ` Ilya Dryomov
2015-04-24 14:40 ` Douglas Fuller
1 sibling, 1 reply; 10+ messages in thread
From: Ilya Dryomov @ 2015-04-24 14:17 UTC (permalink / raw)
To: Alex Elder; +Cc: Douglas Fuller, Ceph Development
On Fri, Apr 24, 2015 at 4:11 PM, Alex Elder <elder@ieee.org> wrote:
> On 04/23/2015 02:06 PM, Douglas Fuller wrote:
>>
>> Support multiple class op calls in one ceph_msg and consolidate rbd header
>> read and refresh processes to use this feature to reduce the number of
>> ceph_msgs sent for that process. Refresh features on header refresh and
>> begin returning EIO if features have changed since mapping.
>>
>> Douglas Fuller (3):
>> ceph: support multiple class method calls in one ceph_msg
>> rbd: combine object method calls in header refresh using fewer
>> ceph_msgs
>> rbd: re-read features during header refresh and detect changes.
>>
>> drivers/block/rbd.c | 518
>> +++++++++++++++++++++++++++++-----------
>> include/linux/ceph/osd_client.h | 3 +-
>> net/ceph/messenger.c | 4 +
>> net/ceph/osd_client.c | 92 ++++++-
>> 4 files changed, 470 insertions(+), 147 deletions(-)
>>
>
> In case Ilya or others don't get to it soon, I plan to review this
> series tomorrow.
I was planning take a look while I'm the road during the weekend.
Doug, from a quick look this revision still has a bunch of style
issues, most notably the alignment of function parameters and braces
around if / else. See Documentation/CodingStyle in the kernel tree for
examples.
You might also want to run your patches through scripts/checkpatch.pl,
but take it with a grain of salt - it can be a bit too extreme at
times. No need to post v3 with just style fixes, wait for more feedback.
Thanks,
Ilya
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/3] rbd: header read/refresh improvements
2015-04-24 14:17 ` Ilya Dryomov
@ 2015-04-24 14:40 ` Douglas Fuller
2015-04-24 15:03 ` Alex Elder
0 siblings, 1 reply; 10+ messages in thread
From: Douglas Fuller @ 2015-04-24 14:40 UTC (permalink / raw)
To: Ilya Dryomov; +Cc: Alex Elder, Ceph Development
> On Apr 24, 2015, at 10:17 AM, Ilya Dryomov <idryomov@gmail.com> wrote:
>
> On Fri, Apr 24, 2015 at 4:11 PM, Alex Elder <elder@ieee.org> wrote:
>> On 04/23/2015 02:06 PM, Douglas Fuller wrote:
>>>
>>> Support multiple class op calls in one ceph_msg and consolidate rbd header
>>> read and refresh processes to use this feature to reduce the number of
>>> ceph_msgs sent for that process. Refresh features on header refresh and
>>> begin returning EIO if features have changed since mapping.
>>>
>>> Douglas Fuller (3):
>>> ceph: support multiple class method calls in one ceph_msg
>>> rbd: combine object method calls in header refresh using fewer
>>> ceph_msgs
>>> rbd: re-read features during header refresh and detect changes.
>>>
>>> drivers/block/rbd.c | 518
>>> +++++++++++++++++++++++++++++-----------
>>> include/linux/ceph/osd_client.h | 3 +-
>>> net/ceph/messenger.c | 4 +
>>> net/ceph/osd_client.c | 92 ++++++-
>>> 4 files changed, 470 insertions(+), 147 deletions(-)
>>>
>>
>> In case Ilya or others don't get to it soon, I plan to review this
>> series tomorrow.
>
> I was planning take a look while I'm the road during the weekend.
>
> Doug, from a quick look this revision still has a bunch of style
> issues, most notably the alignment of function parameters and braces
> around if / else. See Documentation/CodingStyle in the kernel tree for
> examples.
I needed to put out v2 in part because I squashed a couple fixup commits in the wrong place, leaving some things behind in #2 that were corrected in #3.
I changed the braces in that version, but the function parameter indents are inconsistent throughout the code. I’ll try to come up with a compromise.
>
> You might also want to run your patches through scripts/checkpatch.pl,
> but take it with a grain of salt - it can be a bit too extreme at
> times. No need to post v3 with just style fixes, wait for more feedback.
Thanks again for all feedback.
>
> Thanks,
>
> Ilya
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] rbd: header read/refresh improvements
2015-04-24 14:40 ` Douglas Fuller
@ 2015-04-24 15:03 ` Alex Elder
0 siblings, 0 replies; 10+ messages in thread
From: Alex Elder @ 2015-04-24 15:03 UTC (permalink / raw)
To: Douglas Fuller, Ilya Dryomov; +Cc: Ceph Development
On 04/24/2015 09:40 AM, Douglas Fuller wrote:
>
>> On Apr 24, 2015, at 10:17 AM, Ilya Dryomov <idryomov@gmail.com>
>> wrote:
>>
>> On Fri, Apr 24, 2015 at 4:11 PM, Alex Elder <elder@ieee.org>
>> wrote:
>>> On 04/23/2015 02:06 PM, Douglas Fuller wrote:
>>>>
>>>> Support multiple class op calls in one ceph_msg and consolidate
>>>> rbd header read and refresh processes to use this feature to
>>>> reduce the number of ceph_msgs sent for that process. Refresh
>>>> features on header refresh and begin returning EIO if features
>>>> have changed since mapping.
>>>>
>>>> Douglas Fuller (3): ceph: support multiple class method calls
>>>> in one ceph_msg rbd: combine object method calls in header
>>>> refresh using fewer ceph_msgs rbd: re-read features during
>>>> header refresh and detect changes.
>>>>
>>>> drivers/block/rbd.c | 518
>>>> +++++++++++++++++++++++++++++-----------
>>>> include/linux/ceph/osd_client.h | 3 +- net/ceph/messenger.c
>>>> | 4 + net/ceph/osd_client.c | 92 ++++++- 4 files
>>>> changed, 470 insertions(+), 147 deletions(-)
>>>>
>>>
>>> In case Ilya or others don't get to it soon, I plan to review
>>> this series tomorrow.
>>
>> I was planning take a look while I'm the road during the weekend.
>>
>> Doug, from a quick look this revision still has a bunch of style
>> issues, most notably the alignment of function parameters and
>> braces around if / else. See Documentation/CodingStyle in the
>> kernel tree for examples.
>
> I needed to put out v2 in part because I squashed a couple fixup
> commits in the wrong place, leaving some things behind in #2 that
> were corrected in #3.
>
> I changed the braces in that version, but the function parameter
> indents are inconsistent throughout the code. I’ll try to come up
> with a compromise.
When in doubt, lean toward the style used in the rest of
the kernel. I used a few conventions that are not consistent
with that in a lot of places, and those can be gradually
phased toward what's recommended for the kernel. Some
examples are:
sizeof x or sizeof (x) --> sizeof(x)
(cast) foo --> (cast)foo
White space under comment blocks
static int\nfunction(...) -> static int function(...)
-Alex
>>
>> You might also want to run your patches through
>> scripts/checkpatch.pl, but take it with a grain of salt - it can be
>> a bit too extreme at times. No need to post v3 with just style
>> fixes, wait for more feedback.
>
> Thanks again for all feedback.
>
>>
>> Thanks,
>>
>> Ilya
>
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread