diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-11-14 00:40:33 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-12-05 19:11:57 -0500 |
commit | ba8f46135ab19a6bc3ac11a16e8455956e13f6b1 (patch) | |
tree | 671cb02680a103728bbfb95777f777e699107f7b | |
parent | c1d4dd27678fc6892e30ea3de4a7caf86f39df1c (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.c | 50 |
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 | */ |
2588 | static int | 2584 | static int |
2589 | mountpoint_last(struct nameidata *nd, struct path *path) | 2585 | mountpoint_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 | } |