Commit 3a482501 authored by Ilya Dryomov's avatar Ilya Dryomov

rbd: introduce rbd_obj_issue_copyup_ops()

In preparation for deep-flatten feature, split rbd_obj_issue_copyup()
into two functions and add a new write state to make the state machine
slightly more clear.  Make the copyup op optional and start using that
for when the overlap goes to 0.
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 13488d53
...@@ -236,7 +236,8 @@ enum obj_operation_type { ...@@ -236,7 +236,8 @@ enum obj_operation_type {
enum rbd_obj_write_state { enum rbd_obj_write_state {
RBD_OBJ_WRITE_FLAT = 1, RBD_OBJ_WRITE_FLAT = 1,
RBD_OBJ_WRITE_GUARD, RBD_OBJ_WRITE_GUARD,
RBD_OBJ_WRITE_COPYUP, RBD_OBJ_WRITE_READ_FROM_PARENT,
RBD_OBJ_WRITE_COPYUP_OPS,
}; };
struct rbd_obj_request { struct rbd_obj_request {
...@@ -2458,10 +2459,13 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes) ...@@ -2458,10 +2459,13 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes)
return true; return true;
} }
static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) #define MODS_ONLY U32_MAX
static int rbd_obj_issue_copyup_ops(struct rbd_obj_request *obj_req, u32 bytes)
{ {
struct rbd_img_request *img_req = obj_req->img_request; struct rbd_img_request *img_req = obj_req->img_request;
unsigned int num_osd_ops = 1; unsigned int num_osd_ops = (bytes != MODS_ONLY);
unsigned int which = 0;
int ret; int ret;
dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes);
...@@ -2483,31 +2487,25 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) ...@@ -2483,31 +2487,25 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
if (!obj_req->osd_req) if (!obj_req->osd_req)
return -ENOMEM; return -ENOMEM;
ret = osd_req_op_cls_init(obj_req->osd_req, 0, "rbd", "copyup"); if (bytes != MODS_ONLY) {
if (ret) ret = osd_req_op_cls_init(obj_req->osd_req, which, "rbd",
return ret; "copyup");
if (ret)
return ret;
/* osd_req_op_cls_request_data_bvecs(obj_req->osd_req, which++,
* Only send non-zero copyup data to save some I/O and network obj_req->copyup_bvecs,
* bandwidth -- zero copyup data is equivalent to the object not obj_req->copyup_bvec_count,
* existing. bytes);
*/
if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
bytes = 0;
} }
osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0,
obj_req->copyup_bvecs,
obj_req->copyup_bvec_count,
bytes);
switch (img_req->op_type) { switch (img_req->op_type) {
case OBJ_OP_WRITE: case OBJ_OP_WRITE:
__rbd_obj_setup_write(obj_req, 1); __rbd_obj_setup_write(obj_req, which);
break; break;
case OBJ_OP_ZEROOUT: case OBJ_OP_ZEROOUT:
rbd_assert(!rbd_obj_is_entire(obj_req)); rbd_assert(!rbd_obj_is_entire(obj_req));
__rbd_obj_setup_zeroout(obj_req, 1); __rbd_obj_setup_zeroout(obj_req, which);
break; break;
default: default:
rbd_assert(0); rbd_assert(0);
...@@ -2521,6 +2519,22 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) ...@@ -2521,6 +2519,22 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
return 0; return 0;
} }
static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
{
/*
* Only send non-zero copyup data to save some I/O and network
* bandwidth -- zero copyup data is equivalent to the object not
* existing.
*/
if (is_zero_bvecs(obj_req->copyup_bvecs, bytes)) {
dout("%s obj_req %p detected zeroes\n", __func__, obj_req);
bytes = 0;
}
obj_req->write_state = RBD_OBJ_WRITE_COPYUP_OPS;
return rbd_obj_issue_copyup_ops(obj_req, bytes);
}
static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap) static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap)
{ {
u32 i; u32 i;
...@@ -2560,22 +2574,19 @@ static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req) ...@@ -2560,22 +2574,19 @@ static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
if (!obj_req->num_img_extents) { if (!obj_req->num_img_extents) {
/* /*
* The overlap has become 0 (most likely because the * The overlap has become 0 (most likely because the
* image has been flattened). Use rbd_obj_issue_copyup() * image has been flattened). Re-submit the original write
* to re-submit the original write request -- the copyup * request -- pass MODS_ONLY since the copyup isn't needed
* operation itself will be a no-op, since someone must * anymore.
* have populated the child object while we weren't
* looking. Move to WRITE_FLAT state as we'll be done
* with the operation once the null copyup completes.
*/ */
obj_req->write_state = RBD_OBJ_WRITE_FLAT; obj_req->write_state = RBD_OBJ_WRITE_COPYUP_OPS;
return rbd_obj_issue_copyup(obj_req, 0); return rbd_obj_issue_copyup_ops(obj_req, MODS_ONLY);
} }
ret = setup_copyup_bvecs(obj_req, rbd_obj_img_extents_bytes(obj_req)); ret = setup_copyup_bvecs(obj_req, rbd_obj_img_extents_bytes(obj_req));
if (ret) if (ret)
return ret; return ret;
obj_req->write_state = RBD_OBJ_WRITE_COPYUP; obj_req->write_state = RBD_OBJ_WRITE_READ_FROM_PARENT;
return rbd_obj_read_from_parent(obj_req); return rbd_obj_read_from_parent(obj_req);
} }
...@@ -2583,7 +2594,6 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req) ...@@ -2583,7 +2594,6 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
{ {
int ret; int ret;
again:
switch (obj_req->write_state) { switch (obj_req->write_state) {
case RBD_OBJ_WRITE_GUARD: case RBD_OBJ_WRITE_GUARD:
rbd_assert(!obj_req->xferred); rbd_assert(!obj_req->xferred);
...@@ -2602,6 +2612,7 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req) ...@@ -2602,6 +2612,7 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
} }
/* fall through */ /* fall through */
case RBD_OBJ_WRITE_FLAT: case RBD_OBJ_WRITE_FLAT:
case RBD_OBJ_WRITE_COPYUP_OPS:
if (!obj_req->result) if (!obj_req->result)
/* /*
* There is no such thing as a successful short * There is no such thing as a successful short
...@@ -2609,10 +2620,9 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req) ...@@ -2609,10 +2620,9 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req)
*/ */
obj_req->xferred = obj_req->ex.oe_len; obj_req->xferred = obj_req->ex.oe_len;
return true; return true;
case RBD_OBJ_WRITE_COPYUP: case RBD_OBJ_WRITE_READ_FROM_PARENT:
obj_req->write_state = RBD_OBJ_WRITE_GUARD;
if (obj_req->result) if (obj_req->result)
goto again; return true;
rbd_assert(obj_req->xferred); rbd_assert(obj_req->xferred);
ret = rbd_obj_issue_copyup(obj_req, obj_req->xferred); ret = rbd_obj_issue_copyup(obj_req, obj_req->xferred);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment