block: implement and use [__]blk_end_request_all()
Tejun Heo [Thu, 23 Apr 2009 02:05:19 +0000 (11:05 +0900)]
There are many [__]blk_end_request() call sites which call it with
full request length and expect full completion.  Many of them ensure
that the request actually completes by doing BUG_ON() the return
value, which is awkward and error-prone.

This patch adds [__]blk_end_request_all() which takes @rq and @error
and fully completes the request.  BUG_ON() is added to to ensure that
this actually happens.

Most conversions are simple but there are a few noteworthy ones.

* cdrom/viocd: viocd_end_request() replaced with direct calls to
  __blk_end_request_all().

* s390/block/dasd: dasd_end_request() replaced with direct calls to
  __blk_end_request_all().

* s390/char/tape_block: tapeblock_end_request() replaced with direct
  calls to blk_end_request_all().

[ Impact: cleanup ]

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Mike Miller <mike.miller@hp.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Jeff Garzik <jgarzik@pobox.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: Alex Dubov <oakad@yahoo.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>

15 files changed:
arch/arm/plat-omap/mailbox.c
block/blk-barrier.c
block/blk-core.c
block/elevator.c
drivers/block/cpqarray.c
drivers/block/sx8.c
drivers/block/virtio_blk.c
drivers/block/xen-blkfront.c
drivers/cdrom/gdrom.c
drivers/cdrom/viocd.c
drivers/memstick/core/mspro_block.c
drivers/s390/block/dasd.c
drivers/s390/char/tape_block.c
drivers/scsi/scsi_lib.c
include/linux/blkdev.h

index 0abfbaa..cf81bad 100644 (file)
@@ -192,8 +192,7 @@ static void mbox_tx_work(struct work_struct *work)
                }
 
                spin_lock(q->queue_lock);
-               if (__blk_end_request(rq, 0, 0))
-                       BUG();
+               __blk_end_request_all(rq, 0);
                spin_unlock(q->queue_lock);
        }
 }
@@ -224,10 +223,7 @@ static void mbox_rx_work(struct work_struct *work)
                        break;
 
                msg = (mbox_msg_t) rq->data;
-
-               if (blk_end_request(rq, 0, 0))
-                       BUG();
-
+               blk_end_request_all(rq, 0);
                mbox->rxq->callback((void *)msg);
        }
 }
@@ -337,8 +333,7 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
 
                *p = (mbox_msg_t) rq->data;
 
-               if (blk_end_request(rq, 0, 0))
-                       BUG();
+               blk_end_request_all(rq, 0);
 
                if (unlikely(mbox_seq_test(mbox, *p))) {
                        pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
index 20b4111..c8d0876 100644 (file)
@@ -106,10 +106,7 @@ bool blk_ordered_complete_seq(struct request_queue *q, unsigned seq, int error)
         */
        q->ordseq = 0;
        rq = q->orig_bar_rq;
-
-       if (__blk_end_request(rq, q->orderr, blk_rq_bytes(rq)))
-               BUG();
-
+       __blk_end_request_all(rq, q->orderr);
        return true;
 }
 
@@ -252,9 +249,7 @@ bool blk_do_ordered(struct request_queue *q, struct request **rqp)
                         * with prejudice.
                         */
                        elv_dequeue_request(q, rq);
-                       if (__blk_end_request(rq, -EOPNOTSUPP,
-                                             blk_rq_bytes(rq)))
-                               BUG();
+                       __blk_end_request_all(rq, -EOPNOTSUPP);
                        *rqp = NULL;
                        return false;
                }
index b84250d..0520cc7 100644 (file)
@@ -1780,7 +1780,7 @@ struct request *elv_next_request(struct request_queue *q)
                        break;
                } else if (ret == BLKPREP_KILL) {
                        rq->cmd_flags |= REQ_QUIET;
-                       __blk_end_request(rq, -EIO, blk_rq_bytes(rq));
+                       __blk_end_request_all(rq, -EIO);
                } else {
                        printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
                        break;
index b03b875..1af5d9f 100644 (file)
@@ -810,7 +810,7 @@ void elv_abort_queue(struct request_queue *q)
                rq = list_entry_rq(q->queue_head.next);
                rq->cmd_flags |= REQ_QUIET;
                trace_block_rq_abort(q, rq);
-               __blk_end_request(rq, -EIO, blk_rq_bytes(rq));
+               __blk_end_request_all(rq, -EIO);
        }
 }
 EXPORT_SYMBOL(elv_abort_queue);
index ca268ca..488a8f4 100644 (file)
@@ -1024,8 +1024,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
                                cmd->req.sg[i].size, ddir);
 
        DBGPX(printk("Done with %p\n", rq););
