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

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
...@@ -210,6 +210,11 @@ enum obj_request_type { ...@@ -210,6 +210,11 @@ enum obj_request_type {
OBJ_REQUEST_NODATA, OBJ_REQUEST_BIO, OBJ_REQUEST_PAGES OBJ_REQUEST_NODATA, OBJ_REQUEST_BIO, OBJ_REQUEST_PAGES
}; };
enum obj_operation_type {
OBJ_OP_WRITE,
OBJ_OP_READ,
};
enum obj_req_flags { enum obj_req_flags {
OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */ OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */
OBJ_REQ_IMG_DATA, /* object usage: standalone = 0, image = 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) ...@@ -785,6 +790,18 @@ static int parse_rbd_opts_token(char *c, void *private)
return 0; 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 * Get a ceph client with specific addr and configuration, if one does
* not exist create it. Either way, ceph_opts is consumed by this * 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) ...@@ -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( static struct ceph_osd_request *rbd_osd_req_create(
struct rbd_device *rbd_dev, struct rbd_device *rbd_dev,
bool write_request, enum obj_operation_type op_type,
unsigned int num_ops, unsigned int num_ops,
struct rbd_obj_request *obj_request) struct rbd_obj_request *obj_request)
{ {
...@@ -1831,16 +1848,14 @@ static struct ceph_osd_request *rbd_osd_req_create( ...@@ -1831,16 +1848,14 @@ static struct ceph_osd_request *rbd_osd_req_create(
struct ceph_osd_client *osdc; struct ceph_osd_client *osdc;
struct ceph_osd_request *osd_req; 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; struct rbd_img_request *img_request = obj_request->img_request;
rbd_assert(write_request == rbd_assert(img_request_write_test(img_request));
img_request_write_test(img_request)); snapc = img_request->snapc;
if (write_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 */ /* Allocate and initialize the request, for the num_ops ops */
...@@ -1850,7 +1865,7 @@ static struct ceph_osd_request *rbd_osd_req_create( ...@@ -1850,7 +1865,7 @@ static struct ceph_osd_request *rbd_osd_req_create(
if (!osd_req) if (!osd_req)
return NULL; /* ENOMEM */ return NULL; /* ENOMEM */
if (write_request) if (op_type == OBJ_OP_WRITE)
osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK; osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK;
else else
osd_req->r_flags = CEPH_OSD_FLAG_READ; osd_req->r_flags = CEPH_OSD_FLAG_READ;
...@@ -2057,7 +2072,7 @@ static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) ...@@ -2057,7 +2072,7 @@ static bool rbd_dev_parent_get(struct rbd_device *rbd_dev)
static struct rbd_img_request *rbd_img_request_create( static struct rbd_img_request *rbd_img_request_create(
struct rbd_device *rbd_dev, struct rbd_device *rbd_dev,
u64 offset, u64 length, u64 offset, u64 length,
bool write_request, enum obj_operation_type op_type,
struct ceph_snap_context *snapc) struct ceph_snap_context *snapc)
{ {
struct rbd_img_request *img_request; struct rbd_img_request *img_request;
...@@ -2071,7 +2086,7 @@ static struct rbd_img_request *rbd_img_request_create( ...@@ -2071,7 +2086,7 @@ static struct rbd_img_request *rbd_img_request_create(
img_request->offset = offset; img_request->offset = offset;
img_request->length = length; img_request->length = length;
img_request->flags = 0; img_request->flags = 0;
if (write_request) { if (op_type == OBJ_OP_WRITE) {
img_request_write_set(img_request); img_request_write_set(img_request);
img_request->snapc = snapc; img_request->snapc = snapc;
} else { } else {
...@@ -2088,8 +2103,7 @@ static struct rbd_img_request *rbd_img_request_create( ...@@ -2088,8 +2103,7 @@ static struct rbd_img_request *rbd_img_request_create(
kref_init(&img_request->kref); kref_init(&img_request->kref);
dout("%s: rbd_dev %p %s %llu/%llu -> img %p\n", __func__, rbd_dev, dout("%s: rbd_dev %p %s %llu/%llu -> img %p\n", __func__, rbd_dev,
write_request ? "write" : "read", offset, length, obj_op_name(op_type), offset, length, img_request);
img_request);
return img_request; return img_request;
} }
...@@ -2130,7 +2144,7 @@ static struct rbd_img_request *rbd_parent_request_create( ...@@ -2130,7 +2144,7 @@ static struct rbd_img_request *rbd_parent_request_create(
rbd_dev = obj_request->img_request->rbd_dev; rbd_dev = obj_request->img_request->rbd_dev;
parent_request = rbd_img_request_create(rbd_dev->parent, img_offset, parent_request = rbd_img_request_create(rbd_dev->parent, img_offset,
length, false, NULL); length, OBJ_OP_READ, NULL);
if (!parent_request) if (!parent_request)
return NULL; return NULL;
...@@ -2171,11 +2185,14 @@ static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request) ...@@ -2171,11 +2185,14 @@ static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
result = obj_request->result; result = obj_request->result;
if (result) { if (result) {
struct rbd_device *rbd_dev = img_request->rbd_dev; 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)", rbd_warn(rbd_dev, "%s %llx at %llx (%llx)",
img_request_write_test(img_request) ? "write" : "read", obj_op_name(op_type), obj_request->length,
obj_request->length, obj_request->img_offset, obj_request->img_offset, obj_request->offset);
obj_request->offset);
rbd_warn(rbd_dev, " result %d xferred %x", rbd_warn(rbd_dev, " result %d xferred %x",
result, xferred); result, xferred);
if (!img_request->result) if (!img_request->result)
...@@ -2254,10 +2271,10 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request, ...@@ -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_device *rbd_dev = img_request->rbd_dev;
struct rbd_obj_request *obj_request = NULL; struct rbd_obj_request *obj_request = NULL;
struct rbd_obj_request *next_obj_request; struct rbd_obj_request *next_obj_request;
bool write_request = img_request_write_test(img_request);
struct bio *bio_list = NULL; struct bio *bio_list = NULL;
unsigned int bio_offset = 0; unsigned int bio_offset = 0;
struct page **pages = NULL; struct page **pages = NULL;
enum obj_operation_type op_type;
u64 img_offset; u64 img_offset;
u64 resid; u64 resid;
u16 opcode; u16 opcode;
...@@ -2265,7 +2282,6 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request, ...@@ -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, dout("%s: img %p type %d data_desc %p\n", __func__, img_request,
(int)type, data_desc); (int)type, data_desc);
opcode = write_request ? CEPH_OSD_OP_WRITE : CEPH_OSD_OP_READ;
img_offset = img_request->offset; img_offset = img_request->offset;
resid = img_request->length; resid = img_request->length;
rbd_assert(resid > 0); rbd_assert(resid > 0);
...@@ -2327,16 +2343,24 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request, ...@@ -2327,16 +2343,24 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
pages += page_count; pages += page_count;
} }
osd_req = rbd_osd_req_create(rbd_dev, write_request, if (img_request_write_test(img_request)) {
(write_request ? 2 : 1), op_type = OBJ_OP_WRITE;
obj_request); 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) if (!osd_req)
goto out_unwind; goto out_unwind;
obj_request->osd_req = osd_req; obj_request->osd_req = osd_req;
obj_request->callback = rbd_img_obj_callback; obj_request->callback = rbd_img_obj_callback;
rbd_img_request_get(img_request); rbd_img_request_get(img_request);
if (write_request) { if (op_type == OBJ_OP_WRITE) {
osd_req_op_alloc_hint_init(osd_req, which, osd_req_op_alloc_hint_init(osd_req, which,
rbd_obj_bytes(&rbd_dev->header), rbd_obj_bytes(&rbd_dev->header),
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, ...@@ -2353,7 +2377,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
obj_request->pages, length, obj_request->pages, length,
offset & ~PAGE_MASK, false, false); offset & ~PAGE_MASK, false, false);
if (write_request) if (op_type == OBJ_OP_WRITE)
rbd_osd_req_format_write(obj_request); rbd_osd_req_format_write(obj_request);
else else
rbd_osd_req_format_read(obj_request); rbd_osd_req_format_read(obj_request);
...@@ -2723,7 +2747,7 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *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_assert(obj_request->img_request);
rbd_dev = obj_request->img_request->rbd_dev; 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); stat_request);
if (!stat_request->osd_req) if (!stat_request->osd_req)
goto out; goto out;
...@@ -2947,7 +2971,7 @@ static int rbd_obj_notify_ack_sync(struct rbd_device *rbd_dev, u64 notify_id) ...@@ -2947,7 +2971,7 @@ static int rbd_obj_notify_ack_sync(struct rbd_device *rbd_dev, u64 notify_id)
return -ENOMEM; return -ENOMEM;
ret = -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); obj_request);
if (!obj_request->osd_req) if (!obj_request->osd_req)
goto out; goto out;
...@@ -3010,7 +3034,7 @@ static struct rbd_obj_request *rbd_obj_watch_request_helper( ...@@ -3010,7 +3034,7 @@ static struct rbd_obj_request *rbd_obj_watch_request_helper(
if (!obj_request) if (!obj_request)
return ERR_PTR(-ENOMEM); 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); obj_request);
if (!obj_request->osd_req) { if (!obj_request->osd_req) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -3148,7 +3172,7 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, ...@@ -3148,7 +3172,7 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
obj_request->pages = pages; obj_request->pages = pages;
obj_request->page_count = page_count; 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); obj_request);
if (!obj_request->osd_req) if (!obj_request->osd_req)
goto out; goto out;
...@@ -3201,10 +3225,15 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq) ...@@ -3201,10 +3225,15 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
struct ceph_snap_context *snapc = NULL; struct ceph_snap_context *snapc = NULL;
u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT; u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT;
u64 length = blk_rq_bytes(rq); u64 length = blk_rq_bytes(rq);
bool wr = rq_data_dir(rq) == WRITE; enum obj_operation_type op_type;
u64 mapping_size; u64 mapping_size;
int result; 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 */ /* Ignore/skip any zero-length requests */
if (!length) { if (!length) {
...@@ -3213,9 +3242,9 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq) ...@@ -3213,9 +3242,9 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
goto err_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) { if (rbd_dev->mapping.read_only) {
result = -EROFS; result = -EROFS;
goto err_rq; goto err_rq;
...@@ -3245,7 +3274,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq) ...@@ -3245,7 +3274,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
down_read(&rbd_dev->header_rwsem); down_read(&rbd_dev->header_rwsem);
mapping_size = rbd_dev->mapping.size; mapping_size = rbd_dev->mapping.size;
if (wr) { if (op_type != OBJ_OP_READ) {
snapc = rbd_dev->header.snapc; snapc = rbd_dev->header.snapc;
ceph_get_snap_context(snapc); ceph_get_snap_context(snapc);
} }
...@@ -3258,7 +3287,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq) ...@@ -3258,7 +3287,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
goto err_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); snapc);
if (!img_request) { if (!img_request) {
result = -ENOMEM; result = -ENOMEM;
...@@ -3281,7 +3310,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq) ...@@ -3281,7 +3310,7 @@ static void rbd_handle_request(struct rbd_device *rbd_dev, struct request *rq)
err_rq: err_rq:
if (result) if (result)
rbd_warn(rbd_dev, "%s %llx at %llx result %d", 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) if (snapc)
ceph_put_snap_context(snapc); ceph_put_snap_context(snapc);
blk_end_request_all(rq, result); blk_end_request_all(rq, result);
...@@ -3421,7 +3450,7 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, ...@@ -3421,7 +3450,7 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
obj_request->pages = pages; obj_request->pages = pages;
obj_request->page_count = page_count; 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); obj_request);
if (!obj_request->osd_req) if (!obj_request->osd_req)
goto out; goto out;
......
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