]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/scsi/osd/osd_initiator.c
libosd: Use of new blk_make_request
[net-next-2.6.git] / drivers / scsi / osd / osd_initiator.c
index 552f58b655d155bcde07a8911f4e81123a47ce4d..865ec0f4aa80462417c8a0bc2f297e4cad1a92f5 100644 (file)
@@ -338,20 +338,6 @@ struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp)
 }
 EXPORT_SYMBOL(osd_start_request);
 
-/*
- * If osd_finalize_request() was called but the request was not executed through
- * the block layer, then we must release BIOs.
- */
-static void _abort_unexecuted_bios(struct request *rq)
-{
-       struct bio *bio;
-
-       while ((bio = rq->bio) != NULL) {
-               rq->bio = bio->bi_next;
-               bio_endio(bio, 0);
-       }
-}
-
 static void _osd_free_seg(struct osd_request *or __unused,
        struct _osd_req_data_segment *seg)
 {
@@ -363,9 +349,30 @@ static void _osd_free_seg(struct osd_request *or __unused,
        seg->alloc_size = 0;
 }
 
+static void _put_request(struct request *rq , bool is_async)
+{
+       if (is_async) {
+               WARN_ON(rq->bio);
+               __blk_put_request(rq->q, rq);
+       } else {
+               /*
+                * If osd_finalize_request() was called but the request was not
+                * executed through the block layer, then we must release BIOs.
+                * TODO: Keep error code in or->async_error. Need to audit all
+                *       code paths.
+                */
+               if (unlikely(rq->bio))
+                       blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
+               else
+                       blk_put_request(rq);
+       }
+}
+
 void osd_end_request(struct osd_request *or)
 {
        struct request *rq = or->request;
+       /* IMPORTANT: make sure this agrees with osd_execute_request_async */
+       bool is_async = (or->request->end_io_data == or);
 
        _osd_free_seg(or, &or->set_attr);
        _osd_free_seg(or, &or->enc_get_attr);
@@ -373,12 +380,11 @@ void osd_end_request(struct osd_request *or)
 
        if (rq) {
                if (rq->next_rq) {
-                       _abort_unexecuted_bios(rq->next_rq);
-                       blk_put_request(rq->next_rq);
+                       _put_request(rq->next_rq, is_async);
+                       rq->next_rq = NULL;
                }
 
-               _abort_unexecuted_bios(rq);
-               blk_put_request(rq);
+               _put_request(rq, is_async);
        }
        _osd_request_free(or);
 }
@@ -820,26 +826,6 @@ int osd_req_add_set_attr_list(struct osd_request *or,
 }
 EXPORT_SYMBOL(osd_req_add_set_attr_list);
 
-static int _append_map_kern(struct request *req,
-       void *buff, unsigned len, gfp_t flags)
-{
-       struct bio *bio;
-       int ret;
-
-       bio = bio_map_kern(req->q, buff, len, flags);
-       if (IS_ERR(bio)) {
-               OSD_ERR("Failed bio_map_kern(%p, %d) => %ld\n", buff, len,
-                       PTR_ERR(bio));
-               return PTR_ERR(bio);
-       }
-       ret = blk_rq_append_bio(req->q, req, bio);
-       if (ret) {
-               OSD_ERR("Failed blk_rq_append_bio(%p) => %d\n", bio, ret);
-               bio_put(bio);
-       }
-       return ret;
-}
-
 static int _req_append_segment(struct osd_request *or,
        unsigned padding, struct _osd_req_data_segment *seg,
        struct _osd_req_data_segment *last_seg, struct _osd_io_info *io)
@@ -855,14 +841,14 @@ static int _req_append_segment(struct osd_request *or,
                else
                        pad_buff = io->pad_buff;
 
-               ret = _append_map_kern(io->req, pad_buff, padding,
+               ret = blk_rq_map_kern(io->req->q, io->req, pad_buff, padding,
                                       or->alloc_flags);
                if (ret)
                        return ret;
                io->total_bytes += padding;
        }
 
-       ret = _append_map_kern(io->req, seg->buff, seg->total_bytes,
+       ret = blk_rq_map_kern(io->req->q, io->req, seg->buff, seg->total_bytes,
                               or->alloc_flags);
        if (ret)
                return ret;
@@ -1214,6 +1200,21 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or,
 /*
  * osd_finalize_request and helpers
  */
+static struct request *_make_request(struct request_queue *q, bool has_write,
+                             struct _osd_io_info *oii, gfp_t flags)
+{
+       if (oii->bio)
+               return blk_make_request(q, oii->bio, flags);
+       else {
+               struct request *req;
+
+               req = blk_get_request(q, has_write ? WRITE : READ, flags);
+               if (unlikely(!req))
+                       return ERR_PTR(-ENOMEM);
+
+               return req;
+       }
+}
 
 static int _init_blk_request(struct osd_request *or,
        bool has_in, bool has_out)
@@ -1222,11 +1223,13 @@ static int _init_blk_request(struct osd_request *or,
        struct scsi_device *scsi_device = or->osd_dev->scsi_device;
        struct request_queue *q = scsi_device->request_queue;
        struct request *req;
-       int ret = -ENOMEM;
+       int ret;
 
-       req = blk_get_request(q, has_out, flags);
-       if (!req)
+       req = _make_request(q, has_out, has_out ? &or->out : &or->in, flags);
+       if (IS_ERR(req)) {
+               ret = PTR_ERR(req);
                goto out;
+       }
 
        or->request = req;
        req->cmd_type = REQ_TYPE_BLOCK_PC;
@@ -1239,9 +1242,10 @@ static int _init_blk_request(struct osd_request *or,
                or->out.req = req;
                if (has_in) {
                        /* allocate bidi request */
-                       req = blk_get_request(q, READ, flags);
-                       if (!req) {
+                       req = _make_request(q, false, &or->in, flags);
+                       if (IS_ERR(req)) {
                                OSD_DEBUG("blk_get_request for bidi failed\n");
+                               ret = PTR_ERR(req);
                                goto out;
                        }
                        req->cmd_type = REQ_TYPE_BLOCK_PC;
@@ -1285,26 +1289,6 @@ int osd_finalize_request(struct osd_request *or,
                return ret;
        }
 
-       if (or->out.bio) {
-               ret = blk_rq_append_bio(or->request->q, or->out.req,
-                                       or->out.bio);
-               if (ret) {
-                       OSD_DEBUG("blk_rq_append_bio out failed\n");
-                       return ret;
-               }
-               OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n",
-                       _LLU(or->out.total_bytes), or->out.req->data_len);
-       }
-       if (or->in.bio) {
-               ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio);
-               if (ret) {
-                       OSD_DEBUG("blk_rq_append_bio in failed\n");
-                       return ret;
-               }
-               OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n",
-                       _LLU(or->in.total_bytes), or->in.req->data_len);
-       }
-
        or->out.pad_buff = sg_out_pad_buffer;
        or->in.pad_buff = sg_in_pad_buffer;