aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-05-03 09:34:20 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-05-29 23:28:40 -0400
commit408bd629badbd4353b238ab6f58001529b274d73 (patch)
treef152605d09f45ec47d172e6fff22fd937f276c3a
parent28fe3c1963b0bafa56ec92df1987828090151d87 (diff)
get rid of pointless allocations and copying in ecryptfs_follow_link()
switch to generic_readlink(), while we are at it Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ecryptfs/inode.c48
1 files changed, 9 insertions, 39 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index ab35b113003b..a07441a0a878 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -660,11 +660,10 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
660{ 660{
661 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 661 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
662 char *lower_buf; 662 char *lower_buf;
663 size_t lower_bufsiz = PATH_MAX;
664 mm_segment_t old_fs; 663 mm_segment_t old_fs;
665 int rc; 664 int rc;
666 665
667 lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); 666 lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
668 if (!lower_buf) { 667 if (!lower_buf) {
669 rc = -ENOMEM; 668 rc = -ENOMEM;
670 goto out; 669 goto out;
@@ -673,58 +672,29 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
673 set_fs(get_ds()); 672 set_fs(get_ds());
674 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, 673 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
675 (char __user *)lower_buf, 674 (char __user *)lower_buf,
676 lower_bufsiz); 675 PATH_MAX);
677 set_fs(old_fs); 676 set_fs(old_fs);
678 if (rc < 0) 677 if (rc < 0)
679 goto out; 678 goto out;
680 lower_bufsiz = rc;
681 rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, 679 rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
682 lower_buf, lower_bufsiz); 680 lower_buf, rc);
683out: 681out:
684 kfree(lower_buf); 682 kfree(lower_buf);
685 return rc; 683 return rc;
686} 684}
687 685
688static int 686static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
689ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
690{ 687{
691 char *kbuf; 688 char *buf;
692 size_t kbufsiz, copied; 689 size_t len = PATH_MAX;
693 int rc; 690 int rc;
694 691
695 rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); 692 rc = ecryptfs_readlink_lower(dentry, &buf, &len);
696 if (rc) 693 if (rc)
697 goto out; 694 goto out;
698 copied = min_t(size_t, bufsiz, kbufsiz);
699 rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
700 kfree(kbuf);
701 fsstack_copy_attr_atime(dentry->d_inode, 695 fsstack_copy_attr_atime(dentry->d_inode,
702 ecryptfs_dentry_to_lower(dentry)->d_inode); 696 ecryptfs_dentry_to_lower(dentry)->d_inode);
703out: 697 buf[len] = '\0';
704 return rc;
705}
706
707static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
708{
709 char *buf;
710 int len = PAGE_SIZE, rc;
711 mm_segment_t old_fs;
712
713 /* Released in ecryptfs_put_link(); only release here on error */
714 buf = kmalloc(len, GFP_KERNEL);
715 if (!buf) {
716 buf = ERR_PTR(-ENOMEM);
717 goto out;
718 }
719 old_fs = get_fs();
720 set_fs(get_ds());
721 rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
722 set_fs(old_fs);
723 if (rc < 0) {
724 kfree(buf);
725 buf = ERR_PTR(rc);
726 } else
727 buf[rc] = '\0';
728out: 698out:
729 nd_set_link(nd, buf); 699 nd_set_link(nd, buf);
730 return NULL; 700 return NULL;
@@ -1153,7 +1123,7 @@ out:
1153} 1123}
1154 1124
1155const struct inode_operations ecryptfs_symlink_iops = { 1125const struct inode_operations ecryptfs_symlink_iops = {
1156 .readlink = ecryptfs_readlink, 1126 .readlink = generic_readlink,
1157 .follow_link = ecryptfs_follow_link, 1127 .follow_link = ecryptfs_follow_link,
1158 .put_link = ecryptfs_put_link, 1128 .put_link = ecryptfs_put_link,
1159 .permission = ecryptfs_permission, 1129 .permission = ecryptfs_permission,