diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-02 18:20:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-02 18:20:00 -0500 |
commit | 94e877d0fb43bec0540d6a37d49cb4f7f05a5348 (patch) | |
tree | dc301912dff9c390cba59df00cb76b62ac862d6a | |
parent | 69fd110eb650ea7baa82158f3b89a7d86da1d056 (diff) | |
parent | 653a7746fa2f5369985f5368ffc162b6510db6c8 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs pile two from Al Viro:
- orangefs fix
- series of fs/namei.c cleanups from me
- VFS stuff coming from overlayfs tree
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
orangefs: Use RCU for destroy_inode
vfs: use helper for calling f_op->fsync()
mm: use helper for calling f_op->mmap()
vfs: use helpers for calling f_op->{read,write}_iter()
vfs: pass type instead of fn to do_{loop,iter}_readv_writev()
vfs: extract common parts of {compat_,}do_readv_writev()
vfs: wrap write f_ops with file_{start,end}_write()
vfs: deny copy_file_range() for non regular files
vfs: deny fallocate() on directory
vfs: create vfs helper vfs_tmpfile()
namei.c: split unlazy_walk()
namei.c: fold the check for DCACHE_OP_REVALIDATE into d_revalidate()
lookup_fast(): clean up the logics around the fallback to non-rcu mode
namei: fold unlazy_link() into its sole caller
-rw-r--r-- | drivers/block/loop.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vgem/vgem_drv.c | 2 | ||||
-rw-r--r-- | fs/aio.c | 4 | ||||
-rw-r--r-- | fs/coda/file.c | 2 | ||||
-rw-r--r-- | fs/namei.c | 251 | ||||
-rw-r--r-- | fs/open.c | 14 | ||||
-rw-r--r-- | fs/orangefs/super.c | 9 | ||||
-rw-r--r-- | fs/read_write.c | 130 | ||||
-rw-r--r-- | fs/splice.c | 2 | ||||
-rw-r--r-- | fs/sync.c | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 52 | ||||
-rw-r--r-- | ipc/shm.c | 4 | ||||
-rw-r--r-- | mm/mmap.c | 2 | ||||
-rw-r--r-- | mm/nommu.c | 4 |
15 files changed, 261 insertions, 223 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 4b52a1690329..eeb1db73f44e 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -501,9 +501,9 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, | |||
501 | cmd->iocb.ki_flags = IOCB_DIRECT; | 501 | cmd->iocb.ki_flags = IOCB_DIRECT; |
502 | 502 | ||
503 | if (rw == WRITE) | 503 | if (rw == WRITE) |
504 | ret = file->f_op->write_iter(&cmd->iocb, &iter); | 504 | ret = call_write_iter(file, &cmd->iocb, &iter); |
505 | else | 505 | else |
506 | ret = file->f_op->read_iter(&cmd->iocb, &iter); | 506 | ret = call_read_iter(file, &cmd->iocb, &iter); |
507 | 507 | ||
508 | if (ret != -EIOCBQUEUED) | 508 | if (ret != -EIOCBQUEUED) |
509 | cmd->iocb.ki_complete(&cmd->iocb, ret, 0); | 509 | cmd->iocb.ki_complete(&cmd->iocb, ret, 0); |
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index d037adcda6f2..29bb8011dbc4 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c | |||
@@ -141,7 +141,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct * | |||
141 | if (!obj->base.filp) | 141 | if (!obj->base.filp) |
142 | return -ENODEV; | 142 | return -ENODEV; |
143 | 143 | ||
144 | ret = obj->base.filp->f_op->mmap(obj->base.filp, vma); | 144 | ret = call_mmap(obj->base.filp, vma); |
145 | if (ret) | 145 | if (ret) |
146 | return ret; | 146 | return ret; |
147 | 147 | ||
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 7ccbb03e98de..a1f42d125e6e 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c | |||
@@ -288,7 +288,7 @@ static int vgem_prime_mmap(struct drm_gem_object *obj, | |||
288 | if (!obj->filp) | 288 | if (!obj->filp) |
289 | return -ENODEV; | 289 | return -ENODEV; |
290 | 290 | ||
291 | ret = obj->filp->f_op->mmap(obj->filp, vma); | 291 | ret = call_mmap(obj->filp, vma); |
292 | if (ret) | 292 | if (ret) |
293 | return ret; | 293 | return ret; |
294 | 294 | ||
@@ -1495,7 +1495,7 @@ static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored, | |||
1495 | return ret; | 1495 | return ret; |
1496 | ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); | 1496 | ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); |
1497 | if (!ret) | 1497 | if (!ret) |
1498 | ret = aio_ret(req, file->f_op->read_iter(req, &iter)); | 1498 | ret = aio_ret(req, call_read_iter(file, req, &iter)); |
1499 | kfree(iovec); | 1499 | kfree(iovec); |
1500 | return ret; | 1500 | return ret; |
1501 | } | 1501 | } |
@@ -1520,7 +1520,7 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored, | |||
1520 | if (!ret) { | 1520 | if (!ret) { |
1521 | req->ki_flags |= IOCB_WRITE; | 1521 | req->ki_flags |= IOCB_WRITE; |
1522 | file_start_write(file); | 1522 | file_start_write(file); |
1523 | ret = aio_ret(req, file->f_op->write_iter(req, &iter)); | 1523 | ret = aio_ret(req, call_write_iter(file, req, &iter)); |
1524 | /* | 1524 | /* |
1525 | * We release freeze protection in aio_complete(). Fool lockdep | 1525 | * We release freeze protection in aio_complete(). Fool lockdep |
1526 | * by telling it the lock got released so that it doesn't | 1526 | * by telling it the lock got released so that it doesn't |
diff --git a/fs/coda/file.c b/fs/coda/file.c index 6e0154eb6fcc..9d956cd6d46f 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -96,7 +96,7 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) | |||
96 | cfi->cfi_mapcount++; | 96 | cfi->cfi_mapcount++; |
97 | spin_unlock(&cii->c_lock); | 97 | spin_unlock(&cii->c_lock); |
98 | 98 | ||
99 | return host_file->f_op->mmap(host_file, vma); | 99 | return call_mmap(host_file, vma); |
100 | } | 100 | } |
101 | 101 | ||
102 | int coda_open(struct inode *coda_inode, struct file *coda_file) | 102 | int coda_open(struct inode *coda_inode, struct file *coda_file) |
diff --git a/fs/namei.c b/fs/namei.c index da689c9c005e..d41fab78798b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -672,17 +672,15 @@ static bool legitimize_links(struct nameidata *nd) | |||
672 | /** | 672 | /** |
673 | * unlazy_walk - try to switch to ref-walk mode. | 673 | * unlazy_walk - try to switch to ref-walk mode. |
674 | * @nd: nameidata pathwalk data | 674 | * @nd: nameidata pathwalk data |
675 | * @dentry: child of nd->path.dentry or NULL | ||
676 | * @seq: seq number to check dentry against | ||
677 | * Returns: 0 on success, -ECHILD on failure | 675 | * Returns: 0 on success, -ECHILD on failure |
678 | * | 676 | * |
679 | * unlazy_walk attempts to legitimize the current nd->path, nd->root and dentry | 677 | * unlazy_walk attempts to legitimize the current nd->path and nd->root |
680 | * for ref-walk mode. @dentry must be a path found by a do_lookup call on | 678 | * for ref-walk mode. |
681 | * @nd or NULL. Must be called from rcu-walk context. | 679 | * Must be called from rcu-walk context. |
682 | * Nothing should touch nameidata between unlazy_walk() failure and | 680 | * Nothing should touch nameidata between unlazy_walk() failure and |
683 | * terminate_walk(). | 681 | * terminate_walk(). |
684 | */ | 682 | */ |
685 | static int unlazy_walk(struct nameidata *nd, struct dentry *dentry, unsigned seq) | 683 | static int unlazy_walk(struct nameidata *nd) |
686 | { | 684 | { |
687 | struct dentry *parent = nd->path.dentry; | 685 | struct dentry *parent = nd->path.dentry; |
688 | 686 | ||
@@ -691,33 +689,66 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry, unsigned seq | |||
691 | nd->flags &= ~LOOKUP_RCU; | 689 | nd->flags &= ~LOOKUP_RCU; |
692 | if (unlikely(!legitimize_links(nd))) | 690 | if (unlikely(!legitimize_links(nd))) |
693 | goto out2; | 691 | goto out2; |
692 | if (unlikely(!legitimize_path(nd, &nd->path, nd->seq))) | ||
693 | goto out1; | ||
694 | if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { | ||
695 | if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq))) | ||
696 | goto out; | ||
697 | } | ||
698 | rcu_read_unlock(); | ||
699 | BUG_ON(nd->inode != parent->d_inode); | ||
700 | return 0; | ||
701 | |||
702 | out2: | ||
703 | nd->path.mnt = NULL; | ||
704 | nd->path.dentry = NULL; | ||
705 | out1: | ||
706 | if (!(nd->flags & LOOKUP_ROOT)) | ||
707 | nd->root.mnt = NULL; | ||
708 | out: | ||
709 | rcu_read_unlock(); | ||
710 | return -ECHILD; | ||
711 | } | ||
712 | |||
713 | /** | ||
714 | * unlazy_child - try to switch to ref-walk mode. | ||
715 | * @nd: nameidata pathwalk data | ||
716 | * @dentry: child of nd->path.dentry | ||
717 | * @seq: seq number to check dentry against | ||
718 | * Returns: 0 on success, -ECHILD on failure | ||
719 | * | ||
720 | * unlazy_child attempts to legitimize the current nd->path, nd->root and dentry | ||
721 | * for ref-walk mode. @dentry must be a path found by a do_lookup call on | ||
722 | * @nd. Must be called from rcu-walk context. | ||
723 | * Nothing should touch nameidata between unlazy_child() failure and | ||
724 | * terminate_walk(). | ||
725 | */ | ||
726 | static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned seq) | ||
727 | { | ||
728 | BUG_ON(!(nd->flags & LOOKUP_RCU)); | ||
729 | |||
730 | nd->flags &= ~LOOKUP_RCU; | ||
731 | if (unlikely(!legitimize_links(nd))) | ||
732 | goto out2; | ||
694 | if (unlikely(!legitimize_mnt(nd->path.mnt, nd->m_seq))) | 733 | if (unlikely(!legitimize_mnt(nd->path.mnt, nd->m_seq))) |
695 | goto out2; | 734 | goto out2; |
696 | if (unlikely(!lockref_get_not_dead(&parent->d_lockref))) | 735 | if (unlikely(!lockref_get_not_dead(&nd->path.dentry->d_lockref))) |
697 | goto out1; | 736 | goto out1; |
698 | 737 | ||
699 | /* | 738 | /* |
700 | * For a negative lookup, the lookup sequence point is the parents | 739 | * We need to move both the parent and the dentry from the RCU domain |
701 | * sequence point, and it only needs to revalidate the parent dentry. | 740 | * to be properly refcounted. And the sequence number in the dentry |
702 | * | 741 | * validates *both* dentry counters, since we checked the sequence |
703 | * For a positive lookup, we need to move both the parent and the | 742 | * number of the parent after we got the child sequence number. So we |
704 | * dentry from the RCU domain to be properly refcounted. And the | 743 | * know the parent must still be valid if the child sequence number is |
705 | * sequence number in the dentry validates *both* dentry counters, | ||
706 | * since we checked the sequence number of the parent after we got | ||
707 | * the child sequence number. So we know the parent must still | ||
708 | * be valid if the child sequence number is still valid. | ||
709 | */ | 744 | */ |
710 | if (!dentry) { | 745 | if (unlikely(!lockref_get_not_dead(&dentry->d_lockref))) |
711 | if (read_seqcount_retry(&parent->d_seq, nd->seq)) | 746 | goto out; |
712 | goto out; | 747 | if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) { |
713 | BUG_ON(nd->inode != parent->d_inode); | 748 | rcu_read_unlock(); |
714 | } else { | 749 | dput(dentry); |
715 | if (!lockref_get_not_dead(&dentry->d_lockref)) | 750 | goto drop_root_mnt; |
716 | goto out; | ||
717 | if (read_seqcount_retry(&dentry->d_seq, seq)) | ||
718 | goto drop_dentry; | ||
719 | } | 751 | } |
720 | |||
721 | /* | 752 | /* |
722 | * Sequence counts matched. Now make sure that the root is | 753 | * Sequence counts matched. Now make sure that the root is |
723 | * still valid and get it if required. | 754 | * still valid and get it if required. |
@@ -733,10 +764,6 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry, unsigned seq | |||
733 | rcu_read_unlock(); | 764 | rcu_read_unlock(); |
734 | return 0; | 765 | return 0; |
735 | 766 | ||
736 | drop_dentry: | ||
737 | rcu_read_unlock(); | ||
738 | dput(dentry); | ||
739 | goto drop_root_mnt; | ||
740 | out2: | 767 | out2: |
741 | nd->path.mnt = NULL; | 768 | nd->path.mnt = NULL; |
742 | out1: | 769 | out1: |
@@ -749,27 +776,12 @@ drop_root_mnt: | |||
749 | return -ECHILD; | 776 | return -ECHILD; |
750 | } | 777 | } |
751 | 778 | ||
752 | static int unlazy_link(struct nameidata *nd, struct path *link, unsigned seq) | ||
753 | { | ||
754 | if (unlikely(!legitimize_path(nd, link, seq))) { | ||
755 | drop_links(nd); | ||
756 | nd->depth = 0; | ||
757 | nd->flags &= ~LOOKUP_RCU; | ||
758 | nd->path.mnt = NULL; | ||
759 | nd->path.dentry = NULL; | ||
760 | if (!(nd->flags & LOOKUP_ROOT)) | ||
761 | nd->root.mnt = NULL; | ||
762 | rcu_read_unlock(); | ||
763 | } else if (likely(unlazy_walk(nd, NULL, 0)) == 0) { | ||
764 | return 0; | ||
765 | } | ||
766 | path_put(link); | ||
767 | return -ECHILD; | ||
768 | } | ||
769 | |||
770 | static inline int d_revalidate(struct dentry *dentry, unsigned int flags) | 779 | static inline int d_revalidate(struct dentry *dentry, unsigned int flags) |
771 | { | 780 | { |
772 | return dentry->d_op->d_revalidate(dentry, flags); | 781 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) |
782 | return dentry->d_op->d_revalidate(dentry, flags); | ||
783 | else | ||
784 | return 1; | ||
773 | } | 785 | } |
774 | 786 | ||
775 | /** | 787 | /** |
@@ -790,7 +802,7 @@ static int complete_walk(struct nameidata *nd) | |||
790 | if (nd->flags & LOOKUP_RCU) { | 802 | if (nd->flags & LOOKUP_RCU) { |
791 | if (!(nd->flags & LOOKUP_ROOT)) | 803 | if (!(nd->flags & LOOKUP_ROOT)) |
792 | nd->root.mnt = NULL; | 804 | nd->root.mnt = NULL; |
793 | if (unlikely(unlazy_walk(nd, NULL, 0))) | 805 | if (unlikely(unlazy_walk(nd))) |
794 | return -ECHILD; | 806 | return -ECHILD; |
795 | } | 807 | } |
796 | 808 | ||
@@ -1016,7 +1028,7 @@ const char *get_link(struct nameidata *nd) | |||
1016 | touch_atime(&last->link); | 1028 | touch_atime(&last->link); |
1017 | cond_resched(); | 1029 | cond_resched(); |
1018 | } else if (atime_needs_update_rcu(&last->link, inode)) { | 1030 | } else if (atime_needs_update_rcu(&last->link, inode)) { |
1019 | if (unlikely(unlazy_walk(nd, NULL, 0))) | 1031 | if (unlikely(unlazy_walk(nd))) |
1020 | return ERR_PTR(-ECHILD); | 1032 | return ERR_PTR(-ECHILD); |
1021 | touch_atime(&last->link); | 1033 | touch_atime(&last->link); |
1022 | } | 1034 | } |
@@ -1035,7 +1047,7 @@ const char *get_link(struct nameidata *nd) | |||
1035 | if (nd->flags & LOOKUP_RCU) { | 1047 | if (nd->flags & LOOKUP_RCU) { |
1036 | res = get(NULL, inode, &last->done); | 1048 | res = get(NULL, inode, &last->done); |
1037 | if (res == ERR_PTR(-ECHILD)) { | 1049 | if (res == ERR_PTR(-ECHILD)) { |
1038 | if (unlikely(unlazy_walk(nd, NULL, 0))) | 1050 | if (unlikely(unlazy_walk(nd))) |
1039 | return ERR_PTR(-ECHILD); | 1051 | return ERR_PTR(-ECHILD); |
1040 | res = get(dentry, inode, &last->done); | 1052 | res = get(dentry, inode, &last->done); |
1041 | } | 1053 | } |
@@ -1469,19 +1481,14 @@ static struct dentry *lookup_dcache(const struct qstr *name, | |||
1469 | struct dentry *dir, | 1481 | struct dentry *dir, |
1470 | unsigned int flags) | 1482 | unsigned int flags) |
1471 | { | 1483 | { |
1472 | struct dentry *dentry; | 1484 | struct dentry *dentry = d_lookup(dir, name); |
1473 | int error; | ||
1474 | |||
1475 | dentry = d_lookup(dir, name); | ||
1476 | if (dentry) { | 1485 | if (dentry) { |
1477 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) { | 1486 | int error = d_revalidate(dentry, flags); |
1478 | error = d_revalidate(dentry, flags); | 1487 | if (unlikely(error <= 0)) { |
1479 | if (unlikely(error <= 0)) { | 1488 | if (!error) |
1480 | if (!error) | 1489 | d_invalidate(dentry); |
1481 | d_invalidate(dentry); | 1490 | dput(dentry); |
1482 | dput(dentry); | 1491 | return ERR_PTR(error); |
1483 | return ERR_PTR(error); | ||
1484 | } | ||
1485 | } | 1492 | } |
1486 | } | 1493 | } |
1487 | return dentry; | 1494 | return dentry; |
@@ -1546,7 +1553,7 @@ static int lookup_fast(struct nameidata *nd, | |||
1546 | bool negative; | 1553 | bool negative; |
1547 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); | 1554 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); |
1548 | if (unlikely(!dentry)) { | 1555 | if (unlikely(!dentry)) { |
1549 | if (unlazy_walk(nd, NULL, 0)) | 1556 | if (unlazy_walk(nd)) |
1550 | return -ECHILD; | 1557 | return -ECHILD; |
1551 | return 0; | 1558 | return 0; |
1552 | } | 1559 | } |
@@ -1571,14 +1578,8 @@ static int lookup_fast(struct nameidata *nd, | |||
1571 | return -ECHILD; | 1578 | return -ECHILD; |
1572 | 1579 | ||
1573 | *seqp = seq; | 1580 | *seqp = seq; |
1574 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) | 1581 | status = d_revalidate(dentry, nd->flags); |
1575 | status = d_revalidate(dentry, nd->flags); | 1582 | if (likely(status > 0)) { |
1576 | if (unlikely(status <= 0)) { | ||
1577 | if (unlazy_walk(nd, dentry, seq)) | ||
1578 | return -ECHILD; | ||
1579 | if (status == -ECHILD) | ||
1580 | status = d_revalidate(dentry, nd->flags); | ||
1581 | } else { | ||
1582 | /* | 1583 | /* |
1583 | * Note: do negative dentry check after revalidation in | 1584 | * Note: do negative dentry check after revalidation in |
1584 | * case that drops it. | 1585 | * case that drops it. |
@@ -1589,15 +1590,17 @@ static int lookup_fast(struct nameidata *nd, | |||
1589 | path->dentry = dentry; | 1590 | path->dentry = dentry; |
1590 | if (likely(__follow_mount_rcu(nd, path, inode, seqp))) | 1591 | if (likely(__follow_mount_rcu(nd, path, inode, seqp))) |
1591 | return 1; | 1592 | return 1; |
1592 | if (unlazy_walk(nd, dentry, seq)) | ||
1593 | return -ECHILD; | ||
1594 | } | 1593 | } |
1594 | if (unlazy_child(nd, dentry, seq)) | ||
1595 | return -ECHILD; | ||
1596 | if (unlikely(status == -ECHILD)) | ||
1597 | /* we'd been told to redo it in non-rcu mode */ | ||
1598 | status = d_revalidate(dentry, nd->flags); | ||
1595 | } else { | 1599 | } else { |
1596 | dentry = __d_lookup(parent, &nd->last); | 1600 | dentry = __d_lookup(parent, &nd->last); |
1597 | if (unlikely(!dentry)) | 1601 | if (unlikely(!dentry)) |
1598 | return 0; | 1602 | return 0; |
1599 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) | 1603 | status = d_revalidate(dentry, nd->flags); |
1600 | status = d_revalidate(dentry, nd->flags); | ||
1601 | } | 1604 | } |
1602 | if (unlikely(status <= 0)) { | 1605 | if (unlikely(status <= 0)) { |
1603 | if (!status) | 1606 | if (!status) |
@@ -1636,8 +1639,7 @@ again: | |||
1636 | if (IS_ERR(dentry)) | 1639 | if (IS_ERR(dentry)) |
1637 | goto out; | 1640 | goto out; |
1638 | if (unlikely(!d_in_lookup(dentry))) { | 1641 | if (unlikely(!d_in_lookup(dentry))) { |
1639 | if ((dentry->d_flags & DCACHE_OP_REVALIDATE) && | 1642 | if (!(flags & LOOKUP_NO_REVAL)) { |
1640 | !(flags & LOOKUP_NO_REVAL)) { | ||
1641 | int error = d_revalidate(dentry, flags); | 1643 | int error = d_revalidate(dentry, flags); |
1642 | if (unlikely(error <= 0)) { | 1644 | if (unlikely(error <= 0)) { |
1643 | if (!error) { | 1645 | if (!error) { |
@@ -1668,7 +1670,7 @@ static inline int may_lookup(struct nameidata *nd) | |||
1668 | int err = inode_permission(nd->inode, MAY_EXEC|MAY_NOT_BLOCK); | 1670 | int err = inode_permission(nd->inode, MAY_EXEC|MAY_NOT_BLOCK); |
1669 | if (err != -ECHILD) | 1671 | if (err != -ECHILD) |
1670 | return err; | 1672 | return err; |
1671 | if (unlazy_walk(nd, NULL, 0)) | 1673 | if (unlazy_walk(nd)) |
1672 | return -ECHILD; | 1674 | return -ECHILD; |
1673 | } | 1675 | } |
1674 | return inode_permission(nd->inode, MAY_EXEC); | 1676 | return inode_permission(nd->inode, MAY_EXEC); |
@@ -1703,9 +1705,17 @@ static int pick_link(struct nameidata *nd, struct path *link, | |||
1703 | error = nd_alloc_stack(nd); | 1705 | error = nd_alloc_stack(nd); |
1704 | if (unlikely(error)) { | 1706 | if (unlikely(error)) { |
1705 | if (error == -ECHILD) { | 1707 | if (error == -ECHILD) { |
1706 | if (unlikely(unlazy_link(nd, link, seq))) | 1708 | if (unlikely(!legitimize_path(nd, link, seq))) { |
1707 | return -ECHILD; | 1709 | drop_links(nd); |
1708 | error = nd_alloc_stack(nd); | 1710 | nd->depth = 0; |
1711 | nd->flags &= ~LOOKUP_RCU; | ||
1712 | nd->path.mnt = NULL; | ||
1713 | nd->path.dentry = NULL; | ||
1714 | if (!(nd->flags & LOOKUP_ROOT)) | ||
1715 | nd->root.mnt = NULL; | ||
1716 | rcu_read_unlock(); | ||
1717 | } else if (likely(unlazy_walk(nd)) == 0) | ||
1718 | error = nd_alloc_stack(nd); | ||
1709 | } | 1719 | } |
1710 | if (error) { | 1720 | if (error) { |
1711 | path_put(link); | 1721 | path_put(link); |
@@ -2122,7 +2132,7 @@ OK: | |||
2122 | } | 2132 | } |
2123 | if (unlikely(!d_can_lookup(nd->path.dentry))) { | 2133 | if (unlikely(!d_can_lookup(nd->path.dentry))) { |
2124 | if (nd->flags & LOOKUP_RCU) { | 2134 | if (nd->flags & LOOKUP_RCU) { |
2125 | if (unlazy_walk(nd, NULL, 0)) | 2135 | if (unlazy_walk(nd)) |
2126 | return -ECHILD; | 2136 | return -ECHILD; |
2127 | } | 2137 | } |
2128 | return -ENOTDIR; | 2138 | return -ENOTDIR; |
@@ -2579,7 +2589,7 @@ mountpoint_last(struct nameidata *nd) | |||
2579 | 2589 | ||
2580 | /* If we're in rcuwalk, drop out of it to handle last component */ | 2590 | /* If we're in rcuwalk, drop out of it to handle last component */ |
2581 | if (nd->flags & LOOKUP_RCU) { | 2591 | if (nd->flags & LOOKUP_RCU) { |
2582 | if (unlazy_walk(nd, NULL, 0)) | 2592 | if (unlazy_walk(nd)) |
2583 | return -ECHILD; | 2593 | return -ECHILD; |
2584 | } | 2594 | } |
2585 | 2595 | ||
@@ -3072,9 +3082,6 @@ static int lookup_open(struct nameidata *nd, struct path *path, | |||
3072 | if (d_in_lookup(dentry)) | 3082 | if (d_in_lookup(dentry)) |
3073 | break; | 3083 | break; |
3074 | 3084 | ||
3075 | if (!(dentry->d_flags & DCACHE_OP_REVALIDATE)) | ||
3076 | break; | ||
3077 | |||
3078 | error = d_revalidate(dentry, nd->flags); | 3085 | error = d_revalidate(dentry, nd->flags); |
3079 | if (likely(error > 0)) | 3086 | if (likely(error > 0)) |
3080 | break; | 3087 | break; |
@@ -3356,13 +3363,50 @@ out: | |||
3356 | return error; | 3363 | return error; |
3357 | } | 3364 | } |
3358 | 3365 | ||
3366 | struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) | ||
3367 | { | ||
3368 | static const struct qstr name = QSTR_INIT("/", 1); | ||
3369 | struct dentry *child = NULL; | ||
3370 | struct inode *dir = dentry->d_inode; | ||
3371 | struct inode *inode; | ||
3372 | int error; | ||
3373 | |||
3374 | /* we want directory to be writable */ | ||
3375 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); | ||
3376 | if (error) | ||
3377 | goto out_err; | ||
3378 | error = -EOPNOTSUPP; | ||
3379 | if (!dir->i_op->tmpfile) | ||
3380 | goto out_err; | ||
3381 | error = -ENOMEM; | ||
3382 | child = d_alloc(dentry, &name); | ||
3383 | if (unlikely(!child)) | ||
3384 | goto out_err; | ||
3385 | error = dir->i_op->tmpfile(dir, child, mode); | ||
3386 | if (error) | ||
3387 | goto out_err; | ||
3388 | error = -ENOENT; | ||
3389 | inode = child->d_inode; | ||
3390 | if (unlikely(!inode)) | ||
3391 | goto out_err; | ||
3392 | if (!(open_flag & O_EXCL)) { | ||
3393 | spin_lock(&inode->i_lock); | ||
3394 | inode->i_state |= I_LINKABLE; | ||
3395 | spin_unlock(&inode->i_lock); | ||
3396 | } | ||
3397 | return child; | ||
3398 | |||
3399 | out_err: | ||
3400 | dput(child); | ||
3401 | return ERR_PTR(error); | ||
3402 | } | ||
3403 | EXPORT_SYMBOL(vfs_tmpfile); | ||
3404 | |||
3359 | static int do_tmpfile(struct nameidata *nd, unsigned flags, | 3405 | static int do_tmpfile(struct nameidata *nd, unsigned flags, |
3360 | const struct open_flags *op, | 3406 | const struct open_flags *op, |
3361 | struct file *file, int *opened) | 3407 | struct file *file, int *opened) |
3362 | { | 3408 | { |
3363 | static const struct qstr name = QSTR_INIT("/", 1); | ||
3364 | struct dentry *child; | 3409 | struct dentry *child; |
3365 | struct inode *dir; | ||
3366 | struct path path; | 3410 | struct path path; |
3367 | int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path); | 3411 | int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path); |
3368 | if (unlikely(error)) | 3412 | if (unlikely(error)) |
@@ -3370,25 +3414,12 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags, | |||
3370 | error = mnt_want_write(path.mnt); | 3414 | error = mnt_want_write(path.mnt); |
3371 | if (unlikely(error)) | 3415 | if (unlikely(error)) |
3372 | goto out; | 3416 | goto out; |
3373 | dir = path.dentry->d_inode; | 3417 | child = vfs_tmpfile(path.dentry, op->mode, op->open_flag); |
3374 | /* we want directory to be writable */ | 3418 | error = PTR_ERR(child); |
3375 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); | 3419 | if (unlikely(IS_ERR(child))) |
3376 | if (error) | ||
3377 | goto out2; | 3420 | goto out2; |
3378 | if (!dir->i_op->tmpfile) { | ||
3379 | error = -EOPNOTSUPP; | ||
3380 | goto out2; | ||
3381 | } | ||
3382 | child = d_alloc(path.dentry, &name); | ||
3383 | if (unlikely(!child)) { | ||
3384 | error = -ENOMEM; | ||
3385 | goto out2; | ||
3386 | } | ||
3387 | dput(path.dentry); | 3421 | dput(path.dentry); |
3388 | path.dentry = child; | 3422 | path.dentry = child; |
3389 | error = dir->i_op->tmpfile(dir, child, op->mode); | ||
3390 | if (error) | ||
3391 | goto out2; | ||
3392 | audit_inode(nd->name, child, 0); | 3423 | audit_inode(nd->name, child, 0); |
3393 | /* Don't check for other permissions, the inode was just created */ | 3424 | /* Don't check for other permissions, the inode was just created */ |
3394 | error = may_open(&path, 0, op->open_flag); | 3425 | error = may_open(&path, 0, op->open_flag); |
@@ -3399,14 +3430,8 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags, | |||
3399 | if (error) | 3430 | if (error) |
3400 | goto out2; | 3431 | goto out2; |
3401 | error = open_check_o_direct(file); | 3432 | error = open_check_o_direct(file); |
3402 | if (error) { | 3433 | if (error) |
3403 | fput(file); | 3434 | fput(file); |
3404 | } else if (!(op->open_flag & O_EXCL)) { | ||
3405 | struct inode *inode = file_inode(file); | ||
3406 | spin_lock(&inode->i_lock); | ||
3407 | inode->i_state |= I_LINKABLE; | ||
3408 | spin_unlock(&inode->i_lock); | ||
3409 | } | ||
3410 | out2: | 3435 | out2: |
3411 | mnt_drop_write(path.mnt); | 3436 | mnt_drop_write(path.mnt); |
3412 | out: | 3437 | out: |
@@ -301,12 +301,10 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
301 | if (S_ISFIFO(inode->i_mode)) | 301 | if (S_ISFIFO(inode->i_mode)) |
302 | return -ESPIPE; | 302 | return -ESPIPE; |
303 | 303 | ||
304 | /* | 304 | if (S_ISDIR(inode->i_mode)) |
305 | * Let individual file system decide if it supports preallocation | 305 | return -EISDIR; |
306 | * for directories or not. | 306 | |
307 | */ | 307 | if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) |
308 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && | ||
309 | !S_ISBLK(inode->i_mode)) | ||
310 | return -ENODEV; | 308 | return -ENODEV; |
311 | 309 | ||
312 | /* Check for wrap through zero too */ | 310 | /* Check for wrap through zero too */ |
@@ -316,7 +314,7 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
316 | if (!file->f_op->fallocate) | 314 | if (!file->f_op->fallocate) |
317 | return -EOPNOTSUPP; | 315 | return -EOPNOTSUPP; |
318 | 316 | ||
319 | sb_start_write(inode->i_sb); | 317 | file_start_write(file); |
320 | ret = file->f_op->fallocate(file, mode, offset, len); | 318 | ret = file->f_op->fallocate(file, mode, offset, len); |
321 | 319 | ||
322 | /* | 320 | /* |
@@ -329,7 +327,7 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
329 | if (ret == 0) | 327 | if (ret == 0) |
330 | fsnotify_modify(file); | 328 | fsnotify_modify(file); |
331 | 329 | ||
332 | sb_end_write(inode->i_sb); | 330 | file_end_write(file); |
333 | return ret; | 331 | return ret; |
334 | } | 332 | } |
335 | EXPORT_SYMBOL_GPL(vfs_fallocate); | 333 | EXPORT_SYMBOL_GPL(vfs_fallocate); |
diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index c48859f16e7b..67c24351a67f 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c | |||
@@ -115,6 +115,13 @@ static struct inode *orangefs_alloc_inode(struct super_block *sb) | |||
115 | return &orangefs_inode->vfs_inode; | 115 | return &orangefs_inode->vfs_inode; |
116 | } | 116 | } |
117 | 117 | ||
118 | static void orangefs_i_callback(struct rcu_head *head) | ||
119 | { | ||
120 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
121 | struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); | ||
122 | kmem_cache_free(orangefs_inode_cache, orangefs_inode); | ||
123 | } | ||
124 | |||
118 | static void orangefs_destroy_inode(struct inode *inode) | 125 | static void orangefs_destroy_inode(struct inode *inode) |
119 | { | 126 | { |
120 | struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); | 127 | struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); |
@@ -123,7 +130,7 @@ static void orangefs_destroy_inode(struct inode *inode) | |||
123 | "%s: deallocated %p destroying inode %pU\n", | 130 | "%s: deallocated %p destroying inode %pU\n", |
124 | __func__, orangefs_inode, get_khandle_from_ino(inode)); | 131 | __func__, orangefs_inode, get_khandle_from_ino(inode)); |
125 | 132 | ||
126 | kmem_cache_free(orangefs_inode_cache, orangefs_inode); | 133 | call_rcu(&inode->i_rcu, orangefs_i_callback); |
127 | } | 134 | } |
128 | 135 | ||
129 | /* | 136 | /* |
diff --git a/fs/read_write.c b/fs/read_write.c index 5816d4c4cab0..f2ed9fdc98fd 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -23,9 +23,6 @@ | |||
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <asm/unistd.h> | 24 | #include <asm/unistd.h> |
25 | 25 | ||
26 | typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); | ||
27 | typedef ssize_t (*iter_fn_t)(struct kiocb *, struct iov_iter *); | ||
28 | |||
29 | const struct file_operations generic_ro_fops = { | 26 | const struct file_operations generic_ro_fops = { |
30 | .llseek = generic_file_llseek, | 27 | .llseek = generic_file_llseek, |
31 | .read_iter = generic_file_read_iter, | 28 | .read_iter = generic_file_read_iter, |
@@ -370,7 +367,7 @@ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos) | |||
370 | kiocb.ki_pos = *ppos; | 367 | kiocb.ki_pos = *ppos; |
371 | 368 | ||
372 | iter->type |= READ; | 369 | iter->type |= READ; |
373 | ret = file->f_op->read_iter(&kiocb, iter); | 370 | ret = call_read_iter(file, &kiocb, iter); |
374 | BUG_ON(ret == -EIOCBQUEUED); | 371 | BUG_ON(ret == -EIOCBQUEUED); |
375 | if (ret > 0) | 372 | if (ret > 0) |
376 | *ppos = kiocb.ki_pos; | 373 | *ppos = kiocb.ki_pos; |
@@ -390,7 +387,7 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos) | |||
390 | kiocb.ki_pos = *ppos; | 387 | kiocb.ki_pos = *ppos; |
391 | 388 | ||
392 | iter->type |= WRITE; | 389 | iter->type |= WRITE; |
393 | ret = file->f_op->write_iter(&kiocb, iter); | 390 | ret = call_write_iter(file, &kiocb, iter); |
394 | BUG_ON(ret == -EIOCBQUEUED); | 391 | BUG_ON(ret == -EIOCBQUEUED); |
395 | if (ret > 0) | 392 | if (ret > 0) |
396 | *ppos = kiocb.ki_pos; | 393 | *ppos = kiocb.ki_pos; |
@@ -439,7 +436,7 @@ static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, lo | |||
439 | kiocb.ki_pos = *ppos; | 436 | kiocb.ki_pos = *ppos; |
440 | iov_iter_init(&iter, READ, &iov, 1, len); | 437 | iov_iter_init(&iter, READ, &iov, 1, len); |
441 | 438 | ||
442 | ret = filp->f_op->read_iter(&kiocb, &iter); | 439 | ret = call_read_iter(filp, &kiocb, &iter); |
443 | BUG_ON(ret == -EIOCBQUEUED); | 440 | BUG_ON(ret == -EIOCBQUEUED); |
444 | *ppos = kiocb.ki_pos; | 441 | *ppos = kiocb.ki_pos; |
445 | return ret; | 442 | return ret; |
@@ -496,7 +493,7 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t | |||
496 | kiocb.ki_pos = *ppos; | 493 | kiocb.ki_pos = *ppos; |
497 | iov_iter_init(&iter, WRITE, &iov, 1, len); | 494 | iov_iter_init(&iter, WRITE, &iov, 1, len); |
498 | 495 | ||
499 | ret = filp->f_op->write_iter(&kiocb, &iter); | 496 | ret = call_write_iter(filp, &kiocb, &iter); |
500 | BUG_ON(ret == -EIOCBQUEUED); | 497 | BUG_ON(ret == -EIOCBQUEUED); |
501 | if (ret > 0) | 498 | if (ret > 0) |
502 | *ppos = kiocb.ki_pos; | 499 | *ppos = kiocb.ki_pos; |
@@ -675,7 +672,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) | |||
675 | EXPORT_SYMBOL(iov_shorten); | 672 | EXPORT_SYMBOL(iov_shorten); |
676 | 673 | ||
677 | static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | 674 | static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, |
678 | loff_t *ppos, iter_fn_t fn, int flags) | 675 | loff_t *ppos, int type, int flags) |
679 | { | 676 | { |
680 | struct kiocb kiocb; | 677 | struct kiocb kiocb; |
681 | ssize_t ret; | 678 | ssize_t ret; |
@@ -692,7 +689,10 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | |||
692 | kiocb.ki_flags |= (IOCB_DSYNC | IOCB_SYNC); | 689 | kiocb.ki_flags |= (IOCB_DSYNC | IOCB_SYNC); |
693 | kiocb.ki_pos = *ppos; | 690 | kiocb.ki_pos = *ppos; |
694 | 691 | ||
695 | ret = fn(&kiocb, iter); | 692 | if (type == READ) |
693 | ret = call_read_iter(filp, &kiocb, iter); | ||
694 | else | ||
695 | ret = call_write_iter(filp, &kiocb, iter); | ||
696 | BUG_ON(ret == -EIOCBQUEUED); | 696 | BUG_ON(ret == -EIOCBQUEUED); |
697 | *ppos = kiocb.ki_pos; | 697 | *ppos = kiocb.ki_pos; |
698 | return ret; | 698 | return ret; |
@@ -700,7 +700,7 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | |||
700 | 700 | ||
701 | /* Do it by hand, with file-ops */ | 701 | /* Do it by hand, with file-ops */ |
702 | static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, | 702 | static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, |
703 | loff_t *ppos, io_fn_t fn, int flags) | 703 | loff_t *ppos, int type, int flags) |
704 | { | 704 | { |
705 | ssize_t ret = 0; | 705 | ssize_t ret = 0; |
706 | 706 | ||
@@ -711,7 +711,13 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, | |||
711 | struct iovec iovec = iov_iter_iovec(iter); | 711 | struct iovec iovec = iov_iter_iovec(iter); |
712 | ssize_t nr; | 712 | ssize_t nr; |
713 | 713 | ||
714 | nr = fn(filp, iovec.iov_base, iovec.iov_len, ppos); | 714 | if (type == READ) { |
715 | nr = filp->f_op->read(filp, iovec.iov_base, | ||
716 | iovec.iov_len, ppos); | ||
717 | } else { | ||
718 | nr = filp->f_op->write(filp, iovec.iov_base, | ||
719 | iovec.iov_len, ppos); | ||
720 | } | ||
715 | 721 | ||
716 | if (nr < 0) { | 722 | if (nr < 0) { |
717 | if (!ret) | 723 | if (!ret) |
@@ -834,50 +840,32 @@ out: | |||
834 | return ret; | 840 | return ret; |
835 | } | 841 | } |
836 | 842 | ||
837 | static ssize_t do_readv_writev(int type, struct file *file, | 843 | static ssize_t __do_readv_writev(int type, struct file *file, |
838 | const struct iovec __user * uvector, | 844 | struct iov_iter *iter, loff_t *pos, int flags) |
839 | unsigned long nr_segs, loff_t *pos, | ||
840 | int flags) | ||
841 | { | 845 | { |
842 | size_t tot_len; | 846 | size_t tot_len; |
843 | struct iovec iovstack[UIO_FASTIOV]; | 847 | ssize_t ret = 0; |
844 | struct iovec *iov = iovstack; | ||
845 | struct iov_iter iter; | ||
846 | ssize_t ret; | ||
847 | io_fn_t fn; | ||
848 | iter_fn_t iter_fn; | ||
849 | |||
850 | ret = import_iovec(type, uvector, nr_segs, | ||
851 | ARRAY_SIZE(iovstack), &iov, &iter); | ||
852 | if (ret < 0) | ||
853 | return ret; | ||
854 | 848 | ||
855 | tot_len = iov_iter_count(&iter); | 849 | tot_len = iov_iter_count(iter); |
856 | if (!tot_len) | 850 | if (!tot_len) |
857 | goto out; | 851 | goto out; |
858 | ret = rw_verify_area(type, file, pos, tot_len); | 852 | ret = rw_verify_area(type, file, pos, tot_len); |
859 | if (ret < 0) | 853 | if (ret < 0) |
860 | goto out; | 854 | goto out; |
861 | 855 | ||
862 | if (type == READ) { | 856 | if (type != READ) |
863 | fn = file->f_op->read; | ||
864 | iter_fn = file->f_op->read_iter; | ||
865 | } else { | ||
866 | fn = (io_fn_t)file->f_op->write; | ||
867 | iter_fn = file->f_op->write_iter; | ||
868 | file_start_write(file); | 857 | file_start_write(file); |
869 | } | ||
870 | 858 | ||
871 | if (iter_fn) | 859 | if ((type == READ && file->f_op->read_iter) || |
872 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags); | 860 | (type == WRITE && file->f_op->write_iter)) |
861 | ret = do_iter_readv_writev(file, iter, pos, type, flags); | ||
873 | else | 862 | else |
874 | ret = do_loop_readv_writev(file, &iter, pos, fn, flags); | 863 | ret = do_loop_readv_writev(file, iter, pos, type, flags); |
875 | 864 | ||
876 | if (type != READ) | 865 | if (type != READ) |
877 | file_end_write(file); | 866 | file_end_write(file); |
878 | 867 | ||
879 | out: | 868 | out: |
880 | kfree(iov); | ||
881 | if ((ret + (type == READ)) > 0) { | 869 | if ((ret + (type == READ)) > 0) { |
882 | if (type == READ) | 870 | if (type == READ) |
883 | fsnotify_access(file); | 871 | fsnotify_access(file); |
@@ -887,6 +875,27 @@ out: | |||
887 | return ret; | 875 | return ret; |
888 | } | 876 | } |
889 | 877 | ||
878 | static ssize_t do_readv_writev(int type, struct file *file, | ||
879 | const struct iovec __user *uvector, | ||
880 | unsigned long nr_segs, loff_t *pos, | ||
881 | int flags) | ||
882 | { | ||
883 | struct iovec iovstack[UIO_FASTIOV]; | ||
884 | struct iovec *iov = iovstack; | ||
885 | struct iov_iter iter; | ||
886 | ssize_t ret; | ||
887 | |||
888 | ret = import_iovec(type, uvector, nr_segs, | ||
889 | ARRAY_SIZE(iovstack), &iov, &iter); | ||
890 | if (ret < 0) | ||
891 | return ret; | ||
892 | |||
893 | ret = __do_readv_writev(type, file, &iter, pos, flags); | ||
894 | kfree(iov); | ||
895 | |||
896 | return ret; | ||
897 | } | ||
898 | |||
890 | ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, | 899 | ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, |
891 | unsigned long vlen, loff_t *pos, int flags) | 900 | unsigned long vlen, loff_t *pos, int flags) |
892 | { | 901 | { |
@@ -1064,51 +1073,19 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1064 | unsigned long nr_segs, loff_t *pos, | 1073 | unsigned long nr_segs, loff_t *pos, |
1065 | int flags) | 1074 | int flags) |
1066 | { | 1075 | { |
1067 | compat_ssize_t tot_len; | ||
1068 | struct iovec iovstack[UIO_FASTIOV]; | 1076 | struct iovec iovstack[UIO_FASTIOV]; |
1069 | struct iovec *iov = iovstack; | 1077 | struct iovec *iov = iovstack; |
1070 | struct iov_iter iter; | 1078 | struct iov_iter iter; |
1071 | ssize_t ret; | 1079 | ssize_t ret; |
1072 | io_fn_t fn; | ||
1073 | iter_fn_t iter_fn; | ||
1074 | 1080 | ||
1075 | ret = compat_import_iovec(type, uvector, nr_segs, | 1081 | ret = compat_import_iovec(type, uvector, nr_segs, |
1076 | UIO_FASTIOV, &iov, &iter); | 1082 | UIO_FASTIOV, &iov, &iter); |
1077 | if (ret < 0) | 1083 | if (ret < 0) |
1078 | return ret; | 1084 | return ret; |
1079 | 1085 | ||
1080 | tot_len = iov_iter_count(&iter); | 1086 | ret = __do_readv_writev(type, file, &iter, pos, flags); |
1081 | if (!tot_len) | ||
1082 | goto out; | ||
1083 | ret = rw_verify_area(type, file, pos, tot_len); | ||
1084 | if (ret < 0) | ||
1085 | goto out; | ||
1086 | |||
1087 | if (type == READ) { | ||
1088 | fn = file->f_op->read; | ||
1089 | iter_fn = file->f_op->read_iter; | ||
1090 | } else { | ||
1091 | fn = (io_fn_t)file->f_op->write; | ||
1092 | iter_fn = file->f_op->write_iter; | ||
1093 | file_start_write(file); | ||
1094 | } | ||
1095 | |||
1096 | if (iter_fn) | ||
1097 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags); | ||
1098 | else | ||
1099 | ret = do_loop_readv_writev(file, &iter, pos, fn, flags); | ||
1100 | |||
1101 | if (type != READ) | ||
1102 | file_end_write(file); | ||
1103 | |||
1104 | out: | ||
1105 | kfree(iov); | 1087 | kfree(iov); |
1106 | if ((ret + (type == READ)) > 0) { | 1088 | |
1107 | if (type == READ) | ||
1108 | fsnotify_access(file); | ||
1109 | else | ||
1110 | fsnotify_modify(file); | ||
1111 | } | ||
1112 | return ret; | 1089 | return ret; |
1113 | } | 1090 | } |
1114 | 1091 | ||
@@ -1518,6 +1495,11 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, | |||
1518 | if (flags != 0) | 1495 | if (flags != 0) |
1519 | return -EINVAL; | 1496 | return -EINVAL; |
1520 | 1497 | ||
1498 | if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) | ||
1499 | return -EISDIR; | ||
1500 | if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) | ||
1501 | return -EINVAL; | ||
1502 | |||
1521 | ret = rw_verify_area(READ, file_in, &pos_in, len); | 1503 | ret = rw_verify_area(READ, file_in, &pos_in, len); |
1522 | if (unlikely(ret)) | 1504 | if (unlikely(ret)) |
1523 | return ret; | 1505 | return ret; |
@@ -1538,7 +1520,7 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, | |||
1538 | if (len == 0) | 1520 | if (len == 0) |
1539 | return 0; | 1521 | return 0; |
1540 | 1522 | ||
1541 | sb_start_write(inode_out->i_sb); | 1523 | file_start_write(file_out); |
1542 | 1524 | ||
1543 | /* | 1525 | /* |
1544 | * Try cloning first, this is supported by more file systems, and | 1526 | * Try cloning first, this is supported by more file systems, and |
@@ -1574,7 +1556,7 @@ done: | |||
1574 | inc_syscr(current); | 1556 | inc_syscr(current); |
1575 | inc_syscw(current); | 1557 | inc_syscw(current); |
1576 | 1558 | ||
1577 | sb_end_write(inode_out->i_sb); | 1559 | file_end_write(file_out); |
1578 | 1560 | ||
1579 | return ret; | 1561 | return ret; |
1580 | } | 1562 | } |
diff --git a/fs/splice.c b/fs/splice.c index 4ef78aa8ef61..eaafa3d8869a 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -307,7 +307,7 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
307 | idx = to.idx; | 307 | idx = to.idx; |
308 | init_sync_kiocb(&kiocb, in); | 308 | init_sync_kiocb(&kiocb, in); |
309 | kiocb.ki_pos = *ppos; | 309 | kiocb.ki_pos = *ppos; |
310 | ret = in->f_op->read_iter(&kiocb, &to); | 310 | ret = call_read_iter(in, &kiocb, &to); |
311 | if (ret > 0) { | 311 | if (ret > 0) { |
312 | *ppos = kiocb.ki_pos; | 312 | *ppos = kiocb.ki_pos; |
313 | file_accessed(in); | 313 | file_accessed(in); |
@@ -192,7 +192,7 @@ int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) | |||
192 | spin_unlock(&inode->i_lock); | 192 | spin_unlock(&inode->i_lock); |
193 | mark_inode_dirty_sync(inode); | 193 | mark_inode_dirty_sync(inode); |
194 | } | 194 | } |
195 | return file->f_op->fsync(file, start, end, datasync); | 195 | return call_fsync(file, start, end, datasync); |
196 | } | 196 | } |
197 | EXPORT_SYMBOL(vfs_fsync_range); | 197 | EXPORT_SYMBOL(vfs_fsync_range); |
198 | 198 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index c64f2cb7d364..52350947c670 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1567,6 +1567,9 @@ extern int vfs_unlink(struct inode *, struct dentry *, struct inode **); | |||
1567 | extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); | 1567 | extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); |
1568 | extern int vfs_whiteout(struct inode *, struct dentry *); | 1568 | extern int vfs_whiteout(struct inode *, struct dentry *); |
1569 | 1569 | ||
1570 | extern struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, | ||
1571 | int open_flag); | ||
1572 | |||
1570 | /* | 1573 | /* |
1571 | * VFS file helper functions. | 1574 | * VFS file helper functions. |
1572 | */ | 1575 | */ |
@@ -1718,6 +1721,29 @@ struct inode_operations { | |||
1718 | int (*set_acl)(struct inode *, struct posix_acl *, int); | 1721 | int (*set_acl)(struct inode *, struct posix_acl *, int); |
1719 | } ____cacheline_aligned; | 1722 | } ____cacheline_aligned; |
1720 | 1723 | ||
1724 | static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio, | ||
1725 | struct iov_iter *iter) | ||
1726 | { | ||
1727 | return file->f_op->read_iter(kio, iter); | ||
1728 | } | ||
1729 | |||
1730 | static inline ssize_t call_write_iter(struct file *file, struct kiocb *kio, | ||
1731 | struct iov_iter *iter) | ||
1732 | { | ||
1733 | return file->f_op->write_iter(kio, iter); | ||
1734 | } | ||
1735 | |||
1736 | static inline int call_mmap(struct file *file, struct vm_area_struct *vma) | ||
1737 | { | ||
1738 | return file->f_op->mmap(file, vma); | ||
1739 | } | ||
1740 | |||
1741 | static inline int call_fsync(struct file *file, loff_t start, loff_t end, | ||
1742 | int datasync) | ||
1743 | { | ||
1744 | return file->f_op->fsync(file, start, end, datasync); | ||
1745 | } | ||
1746 | |||
1721 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, | 1747 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, |
1722 | unsigned long nr_segs, unsigned long fast_segs, | 1748 | unsigned long nr_segs, unsigned long fast_segs, |
1723 | struct iovec *fast_pointer, | 1749 | struct iovec *fast_pointer, |
@@ -1744,19 +1770,6 @@ extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, | |||
1744 | extern int vfs_dedupe_file_range(struct file *file, | 1770 | extern int vfs_dedupe_file_range(struct file *file, |
1745 | struct file_dedupe_range *same); | 1771 | struct file_dedupe_range *same); |
1746 | 1772 | ||
1747 | static inline int do_clone_file_range(struct file *file_in, loff_t pos_in, | ||
1748 | struct file *file_out, loff_t pos_out, | ||
1749 | u64 len) | ||
1750 | { | ||
1751 | int ret; | ||
1752 | |||
1753 | sb_start_write(file_inode(file_out)->i_sb); | ||
1754 | ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len); | ||
1755 | sb_end_write(file_inode(file_out)->i_sb); | ||
1756 | |||
1757 | return ret; | ||
1758 | } | ||
1759 | |||
1760 | struct super_operations { | 1773 | struct super_operations { |
1761 | struct inode *(*alloc_inode)(struct super_block *sb); | 1774 | struct inode *(*alloc_inode)(struct super_block *sb); |
1762 | void (*destroy_inode)(struct inode *); | 1775 | void (*destroy_inode)(struct inode *); |
@@ -2568,6 +2581,19 @@ static inline void file_end_write(struct file *file) | |||
2568 | __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); | 2581 | __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); |
2569 | } | 2582 | } |
2570 | 2583 | ||
2584 | static inline int do_clone_file_range(struct file *file_in, loff_t pos_in, | ||
2585 | struct file *file_out, loff_t pos_out, | ||
2586 | u64 len) | ||
2587 | { | ||
2588 | int ret; | ||
2589 | |||
2590 | file_start_write(file_out); | ||
2591 | ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len); | ||
2592 | file_end_write(file_out); | ||
2593 | |||
2594 | return ret; | ||
2595 | } | ||
2596 | |||
2571 | /* | 2597 | /* |
2572 | * get_write_access() gets write permission for a file. | 2598 | * get_write_access() gets write permission for a file. |
2573 | * put_write_access() releases this write permission. | 2599 | * put_write_access() releases this write permission. |
@@ -423,7 +423,7 @@ static int shm_mmap(struct file *file, struct vm_area_struct *vma) | |||
423 | if (ret) | 423 | if (ret) |
424 | return ret; | 424 | return ret; |
425 | 425 | ||
426 | ret = sfd->file->f_op->mmap(sfd->file, vma); | 426 | ret = call_mmap(sfd->file, vma); |
427 | if (ret) { | 427 | if (ret) { |
428 | shm_close(vma); | 428 | shm_close(vma); |
429 | return ret; | 429 | return ret; |
@@ -452,7 +452,7 @@ static int shm_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
452 | 452 | ||
453 | if (!sfd->file->f_op->fsync) | 453 | if (!sfd->file->f_op->fsync) |
454 | return -EINVAL; | 454 | return -EINVAL; |
455 | return sfd->file->f_op->fsync(sfd->file, start, end, datasync); | 455 | return call_fsync(sfd->file, start, end, datasync); |
456 | } | 456 | } |
457 | 457 | ||
458 | static long shm_fallocate(struct file *file, int mode, loff_t offset, | 458 | static long shm_fallocate(struct file *file, int mode, loff_t offset, |
@@ -1672,7 +1672,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, | |||
1672 | * new file must not have been exposed to user-space, yet. | 1672 | * new file must not have been exposed to user-space, yet. |
1673 | */ | 1673 | */ |
1674 | vma->vm_file = get_file(file); | 1674 | vma->vm_file = get_file(file); |
1675 | error = file->f_op->mmap(file, vma); | 1675 | error = call_mmap(file, vma); |
1676 | if (error) | 1676 | if (error) |
1677 | goto unmap_and_free_vma; | 1677 | goto unmap_and_free_vma; |
1678 | 1678 | ||
diff --git a/mm/nommu.c b/mm/nommu.c index fe9f4fa4a7a7..5bbef9cb89eb 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1084,7 +1084,7 @@ static int do_mmap_shared_file(struct vm_area_struct *vma) | |||
1084 | { | 1084 | { |
1085 | int ret; | 1085 | int ret; |
1086 | 1086 | ||
1087 | ret = vma->vm_file->f_op->mmap(vma->vm_file, vma); | 1087 | ret = call_mmap(vma->vm_file, vma); |
1088 | if (ret == 0) { | 1088 | if (ret == 0) { |
1089 | vma->vm_region->vm_top = vma->vm_region->vm_end; | 1089 | vma->vm_region->vm_top = vma->vm_region->vm_end; |
1090 | return 0; | 1090 | return 0; |
@@ -1115,7 +1115,7 @@ static int do_mmap_private(struct vm_area_struct *vma, | |||
1115 | * - VM_MAYSHARE will be set if it may attempt to share | 1115 | * - VM_MAYSHARE will be set if it may attempt to share |
1116 | */ | 1116 | */ |
1117 | if (capabilities & NOMMU_MAP_DIRECT) { | 1117 | if (capabilities & NOMMU_MAP_DIRECT) { |
1118 | ret = vma->vm_file->f_op->mmap(vma->vm_file, vma); | 1118 | ret = call_mmap(vma->vm_file, vma); |
1119 | if (ret == 0) { | 1119 | if (ret == 0) { |
1120 | /* shouldn't return success if we're not sharing */ | 1120 | /* shouldn't return success if we're not sharing */ |
1121 | BUG_ON(!(vma->vm_flags & VM_MAYSHARE)); | 1121 | BUG_ON(!(vma->vm_flags & VM_MAYSHARE)); |