summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-11-14 22:25:19 +0400
committerAlex Elder <elder@inktank.com>2013-01-18 02:34:58 +0400
commit47dba7ba2623b088cbbe1ac0aaa1a034f3249b6d (patch)
tree5b9fb7fc6820dd917c9b6c034d4b35b6c1714204 /drivers/block
parente01e79273b251dbb35ff2522a688229b09481923 (diff)
downloadlinux-47dba7ba2623b088cbbe1ac0aaa1a034f3249b6d.tar.xz
rbd: don't bother calculating file mapping
When rbd_do_request() has a request to process it initializes a ceph file layout structure and uses it to compute offsets and limits for the range of the request using ceph_calc_file_object_mapping(). The layout used is fixed, and is based on RBD_MAX_OBJ_ORDER (30). It sets the layout's object size and stripe unit to be 1 GB (2^30), and sets the stripe count to be 1. The job of ceph_calc_file_object_mapping() is to determine which of a sequence of objects will contain data covered by range, and within that object, at what offset the range starts. It also truncates the length of the range at the end of the selected object if necessary. This is needed for ceph fs, but for rbd it really serves no purpose. It does its own blocking of images into objects, echo of which is (1 << obj_order) in size, and as a result it ignores the "bno" value returned by ceph_calc_file_object_mapping(). In addition, by the point a request has reached this function, it is already destined for a single rbd object, and its length will not exceed that object's extent. Because of this, and because the mapping will result in blocking up the range using an integer multiple of the image's object order, ceph_calc_file_object_mapping() will never change the offset or length values defined by the request. In other words, this call is a big no-op for rbd data requests. There is one exception. We read the header object using this function, and in that case we will not have already limited the request size. However, the header is a single object (not a file or rbd image), and should not be broken into pieces anyway. So in fact we should *not* be calling ceph_calc_file_object_mapping() when operating on the header object. So... Don't call ceph_calc_file_object_mapping() in rbd_do_request(), because useless for image data and incorrect to do sofor the image header. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c18
1 files changed, 4 insertions, 14 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index f5f4e4a8fc87..1c0192c3cf47 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1123,9 +1123,6 @@ static int rbd_do_request(struct request *rq,
{
struct ceph_osd_request *osd_req;
int ret;
- u64 bno;
- u64 obj_off = 0;
- u64 obj_len = 0;
struct timespec mtime = CURRENT_TIME;
struct rbd_request *rbd_req;
struct ceph_osd_client *osdc;
@@ -1169,19 +1166,12 @@ static int rbd_do_request(struct request *rq,
osd_req->r_oid_len = strlen(osd_req->r_oid);
rbd_layout_init(&osd_req->r_file_layout, rbd_dev->spec->pool_id);
- ret = ceph_calc_file_object_mapping(&osd_req->r_file_layout, ofs, len,
- &bno, &obj_off, &obj_len);
- rbd_assert(ret == 0);
- if (obj_len < len) {
- dout(" skipping last %llu, final file extent %llu~%llu\n",
- len - obj_len, ofs, obj_len);
- len = obj_len;
- }
+
if (op->op == CEPH_OSD_OP_READ || op->op == CEPH_OSD_OP_WRITE) {
- op->extent.offset = obj_off;
- op->extent.length = obj_len;
+ op->extent.offset = ofs;
+ op->extent.length = len;
if (op->op == CEPH_OSD_OP_WRITE)
- op->payload_len = obj_len;
+ op->payload_len = len;
}
osd_req->r_num_pages = calc_pages_for(ofs, len);
osd_req->r_page_alignment = ofs & ~PAGE_MASK;