Commit 0c949334a9e2581646c6ff0d1470a805b1e5be99
1 parent
28060d5d9b
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
iov_iter_truncate()
Now It Can Be Done(tm) - we don't need to do iov_shorten() in generic_file_direct_write() anymore, now that all ->direct_IO() instances are converted to proper iov_iter methods and honour iter->count and iter->iov_offset properly. Get rid of count/ocount arguments of generic_file_direct_write(), while we are at it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 7 changed files with 40 additions and 42 deletions Side-by-side Diff
fs/btrfs/file.c
... | ... | @@ -1659,8 +1659,7 @@ |
1659 | 1659 | |
1660 | 1660 | static ssize_t __btrfs_direct_write(struct kiocb *iocb, |
1661 | 1661 | struct iov_iter *from, |
1662 | - loff_t pos, | |
1663 | - size_t count, size_t ocount) | |
1662 | + loff_t pos) | |
1664 | 1663 | { |
1665 | 1664 | struct file *file = iocb->ki_filp; |
1666 | 1665 | ssize_t written; |
1667 | 1666 | |
... | ... | @@ -1668,9 +1667,9 @@ |
1668 | 1667 | loff_t endbyte; |
1669 | 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 | 1673 | return written; |
1675 | 1674 | |
1676 | 1675 | pos += written; |
1677 | 1676 | |
... | ... | @@ -1720,13 +1719,14 @@ |
1720 | 1719 | u64 end_pos; |
1721 | 1720 | ssize_t num_written = 0; |
1722 | 1721 | ssize_t err = 0; |
1723 | - size_t count, ocount; | |
1722 | + size_t count; | |
1724 | 1723 | bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); |
1725 | 1724 | struct iov_iter i; |
1726 | 1725 | |
1727 | 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 | 1731 | current->backing_dev_info = inode->i_mapping->backing_dev_info; |
1732 | 1732 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); |
... | ... | @@ -1740,7 +1740,7 @@ |
1740 | 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 | 1745 | err = file_remove_suid(file); |
1746 | 1746 | if (err) { |
... | ... | @@ -1783,8 +1783,7 @@ |
1783 | 1783 | atomic_inc(&BTRFS_I(inode)->sync_writers); |
1784 | 1784 | |
1785 | 1785 | if (unlikely(file->f_flags & O_DIRECT)) { |
1786 | - num_written = __btrfs_direct_write(iocb, &i, | |
1787 | - pos, count, ocount); | |
1786 | + num_written = __btrfs_direct_write(iocb, &i, pos); | |
1788 | 1787 | } else { |
1789 | 1788 | num_written = __btrfs_buffered_write(file, &i, pos); |
1790 | 1789 | if (num_written > 0) |
fs/fuse/file.c
... | ... | @@ -1188,8 +1188,7 @@ |
1188 | 1188 | { |
1189 | 1189 | struct file *file = iocb->ki_filp; |
1190 | 1190 | struct address_space *mapping = file->f_mapping; |
1191 | - size_t count = 0; | |
1192 | - size_t ocount = 0; | |
1191 | + size_t count; | |
1193 | 1192 | ssize_t written = 0; |
1194 | 1193 | ssize_t written_buffered = 0; |
1195 | 1194 | struct inode *inode = mapping->host; |
... | ... | @@ -1208,7 +1207,8 @@ |
1208 | 1207 | |
1209 | 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 | 1212 | mutex_lock(&inode->i_mutex); |
1213 | 1213 | |
1214 | 1214 | /* We can write back this queue in page reclaim */ |
1215 | 1215 | |
... | ... | @@ -1217,11 +1217,11 @@ |
1217 | 1217 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); |
1218 | 1218 | if (err) |
1219 | 1219 | goto out; |
1220 | - iov_iter_init(&i, WRITE, iov, nr_segs, count); | |
1221 | 1220 | |
1222 | 1221 | if (count == 0) |
1223 | 1222 | goto out; |
1224 | 1223 | |
1224 | + iov_iter_truncate(&i, count); | |
1225 | 1225 | err = file_remove_suid(file); |
1226 | 1226 | if (err) |
1227 | 1227 | goto out; |
... | ... | @@ -1231,8 +1231,8 @@ |
1231 | 1231 | goto out; |
1232 | 1232 | |
1233 | 1233 | if (file->f_flags & O_DIRECT) { |
1234 | - written = generic_file_direct_write(iocb, &i, pos, count, ocount); | |
1235 | - if (written < 0 || written == count) | |
1234 | + written = generic_file_direct_write(iocb, &i, pos); | |
1235 | + if (written < 0 || !iov_iter_count(&i)) | |
1236 | 1236 | goto out; |
1237 | 1237 | |
1238 | 1238 | pos += written; |
... | ... | @@ -1469,8 +1469,7 @@ |
1469 | 1469 | |
1470 | 1470 | res = generic_write_checks(file, ppos, &count, 0); |
1471 | 1471 | if (!res) { |
1472 | - if (iter->count > count) | |
1473 | - iter->count = count; | |
1472 | + iov_iter_truncate(iter, count); | |
1474 | 1473 | res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE); |
1475 | 1474 | } |
1476 | 1475 | |
... | ... | @@ -2896,8 +2895,7 @@ |
2896 | 2895 | if (offset >= i_size) |
2897 | 2896 | return 0; |
2898 | 2897 | count = min_t(loff_t, count, fuse_round_up(i_size - offset)); |
2899 | - if (iter->count > count) | |
2900 | - iter->count = count; | |
2898 | + iov_iter_truncate(iter, count); | |
2901 | 2899 | } |
2902 | 2900 | |
2903 | 2901 | io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); |
fs/ocfs2/file.c
... | ... | @@ -2241,7 +2241,6 @@ |
2241 | 2241 | int ret, direct_io, appending, rw_level, have_alloc_sem = 0; |
2242 | 2242 | int can_do_direct, has_refcount = 0; |
2243 | 2243 | ssize_t written = 0; |
2244 | - size_t ocount; /* original count */ | |
2245 | 2244 | size_t count; /* after file limit checks */ |
2246 | 2245 | loff_t old_size, *ppos = &iocb->ki_pos; |
2247 | 2246 | u32 old_clusters; |
... | ... | @@ -2253,6 +2252,9 @@ |
2253 | 2252 | int unaligned_dio = 0; |
2254 | 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 | 2258 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, |
2257 | 2259 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
2258 | 2260 | file->f_path.dentry->d_name.len, |
2259 | 2261 | |
2260 | 2262 | |
... | ... | @@ -2355,16 +2357,14 @@ |
2355 | 2357 | /* communicate with ocfs2_dio_end_io */ |
2356 | 2358 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
2357 | 2359 | |
2358 | - count = ocount = iov_length(iov, nr_segs); | |
2359 | 2360 | ret = generic_write_checks(file, ppos, &count, |
2360 | 2361 | S_ISBLK(inode->i_mode)); |
2361 | 2362 | if (ret) |
2362 | 2363 | goto out_dio; |
2363 | 2364 | |
2364 | - iov_iter_init(&from, WRITE, iov, nr_segs, count); | |
2365 | + iov_iter_truncate(&from, count); | |
2365 | 2366 | if (direct_io) { |
2366 | - written = generic_file_direct_write(iocb, &from, *ppos, | |
2367 | - count, ocount); | |
2367 | + written = generic_file_direct_write(iocb, &from, *ppos); | |
2368 | 2368 | if (written < 0) { |
2369 | 2369 | ret = written; |
2370 | 2370 | goto out_dio; |
fs/xfs/xfs_file.c
... | ... | @@ -626,7 +626,7 @@ |
626 | 626 | const struct iovec *iovp, |
627 | 627 | unsigned long nr_segs, |
628 | 628 | loff_t pos, |
629 | - size_t ocount) | |
629 | + size_t count) | |
630 | 630 | { |
631 | 631 | struct file *file = iocb->ki_filp; |
632 | 632 | struct address_space *mapping = file->f_mapping; |
... | ... | @@ -634,7 +634,6 @@ |
634 | 634 | struct xfs_inode *ip = XFS_I(inode); |
635 | 635 | struct xfs_mount *mp = ip->i_mount; |
636 | 636 | ssize_t ret = 0; |
637 | - size_t count = ocount; | |
638 | 637 | int unaligned_io = 0; |
639 | 638 | int iolock; |
640 | 639 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? |
... | ... | @@ -645,6 +644,8 @@ |
645 | 644 | if ((pos | count) & target->bt_logical_sectormask) |
646 | 645 | return -XFS_ERROR(EINVAL); |
647 | 646 | |
647 | + iov_iter_init(&from, WRITE, iovp, nr_segs, count); | |
648 | + | |
648 | 649 | /* "unaligned" here means not aligned to a filesystem block */ |
649 | 650 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) |
650 | 651 | unaligned_io = 1; |
... | ... | @@ -676,6 +677,7 @@ |
676 | 677 | ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock); |
677 | 678 | if (ret) |
678 | 679 | goto out; |
680 | + iov_iter_truncate(&from, count); | |
679 | 681 | |
680 | 682 | if (mapping->nrpages) { |
681 | 683 | ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, |
... | ... | @@ -697,8 +699,7 @@ |
697 | 699 | } |
698 | 700 | |
699 | 701 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); |
700 | - iov_iter_init(&from, WRITE, iovp, nr_segs, count); | |
701 | - ret = generic_file_direct_write(iocb, &from, pos, count, ocount); | |
702 | + ret = generic_file_direct_write(iocb, &from, pos); | |
702 | 703 | |
703 | 704 | out: |
704 | 705 | xfs_rw_iunlock(ip, iolock); |
include/linux/fs.h
... | ... | @@ -2407,8 +2407,7 @@ |
2407 | 2407 | extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); |
2408 | 2408 | extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long); |
2409 | 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 *, struct iov_iter *, | |
2411 | - loff_t, size_t, size_t); | |
2410 | +extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *, loff_t); | |
2412 | 2411 | extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); |
2413 | 2412 | extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); |
2414 | 2413 | extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); |
include/linux/uio.h
... | ... | @@ -82,6 +82,12 @@ |
82 | 82 | return i->count; |
83 | 83 | } |
84 | 84 | |
85 | +static inline void iov_iter_truncate(struct iov_iter *i, size_t count) | |
86 | +{ | |
87 | + if (i->count > count) | |
88 | + i->count = count; | |
89 | +} | |
90 | + | |
85 | 91 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); |
86 | 92 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); |
87 | 93 |
mm/filemap.c
... | ... | @@ -2345,8 +2345,7 @@ |
2345 | 2345 | EXPORT_SYMBOL(pagecache_write_end); |
2346 | 2346 | |
2347 | 2347 | ssize_t |
2348 | -generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, | |
2349 | - loff_t pos, size_t count, size_t ocount) | |
2348 | +generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos) | |
2350 | 2349 | { |
2351 | 2350 | struct file *file = iocb->ki_filp; |
2352 | 2351 | struct address_space *mapping = file->f_mapping; |
... | ... | @@ -2356,10 +2355,7 @@ |
2356 | 2355 | pgoff_t end; |
2357 | 2356 | struct iov_iter data; |
2358 | 2357 | |
2359 | - if (count != ocount) | |
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); | |
2358 | + write_len = iov_iter_count(from); | |
2363 | 2359 | end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT; |
2364 | 2360 | |
2365 | 2361 | written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1); |
... | ... | @@ -2568,7 +2564,6 @@ |
2568 | 2564 | { |
2569 | 2565 | struct file *file = iocb->ki_filp; |
2570 | 2566 | struct address_space * mapping = file->f_mapping; |
2571 | - size_t ocount; /* original count */ | |
2572 | 2567 | size_t count; /* after file limit checks */ |
2573 | 2568 | struct inode *inode = mapping->host; |
2574 | 2569 | loff_t pos = iocb->ki_pos; |
... | ... | @@ -2577,7 +2572,8 @@ |
2577 | 2572 | ssize_t status; |
2578 | 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 | 2578 | /* We can write back this queue in page reclaim */ |
2583 | 2579 | current->backing_dev_info = mapping->backing_dev_info; |
... | ... | @@ -2588,6 +2584,8 @@ |
2588 | 2584 | if (count == 0) |
2589 | 2585 | goto out; |
2590 | 2586 | |
2587 | + iov_iter_truncate(&from, count); | |
2588 | + | |
2591 | 2589 | err = file_remove_suid(file); |
2592 | 2590 | if (err) |
2593 | 2591 | goto out; |
2594 | 2592 | |
... | ... | @@ -2596,14 +2594,11 @@ |
2596 | 2594 | if (err) |
2597 | 2595 | goto out; |
2598 | 2596 | |
2599 | - iov_iter_init(&from, WRITE, iov, nr_segs, count); | |
2600 | - | |
2601 | 2597 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ |
2602 | 2598 | if (unlikely(file->f_flags & O_DIRECT)) { |
2603 | 2599 | loff_t endbyte; |
2604 | 2600 | |
2605 | - written = generic_file_direct_write(iocb, &from, pos, | |
2606 | - count, ocount); | |
2601 | + written = generic_file_direct_write(iocb, &from, pos); | |
2607 | 2602 | if (written < 0 || written == count) |
2608 | 2603 | goto out; |
2609 | 2604 |