Commit 0ad5d953 authored by Ilya Dryomov's avatar Ilya Dryomov

rbd: get rid of RBD_OBJ_WRITE_{FLAT,GUARD}

In preparation for moving OSD request allocation and submission into
object request state machines, get rid of RBD_OBJ_WRITE_{FLAT,GUARD}.
We would need to start in a new state, whether the request is guarded
or not.  Unify them into RBD_OBJ_WRITE_OBJECT and pass guard info
through obj_req->flags.

While at it, make our ENOENT handling a little more precise: only hide
ENOENT when it is actually expected, that is on delete.
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
Reviewed-by: default avatarDongsheng Yang <dongsheng.yang@easystack.cn>
parent a9b67e69
...@@ -219,6 +219,9 @@ enum obj_operation_type { ...@@ -219,6 +219,9 @@ enum obj_operation_type {
OBJ_OP_ZEROOUT, OBJ_OP_ZEROOUT,
}; };
#define RBD_OBJ_FLAG_DELETION (1U << 0)
#define RBD_OBJ_FLAG_COPYUP_ENABLED (1U << 1)
enum rbd_obj_read_state { enum rbd_obj_read_state {
RBD_OBJ_READ_OBJECT = 1, RBD_OBJ_READ_OBJECT = 1,
RBD_OBJ_READ_PARENT, RBD_OBJ_READ_PARENT,
...@@ -250,8 +253,7 @@ enum rbd_obj_read_state { ...@@ -250,8 +253,7 @@ enum rbd_obj_read_state {
* even if there is a parent). * even if there is a parent).
*/ */
enum rbd_obj_write_state { enum rbd_obj_write_state {
RBD_OBJ_WRITE_FLAT = 1, RBD_OBJ_WRITE_OBJECT = 1,
RBD_OBJ_WRITE_GUARD,
RBD_OBJ_WRITE_READ_FROM_PARENT, RBD_OBJ_WRITE_READ_FROM_PARENT,
RBD_OBJ_WRITE_COPYUP_EMPTY_SNAPC, RBD_OBJ_WRITE_COPYUP_EMPTY_SNAPC,
RBD_OBJ_WRITE_COPYUP_OPS, RBD_OBJ_WRITE_COPYUP_OPS,
...@@ -259,6 +261,7 @@ enum rbd_obj_write_state { ...@@ -259,6 +261,7 @@ enum rbd_obj_write_state {
struct rbd_obj_request { struct rbd_obj_request {
struct ceph_object_extent ex; struct ceph_object_extent ex;
unsigned int flags; /* RBD_OBJ_FLAG_* */
union { union {
enum rbd_obj_read_state read_state; /* for reads */ enum rbd_obj_read_state read_state; /* for reads */
enum rbd_obj_write_state write_state; /* for writes */ enum rbd_obj_write_state write_state; /* for writes */
...@@ -1858,7 +1861,6 @@ static void __rbd_obj_setup_write(struct rbd_obj_request *obj_req, ...@@ -1858,7 +1861,6 @@ static void __rbd_obj_setup_write(struct rbd_obj_request *obj_req,
static int rbd_obj_setup_write(struct rbd_obj_request *obj_req) static int rbd_obj_setup_write(struct rbd_obj_request *obj_req)
{ {
unsigned int num_osd_ops, which = 0; unsigned int num_osd_ops, which = 0;
bool need_guard;
int ret; int ret;
/* reverse map the entire object onto the parent */ /* reverse map the entire object onto the parent */
...@@ -1866,23 +1868,24 @@ static int rbd_obj_setup_write(struct rbd_obj_request *obj_req) ...@@ -1866,23 +1868,24 @@ static int rbd_obj_setup_write(struct rbd_obj_request *obj_req)
if (ret) if (ret)
return ret; return ret;
need_guard = rbd_obj_copyup_enabled(obj_req); if (rbd_obj_copyup_enabled(obj_req))
num_osd_ops = need_guard + count_write_ops(obj_req); obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
num_osd_ops = count_write_ops(obj_req);
if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED)
num_osd_ops++; /* stat */
obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops);
if (!obj_req->osd_req) if (!obj_req->osd_req)
return -ENOMEM; return -ENOMEM;
if (need_guard) { if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED) {
ret = __rbd_obj_setup_stat(obj_req, which++); ret = __rbd_obj_setup_stat(obj_req, which++);
if (ret) if (ret)
return ret; return ret;
obj_req->write_state = RBD_OBJ_WRITE_GUARD;
} else {
obj_req->write_state = RBD_OBJ_WRITE_FLAT;
} }
obj_req->write_state = RBD_OBJ_WRITE_OBJECT;
__rbd_obj_setup_write(obj_req, which); __rbd_obj_setup_write(obj_req, which);
return 0; return 0;
} }
...@@ -1921,11 +1924,15 @@ static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req) ...@@ -1921,11 +1924,15 @@ static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req)
if (ret) if (ret)
return ret; return ret;
if (rbd_obj_is_entire(obj_req) && !obj_req->num_img_extents)
obj_req->flags |= RBD_OBJ_FLAG_DELETION;
obj_req->osd_req = rbd_osd_req_create(obj_req, 1); obj_req->osd_req = rbd_osd_req_create(obj_req, 1);
if (!obj_req->osd_req) if (!obj_req->osd_req)
return -ENOMEM; return -ENOMEM;
if (rbd_obj_is_entire(obj_req) && !obj_req->num_img_extents) { if (rbd_obj_is_entire(obj_req) && !obj_req->num_img_extents) {
rbd_assert(obj_req->flags & RBD_OBJ_FLAG_DELETION);
osd_req_op_init(obj_req->osd_req, 0, CEPH_OSD_OP_DELETE, 0); osd_req_op_init(obj_req->osd_req, 0, CEPH_OSD_OP_DELETE, 0);
} else { } else {
dout("%s %p %llu~%llu -> %llu~%llu\n", __func__, dout("%s %p %llu~%llu -> %llu~%llu\n", __func__,
...@@ -1936,7 +1943,7 @@ static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req) ...@@ -1936,7 +1943,7 @@ static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req)
off, next_off - off, 0, 0); off, next_off - off, 0, 0);
} }
obj_req->write_state = RBD_OBJ_WRITE_FLAT; obj_req->write_state = RBD_OBJ_WRITE_OBJECT;
rbd_osd_req_format_write(obj_req); rbd_osd_req_format_write(obj_req);
return 0; return 0;
} }
...@@ -1961,11 +1968,12 @@ static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req, ...@@ -1961,11 +1968,12 @@ static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req,
if (rbd_obj_is_entire(obj_req)) { if (rbd_obj_is_entire(obj_req)) {
if (obj_req->num_img_extents) { if (obj_req->num_img_extents) {
if (!rbd_obj_copyup_enabled(obj_req)) if (!(obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED))
osd_req_op_init(obj_req->osd_req, which++, osd_req_op_init(obj_req->osd_req, which++,
CEPH_OSD_OP_CREATE, 0); CEPH_OSD_OP_CREATE, 0);
opcode = CEPH_OSD_OP_TRUNCATE; opcode = CEPH_OSD_OP_TRUNCATE;
} else { } else {
rbd_assert(obj_req->flags & RBD_OBJ_FLAG_DELETION);
osd_req_op_init(obj_req->osd_req, which++, osd_req_op_init(obj_req->osd_req, which++,
CEPH_OSD_OP_DELETE, 0); CEPH_OSD_OP_DELETE, 0);
opcode = 0; opcode = 0;
...@@ -1986,7 +1994,6 @@ static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req, ...@@ -1986,7 +1994,6 @@ static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req,
static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req) static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req)
{ {
unsigned int num_osd_ops, which = 0; unsigned int num_osd_ops, which = 0;
bool need_guard;
int ret; int ret;
/* reverse map the entire object onto the parent */ /* reverse map the entire object onto the parent */
...@@ -1994,23 +2001,28 @@ static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req) ...@@ -1994,23 +2001,28 @@ static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req)
if (ret) if (ret)
return ret; return ret;
need_guard = rbd_obj_copyup_enabled(obj_req); if (rbd_obj_copyup_enabled(obj_req))
num_osd_ops = need_guard + count_zeroout_ops(obj_req); obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
if (!obj_req->num_img_extents) {
if (rbd_obj_is_entire(obj_req))
obj_req->flags |= RBD_OBJ_FLAG_DELETION;
}
num_osd_ops = count_zeroout_ops(obj_req);
if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED)
num_osd_ops++; /* stat */
obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops);
if (!obj_req->osd_req) if (!obj_req->osd_req)
return -ENOMEM; return -ENOMEM;
if (need_guard) { if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED) {
ret = __rbd_obj_setup_stat(obj_req, which++); ret = __rbd_obj_setup_stat(obj_req, which++);
if (ret) if (ret)
return ret; return ret;
obj_req->write_state = RBD_OBJ_WRITE_GUARD;
} else {
obj_req->write_state = RBD_OBJ_WRITE_FLAT;
} }
obj_req->write_state = RBD_OBJ_WRITE_OBJECT;
__rbd_obj_setup_zeroout(obj_req, which); __rbd_obj_setup_zeroout(obj_req, which);
return 0; return 0;
} }
...@@ -2617,6 +2629,11 @@ static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap) ...@@ -2617,6 +2629,11 @@ static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap)
return 0; return 0;
} }
/*
* The target object doesn't exist. Read the data for the entire
* target object up to the overlap point (if any) from the parent,
* so we can use it for a copyup.
*/
static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req) static int rbd_obj_handle_write_guard(struct rbd_obj_request *obj_req)
{ {
struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev;
...@@ -2649,22 +2666,24 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req, int *result) ...@@ -2649,22 +2666,24 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req, int *result)
int ret; int ret;
switch (obj_req->write_state) { switch (obj_req->write_state) {
case RBD_OBJ_WRITE_GUARD: case RBD_OBJ_WRITE_OBJECT:
if (*result == -ENOENT) { if (*result == -ENOENT) {
if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED) {
ret = rbd_obj_handle_write_guard(obj_req);
if (ret) {
*result = ret;
return true;
}
return false;
}
/* /*
* The target object doesn't exist. Read the data for * On a non-existent object:
* the entire target object up to the overlap point (if * delete - -ENOENT, truncate/zero - 0
* any) from the parent, so we can use it for a copyup.
*/ */
ret = rbd_obj_handle_write_guard(obj_req); if (obj_req->flags & RBD_OBJ_FLAG_DELETION)
if (ret) { *result = 0;
*result = ret;
return true;
}
return false;
} }
/* fall through */ /* fall through */
case RBD_OBJ_WRITE_FLAT:
case RBD_OBJ_WRITE_COPYUP_OPS: case RBD_OBJ_WRITE_COPYUP_OPS:
return true; return true;
case RBD_OBJ_WRITE_READ_FROM_PARENT: case RBD_OBJ_WRITE_READ_FROM_PARENT:
...@@ -2695,31 +2714,20 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req, int *result) ...@@ -2695,31 +2714,20 @@ static bool rbd_obj_handle_write(struct rbd_obj_request *obj_req, int *result)
} }
/* /*
* Returns true if @obj_req is completed, or false otherwise. * Return true if @obj_req is completed.
*/ */
static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req, static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req,
int *result) int *result)
{ {
switch (obj_req->img_request->op_type) { struct rbd_img_request *img_req = obj_req->img_request;
case OBJ_OP_READ: bool done;
return rbd_obj_handle_read(obj_req, result);
case OBJ_OP_WRITE: if (!rbd_img_is_write(img_req))
return rbd_obj_handle_write(obj_req, result); done = rbd_obj_handle_read(obj_req, result);
case OBJ_OP_DISCARD: else
case OBJ_OP_ZEROOUT: done = rbd_obj_handle_write(obj_req, result);
if (rbd_obj_handle_write(obj_req, result)) {
/* return done;
* Hide -ENOENT from delete/truncate/zero -- discarding
* a non-existent object is not a problem.
*/
if (*result == -ENOENT)
*result = 0;
return true;
}
return false;
default:
BUG();
}
} }
static void rbd_obj_end_request(struct rbd_obj_request *obj_req, int result) static void rbd_obj_end_request(struct rbd_obj_request *obj_req, int result)
......
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