diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 13:30:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 13:30:18 -0400 |
commit | 16b9057804c02e2d351e9c8f606e909b43cbd9e7 (patch) | |
tree | a3ac6e1d9d57a8abf4267e5ead3f2de1309335eb /fs/fuse | |
parent | 5c02c392cd2320e8d612376d6b72b6548a680923 (diff) | |
parent | c2338f2dc7c1e9f6202f370c64ffd7f44f3d4b51 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"This the bunch that sat in -next + lock_parent() fix. This is the
minimal set; there's more pending stuff.
In particular, I really hope to get acct.c fixes merged this cycle -
we need that to deal sanely with delayed-mntput stuff. In the next
pile, hopefully - that series is fairly short and localized
(kernel/acct.c, fs/super.c and fs/namespace.c). In this pile: more
iov_iter work. Most of prereqs for ->splice_write with sane locking
order are there and Kent's dio rewrite would also fit nicely on top of
this pile"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (70 commits)
lock_parent: don't step on stale ->d_parent of all-but-freed one
kill generic_file_splice_write()
ceph: switch to iter_file_splice_write()
shmem: switch to iter_file_splice_write()
nfs: switch to iter_splice_write_file()
fs/splice.c: remove unneeded exports
ocfs2: switch to iter_file_splice_write()
->splice_write() via ->write_iter()
bio_vec-backed iov_iter
optimize copy_page_{to,from}_iter()
bury generic_file_aio_{read,write}
lustre: get rid of messing with iovecs
ceph: switch to ->write_iter()
ceph_sync_direct_write: stop poking into iov_iter guts
ceph_sync_read: stop poking into iov_iter guts
new helper: copy_page_from_iter()
fuse: switch to ->write_iter()
btrfs: switch to ->write_iter()
ocfs2: switch to ->write_iter()
xfs: switch to ->write_iter()
...
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/cuse.c | 8 | ||||
-rw-r--r-- | fs/fuse/file.c | 154 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 5 |
3 files changed, 69 insertions, 98 deletions
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 13b691a8a7d2..966ace8b243f 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c | |||
@@ -94,8 +94,10 @@ static ssize_t cuse_read(struct file *file, char __user *buf, size_t count, | |||
94 | loff_t pos = 0; | 94 | loff_t pos = 0; |
95 | struct iovec iov = { .iov_base = buf, .iov_len = count }; | 95 | struct iovec iov = { .iov_base = buf, .iov_len = count }; |
96 | struct fuse_io_priv io = { .async = 0, .file = file }; | 96 | struct fuse_io_priv io = { .async = 0, .file = file }; |
97 | struct iov_iter ii; | ||
98 | iov_iter_init(&ii, READ, &iov, 1, count); | ||
97 | 99 | ||
98 | return fuse_direct_io(&io, &iov, 1, count, &pos, FUSE_DIO_CUSE); | 100 | return fuse_direct_io(&io, &ii, &pos, FUSE_DIO_CUSE); |
99 | } | 101 | } |
100 | 102 | ||
101 | static ssize_t cuse_write(struct file *file, const char __user *buf, | 103 | static ssize_t cuse_write(struct file *file, const char __user *buf, |
@@ -104,12 +106,14 @@ static ssize_t cuse_write(struct file *file, const char __user *buf, | |||
104 | loff_t pos = 0; | 106 | loff_t pos = 0; |
105 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; | 107 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; |
106 | struct fuse_io_priv io = { .async = 0, .file = file }; | 108 | struct fuse_io_priv io = { .async = 0, .file = file }; |
109 | struct iov_iter ii; | ||
110 | iov_iter_init(&ii, WRITE, &iov, 1, count); | ||
107 | 111 | ||
108 | /* | 112 | /* |
109 | * No locking or generic_write_checks(), the server is | 113 | * No locking or generic_write_checks(), the server is |
110 | * responsible for locking and sanity checks. | 114 | * responsible for locking and sanity checks. |
111 | */ | 115 | */ |
112 | return fuse_direct_io(&io, &iov, 1, count, &pos, | 116 | return fuse_direct_io(&io, &ii, &pos, |
113 | FUSE_DIO_WRITE | FUSE_DIO_CUSE); | 117 | FUSE_DIO_WRITE | FUSE_DIO_CUSE); |
114 | } | 118 | } |
115 | 119 | ||
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 903cbc9cd6bd..6e16dad13e9b 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -933,8 +933,7 @@ out: | |||
933 | return err; | 933 | return err; |
934 | } | 934 | } |
935 | 935 | ||
936 | static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | 936 | static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to) |
937 | unsigned long nr_segs, loff_t pos) | ||
938 | { | 937 | { |
939 | struct inode *inode = iocb->ki_filp->f_mapping->host; | 938 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
940 | struct fuse_conn *fc = get_fuse_conn(inode); | 939 | struct fuse_conn *fc = get_fuse_conn(inode); |
@@ -945,14 +944,14 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
945 | * i_size is up to date). | 944 | * i_size is up to date). |
946 | */ | 945 | */ |
947 | if (fc->auto_inval_data || | 946 | if (fc->auto_inval_data || |
948 | (pos + iov_length(iov, nr_segs) > i_size_read(inode))) { | 947 | (iocb->ki_pos + iov_iter_count(to) > i_size_read(inode))) { |
949 | int err; | 948 | int err; |
950 | err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); | 949 | err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); |
951 | if (err) | 950 | if (err) |
952 | return err; | 951 | return err; |
953 | } | 952 | } |
954 | 953 | ||
955 | return generic_file_aio_read(iocb, iov, nr_segs, pos); | 954 | return generic_file_read_iter(iocb, to); |
956 | } | 955 | } |
957 | 956 | ||
958 | static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, | 957 | static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, |
@@ -1181,19 +1180,17 @@ static ssize_t fuse_perform_write(struct file *file, | |||
1181 | return res > 0 ? res : err; | 1180 | return res > 0 ? res : err; |
1182 | } | 1181 | } |
1183 | 1182 | ||
1184 | static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 1183 | static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) |
1185 | unsigned long nr_segs, loff_t pos) | ||
1186 | { | 1184 | { |
1187 | struct file *file = iocb->ki_filp; | 1185 | struct file *file = iocb->ki_filp; |
1188 | struct address_space *mapping = file->f_mapping; | 1186 | struct address_space *mapping = file->f_mapping; |
1189 | size_t count = 0; | 1187 | size_t count = iov_iter_count(from); |
1190 | size_t ocount = 0; | ||
1191 | ssize_t written = 0; | 1188 | ssize_t written = 0; |
1192 | ssize_t written_buffered = 0; | 1189 | ssize_t written_buffered = 0; |
1193 | struct inode *inode = mapping->host; | 1190 | struct inode *inode = mapping->host; |
1194 | ssize_t err; | 1191 | ssize_t err; |
1195 | struct iov_iter i; | ||
1196 | loff_t endbyte = 0; | 1192 | loff_t endbyte = 0; |
1193 | loff_t pos = iocb->ki_pos; | ||
1197 | 1194 | ||
1198 | if (get_fuse_conn(inode)->writeback_cache) { | 1195 | if (get_fuse_conn(inode)->writeback_cache) { |
1199 | /* Update size (EOF optimization) and mode (SUID clearing) */ | 1196 | /* Update size (EOF optimization) and mode (SUID clearing) */ |
@@ -1201,17 +1198,9 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1201 | if (err) | 1198 | if (err) |
1202 | return err; | 1199 | return err; |
1203 | 1200 | ||
1204 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | 1201 | return generic_file_write_iter(iocb, from); |
1205 | } | 1202 | } |
1206 | 1203 | ||
1207 | WARN_ON(iocb->ki_pos != pos); | ||
1208 | |||
1209 | ocount = 0; | ||
1210 | err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); | ||
1211 | if (err) | ||
1212 | return err; | ||
1213 | |||
1214 | count = ocount; | ||
1215 | mutex_lock(&inode->i_mutex); | 1204 | mutex_lock(&inode->i_mutex); |
1216 | 1205 | ||
1217 | /* We can write back this queue in page reclaim */ | 1206 | /* We can write back this queue in page reclaim */ |
@@ -1224,6 +1213,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1224 | if (count == 0) | 1213 | if (count == 0) |
1225 | goto out; | 1214 | goto out; |
1226 | 1215 | ||
1216 | iov_iter_truncate(from, count); | ||
1227 | err = file_remove_suid(file); | 1217 | err = file_remove_suid(file); |
1228 | if (err) | 1218 | if (err) |
1229 | goto out; | 1219 | goto out; |
@@ -1233,16 +1223,13 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1233 | goto out; | 1223 | goto out; |
1234 | 1224 | ||
1235 | if (file->f_flags & O_DIRECT) { | 1225 | if (file->f_flags & O_DIRECT) { |
1236 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, | 1226 | written = generic_file_direct_write(iocb, from, pos); |
1237 | count, ocount); | 1227 | if (written < 0 || !iov_iter_count(from)) |
1238 | if (written < 0 || written == count) | ||
1239 | goto out; | 1228 | goto out; |
1240 | 1229 | ||
1241 | pos += written; | 1230 | pos += written; |
1242 | count -= written; | ||
1243 | 1231 | ||
1244 | iov_iter_init(&i, iov, nr_segs, count, written); | 1232 | written_buffered = fuse_perform_write(file, mapping, from, pos); |
1245 | written_buffered = fuse_perform_write(file, mapping, &i, pos); | ||
1246 | if (written_buffered < 0) { | 1233 | if (written_buffered < 0) { |
1247 | err = written_buffered; | 1234 | err = written_buffered; |
1248 | goto out; | 1235 | goto out; |
@@ -1261,8 +1248,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1261 | written += written_buffered; | 1248 | written += written_buffered; |
1262 | iocb->ki_pos = pos + written_buffered; | 1249 | iocb->ki_pos = pos + written_buffered; |
1263 | } else { | 1250 | } else { |
1264 | iov_iter_init(&i, iov, nr_segs, count, 0); | 1251 | written = fuse_perform_write(file, mapping, from, pos); |
1265 | written = fuse_perform_write(file, mapping, &i, pos); | ||
1266 | if (written >= 0) | 1252 | if (written >= 0) |
1267 | iocb->ki_pos = pos + written; | 1253 | iocb->ki_pos = pos + written; |
1268 | } | 1254 | } |
@@ -1300,7 +1286,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, | |||
1300 | size_t nbytes = 0; /* # bytes already packed in req */ | 1286 | size_t nbytes = 0; /* # bytes already packed in req */ |
1301 | 1287 | ||
1302 | /* Special case for kernel I/O: can copy directly into the buffer */ | 1288 | /* Special case for kernel I/O: can copy directly into the buffer */ |
1303 | if (segment_eq(get_fs(), KERNEL_DS)) { | 1289 | if (ii->type & ITER_KVEC) { |
1304 | unsigned long user_addr = fuse_get_user_addr(ii); | 1290 | unsigned long user_addr = fuse_get_user_addr(ii); |
1305 | size_t frag_size = fuse_get_frag_size(ii, *nbytesp); | 1291 | size_t frag_size = fuse_get_frag_size(ii, *nbytesp); |
1306 | 1292 | ||
@@ -1316,35 +1302,26 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, | |||
1316 | 1302 | ||
1317 | while (nbytes < *nbytesp && req->num_pages < req->max_pages) { | 1303 | while (nbytes < *nbytesp && req->num_pages < req->max_pages) { |
1318 | unsigned npages; | 1304 | unsigned npages; |
1319 | unsigned long user_addr = fuse_get_user_addr(ii); | 1305 | size_t start; |
1320 | unsigned offset = user_addr & ~PAGE_MASK; | ||
1321 | size_t frag_size = fuse_get_frag_size(ii, *nbytesp - nbytes); | ||
1322 | int ret; | ||
1323 | |||
1324 | unsigned n = req->max_pages - req->num_pages; | 1306 | unsigned n = req->max_pages - req->num_pages; |
1325 | frag_size = min_t(size_t, frag_size, n << PAGE_SHIFT); | 1307 | ssize_t ret = iov_iter_get_pages(ii, |
1326 | 1308 | &req->pages[req->num_pages], | |
1327 | npages = (frag_size + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1309 | n * PAGE_SIZE, &start); |
1328 | npages = clamp(npages, 1U, n); | ||
1329 | |||
1330 | ret = get_user_pages_fast(user_addr, npages, !write, | ||
1331 | &req->pages[req->num_pages]); | ||
1332 | if (ret < 0) | 1310 | if (ret < 0) |
1333 | return ret; | 1311 | return ret; |
1334 | 1312 | ||
1335 | npages = ret; | 1313 | iov_iter_advance(ii, ret); |
1336 | frag_size = min_t(size_t, frag_size, | 1314 | nbytes += ret; |
1337 | (npages << PAGE_SHIFT) - offset); | 1315 | |
1338 | iov_iter_advance(ii, frag_size); | 1316 | ret += start; |
1317 | npages = (ret + PAGE_SIZE - 1) / PAGE_SIZE; | ||
1339 | 1318 | ||
1340 | req->page_descs[req->num_pages].offset = offset; | 1319 | req->page_descs[req->num_pages].offset = start; |
1341 | fuse_page_descs_length_init(req, req->num_pages, npages); | 1320 | fuse_page_descs_length_init(req, req->num_pages, npages); |
1342 | 1321 | ||
1343 | req->num_pages += npages; | 1322 | req->num_pages += npages; |
1344 | req->page_descs[req->num_pages - 1].length -= | 1323 | req->page_descs[req->num_pages - 1].length -= |
1345 | (npages << PAGE_SHIFT) - offset - frag_size; | 1324 | (PAGE_SIZE - ret) & (PAGE_SIZE - 1); |
1346 | |||
1347 | nbytes += frag_size; | ||
1348 | } | 1325 | } |
1349 | 1326 | ||
1350 | if (write) | 1327 | if (write) |
@@ -1359,24 +1336,11 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, | |||
1359 | 1336 | ||
1360 | static inline int fuse_iter_npages(const struct iov_iter *ii_p) | 1337 | static inline int fuse_iter_npages(const struct iov_iter *ii_p) |
1361 | { | 1338 | { |
1362 | struct iov_iter ii = *ii_p; | 1339 | return iov_iter_npages(ii_p, FUSE_MAX_PAGES_PER_REQ); |
1363 | int npages = 0; | ||
1364 | |||
1365 | while (iov_iter_count(&ii) && npages < FUSE_MAX_PAGES_PER_REQ) { | ||
1366 | unsigned long user_addr = fuse_get_user_addr(&ii); | ||
1367 | unsigned offset = user_addr & ~PAGE_MASK; | ||
1368 | size_t frag_size = iov_iter_single_seg_count(&ii); | ||
1369 | |||
1370 | npages += (frag_size + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
1371 | iov_iter_advance(&ii, frag_size); | ||
1372 | } | ||
1373 | |||
1374 | return min(npages, FUSE_MAX_PAGES_PER_REQ); | ||
1375 | } | 1340 | } |
1376 | 1341 | ||
1377 | ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | 1342 | ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, |
1378 | unsigned long nr_segs, size_t count, loff_t *ppos, | 1343 | loff_t *ppos, int flags) |
1379 | int flags) | ||
1380 | { | 1344 | { |
1381 | int write = flags & FUSE_DIO_WRITE; | 1345 | int write = flags & FUSE_DIO_WRITE; |
1382 | int cuse = flags & FUSE_DIO_CUSE; | 1346 | int cuse = flags & FUSE_DIO_CUSE; |
@@ -1386,18 +1350,16 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1386 | struct fuse_conn *fc = ff->fc; | 1350 | struct fuse_conn *fc = ff->fc; |
1387 | size_t nmax = write ? fc->max_write : fc->max_read; | 1351 | size_t nmax = write ? fc->max_write : fc->max_read; |
1388 | loff_t pos = *ppos; | 1352 | loff_t pos = *ppos; |
1353 | size_t count = iov_iter_count(iter); | ||
1389 | pgoff_t idx_from = pos >> PAGE_CACHE_SHIFT; | 1354 | pgoff_t idx_from = pos >> PAGE_CACHE_SHIFT; |
1390 | pgoff_t idx_to = (pos + count - 1) >> PAGE_CACHE_SHIFT; | 1355 | pgoff_t idx_to = (pos + count - 1) >> PAGE_CACHE_SHIFT; |
1391 | ssize_t res = 0; | 1356 | ssize_t res = 0; |
1392 | struct fuse_req *req; | 1357 | struct fuse_req *req; |
1393 | struct iov_iter ii; | ||
1394 | |||
1395 | iov_iter_init(&ii, iov, nr_segs, count, 0); | ||
1396 | 1358 | ||
1397 | if (io->async) | 1359 | if (io->async) |
1398 | req = fuse_get_req_for_background(fc, fuse_iter_npages(&ii)); | 1360 | req = fuse_get_req_for_background(fc, fuse_iter_npages(iter)); |
1399 | else | 1361 | else |
1400 | req = fuse_get_req(fc, fuse_iter_npages(&ii)); | 1362 | req = fuse_get_req(fc, fuse_iter_npages(iter)); |
1401 | if (IS_ERR(req)) | 1363 | if (IS_ERR(req)) |
1402 | return PTR_ERR(req); | 1364 | return PTR_ERR(req); |
1403 | 1365 | ||
@@ -1413,7 +1375,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1413 | size_t nres; | 1375 | size_t nres; |
1414 | fl_owner_t owner = current->files; | 1376 | fl_owner_t owner = current->files; |
1415 | size_t nbytes = min(count, nmax); | 1377 | size_t nbytes = min(count, nmax); |
1416 | int err = fuse_get_user_pages(req, &ii, &nbytes, write); | 1378 | int err = fuse_get_user_pages(req, iter, &nbytes, write); |
1417 | if (err) { | 1379 | if (err) { |
1418 | res = err; | 1380 | res = err; |
1419 | break; | 1381 | break; |
@@ -1443,9 +1405,9 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1443 | fuse_put_request(fc, req); | 1405 | fuse_put_request(fc, req); |
1444 | if (io->async) | 1406 | if (io->async) |
1445 | req = fuse_get_req_for_background(fc, | 1407 | req = fuse_get_req_for_background(fc, |
1446 | fuse_iter_npages(&ii)); | 1408 | fuse_iter_npages(iter)); |
1447 | else | 1409 | else |
1448 | req = fuse_get_req(fc, fuse_iter_npages(&ii)); | 1410 | req = fuse_get_req(fc, fuse_iter_npages(iter)); |
1449 | if (IS_ERR(req)) | 1411 | if (IS_ERR(req)) |
1450 | break; | 1412 | break; |
1451 | } | 1413 | } |
@@ -1460,9 +1422,8 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1460 | EXPORT_SYMBOL_GPL(fuse_direct_io); | 1422 | EXPORT_SYMBOL_GPL(fuse_direct_io); |
1461 | 1423 | ||
1462 | static ssize_t __fuse_direct_read(struct fuse_io_priv *io, | 1424 | static ssize_t __fuse_direct_read(struct fuse_io_priv *io, |
1463 | const struct iovec *iov, | 1425 | struct iov_iter *iter, |
1464 | unsigned long nr_segs, loff_t *ppos, | 1426 | loff_t *ppos) |
1465 | size_t count) | ||
1466 | { | 1427 | { |
1467 | ssize_t res; | 1428 | ssize_t res; |
1468 | struct file *file = io->file; | 1429 | struct file *file = io->file; |
@@ -1471,7 +1432,7 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io, | |||
1471 | if (is_bad_inode(inode)) | 1432 | if (is_bad_inode(inode)) |
1472 | return -EIO; | 1433 | return -EIO; |
1473 | 1434 | ||
1474 | res = fuse_direct_io(io, iov, nr_segs, count, ppos, 0); | 1435 | res = fuse_direct_io(io, iter, ppos, 0); |
1475 | 1436 | ||
1476 | fuse_invalidate_attr(inode); | 1437 | fuse_invalidate_attr(inode); |
1477 | 1438 | ||
@@ -1483,22 +1444,26 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, | |||
1483 | { | 1444 | { |
1484 | struct fuse_io_priv io = { .async = 0, .file = file }; | 1445 | struct fuse_io_priv io = { .async = 0, .file = file }; |
1485 | struct iovec iov = { .iov_base = buf, .iov_len = count }; | 1446 | struct iovec iov = { .iov_base = buf, .iov_len = count }; |
1486 | return __fuse_direct_read(&io, &iov, 1, ppos, count); | 1447 | struct iov_iter ii; |
1448 | iov_iter_init(&ii, READ, &iov, 1, count); | ||
1449 | return __fuse_direct_read(&io, &ii, ppos); | ||
1487 | } | 1450 | } |
1488 | 1451 | ||
1489 | static ssize_t __fuse_direct_write(struct fuse_io_priv *io, | 1452 | static ssize_t __fuse_direct_write(struct fuse_io_priv *io, |
1490 | const struct iovec *iov, | 1453 | struct iov_iter *iter, |
1491 | unsigned long nr_segs, loff_t *ppos) | 1454 | loff_t *ppos) |
1492 | { | 1455 | { |
1493 | struct file *file = io->file; | 1456 | struct file *file = io->file; |
1494 | struct inode *inode = file_inode(file); | 1457 | struct inode *inode = file_inode(file); |
1495 | size_t count = iov_length(iov, nr_segs); | 1458 | size_t count = iov_iter_count(iter); |
1496 | ssize_t res; | 1459 | ssize_t res; |
1497 | 1460 | ||
1461 | |||
1498 | res = generic_write_checks(file, ppos, &count, 0); | 1462 | res = generic_write_checks(file, ppos, &count, 0); |
1499 | if (!res) | 1463 | if (!res) { |
1500 | res = fuse_direct_io(io, iov, nr_segs, count, ppos, | 1464 | iov_iter_truncate(iter, count); |
1501 | FUSE_DIO_WRITE); | 1465 | res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE); |
1466 | } | ||
1502 | 1467 | ||
1503 | fuse_invalidate_attr(inode); | 1468 | fuse_invalidate_attr(inode); |
1504 | 1469 | ||
@@ -1512,13 +1477,15 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, | |||
1512 | struct inode *inode = file_inode(file); | 1477 | struct inode *inode = file_inode(file); |
1513 | ssize_t res; | 1478 | ssize_t res; |
1514 | struct fuse_io_priv io = { .async = 0, .file = file }; | 1479 | struct fuse_io_priv io = { .async = 0, .file = file }; |
1480 | struct iov_iter ii; | ||
1481 | iov_iter_init(&ii, WRITE, &iov, 1, count); | ||
1515 | 1482 | ||
1516 | if (is_bad_inode(inode)) | 1483 | if (is_bad_inode(inode)) |
1517 | return -EIO; | 1484 | return -EIO; |
1518 | 1485 | ||
1519 | /* Don't allow parallel writes to the same file */ | 1486 | /* Don't allow parallel writes to the same file */ |
1520 | mutex_lock(&inode->i_mutex); | 1487 | mutex_lock(&inode->i_mutex); |
1521 | res = __fuse_direct_write(&io, &iov, 1, ppos); | 1488 | res = __fuse_direct_write(&io, &ii, ppos); |
1522 | if (res > 0) | 1489 | if (res > 0) |
1523 | fuse_write_update_size(inode, *ppos); | 1490 | fuse_write_update_size(inode, *ppos); |
1524 | mutex_unlock(&inode->i_mutex); | 1491 | mutex_unlock(&inode->i_mutex); |
@@ -2372,7 +2339,7 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, | |||
2372 | if (!bytes) | 2339 | if (!bytes) |
2373 | return 0; | 2340 | return 0; |
2374 | 2341 | ||
2375 | iov_iter_init(&ii, iov, nr_segs, bytes, 0); | 2342 | iov_iter_init(&ii, to_user ? READ : WRITE, iov, nr_segs, bytes); |
2376 | 2343 | ||
2377 | while (iov_iter_count(&ii)) { | 2344 | while (iov_iter_count(&ii)) { |
2378 | struct page *page = pages[page_idx++]; | 2345 | struct page *page = pages[page_idx++]; |
@@ -2894,8 +2861,8 @@ static inline loff_t fuse_round_up(loff_t off) | |||
2894 | } | 2861 | } |
2895 | 2862 | ||
2896 | static ssize_t | 2863 | static ssize_t |
2897 | fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | 2864 | fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, |
2898 | loff_t offset, unsigned long nr_segs) | 2865 | loff_t offset) |
2899 | { | 2866 | { |
2900 | ssize_t ret = 0; | 2867 | ssize_t ret = 0; |
2901 | struct file *file = iocb->ki_filp; | 2868 | struct file *file = iocb->ki_filp; |
@@ -2904,7 +2871,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
2904 | loff_t pos = 0; | 2871 | loff_t pos = 0; |
2905 | struct inode *inode; | 2872 | struct inode *inode; |
2906 | loff_t i_size; | 2873 | loff_t i_size; |
2907 | size_t count = iov_length(iov, nr_segs); | 2874 | size_t count = iov_iter_count(iter); |
2908 | struct fuse_io_priv *io; | 2875 | struct fuse_io_priv *io; |
2909 | 2876 | ||
2910 | pos = offset; | 2877 | pos = offset; |
@@ -2919,6 +2886,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
2919 | if (offset >= i_size) | 2886 | if (offset >= i_size) |
2920 | return 0; | 2887 | return 0; |
2921 | count = min_t(loff_t, count, fuse_round_up(i_size - offset)); | 2888 | count = min_t(loff_t, count, fuse_round_up(i_size - offset)); |
2889 | iov_iter_truncate(iter, count); | ||
2922 | } | 2890 | } |
2923 | 2891 | ||
2924 | io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); | 2892 | io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); |
@@ -2948,9 +2916,9 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
2948 | io->async = false; | 2916 | io->async = false; |
2949 | 2917 | ||
2950 | if (rw == WRITE) | 2918 | if (rw == WRITE) |
2951 | ret = __fuse_direct_write(io, iov, nr_segs, &pos); | 2919 | ret = __fuse_direct_write(io, iter, &pos); |
2952 | else | 2920 | else |
2953 | ret = __fuse_direct_read(io, iov, nr_segs, &pos, count); | 2921 | ret = __fuse_direct_read(io, iter, &pos); |
2954 | 2922 | ||
2955 | if (io->async) { | 2923 | if (io->async) { |
2956 | fuse_aio_complete(io, ret < 0 ? ret : 0, -1); | 2924 | fuse_aio_complete(io, ret < 0 ? ret : 0, -1); |
@@ -3061,10 +3029,10 @@ out: | |||
3061 | 3029 | ||
3062 | static const struct file_operations fuse_file_operations = { | 3030 | static const struct file_operations fuse_file_operations = { |
3063 | .llseek = fuse_file_llseek, | 3031 | .llseek = fuse_file_llseek, |
3064 | .read = do_sync_read, | 3032 | .read = new_sync_read, |
3065 | .aio_read = fuse_file_aio_read, | 3033 | .read_iter = fuse_file_read_iter, |
3066 | .write = do_sync_write, | 3034 | .write = new_sync_write, |
3067 | .aio_write = fuse_file_aio_write, | 3035 | .write_iter = fuse_file_write_iter, |
3068 | .mmap = fuse_file_mmap, | 3036 | .mmap = fuse_file_mmap, |
3069 | .open = fuse_open, | 3037 | .open = fuse_open, |
3070 | .flush = fuse_flush, | 3038 | .flush = fuse_flush, |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 7aa5c75e0de1..e8e47a6ab518 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -880,9 +880,8 @@ int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, | |||
880 | /** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */ | 880 | /** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */ |
881 | #define FUSE_DIO_CUSE (1 << 1) | 881 | #define FUSE_DIO_CUSE (1 << 1) |
882 | 882 | ||
883 | ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | 883 | ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, |
884 | unsigned long nr_segs, size_t count, loff_t *ppos, | 884 | loff_t *ppos, int flags); |
885 | int flags); | ||
886 | long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | 885 | long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, |
887 | unsigned int flags); | 886 | unsigned int flags); |
888 | long fuse_ioctl_common(struct file *file, unsigned int cmd, | 887 | long fuse_ioctl_common(struct file *file, unsigned int cmd, |