提交 6dd1d8a7 编写于 作者: B Boaz Harrosh 提交者: James Bottomley

[SCSI] libosd: write/read_sg_kern API

This is a trivial addition to the SG API that can receive kernel
pointers. It is only used by the out-of-tree test module. So
it's immediate need is questionable. For maintenance ease it might
just get in, as it's very small.

John.
do you need this in the Kernel, or is it only for osd_ktest.ko?
Signed-off-by: NJohn A. Chandy <john.chandy@uconn.edu>
Signed-off-by: NBoaz Harrosh <bharrosh@panasas.com>
Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
上级 e96e72c4
......@@ -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)
{
......
......@@ -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
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册