int (*rename2) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *, unsigned int);
        int (*readlink) (struct dentry *, char __user *,int);
-       void * (*follow_link) (struct dentry *, struct nameidata *);
-       void (*put_link) (struct dentry *, struct nameidata *, void *);
+       const char *(*follow_link) (struct dentry *, void **, struct nameidata *);
+       void (*put_link) (struct dentry *, void *);
        void (*truncate) (struct inode *);
        int (*permission) (struct inode *, int, unsigned int);
        int (*get_acl)(struct inode *, int);
 
        int (*rename2) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *, unsigned int);
        int (*readlink) (struct dentry *, char __user *,int);
-        void * (*follow_link) (struct dentry *, struct nameidata *);
-        void (*put_link) (struct dentry *, struct nameidata *, void *);
+       const char *(*follow_link) (struct dentry *, void **, struct nameidata *);
+       void (*put_link) (struct dentry *, void *);
        int (*permission) (struct inode *, int);
        int (*get_acl)(struct inode *, int);
        int (*setattr) (struct dentry *, struct iattr *);
 
        return rc;
 }
 
-static void *ll_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *ll_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct inode *inode = d_inode(dentry);
        struct ptlrpc_request *request = NULL;
        }
        if (rc) {
                ptlrpc_req_finished(request);
-               request = NULL;
-               symname = ERR_PTR(rc);
+               return ERR_PTR(rc);
        }
 
-       nd_set_link(nd, symname);
        /* symname may contain a pointer to the request message buffer,
         * we delay request releasing until ll_put_link then.
         */
-       return request;
+       *cookie = request;
+       return symname;
 }
 
-static void ll_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+static void ll_put_link(struct dentry *dentry, void *cookie)
 {
        ptlrpc_req_finished(cookie);
 }
 
  *
  */
 
-static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *v9fs_vfs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct v9fs_session_info *v9ses = v9fs_dentry2v9ses(dentry);
        struct p9_fid *fid = v9fs_fid_lookup(dentry);
        struct p9_wstat *st;
+       char *res;
 
        p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
 
                kfree(st);
                return ERR_PTR(-EINVAL);
        }
-       if (strlen(st->extension) >= PATH_MAX)
-               st->extension[PATH_MAX - 1] = '\0';
-
-       nd_set_link(nd, st->extension);
+       res = st->extension;
        st->extension = NULL;
+       if (strlen(res) >= PATH_MAX)
+               res[PATH_MAX - 1] = '\0';
+
        p9stat_free(st);
        kfree(st);
-       return NULL;
+       return *cookie = res;
 }
 
 /**
 
  *
  */
 
-static void *
-v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
+static const char *
+v9fs_vfs_follow_link_dotl(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct p9_fid *fid = v9fs_fid_lookup(dentry);
        char *target;
        retval = p9_client_readlink(fid, &target);
        if (retval)
                return ERR_PTR(retval);
-       nd_set_link(nd, target);
-       return NULL;
+       return *cookie = target;
 }
 
 int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
 
 
 #include "autofs_i.h"
 
-static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *autofs4_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
        struct autofs_info *ino = autofs4_dentry_ino(dentry);
        if (ino && !autofs4_oz_mode(sbi))
                ino->last_used = jiffies;
-       nd_set_link(nd, d_inode(dentry)->i_private);
-       return NULL;
+       return d_inode(dentry)->i_private;
 }
 
 const struct inode_operations autofs4_symlink_inode_operations = {
 
 static struct inode *befs_alloc_inode(struct super_block *sb);
 static void befs_destroy_inode(struct inode *inode);
 static void befs_destroy_inodecache(void);
-static void *befs_follow_link(struct dentry *, struct nameidata *);
+static const char *befs_follow_link(struct dentry *, void **, struct nameidata *nd);
 static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
                        char **out, int *out_len);
 static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
  * The data stream become link name. Unless the LONG_SYMLINK
  * flag is set.
  */
