Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 331650
b: refs/heads/master
c: 65ccfe2
h: refs/heads/master
v: v3
  • Loading branch information
Alex Elder committed Oct 1, 2012
1 parent 8157b6c commit ce9973f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: df111be6310fc41d059a485368e3c51a684859c2
refs/heads/master: 65ccfe21dd8fb402547bb1c50bbc2737c4ef37b8
66 changes: 40 additions & 26 deletions trunk/drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,27 +669,47 @@ static void rbd_header_free(struct rbd_image_header *header)
header->snapc = NULL;
}

/*
* get the actual striped segment name, offset and length
*/
static u64 rbd_get_segment(struct rbd_image_header *header,
const char *object_prefix,
u64 ofs, u64 len,
char *seg_name, u64 *segofs)
static char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset)
{
char *name;
u64 segment;
int ret;

name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
if (!name)
return NULL;
segment = offset >> rbd_dev->header.obj_order;
ret = snprintf(name, RBD_MAX_SEG_NAME_LEN, "%s.%012llx",
rbd_dev->header.object_prefix, segment);
if (ret < 0 || ret >= RBD_MAX_SEG_NAME_LEN) {
pr_err("error formatting segment name for #%llu (%d)\n",
segment, ret);
kfree(name);
name = NULL;
}

return name;
}

static u64 rbd_segment_offset(struct rbd_device *rbd_dev, u64 offset)
{
u64 seg = ofs >> header->obj_order;
u64 segment_size = (u64) 1 << rbd_dev->header.obj_order;

if (seg_name)
snprintf(seg_name, RBD_MAX_SEG_NAME_LEN,
"%s.%012llx", object_prefix, seg);
return offset & (segment_size - 1);
}

static u64 rbd_segment_length(struct rbd_device *rbd_dev,
u64 offset, u64 length)
{
u64 segment_size = (u64) 1 << rbd_dev->header.obj_order;

ofs = ofs & ((1 << header->obj_order) - 1);
len = min_t(u64, len, (1 << header->obj_order) - ofs);
offset &= segment_size - 1;

if (segofs)
*segofs = ofs;
BUG_ON(length > U64_MAX - offset);
if (offset + length > segment_size)
length = segment_size - offset;

return len;
return length;
}

static int rbd_get_num_segments(struct rbd_image_header *header,
Expand Down Expand Up @@ -1127,14 +1147,11 @@ static int rbd_do_op(struct request *rq,
struct ceph_osd_req_op *ops;
u32 payload_len;

seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
seg_name = rbd_segment_name(rbd_dev, ofs);
if (!seg_name)
return -ENOMEM;

seg_len = rbd_get_segment(&rbd_dev->header,
rbd_dev->header.object_prefix,
ofs, len,
seg_name, &seg_ofs);
seg_len = rbd_segment_length(rbd_dev, ofs, len);
seg_ofs = rbd_segment_offset(rbd_dev, ofs);

payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0);

Expand Down Expand Up @@ -1545,10 +1562,7 @@ static void rbd_rq_fn(struct request_queue *q)
do {
/* a bio clone to be passed down to OSD req */
dout("rq->bio->bi_vcnt=%hu\n", rq->bio->bi_vcnt);
op_size = rbd_get_segment(&rbd_dev->header,
rbd_dev->header.object_prefix,
ofs, size,
NULL, NULL);
op_size = rbd_segment_length(rbd_dev, ofs, size);
kref_get(&coll->kref);
bio = bio_chain_clone(&rq_bio, &next_bio, &bp,
op_size, GFP_ATOMIC);
Expand Down

0 comments on commit ce9973f

Please sign in to comment.