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: Guangliang Zhao <lucienchao@gmail.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com> Reviewed-by: Alex Elder <elder@linaro.org>
This commit is contained in:
parent
c622d22615
commit
6d2940c881
1 changed files with 63 additions and 34 deletions
|
@ -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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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(
|
||||||
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));
|
|
||||||
if (write_request)
|
|
||||||
snapc = img_request->snapc;
|
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(
|
||||||
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)
|
||||||
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(
|
||||||
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(
|
||||||
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(
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,8 +2343,16 @@ 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;
|
||||||
|
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);
|
obj_request);
|
||||||
if (!osd_req)
|
if (!osd_req)
|
||||||
goto out_unwind;
|
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;
|
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,
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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(
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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 @@ err_img_request:
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue