aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-16 16:08:30 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:32:51 -0400
commitc9c37e2e63786c595d704244cbb7d19dc5630493 (patch)
tree37791f3af751c8f3b5d445e8d31c866775012653
parentd22a943f44c79c98ac7a93653fdd330378581741 (diff)
fuse: switch to iov_iter_get_pages()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/fuse/file.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 10e9fcd8fe55..7db564d18dc6 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1294,7 +1294,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
1294 size_t nbytes = 0; /* # bytes already packed in req */ 1294 size_t nbytes = 0; /* # bytes already packed in req */
1295 1295
1296 /* Special case for kernel I/O: can copy directly into the buffer */ 1296 /* Special case for kernel I/O: can copy directly into the buffer */
1297 if (segment_eq(get_fs(), KERNEL_DS)) { 1297 if (ii->type & REQ_KERNEL) {
1298 unsigned long user_addr = fuse_get_user_addr(ii); 1298 unsigned long user_addr = fuse_get_user_addr(ii);
1299 size_t frag_size = fuse_get_frag_size(ii, *nbytesp); 1299 size_t frag_size = fuse_get_frag_size(ii, *nbytesp);
1300 1300
@@ -1310,35 +1310,26 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
1310 1310
1311 while (nbytes < *nbytesp && req->num_pages < req->max_pages) { 1311 while (nbytes < *nbytesp && req->num_pages < req->max_pages) {
1312 unsigned npages; 1312 unsigned npages;
1313 unsigned long user_addr = fuse_get_user_addr(ii); 1313 size_t start, end, frag_size;
1314 unsigned offset = user_addr & ~PAGE_MASK;
1315 size_t frag_size = fuse_get_frag_size(ii, *nbytesp - nbytes);
1316 int ret;
1317
1318 unsigned n = req->max_pages - req->num_pages; 1314 unsigned n = req->max_pages - req->num_pages;
1319 frag_size = min_t(size_t, frag_size, n << PAGE_SHIFT); 1315 ssize_t ret = iov_iter_get_pages(ii,
1320 1316 &req->pages[req->num_pages],
1321 npages = (frag_size + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 1317 n * PAGE_SIZE, &start);
1322 npages = clamp(npages, 1U, n);
1323
1324 ret = get_user_pages_fast(user_addr, npages, !write,
1325 &req->pages[req->num_pages]);
1326 if (ret < 0) 1318 if (ret < 0)
1327 return ret; 1319 return ret;
1328 1320
1329 npages = ret; 1321 iov_iter_advance(ii, ret);
1330 frag_size = min_t(size_t, frag_size, 1322 nbytes += ret;
1331 (npages << PAGE_SHIFT) - offset);
1332 iov_iter_advance(ii, frag_size);
1333 1323
1334 req->page_descs[req->num_pages].offset = offset; 1324 ret += start;
1325 npages = (ret + PAGE_SIZE - 1) / PAGE_SIZE;
1326
1327 req->page_descs[req->num_pages].offset = start;
1335 fuse_page_descs_length_init(req, req->num_pages, npages); 1328 fuse_page_descs_length_init(req, req->num_pages, npages);
1336 1329
1337 req->num_pages += npages; 1330 req->num_pages += npages;
1338 req->page_descs[req->num_pages - 1].length -= 1331 req->page_descs[req->num_pages - 1].length -=
1339 (npages << PAGE_SHIFT) - offset - frag_size; 1332 (PAGE_SIZE - ret) & (PAGE_SIZE - 1);
1340
1341 nbytes += frag_size;
1342 } 1333 }
1343 1334
1344 if (write) 1335 if (write)