aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-02-22 15:50:10 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-14 09:15:24 -0400
commit16c2cd7179881d5dd87779512ca5a0d657c64f62 (patch)
tree822d14ecf505cb3f53e2afe3e1e7867bb32ca346 /fs/namei.c
parentfe479a580dc9c737c4eb49ff7fdb31d41d2c7003 (diff)
untangle the "need_reval_dot" mess
instead of ad-hackery around need_reval_dot(), do the following: set a flag (LOOKUP_JUMPED) in the beginning of path, on absolute symlink traversal, on ".." and on procfs-style symlinks. Clear on normal components, leave unchanged on ".". Non-nested callers of link_path_walk() call handle_reval_path(), which checks that flag is set and that fs does want the final revalidate thing, then does ->d_revalidate(). In link_path_walk() all the return_reval stuff is gone. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c107
1 files changed, 44 insertions, 63 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 4521b5ff7c93..450b686e9682 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -613,19 +613,8 @@ do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd)
613 return dentry; 613 return dentry;
614} 614}
615 615
616static inline int need_reval_dot(struct dentry *dentry)
617{
618 if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE)))
619 return 0;
620
621 if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)))
622 return 0;
623
624 return 1;
625}
626
627/* 616/*
628 * force_reval_path - force revalidation of a dentry 617 * handle_reval_path - force revalidation of a dentry
629 * 618 *
630 * In some situations the path walking code will trust dentries without 619 * In some situations the path walking code will trust dentries without
631 * revalidating them. This causes problems for filesystems that depend on 620 * revalidating them. This causes problems for filesystems that depend on
@@ -639,27 +628,28 @@ static inline int need_reval_dot(struct dentry *dentry)
639 * invalidate the dentry. It's up to the caller to handle putting references 628 * invalidate the dentry. It's up to the caller to handle putting references
640 * to the path if necessary. 629 * to the path if necessary.
641 */ 630 */
642static int 631static inline int handle_reval_path(struct nameidata *nd)
643force_reval_path(struct path *path, struct nameidata *nd)
644{ 632{
633 struct dentry *dentry = nd->path.dentry;
645 int status; 634 int status;
646 struct dentry *dentry = path->dentry;
647 635
648 /* 636 if (likely(!(nd->flags & LOOKUP_JUMPED)))
649 * only check on filesystems where it's possible for the dentry to 637 return 0;
650 * become stale. 638
651 */ 639 if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE)))
652 if (!need_reval_dot(dentry))
653 return 0; 640 return 0;
654 641
642 if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)))
643 return 0;
644
645 /* Note: we do not d_invalidate() */
655 status = d_revalidate(dentry, nd); 646 status = d_revalidate(dentry, nd);
656 if (status > 0) 647 if (status > 0)
657 return 0; 648 return 0;
658 649
659 if (!status) { 650 if (!status)
660 d_invalidate(dentry);
661 status = -ESTALE; 651 status = -ESTALE;
662 } 652
663 return status; 653 return status;
664} 654}
665 655
@@ -728,6 +718,7 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
728 path_put(&nd->path); 718 path_put(&nd->path);
729 nd->path = nd->root; 719 nd->path = nd->root;
730 path_get(&nd->root); 720 path_get(&nd->root);
721 nd->flags |= LOOKUP_JUMPED;
731 } 722 }
732 nd->inode = nd->path.dentry->d_inode; 723 nd->inode = nd->path.dentry->d_inode;
733 724
@@ -779,11 +770,8 @@ __do_follow_link(const struct path *link, struct nameidata *nd, void **p)
779 error = 0; 770 error = 0;
780 if (s) 771 if (s)
781 error = __vfs_follow_link(nd, s); 772 error = __vfs_follow_link(nd, s);
782 else if (nd->last_type == LAST_BIND) { 773 else if (nd->last_type == LAST_BIND)
783 error = force_reval_path(&nd->path, nd); 774 nd->flags |= LOOKUP_JUMPED;
784 if (error)
785 path_put(&nd->path);
786 }
787 } 775 }
788 return error; 776 return error;
789} 777}
@@ -1351,7 +1339,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1351 while (*name=='/') 1339 while (*name=='/')
1352 name++; 1340 name++;
1353 if (!*name) 1341 if (!*name)
1354 goto return_reval; 1342 goto return_base;
1355 1343
1356 if (nd->depth) 1344 if (nd->depth)
1357 lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); 1345 lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
@@ -1385,12 +1373,16 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1385 type = LAST_NORM; 1373 type = LAST_NORM;
1386 if (this.name[0] == '.') switch (this.len) { 1374 if (this.name[0] == '.') switch (this.len) {
1387 case 2: 1375 case 2:
1388 if (this.name[1] == '.') 1376 if (this.name[1] == '.') {
1389 type = LAST_DOTDOT; 1377 type = LAST_DOTDOT;
1378 nd->flags |= LOOKUP_JUMPED;
1379 }
1390 break; 1380 break;
1391 case 1: 1381 case 1:
1392 type = LAST_DOT; 1382 type = LAST_DOT;
1393 } 1383 }
1384 if (likely(type == LAST_NORM))
1385 nd->flags &= ~LOOKUP_JUMPED;
1394 1386
1395 /* remove trailing slashes? */ 1387 /* remove trailing slashes? */
1396 if (!c) 1388 if (!c)
@@ -1456,7 +1448,7 @@ last_component:
1456 } else 1448 } else
1457 follow_dotdot(nd); 1449 follow_dotdot(nd);
1458 } 1450 }
1459 goto return_reval; 1451 goto return_base;
1460 } 1452 }
1461 err = do_lookup(nd, &this, &next, &inode); 1453 err = do_lookup(nd, &this, &next, &inode);
1462 if (err) 1454 if (err)
@@ -1483,24 +1475,6 @@ last_component:
1483lookup_parent: 1475lookup_parent:
1484 nd->last = this; 1476 nd->last = this;
1485 nd->last_type = type; 1477 nd->last_type = type;
1486 if (type == LAST_NORM)
1487 goto return_base;
1488return_reval:
1489 /*
1490 * We bypassed the ordinary revalidation routines.
1491 * We may need to check the cached dentry for staleness.
1492 */
1493 if (need_reval_dot(nd->path.dentry)) {
1494 if (nameidata_drop_rcu_last_maybe(nd))
1495 return -ECHILD;
1496 /* Note: we do not d_invalidate() */
1497 err = d_revalidate(nd->path.dentry, nd);
1498 if (!err)
1499 err = -ESTALE;
1500 if (err < 0)
1501 break;
1502 return 0;
1503 }
1504return_base: 1478return_base:
1505 if (nameidata_drop_rcu_last_maybe(nd)) 1479 if (nameidata_drop_rcu_last_maybe(nd))
1506 return -ECHILD; 1480 return -ECHILD;
@@ -1523,7 +1497,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, struct namei
1523 struct file *file; 1497 struct file *file;
1524 1498
1525 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1499 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1526 nd->flags = flags; 1500 nd->flags = flags | LOOKUP_JUMPED;
1527 nd->depth = 0; 1501 nd->depth = 0;
1528 nd->root.mnt = NULL; 1502 nd->root.mnt = NULL;
1529 nd->file = NULL; 1503 nd->file = NULL;
@@ -1630,6 +1604,9 @@ static int path_lookupat(int dfd, const char *name,
1630 br_read_unlock(vfsmount_lock); 1604 br_read_unlock(vfsmount_lock);
1631 } 1605 }
1632 1606
1607 if (!retval)
1608 retval = handle_reval_path(nd);
1609
1633 if (nd->file) { 1610 if (nd->file) {
1634 fput(nd->file); 1611 fput(nd->file);
1635 nd->file = NULL; 1612 nd->file = NULL;
@@ -1690,7 +1667,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1690 1667
1691 /* same as do_path_lookup */ 1668 /* same as do_path_lookup */
1692 nd->last_type = LAST_ROOT; 1669 nd->last_type = LAST_ROOT;
1693 nd->flags = flags; 1670 nd->flags = flags | LOOKUP_JUMPED;
1694 nd->depth = 0; 1671 nd->depth = 0;
1695 1672
1696 nd->path.dentry = dentry; 1673 nd->path.dentry = dentry;
@@ -1703,6 +1680,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1703 current->total_link_count = 0; 1680 current->total_link_count = 0;
1704 1681
1705 result = link_path_walk(name, nd); 1682 result = link_path_walk(name, nd);
1683 if (!result)
1684 result = handle_reval_path(nd);
1706 if (result == -ESTALE) { 1685 if (result == -ESTALE) {
1707 /* nd->path had been dropped */ 1686 /* nd->path had been dropped */
1708 current->total_link_count = 0; 1687 current->total_link_count = 0;
@@ -1710,8 +1689,11 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1710 nd->path.mnt = mnt; 1689 nd->path.mnt = mnt;
1711 nd->inode = dentry->d_inode; 1690 nd->inode = dentry->d_inode;
1712 path_get(&nd->path); 1691 path_get(&nd->path);
1713 nd->flags |= LOOKUP_REVAL; 1692 nd->flags = flags | LOOKUP_JUMPED | LOOKUP_REVAL;
1693
1714 result = link_path_walk(name, nd); 1694 result = link_path_walk(name, nd);
1695 if (!result)
1696 result = handle_reval_path(nd);
1715 } 1697 }
1716 if (unlikely(!result && !audit_dummy_context() && nd->path.dentry && 1698 if (unlikely(!result && !audit_dummy_context() && nd->path.dentry &&
1717 nd->inode)) 1699 nd->inode))
@@ -2198,30 +2180,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
2198{ 2180{
2199 struct dentry *dir = nd->path.dentry; 2181 struct dentry *dir = nd->path.dentry;
2200 struct file *filp; 2182 struct file *filp;
2201 int error = -EISDIR; 2183 int error;
2202 2184
2203 switch (nd->last_type) { 2185 switch (nd->last_type) {
2204 case LAST_DOTDOT: 2186 case LAST_DOTDOT:
2205 follow_dotdot(nd); 2187 follow_dotdot(nd);
2206 dir = nd->path.dentry; 2188 dir = nd->path.dentry;
2207 case LAST_DOT: 2189 case LAST_DOT:
2208 if (need_reval_dot(dir)) {
2209 int status = d_revalidate(nd->path.dentry, nd);
2210 if (!status)
2211 status = -ESTALE;
2212 if (status < 0) {
2213 error = status;
2214 goto exit;
2215 }
2216 }
2217 /* fallthrough */ 2190 /* fallthrough */
2218 case LAST_ROOT: 2191 case LAST_ROOT:
2192 error = handle_reval_path(nd);
2193 if (error)
2194 goto exit;
2195 error = -EISDIR;
2219 goto exit; 2196 goto exit;
2220 case LAST_BIND: 2197 case LAST_BIND:
2198 error = handle_reval_path(nd);
2199 if (error)
2200 goto exit;
2221 audit_inode(pathname, dir); 2201 audit_inode(pathname, dir);
2222 goto ok; 2202 goto ok;
2223 } 2203 }
2224 2204
2205 error = -EISDIR;
2225 /* trailing slashes? */ 2206 /* trailing slashes? */
2226 if (nd->last.name[nd->last.len]) 2207 if (nd->last.name[nd->last.len])
2227 goto exit; 2208 goto exit;
@@ -2422,7 +2403,7 @@ reval:
2422 /* 2403 /*
2423 * We have the parent and last component. 2404 * We have the parent and last component.
2424 */ 2405 */
2425 nd.flags = flags; 2406 nd.flags = (nd.flags & ~LOOKUP_PARENT) | flags;
2426 filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); 2407 filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
2427 while (unlikely(!filp)) { /* trailing symlink */ 2408 while (unlikely(!filp)) { /* trailing symlink */
2428 struct path link = path; 2409 struct path link = path;