On Wed, 15 Jan 2014, Matthew Wilcox wrote:

>  static ssize_t xip_io(int rw, struct inode *inode, const struct iovec
> *iov,
>                       loff_t start, loff_t end, unsigned nr_segs,
>                       get_block_t get_block, struct buffer_head *bh)
> @@ -103,21 +109,29 @@ static ssize_t xip_io(int rw, struct inode *inode,
> const struct iovec *iov,
>                       retval = get_block(inode, block, bh, rw == WRITE);
>                       if (retval)
>                               break;
> -                     if (buffer_mapped(bh)) {
> -                             retval = xip_get_addr(inode, bh, &addr);
> -                             if (retval < 0)
> -                                     break;
> -                             addr += offset - (block << inode->i_blkbits);
> -                             hole = false;
> -                             size = retval;
> -                     } else {
> -                             if (rw == WRITE) {
> +                     if (rw == WRITE) {
> +                             if (!buffer_mapped(bh)) {
>                                       retval = -EIO;
>                                       break;
>                               }
> +                             hole = false;
> +                     } else {
> +                             hole = !buffer_written(bh);
> +                     }
> +
> +                     if (hole) {
>                               addr = NULL;
> -                             hole = true;
>                               size = bh->b_size;
> +                     } else {
> +                             unsigned first;
> +                             retval = xip_get_addr(inode, bh, &addr);
> +                             if (retval < 0)
> +                                     break;
> +                             size = retval;
> +                             first = offset - (block << inode->i_blkbits);
> +                             if (buffer_unwritten(bh))
> +                                     memset(addr, 0, first);
> +                             addr += first;

+                               size -= first;

This is needed so that we don't overrun the XIP buffer we are given in the
event that our user buffer >= our XIP buffer and the start of our I/O isn't
block aligned.

You can add my 
Reviewed-by: Ross Zwisler <ross.zwis...@linux.intel.com> 

Thanks,
- Ross
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to