}
 }
 
-static int trailing_symlink(struct nameidata *nd)
+static const char *trailing_symlink(struct nameidata *nd)
 {
        const char *s;
        int error = may_follow_link(nd);
        if (unlikely(error)) {
                terminate_walk(nd);
-               return error;
+               return ERR_PTR(error);
        }
        nd->flags |= LOOKUP_PARENT;
        nd->stack[0].name = NULL;
        s = get_link(nd);
        if (unlikely(IS_ERR(s))) {
                terminate_walk(nd);
-               return PTR_ERR(s);
+               return s;
        }
        if (unlikely(!s))
-               return 0;
-       return link_path_walk(s, nd);
+               s = "";
+       return s;
 }
 
 static inline int lookup_last(struct nameidata *nd)
 
        if (IS_ERR(s))
                return PTR_ERR(s);
-       err = link_path_walk(s, nd);
-       if (!err) {
-               while ((err = lookup_last(nd)) > 0) {
-                       err = trailing_symlink(nd);
-                       if (err)
-                               break;
+       while (!(err = link_path_walk(s, nd))
+               && ((err = lookup_last(nd)) > 0)) {
+               s = trailing_symlink(nd);
+               if (IS_ERR(s)) {
+                       err = PTR_ERR(s);
+                       break;
                }
        }
 
        int err;
        if (IS_ERR(s))
                return PTR_ERR(s);
-       err = link_path_walk(s, nd);
-       if (unlikely(err))
-               goto out;
-
-       while ((err = mountpoint_last(nd, path)) > 0) {
-               err = trailing_symlink(nd);
-               if (err)
+       while (!(err = link_path_walk(s, nd)) &&
+               (err = mountpoint_last(nd, path)) > 0) {
+               s = trailing_symlink(nd);
+               if (IS_ERR(s)) {
+                       err = PTR_ERR(s);
                        break;
+               }
        }
-out:
        path_cleanup(nd);
        return err;
 }
                put_filp(file);
                return ERR_CAST(s);
        }
-       error = link_path_walk(s, nd);
-       if (unlikely(error))
-               goto out;
-
-       while ((error = do_last(nd, file, op, &opened, pathname)) > 0) {
+       while (!(error = link_path_walk(s, nd)) &&
+               (error = do_last(nd, file, op, &opened, pathname)) > 0) {
                nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
-               error = trailing_symlink(nd);
-               if (unlikely(error))
+               s = trailing_symlink(nd);
+               if (IS_ERR(s)) {
+                       error = PTR_ERR(s);
                        break;
+               }
        }
-out:
        path_cleanup(nd);
 out2:
        if (!(opened & FILE_OPENED)) {