tools headers UAPI: Sync linux/prctl.h with the kernel sources
[linux-2.6-microblaze.git] / block / blk-map.c
index 369e204..3743158 100644 (file)
@@ -123,7 +123,6 @@ static int bio_uncopy_user(struct bio *bio)
                        bio_free_pages(bio);
        }
        kfree(bmd);
-       bio_put(bio);
        return ret;
 }
 
@@ -132,7 +131,7 @@ static int bio_copy_user_iov(struct request *rq, struct rq_map_data *map_data,
 {
        struct bio_map_data *bmd;
        struct page *page;
-       struct bio *bio, *bounce_bio;
+       struct bio *bio;
        int i = 0, ret;
        int nr_pages;
        unsigned int len = iter->count;
@@ -181,7 +180,7 @@ static int bio_copy_user_iov(struct request *rq, struct rq_map_data *map_data,
 
                        i++;
                } else {
-                       page = alloc_page(rq->q->bounce_gfp | gfp_mask);
+                       page = alloc_page(GFP_NOIO | gfp_mask);
                        if (!page) {
                                ret = -ENOMEM;
                                goto cleanup;
@@ -218,16 +217,9 @@ static int bio_copy_user_iov(struct request *rq, struct rq_map_data *map_data,
 
        bio->bi_private = bmd;
 
-       bounce_bio = bio;
-       ret = blk_rq_append_bio(rq, &bounce_bio);
+       ret = blk_rq_append_bio(rq, bio);
        if (ret)
                goto cleanup;
-
-       /*
-        * We link the bounce buffer in and could have to traverse it later, so
-        * we have to get a ref to prevent it from being freed
-        */
-       bio_get(bounce_bio);
        return 0;
 cleanup:
        if (!map_data)
@@ -242,14 +234,14 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
                gfp_t gfp_mask)
 {
        unsigned int max_sectors = queue_max_hw_sectors(rq->q);
-       struct bio *bio, *bounce_bio;
+       struct bio *bio;
        int ret;
        int j;
 
        if (!iov_iter_count(iter))
                return -EINVAL;
 
-       bio = bio_kmalloc(gfp_mask, iov_iter_npages(iter, BIO_MAX_PAGES));
+       bio = bio_kmalloc(gfp_mask, iov_iter_npages(iter, BIO_MAX_VECS));
        if (!bio)
                return -ENOMEM;
        bio->bi_opf |= req_op(rq);
@@ -304,49 +296,17 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
                        break;
        }
 
-       /*
-        * Subtle: if we end up needing to bounce a bio, it would normally
-        * disappear when its bi_end_io is run.  However, we need the original
-        * bio for the unmap, so grab an extra reference to it
-        */
-       bio_get(bio);
-
-       bounce_bio = bio;
-       ret = blk_rq_append_bio(rq, &bounce_bio);
+       ret = blk_rq_append_bio(rq, bio);
        if (ret)
-               goto out_put_orig;
-
-       /*
-        * We link the bounce buffer in and could have to traverse it
-        * later, so we have to get a ref to prevent it from being freed
-        */
-       bio_get(bounce_bio);
+               goto out_unmap;
        return 0;
 
- out_put_orig:
-       bio_put(bio);
  out_unmap:
        bio_release_pages(bio, false);
        bio_put(bio);
        return ret;
 }
 
-/**
- *     bio_unmap_user  -       unmap a bio
- *     @bio:           the bio being unmapped
- *
- *     Unmap a bio previously mapped by bio_map_user_iov(). Must be called from
- *     process context.
- *
- *     bio_unmap_user() may sleep.
- */
-static void bio_unmap_user(struct bio *bio)
-{
-       bio_release_pages(bio, bio_data_dir(bio) == READ);
-       bio_put(bio);
-       bio_put(bio);
-}
-
 static void bio_invalidate_vmalloc_pages(struct bio *bio)
 {
 #ifdef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
@@ -486,7 +446,7 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data,
                if (bytes > len)
                        bytes = len;
 
-               page = alloc_page(q->bounce_gfp | gfp_mask);
+               page = alloc_page(GFP_NOIO | gfp_mask);
                if (!page)
                        goto cleanup;
 
@@ -519,33 +479,24 @@ cleanup:
  * Append a bio to a passthrough request.  Only works if the bio can be merged
  * into the request based on the driver constraints.
  */
-int blk_rq_append_bio(struct request *rq, struct bio **bio)
+int blk_rq_append_bio(struct request *rq, struct bio *bio)
 {
-       struct bio *orig_bio = *bio;
        struct bvec_iter iter;
        struct bio_vec bv;
        unsigned int nr_segs = 0;
 
-       blk_queue_bounce(rq->q, bio);
-
-       bio_for_each_bvec(bv, *bio, iter)
+       bio_for_each_bvec(bv, bio, iter)
                nr_segs++;
 
        if (!rq->bio) {
-               blk_rq_bio_prep(rq, *bio, nr_segs);
+               blk_rq_bio_prep(rq, bio, nr_segs);
        } else {
-               if (!ll_back_merge_fn(rq, *bio, nr_segs)) {
-                       if (orig_bio != *bio) {
-                               bio_put(*bio);
-                               *bio = orig_bio;
-                       }
+               if (!ll_back_merge_fn(rq, bio, nr_segs))
                        return -EINVAL;
-               }
-
-               rq->biotail->bi_next = *bio;
-               rq->biotail = *bio;
-               rq->__data_len += (*bio)->bi_iter.bi_size;
-               bio_crypt_free_ctx(*bio);
+               rq->biotail->bi_next = bio;
+               rq->biotail = bio;
+               rq->__data_len += (bio)->bi_iter.bi_size;
+               bio_crypt_free_ctx(bio);
        }
 
        return 0;
@@ -566,12 +517,6 @@ EXPORT_SYMBOL(blk_rq_append_bio);
  *
  *    A matching blk_rq_unmap_user() must be issued at the end of I/O, while
  *    still in process context.
- *
- *    Note: The mapped bio may need to be bounced through blk_queue_bounce()
- *    before being submitted to the device, as pages mapped may be out of
- *    reach. It's the callers responsibility to make sure this happens. The
- *    original bio must be passed back in to blk_rq_unmap_user() for proper
- *    unmapping.
  */
 int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
                        struct rq_map_data *map_data,
@@ -588,6 +533,8 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
 
        if (map_data)
                copy = true;
+       else if (blk_queue_may_bounce(q))
+               copy = true;
        else if (iov_iter_alignment(iter) & align)
                copy = true;
        else if (queue_virt_boundary(q))
@@ -641,25 +588,21 @@ EXPORT_SYMBOL(blk_rq_map_user);
  */
 int blk_rq_unmap_user(struct bio *bio)
 {
-       struct bio *mapped_bio;
+       struct bio *next_bio;
        int ret = 0, ret2;
 
        while (bio) {
-               mapped_bio = bio;
-               if (unlikely(bio_flagged(bio, BIO_BOUNCED)))
-                       mapped_bio = bio->bi_private;
-
                if (bio->bi_private) {
-                       ret2 = bio_uncopy_user(mapped_bio);
+                       ret2 = bio_uncopy_user(bio);
                        if (ret2 && !ret)
                                ret = ret2;
                } else {
-                       bio_unmap_user(mapped_bio);
+                       bio_release_pages(bio, bio_data_dir(bio) == READ);
                }
 
-               mapped_bio = bio;
+               next_bio = bio;
                bio = bio->bi_next;
-               bio_put(mapped_bio);
+               bio_put(next_bio);
        }
 
        return ret;
@@ -684,7 +627,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
 {
        int reading = rq_data_dir(rq) == READ;
        unsigned long addr = (unsigned long) kbuf;
-       struct bio *bio, *orig_bio;
+       struct bio *bio;
        int ret;
 
        if (len > (queue_max_hw_sectors(q) << 9))
@@ -692,7 +635,8 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
        if (!len || !kbuf)
                return -EINVAL;
 
-       if (!blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf))
+       if (!blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf) ||
+           blk_queue_may_bounce(q))
                bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
        else
                bio = bio_map_kern(q, kbuf, len, gfp_mask);
@@ -703,14 +647,9 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
        bio->bi_opf &= ~REQ_OP_MASK;
        bio->bi_opf |= req_op(rq);
 
-       orig_bio = bio;
-       ret = blk_rq_append_bio(rq, &bio);
-       if (unlikely(ret)) {
-               /* request is too big */
-               bio_put(orig_bio);
-               return ret;
-       }
-
-       return 0;
+       ret = blk_rq_append_bio(rq, bio);
+       if (unlikely(ret))
+               bio_put(bio);
+       return ret;
 }
 EXPORT_SYMBOL(blk_rq_map_kern);