mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 13:11:40 +00:00
rbd: extract a method for adding object operations
rbd_img_request_fill() creates a ceph_osd_request and has logic for adding the appropriate osd ops to it based on the request type and image properties. For layered images, the original rbd_obj_request is resent with a copyup operation in front, using a new ceph_osd_request. The logic for adding the original operations should be the same as when first sending them, so move it to a helper function. op_type only needs to be checked once, so create a helper for that as well and call it outside the loop in rbd_img_request_fill(). Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
parent
1c220881e3
commit
3b434a2aff
@ -1672,6 +1672,17 @@ static bool img_request_layered_test(struct rbd_img_request *img_request)
|
||||
return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0;
|
||||
}
|
||||
|
||||
static enum obj_operation_type
|
||||
rbd_img_request_op_type(struct rbd_img_request *img_request)
|
||||
{
|
||||
if (img_request_write_test(img_request))
|
||||
return OBJ_OP_WRITE;
|
||||
else if (img_request_discard_test(img_request))
|
||||
return OBJ_OP_DISCARD;
|
||||
else
|
||||
return OBJ_OP_READ;
|
||||
}
|
||||
|
||||
static void
|
||||
rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
|
||||
{
|
||||
@ -2307,6 +2318,68 @@ out:
|
||||
rbd_img_request_complete(img_request);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add individual osd ops to the given ceph_osd_request and prepare
|
||||
* them for submission. num_ops is the current number of
|
||||
* osd operations already to the object request.
|
||||
*/
|
||||
static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
|
||||
struct ceph_osd_request *osd_request,
|
||||
enum obj_operation_type op_type,
|
||||
unsigned int num_ops)
|
||||
{
|
||||
struct rbd_img_request *img_request = obj_request->img_request;
|
||||
struct rbd_device *rbd_dev = img_request->rbd_dev;
|
||||
u64 object_size = rbd_obj_bytes(&rbd_dev->header);
|
||||
u64 offset = obj_request->offset;
|
||||
u64 length = obj_request->length;
|
||||
u64 img_end;
|
||||
u16 opcode;
|
||||
|
||||
if (op_type == OBJ_OP_DISCARD) {
|
||||
if (!offset && (length == object_size)
|
||||
&& (!img_request_layered_test(img_request) ||
|
||||
(rbd_dev->parent_overlap <=
|
||||
obj_request->img_offset))) {
|
||||
opcode = CEPH_OSD_OP_DELETE;
|
||||
} else if ((offset + length == object_size)) {
|
||||
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||
} else {
|
||||
down_read(&rbd_dev->header_rwsem);
|
||||
img_end = rbd_dev->header.image_size;
|
||||
up_read(&rbd_dev->header_rwsem);
|
||||
|
||||
if (obj_request->img_offset + length == img_end)
|
||||
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||
else
|
||||
opcode = CEPH_OSD_OP_ZERO;
|
||||
}
|
||||
} else if (op_type == OBJ_OP_WRITE) {
|
||||
opcode = CEPH_OSD_OP_WRITE;
|
||||
osd_req_op_alloc_hint_init(osd_request, num_ops,
|
||||
object_size, object_size);
|
||||
num_ops++;
|
||||
} else {
|
||||
opcode = CEPH_OSD_OP_READ;
|
||||
}
|
||||
|
||||
osd_req_op_extent_init(osd_request, num_ops, opcode, offset, length,
|
||||
0, 0);
|
||||
if (obj_request->type == OBJ_REQUEST_BIO)
|
||||
osd_req_op_extent_osd_data_bio(osd_request, num_ops,
|
||||
obj_request->bio_list, length);
|
||||
else if (obj_request->type == OBJ_REQUEST_PAGES)
|
||||
osd_req_op_extent_osd_data_pages(osd_request, num_ops,
|
||||
obj_request->pages, length,
|
||||
offset & ~PAGE_MASK, false, false);
|
||||
|
||||
/* Discards are also writes */
|
||||
if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
|
||||
rbd_osd_req_format_write(obj_request);
|
||||
else
|
||||
rbd_osd_req_format_read(obj_request);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split up an image request into one or more object requests, each
|
||||
* to a different object. The "type" parameter indicates whether
|
||||
@ -2326,11 +2399,8 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
|
||||
unsigned int bio_offset = 0;
|
||||
struct page **pages = NULL;
|
||||
enum obj_operation_type op_type;
|
||||
u64 object_size = rbd_obj_bytes(&rbd_dev->header);
|
||||
u64 img_offset;
|
||||
u64 img_end;
|
||||
u64 resid;
|
||||
u16 opcode;
|
||||
|
||||
dout("%s: img %p type %d data_desc %p\n", __func__, img_request,
|
||||
(int)type, data_desc);
|
||||
@ -2338,6 +2408,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
|
||||
img_offset = img_request->offset;
|
||||
resid = img_request->length;
|
||||
rbd_assert(resid > 0);
|
||||
op_type = rbd_img_request_op_type(img_request);
|
||||
|
||||
if (type == OBJ_REQUEST_BIO) {
|
||||
bio_list = data_desc;
|
||||
@ -2352,7 +2423,6 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
|
||||
const char *object_name;
|
||||
u64 offset;
|
||||
u64 length;
|
||||
unsigned int which = 0;
|
||||
|
||||
object_name = rbd_segment_name(rbd_dev, img_offset);
|
||||
if (!object_name)
|
||||
@ -2395,67 +2465,20 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
|
||||
pages += page_count;
|
||||
}
|
||||
|
||||
if (img_request_discard_test(img_request)) {
|
||||
op_type = OBJ_OP_DISCARD;
|
||||
if (!offset && (length == object_size)
|
||||
&& (!img_request_layered_test(img_request) ||
|
||||
(rbd_dev->parent_overlap <=
|
||||
obj_request->img_offset))) {
|
||||
opcode = CEPH_OSD_OP_DELETE;
|
||||
} else if ((offset + length == object_size)) {
|
||||
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||
} else {
|
||||
down_read(&rbd_dev->header_rwsem);
|
||||
img_end = rbd_dev->header.image_size;
|
||||
up_read(&rbd_dev->header_rwsem);
|
||||
|
||||
if (obj_request->img_offset + length == img_end)
|
||||
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||
else
|
||||
opcode = CEPH_OSD_OP_ZERO;
|
||||
}
|
||||
} else if (img_request_write_test(img_request)) {
|
||||
op_type = OBJ_OP_WRITE;
|
||||
opcode = CEPH_OSD_OP_WRITE;
|
||||
} else {
|
||||
op_type = OBJ_OP_READ;
|
||||
opcode = CEPH_OSD_OP_READ;
|
||||
}
|
||||
|
||||
osd_req = rbd_osd_req_create(rbd_dev, op_type,
|
||||
(op_type == OBJ_OP_WRITE) ? 2 : 1,
|
||||
obj_request);
|
||||
if (!osd_req)
|
||||
goto out_unwind;
|
||||
|
||||
obj_request->osd_req = osd_req;
|
||||
obj_request->callback = rbd_img_obj_callback;
|
||||
rbd_img_request_get(img_request);
|
||||
|
||||
if (op_type == OBJ_OP_WRITE) {
|
||||
osd_req_op_alloc_hint_init(osd_req, which,
|
||||
rbd_obj_bytes(&rbd_dev->header),
|
||||
rbd_obj_bytes(&rbd_dev->header));
|
||||
which++;
|
||||
}
|
||||
|
||||
osd_req_op_extent_init(osd_req, which, opcode, offset, length,
|
||||
0, 0);
|
||||
if (type == OBJ_REQUEST_BIO)
|
||||
osd_req_op_extent_osd_data_bio(osd_req, which,
|
||||
obj_request->bio_list, length);
|
||||
else if (type == OBJ_REQUEST_PAGES)
|
||||
osd_req_op_extent_osd_data_pages(osd_req, which,
|
||||
obj_request->pages, length,
|
||||
offset & ~PAGE_MASK, false, false);
|
||||
|
||||
/* Discards are also writes */
|
||||
if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
|
||||
rbd_osd_req_format_write(obj_request);
|
||||
else
|
||||
rbd_osd_req_format_read(obj_request);
|
||||
|
||||
obj_request->img_offset = img_offset;
|
||||
|
||||
rbd_img_obj_request_fill(obj_request, osd_req, op_type, 0);
|
||||
|
||||
rbd_img_request_get(img_request);
|
||||
|
||||
img_offset += length;
|
||||
resid -= length;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user