-       if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
-               BUG();
+       __blk_end_request_all(rq, error);
 }
 
 /*
index ff0448e..60e85bb 100644 (file)
@@ -749,8 +749,7 @@ static inline void carm_end_request_queued(struct carm_host *host,
        struct request *req = crq->rq;
        int rc;
 
-       rc = __blk_end_request(req, error, blk_rq_bytes(req));
-       assert(rc == 0);
+       __blk_end_request_all(req, error);
 
        rc = carm_put_request(host, crq);
        assert(rc == 0);
index 5d34764..50745e6 100644 (file)
@@ -62,7 +62,7 @@ static void blk_done(struct virtqueue *vq)
                        break;
                }
 
-               __blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req));
+               __blk_end_request_all(vbr->req, error);
                list_del(&vbr->list);
                mempool_free(vbr, vblk->pool);
        }
index 8f90508..cd6cfe3 100644 (file)
@@ -551,7 +551,6 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
 
        for (i = info->ring.rsp_cons; i != rp; i++) {
                unsigned long id;
-               int ret;
 
                bret = RING_GET_RESPONSE(&info->ring, i);
                id   = bret->id;
@@ -578,8 +577,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                                dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
                                        "request: %x\n", bret->status);
 
-                       ret = __blk_end_request(req, error, blk_rq_bytes(req));
-                       BUG_ON(ret);
+                       __blk_end_request_all(req, error);
                        break;
                default:
                        BUG();
index 2eecb77..fee9a9e 100644 (file)
@@ -632,7 +632,7 @@ static void gdrom_readdisk_dma(struct work_struct *work)
                * before handling ending the request */
                spin_lock(&gdrom_lock);
                list_del_init(&req->queuelist);
-               __blk_end_request(req, err, blk_rq_bytes(req));
+               __blk_end_request_all(req, err);
        }
        spin_unlock(&gdrom_lock);
        kfree(read_command);
index 1392935..cc3efa0 100644 (file)
@@ -291,23 +291,6 @@ static int send_request(struct request *req)
        return 0;
 }
 
-static void viocd_end_request(struct request *req, int error)
-{
-       int nsectors = req->hard_nr_sectors;
-
-       /*
-        * Make sure it's fully ended, and ensure that we process
-        * at least one sector.
-        */
-       if (blk_pc_request(req))
-               nsectors = (req->data_len + 511) >> 9;
-       if (!nsectors)
-               nsectors = 1;
-
-       if (__blk_end_request(req, error, nsectors << 9))
-               BUG();
-}
-
 static int rwreq;
 
 static void do_viocd_request(struct request_queue *q)
@@ -316,11 +299,11 @@ static void do_viocd_request(struct request_queue *q)
 
        while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) {
                if (!blk_fs_request(req))
-                       viocd_end_request(req, -EIO);
+                       __blk_end_request_all(req, -EIO);
                else if (send_request(req) < 0) {
                        printk(VIOCD_KERN_WARNING
                                        "unable to send message to OS/400!");
-                       viocd_end_request(req, -EIO);
+                       __blk_end_request_all(req, -EIO);
                } else
                        rwreq++;
        }
@@ -531,9 +514,9 @@ return_complete:
                                        "with rc %d:0x%04X: %s\n",
                                        req, event->xRc,
                                        bevent->sub_result, err->msg);
-                       viocd_end_request(req, -EIO);
+                       __blk_end_request_all(req, -EIO);
                } else
-                       viocd_end_request(req, 0);
+                       __blk_end_request_all(req, 0);
 
                /* restart handling of incoming requests */
                spin_unlock_irqrestore(&viocd_reqlock, flags);
index de143de..a416346 100644 (file)
@@ -826,7 +826,7 @@ static void mspro_block_submit_req(struct request_queue *q)
 
        if (msb->eject) {
                while ((req = elv_next_request(q)) != NULL)
-                       __blk_end_request(req, -ENODEV, blk_rq_bytes(req));
+                       __blk_end_request_all(req, -ENODEV);
 
                return;
        }
index d181527..fabec95 100644 (file)
@@ -1614,15 +1614,6 @@ void dasd_block_clear_timer(struct dasd_block *block)
 }
 
 /*
- * posts the buffer_cache about a finalized request
- */
-static inline void dasd_end_request(struct request *req, int error)
-{
-       if (__blk_end_request(req, error, blk_rq_bytes(req)))
-               BUG();
-}
-
-/*
  * Process finished error recovery ccw.
  */
 static inline void __dasd_block_process_erp(struct dasd_block *block,
@@ -1676,7 +1667,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
                                      "Rejecting write request %p",
                                      req);
                        blkdev_dequeue_request(req);
-                       dasd_end_request(req, -EIO);
+                       __blk_end_request_all(req, -EIO);
                        continue;
                }
                cqr = basedev->discipline->build_cp(basedev, block, req);