-static void *
-befs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *
+befs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct super_block *sb = dentry->d_sb;
        struct befs_inode_info *befs_ino = BEFS_I(d_inode(dentry));
 
        if (len == 0) {
                befs_error(sb, "Long symlink with illegal length");
-               link = ERR_PTR(-EIO);
-       } else {
-               befs_debug(sb, "Follow long symlink");
-
-               link = kmalloc(len, GFP_NOFS);
-               if (!link) {
-                       link = ERR_PTR(-ENOMEM);
-               } else if (befs_read_lsymlink(sb, data, link, len) != len) {
-                       kfree(link);
-                       befs_error(sb, "Failed to read entire long symlink");
-                       link = ERR_PTR(-EIO);
-               } else {
-                       link[len - 1] = '\0';
-               }
+               return ERR_PTR(-EIO);
        }
-       nd_set_link(nd, link);
-       return NULL;
+       befs_debug(sb, "Follow long symlink");
+
+       link = kmalloc(len, GFP_NOFS);
+       if (!link)
+               return ERR_PTR(-ENOMEM);
+       if (befs_read_lsymlink(sb, data, link, len) != len) {
+               kfree(link);
+               befs_error(sb, "Failed to read entire long symlink");
+               return ERR_PTR(-EIO);
+       }
+       link[len - 1] = '\0';
+       return *cookie = link;
 }
 
 /*
 
 #endif
 
 /* Functions related to symlinks */
-extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
+extern const char *cifs_follow_link(struct dentry *direntry, void **cookie, struct nameidata *nd);
 extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
                         int buflen);
 extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
 
        return rc;
 }
 
-void *
-cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
+const char *
+cifs_follow_link(struct dentry *direntry, void **cookie, struct nameidata *nd)
 {
        struct inode *inode = d_inode(direntry);
        int rc = -ENOMEM;
 
        tlink = cifs_sb_tlink(cifs_sb);
        if (IS_ERR(tlink)) {
-               rc = PTR_ERR(tlink);
-               tlink = NULL;
-               goto out;
+               free_xid(xid);
+               return ERR_CAST(tlink);
        }
        tcon = tlink_tcon(tlink);
        server = tcon->ses->server;
 
        full_path = build_path_from_dentry(direntry);
-       if (!full_path)
-               goto out;
+       if (!full_path) {
+               free_xid(xid);
+               cifs_put_tlink(tlink);
+               return ERR_PTR(-ENOMEM);
+       }
 
        cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, inode);
 
                                                &target_path, cifs_sb);
 
        kfree(full_path);
-out:
+       free_xid(xid);
+       cifs_put_tlink(tlink);
        if (rc != 0) {
                kfree(target_path);
-               target_path = ERR_PTR(rc);
+               return ERR_PTR(rc);
        }
-
-       free_xid(xid);
-       if (tlink)
-               cifs_put_tlink(tlink);
-       nd_set_link(nd, target_path);
-       return NULL;
+       return *cookie = target_path;
 }
 
 int
 
 
 }
 
-static void *configfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *configfs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
-       int error = -ENOMEM;
        unsigned long page = get_zeroed_page(GFP_KERNEL);
+       int error;
 
-       if (page) {
-               error = configfs_getlink(dentry, (char *)page);
-               if (!error) {
-                       nd_set_link(nd, (char *)page);
-                       return (void *)page;
-               }
+       if (!page)
+               return ERR_PTR(-ENOMEM);
+
+       error = configfs_getlink(dentry, (char *)page);
+       if (!error) {
+               return *cookie = (void *)page;
        }
 
-       nd_set_link(nd, ERR_PTR(error));
-       return NULL;
+       free_page(page);
+       return ERR_PTR(error);
 }
 
-static void configfs_put_link(struct dentry *dentry, struct nameidata *nd,
-                             void *cookie)
+static void configfs_put_link(struct dentry *dentry, void *cookie)
 {
-       if (cookie) {
-               unsigned long page = (unsigned long)cookie;
-               free_page(page);
-       }
+       free_page((unsigned long)cookie);
 }
 
 const struct inode_operations configfs_symlink_inode_operations = {
 
        return rc ? ERR_PTR(rc) : buf;
 }
 
-static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *ecryptfs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        size_t len;
        char *buf = ecryptfs_readlink_lower(dentry, &len);
        if (IS_ERR(buf))
