aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-11-14 00:40:33 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2016-12-05 19:11:57 -0500
commitba8f46135ab19a6bc3ac11a16e8455956e13f6b1 (patch)
tree671cb02680a103728bbfb95777f777e699107f7b
parentc1d4dd27678fc6892e30ea3de4a7caf86f39df1c (diff)
namei: saner calling conventions for mountpoint_last()
leave the result in nd->path, have caller do follow_mount() and copy it to the final destination. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 85d2097fec9a..ab4caccfe304 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2561,7 +2561,6 @@ EXPORT_SYMBOL(user_path_at_empty);
2561/** 2561/**
2562 * mountpoint_last - look up last component for umount 2562 * mountpoint_last - look up last component for umount
2563 * @nd: pathwalk nameidata - currently pointing at parent directory of "last" 2563 * @nd: pathwalk nameidata - currently pointing at parent directory of "last"
2564 * @path: pointer to container for result
2565 * 2564 *
2566 * This is a special lookup_last function just for umount. In this case, we 2565 * This is a special lookup_last function just for umount. In this case, we
2567 * need to resolve the path without doing any revalidation. 2566 * need to resolve the path without doing any revalidation.
@@ -2574,23 +2573,20 @@ EXPORT_SYMBOL(user_path_at_empty);
2574 * 2573 *
2575 * Returns: 2574 * Returns:
2576 * -error: if there was an error during lookup. This includes -ENOENT if the 2575 * -error: if there was an error during lookup. This includes -ENOENT if the
2577 * lookup found a negative dentry. The nd->path reference will also be 2576 * lookup found a negative dentry.
2578 * put in this case.
2579 * 2577 *
2580 * 0: if we successfully resolved nd->path and found it to not to be a 2578 * 0: if we successfully resolved nd->last and found it to not to be a
2581 * symlink that needs to be followed. "path" will also be populated. 2579 * symlink that needs to be followed.
2582 * The nd->path reference will also be put.
2583 * 2580 *
2584 * 1: if we successfully resolved nd->last and found it to be a symlink 2581 * 1: if we successfully resolved nd->last and found it to be a symlink
2585 * that needs to be followed. "path" will be populated with the path 2582 * that needs to be followed.
2586 * to the link, and nd->path will *not* be put.
2587 */ 2583 */
2588static int 2584static int
2589mountpoint_last(struct nameidata *nd, struct path *path) 2585mountpoint_last(struct nameidata *nd)
2590{ 2586{
2591 int error = 0; 2587 int error = 0;
2592 struct dentry *dentry;
2593 struct dentry *dir = nd->path.dentry; 2588 struct dentry *dir = nd->path.dentry;
2589 struct path path;
2594 2590
2595 /* If we're in rcuwalk, drop out of it to handle last component */ 2591 /* If we're in rcuwalk, drop out of it to handle last component */
2596 if (nd->flags & LOOKUP_RCU) { 2592 if (nd->flags & LOOKUP_RCU) {
@@ -2604,36 +2600,34 @@ mountpoint_last(struct nameidata *nd, struct path *path)
2604 error = handle_dots(nd, nd->last_type); 2600 error = handle_dots(nd, nd->last_type);
2605 if (error) 2601 if (error)
2606 return error; 2602 return error;
2607 dentry = dget(nd->path.dentry); 2603 path.dentry = dget(nd->path.dentry);
2608 } else { 2604 } else {
2609 dentry = d_lookup(dir, &nd->last); 2605 path.dentry = d_lookup(dir, &nd->last);
2610 if (!dentry) { 2606 if (!path.dentry) {
2611 /* 2607 /*
2612 * No cached dentry. Mounted dentries are pinned in the 2608 * No cached dentry. Mounted dentries are pinned in the
2613 * cache, so that means that this dentry is probably 2609 * cache, so that means that this dentry is probably
2614 * a symlink or the path doesn't actually point 2610 * a symlink or the path doesn't actually point
2615 * to a mounted dentry. 2611 * to a mounted dentry.
2616 */ 2612 */
2617 dentry = lookup_slow(&nd->last, dir, 2613 path.dentry = lookup_slow(&nd->last, dir,
2618 nd->flags | LOOKUP_NO_REVAL); 2614 nd->flags | LOOKUP_NO_REVAL);
2619 if (IS_ERR(dentry)) 2615 if (IS_ERR(path.dentry))
2620 return PTR_ERR(dentry); 2616 return PTR_ERR(path.dentry);
2621 } 2617 }
2622 } 2618 }
2623 if (d_is_negative(dentry)) { 2619 if (d_is_negative(path.dentry)) {
2624 dput(dentry); 2620 dput(path.dentry);
2625 return -ENOENT; 2621 return -ENOENT;
2626 } 2622 }
2627 if (nd->depth) 2623 if (nd->depth)
2628 put_link(nd); 2624 put_link(nd);
2629 path->dentry = dentry; 2625 path.mnt = nd->path.mnt;
2630 path->mnt = nd->path.mnt; 2626 error = should_follow_link(nd, &path, nd->flags & LOOKUP_FOLLOW,
2631 error = should_follow_link(nd, path, nd->flags & LOOKUP_FOLLOW, 2627 d_backing_inode(path.dentry), 0);
2632 d_backing_inode(dentry), 0);
2633 if (unlikely(error)) 2628 if (unlikely(error))
2634 return error; 2629 return error;
2635 mntget(path->mnt); 2630 path_to_nameidata(&path, nd);
2636 follow_mount(path);
2637 return 0; 2631 return 0;
2638} 2632}
2639 2633
@@ -2654,13 +2648,19 @@ path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
2654 if (IS_ERR(s)) 2648 if (IS_ERR(s))
2655 return PTR_ERR(s); 2649 return PTR_ERR(s);
2656 while (!(err = link_path_walk(s, nd)) && 2650 while (!(err = link_path_walk(s, nd)) &&
2657 (err = mountpoint_last(nd, path)) > 0) { 2651 (err = mountpoint_last(nd)) > 0) {
2658 s = trailing_symlink(nd); 2652 s = trailing_symlink(nd);
2659 if (IS_ERR(s)) { 2653 if (IS_ERR(s)) {
2660 err = PTR_ERR(s); 2654 err = PTR_ERR(s);
2661 break; 2655 break;
2662 } 2656 }
2663 } 2657 }
2658 if (!err) {
2659 *path = nd->path;
2660 nd->path.mnt = NULL;
2661 nd->path.dentry = NULL;
2662 follow_mount(path);
2663 }
2664 terminate_walk(nd); 2664 terminate_walk(nd);
2665 return err; 2665 return err;
2666} 2666}