return symname;
  }
  
- struct inode_operations ll_fast_symlink_inode_operations = {
 -static void ll_put_link(struct inode *unused, void *cookie)
 -{
 -      ptlrpc_req_finished(cookie);
 -}
 -
+ const struct inode_operations ll_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .setattr        = ll_setattr,
 -      .follow_link    = ll_follow_link,
 -      .put_link       = ll_put_link,
 +      .get_link       = ll_get_link,
        .getattr        = ll_getattr,
        .permission     = ll_inode_permission,
        .setxattr       = ll_setxattr,
 
        nd->path.dentry = path->dentry;
  }
  
+ static int nd_jump_root(struct nameidata *nd)
+ {
+       if (nd->flags & LOOKUP_RCU) {
+               struct dentry *d;
+               nd->path = nd->root;
+               d = nd->path.dentry;
+               nd->inode = d->d_inode;
+               nd->seq = nd->root_seq;
+               if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
+                       return -ECHILD;
+       } else {
+               path_put(&nd->path);
+               nd->path = nd->root;
+               path_get(&nd->path);
+               nd->inode = nd->path.dentry->d_inode;
+       }
+       nd->flags |= LOOKUP_JUMPED;
+       return 0;
+ }
+ 
  /*
 - * Helper to directly jump to a known parsed path from ->follow_link,
 + * Helper to directly jump to a known parsed path from ->get_link,
   * caller must have taken a reference to path beforehand.
   */
  void nd_jump_link(struct path *path)
        nd->last_type = LAST_BIND;
        res = inode->i_link;
        if (!res) {
 +              const char * (*get)(struct dentry *, struct inode *,
 +                              struct delayed_call *);
 +              get = inode->i_op->get_link;
                if (nd->flags & LOOKUP_RCU) {
 -                      if (unlikely(unlazy_walk(nd, NULL, 0)))
 -                              return ERR_PTR(-ECHILD);
 +                      res = get(NULL, inode, &last->done);
 +                      if (res == ERR_PTR(-ECHILD)) {
 +                              if (unlikely(unlazy_walk(nd, NULL, 0)))
 +                                      return ERR_PTR(-ECHILD);
 +                              res = get(dentry, inode, &last->done);
 +                      }
 +              } else {
 +                      res = get(dentry, inode, &last->done);
                }
 -              res = inode->i_op->follow_link(dentry, &last->cookie);
 -              if (IS_ERR_OR_NULL(res)) {
 -                      last->cookie = NULL;
 +              if (IS_ERR_OR_NULL(res))
                        return res;
 -              }
        }
        if (*res == '/') {
-               if (nd->flags & LOOKUP_RCU) {
-                       struct dentry *d;
-                       if (!nd->root.mnt)
-                               set_root_rcu(nd);
-                       nd->path = nd->root;
-                       d = nd->path.dentry;
-                       nd->inode = d->d_inode;
-                       nd->seq = nd->root_seq;
-                       if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
-                               return ERR_PTR(-ECHILD);
-               } else {
-                       if (!nd->root.mnt)
-                               set_root(nd);
-                       path_put(&nd->path);
-                       nd->path = nd->root;
-                       path_get(&nd->root);
-                       nd->inode = nd->path.dentry->d_inode;
-               }
-               nd->flags |= LOOKUP_JUMPED;
+               if (!nd->root.mnt)
+                       set_root(nd);
+               if (unlikely(nd_jump_root(nd)))
+                       return ERR_PTR(-ECHILD);
                while (unlikely(*++res == '/'))
                        ;
        }