-               goto out;
+               return buf;
        fsstack_copy_attr_atime(d_inode(dentry),
                                d_inode(ecryptfs_dentry_to_lower(dentry)));
        buf[len] = '\0';
-out:
-       nd_set_link(nd, buf);
-       return NULL;
+       return *cookie = buf;
 }
 
 /**
 
 #include "xattr.h"
 
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
-static void *ext4_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *ext4_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct page *cpage = NULL;
        char *caddr, *paddr = NULL;
 
        ctx = ext4_get_fname_crypto_ctx(inode, inode->i_sb->s_blocksize);
        if (IS_ERR(ctx))
-               return ctx;
+               return ERR_CAST(ctx);
 
        if (ext4_inode_is_fast_symlink(inode)) {
                caddr = (char *) EXT4_I(inode)->i_data;
                cpage = read_mapping_page(inode->i_mapping, 0, NULL);
                if (IS_ERR(cpage)) {
                        ext4_put_fname_crypto_ctx(&ctx);
-                       return cpage;
+                       return ERR_CAST(cpage);
                }
                caddr = kmap(cpage);
                caddr[size] = 0;
        /* Null-terminate the name */
        if (res <= plen)
                paddr[res] = '\0';
-       nd_set_link(nd, paddr);
        ext4_put_fname_crypto_ctx(&ctx);
        if (cpage) {
                kunmap(cpage);
                page_cache_release(cpage);
        }
-       return NULL;
+       return *cookie = paddr;
 errout:
        ext4_put_fname_crypto_ctx(&ctx);
        if (cpage) {
 
        return err;
 }
 
-static void *f2fs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *f2fs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
-       struct page *page = page_follow_link_light(dentry, nd);
-
-       if (IS_ERR_OR_NULL(page))
-               return page;
-
-       /* this is broken symlink case */
-       if (*nd_get_link(nd) == 0) {
-               page_put_link(dentry, nd, page);
-               return ERR_PTR(-ENOENT);
+       const char *link = page_follow_link_light(dentry, cookie, nd);
+       if (!IS_ERR(link) && !*link) {
+               /* this is broken symlink case */
+               page_put_link(dentry, *cookie);
+               link = ERR_PTR(-ENOENT);
        }
-       return page;
+       return link;
 }
 
 static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
 
        return err;
 }
 
-static char *read_link(struct dentry *dentry)
+static const char *fuse_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct inode *inode = d_inode(dentry);
        struct fuse_conn *fc = get_fuse_conn(inode);
                link = ERR_PTR(ret);
        } else {
                link[ret] = '\0';
+               *cookie = link;
        }
        fuse_invalidate_atime(inode);
        return link;
 }
 
-static void free_link(char *link)
+static void fuse_put_link(struct dentry *dentry, void *cookie)
 {
-       if (!IS_ERR(link))
-               free_page((unsigned long) link);
-}
-
-static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       nd_set_link(nd, read_link(dentry));
-       return NULL;
-}
-
-static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
-{
-       free_link(nd_get_link(nd));
+       free_page((unsigned long) cookie);
 }
 
 static int fuse_dir_open(struct inode *inode, struct file *file)
 
  * Returns: 0 on success or error code
  */
 
-static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *gfs2_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
        struct gfs2_holder i_gh;
        error = gfs2_glock_nq(&i_gh);
        if (error) {
                gfs2_holder_uninit(&i_gh);
-               nd_set_link(nd, ERR_PTR(error));
-               return NULL;
+               return ERR_PTR(error);
        }
 
        size = (unsigned int)i_size_read(&ip->i_inode);
        brelse(dibh);
 out:
        gfs2_glock_dq_uninit(&i_gh);
