Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 221510
b: refs/heads/master
c: 6dd1d8a
h: refs/heads/master
v: v3
  • Loading branch information
Boaz Harrosh authored and James Bottomley committed Oct 26, 2010
1 parent 2e6ca7d commit 3ae6724
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e96e72c45a1e78e9266dd70113b851395a440ef3
refs/heads/master: 6dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9da
71 changes: 71 additions & 0 deletions trunk/drivers/scsi/osd/osd_initiator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,77 @@ int osd_req_read_sg(struct osd_request *or,
}
EXPORT_SYMBOL(osd_req_read_sg);

/* SG-list write/read Kern API
*
* osd_req_{write,read}_sg_kern takes an array of @buff pointers and an array
* of sg_entries. @numentries indicates how many pointers and sg_entries there
* are. By requiring an array of buff pointers. This allows a caller to do a
* single write/read and scatter into multiple buffers.
* NOTE: Each buffer + len should not cross a page boundary.
*/
static struct bio *_create_sg_bios(struct osd_request *or,
void **buff, const struct osd_sg_entry *sglist, unsigned numentries)
{
struct request_queue *q = osd_request_queue(or->osd_dev);
struct bio *bio;
unsigned i;

bio = bio_kmalloc(GFP_KERNEL, numentries);
if (unlikely(!bio)) {
OSD_DEBUG("Faild to allocate BIO size=%u\n", numentries);
return ERR_PTR(-ENOMEM);
}

for (i = 0; i < numentries; i++) {
unsigned offset = offset_in_page(buff[i]);
struct page *page = virt_to_page(buff[i]);
unsigned len = sglist[i].len;
unsigned added_len;

BUG_ON(offset + len > PAGE_SIZE);
added_len = bio_add_pc_page(q, bio, page, len, offset);
if (unlikely(len != added_len)) {
OSD_DEBUG("bio_add_pc_page len(%d) != added_len(%d)\n",
len, added_len);
bio_put(bio);
return ERR_PTR(-ENOMEM);
}
}

return bio;
}

int osd_req_write_sg_kern(struct osd_request *or,
const struct osd_obj_id *obj, void **buff,
const struct osd_sg_entry *sglist, unsigned numentries)
{
struct bio *bio = _create_sg_bios(or, buff, sglist, numentries);
if (IS_ERR(bio))
return PTR_ERR(bio);

bio->bi_rw |= REQ_WRITE;
osd_req_write_sg(or, obj, bio, sglist, numentries);

return 0;
}
EXPORT_SYMBOL(osd_req_write_sg_kern);

int osd_req_read_sg_kern(struct osd_request *or,
const struct osd_obj_id *obj, void **buff,
const struct osd_sg_entry *sglist, unsigned numentries)
{
struct bio *bio = _create_sg_bios(or, buff, sglist, numentries);
if (IS_ERR(bio))
return PTR_ERR(bio);

osd_req_read_sg(or, obj, bio, sglist, numentries);

return 0;
}
EXPORT_SYMBOL(osd_req_read_sg_kern);



void osd_req_get_attributes(struct osd_request *or,
const struct osd_obj_id *obj)
{
Expand Down
7 changes: 7 additions & 0 deletions trunk/include/scsi/osd_initiator.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,13 @@ int osd_req_write_sg(struct osd_request *or,
int osd_req_read_sg(struct osd_request *or,
const struct osd_obj_id *obj, struct bio *bio,
const struct osd_sg_entry *sglist, unsigned numentries);
int osd_req_write_sg_kern(struct osd_request *or,
const struct osd_obj_id *obj, void **buff,
const struct osd_sg_entry *sglist, unsigned numentries);
int osd_req_read_sg_kern(struct osd_request *or,
const struct osd_obj_id *obj, void **buff,
const struct osd_sg_entry *sglist, unsigned numentries);

/*
* Root/Partition/Collection/Object Attributes commands
*/
Expand Down

0 comments on commit 3ae6724

Please sign in to comment.