summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-03-02 06:41:12 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2017-03-02 06:41:12 -0500
commitf6c99aad4d9f3521fe38e552fd2a2e12cdc52418 (patch)
tree29657fa7c68a5d206fc718d6a353ed26197e5906 /fs/namei.c
parent0695d7dc1d9f19b82ec2cae24856bddce278cfe6 (diff)
parent4675ac39b5dd5ff08dd8cb2be9ddd3cba778aa39 (diff)
Merge branch 'work.namei' into for-linus
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c183
1 files changed, 95 insertions, 88 deletions
diff --git a/fs/namei.c b/fs/namei.c
index da689c9c005e..07e292bbf479 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 */
685static int unlazy_walk(struct nameidata *nd, struct dentry *dentry, unsigned seq) 683static 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
702out2:
703 nd->path.mnt = NULL;
704 nd->path.dentry = NULL;
705out1:
706 if (!(nd->flags & LOOKUP_ROOT))
707 nd->root.mnt = NULL;
708out:
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 */
726static 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
736drop_dentry:
737 rcu_read_unlock();
738 dput(dentry);
739 goto drop_root_mnt;
740out2: 767out2:
741 nd->path.mnt = NULL; 768 nd->path.mnt = NULL;
742out1: 769out1:
@@ -749,27 +776,12 @@ drop_root_mnt:
749 return -ECHILD; 776 return -ECHILD;
750} 777}
751 778
752static 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
770static inline int d_revalidate(struct dentry *dentry, unsigned int flags) 779static 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;