aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/file.c17
-rw-r--r--fs/fuse/file.c18
-rw-r--r--fs/ocfs2/file.c10
-rw-r--r--fs/xfs/xfs_file.c9
-rw-r--r--include/linux/fs.h3
-rw-r--r--include/linux/uio.h6
-rw-r--r--mm/filemap.c19
7 files changed, 40 insertions, 42 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index f8cee205618a..ea63a51c148c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1659,8 +1659,7 @@ again:
1659 1659
1660static ssize_t __btrfs_direct_write(struct kiocb *iocb, 1660static ssize_t __btrfs_direct_write(struct kiocb *iocb,
1661 struct iov_iter *from, 1661 struct iov_iter *from,
1662 loff_t pos, 1662 loff_t pos)
1663 size_t count, size_t ocount)
1664{ 1663{
1665 struct file *file = iocb->ki_filp; 1664 struct file *file = iocb->ki_filp;
1666 ssize_t written; 1665 ssize_t written;
@@ -1668,9 +1667,9 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb,
1668 loff_t endbyte; 1667 loff_t endbyte;
1669 int err; 1668 int err;
1670 1669
1671 written = generic_file_direct_write(iocb, from, pos, count, ocount); 1670 written = generic_file_direct_write(iocb, from, pos);
1672 1671
1673 if (written < 0 || written == count) 1672 if (written < 0 || !iov_iter_count(from))
1674 return written; 1673 return written;
1675 1674
1676 pos += written; 1675 pos += written;
@@ -1720,13 +1719,14 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1720 u64 end_pos; 1719 u64 end_pos;
1721 ssize_t num_written = 0; 1720 ssize_t num_written = 0;
1722 ssize_t err = 0; 1721 ssize_t err = 0;
1723 size_t count, ocount; 1722 size_t count;
1724 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); 1723 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
1725 struct iov_iter i; 1724 struct iov_iter i;
1726 1725
1727 mutex_lock(&inode->i_mutex); 1726 mutex_lock(&inode->i_mutex);
1728 1727
1729 count = ocount = iov_length(iov, nr_segs); 1728 count = iov_length(iov, nr_segs);
1729 iov_iter_init(&i, WRITE, iov, nr_segs, count);
1730 1730
1731 current->backing_dev_info = inode->i_mapping->backing_dev_info; 1731 current->backing_dev_info = inode->i_mapping->backing_dev_info;
1732 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); 1732 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
@@ -1740,7 +1740,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1740 goto out; 1740 goto out;
1741 } 1741 }
1742 1742
1743 iov_iter_init(&i, WRITE, iov, nr_segs, count); 1743 iov_iter_truncate(&i, count);
1744 1744
1745 err = file_remove_suid(file); 1745 err = file_remove_suid(file);
1746 if (err) { 1746 if (err) {
@@ -1783,8 +1783,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1783 atomic_inc(&BTRFS_I(inode)->sync_writers); 1783 atomic_inc(&BTRFS_I(inode)->sync_writers);
1784 1784
1785 if (unlikely(file->f_flags & O_DIRECT)) { 1785 if (unlikely(file->f_flags & O_DIRECT)) {
1786 num_written = __btrfs_direct_write(iocb, &i, 1786 num_written = __btrfs_direct_write(iocb, &i, pos);
1787 pos, count, ocount);
1788 } else { 1787 } else {
1789 num_written = __btrfs_buffered_write(file, &i, pos); 1788 num_written = __btrfs_buffered_write(file, &i, pos);
1790 if (num_written > 0) 1789 if (num_written > 0)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 7026014717bc..66d2d5de19d2 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1188,8 +1188,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
1188{ 1188{
1189 struct file *file = iocb->ki_filp; 1189 struct file *file = iocb->ki_filp;
1190 struct address_space *mapping = file->f_mapping; 1190 struct address_space *mapping = file->f_mapping;
1191 size_t count = 0; 1191 size_t count;
1192 size_t ocount = 0;
1193 ssize_t written = 0; 1192 ssize_t written = 0;
1194 ssize_t written_buffered = 0; 1193 ssize_t written_buffered = 0;
1195 struct inode *inode = mapping->host; 1194 struct inode *inode = mapping->host;
@@ -1208,7 +1207,8 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
1208 1207
1209 WARN_ON(iocb->ki_pos != pos); 1208 WARN_ON(iocb->ki_pos != pos);
1210 1209
1211 count = ocount = iov_length(iov, nr_segs); 1210 count = iov_length(iov, nr_segs);
1211 iov_iter_init(&i, WRITE, iov, nr_segs, count);
1212 mutex_lock(&inode->i_mutex); 1212 mutex_lock(&inode->i_mutex);
1213 1213
1214 /* We can write back this queue in page reclaim */ 1214 /* We can write back this queue in page reclaim */
@@ -1217,11 +1217,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
1217 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); 1217 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
1218 if (err) 1218 if (err)
1219 goto out; 1219 goto out;
1220 iov_iter_init(&i, WRITE, iov, nr_segs, count);
1221 1220
1222 if (count == 0) 1221 if (count == 0)
1223 goto out; 1222 goto out;
1224 1223
1224 iov_iter_truncate(&i, count);
1225 err = file_remove_suid(file); 1225 err = file_remove_suid(file);
1226 if (err) 1226 if (err)
1227 goto out; 1227 goto out;
@@ -1231,8 +1231,8 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
1231 goto out; 1231 goto out;
1232 1232
1233 if (file->f_flags & O_DIRECT) { 1233 if (file->f_flags & O_DIRECT) {
1234 written = generic_file_direct_write(iocb, &i, pos, count, ocount); 1234 written = generic_file_direct_write(iocb, &i, pos);
1235 if (written < 0 || written == count) 1235 if (written < 0 || !iov_iter_count(&i))
1236 goto out; 1236 goto out;
1237 1237
1238 pos += written; 1238 pos += written;
@@ -1469,8 +1469,7 @@ static ssize_t __fuse_direct_write(struct fuse_io_priv *io,
1469 1469
1470 res = generic_write_checks(file, ppos, &count, 0); 1470 res = generic_write_checks(file, ppos, &count, 0);
1471 if (!res) { 1471 if (!res) {
1472 if (iter->count > count) 1472 iov_iter_truncate(iter, count);
1473 iter->count = count;
1474 res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE); 1473 res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE);
1475 } 1474 }
1476 1475
@@ -2896,8 +2895,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
2896 if (offset >= i_size) 2895 if (offset >= i_size)
2897 return 0; 2896 return 0;
2898 count = min_t(loff_t, count, fuse_round_up(i_size - offset)); 2897 count = min_t(loff_t, count, fuse_round_up(i_size - offset));
2899 if (iter->count > count) 2898 iov_iter_truncate(iter, count);
2900 iter->count = count;
2901 } 2899 }
2902 2900
2903 io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); 2901 io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 9ce9ed7615c1..06b6a16d9776 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2241,7 +2241,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2241 int ret, direct_io, appending, rw_level, have_alloc_sem = 0; 2241 int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
2242 int can_do_direct, has_refcount = 0; 2242 int can_do_direct, has_refcount = 0;
2243 ssize_t written = 0; 2243 ssize_t written = 0;
2244 size_t ocount; /* original count */
2245 size_t count; /* after file limit checks */ 2244 size_t count; /* after file limit checks */
2246 loff_t old_size, *ppos = &iocb->ki_pos; 2245 loff_t old_size, *ppos = &iocb->ki_pos;
2247 u32 old_clusters; 2246 u32 old_clusters;
@@ -2253,6 +2252,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2253 int unaligned_dio = 0; 2252 int unaligned_dio = 0;
2254 struct iov_iter from; 2253 struct iov_iter from;
2255 2254
2255 count = iov_length(iov, nr_segs);
2256 iov_iter_init(&from, WRITE, iov, nr_segs, count);
2257
2256 trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, 2258 trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
2257 (unsigned long long)OCFS2_I(inode)->ip_blkno, 2259 (unsigned long long)OCFS2_I(inode)->ip_blkno,
2258 file->f_path.dentry->d_name.len, 2260 file->f_path.dentry->d_name.len,
@@ -2355,16 +2357,14 @@ relock:
2355 /* communicate with ocfs2_dio_end_io */ 2357 /* communicate with ocfs2_dio_end_io */
2356 ocfs2_iocb_set_rw_locked(iocb, rw_level); 2358 ocfs2_iocb_set_rw_locked(iocb, rw_level);
2357 2359
2358 count = ocount = iov_length(iov, nr_segs);
2359 ret = generic_write_checks(file, ppos, &count, 2360 ret = generic_write_checks(file, ppos, &count,
2360 S_ISBLK(inode->i_mode)); 2361 S_ISBLK(inode->i_mode));
2361 if (ret) 2362 if (ret)
2362 goto out_dio; 2363 goto out_dio;
2363 2364
2364 iov_iter_init(&from, WRITE, iov, nr_segs, count); 2365 iov_iter_truncate(&from, count);
2365 if (direct_io) { 2366 if (direct_io) {
2366 written = generic_file_direct_write(iocb, &from, *ppos, 2367 written = generic_file_direct_write(iocb, &from, *ppos);
2367 count, ocount);
2368 if (written < 0) { 2368 if (written < 0) {
2369 ret = written; 2369 ret = written;
2370 goto out_dio; 2370 goto out_dio;
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 762bb3e148a6..c997aa2751b2 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -626,7 +626,7 @@ xfs_file_dio_aio_write(
626 const struct iovec *iovp, 626 const struct iovec *iovp,
627 unsigned long nr_segs, 627 unsigned long nr_segs,
628 loff_t pos, 628 loff_t pos,
629 size_t ocount) 629 size_t count)
630{ 630{
631 struct file *file = iocb->ki_filp; 631 struct file *file = iocb->ki_filp;
632 struct address_space *mapping = file->f_mapping; 632 struct address_space *mapping = file->f_mapping;
@@ -634,7 +634,6 @@ xfs_file_dio_aio_write(
634 struct xfs_inode *ip = XFS_I(inode); 634 struct xfs_inode *ip = XFS_I(inode);
635 struct xfs_mount *mp = ip->i_mount; 635 struct xfs_mount *mp = ip->i_mount;
636 ssize_t ret = 0; 636 ssize_t ret = 0;
637 size_t count = ocount;
638 int unaligned_io = 0; 637 int unaligned_io = 0;
639 int iolock; 638 int iolock;
640 struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? 639 struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ?
@@ -645,6 +644,8 @@ xfs_file_dio_aio_write(
645 if ((pos | count) & target->bt_logical_sectormask) 644 if ((pos | count) & target->bt_logical_sectormask)
646 return -XFS_ERROR(EINVAL); 645 return -XFS_ERROR(EINVAL);
647 646
647 iov_iter_init(&from, WRITE, iovp, nr_segs, count);
648
648 /* "unaligned" here means not aligned to a filesystem block */ 649 /* "unaligned" here means not aligned to a filesystem block */
649 if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) 650 if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask))
650 unaligned_io = 1; 651 unaligned_io = 1;
@@ -676,6 +677,7 @@ xfs_file_dio_aio_write(
676 ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); 677 ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock);
677 if (ret) 678 if (ret)
678 goto out; 679 goto out;
680 iov_iter_truncate(&from, count);
679 681
680 if (mapping->nrpages) { 682 if (mapping->nrpages) {
681 ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, 683 ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
@@ -697,8 +699,7 @@ xfs_file_dio_aio_write(
697 } 699 }
698 700
699 trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); 701 trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0);
700 iov_iter_init(&from, WRITE, iovp, nr_segs, count); 702 ret = generic_file_direct_write(iocb, &from, pos);
701 ret = generic_file_direct_write(iocb, &from, pos, count, ocount);
702 703
703out: 704out:
704 xfs_rw_iunlock(ip, iolock); 705 xfs_rw_iunlock(ip, iolock);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d096ebc7f348..8153396d19b4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2407,8 +2407,7 @@ extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsig
2407extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); 2407extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
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 *, struct iov_iter *, 2410extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *, loff_t);
2411 loff_t, size_t, size_t);
2412extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); 2411extern 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); 2412extern 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); 2413extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 4876e9f2a58f..532f59d0adbb 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -82,6 +82,12 @@ static inline size_t iov_iter_count(struct iov_iter *i)
82 return i->count; 82 return i->count;
83} 83}
84 84
85static inline void iov_iter_truncate(struct iov_iter *i, size_t count)
86{
87 if (i->count > count)
88 i->count = count;
89}
90
85int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); 91int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
86int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); 92int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
87 93
diff --git a/mm/filemap.c b/mm/filemap.c
index 3aeaf2df4135..c0404b763a17 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2345,8 +2345,7 @@ int pagecache_write_end(struct file *file, struct address_space *mapping,
2345EXPORT_SYMBOL(pagecache_write_end); 2345EXPORT_SYMBOL(pagecache_write_end);
2346 2346
2347ssize_t 2347ssize_t
2348generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, 2348generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos)
2349 loff_t pos, size_t count, size_t ocount)
2350{ 2349{
2351 struct file *file = iocb->ki_filp; 2350 struct file *file = iocb->ki_filp;
2352 struct address_space *mapping = file->f_mapping; 2351 struct address_space *mapping = file->f_mapping;
@@ -2356,10 +2355,7 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
2356 pgoff_t end; 2355 pgoff_t end;
2357 struct iov_iter data; 2356 struct iov_iter data;
2358 2357
2359 if (count != ocount) 2358 write_len = iov_iter_count(from);
2360 from->nr_segs = iov_shorten((struct iovec *)from->iov, from->nr_segs, count);
2361
2362 write_len = iov_length(from->iov, from->nr_segs);
2363 end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT; 2359 end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT;
2364 2360
2365 written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1); 2361 written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1);
@@ -2568,7 +2564,6 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2568{ 2564{
2569 struct file *file = iocb->ki_filp; 2565 struct file *file = iocb->ki_filp;
2570 struct address_space * mapping = file->f_mapping; 2566 struct address_space * mapping = file->f_mapping;
2571 size_t ocount; /* original count */
2572 size_t count; /* after file limit checks */ 2567 size_t count; /* after file limit checks */
2573 struct inode *inode = mapping->host; 2568 struct inode *inode = mapping->host;
2574 loff_t pos = iocb->ki_pos; 2569 loff_t pos = iocb->ki_pos;
@@ -2577,7 +2572,8 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2577 ssize_t status; 2572 ssize_t status;
2578 struct iov_iter from; 2573 struct iov_iter from;
2579 2574
2580 count = ocount = iov_length(iov, nr_segs); 2575 count = iov_length(iov, nr_segs);
2576 iov_iter_init(&from, WRITE, iov, nr_segs, count);
2581 2577
2582 /* We can write back this queue in page reclaim */ 2578 /* We can write back this queue in page reclaim */
2583 current->backing_dev_info = mapping->backing_dev_info; 2579 current->backing_dev_info = mapping->backing_dev_info;
@@ -2588,6 +2584,8 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2588 if (count == 0) 2584 if (count == 0)
2589 goto out; 2585 goto out;
2590 2586
2587 iov_iter_truncate(&from, count);
2588
2591 err = file_remove_suid(file); 2589 err = file_remove_suid(file);
2592 if (err) 2590 if (err)
2593 goto out; 2591 goto out;
@@ -2596,14 +2594,11 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2596 if (err) 2594 if (err)
2597 goto out; 2595 goto out;
2598 2596
2599 iov_iter_init(&from, WRITE, iov, nr_segs, count);
2600
2601 /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ 2597 /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
2602 if (unlikely(file->f_flags & O_DIRECT)) { 2598 if (unlikely(file->f_flags & O_DIRECT)) {
2603 loff_t endbyte; 2599 loff_t endbyte;
2604 2600
2605 written = generic_file_direct_write(iocb, &from, pos, 2601 written = generic_file_direct_write(iocb, &from, pos);
2606 count, ocount);
2607 if (written < 0 || written == count) 2602 if (written < 0 || written == count)
2608 goto out; 2603 goto out;
2609 2604