aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/file.c6
-rw-r--r--fs/fuse/file.c6
-rw-r--r--fs/ocfs2/file.c6
-rw-r--r--fs/xfs/xfs_file.c5
-rw-r--r--include/linux/fs.h4
-rw-r--r--mm/filemap.c15
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
704out: 705out:
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
2407extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); 2407extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
2408extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long); 2408extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long);
2409extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); 2409extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
2410extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *, 2410extern 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);
2412extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); 2412extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t);
2413extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); 2413extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
2414extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); 2414extern 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,
2385EXPORT_SYMBOL(pagecache_write_end); 2385EXPORT_SYMBOL(pagecache_write_end);
2386 2386
2387ssize_t 2387ssize_t
2388generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, 2388generic_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