lkml.org 
[lkml]   [2015]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2.6.32 01/38] [PATCH 01/38] dcache: Handle escaped paths in prepend_path
    2.6.32-longterm review patch.  If anyone has any objections, please let me know.

    ------------------

    commit cde93be45a8a90d8c264c776fab63487b5038a65 upstream.

    A rename can result in a dentry that by walking up d_parent
    will never reach it's mnt_root. For lack of a better term
    I call this an escaped path.

    prepend_path is called by four different functions __d_path,
    d_absolute_path, d_path, and getcwd.

    __d_path only wants to see paths are connected to the root it passes
    in. So __d_path needs prepend_path to return an error.

    d_absolute_path similarly wants to see paths that are connected to
    some root. Escaped paths are not connected to any mnt_root so
    d_absolute_path needs prepend_path to return an error greater
    than 1. So escaped paths will be treated like paths on lazily
    unmounted mounts.

    getcwd needs to prepend "(unreachable)" so getcwd also needs
    prepend_path to return an error.

    d_path is the interesting hold out. d_path just wants to print
    something, and does not care about the weird cases. Which raises
    the question what should be printed?

    Given that <escaped_path>/<anything> should result in -ENOENT I
    believe it is desirable for escaped paths to be printed as empty
    paths. As there are not really any meaninful path components when
    considered from the perspective of a mount tree.

    So tweak prepend_path to return an empty path with an new error
    code of 3 when it encounters an escaped path.

    Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    [bwh: For 2.6.32, implement the "(unreachable)" string in __d_path()]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    Signed-off-by: Willy Tarreau <w@1wt.eu>
    ---
    fs/dcache.c | 11 ++++++++++-
    1 file changed, 10 insertions(+), 1 deletion(-)

    diff --git a/fs/dcache.c b/fs/dcache.c
    index 44c0aea..07c4472 100644
    --- a/fs/dcache.c
    +++ b/fs/dcache.c
    @@ -1910,7 +1910,7 @@ char *__d_path(const struct path *path, struct path *root,
    struct dentry *dentry = path->dentry;
    struct vfsmount *vfsmnt = path->mnt;
    char *end = buffer + buflen;
    - char *retval;
    + char *retval, *tail;

    spin_lock(&vfsmount_lock);
    prepend(&end, &buflen, "\0", 1);
    @@ -1923,6 +1923,7 @@ char *__d_path(const struct path *path, struct path *root,
    /* Get '/' right */
    retval = end-1;
    *retval = '/';
    + tail = end;

    for (;;) {
    struct dentry * parent;
    @@ -1930,6 +1931,14 @@ char *__d_path(const struct path *path, struct path *root,
    if (dentry == root->dentry && vfsmnt == root->mnt)
    break;
    if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
    + /* Escaped? */
    + if (dentry != vfsmnt->mnt_root) {
    + buflen += (tail - end);
    + end = tail;
    + prepend(&end, &buflen, "(unreachable)/", 14);
    + retval = end;
    + goto out;
    + }
    /* Global root? */
    if (vfsmnt->mnt_parent == vfsmnt) {
    goto global_root;
    --
    1.7.12.2.21.g234cd45.dirty




    \
     
     \ /
      Last update: 2015-11-29 23:21    [W:9.508 / U:0.488 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site