-       nd_set_link(nd, buf);
-       return NULL;
+       if (!IS_ERR(buf))
+               *cookie = buf;
+       return buf;
 }
 
 /**
 
        .setattr        = hostfs_setattr,
 };
 
-static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *hostfs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        char *link = __getname();
        if (link) {
                }
                if (err < 0) {
                        __putname(link);
-                       link = ERR_PTR(err);
+                       return ERR_PTR(err);
                }
        } else {
-               link = ERR_PTR(-ENOMEM);
+               return ERR_PTR(-ENOMEM);
        }
 
-       nd_set_link(nd, link);
-       return NULL;
+       return *cookie = link;
 }
 
-static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+static void hostfs_put_link(struct dentry *dentry, void *cookie)
 {
-       char *s = nd_get_link(nd);
-       if (!IS_ERR(s))
-               __putname(s);
+       __putname(cookie);
 }
 
 static const struct inode_operations hostfs_link_iops = {
 
                                                    buflen);
 }
 
-static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *hppfs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
 
-       return d_inode(proc_dentry)->i_op->follow_link(proc_dentry, nd);
+       return d_inode(proc_dentry)->i_op->follow_link(proc_dentry, cookie, nd);
 }
 
-static void hppfs_put_link(struct dentry *dentry, struct nameidata *nd,
-                          void *cookie)
+static void hppfs_put_link(struct dentry *dentry, void *cookie)
 {
        struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
 
        if (d_inode(proc_dentry)->i_op->put_link)
-               d_inode(proc_dentry)->i_op->put_link(proc_dentry, nd, cookie);
+               d_inode(proc_dentry)->i_op->put_link(proc_dentry, cookie);
 }
 
 static const struct inode_operations hppfs_dir_iops = {
 
        return error;
 }
 
-static void *kernfs_iop_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *kernfs_iop_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        int error = -ENOMEM;
        unsigned long page = get_zeroed_page(GFP_KERNEL);
-       if (page) {
-               error = kernfs_getlink(dentry, (char *) page);
-               if (error < 0)
-                       free_page((unsigned long)page);
+       if (!page)
+               return ERR_PTR(-ENOMEM);
+       error = kernfs_getlink(dentry, (char *)page);
+       if (unlikely(error < 0)) {
+               free_page((unsigned long)page);
+               return ERR_PTR(error);
        }
-       nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);
-       return NULL;
+       return *cookie = (char *)page;
 }
 
-static void kernfs_iop_put_link(struct dentry *dentry, struct nameidata *nd,
-                               void *cookie)
+static void kernfs_iop_put_link(struct dentry *dentry, void *cookie)
 {
-       char *page = nd_get_link(nd);
-       if (!IS_ERR(page))
-               free_page((unsigned long)page);
+       free_page((unsigned long)cookie);
 }
 
 const struct inode_operations kernfs_symlink_iops = {
 
 }
 EXPORT_SYMBOL(noop_fsync);
 
-void kfree_put_link(struct dentry *dentry, struct nameidata *nd,
-                               void *cookie)
+void kfree_put_link(struct dentry *dentry, void *cookie)
 {
-       char *s = nd_get_link(nd);
-       if (!IS_ERR(s))
-               kfree(s);
+       kfree(cookie);
 }
 EXPORT_SYMBOL(kfree_put_link);
 
 }
 EXPORT_SYMBOL(simple_nosetlease);
 
-void *simple_follow_link(struct dentry *dentry, struct nameidata *nd)
+const char *simple_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
-       nd_set_link(nd, d_inode(dentry)->i_link);
-       return NULL;
+       return d_inode(dentry)->i_link;
 }
 EXPORT_SYMBOL(simple_follow_link);
 
 
        int             last_type;
        unsigned        depth;
        struct file     *base;
-       char *saved_names[MAX_NESTED_LINKS + 1];
 };
 
 /*
        nd->flags |= LOOKUP_JUMPED;
 }
 
-void nd_set_link(struct nameidata *nd, char *path)
-{
-       nd->saved_names[nd->depth] = path;
-}
-EXPORT_SYMBOL(nd_set_link);
-
-char *nd_get_link(struct nameidata *nd)
-{
-       return nd->saved_names[nd->depth];
-}
-EXPORT_SYMBOL(nd_get_link);
-
 static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
 {
        struct inode *inode = link->dentry->d_inode;
-       if (inode->i_op->put_link)
-               inode->i_op->put_link(link->dentry, nd, cookie);
+       if (cookie && inode->i_op->put_link)
+               inode->i_op->put_link(link->dentry, cookie);
        path_put(link);
 }
 
 {
        struct dentry *dentry = link->dentry;
        int error;
-       char *s;
+       const char *s;
 
        BUG_ON(nd->flags & LOOKUP_RCU);
 
        current->total_link_count++;
 
        touch_atime(link);
-       nd_set_link(nd, NULL);
 
        error = security_inode_follow_link(dentry);
        if (error)
                goto out_put_nd_path;
 
        nd->last_type = LAST_BIND;
-       *p = dentry->d_inode->i_op->follow_link(dentry, nd);
-       error = PTR_ERR(*p);
-       if (IS_ERR(*p))
+       *p = NULL;
+       s = dentry->d_inode->i_op->follow_link(dentry, p, nd);
+       error = PTR_ERR(s);
+       if (IS_ERR(s))
                goto out_put_nd_path;
 
        error = 0;
-       s = nd_get_link(nd);
        if (s) {
-               if (unlikely(IS_ERR(s))) {
-                       path_put(&nd->path);
-                       put_link(nd, link, *p);
-                       return PTR_ERR(s);
-               }
                if (*s == '/') {
                        if (!nd->root.mnt)
                                set_root(nd);
        return error;
 
 out_put_nd_path:
-       *p = NULL;
        path_put(&nd->path);
        path_put(link);
        return error;
  */
 int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
