Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6484cbe9 authored by Ilya Dryomov's avatar Ilya Dryomov
Browse files

rbd: handle DISCARD and WRITE_ZEROES separately



With discard_zeroes_data gone in commit 48920ff2 ("block: remove
the discard_zeroes_data flag"), continuing to provide this guarantee is
pointless: applications can't query it and discards can only be used
for deallocating.

Add OBJ_OP_ZEROOUT and move the existing logic under it.  As the first
step to divorcing OBJ_OP_DISCARD, stop worrying about copyups but keep
special casing whole-object layered discards.

Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
Reviewed-by: default avatarJason Dillaman <dillaman@redhat.com>
parent fd7e3f0d
Loading
Loading
Loading
Loading
+51 −10
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ enum obj_operation_type {
	OBJ_OP_READ = 1,
	OBJ_OP_WRITE,
	OBJ_OP_DISCARD,
	OBJ_OP_ZEROOUT,
};

/*
@@ -857,6 +858,8 @@ static char* obj_op_name(enum obj_operation_type op_type)
		return "write";
	case OBJ_OP_DISCARD:
		return "discard";
	case OBJ_OP_ZEROOUT:
		return "zeroout";
	default:
		return "???";
	}
@@ -1419,6 +1422,7 @@ static bool rbd_img_is_write(struct rbd_img_request *img_req)
		return false;
	case OBJ_OP_WRITE:
	case OBJ_OP_DISCARD:
	case OBJ_OP_ZEROOUT:
		return true;
	default:
		BUG();
@@ -1841,7 +1845,40 @@ static int rbd_obj_setup_write(struct rbd_obj_request *obj_req)
	return 0;
}

static void __rbd_obj_setup_discard(struct rbd_obj_request *obj_req,
static u16 truncate_or_zero_opcode(struct rbd_obj_request *obj_req)
{
	return rbd_obj_is_tail(obj_req) ? CEPH_OSD_OP_TRUNCATE :
					  CEPH_OSD_OP_ZERO;
}

static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req)
{
	int ret;

	/* reverse map the entire object onto the parent */
	ret = rbd_obj_calc_img_extents(obj_req, true);
	if (ret)
		return ret;

	obj_req->osd_req = rbd_osd_req_create(obj_req, 1);
	if (!obj_req->osd_req)
		return -ENOMEM;

	if (rbd_obj_is_entire(obj_req) && !obj_req->num_img_extents) {
		osd_req_op_init(obj_req->osd_req, 0, CEPH_OSD_OP_DELETE, 0);
	} else {
		osd_req_op_extent_init(obj_req->osd_req, 0,
				       truncate_or_zero_opcode(obj_req),
				       obj_req->ex.oe_off, obj_req->ex.oe_len,
				       0, 0);
	}

	obj_req->write_state = RBD_OBJ_WRITE_FLAT;
	rbd_osd_req_format_write(obj_req);
	return 0;
}

static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req,
				    unsigned int which)
{
	u16 opcode;
@@ -1856,10 +1893,8 @@ static void __rbd_obj_setup_discard(struct rbd_obj_request *obj_req,
					CEPH_OSD_OP_DELETE, 0);
			opcode = 0;
		}
	} else if (rbd_obj_is_tail(obj_req)) {
		opcode = CEPH_OSD_OP_TRUNCATE;
	} else {
		opcode = CEPH_OSD_OP_ZERO;
		opcode = truncate_or_zero_opcode(obj_req);
	}

	if (opcode)
@@ -1871,7 +1906,7 @@ static void __rbd_obj_setup_discard(struct rbd_obj_request *obj_req,
	rbd_osd_req_format_write(obj_req);
}

static int rbd_obj_setup_discard(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;
	int ret;
@@ -1907,7 +1942,7 @@ static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req)
			return ret;
	}

	__rbd_obj_setup_discard(obj_req, which);
	__rbd_obj_setup_zeroout(obj_req, which);
	return 0;
}

@@ -1932,6 +1967,9 @@ static int __rbd_img_fill_request(struct rbd_img_request *img_req)
		case OBJ_OP_DISCARD:
			ret = rbd_obj_setup_discard(obj_req);
			break;
		case OBJ_OP_ZEROOUT:
			ret = rbd_obj_setup_zeroout(obj_req);
			break;
		default:
			rbd_assert(0);
		}
@@ -2392,9 +2430,9 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
	case OBJ_OP_WRITE:
		__rbd_obj_setup_write(obj_req, 1);
		break;
	case OBJ_OP_DISCARD:
	case OBJ_OP_ZEROOUT:
		rbd_assert(!rbd_obj_is_entire(obj_req));
		__rbd_obj_setup_discard(obj_req, 1);
		__rbd_obj_setup_zeroout(obj_req, 1);
		break;
	default:
		rbd_assert(0);
@@ -2524,6 +2562,7 @@ static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req)
	case OBJ_OP_WRITE:
		return rbd_obj_handle_write(obj_req);
	case OBJ_OP_DISCARD:
	case OBJ_OP_ZEROOUT:
		if (rbd_obj_handle_write(obj_req)) {
			/*
			 * Hide -ENOENT from delete/truncate/zero -- discarding
@@ -3636,9 +3675,11 @@ static void rbd_queue_workfn(struct work_struct *work)

	switch (req_op(rq)) {
	case REQ_OP_DISCARD:
	case REQ_OP_WRITE_ZEROES:
		op_type = OBJ_OP_DISCARD;
		break;
	case REQ_OP_WRITE_ZEROES:
		op_type = OBJ_OP_ZEROOUT;
		break;
	case REQ_OP_WRITE:
		op_type = OBJ_OP_WRITE;
		break;
@@ -3718,7 +3759,7 @@ static void rbd_queue_workfn(struct work_struct *work)
	img_request->rq = rq;
	snapc = NULL; /* img_request consumes a ref */

	if (op_type == OBJ_OP_DISCARD)
	if (op_type == OBJ_OP_DISCARD || op_type == OBJ_OP_ZEROOUT)
		result = rbd_img_fill_nodata(img_request, offset, length);
	else
		result = rbd_img_fill_from_bio(img_request, offset, length,