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

Commit 6d2940c8 authored by Guangliang Zhao's avatar Guangliang Zhao Committed by Ilya Dryomov
Browse files

rbd: extend the operation type



It could only handle the read and write operations now,
extend it for the coming discard support.

Signed-off-by: default avatarGuangliang Zhao <lucienchao@gmail.com>
Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
Reviewed-by: default avatarAlex Elder <elder@linaro.org>
parent c622d226
Loading
Loading
Loading
Loading
+63 −34
Original line number Diff line number Diff line
@@ -210,6 +210,11 @@ enum obj_request_type {
	OBJ_REQUEST_NODATA, OBJ_REQUEST_BIO, OBJ_REQUEST_PAGES
};

enum obj_operation_type {
	OBJ_OP_WRITE,
	OBJ_OP_READ,
};

enum obj_req_flags {
	OBJ_REQ_DONE,		/* completion flag: not done = 0, done = 1 */
	OBJ_REQ_IMG_DATA,	/* object usage: standalone = 0, image = 1 */
@@ -785,6 +790,18 @@ static int parse_rbd_opts_token(char *c, void *private)
	return 0;
}

static char* obj_op_name(enum obj_operation_type op_type)
{
	switch (op_type) {
	case OBJ_OP_READ:
		return "read";
	case OBJ_OP_WRITE:
		return "write";
	default:
		return "???";
	}
}

/*
 * Get a ceph client with specific addr and configuration, if one does
 * not exist create it.  Either way, ceph_opts is consumed by this
@@ -1823,7 +1840,7 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request)
 */
