• Al Viro's avatar
    link_path_walk(): simplify stack handling · d8d4611a
    Al Viro authored
    
    
    We use nd->stack to store two things: pinning down the symlinks
    we are resolving and resuming the name traversal when a nested
    symlink is finished.
    
    Currently, nd->depth is used to keep track of both.  It's 0 when
    we call link_path_walk() for the first time (for the pathname
    itself) and 1 on all subsequent calls (for trailing symlinks,
    if any).  That's fine, as far as pinning symlinks goes - when
    handling a trailing symlink, the string we are interpreting
    is the body of symlink pinned down in nd->stack[0].  It's
    rather inconvenient with respect to handling nested symlinks,
    though - when we run out of a string we are currently interpreting,
    we need to decide whether it's a nested symlink (in which case
    we need to pick the string saved back when we started to interpret
    that nested symlink and resume its traversal) or not (in which
    case we are done with link_path_walk()).
    
    Current solution is a bit of a kludge - in handling of trailing symlink
    (in lookup_last() and open_last_lookups() we clear nd->stack[0].name.
    That allows link_path_walk() to use the following rules when
    running out of a string to interpret:
    	* if nd->depth is zero, we are at the end of pathname itself.
    	* if nd->depth is positive, check the saved string; for
    nested symlink it will be non-NULL, for trailing symlink - NULL.
    
    It works, but it's rather non-obvious.  Note that we have two sets:
    the set of symlinks currently being traversed and the set of postponed
    pathname tails.  The former is stored in nd->stack[0..nd->depth-1].link
    and it's valid throught the pathname resolution; the latter is valid only
    during an individual call of link_path_walk() and it occupies
    nd->stack[0..nd->depth-1].name for the first call of link_path_walk() and
    nd->stack[1..nd->depth-1].name for subsequent ones.  The kludge is basically
    a way to recognize the second set becoming empty.
    
    The things get simpler if we keep track of the second set's size
    explicitly and always store it in nd->stack[0..depth-1].name.
    We access the second set only inside link_path_walk(), so its
    size can live in a local variable; that way the check becomes
    trivial without the need of that kludge.
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    d8d4611a
namei.c 122 KB