diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-09 12:55:47 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:30:21 -0400 |
commit | 3309dd04cbcd2cdad168485af5cf3576b5051e49 (patch) | |
tree | 3e01f865306dee01b31f34c9e7e819a5f42a4087 /fs/fuse | |
parent | 90320251db0fe3d05f2b10686ec936c7d6ecd99a (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
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/file.c | 22 |
1 files changed, 7 insertions, 15 deletions
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 | } |
1216 | out: | 1211 | out: |
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); |