LCOV - code coverage report
Current view: top level - block - blk-map.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 112 0.0 %
Date: 2014-02-18 Functions: 0 7 0.0 %
Branches: 0 86 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Functions related to mapping data to requests
       3                 :            :  */
       4                 :            : #include <linux/kernel.h>
       5                 :            : #include <linux/module.h>
       6                 :            : #include <linux/bio.h>
       7                 :            : #include <linux/blkdev.h>
       8                 :            : #include <scsi/sg.h>              /* for struct sg_iovec */
       9                 :            : 
      10                 :            : #include "blk.h"
      11                 :            : 
      12                 :          0 : int blk_rq_append_bio(struct request_queue *q, struct request *rq,
      13                 :            :                       struct bio *bio)
      14                 :            : {
      15         [ #  # ]:          0 :         if (!rq->bio)
      16                 :          0 :                 blk_rq_bio_prep(q, rq, bio);
      17         [ #  # ]:          0 :         else if (!ll_back_merge_fn(q, rq, bio))
      18                 :            :                 return -EINVAL;
      19                 :            :         else {
      20                 :          0 :                 rq->biotail->bi_next = bio;
      21                 :          0 :                 rq->biotail = bio;
      22                 :            : 
      23                 :          0 :                 rq->__data_len += bio->bi_size;
      24                 :            :         }
      25                 :            :         return 0;
      26                 :            : }
      27                 :            : 
      28                 :          0 : static int __blk_rq_unmap_user(struct bio *bio)
      29                 :            : {
      30                 :            :         int ret = 0;
      31                 :            : 
      32         [ #  # ]:          0 :         if (bio) {
      33         [ #  # ]:          0 :                 if (bio_flagged(bio, BIO_USER_MAPPED))
      34                 :          0 :                         bio_unmap_user(bio);
      35                 :            :                 else
      36                 :          0 :                         ret = bio_uncopy_user(bio);
      37                 :            :         }
      38                 :            : 
      39                 :          0 :         return ret;
      40                 :            : }
      41                 :            : 
      42                 :          0 : static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
      43                 :            :                              struct rq_map_data *map_data, void __user *ubuf,
      44                 :            :                              unsigned int len, gfp_t gfp_mask)
      45                 :            : {
      46                 :            :         unsigned long uaddr;
      47                 :            :         struct bio *bio, *orig_bio;
      48                 :            :         int reading, ret;
      49                 :            : 
      50                 :          0 :         reading = rq_data_dir(rq) == READ;
      51                 :            : 
      52                 :            :         /*
      53                 :            :          * if alignment requirement is satisfied, map in user pages for
      54                 :            :          * direct dma. else, set up kernel bounce buffers
      55                 :            :          */
      56                 :          0 :         uaddr = (unsigned long) ubuf;
      57 [ #  # ][ #  # ]:          0 :         if (blk_rq_aligned(q, uaddr, len) && !map_data)
      58                 :          0 :                 bio = bio_map_user(q, NULL, uaddr, len, reading, gfp_mask);
      59                 :            :         else
      60                 :          0 :                 bio = bio_copy_user(q, map_data, uaddr, len, reading, gfp_mask);
      61                 :            : 
      62         [ #  # ]:          0 :         if (IS_ERR(bio))
      63                 :          0 :                 return PTR_ERR(bio);
      64                 :            : 
      65 [ #  # ][ #  # ]:          0 :         if (map_data && map_data->null_mapped)
      66                 :          0 :                 bio->bi_flags |= (1 << BIO_NULL_MAPPED);
      67                 :            : 
      68                 :            :         orig_bio = bio;
      69                 :          0 :         blk_queue_bounce(q, &bio);
      70                 :            : 
      71                 :            :         /*
      72                 :            :          * We link the bounce buffer in and could have to traverse it
      73                 :            :          * later so we have to get a ref to prevent it from being freed
      74                 :            :          */
      75                 :          0 :         bio_get(bio);
      76                 :            : 
      77                 :          0 :         ret = blk_rq_append_bio(q, rq, bio);
      78         [ #  # ]:          0 :         if (!ret)
      79                 :          0 :                 return bio->bi_size;
      80                 :            : 
      81                 :            :         /* if it was boucned we must call the end io function */
      82                 :          0 :         bio_endio(bio, 0);
      83                 :          0 :         __blk_rq_unmap_user(orig_bio);
      84                 :          0 :         bio_put(bio);
      85                 :          0 :         return ret;
      86                 :            : }
      87                 :            : 
      88                 :            : /**
      89                 :            :  * blk_rq_map_user - map user data to a request, for REQ_TYPE_BLOCK_PC usage
      90                 :            :  * @q:          request queue where request should be inserted
      91                 :            :  * @rq:         request structure to fill
      92                 :            :  * @map_data:   pointer to the rq_map_data holding pages (if necessary)
      93                 :            :  * @ubuf:       the user buffer
      94                 :            :  * @len:        length of user data
      95                 :            :  * @gfp_mask:   memory allocation flags
      96                 :            :  *
      97                 :            :  * Description:
      98                 :            :  *    Data will be mapped directly for zero copy I/O, if possible. Otherwise
      99                 :            :  *    a kernel bounce buffer is used.
     100                 :            :  *
     101                 :            :  *    A matching blk_rq_unmap_user() must be issued at the end of I/O, while
     102                 :            :  *    still in process context.
     103                 :            :  *
     104                 :            :  *    Note: The mapped bio may need to be bounced through blk_queue_bounce()
     105                 :            :  *    before being submitted to the device, as pages mapped may be out of
     106                 :            :  *    reach. It's the callers responsibility to make sure this happens. The
     107                 :            :  *    original bio must be passed back in to blk_rq_unmap_user() for proper
     108                 :            :  *    unmapping.
     109                 :            :  */
     110                 :          0 : int blk_rq_map_user(struct request_queue *q, struct request *rq,
     111                 :            :                     struct rq_map_data *map_data, void __user *ubuf,
     112                 :            :                     unsigned long len, gfp_t gfp_mask)
     113                 :            : {
     114                 :            :         unsigned long bytes_read = 0;
     115                 :            :         struct bio *bio = NULL;
     116                 :            :         int ret;
     117                 :            : 
     118         [ #  # ]:          0 :         if (len > (queue_max_hw_sectors(q) << 9))
     119                 :            :                 return -EINVAL;
     120         [ #  # ]:          0 :         if (!len)
     121                 :            :                 return -EINVAL;
     122                 :            : 
     123 [ #  # ][ #  # ]:          0 :         if (!ubuf && (!map_data || !map_data->null_mapped))
                 [ #  # ]
     124                 :            :                 return -EINVAL;
     125                 :            : 
     126         [ #  # ]:          0 :         while (bytes_read != len) {
     127                 :            :                 unsigned long map_len, end, start;
     128                 :            : 
     129                 :          0 :                 map_len = min_t(unsigned long, len - bytes_read, BIO_MAX_SIZE);
     130                 :          0 :                 end = ((unsigned long)ubuf + map_len + PAGE_SIZE - 1)
     131                 :            :                                                                 >> PAGE_SHIFT;
     132                 :          0 :                 start = (unsigned long)ubuf >> PAGE_SHIFT;
     133                 :            : 
     134                 :            :                 /*
     135                 :            :                  * A bad offset could cause us to require BIO_MAX_PAGES + 1
     136                 :            :                  * pages. If this happens we just lower the requested
     137                 :            :                  * mapping len by a page so that we can fit
     138                 :            :                  */
     139         [ #  # ]:          0 :                 if (end - start > BIO_MAX_PAGES)
     140                 :          0 :                         map_len -= PAGE_SIZE;
     141                 :            : 
     142                 :          0 :                 ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
     143                 :            :                                         gfp_mask);
     144         [ #  # ]:          0 :                 if (ret < 0)
     145                 :            :                         goto unmap_rq;
     146         [ #  # ]:          0 :                 if (!bio)
     147                 :          0 :                         bio = rq->bio;
     148                 :          0 :                 bytes_read += ret;
     149                 :          0 :                 ubuf += ret;
     150                 :            : 
     151         [ #  # ]:          0 :                 if (map_data)
     152                 :          0 :                         map_data->offset += ret;
     153                 :            :         }
     154                 :            : 
     155         [ #  # ]:          0 :         if (!bio_flagged(bio, BIO_USER_MAPPED))
     156                 :          0 :                 rq->cmd_flags |= REQ_COPY_USER;
     157                 :            : 
     158                 :          0 :         rq->buffer = NULL;
     159                 :          0 :         return 0;
     160                 :            : unmap_rq:
     161                 :          0 :         blk_rq_unmap_user(bio);
     162                 :          0 :         rq->bio = NULL;
     163                 :          0 :         return ret;
     164                 :            : }
     165                 :            : EXPORT_SYMBOL(blk_rq_map_user);
     166                 :            : 
     167                 :            : /**
     168                 :            :  * blk_rq_map_user_iov - map user data to a request, for REQ_TYPE_BLOCK_PC usage
     169                 :            :  * @q:          request queue where request should be inserted
     170                 :            :  * @rq:         request to map data to
     171                 :            :  * @map_data:   pointer to the rq_map_data holding pages (if necessary)
     172                 :            :  * @iov:        pointer to the iovec
     173                 :            :  * @iov_count:  number of elements in the iovec
     174                 :            :  * @len:        I/O byte count
     175                 :            :  * @gfp_mask:   memory allocation flags
     176                 :            :  *
     177                 :            :  * Description:
     178                 :            :  *    Data will be mapped directly for zero copy I/O, if possible. Otherwise
     179                 :            :  *    a kernel bounce buffer is used.
     180                 :            :  *
     181                 :            :  *    A matching blk_rq_unmap_user() must be issued at the end of I/O, while
     182                 :            :  *    still in process context.
     183                 :            :  *
     184                 :            :  *    Note: The mapped bio may need to be bounced through blk_queue_bounce()
     185                 :            :  *    before being submitted to the device, as pages mapped may be out of
     186                 :            :  *    reach. It's the callers responsibility to make sure this happens. The
     187                 :            :  *    original bio must be passed back in to blk_rq_unmap_user() for proper
     188                 :            :  *    unmapping.
     189                 :            :  */
     190                 :          0 : int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
     191                 :            :                         struct rq_map_data *map_data, struct sg_iovec *iov,
     192                 :            :                         int iov_count, unsigned int len, gfp_t gfp_mask)
     193                 :            : {
     194                 :            :         struct bio *bio;
     195                 :          0 :         int i, read = rq_data_dir(rq) == READ;
     196                 :            :         int unaligned = 0;
     197                 :            : 
     198         [ #  # ]:          0 :         if (!iov || iov_count <= 0)
     199                 :            :                 return -EINVAL;
     200                 :            : 
     201         [ #  # ]:          0 :         for (i = 0; i < iov_count; i++) {
     202                 :          0 :                 unsigned long uaddr = (unsigned long)iov[i].iov_base;
     203                 :            : 
     204         [ #  # ]:          0 :                 if (!iov[i].iov_len)
     205                 :            :                         return -EINVAL;
     206                 :            : 
     207                 :            :                 /*
     208                 :            :                  * Keep going so we check length of all segments
     209                 :            :                  */
     210         [ #  # ]:          0 :                 if (uaddr & queue_dma_alignment(q))
     211                 :            :                         unaligned = 1;
     212                 :            :         }
     213                 :            : 
     214 [ #  # ][ #  # ]:          0 :         if (unaligned || (q->dma_pad_mask & len) || map_data)
                 [ #  # ]
     215                 :          0 :                 bio = bio_copy_user_iov(q, map_data, iov, iov_count, read,
     216                 :            :                                         gfp_mask);
     217                 :            :         else
     218                 :          0 :                 bio = bio_map_user_iov(q, NULL, iov, iov_count, read, gfp_mask);
     219                 :            : 
     220         [ #  # ]:          0 :         if (IS_ERR(bio))
     221                 :          0 :                 return PTR_ERR(bio);
     222                 :            : 
     223         [ #  # ]:          0 :         if (bio->bi_size != len) {
     224                 :            :                 /*
     225                 :            :                  * Grab an extra reference to this bio, as bio_unmap_user()
     226                 :            :                  * expects to be able to drop it twice as it happens on the
     227                 :            :                  * normal IO completion path
     228                 :            :                  */
     229                 :          0 :                 bio_get(bio);
     230                 :          0 :                 bio_endio(bio, 0);
     231                 :          0 :                 __blk_rq_unmap_user(bio);
     232                 :          0 :                 return -EINVAL;
     233                 :            :         }
     234                 :            : 
     235         [ #  # ]:          0 :         if (!bio_flagged(bio, BIO_USER_MAPPED))
     236                 :          0 :                 rq->cmd_flags |= REQ_COPY_USER;
     237                 :            : 
     238                 :          0 :         blk_queue_bounce(q, &bio);
     239                 :          0 :         bio_get(bio);
     240                 :          0 :         blk_rq_bio_prep(q, rq, bio);
     241                 :          0 :         rq->buffer = NULL;
     242                 :          0 :         return 0;
     243                 :            : }
     244                 :            : EXPORT_SYMBOL(blk_rq_map_user_iov);
     245                 :            : 
     246                 :            : /**
     247                 :            :  * blk_rq_unmap_user - unmap a request with user data
     248                 :            :  * @bio:               start of bio list
     249                 :            :  *
     250                 :            :  * Description:
     251                 :            :  *    Unmap a rq previously mapped by blk_rq_map_user(). The caller must
     252                 :            :  *    supply the original rq->bio from the blk_rq_map_user() return, since
     253                 :            :  *    the I/O completion may have changed rq->bio.
     254                 :            :  */
     255                 :          0 : int blk_rq_unmap_user(struct bio *bio)
     256                 :            : {
     257                 :            :         struct bio *mapped_bio;
     258                 :            :         int ret = 0, ret2;
     259                 :            : 
     260         [ #  # ]:          0 :         while (bio) {
     261                 :            :                 mapped_bio = bio;
     262         [ #  # ]:          0 :                 if (unlikely(bio_flagged(bio, BIO_BOUNCED)))
     263                 :          0 :                         mapped_bio = bio->bi_private;
     264                 :            : 
     265                 :          0 :                 ret2 = __blk_rq_unmap_user(mapped_bio);
     266         [ #  # ]:          0 :                 if (ret2 && !ret)
     267                 :            :                         ret = ret2;
     268                 :            : 
     269                 :            :                 mapped_bio = bio;
     270                 :          0 :                 bio = bio->bi_next;
     271                 :          0 :                 bio_put(mapped_bio);
     272                 :            :         }
     273                 :            : 
     274                 :          0 :         return ret;
     275                 :            : }
     276                 :            : EXPORT_SYMBOL(blk_rq_unmap_user);
     277                 :            : 
     278                 :            : /**
     279                 :            :  * blk_rq_map_kern - map kernel data to a request, for REQ_TYPE_BLOCK_PC usage
     280                 :            :  * @q:          request queue where request should be inserted
     281                 :            :  * @rq:         request to fill
     282                 :            :  * @kbuf:       the kernel buffer
     283                 :            :  * @len:        length of user data
     284                 :            :  * @gfp_mask:   memory allocation flags
     285                 :            :  *
     286                 :            :  * Description:
     287                 :            :  *    Data will be mapped directly if possible. Otherwise a bounce
     288                 :            :  *    buffer is used. Can be called multple times to append multple
     289                 :            :  *    buffers.
     290                 :            :  */
     291                 :          0 : int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
     292                 :            :                     unsigned int len, gfp_t gfp_mask)
     293                 :            : {
     294                 :          0 :         int reading = rq_data_dir(rq) == READ;
     295                 :          0 :         unsigned long addr = (unsigned long) kbuf;
     296                 :            :         int do_copy = 0;
     297                 :            :         struct bio *bio;
     298                 :            :         int ret;
     299                 :            : 
     300         [ #  # ]:          0 :         if (len > (queue_max_hw_sectors(q) << 9))
     301                 :            :                 return -EINVAL;
     302         [ #  # ]:          0 :         if (!len || !kbuf)
     303                 :            :                 return -EINVAL;
     304                 :            : 
     305 [ #  # ][ #  # ]:          0 :         do_copy = !blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf);
     306         [ #  # ]:          0 :         if (do_copy)
     307                 :          0 :                 bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
     308                 :            :         else
     309                 :          0 :                 bio = bio_map_kern(q, kbuf, len, gfp_mask);
     310                 :            : 
     311         [ #  # ]:          0 :         if (IS_ERR(bio))
     312                 :          0 :                 return PTR_ERR(bio);
     313                 :            : 
     314         [ #  # ]:          0 :         if (!reading)
     315                 :          0 :                 bio->bi_rw |= REQ_WRITE;
     316                 :            : 
     317         [ #  # ]:          0 :         if (do_copy)
     318                 :          0 :                 rq->cmd_flags |= REQ_COPY_USER;
     319                 :            : 
     320                 :          0 :         ret = blk_rq_append_bio(q, rq, bio);
     321         [ #  # ]:          0 :         if (unlikely(ret)) {
     322                 :            :                 /* request is too big */
     323                 :          0 :                 bio_put(bio);
     324                 :          0 :                 return ret;
     325                 :            :         }
     326                 :            : 
     327                 :          0 :         blk_queue_bounce(q, &rq->bio);
     328                 :          0 :         rq->buffer = NULL;
     329                 :          0 :         return 0;
     330                 :            : }
     331                 :            : EXPORT_SYMBOL(blk_rq_map_kern);

Generated by: LCOV version 1.9