diff options
-rw-r--r-- | fs/btrfs/file.c | 6 | ||||
-rw-r--r-- | fs/fuse/file.c | 6 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 5 | ||||
-rw-r--r-- | include/linux/fs.h | 4 | ||||
-rw-r--r-- | mm/filemap.c | 15 |
6 files changed, 19 insertions, 23 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index ae6af072b635..9fe20c2052af 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1669,15 +1669,13 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, | |||
1669 | loff_t endbyte; | 1669 | loff_t endbyte; |
1670 | int err; | 1670 | int err; |
1671 | 1671 | ||
1672 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, | 1672 | iov_iter_init(&i, iov, nr_segs, count, 0); |
1673 | count, ocount); | 1673 | written = generic_file_direct_write(iocb, &i, pos, count, ocount); |
1674 | 1674 | ||
1675 | if (written < 0 || written == count) | 1675 | if (written < 0 || written == count) |
1676 | return written; | 1676 | return written; |
1677 | 1677 | ||
1678 | pos += written; | 1678 | pos += written; |
1679 | count -= written; | ||
1680 | iov_iter_init(&i, iov, nr_segs, count, written); | ||
1681 | written_buffered = __btrfs_buffered_write(file, &i, pos); | 1679 | written_buffered = __btrfs_buffered_write(file, &i, pos); |
1682 | if (written_buffered < 0) { | 1680 | if (written_buffered < 0) { |
1683 | err = written_buffered; | 1681 | err = written_buffered; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 96d513e01a5d..126deb5d0a9c 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -1235,15 +1235,13 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1235 | goto out; | 1235 | goto out; |
1236 | 1236 | ||
1237 | if (file->f_flags & O_DIRECT) { | 1237 | if (file->f_flags & O_DIRECT) { |
1238 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, | 1238 | iov_iter_init(&i, iov, nr_segs, count, 0); |
1239 | count, ocount); | 1239 | written = generic_file_direct_write(iocb, &i, pos, count, ocount); |
1240 | if (written < 0 || written == count) | 1240 | if (written < 0 || written == count) |
1241 | goto out; | 1241 | goto out; |
1242 | 1242 | ||
1243 | pos += written; | 1243 | pos += written; |
1244 | count -= written; | ||
1245 | 1244 | ||
1246 | iov_iter_init(&i, iov, nr_segs, count, written); | ||
1247 | written_buffered = fuse_perform_write(file, mapping, &i, pos); | 1245 | written_buffered = fuse_perform_write(file, mapping, &i, pos); |
1248 | if (written_buffered < 0) { | 1246 | if (written_buffered < 0) { |
1249 | err = written_buffered; | 1247 | err = written_buffered; |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8970dcf74de5..d6d78c2aa96e 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2251,6 +2251,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
2251 | int full_coherency = !(osb->s_mount_opt & | 2251 | int full_coherency = !(osb->s_mount_opt & |
2252 | OCFS2_MOUNT_COHERENCY_BUFFERED); | 2252 | OCFS2_MOUNT_COHERENCY_BUFFERED); |
2253 | int unaligned_dio = 0; | 2253 | int unaligned_dio = 0; |
2254 | struct iov_iter from; | ||
2254 | 2255 | ||
2255 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, | 2256 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, |
2256 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 2257 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
@@ -2365,16 +2366,15 @@ relock: | |||
2365 | if (ret) | 2366 | if (ret) |
2366 | goto out_dio; | 2367 | goto out_dio; |
2367 | 2368 | ||
2369 | iov_iter_init(&from, iov, nr_segs, count, 0); | ||
2368 | if (direct_io) { | 2370 | if (direct_io) { |
2369 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, | 2371 | written = generic_file_direct_write(iocb, &from, *ppos, |
2370 | count, ocount); | 2372 | count, ocount); |
2371 | if (written < 0) { | 2373 | if (written < 0) { |
2372 | ret = written; | 2374 | ret = written; |
2373 | goto out_dio; | 2375 | goto out_dio; |
2374 | } | 2376 | } |
2375 | } else { | 2377 | } else { |
2376 | struct iov_iter from; | ||
2377 | iov_iter_init(&from, iov, nr_segs, count, 0); | ||
2378 | current->backing_dev_info = file->f_mapping->backing_dev_info; | 2378 | current->backing_dev_info = file->f_mapping->backing_dev_info; |
2379 | written = generic_perform_write(file, &from, *ppos); | 2379 | written = generic_perform_write(file, &from, *ppos); |
2380 | if (likely(written >= 0)) | 2380 | if (likely(written >= 0)) |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 951a2321ee01..8617497867c7 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -641,6 +641,7 @@ xfs_file_dio_aio_write( | |||
641 | int iolock; | 641 | int iolock; |
642 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? | 642 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? |
643 | mp->m_rtdev_targp : mp->m_ddev_targp; | 643 | mp->m_rtdev_targp : mp->m_ddev_targp; |
644 | struct iov_iter from; | ||
644 | 645 | ||
645 | /* DIO must be aligned to device logical sector size */ | 646 | /* DIO must be aligned to device logical sector size */ |
646 | if ((pos | count) & target->bt_logical_sectormask) | 647 | if ((pos | count) & target->bt_logical_sectormask) |
@@ -698,8 +699,8 @@ xfs_file_dio_aio_write( | |||
698 | } | 699 | } |
699 | 700 | ||
700 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); | 701 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); |
701 | ret = generic_file_direct_write(iocb, iovp, | 702 | iov_iter_init(&from, iovp, nr_segs, count, 0); |
702 | &nr_segs, pos, count, ocount); | 703 | ret = generic_file_direct_write(iocb, &from, pos, count, ocount); |
703 | 704 | ||
704 | out: | 705 | out: |
705 | xfs_rw_iunlock(ip, iolock); | 706 | xfs_rw_iunlock(ip, iolock); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 878031227c57..262f96e579b8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2407,8 +2407,8 @@ int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isbl | |||
2407 | extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); | 2407 | extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); |
2408 | extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long); | 2408 | extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long); |
2409 | extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); | 2409 | extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); |
2410 | extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *, | 2410 | extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *, |
2411 | unsigned long *, loff_t, size_t, size_t); | 2411 | loff_t, size_t, size_t); |
2412 | extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); | 2412 | extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); |
2413 | extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); | 2413 | extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); |
2414 | extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); | 2414 | extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); |
diff --git a/mm/filemap.c b/mm/filemap.c index 000a220e2a41..a840890ed39f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -2385,9 +2385,8 @@ int pagecache_write_end(struct file *file, struct address_space *mapping, | |||
2385 | EXPORT_SYMBOL(pagecache_write_end); | 2385 | EXPORT_SYMBOL(pagecache_write_end); |
2386 | 2386 | ||
2387 | ssize_t | 2387 | ssize_t |
2388 | generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | 2388 | generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, |
2389 | unsigned long *nr_segs, loff_t pos, | 2389 | loff_t pos, size_t count, size_t ocount) |
2390 | size_t count, size_t ocount) | ||
2391 | { | 2390 | { |
2392 | struct file *file = iocb->ki_filp; | 2391 | struct file *file = iocb->ki_filp; |
2393 | struct address_space *mapping = file->f_mapping; | 2392 | struct address_space *mapping = file->f_mapping; |
@@ -2397,9 +2396,9 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
2397 | pgoff_t end; | 2396 | pgoff_t end; |
2398 | 2397 | ||
2399 | if (count != ocount) | 2398 | if (count != ocount) |
2400 | *nr_segs = iov_shorten((struct iovec *)iov, *nr_segs, count); | 2399 | from->nr_segs = iov_shorten((struct iovec *)from->iov, from->nr_segs, count); |
2401 | 2400 | ||
2402 | write_len = iov_length(iov, *nr_segs); | 2401 | write_len = iov_length(from->iov, from->nr_segs); |
2403 | end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT; | 2402 | end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT; |
2404 | 2403 | ||
2405 | written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1); | 2404 | written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1); |
@@ -2426,7 +2425,7 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
2426 | } | 2425 | } |
2427 | } | 2426 | } |
2428 | 2427 | ||
2429 | written = mapping->a_ops->direct_IO(WRITE, iocb, iov, pos, *nr_segs); | 2428 | written = mapping->a_ops->direct_IO(WRITE, iocb, from->iov, pos, from->nr_segs); |
2430 | 2429 | ||
2431 | /* | 2430 | /* |
2432 | * Finally, try again to invalidate clean pages which might have been | 2431 | * Finally, try again to invalidate clean pages which might have been |
@@ -2443,6 +2442,7 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
2443 | 2442 | ||
2444 | if (written > 0) { | 2443 | if (written > 0) { |
2445 | pos += written; | 2444 | pos += written; |
2445 | iov_iter_advance(from, written); | ||
2446 | if (pos > i_size_read(inode) && !S_ISBLK(inode->i_mode)) { | 2446 | if (pos > i_size_read(inode) && !S_ISBLK(inode->i_mode)) { |
2447 | i_size_write(inode, pos); | 2447 | i_size_write(inode, pos); |
2448 | mark_inode_dirty(inode); | 2448 | mark_inode_dirty(inode); |
@@ -2645,11 +2645,10 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2645 | if (unlikely(file->f_flags & O_DIRECT)) { | 2645 | if (unlikely(file->f_flags & O_DIRECT)) { |
2646 | loff_t endbyte; | 2646 | loff_t endbyte; |
2647 | 2647 | ||
2648 | written = generic_file_direct_write(iocb, iov, &from.nr_segs, pos, | 2648 | written = generic_file_direct_write(iocb, &from, pos, |
2649 | count, ocount); | 2649 | count, ocount); |
2650 | if (written < 0 || written == count) | 2650 | if (written < 0 || written == count) |
2651 | goto out; | 2651 | goto out; |
2652 | iov_iter_advance(&from, written); | ||
2653 | 2652 | ||
2654 | /* | 2653 | /* |
2655 | * direct-io write to a hole: fall through to buffered I/O | 2654 | * direct-io write to a hole: fall through to buffered I/O |