Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359576
b: refs/heads/master
c: 8295cda
h: refs/heads/master
v: v3
  • Loading branch information
Alex Elder committed Jan 17, 2013
1 parent f51d92c commit 25c664c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 57 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: 8986cb37b1cf1f54b35f062f0a12dc68dd89f311
refs/heads/master: 8295cda7ceceb7b25f9a12cd21bbfb6206e28a6d
119 changes: 63 additions & 56 deletions trunk/drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,64 @@ static struct rbd_req_coll *rbd_alloc_coll(int num_reqs)
return coll;
}

static int rbd_dev_do_request(struct request *rq,
struct rbd_device *rbd_dev,
struct ceph_snap_context *snapc,
u64 ofs, unsigned int size,
struct bio *bio_chain)
{
int num_segs;
struct rbd_req_coll *coll;
unsigned int bio_offset;
int cur_seg = 0;

dout("%s 0x%x bytes at 0x%llx\n",
rq_data_dir(rq) == WRITE ? "write" : "read",
size, (unsigned long long) blk_rq_pos(rq) * SECTOR_SIZE);

num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size);
if (num_segs <= 0)
return num_segs;

coll = rbd_alloc_coll(num_segs);
if (!coll)
return -ENOMEM;

bio_offset = 0;
do {
u64 limit = rbd_segment_length(rbd_dev, ofs, size);
unsigned int clone_size;
struct bio *bio_clone;

BUG_ON(limit > (u64)UINT_MAX);
clone_size = (unsigned int)limit;
dout("bio_chain->bi_vcnt=%hu\n", bio_chain->bi_vcnt);

kref_get(&coll->kref);

/* Pass a cloned bio chain via an osd request */

bio_clone = bio_chain_clone_range(&bio_chain,
&bio_offset, clone_size,
GFP_ATOMIC);
if (bio_clone)
(void)rbd_do_op(rq, rbd_dev, snapc,
ofs, clone_size,
bio_clone, coll, cur_seg);
else
rbd_coll_end_req_index(rq, coll, cur_seg,
(s32)-ENOMEM,
clone_size);
size -= clone_size;
ofs += clone_size;

cur_seg++;
} while (size > 0);
kref_put(&coll->kref, rbd_coll_release);

return 0;
}

/*
* block device queue callback
*/
Expand All @@ -1596,10 +1654,8 @@ static void rbd_rq_fn(struct request_queue *q)
bool do_write;
unsigned int size;
u64 ofs;
int num_segs, cur_seg = 0;
struct rbd_req_coll *coll;
struct ceph_snap_context *snapc;
unsigned int bio_offset;
int result;

dout("fetched request\n");

Expand Down Expand Up @@ -1637,60 +1693,11 @@ static void rbd_rq_fn(struct request_queue *q)
ofs = blk_rq_pos(rq) * SECTOR_SIZE;
bio = rq->bio;

dout("%s 0x%x bytes at 0x%llx\n",
do_write ? "write" : "read",
size, (unsigned long long) blk_rq_pos(rq) * SECTOR_SIZE);

num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size);
if (num_segs <= 0) {
spin_lock_irq(q->queue_lock);
__blk_end_request_all(rq, num_segs);
ceph_put_snap_context(snapc);
continue;
}
coll = rbd_alloc_coll(num_segs);
if (!coll) {
spin_lock_irq(q->queue_lock);
__blk_end_request_all(rq, -ENOMEM);
ceph_put_snap_context(snapc);
continue;
}

bio_offset = 0;
do {
u64 limit = rbd_segment_length(rbd_dev, ofs, size);
unsigned int chain_size;
struct bio *bio_chain;

BUG_ON(limit > (u64) UINT_MAX);
chain_size = (unsigned int) limit;
dout("rq->bio->bi_vcnt=%hu\n", rq->bio->bi_vcnt);

kref_get(&coll->kref);

/* Pass a cloned bio chain via an osd request */

bio_chain = bio_chain_clone_range(&bio,
&bio_offset, chain_size,
GFP_ATOMIC);
if (bio_chain)
(void) rbd_do_op(rq, rbd_dev, snapc,
ofs, chain_size,
bio_chain, coll, cur_seg);
else
rbd_coll_end_req_index(rq, coll, cur_seg,
(s32)-ENOMEM,
chain_size);
size -= chain_size;
ofs += chain_size;

cur_seg++;
} while (size > 0);
kref_put(&coll->kref, rbd_coll_release);

spin_lock_irq(q->queue_lock);

result = rbd_dev_do_request(rq, rbd_dev, snapc, ofs, size, bio);
ceph_put_snap_context(snapc);
spin_lock_irq(q->queue_lock);
if (!size || result < 0)
__blk_end_request_all(rq, result);
}
}

Expand Down

0 comments on commit 25c664c

Please sign in to comment.