On Mon, Apr 04, 2016 at 07:47:36PM +0100, Al Viro wrote:
> On Mon, Apr 04, 2016 at 06:16:12PM +0100, Al Viro wrote:
> 
> > will see NULL map_data; the ->from_user case is sg_start_req() stuff.  IOW,
> > SG_IO behaviour for /dev/sg* is different from the generic one...
> 
> While we are at it: in bio_map_user_iov() we have
>         iov_for_each(iov, i, *iter) { 
>                 unsigned long uaddr = (unsigned long) iov.iov_base;
>                 unsigned long len = iov.iov_len;
>                 unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> 
> PAGE_SHIFT;
>                 unsigned long start = uaddr >> PAGE_SHIFT;
> 
>                 /*
>                  * Overflow, abort
>                  */
>                 if (end < start)
>                         return ERR_PTR(-EINVAL);
> 
>                 nr_pages += end - start;
>                 /*
>                  * buffer must be aligned to at least hardsector size for now
>                  */
>                 if (uaddr & queue_dma_alignment(q))
>                         return ERR_PTR(-EINVAL);
>         }
> 
> Do we only care about the iov_base alignment?  IOW, shouldn't we check for
> iov_len being a multiple of queue_dma_alignment(q) as well?

What happens if somebody issues SG_IO with 256-segment vector, each segment
1 byte long and page-aligned?  Will the driver really be happy with the
resulting request, as long as it hasn't claimed non-zero queue_virt_boundary?
Because AFAICS we'll get a request with a pile of bvecs, each with
->bv_offset equal to 0 and ->bv_len equal to 1; can that really work?

Reply via email to