aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-12 17:49:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-12 17:49:50 -0400
commit5166701b368caea89d57b14bf41cf39e819dad51 (patch)
treec73b9d4860809e3afa9359be9d03ba2d8d98a18e /mm/shmem.c
parent0a7418f5f569512e98789c439198eed4b507cce3 (diff)
parenta786c06d9f2719203c00b3d97b21f9a96980d0b5 (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.c79
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
1405static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc, read_actor_t actor) 1405static 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
1509static 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
1543static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, 1520static 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);