|
@@ -4712,29 +4712,6 @@ out:
|
|
|
return len;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * A helper for ->readlink(). This should be used *ONLY* for symlinks that
|
|
|
- * have ->get_link() not calling nd_jump_link(). Using (or not using) it
|
|
|
- * for any given inode is up to filesystem.
|
|
|
- */
|
|
|
-static int generic_readlink(struct dentry *dentry, char __user *buffer,
|
|
|
- int buflen)
|
|
|
-{
|
|
|
- DEFINE_DELAYED_CALL(done);
|
|
|
- struct inode *inode = d_inode(dentry);
|
|
|
- const char *link = inode->i_link;
|
|
|
- int res;
|
|
|
-
|
|
|
- if (!link) {
|
|
|
- link = inode->i_op->get_link(dentry, inode, &done);
|
|
|
- if (IS_ERR(link))
|
|
|
- return PTR_ERR(link);
|
|
|
- }
|
|
|
- res = readlink_copy(buffer, buflen, link);
|
|
|
- do_delayed_call(&done);
|
|
|
- return res;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* vfs_readlink - copy symlink body into userspace buffer
|
|
|
* @dentry: dentry on which to get symbolic link
|
|
@@ -4748,6 +4725,9 @@ static int generic_readlink(struct dentry *dentry, char __user *buffer,
|
|
|
int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
|
|
|
{
|
|
|
struct inode *inode = d_inode(dentry);
|
|
|
+ DEFINE_DELAYED_CALL(done);
|
|
|
+ const char *link;
|
|
|
+ int res;
|
|
|
|
|
|
if (unlikely(!(inode->i_opflags & IOP_DEFAULT_READLINK))) {
|
|
|
if (unlikely(inode->i_op->readlink))
|
|
@@ -4761,7 +4741,15 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
}
|
|
|
|
|
|
- return generic_readlink(dentry, buffer, buflen);
|
|
|
+ link = inode->i_link;
|
|
|
+ if (!link) {
|
|
|
+ link = inode->i_op->get_link(dentry, inode, &done);
|
|
|
+ if (IS_ERR(link))
|
|
|
+ return PTR_ERR(link);
|
|
|
+ }
|
|
|
+ res = readlink_copy(buffer, buflen, link);
|
|
|
+ do_delayed_call(&done);
|
|
|
+ return res;
|
|
|
}
|
|
|
EXPORT_SYMBOL(vfs_readlink);
|
|
|
|