-       struct nameidata nd;
        void *cookie;
+       const char *link = dentry->d_inode->i_op->follow_link(dentry, &cookie, NULL);
        int res;
 
-       nd.depth = 0;
-       cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
-       if (IS_ERR(cookie))
-               return PTR_ERR(cookie);
-
-       res = readlink_copy(buffer, buflen, nd_get_link(&nd));
-       if (dentry->d_inode->i_op->put_link)
-               dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+       if (IS_ERR(link))
+               return PTR_ERR(link);
+       res = readlink_copy(buffer, buflen, link);
+       if (cookie && dentry->d_inode->i_op->put_link)
+               dentry->d_inode->i_op->put_link(dentry, cookie);
        return res;
 }
 EXPORT_SYMBOL(generic_readlink);
 }
 EXPORT_SYMBOL(page_readlink);
 
-void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
+const char *page_follow_link_light(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct page *page = NULL;
-       nd_set_link(nd, page_getlink(dentry, &page));
-       return page;
+       char *res = page_getlink(dentry, &page);
+       if (!IS_ERR(res))
+               *cookie = page;
+       return res;
 }
 EXPORT_SYMBOL(page_follow_link_light);
 
-void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+void page_put_link(struct dentry *dentry, void *cookie)
 {
        struct page *page = cookie;
-
-       if (page) {
-               kunmap(page);
-               page_cache_release(page);
-       }
+       kunmap(page);
+       page_cache_release(page);
 }
 EXPORT_SYMBOL(page_put_link);
 
 
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/string.h>
-#include <linux/namei.h>
 
 /* Symlink caching in the page cache is even more simplistic
  * and straight-forward than readdir caching.
        return -EIO;
 }
 
-static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *nfs_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct inode *inode = d_inode(dentry);
        struct page *page;
 
        err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
        if (err)
-               goto read_failed;
+               return err;
        page = read_cache_page(&inode->i_data, 0,
                                (filler_t *)nfs_symlink_filler, inode);
-       if (IS_ERR(page)) {
-               err = page;
-               goto read_failed;
-       }
-       nd_set_link(nd, kmap(page));
-       return page;
-
-read_failed:
-       nd_set_link(nd, err);
-       return NULL;
+       if (IS_ERR(page))
+               return ERR_CAST(page);
+       *cookie = page;
+       return kmap(page);
 }
 
 /*
 
        void *cookie;
 };
 
-static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *ovl_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
-       void *ret;
        struct dentry *realdentry;
        struct inode *realinode;
        struct ovl_link_data *data = NULL;
+       const char *ret;
 
        realdentry = ovl_dentry_real(dentry);
        realinode = realdentry->d_inode;
                data->realdentry = realdentry;
        }
 
-       ret = realinode->i_op->follow_link(realdentry, nd);
-       if (IS_ERR(ret)) {
+       ret = realinode->i_op->follow_link(realdentry, cookie, nd);
+       if (IS_ERR_OR_NULL(ret)) {
                kfree(data);
                return ret;
        }
 
        if (data)
-               data->cookie = ret;
+               data->cookie = *cookie;
 
-       return data;
+       *cookie = data;
+
+       return ret;
 }
 
-static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
+static void ovl_put_link(struct dentry *dentry, void *c)
 {
        struct inode *realinode;
        struct ovl_link_data *data = c;
                return;
 
        realinode = data->realdentry->d_inode;
-       realinode->i_op->put_link(data->realdentry, nd, data->cookie);
+       realinode->i_op->put_link(data->realdentry, data->cookie);
        kfree(data);
 }
 
 
                return -ENOENT;
 }
 
-static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *proc_pid_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct inode *inode = d_inode(dentry);
        struct path path;
 
 #include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/magic.h>
-#include <linux/namei.h>
 
 #include <asm/uaccess.h>
 
 };
 #endif
 
-static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *proc_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct proc_dir_entry *pde = PDE(d_inode(dentry));
        if (unlikely(!use_pde(pde)))
                return ERR_PTR(-EINVAL);
-       nd_set_link(nd, pde->data);
-       return pde;
+       *cookie = pde;
+       return pde->data;
 }
 
-static void proc_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
+static void proc_put_link(struct dentry *dentry, void *p)
 {
        unuse_pde(p);
 }
 
        &mntns_operations,
 };
 
-static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *proc_ns_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct inode *inode = d_inode(dentry);
        const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
 
 #include <linux/sched.h>
-#include <linux/namei.h>
 #include <linux/slab.h>
 #include <linux/pid_namespace.h>
 #include "internal.h"
        return readlink_copy(buffer, buflen, tmp);
 }
 
-static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *proc_self_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct pid_namespace *ns = dentry->d_sb->s_fs_info;
        pid_t tgid = task_tgid_nr_ns(current, ns);
-       char *name = ERR_PTR(-ENOENT);
-       if (tgid) {
-               /* 11 for max length of signed int in decimal + NULL term */
-               name = kmalloc(12, GFP_KERNEL);
-               if (!name)
-                       name = ERR_PTR(-ENOMEM);
-               else
-                       sprintf(name, "%d", tgid);
-       }
-       nd_set_link(nd, name);
-       return NULL;
+       char *name;
+
+       if (!tgid)
+               return ERR_PTR(-ENOENT);
+       /* 11 for max length of signed int in decimal + NULL term */
+       name = kmalloc(12, GFP_KERNEL);
+       if (!name)
+               return ERR_PTR(-ENOMEM);
+       sprintf(name, "%d", tgid);
+       return *cookie = name;
 }
 
 static const struct inode_operations proc_self_inode_operations = {
 
 #include <linux/sched.h>
-#include <linux/namei.h>
 #include <linux/slab.h>
 #include <linux/pid_namespace.h>
 #include "internal.h"
        return readlink_copy(buffer, buflen, tmp);
 }
 
