diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-03-16 15:50:47 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:32:51 -0400 |
commit | d22a943f44c79c98ac7a93653fdd330378581741 (patch) | |
tree | 7d23353cca628d240a2260c27cfaa73837cc2447 /fs/fuse | |
parent | 7b2c99d15559e285384c742db52316802e24b0bd (diff) |
fuse: pull iov_iter initializations up
... to fuse_direct_{read,write}(). ->direct_IO() path uses the
iov_iter passed by the caller instead.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/cuse.c | 8 | ||||
-rw-r--r-- | fs/fuse/file.c | 55 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 5 |
3 files changed, 38 insertions, 30 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 4a5519ca253f..10e9fcd8fe55 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -1368,9 +1368,8 @@ static inline int fuse_iter_npages(const struct iov_iter *ii_p) | |||
1368 | return min(npages, FUSE_MAX_PAGES_PER_REQ); | 1368 | return min(npages, FUSE_MAX_PAGES_PER_REQ); |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | 1371 | ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, |
1372 | unsigned long nr_segs, size_t count, loff_t *ppos, | 1372 | loff_t *ppos, int flags) |
1373 | int flags) | ||
1374 | { | 1373 | { |
1375 | int write = flags & FUSE_DIO_WRITE; | 1374 | int write = flags & FUSE_DIO_WRITE; |
1376 | int cuse = flags & FUSE_DIO_CUSE; | 1375 | int cuse = flags & FUSE_DIO_CUSE; |
@@ -1380,18 +1379,16 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1380 | struct fuse_conn *fc = ff->fc; | 1379 | struct fuse_conn *fc = ff->fc; |
1381 | size_t nmax = write ? fc->max_write : fc->max_read; | 1380 | size_t nmax = write ? fc->max_write : fc->max_read; |
1382 | loff_t pos = *ppos; | 1381 | loff_t pos = *ppos; |
1382 | size_t count = iov_iter_count(iter); | ||
1383 | pgoff_t idx_from = pos >> PAGE_CACHE_SHIFT; | 1383 | pgoff_t idx_from = pos >> PAGE_CACHE_SHIFT; |
1384 | pgoff_t idx_to = (pos + count - 1) >> PAGE_CACHE_SHIFT; | 1384 | pgoff_t idx_to = (pos + count - 1) >> PAGE_CACHE_SHIFT; |
1385 | ssize_t res = 0; | 1385 | ssize_t res = 0; |
1386 | struct fuse_req *req; | 1386 | struct fuse_req *req; |
1387 | struct iov_iter ii; | ||
1388 | |||
1389 | iov_iter_init(&ii, write ? WRITE : READ, iov, nr_segs, count); | ||
1390 | 1387 | ||
1391 | if (io->async) | 1388 | if (io->async) |
1392 | req = fuse_get_req_for_background(fc, fuse_iter_npages(&ii)); | 1389 | req = fuse_get_req_for_background(fc, fuse_iter_npages(iter)); |
1393 | else | 1390 | else |
1394 | req = fuse_get_req(fc, fuse_iter_npages(&ii)); | 1391 | req = fuse_get_req(fc, fuse_iter_npages(iter)); |
1395 | if (IS_ERR(req)) | 1392 | if (IS_ERR(req)) |
1396 | return PTR_ERR(req); | 1393 | return PTR_ERR(req); |
1397 | 1394 | ||
@@ -1407,7 +1404,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1407 | size_t nres; | 1404 | size_t nres; |
1408 | fl_owner_t owner = current->files; | 1405 | fl_owner_t owner = current->files; |
1409 | size_t nbytes = min(count, nmax); | 1406 | size_t nbytes = min(count, nmax); |
1410 | int err = fuse_get_user_pages(req, &ii, &nbytes, write); | 1407 | int err = fuse_get_user_pages(req, iter, &nbytes, write); |
1411 | if (err) { | 1408 | if (err) { |
1412 | res = err; | 1409 | res = err; |
1413 | break; | 1410 | break; |
@@ -1437,9 +1434,9 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1437 | fuse_put_request(fc, req); | 1434 | fuse_put_request(fc, req); |
1438 | if (io->async) | 1435 | if (io->async) |
1439 | req = fuse_get_req_for_background(fc, | 1436 | req = fuse_get_req_for_background(fc, |
1440 | fuse_iter_npages(&ii)); | 1437 | fuse_iter_npages(iter)); |
1441 | else | 1438 | else |
1442 | req = fuse_get_req(fc, fuse_iter_npages(&ii)); | 1439 | req = fuse_get_req(fc, fuse_iter_npages(iter)); |
1443 | if (IS_ERR(req)) | 1440 | if (IS_ERR(req)) |
1444 | break; | 1441 | break; |
1445 | } | 1442 | } |
@@ -1454,9 +1451,8 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov, | |||
1454 | EXPORT_SYMBOL_GPL(fuse_direct_io); | 1451 | EXPORT_SYMBOL_GPL(fuse_direct_io); |
1455 | 1452 | ||
1456 | static ssize_t __fuse_direct_read(struct fuse_io_priv *io, | 1453 | static ssize_t __fuse_direct_read(struct fuse_io_priv *io, |
1457 | const struct iovec *iov, | 1454 | struct iov_iter *iter, |
1458 | unsigned long nr_segs, loff_t *ppos, | 1455 | loff_t *ppos) |
1459 | size_t count) | ||
1460 | { | 1456 | { |
1461 | ssize_t res; | 1457 | ssize_t res; |
1462 | struct file *file = io->file; | 1458 | struct file *file = io->file; |
@@ -1465,7 +1461,7 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io, | |||
1465 | if (is_bad_inode(inode)) | 1461 | if (is_bad_inode(inode)) |
1466 | return -EIO; | 1462 | return -EIO; |
1467 | 1463 | ||
1468 | res = fuse_direct_io(io, iov, nr_segs, count, ppos, 0); | 1464 | res = fuse_direct_io(io, iter, ppos, 0); |
1469 | 1465 | ||
1470 | fuse_invalidate_attr(inode); | 1466 | fuse_invalidate_attr(inode); |
1471 | 1467 | ||
@@ -1477,22 +1473,27 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, | |||
1477 | { | 1473 | { |
1478 | struct fuse_io_priv io = { .async = 0, .file = file }; | 1474 | struct fuse_io_priv io = { .async = 0, .file = file }; |
1479 | struct iovec iov = { .iov_base = buf, .iov_len = count }; | 1475 | struct iovec iov = { .iov_base = buf, .iov_len = count }; |
1480 | return __fuse_direct_read(&io, &iov, 1, ppos, count); | 1476 | struct iov_iter ii; |
1477 | iov_iter_init(&ii, READ, &iov, 1, count); | ||
1478 | return __fuse_direct_read(&io, &ii, ppos); | ||
1481 | } | 1479 | } |
1482 | 1480 | ||
1483 | static ssize_t __fuse_direct_write(struct fuse_io_priv *io, | 1481 | static ssize_t __fuse_direct_write(struct fuse_io_priv *io, |
1484 | const struct iovec *iov, | 1482 | struct iov_iter *iter, |
1485 | unsigned long nr_segs, loff_t *ppos) | 1483 | loff_t *ppos) |
1486 | { | 1484 | { |
1487 | struct file *file = io->file; | 1485 | struct file *file = io->file; |
1488 | struct inode *inode = file_inode(file); | 1486 | struct inode *inode = file_inode(file); |
1489 | size_t count = iov_length(iov, nr_segs); | 1487 | size_t count = iov_iter_count(iter); |
1490 | ssize_t res; | 1488 | ssize_t res; |
1491 | 1489 | ||
1490 | |||
1492 | res = generic_write_checks(file, ppos, &count, 0); | 1491 | res = generic_write_checks(file, ppos, &count, 0); |
1493 | if (!res) | 1492 | if (!res) { |
1494 | res = fuse_direct_io(io, iov, nr_segs, count, ppos, | 1493 | if (iter->count > count) |
1495 | FUSE_DIO_WRITE); | 1494 | iter->count = count; |
1495 | res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE); | ||
1496 | } | ||
1496 | 1497 | ||
1497 | fuse_invalidate_attr(inode); | 1498 | fuse_invalidate_attr(inode); |
1498 | 1499 | ||
@@ -1506,13 +1507,15 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, | |||
1506 | struct inode *inode = file_inode(file); | 1507 | struct inode *inode = file_inode(file); |
1507 | ssize_t res; | 1508 | ssize_t res; |
1508 | struct fuse_io_priv io = { .async = 0, .file = file }; | 1509 | struct fuse_io_priv io = { .async = 0, .file = file }; |
1510 | struct iov_iter ii; | ||
1511 | iov_iter_init(&ii, WRITE, &iov, 1, count); | ||
1509 | 1512 | ||
1510 | if (is_bad_inode(inode)) | 1513 | if (is_bad_inode(inode)) |
1511 | return -EIO; | 1514 | return -EIO; |
1512 | 1515 | ||
1513 | /* Don't allow parallel writes to the same file */ | 1516 | /* Don't allow parallel writes to the same file */ |
1514 | mutex_lock(&inode->i_mutex); | 1517 | mutex_lock(&inode->i_mutex); |
1515 | res = __fuse_direct_write(&io, &iov, 1, ppos); | 1518 | res = __fuse_direct_write(&io, &ii, ppos); |
1516 | if (res > 0) | 1519 | if (res > 0) |
1517 | fuse_write_update_size(inode, *ppos); | 1520 | fuse_write_update_size(inode, *ppos); |
1518 | mutex_unlock(&inode->i_mutex); | 1521 | mutex_unlock(&inode->i_mutex); |
@@ -2914,6 +2917,8 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, | |||
2914 | if (offset >= i_size) | 2917 | if (offset >= i_size) |
2915 | return 0; | 2918 | return 0; |
2916 | count = min_t(loff_t, count, fuse_round_up(i_size - offset)); | 2919 | count = min_t(loff_t, count, fuse_round_up(i_size - offset)); |
2920 | if (iter->count > count) | ||
2921 | iter->count = count; | ||
2917 | } | 2922 | } |
2918 | 2923 | ||
2919 | io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); | 2924 | io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); |
@@ -2943,9 +2948,9 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, | |||
2943 | io->async = false; | 2948 | io->async = false; |
2944 | 2949 | ||
2945 | if (rw == WRITE) | 2950 | if (rw == WRITE) |
2946 | ret = __fuse_direct_write(io, iter->iov, iter->nr_segs, &pos); | 2951 | ret = __fuse_direct_write(io, iter, &pos); |
2947 | else | 2952 | else |
2948 | ret = __fuse_direct_read(io, iter->iov, iter->nr_segs, &pos, count); | 2953 | ret = __fuse_direct_read(io, iter, &pos); |
2949 | 2954 | ||
2950 | if (io->async) { | 2955 | if (io->async) { |
2951 | fuse_aio_complete(io, ret < 0 ? ret : 0, -1); | 2956 | fuse_aio_complete(io, ret < 0 ? ret : 0, -1); |
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, |