static struct ceph_osd_request *rbd_osd_req_create(
					struct rbd_device *rbd_dev,
					bool write_request,
					enum obj_operation_type op_type,
					unsigned int num_ops,
					struct rbd_obj_request *obj_request)
{
@@ -1831,16 +1848,14 @@ static struct ceph_osd_request *rbd_osd_req_create(
	struct ceph_osd_client *osdc;
	struct ceph_osd_request *osd_req;

	if (obj_request_img_data_test(obj_request)) {
	if (obj_request_img_data_test(obj_request) && op_type == OBJ_OP_WRITE) {
		struct rbd_img_request *img_request = obj_request->img_request;

		rbd_assert(write_request ==
				img_request_write_test(img_request));
		if (write_request)
		rbd_assert(img_request_write_test(img_request));
		snapc = img_request->snapc;
	}

	rbd_assert(num_ops == 1 || (write_request && num_ops == 2));
	rbd_assert(num_ops == 1 || ((op_type == OBJ_OP_WRITE) && num_ops == 2));

	/* Allocate and initialize the request, for the num_ops ops */

@@ -1850,7 +1865,7 @@ static struct ceph_osd_request *rbd_osd_req_create(
	if (!osd_req)
		return NULL;	/* ENOMEM */

	if (write_request)
	if (op_type == OBJ_OP_WRITE)
		osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK;
	else
		osd_req->r_flags = CEPH_OSD_FLAG_READ;
@@ -2057,7 +2072,7 @@ static bool rbd_dev_parent_get(struct rbd_device *rbd_dev)
static struct rbd_img_request *rbd_img_request_create(
					struct rbd_device *rbd_dev,
					u64 offset, u64 length,
					bool write_request,
					enum obj_operation_type op_type,
					struct ceph_snap_context *snapc)
{
	struct rbd_img_request *img_request;
@@ -2071,7 +2086,7 @@ static struct rbd_img_request *rbd_img_request_create(
	img_request->offset = offset;
	img_request->length = length;
	img_request->flags = 0;
	if (write_request) {
	if (op_type == OBJ_OP_WRITE) {
		img_request_write_set(img_request);
		img_request->snapc = snapc;
	} else {
@@ -2088,8 +2103,7 @@ static struct rbd_img_request *rbd_img_request_create(
	kref_init(&img_request->kref);

	dout("%s: rbd_dev %p %s %llu/%llu -> img %p\n", __func__, rbd_dev,
		write_request ? "write" : "read", offset, length,
		img_request);
		obj_op_name(op_type), offset, length, img_request);

	return img_request;
}
@@ -2130,7 +2144,7 @@ static struct rbd_img_request *rbd_parent_request_create(
	rbd_dev = obj_request->img_request->rbd_dev;

	parent_request = rbd_img_request_create(rbd_dev->parent, img_offset,
						length, false, NULL);
						length, OBJ_OP_READ, NULL);
	if (!parent_request)
		return NULL;

@@ -2171,11 +2185,14 @@ static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
	result = obj_request->result;
	if (result) {
		struct rbd_device *rbd_dev = img_request->rbd_dev;
		enum obj_operation_type op_type;

		op_type = img_request_write_test(img_request) ? OBJ_OP_WRITE :
								OBJ_OP_READ;

		rbd_warn(rbd_dev, "%s %llx at %llx (%llx)",
			img_request_write_test(img_request) ? "write" : "read",
			obj_request->length, obj_request->img_offset,
			obj_request->offset);
			obj_op_name(op_type), obj_request->length,
			obj_request->img_offset, obj_request->offset);
		rbd_warn(rbd_dev, "  result %d xferred %x",
			result, xferred);
		if (!img_request->result)
@@ -2254,10 +2271,10 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
	struct rbd_device *rbd_dev = img_request->rbd_dev;
	struct rbd_obj_request *obj_request = NULL;
	struct rbd_obj_request *next_obj_request;
	bool write_request = img_request_write_test(img_request);
	struct bio *bio_list = NULL;
	unsigned int bio_offset = 0;
	struct page **pages = NULL;
	enum obj_operation_type op_type;
	u64 img_offset;
	u64 resid;
	u16 opcode;
@@ -2265,7 +2282,6 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
	dout("%s: img %p type %d data_desc %p\n", __func__, img_request,
		(int)type, data_desc);

	opcode = write_request ? CEPH_OSD_OP_WRITE : CEPH_OSD_OP_READ;
	img_offset = img_request->offset;
	resid = img_request->length;
	rbd_assert(resid > 0);
@@ -2327,8 +2343,16 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
			pages += page_count;
		}

		osd_req = rbd_osd_req_create(rbd_dev, write_request,
					     (write_request ? 2 : 1),
		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;
@@ -2336,7 +2360,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
		obj_request->callback = rbd_img_obj_callback;
		rbd_img_request_get(img_request);

		if (write_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));
@@ -2353,7 +2377,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
					obj_request->pages, length,
					offset & ~PAGE_MASK, false, false);

		if (write_request)
		if (op_type == OBJ_OP_WRITE)
			rbd_osd_req_format_write(obj_request);
		else
			rbd_osd_req_format_read(obj_request);
@@ -2723,7 +2747,7 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)

	rbd_assert(obj_request->img_request);
	rbd_dev = obj_request->img_request->rbd_dev;
	stat_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
	stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
						   stat_request);
	if (!stat_request->osd_req)
		goto out;
@@ -2947,7 +2971,7 @@ static int rbd_obj_notify_ack_sync(struct rbd_device *rbd_dev, u64 notify_id)
		return -ENOMEM;

	ret = -ENOMEM;
	obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
	obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
						  obj_request);
	if (!obj_request->osd_req)
		goto out;
@@ -3010,7 +3034,7 @@ static struct rbd_obj_request *rbd_obj_watch_request_helper(
	if (!obj_request)
		return ERR_PTR(-ENOMEM);

	obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, 1,
	obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_WRITE, 1,
						  obj_request);
	if (!obj_request->osd_req) {
		ret = -ENOMEM;
@@ -3148,7 +3172,7 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
	obj_request->pages = pages;
	obj_request->page_count = page_count;

	obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
	obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
						  obj_request);
	if (!obj_request->osd_req)
		goto out;
@@ -3201,10 +3225,15 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
	struct ceph_snap_context *snapc = NULL;
	u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT;
	u64 length = blk_rq_bytes(rq);
	bool wr = rq_data_dir(rq) == WRITE;
	enum obj_operation_type op_type;
	u64 mapping_size;
	int result;

	if (rq->cmd_flags & REQ_WRITE)
		op_type = OBJ_OP_WRITE;
	else
		op_type = OBJ_OP_READ;

	/* Ignore/skip any zero-length requests */

	if (!length) {
@@ -3213,9 +3242,9 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
		goto err_rq;
	}

	/* Disallow writes to a read-only device */
	/* Only reads are allowed to a read-only device */

	if (wr) {
	if (op_type != OBJ_OP_READ) {
		if (rbd_dev->mapping.read_only) {
			result = -EROFS;
			goto err_rq;
@@ -3245,7 +3274,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)

	down_read(&rbd_dev->header_rwsem);
	mapping_size = rbd_dev->mapping.size;
	if (wr) {
	if (op_type != OBJ_OP_READ) {
		snapc = rbd_dev->header.snapc;
		ceph_get_snap_context(snapc);
	}
@@ -3258,7 +3287,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
		goto err_rq;
	}

	img_request = rbd_img_request_create(rbd_dev, offset, length, wr,
	img_request = rbd_img_request_create(rbd_dev, offset, length, op_type,
					     snapc);
	if (!img_request) {
		result = -ENOMEM;
@@ -3281,7 +3310,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
err_rq:
	if (result)
		rbd_warn(rbd_dev, "%s %llx at %llx result %d",
			 wr ? "write" : "read", length, offset, result);
			 obj_op_name(op_type), length, offset, result);
	if (snapc)
		ceph_put_snap_context(snapc);
	blk_end_request_all(rq, result);
@@ -3421,7 +3450,7 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
	obj_request->pages = pages;
	obj_request->page_count = page_count;

	obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
	obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1,
						  obj_request);
	if (!obj_request->osd_req)
		goto out;