Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / block / blk-core.c
index 66c3cfe..ee1a1e7 100644 (file)
@@ -608,6 +608,7 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
 
        q->request_fn           = rfn;
        q->prep_rq_fn           = NULL;
+       q->unprep_rq_fn         = NULL;
        q->unplug_fn            = generic_unplug_device;
        q->queue_flags          = QUEUE_FLAG_DEFAULT;
        q->queue_lock           = lock;
@@ -1135,6 +1136,38 @@ void blk_put_request(struct request *req)
 }
 EXPORT_SYMBOL(blk_put_request);
 
+/**
+ * blk_add_request_payload - add a payload to a request
+ * @rq: request to update
+ * @page: page backing the payload
+ * @len: length of the payload.
+ *
+ * This allows to later add a payload to an already submitted request by
+ * a block driver.  The driver needs to take care of freeing the payload
+ * itself.
+ *
+ * Note that this is a quite horrible hack and nothing but handling of
+ * discard requests should ever use it.
+ */
+void blk_add_request_payload(struct request *rq, struct page *page,
+               unsigned int len)
+{
+       struct bio *bio = rq->bio;
+
+       bio->bi_io_vec->bv_page = page;
+       bio->bi_io_vec->bv_offset = 0;
+       bio->bi_io_vec->bv_len = len;
+
+       bio->bi_size = len;
+       bio->bi_vcnt = 1;
+       bio->bi_phys_segments = 1;
+
+       rq->__data_len = rq->resid_len = len;
+       rq->nr_phys_segments = 1;
+       rq->buffer = bio_data(bio);
+}
+EXPORT_SYMBOL_GPL(blk_add_request_payload);
+
 void init_request_from_bio(struct request *req, struct bio *bio)
 {
        req->cpu = bio->bi_comp_cpu;
@@ -1481,7 +1514,10 @@ static inline void __generic_make_request(struct bio *bio)
                if (bio_check_eod(bio, nr_sectors))
                        goto end_io;
 
-               if ((bio->bi_rw & REQ_DISCARD) && !blk_queue_discard(q)) {
+               if ((bio->bi_rw & REQ_DISCARD) &&
+                   (!blk_queue_discard(q) ||
+                    ((bio->bi_rw & REQ_SECURE) &&
+                     !blk_queue_secdiscard(q)))) {
                        err = -EOPNOTSUPP;
                        goto end_io;
                }
@@ -1566,7 +1602,7 @@ void submit_bio(int rw, struct bio *bio)
         * If it's a regular read/write or a barrier with data attached,
         * go through the normal accounting stuff before submission.
         */
-       if (bio_has_data(bio) && !(rw & (1 << BIO_RW_DISCARD))) {
+       if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
                if (rw & WRITE) {
                        count_vm_events(PGPGOUT, count);
                } else {
@@ -1611,6 +1647,9 @@ EXPORT_SYMBOL(submit_bio);
  */
 int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 {
+       if (rq->cmd_flags & REQ_DISCARD)
+               return 0;
+
        if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
            blk_rq_bytes(rq) > queue_max_hw_sectors(q) << 9) {
                printk(KERN_ERR "%s: over max size limit.\n", __func__);
@@ -2101,6 +2140,26 @@ static bool blk_update_bidi_request(struct request *rq, int error,
        return false;
 }
 
+/**
+ * blk_unprep_request - unprepare a request
+ * @req:       the request
+ *
+ * This function makes a request ready for complete resubmission (or
+ * completion).  It happens only after all error handling is complete,
+ * so represents the appropriate moment to deallocate any resources
+ * that were allocated to the request in the prep_rq_fn.  The queue
+ * lock is held when calling this.
+ */
+void blk_unprep_request(struct request *req)
+{
+       struct request_queue *q = req->q;
+
+       req->cmd_flags &= ~REQ_DONTPREP;
+       if (q->unprep_rq_fn)
+               q->unprep_rq_fn(q, req);
+}
+EXPORT_SYMBOL_GPL(blk_unprep_request);
+
 /*
  * queue lock must be held
  */
@@ -2116,6 +2175,10 @@ static void blk_finish_request(struct request *req, int error)
 
        blk_delete_timer(req);
 
+       if (req->cmd_flags & REQ_DONTPREP)
+               blk_unprep_request(req);
+
+
        blk_account_io_done(req);
 
        if (req->end_io)
@@ -2435,6 +2498,8 @@ static void __blk_rq_prep_clone(struct request *dst, struct request *src)
 {
        dst->cpu = src->cpu;
        dst->cmd_flags = (rq_data_dir(src) | REQ_NOMERGE);
+       if (src->cmd_flags & REQ_DISCARD)
+               dst->cmd_flags |= REQ_DISCARD;
        dst->cmd_type = src->cmd_type;
        dst->__sector = blk_rq_pos(src);
        dst->__data_len = blk_rq_bytes(src);