diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 17:49:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 17:49:50 -0400 |
commit | 5166701b368caea89d57b14bf41cf39e819dad51 (patch) | |
tree | c73b9d4860809e3afa9359be9d03ba2d8d98a18e /mm/shmem.c | |
parent | 0a7418f5f569512e98789c439198eed4b507cce3 (diff) | |
parent | a786c06d9f2719203c00b3d97b21f9a96980d0b5 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"The first vfs pile, with deep apologies for being very late in this
window.
Assorted cleanups and fixes, plus a large preparatory part of iov_iter
work. There's a lot more of that, but it'll probably go into the next
merge window - it *does* shape up nicely, removes a lot of
boilerplate, gets rid of locking inconsistencie between aio_write and
splice_write and I hope to get Kent's direct-io rewrite merged into
the same queue, but some of the stuff after this point is having
(mostly trivial) conflicts with the things already merged into
mainline and with some I want more testing.
This one passes LTP and xfstests without regressions, in addition to
usual beating. BTW, readahead02 in ltp syscalls testsuite has started
giving failures since "mm/readahead.c: fix readahead failure for
memoryless NUMA nodes and limit readahead pages" - might be a false
positive, might be a real regression..."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
missing bits of "splice: fix racy pipe->buffers uses"
cifs: fix the race in cifs_writev()
ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure
kill generic_file_buffered_write()
ocfs2_file_aio_write(): switch to generic_perform_write()
ceph_aio_write(): switch to generic_perform_write()
xfs_file_buffered_aio_write(): switch to generic_perform_write()
export generic_perform_write(), start getting rid of generic_file_buffer_write()
generic_file_direct_write(): get rid of ppos argument
btrfs_file_aio_write(): get rid of ppos
kill the 5th argument of generic_file_buffered_write()
kill the 4th argument of __generic_file_aio_write()
lustre: don't open-code kernel_recvmsg()
ocfs2: don't open-code kernel_recvmsg()
drbd: don't open-code kernel_recvmsg()
constify blk_rq_map_user_iov() and friends
lustre: switch to kernel_sendmsg()
ocfs2: don't open-code kernel_sendmsg()
take iov_iter stuff to mm/iov_iter.c
process_vm_access: tidy up a bit
...
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 79 |
1 files changed, 28 insertions, 51 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 70273f8df586..8f1a95406bae 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1402,13 +1402,25 @@ shmem_write_end(struct file *file, struct address_space *mapping, | |||
1402 | return copied; | 1402 | return copied; |
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc, read_actor_t actor) | 1405 | static ssize_t shmem_file_aio_read(struct kiocb *iocb, |
1406 | const struct iovec *iov, unsigned long nr_segs, loff_t pos) | ||
1406 | { | 1407 | { |
1407 | struct inode *inode = file_inode(filp); | 1408 | struct file *file = iocb->ki_filp; |
1409 | struct inode *inode = file_inode(file); | ||
1408 | struct address_space *mapping = inode->i_mapping; | 1410 | struct address_space *mapping = inode->i_mapping; |
1409 | pgoff_t index; | 1411 | pgoff_t index; |
1410 | unsigned long offset; | 1412 | unsigned long offset; |
1411 | enum sgp_type sgp = SGP_READ; | 1413 | enum sgp_type sgp = SGP_READ; |
1414 | int error; | ||
1415 | ssize_t retval; | ||
1416 | size_t count; | ||
1417 | loff_t *ppos = &iocb->ki_pos; | ||
1418 | struct iov_iter iter; | ||
1419 | |||
1420 | retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); | ||
1421 | if (retval) | ||
1422 | return retval; | ||
1423 | iov_iter_init(&iter, iov, nr_segs, count, 0); | ||
1412 | 1424 | ||
1413 | /* | 1425 | /* |
1414 | * Might this read be for a stacking filesystem? Then when reading | 1426 | * Might this read be for a stacking filesystem? Then when reading |
@@ -1436,10 +1448,10 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
1436 | break; | 1448 | break; |
1437 | } | 1449 | } |
1438 | 1450 | ||
1439 | desc->error = shmem_getpage(inode, index, &page, sgp, NULL); | 1451 | error = shmem_getpage(inode, index, &page, sgp, NULL); |
1440 | if (desc->error) { | 1452 | if (error) { |
1441 | if (desc->error == -EINVAL) | 1453 | if (error == -EINVAL) |
1442 | desc->error = 0; | 1454 | error = 0; |
1443 | break; | 1455 | break; |
1444 | } | 1456 | } |
1445 | if (page) | 1457 | if (page) |
@@ -1483,61 +1495,26 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
1483 | /* | 1495 | /* |
1484 | * Ok, we have the page, and it's up-to-date, so | 1496 | * Ok, we have the page, and it's up-to-date, so |
1485 | * now we can copy it to user space... | 1497 | * now we can copy it to user space... |
1486 | * | ||
1487 | * The actor routine returns how many bytes were actually used.. | ||
1488 | * NOTE! This may not be the same as how much of a user buffer | ||
1489 | * we filled up (we may be padding etc), so we can only update | ||
1490 | * "pos" here (the actor routine has to update the user buffer | ||
1491 | * pointers and the remaining count). | ||
1492 | */ | 1498 | */ |
1493 | ret = actor(desc, page, offset, nr); | 1499 | ret = copy_page_to_iter(page, offset, nr, &iter); |
1500 | retval += ret; | ||
1494 | offset += ret; | 1501 | offset += ret; |
1495 | index += offset >> PAGE_CACHE_SHIFT; | 1502 | index += offset >> PAGE_CACHE_SHIFT; |
1496 | offset &= ~PAGE_CACHE_MASK; | 1503 | offset &= ~PAGE_CACHE_MASK; |
1497 | 1504 | ||
1498 | page_cache_release(page); | 1505 | page_cache_release(page); |
1499 | if (ret != nr || !desc->count) | 1506 | if (!iov_iter_count(&iter)) |
1500 | break; | 1507 | break; |
1501 | 1508 | if (ret < nr) { | |
1509 | error = -EFAULT; | ||
1510 | break; | ||
1511 | } | ||
1502 | cond_resched(); | 1512 | cond_resched(); |
1503 | } | 1513 | } |
1504 | 1514 | ||
1505 | *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; | 1515 | *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; |
1506 | file_accessed(filp); | 1516 | file_accessed(file); |
1507 | } | 1517 | return retval ? retval : error; |
1508 | |||
1509 | static ssize_t shmem_file_aio_read(struct kiocb *iocb, | ||
1510 | const struct iovec *iov, unsigned long nr_segs, loff_t pos) | ||
1511 | { | ||
1512 | struct file *filp = iocb->ki_filp; | ||
1513 | ssize_t retval; | ||
1514 | unsigned long seg; | ||
1515 | size_t count; | ||
1516 | loff_t *ppos = &iocb->ki_pos; | ||
1517 | |||
1518 | retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); | ||
1519 | if (retval) | ||
1520 | return retval; | ||
1521 | |||
1522 | for (seg = 0; seg < nr_segs; seg++) { | ||
1523 | read_descriptor_t desc; | ||
1524 | |||
1525 | desc.written = 0; | ||
1526 | desc.arg.buf = iov[seg].iov_base; | ||
1527 | desc.count = iov[seg].iov_len; | ||
1528 | if (desc.count == 0) | ||
1529 | continue; | ||
1530 | desc.error = 0; | ||
1531 | do_shmem_file_read(filp, ppos, &desc, file_read_actor); | ||
1532 | retval += desc.written; | ||
1533 | if (desc.error) { | ||
1534 | retval = retval ?: desc.error; | ||
1535 | break; | ||
1536 | } | ||
1537 | if (desc.count > 0) | ||
1538 | break; | ||
1539 | } | ||
1540 | return retval; | ||
1541 | } | 1518 | } |
1542 | 1519 | ||
1543 | static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, | 1520 | static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, |
@@ -1576,7 +1553,7 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, | |||
1576 | index = *ppos >> PAGE_CACHE_SHIFT; | 1553 | index = *ppos >> PAGE_CACHE_SHIFT; |
1577 | loff = *ppos & ~PAGE_CACHE_MASK; | 1554 | loff = *ppos & ~PAGE_CACHE_MASK; |
1578 | req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 1555 | req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
1579 | nr_pages = min(req_pages, pipe->buffers); | 1556 | nr_pages = min(req_pages, spd.nr_pages_max); |
1580 | 1557 | ||
1581 | spd.nr_pages = find_get_pages_contig(mapping, index, | 1558 | spd.nr_pages = find_get_pages_contig(mapping, index, |
1582 | nr_pages, spd.pages); | 1559 | nr_pages, spd.pages); |