aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-04-09 12:55:47 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-04-11 22:30:21 -0400
commit3309dd04cbcd2cdad168485af5cf3576b5051e49 (patch)
tree3e01f865306dee01b31f34c9e7e819a5f42a4087
parent90320251db0fe3d05f2b10686ec936c7d6ecd99a (diff)
switch generic_write_checks() to iocb and iter
... returning -E... upon error and amount of data left in iter after (possible) truncation upon success. Note, that normal case gives a non-zero (positive) return value, so any tests for != 0 _must_ be updated. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Conflicts: fs/ext4/file.c
-rw-r--r--fs/9p/vfs_file.c26
-rw-r--r--fs/btrfs/file.c24
-rw-r--r--fs/ceph/file.c14
-rw-r--r--fs/cifs/file.c26
-rw-r--r--fs/ext4/file.c20
-rw-r--r--fs/fuse/file.c22
-rw-r--r--fs/ncpfs/file.c14
-rw-r--r--fs/nfs/direct.c25
-rw-r--r--fs/ntfs/file.c11
-rw-r--r--fs/ocfs2/file.c19
-rw-r--r--fs/udf/file.c10
-rw-r--r--fs/xfs/xfs_file.c8
-rw-r--r--include/linux/fs.h2
-rw-r--r--mm/filemap.c44
14 files changed, 99 insertions, 166 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index b5b020ace1b3..2a9dd37dc426 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -404,21 +404,16 @@ static ssize_t
404v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 404v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
405{ 405{
406 struct file *file = iocb->ki_filp; 406 struct file *file = iocb->ki_filp;
407 ssize_t retval = 0; 407 ssize_t retval;
408 loff_t origin = iocb->ki_pos; 408 loff_t origin;
409 size_t count = iov_iter_count(from);
410 int err = 0; 409 int err = 0;
411 410
412 retval = generic_write_checks(file, &origin, &count); 411 retval = generic_write_checks(iocb, from);
413 if (retval) 412 if (retval <= 0)
414 return retval; 413 return retval;
415 414
416 iov_iter_truncate(from, count); 415 origin = iocb->ki_pos;
417 416 retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err);
418 if (!count)
419 return 0;
420
421 retval = p9_client_write(file->private_data, origin, from, &err);
422 if (retval > 0) { 417 if (retval > 0) {
423 struct inode *inode = file_inode(file); 418 struct inode *inode = file_inode(file);
424 loff_t i_size; 419 loff_t i_size;
@@ -428,12 +423,11 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
428 if (inode->i_mapping && inode->i_mapping->nrpages) 423 if (inode->i_mapping && inode->i_mapping->nrpages)
429 invalidate_inode_pages2_range(inode->i_mapping, 424 invalidate_inode_pages2_range(inode->i_mapping,
430 pg_start, pg_end); 425 pg_start, pg_end);
431 origin += retval; 426 iocb->ki_pos += retval;
432 i_size = i_size_read(inode); 427 i_size = i_size_read(inode);
433 iocb->ki_pos = origin; 428 if (iocb->ki_pos > i_size) {
434 if (origin > i_size) { 429 inode_add_bytes(inode, iocb->ki_pos - i_size);
435 inode_add_bytes(inode, origin - i_size); 430 i_size_write(inode, iocb->ki_pos);
436 i_size_write(inode, origin);
437 } 431 }
438 return retval; 432 return retval;
439 } 433 }
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 691a84a81e09..c64d11c41eeb 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1739,27 +1739,19 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
1739 u64 start_pos; 1739 u64 start_pos;
1740 u64 end_pos; 1740 u64 end_pos;
1741 ssize_t num_written = 0; 1741 ssize_t num_written = 0;
1742 ssize_t err = 0;
1743 size_t count = iov_iter_count(from);
1744 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); 1742 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
1745 loff_t pos = iocb->ki_pos; 1743 ssize_t err;
1744 loff_t pos;
1745 size_t count;
1746 1746
1747 mutex_lock(&inode->i_mutex); 1747 mutex_lock(&inode->i_mutex);
1748 1748 err = generic_write_checks(iocb, from);
1749 current->backing_dev_info = inode_to_bdi(inode); 1749 if (err <= 0) {
1750 err = generic_write_checks(file, &pos, &count);
1751 if (err) {
1752 mutex_unlock(&inode->i_mutex); 1750 mutex_unlock(&inode->i_mutex);
1753 goto out; 1751 return err;
1754 }
1755
1756 if (count == 0) {
1757 mutex_unlock(&inode->i_mutex);
1758 goto out;
1759 } 1752 }
1760 1753
1761 iov_iter_truncate(from, count); 1754 current->backing_dev_info = inode_to_bdi(inode);
1762
1763 err = file_remove_suid(file); 1755 err = file_remove_suid(file);
1764 if (err) { 1756 if (err) {
1765 mutex_unlock(&inode->i_mutex); 1757 mutex_unlock(&inode->i_mutex);
@@ -1786,6 +1778,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
1786 */ 1778 */
1787 update_time_for_write(inode); 1779 update_time_for_write(inode);
1788 1780
1781 pos = iocb->ki_pos;
1782 count = iov_iter_count(from);
1789 start_pos = round_down(pos, root->sectorsize); 1783 start_pos = round_down(pos, root->sectorsize);
1790 if (start_pos > i_size_read(inode)) { 1784 if (start_pos > i_size_read(inode)) {
1791 /* Expand hole size to cover write data, preventing empty gap */ 1785 /* Expand hole size to cover write data, preventing empty gap */
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 761841903160..3f0b9339d823 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -941,9 +941,9 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
941 struct ceph_inode_info *ci = ceph_inode(inode); 941 struct ceph_inode_info *ci = ceph_inode(inode);
942 struct ceph_osd_client *osdc = 942 struct ceph_osd_client *osdc =
943 &ceph_sb_to_client(inode->i_sb)->client->osdc; 943 &ceph_sb_to_client(inode->i_sb)->client->osdc;
944 ssize_t count = iov_iter_count(from), written = 0; 944 ssize_t count, written = 0;
945 int err, want, got; 945 int err, want, got;
946 loff_t pos = iocb->ki_pos; 946 loff_t pos;
947 947
948 if (ceph_snap(inode) != CEPH_NOSNAP) 948 if (ceph_snap(inode) != CEPH_NOSNAP)
949 return -EROFS; 949 return -EROFS;
@@ -953,14 +953,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
953 /* We can write back this queue in page reclaim */ 953 /* We can write back this queue in page reclaim */
954 current->backing_dev_info = inode_to_bdi(inode); 954 current->backing_dev_info = inode_to_bdi(inode);
955 955
956 err = generic_write_checks(file, &pos, &count); 956 err = generic_write_checks(iocb, from);
957 if (err) 957 if (err <= 0)
958 goto out;
959
960 if (count == 0)
961 goto out; 958 goto out;
962 iov_iter_truncate(from, count);
963 959
960 pos = iocb->ki_pos;
961 count = iov_iter_count(from);
964 err = file_remove_suid(file); 962 err = file_remove_suid(file);
965 if (err) 963 if (err)
966 goto out; 964 goto out;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 4202e74b2db5..ca2bc5406306 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2563,7 +2563,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2563ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) 2563ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
2564{ 2564{
2565 struct file *file = iocb->ki_filp; 2565 struct file *file = iocb->ki_filp;
2566 size_t len;
2567 ssize_t total_written = 0; 2566 ssize_t total_written = 0;
2568 struct cifsFileInfo *open_file; 2567 struct cifsFileInfo *open_file;
2569 struct cifs_tcon *tcon; 2568 struct cifs_tcon *tcon;
@@ -2579,16 +2578,10 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
2579 * write request. 2578 * write request.
2580 */ 2579 */
2581 2580
2582 len = iov_iter_count(from); 2581 rc = generic_write_checks(iocb, from);
2583 rc = generic_write_checks(file, &iocb->ki_pos, &len); 2582 if (rc <= 0)
2584 if (rc)
2585 return rc; 2583 return rc;
2586 2584
2587 if (!len)
2588 return 0;
2589
2590 iov_iter_truncate(from, len);
2591
2592 INIT_LIST_HEAD(&wdata_list); 2585 INIT_LIST_HEAD(&wdata_list);
2593 cifs_sb = CIFS_FILE_SB(file); 2586 cifs_sb = CIFS_FILE_SB(file);
2594 open_file = file->private_data; 2587 open_file = file->private_data;
@@ -2599,8 +2592,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
2599 2592
2600 memcpy(&saved_from, from, sizeof(struct iov_iter)); 2593 memcpy(&saved_from, from, sizeof(struct iov_iter));
2601 2594
2602 rc = cifs_write_from_iter(iocb->ki_pos, len, from, open_file, cifs_sb, 2595 rc = cifs_write_from_iter(iocb->ki_pos, iov_iter_count(from), from,
2603 &wdata_list); 2596 open_file, cifs_sb, &wdata_list);
2604 2597
2605 /* 2598 /*
2606 * If at least one write was successfully sent, then discard any rc 2599 * If at least one write was successfully sent, then discard any rc
@@ -2674,7 +2667,6 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
2674 struct cifsInodeInfo *cinode = CIFS_I(inode); 2667 struct cifsInodeInfo *cinode = CIFS_I(inode);
2675 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; 2668 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
2676 ssize_t rc; 2669 ssize_t rc;
2677 size_t count;
2678 2670
2679 /* 2671 /*
2680 * We need to hold the sem to be sure nobody modifies lock list 2672 * We need to hold the sem to be sure nobody modifies lock list
@@ -2683,16 +2675,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
2683 down_read(&cinode->lock_sem); 2675 down_read(&cinode->lock_sem);
2684 mutex_lock(&inode->i_mutex); 2676 mutex_lock(&inode->i_mutex);
2685 2677
2686 count = iov_iter_count(from); 2678 rc = generic_write_checks(iocb, from);
2687 rc = generic_write_checks(file, &iocb->ki_pos, &count); 2679 if (rc <= 0)
2688 if (rc)
2689 goto out; 2680 goto out;
2690 2681
2691 if (count == 0)
2692 goto out;
2693
2694 iov_iter_truncate(from, count);
2695
2696 if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), 2682 if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
2697 server->vals->exclusive_lock_type, NULL, 2683 server->vals->exclusive_lock_type, NULL,
2698 CIFS_WRITE_OP)) 2684 CIFS_WRITE_OP))
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 42b1fa33a17a..c10785f10d1d 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -97,9 +97,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
97 struct blk_plug plug; 97 struct blk_plug plug;
98 int o_direct = io_is_direct(file); 98 int o_direct = io_is_direct(file);
99 int overwrite = 0; 99 int overwrite = 0;
100 size_t length = iov_iter_count(from);
101 ssize_t ret; 100 ssize_t ret;
102 loff_t pos;
103 101
104 /* 102 /*
105 * Unaligned direct AIO must be serialized; see comment above 103 * Unaligned direct AIO must be serialized; see comment above
@@ -116,16 +114,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
116 } 114 }
117 115
118 mutex_lock(&inode->i_mutex); 116 mutex_lock(&inode->i_mutex);
119 ret = generic_write_checks(file, &iocb->ki_pos, &length); 117 ret = generic_write_checks(iocb, from);
120 if (ret) 118 if (ret <= 0)
121 goto out; 119 goto out;
122 120
123 if (length == 0)
124 goto out;
125
126 iov_iter_truncate(from, length);
127 pos = iocb->ki_pos;
128
129 /* 121 /*
130 * If we have encountered a bitmap-format file, the size limit 122 * If we have encountered a bitmap-format file, the size limit
131 * is smaller than s_maxbytes, which is for extent-mapped files. 123 * is smaller than s_maxbytes, which is for extent-mapped files.
@@ -133,19 +125,19 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
133 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { 125 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
134 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 126 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
135 127
136 if (pos >= sbi->s_bitmap_maxbytes) { 128 if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) {
137 ret = -EFBIG; 129 ret = -EFBIG;
138 goto out; 130 goto out;
139 } 131 }
140 iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos); 132 iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos);
141 } 133 }
142 134
143 iocb->private = &overwrite; 135 iocb->private = &overwrite;
144 if (o_direct) { 136 if (o_direct) {
145 length = iov_iter_count(from); 137 size_t length = iov_iter_count(from);
138 loff_t pos = iocb->ki_pos;
146 blk_start_plug(&plug); 139 blk_start_plug(&plug);
147 140
148
149 /* check whether we do a DIO overwrite or not */ 141 /* check whether we do a DIO overwrite or not */
150 if (ext4_should_dioread_nolock(inode) && !aio_mutex && 142 if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
151 !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { 143 !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 8c15d0a077e8..b86c8e08399a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1145,13 +1145,11 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1145{ 1145{
1146 struct file *file = iocb->ki_filp; 1146 struct file *file = iocb->ki_filp;
1147 struct address_space *mapping = file->f_mapping; 1147 struct address_space *mapping = file->f_mapping;
1148 size_t count = iov_iter_count(from);
1149 ssize_t written = 0; 1148 ssize_t written = 0;
1150 ssize_t written_buffered = 0; 1149 ssize_t written_buffered = 0;
1151 struct inode *inode = mapping->host; 1150 struct inode *inode = mapping->host;
1152 ssize_t err; 1151 ssize_t err;
1153 loff_t endbyte = 0; 1152 loff_t endbyte = 0;
1154 loff_t pos = iocb->ki_pos;
1155 1153
1156 if (get_fuse_conn(inode)->writeback_cache) { 1154 if (get_fuse_conn(inode)->writeback_cache) {
1157 /* Update size (EOF optimization) and mode (SUID clearing) */ 1155 /* Update size (EOF optimization) and mode (SUID clearing) */
@@ -1167,14 +1165,10 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1167 /* We can write back this queue in page reclaim */ 1165 /* We can write back this queue in page reclaim */
1168 current->backing_dev_info = inode_to_bdi(inode); 1166 current->backing_dev_info = inode_to_bdi(inode);
1169 1167
1170 err = generic_write_checks(file, &pos, &count); 1168 err = generic_write_checks(iocb, from);
1171 if (err) 1169 if (err <= 0)
1172 goto out;
1173
1174 if (count == 0)
1175 goto out; 1170 goto out;
1176 1171
1177 iov_iter_truncate(from, count);
1178 err = file_remove_suid(file); 1172 err = file_remove_suid(file);
1179 if (err) 1173 if (err)
1180 goto out; 1174 goto out;
@@ -1184,6 +1178,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1184 goto out; 1178 goto out;
1185 1179
1186 if (file->f_flags & O_DIRECT) { 1180 if (file->f_flags & O_DIRECT) {
1181 loff_t pos = iocb->ki_pos;
1187 written = generic_file_direct_write(iocb, from, pos); 1182 written = generic_file_direct_write(iocb, from, pos);
1188 if (written < 0 || !iov_iter_count(from)) 1183 if (written < 0 || !iov_iter_count(from))
1189 goto out; 1184 goto out;
@@ -1209,9 +1204,9 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1209 written += written_buffered; 1204 written += written_buffered;
1210 iocb->ki_pos = pos + written_buffered; 1205 iocb->ki_pos = pos + written_buffered;
1211 } else { 1206 } else {
1212 written = fuse_perform_write(file, mapping, from, pos); 1207 written = fuse_perform_write(file, mapping, from, iocb->ki_pos);
1213 if (written >= 0) 1208 if (written >= 0)
1214 iocb->ki_pos = pos + written; 1209 iocb->ki_pos += written;
1215 } 1210 }
1216out: 1211out:
1217 current->backing_dev_info = NULL; 1212 current->backing_dev_info = NULL;
@@ -1412,7 +1407,6 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
1412 struct file *file = iocb->ki_filp; 1407 struct file *file = iocb->ki_filp;
1413 struct inode *inode = file_inode(file); 1408 struct inode *inode = file_inode(file);
1414 struct fuse_io_priv io = { .async = 0, .file = file }; 1409 struct fuse_io_priv io = { .async = 0, .file = file };
1415 size_t count = iov_iter_count(from);
1416 ssize_t res; 1410 ssize_t res;
1417 1411
1418 if (is_bad_inode(inode)) 1412 if (is_bad_inode(inode))
@@ -1420,11 +1414,9 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
1420 1414
1421 /* Don't allow parallel writes to the same file */ 1415 /* Don't allow parallel writes to the same file */
1422 mutex_lock(&inode->i_mutex); 1416 mutex_lock(&inode->i_mutex);
1423 res = generic_write_checks(file, &iocb->ki_pos, &count); 1417 res = generic_write_checks(iocb, from);
1424 if (!res) { 1418 if (res > 0)
1425 iov_iter_truncate(from, count);
1426 res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE); 1419 res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE);
1427 }
1428 fuse_invalidate_attr(inode); 1420 fuse_invalidate_attr(inode);
1429 if (res > 0) 1421 if (res > 0)
1430 fuse_write_update_size(inode, iocb->ki_pos); 1422 fuse_write_update_size(inode, iocb->ki_pos);
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index ab6363b16556..011324ce9df2 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -170,20 +170,15 @@ ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
170 struct file *file = iocb->ki_filp; 170 struct file *file = iocb->ki_filp;
171 struct inode *inode = file_inode(file); 171 struct inode *inode = file_inode(file);
172 size_t already_written = 0; 172 size_t already_written = 0;
173 loff_t pos = iocb->ki_pos;
174 size_t count = iov_iter_count(from);
175 size_t bufsize; 173 size_t bufsize;
176 int errno; 174 int errno;
177 void *bouncebuffer; 175 void *bouncebuffer;
176 off_t pos;
178 177
179 ncp_dbg(1, "enter %pD2\n", file); 178 ncp_dbg(1, "enter %pD2\n", file);
180 errno = generic_write_checks(file, &pos, &count); 179 errno = generic_write_checks(iocb, from);
181 if (errno) 180 if (errno <= 0)
182 return errno; 181 return errno;
183 iov_iter_truncate(from, count);
184
185 if (!count)
186 return 0;
187 182
188 errno = ncp_make_open(inode, O_WRONLY); 183 errno = ncp_make_open(inode, O_WRONLY);
189 if (errno) { 184 if (errno) {
@@ -201,10 +196,11 @@ ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
201 errno = -EIO; /* -ENOMEM */ 196 errno = -EIO; /* -ENOMEM */
202 goto outrel; 197 goto outrel;
203 } 198 }
199 pos = iocb->ki_pos;
204 while (iov_iter_count(from)) { 200 while (iov_iter_count(from)) {
205 int written_this_time; 201 int written_this_time;
206 size_t to_write = min_t(size_t, 202 size_t to_write = min_t(size_t,
207 bufsize - ((off_t)pos % bufsize), 203 bufsize - (pos % bufsize),
208 iov_iter_count(from)); 204 iov_iter_count(from));
209 205
210 if (copy_from_iter(bouncebuffer, to_write, from) != to_write) { 206 if (copy_from_iter(bouncebuffer, to_write, from) != to_write) {
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 5ddd77acb3f7..9634189b8545 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -969,24 +969,19 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
969 struct nfs_direct_req *dreq; 969 struct nfs_direct_req *dreq;
970 struct nfs_lock_context *l_ctx; 970 struct nfs_lock_context *l_ctx;
971 loff_t end; 971 loff_t end;
972 size_t count = iov_iter_count(iter);
973 end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
974
975 nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
976 972
977 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", 973 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
978 file, count, (long long) pos); 974 file, iov_iter_count(iter), (long long) iocb->ki_pos);
979 975
980 result = generic_write_checks(file, &pos, &count); 976 result = generic_write_checks(iocb, iter);
981 if (result) 977 if (result <= 0)
982 goto out; 978 goto out;
983 979
984 result = -EINVAL; 980 nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES,
985 if ((ssize_t) count < 0) 981 iov_iter_count(iter));
986 goto out; 982
987 result = 0; 983 pos = iocb->ki_pos;
988 if (!count) 984 end = (pos + iov_iter_count(iter) - 1) >> PAGE_CACHE_SHIFT;
989 goto out;
990 985
991 mutex_lock(&inode->i_mutex); 986 mutex_lock(&inode->i_mutex);
992 987
@@ -1001,7 +996,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
1001 goto out_unlock; 996 goto out_unlock;
1002 } 997 }
1003 998
1004 task_io_account_write(count); 999 task_io_account_write(iov_iter_count(iter));
1005 1000
1006 result = -ENOMEM; 1001 result = -ENOMEM;
1007 dreq = nfs_direct_req_alloc(); 1002 dreq = nfs_direct_req_alloc();
@@ -1009,7 +1004,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
1009 goto out_unlock; 1004 goto out_unlock;
1010 1005
1011 dreq->inode = inode; 1006 dreq->inode = inode;
1012 dreq->bytes_left = count; 1007 dreq->bytes_left = iov_iter_count(iter);
1013 dreq->io_start = pos; 1008 dreq->io_start = pos;
1014 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 1009 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
1015 l_ctx = nfs_get_lock_context(dreq->ctx); 1010 l_ctx = nfs_get_lock_context(dreq->ctx);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index cec4ec3c1ede..7bb487e663b4 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -339,17 +339,14 @@ static ssize_t ntfs_prepare_file_for_write(struct kiocb *iocb,
339 struct inode *vi = file_inode(file); 339 struct inode *vi = file_inode(file);
340 ntfs_inode *base_ni, *ni = NTFS_I(vi); 340 ntfs_inode *base_ni, *ni = NTFS_I(vi);
341 ntfs_volume *vol = ni->vol; 341 ntfs_volume *vol = ni->vol;
342 size_t count = iov_iter_count(from);
343 342
344 ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, pos " 343 ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, pos "
345 "0x%llx, count 0x%zx.", vi->i_ino, 344 "0x%llx, count 0x%zx.", vi->i_ino,
346 (unsigned)le32_to_cpu(ni->type), 345 (unsigned)le32_to_cpu(ni->type),
347 (unsigned long long)iocb->ki_pos, count); 346 (unsigned long long)iocb->ki_pos,
348 err = generic_write_checks(file, &iocb->ki_pos, &count); 347 iov_iter_count(from));
349 if (unlikely(err)) 348 err = generic_write_checks(iocb, from);
350 goto out; 349 if (unlikely(err <= 0))
351 iov_iter_truncate(from, count);
352 if (count == 0)
353 goto out; 350 goto out;
354 /* 351 /*
355 * All checks have passed. Before we start doing any writing we want 352 * All checks have passed. Before we start doing any writing we want
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index fc53ff065364..b93919f50f0f 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2250,9 +2250,10 @@ out:
2250static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, 2250static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
2251 struct iov_iter *from) 2251 struct iov_iter *from)
2252{ 2252{
2253 int ret, direct_io, appending, rw_level, have_alloc_sem = 0; 2253 int direct_io, appending, rw_level, have_alloc_sem = 0;
2254 int can_do_direct, has_refcount = 0; 2254 int can_do_direct, has_refcount = 0;
2255 ssize_t written = 0; 2255 ssize_t written = 0;
2256 ssize_t ret;
2256 size_t count = iov_iter_count(from), orig_count; 2257 size_t count = iov_iter_count(from), orig_count;
2257 loff_t old_size; 2258 loff_t old_size;
2258 u32 old_clusters; 2259 u32 old_clusters;
@@ -2319,13 +2320,14 @@ relock:
2319 ocfs2_inode_unlock(inode, 1); 2320 ocfs2_inode_unlock(inode, 1);
2320 } 2321 }
2321 2322
2322 orig_count = count; 2323 orig_count = iov_iter_count(from);
2323 ret = generic_write_checks(file, &iocb->ki_pos, &count); 2324 ret = generic_write_checks(iocb, from);
2324 if (ret < 0) { 2325 if (ret <= 0) {
2325 mlog_errno(ret); 2326 if (ret)
2327 mlog_errno(ret);
2326 goto out; 2328 goto out;
2327 } 2329 }
2328 iov_iter_truncate(from, count); 2330 count = ret;
2329 2331
2330 can_do_direct = direct_io; 2332 can_do_direct = direct_io;
2331 ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending, 2333 ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending,
@@ -2349,7 +2351,7 @@ relock:
2349 rw_level = -1; 2351 rw_level = -1;
2350 2352
2351 direct_io = 0; 2353 direct_io = 0;
2352 iov_iter_reexpand(from, count = orig_count); 2354 iov_iter_reexpand(from, orig_count);
2353 goto relock; 2355 goto relock;
2354 } 2356 }
2355 2357
@@ -2377,7 +2379,7 @@ relock:
2377 loff_t endbyte; 2379 loff_t endbyte;
2378 ssize_t written_buffered; 2380 ssize_t written_buffered;
2379 written = generic_file_direct_write(iocb, from, iocb->ki_pos); 2381 written = generic_file_direct_write(iocb, from, iocb->ki_pos);
2380 if (written < 0 || written == count) { 2382 if (written < 0 || !iov_iter_count(from)) {
2381 ret = written; 2383 ret = written;
2382 goto out_dio; 2384 goto out_dio;
2383 } 2385 }
@@ -2385,7 +2387,6 @@ relock:
2385 /* 2387 /*
2386 * for completing the rest of the request. 2388 * for completing the rest of the request.
2387 */ 2389 */
2388 count -= written;
2389 written_buffered = generic_perform_write(file, from, iocb->ki_pos); 2390 written_buffered = generic_perform_write(file, from, iocb->ki_pos);
2390 /* 2391 /*
2391 * If generic_file_buffered_write() returned a synchronous error 2392 * If generic_file_buffered_write() returned a synchronous error
diff --git a/fs/udf/file.c b/fs/udf/file.c
index ccab8b78e363..3de2edafff73 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -120,21 +120,15 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
120 ssize_t retval; 120 ssize_t retval;
121 struct file *file = iocb->ki_filp; 121 struct file *file = iocb->ki_filp;
122 struct inode *inode = file_inode(file); 122 struct inode *inode = file_inode(file);
123 size_t count = iov_iter_count(from);
124 struct udf_inode_info *iinfo = UDF_I(inode); 123 struct udf_inode_info *iinfo = UDF_I(inode);
125 int err; 124 int err;
126 125
127 mutex_lock(&inode->i_mutex); 126 mutex_lock(&inode->i_mutex);
128 127
129 retval = generic_write_checks(file, &iocb->ki_pos, &count); 128 retval = generic_write_checks(iocb, from);
130 if (retval) 129 if (retval <= 0)
131 goto out; 130 goto out;
132 131
133 if (count == 0)
134 goto out;
135
136 iov_iter_truncate(from, count);
137
138 down_write(&iinfo->i_data_sem); 132 down_write(&iinfo->i_data_sem);
139 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 133 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
140 loff_t end = iocb->ki_pos + iov_iter_count(from); 134 loff_t end = iocb->ki_pos + iov_iter_count(from);
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index ebde43e15dd9..28d157807b42 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -551,12 +551,12 @@ xfs_file_aio_write_checks(
551 struct file *file = iocb->ki_filp; 551 struct file *file = iocb->ki_filp;
552 struct inode *inode = file->f_mapping->host; 552 struct inode *inode = file->f_mapping->host;
553 struct xfs_inode *ip = XFS_I(inode); 553 struct xfs_inode *ip = XFS_I(inode);
554 int error = 0; 554 ssize_t error = 0;
555 size_t count = iov_iter_count(from); 555 size_t count = iov_iter_count(from);
556 556
557restart: 557restart:
558 error = generic_write_checks(file, &iocb->ki_pos, &count); 558 error = generic_write_checks(iocb, from);
559 if (error) 559 if (error <= 0)
560 return error; 560 return error;
561 561
562 error = xfs_break_layouts(inode, iolock); 562 error = xfs_break_layouts(inode, iolock);
@@ -577,13 +577,13 @@ restart:
577 xfs_rw_iunlock(ip, *iolock); 577 xfs_rw_iunlock(ip, *iolock);
578 *iolock = XFS_IOLOCK_EXCL; 578 *iolock = XFS_IOLOCK_EXCL;
579 xfs_rw_ilock(ip, *iolock); 579 xfs_rw_ilock(ip, *iolock);
580 iov_iter_reexpand(from, count);
580 goto restart; 581 goto restart;
581 } 582 }
582 error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero); 583 error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero);
583 if (error) 584 if (error)
584 return error; 585 return error;
585 } 586 }
586 iov_iter_truncate(from, count);
587 587
588 /* 588 /*
589 * Updating the timestamps will grab the ilock again from 589 * Updating the timestamps will grab the ilock again from
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c7b21db7782f..b4aa400ac723 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2566,7 +2566,7 @@ extern int sb_min_blocksize(struct super_block *, int);
2566 2566
2567extern int generic_file_mmap(struct file *, struct vm_area_struct *); 2567extern int generic_file_mmap(struct file *, struct vm_area_struct *);
2568extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); 2568extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
2569int generic_write_checks(struct file *file, loff_t *pos, size_t *count); 2569extern ssize_t generic_write_checks(struct kiocb *, struct iov_iter *);
2570extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); 2570extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
2571extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); 2571extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *);
2572extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); 2572extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *);
diff --git a/mm/filemap.c b/mm/filemap.c
index dfc573c6ec25..243997a26e7c 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2260,36 +2260,38 @@ EXPORT_SYMBOL(read_cache_page_gfp);
2260 * Returns appropriate error code that caller should return or 2260 * Returns appropriate error code that caller should return or
2261 * zero in case that write should be allowed. 2261 * zero in case that write should be allowed.
2262 */ 2262 */
2263inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count) 2263inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from)
2264{ 2264{
2265 struct file *file = iocb->ki_filp;
2265 struct inode *inode = file->f_mapping->host; 2266 struct inode *inode = file->f_mapping->host;
2266 unsigned long limit = rlimit(RLIMIT_FSIZE); 2267 unsigned long limit = rlimit(RLIMIT_FSIZE);
2268 loff_t pos;
2267 2269
2268 if (unlikely(*pos < 0)) 2270 if (!iov_iter_count(from))
2269 return -EINVAL; 2271 return 0;
2270 2272
2271 /* FIXME: this is for backwards compatibility with 2.4 */ 2273 /* FIXME: this is for backwards compatibility with 2.4 */
2272 if (file->f_flags & O_APPEND) 2274 if (file->f_flags & O_APPEND)
2273 *pos = i_size_read(inode); 2275 iocb->ki_pos = i_size_read(inode);
2276
2277 pos = iocb->ki_pos;
2274 2278
2275 if (limit != RLIM_INFINITY) { 2279 if (limit != RLIM_INFINITY) {
2276 if (*pos >= limit) { 2280 if (iocb->ki_pos >= limit) {
2277 send_sig(SIGXFSZ, current, 0); 2281 send_sig(SIGXFSZ, current, 0);
2278 return -EFBIG; 2282 return -EFBIG;
2279 } 2283 }
2280 if (*count > limit - (typeof(limit))*pos) 2284 iov_iter_truncate(from, limit - (unsigned long)pos);
2281 *count = limit - (typeof(limit))*pos;
2282 } 2285 }
2283 2286
2284 /* 2287 /*
2285 * LFS rule 2288 * LFS rule
2286 */ 2289 */
2287 if (unlikely(*pos + *count > MAX_NON_LFS && 2290 if (unlikely(pos + iov_iter_count(from) > MAX_NON_LFS &&
2288 !(file->f_flags & O_LARGEFILE))) { 2291 !(file->f_flags & O_LARGEFILE))) {
2289 if (*pos >= MAX_NON_LFS) 2292 if (pos >= MAX_NON_LFS)
2290 return -EFBIG; 2293 return -EFBIG;
2291 if (*count > MAX_NON_LFS - (unsigned long)*pos) 2294 iov_iter_truncate(from, MAX_NON_LFS - (unsigned long)pos);
2292 *count = MAX_NON_LFS - (unsigned long)*pos;
2293 } 2295 }
2294 2296
2295 /* 2297 /*
@@ -2299,16 +2301,11 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count)
2299 * exceeded without writing data we send a signal and return EFBIG. 2301 * exceeded without writing data we send a signal and return EFBIG.
2300 * Linus frestrict idea will clean these up nicely.. 2302 * Linus frestrict idea will clean these up nicely..
2301 */ 2303 */
2302 if (unlikely(*pos >= inode->i_sb->s_maxbytes)) { 2304 if (unlikely(pos >= inode->i_sb->s_maxbytes))
2303 if (*count || *pos > inode->i_sb->s_maxbytes) { 2305 return -EFBIG;
2304 return -EFBIG;
2305 }
2306 /* zero-length writes at ->s_maxbytes are OK */
2307 }
2308 2306
2309 if (unlikely(*pos + *count > inode->i_sb->s_maxbytes)) 2307 iov_iter_truncate(from, inode->i_sb->s_maxbytes - pos);
2310 *count = inode->i_sb->s_maxbytes - *pos; 2308 return iov_iter_count(from);
2311 return 0;
2312} 2309}
2313EXPORT_SYMBOL(generic_write_checks); 2310EXPORT_SYMBOL(generic_write_checks);
2314 2311
@@ -2618,14 +2615,11 @@ ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
2618 struct file *file = iocb->ki_filp; 2615 struct file *file = iocb->ki_filp;
2619 struct inode *inode = file->f_mapping->host; 2616 struct inode *inode = file->f_mapping->host;
2620 ssize_t ret; 2617 ssize_t ret;
2621 size_t count = iov_iter_count(from);
2622 2618
2623 mutex_lock(&inode->i_mutex); 2619 mutex_lock(&inode->i_mutex);
2624 ret = generic_write_checks(file, &iocb->ki_pos, &count); 2620 ret = generic_write_checks(iocb, from);
2625 if (!ret && count) { 2621 if (ret > 0)
2626 iov_iter_truncate(from, count);
2627 ret = __generic_file_write_iter(iocb, from); 2622 ret = __generic_file_write_iter(iocb, from);
2628 }
2629 mutex_unlock(&inode->i_mutex); 2623 mutex_unlock(&inode->i_mutex);
2630 2624
2631 if (ret > 0) { 2625 if (ret > 0) {