@@ -1705,7 +1696,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
                                      "on request %p",
                                      PTR_ERR(cqr), req);
                        blkdev_dequeue_request(req);
-                       dasd_end_request(req, -EIO);
+                       __blk_end_request_all(req, -EIO);
                        continue;
                }
                /*
@@ -1731,7 +1722,7 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr)
        status = cqr->block->base->discipline->free_cp(cqr, req);
        if (status <= 0)
                error = status ? status : -EIO;
-       dasd_end_request(req, error);
+       __blk_end_request_all(req, error);
 }
 
 /*
@@ -2040,7 +2031,7 @@ static void dasd_flush_request_queue(struct dasd_block *block)
        spin_lock_irq(&block->request_queue_lock);
        while ((req = elv_next_request(block->request_queue))) {
                blkdev_dequeue_request(req);
-               dasd_end_request(req, -EIO);
+               __blk_end_request_all(req, -EIO);
        }
        spin_unlock_irq(&block->request_queue_lock);
 }
index f32e89e..86596d3 100644 (file)
@@ -74,13 +74,6 @@ tapeblock_trigger_requeue(struct tape_device *device)
  * Post finished request.
  */
 static void
-tapeblock_end_request(struct request *req, int error)
-{
-       if (blk_end_request(req, error, blk_rq_bytes(req)))
-               BUG();
-}
-
-static void
 __tapeblock_end_request(struct tape_request *ccw_req, void *data)
 {
        struct tape_device *device;
@@ -90,7 +83,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data)
 
        device = ccw_req->device;
        req = (struct request *) data;
-       tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO);
+       blk_end_request_all(req, (ccw_req->rc == 0) ? 0 : -EIO);
        if (ccw_req->rc == 0)
                /* Update position. */
                device->blk_data.block_position =
@@ -118,7 +111,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
        ccw_req = device->discipline->bread(device, req);
        if (IS_ERR(ccw_req)) {
                DBF_EVENT(1, "TBLOCK: bread failed\n");
-               tapeblock_end_request(req, -EIO);
+               blk_end_request_all(req, -EIO);
                return PTR_ERR(ccw_req);
        }
        ccw_req->callback = __tapeblock_end_request;
@@ -131,7 +124,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
                 * Start/enqueueing failed. No retries in
                 * this case.
                 */
-               tapeblock_end_request(req, -EIO);
+               blk_end_request_all(req, -EIO);
                device->discipline->free_bread(ccw_req);
        }
 
@@ -177,7 +170,7 @@ tapeblock_requeue(struct work_struct *work) {
                        DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
                        blkdev_dequeue_request(req);
                        spin_unlock_irq(&device->blk_data.request_queue_lock);
-                       tapeblock_end_request(req, -EIO);
+                       blk_end_request_all(req, -EIO);
                        spin_lock_irq(&device->blk_data.request_queue_lock);
                        continue;
                }
index d1cb64a..756ac7c 100644 (file)
@@ -922,7 +922,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        if (driver_byte(result) & DRIVER_SENSE)
                                scsi_print_sense("", cmd);
                }
-               blk_end_request(req, -EIO, blk_rq_bytes(req));
+               blk_end_request_all(req, -EIO);
                scsi_next_command(cmd);
                break;
        case ACTION_REPREP:
index 501f684..e33c835 100644 (file)
@@ -883,6 +883,22 @@ static inline bool blk_end_request(struct request *rq, int error,
 }
 
 /**
+ * blk_end_request_all - Helper function for drives to finish the request.
+ * @rq: the request to finish
+ * @err: %0 for success, < %0 for error
+ *
+ * Description:
+ *     Completely finish @rq.
+ */
+static inline void blk_end_request_all(struct request *rq, int error)
+{
+       bool pending;
+
+       pending = blk_end_request(rq, error, blk_rq_bytes(rq));
+       BUG_ON(pending);
+}
+
+/**
  * __blk_end_request - Helper function for drivers to complete the request.
  * @rq:       the request being processed
  * @error:    %0 for success, < %0 for error
@@ -902,6 +918,22 @@ static inline bool __blk_end_request(struct request *rq, int error,
 }
 
 /**
+ * __blk_end_request_all - Helper function for drives to finish the request.
+ * @rq: the request to finish
+ * @err: %0 for success, < %0 for error
+ *
+ * Description:
+ *     Completely finish @rq.  Must be called with queue lock held.
+ */
+static inline void __blk_end_request_all(struct request *rq, int error)
+{
+       bool pending;
+
+       pending = __blk_end_request(rq, error, blk_rq_bytes(rq));
+       BUG_ON(pending);
+}
+
+/**
  * end_request - end I/O on the current segment of the request
  * @rq:                the request being processed
  * @uptodate:  error value or %0/%1 uptodate flag