summaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r--fs/ecryptfs/inode.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index cf390dceddd2..e7413f82d27b 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -631,28 +631,23 @@ out_lock:
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
{
+ DEFINE_DELAYED_CALL(done);
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
- char *lower_buf;
+ const char *link;
char *buf;
- mm_segment_t old_fs;
int rc;
- lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
- if (!lower_buf)
- return ERR_PTR(-ENOMEM);
- old_fs = get_fs();
- set_fs(get_ds());
- rc = d_inode(lower_dentry)->i_op->readlink(lower_dentry,
- (char __user *)lower_buf,
- PATH_MAX);
- set_fs(old_fs);
- if (rc < 0)
- goto out;
+ link = vfs_get_link(lower_dentry, &done);
+ if (IS_ERR(link))
+ return ERR_CAST(link);
+
rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
- lower_buf, rc);
-out:
- kfree(lower_buf);
- return rc ? ERR_PTR(rc) : buf;
+ link, strlen(link));
+ do_delayed_call(&done);
+ if (rc)
+ return ERR_PTR(rc);
+
+ return buf;
}
static const char *ecryptfs_get_link(struct dentry *dentry,
@@ -1089,7 +1084,6 @@ out:
}
const struct inode_operations ecryptfs_symlink_iops = {
- .readlink = generic_readlink,
.get_link = ecryptfs_get_link,
.permission = ecryptfs_permission,
.setattr = ecryptfs_setattr,