@@ -267,7 +267,8 @@ enum rbd_obj_read_state {
* even if there is a parent).
*/
enum rbd_obj_write_state {
- RBD_OBJ_WRITE_START = 1,
+ RBD_OBJ_WRITE_DONE,
+ RBD_OBJ_WRITE_START,
RBD_OBJ_WRITE_PRE_OBJECT_MAP,
RBD_OBJ_WRITE_OBJECT,
__RBD_OBJ_WRITE_COPYUP,
@@ -3382,31 +3383,37 @@ static bool rbd_obj_advance_write(struct rbd_obj_request *obj_req, int *result)
int ret;
again:
+ dout("%s: obj %p state %d\n", __func__, obj_req, obj_req->write_state);
switch (obj_req->write_state) {
case RBD_OBJ_WRITE_START:
rbd_assert(!*result);
- if (rbd_obj_write_is_noop(obj_req))
+ if (rbd_obj_write_is_noop(obj_req)) {
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
+ }
ret = rbd_obj_write_pre_object_map(obj_req);
if (ret < 0) {
*result = ret;
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
}
obj_req->write_state = RBD_OBJ_WRITE_PRE_OBJECT_MAP;
- if (ret > 0)
- goto again;
- return false;
+ if (ret == 0)
+ return false;
+ /* fall through */
case RBD_OBJ_WRITE_PRE_OBJECT_MAP:
if (*result) {
rbd_warn(rbd_dev, "pre object map update failed: %d",
*result);
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
}
ret = rbd_obj_write_object(obj_req);
if (ret) {
*result = ret;
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
}
obj_req->write_state = RBD_OBJ_WRITE_OBJECT;
@@ -3426,33 +3433,40 @@ static bool rbd_obj_advance_write(struct rbd_obj_request *obj_req, int *result)
if (obj_req->flags & RBD_OBJ_FLAG_DELETION)
*result = 0;
}
- if (*result)
+ if (*result) {
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
-
+ }
obj_req->write_state = RBD_OBJ_WRITE_COPYUP;
goto again;
case __RBD_OBJ_WRITE_COPYUP:
if (!rbd_obj_advance_copyup(obj_req, result))
return false;
+ obj_req->write_state = RBD_OBJ_WRITE_COPYUP;
/* fall through */
case RBD_OBJ_WRITE_COPYUP:
if (*result) {
rbd_warn(rbd_dev, "copyup failed: %d", *result);
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
}
+ obj_req->write_state = RBD_OBJ_WRITE_POST_OBJECT_MAP;
ret = rbd_obj_write_post_object_map(obj_req);
if (ret < 0) {
*result = ret;
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
return true;
}
- obj_req->write_state = RBD_OBJ_WRITE_POST_OBJECT_MAP;
- if (ret > 0)
- goto again;
- return false;
+ if (ret == 0)
+ return false;
+ /* fall through */
case RBD_OBJ_WRITE_POST_OBJECT_MAP:
if (*result)
rbd_warn(rbd_dev, "post object map update failed: %d",
*result);
+ obj_req->write_state = RBD_OBJ_WRITE_DONE;
+ /* fall through */
+ case RBD_OBJ_WRITE_DONE:
return true;
default:
BUG();
Reorder switch statement to avoid the use of a label/goto statement and add a 'done' state to indicate that the state machine has completed. Signed-off-by: Hannes Reinecke <hare@suse.de> --- drivers/block/rbd.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-)