-static void *proc_thread_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *proc_thread_self_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct pid_namespace *ns = dentry->d_sb->s_fs_info;
        pid_t tgid = task_tgid_nr_ns(current, ns);
        pid_t pid = task_pid_nr_ns(current, ns);
-       char *name = ERR_PTR(-ENOENT);
-       if (pid) {
-               name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, GFP_KERNEL);
-               if (!name)
-                       name = ERR_PTR(-ENOMEM);
-               else
-                       sprintf(name, "%d/task/%d", tgid, pid);
-       }
-       nd_set_link(nd, name);
-       return NULL;
+       char *name;
+
+       if (!pid)
+               return ERR_PTR(-ENOENT);
+       name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, GFP_KERNEL);
+       if (!name)
+               return ERR_PTR(-ENOMEM);
+       sprintf(name, "%d/task/%d", tgid, pid);
+       return *cookie = name;
 }
 
 static const struct inode_operations proc_thread_self_inode_operations = {
 
 
 #include <linux/capability.h>
 #include <linux/xattr.h>
-#include <linux/namei.h>
 #include <linux/posix_acl.h>
 #include <linux/security.h>
 #include <linux/fiemap.h>
  * we need to be very careful about how much stack we use.
  * uio is kmalloced for this reason...
  */
-STATIC void *
+STATIC const char *
 xfs_vn_follow_link(
        struct dentry           *dentry,
+       void                    **cookie,
        struct nameidata        *nd)
 {
        char                    *link;
        if (unlikely(error))
                goto out_kfree;
 
-       nd_set_link(nd, link);
-       return NULL;
+       return *cookie = link;
 
  out_kfree:
        kfree(link);
  out_err:
-       nd_set_link(nd, ERR_PTR(error));
-       return NULL;
+       return ERR_PTR(error);
 }
 
 STATIC int
 
 
 struct inode_operations {
        struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
-       void * (*follow_link) (struct dentry *, struct nameidata *);
+       const char * (*follow_link) (struct dentry *, void **, struct nameidata *);
        int (*permission) (struct inode *, int);
        struct posix_acl * (*get_acl)(struct inode *, int);
 
        int (*readlink) (struct dentry *, char __user *,int);
-       void (*put_link) (struct dentry *, struct nameidata *, void *);
+       void (*put_link) (struct dentry *, void *);
 
        int (*create) (struct inode *,struct dentry *, umode_t, bool);
        int (*link) (struct dentry *,struct inode *,struct dentry *);
 
 extern int readlink_copy(char __user *, int, const char *);
 extern int page_readlink(struct dentry *, char __user *, int);
-extern void *page_follow_link_light(struct dentry *, struct nameidata *);
-extern void page_put_link(struct dentry *, struct nameidata *, void *);
+extern const char *page_follow_link_light(struct dentry *, void **, struct nameidata *);
+extern void page_put_link(struct dentry *, void *);
 extern int __page_symlink(struct inode *inode, const char *symname, int len,
                int nofs);
 extern int page_symlink(struct inode *inode, const char *symname, int len);
 extern const struct inode_operations page_symlink_inode_operations;
-extern void kfree_put_link(struct dentry *, struct nameidata *, void *);
+extern void kfree_put_link(struct dentry *, void *);
 extern int generic_readlink(struct dentry *, char __user *, int);
 extern void generic_fillattr(struct inode *, struct kstat *);
 int vfs_getattr_nosec(struct path *path, struct kstat *stat);
 void inode_sub_bytes(struct inode *inode, loff_t bytes);
 loff_t inode_get_bytes(struct inode *inode);
 void inode_set_bytes(struct inode *inode, loff_t bytes);
-void *simple_follow_link(struct dentry *, struct nameidata *);
+const char *simple_follow_link(struct dentry *, void **, struct nameidata *);
 extern const struct inode_operations simple_symlink_inode_operations;
 
 extern int iterate_dir(struct file *, struct dir_context *);
 
 extern void unlock_rename(struct dentry *, struct dentry *);
 
 extern void nd_jump_link(struct nameidata *nd, struct path *path);
-extern void nd_set_link(struct nameidata *nd, char *path);
-extern char *nd_get_link(struct nameidata *nd);
 
 static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
 {
 
        return 0;
 }
 
-static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
+static const char *shmem_follow_link(struct dentry *dentry, void **cookie, struct nameidata *nd)
 {
        struct page *page = NULL;
        int error = shmem_getpage(d_inode(dentry), 0, &page, SGP_READ, NULL);
-       nd_set_link(nd, error ? ERR_PTR(error) : kmap(page));
-       if (page)
-               unlock_page(page);
-       return page;
+       if (error)
+               return ERR_PTR(error);
+       unlock_page(page);
+       *cookie = page;
+       return kmap(page);
 }
 
-static void shmem_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+static void shmem_put_link(struct dentry *dentry, void *cookie)
 {
-       if (!IS_ERR(nd_get_link(nd))) {
-               struct page *page = cookie;
-               kunmap(page);
-               mark_page_accessed(page);
-               page_cache_release(page);
-       }
+       struct page *page = cookie;
+       kunmap(page);
+       mark_page_accessed(page);
+       page_cache_release(page);
 }
 
 #ifdef CONFIG_TMPFS_XATTR