Loading drivers/staging/lustre/lustre/llite/rw26.c +2 −5 Original line number Diff line number Diff line Loading @@ -391,11 +391,8 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, MAX_DIO_SIZE >> PAGE_CACHE_SHIFT); /* Check that all user buffers are aligned as well */ for (seg = 0; seg < iter->nr_segs; seg++) { if (((unsigned long)iter->iov[seg].iov_base & ~CFS_PAGE_MASK) || (iter->iov[seg].iov_len & ~CFS_PAGE_MASK)) if (iov_iter_alignment(iter) & ~CFS_PAGE_MASK) return -EINVAL; } env = cl_env_get(&refcheck); LASSERT(!IS_ERR(env)); Loading fs/direct-io.c +5 −22 Original line number Diff line number Diff line Loading @@ -1112,19 +1112,18 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, dio_submit_t submit_io, int flags) { int seg; size_t size; unsigned long addr; unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits); unsigned blkbits = i_blkbits; unsigned blocksize_mask = (1 << blkbits) - 1; ssize_t retval = -EINVAL; loff_t end = offset; loff_t end = offset + iov_iter_count(iter); struct dio *dio; struct dio_submit sdio = { 0, }; unsigned long user_addr; size_t bytes; struct buffer_head map_bh = { 0, }; struct blk_plug plug; unsigned long align = offset | iov_iter_alignment(iter); if (rw & WRITE) rw = WRITE_ODIRECT; Loading @@ -1134,32 +1133,16 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, * the early prefetch in the caller enough time. */ if (offset & blocksize_mask) { if (align & blocksize_mask) { if (bdev) blkbits = blksize_bits(bdev_logical_block_size(bdev)); blocksize_mask = (1 << blkbits) - 1; if (offset & blocksize_mask) if (align & blocksize_mask) goto out; } /* Check the memory alignment. Blocks cannot straddle pages */ for (seg = 0; seg < iter->nr_segs; seg++) { addr = (unsigned long)iter->iov[seg].iov_base; size = iter->iov[seg].iov_len; end += size; if (unlikely((addr & blocksize_mask) || (size & blocksize_mask))) { if (bdev) blkbits = blksize_bits( bdev_logical_block_size(bdev)); blocksize_mask = (1 << blkbits) - 1; if ((addr & blocksize_mask) || (size & blocksize_mask)) goto out; } } /* watch out for a 0 len io from a tricksy fs */ if (rw == READ && end == offset) if (rw == READ && !iov_iter_count(iter)) return 0; dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); Loading include/linux/uio.h +2 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); size_t iov_iter_single_seg_count(const struct iov_iter *i); size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, struct iov_iter *i); unsigned long iov_iter_alignment(const struct iov_iter *i); static inline void iov_iter_init(struct iov_iter *i, const struct iovec *iov, unsigned long nr_segs, Loading @@ -88,4 +89,5 @@ static inline size_t iov_iter_count(struct iov_iter *i) int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); #endif mm/iov_iter.c +25 −0 Original line number Diff line number Diff line Loading @@ -195,3 +195,28 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i) return min(i->count, iov->iov_len - i->iov_offset); } EXPORT_SYMBOL(iov_iter_single_seg_count); unsigned long iov_iter_alignment(const struct iov_iter *i) { const struct iovec *iov = i->iov; unsigned long res; size_t size = i->count; size_t n; if (!size) return 0; res = (unsigned long)iov->iov_base + i->iov_offset; n = iov->iov_len - i->iov_offset; if (n >= size) return res | size; size -= n; res |= n; while (size > (++iov)->iov_len) { res |= (unsigned long)iov->iov_base | iov->iov_len; size -= iov->iov_len; } res |= (unsigned long)iov->iov_base | size; return res; } EXPORT_SYMBOL(iov_iter_alignment); Loading
drivers/staging/lustre/lustre/llite/rw26.c +2 −5 Original line number Diff line number Diff line Loading @@ -391,11 +391,8 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, MAX_DIO_SIZE >> PAGE_CACHE_SHIFT); /* Check that all user buffers are aligned as well */ for (seg = 0; seg < iter->nr_segs; seg++) { if (((unsigned long)iter->iov[seg].iov_base & ~CFS_PAGE_MASK) || (iter->iov[seg].iov_len & ~CFS_PAGE_MASK)) if (iov_iter_alignment(iter) & ~CFS_PAGE_MASK) return -EINVAL; } env = cl_env_get(&refcheck); LASSERT(!IS_ERR(env)); Loading
fs/direct-io.c +5 −22 Original line number Diff line number Diff line Loading @@ -1112,19 +1112,18 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, dio_submit_t submit_io, int flags) { int seg; size_t size; unsigned long addr; unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits); unsigned blkbits = i_blkbits; unsigned blocksize_mask = (1 << blkbits) - 1; ssize_t retval = -EINVAL; loff_t end = offset; loff_t end = offset + iov_iter_count(iter); struct dio *dio; struct dio_submit sdio = { 0, }; unsigned long user_addr; size_t bytes; struct buffer_head map_bh = { 0, }; struct blk_plug plug; unsigned long align = offset | iov_iter_alignment(iter); if (rw & WRITE) rw = WRITE_ODIRECT; Loading @@ -1134,32 +1133,16 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, * the early prefetch in the caller enough time. */ if (offset & blocksize_mask) { if (align & blocksize_mask) { if (bdev) blkbits = blksize_bits(bdev_logical_block_size(bdev)); blocksize_mask = (1 << blkbits) - 1; if (offset & blocksize_mask) if (align & blocksize_mask) goto out; } /* Check the memory alignment. Blocks cannot straddle pages */ for (seg = 0; seg < iter->nr_segs; seg++) { addr = (unsigned long)iter->iov[seg].iov_base; size = iter->iov[seg].iov_len; end += size; if (unlikely((addr & blocksize_mask) || (size & blocksize_mask))) { if (bdev) blkbits = blksize_bits( bdev_logical_block_size(bdev)); blocksize_mask = (1 << blkbits) - 1; if ((addr & blocksize_mask) || (size & blocksize_mask)) goto out; } } /* watch out for a 0 len io from a tricksy fs */ if (rw == READ && end == offset) if (rw == READ && !iov_iter_count(iter)) return 0; dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); Loading
include/linux/uio.h +2 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); size_t iov_iter_single_seg_count(const struct iov_iter *i); size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, struct iov_iter *i); unsigned long iov_iter_alignment(const struct iov_iter *i); static inline void iov_iter_init(struct iov_iter *i, const struct iovec *iov, unsigned long nr_segs, Loading @@ -88,4 +89,5 @@ static inline size_t iov_iter_count(struct iov_iter *i) int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); #endif
mm/iov_iter.c +25 −0 Original line number Diff line number Diff line Loading @@ -195,3 +195,28 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i) return min(i->count, iov->iov_len - i->iov_offset); } EXPORT_SYMBOL(iov_iter_single_seg_count); unsigned long iov_iter_alignment(const struct iov_iter *i) { const struct iovec *iov = i->iov; unsigned long res; size_t size = i->count; size_t n; if (!size) return 0; res = (unsigned long)iov->iov_base + i->iov_offset; n = iov->iov_len - i->iov_offset; if (n >= size) return res | size; size -= n; res |= n; while (size > (++iov)->iov_len) { res |= (unsigned long)iov->iov_base | iov->iov_len; size -= iov->iov_len; } res |= (unsigned long)iov->iov_base | size; return res; } EXPORT_SYMBOL(iov_iter_alignment);