namei: have terminate_walk() do put_link() on everything left
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 4 May 2015 12:34:59 +0000 (08:34 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 11 May 2015 02:20:11 +0000 (22:20 -0400)
All callers of terminate_walk() are followed by more or less
open-coded eqiuvalent of "do put_link() on everything left
in nd->stack".  Better done in terminate_walk() itself, and
when we go for RCU symlink traversal we'll have to do it
there anyway.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 26466fbc5b563e0e3eeb143bceed8dbc3b7db488..31da71753d7b952d9c6d254465cffecc7a15ce6f 100644 (file)
@@ -1562,6 +1562,8 @@ static void terminate_walk(struct nameidata *nd)
                        nd->root.mnt = NULL;
                rcu_read_unlock();
        }
+       while (unlikely(nd->depth))
+               put_link(nd);
 }
 
 /*
@@ -1856,8 +1858,6 @@ Walked:
                }
        }
        terminate_walk(nd);
-       while (unlikely(nd->depth))
-               put_link(nd);
        return err;
 OK:
        if (!nd->depth)         /* called from path_init(), done */
@@ -2374,8 +2374,6 @@ done:
        error = 0;
 out:
        terminate_walk(nd);
-       if (nd->depth)
-               put_link(nd);
        return error;
 }
 
@@ -2978,8 +2976,6 @@ static int do_last(struct nameidata *nd,
                error = handle_dots(nd, nd->last_type);
                if (unlikely(error)) {
                        terminate_walk(nd);
-                       if (nd->depth)
-                               put_link(nd);
                        return error;
                }
                goto finish_open;
@@ -3176,8 +3172,6 @@ out:
                mnt_drop_write(nd->path.mnt);
        path_put(&save_parent);
        terminate_walk(nd);
-       if (nd->depth)
-               put_link(nd);
        return error;
 
 exit_dput: