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.zwisler@xxxxxxxxxxxxxxx> Thanks, - Ross -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html