diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-03 09:34:20 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-29 23:28:40 -0400 |
commit | 408bd629badbd4353b238ab6f58001529b274d73 (patch) | |
tree | f152605d09f45ec47d172e6fff22fd937f276c3a | |
parent | 28fe3c1963b0bafa56ec92df1987828090151d87 (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.c | 48 |
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); |
683 | out: | 681 | out: |
684 | kfree(lower_buf); | 682 | kfree(lower_buf); |
685 | return rc; | 683 | return rc; |
686 | } | 684 | } |
687 | 685 | ||
688 | static int | 686 | static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
689 | ecryptfs_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); |
703 | out: | 697 | buf[len] = '\0'; |
704 | return rc; | ||
705 | } | ||
706 | |||
707 | static 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'; | ||
728 | out: | 698 | out: |
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 | ||
1155 | const struct inode_operations ecryptfs_symlink_iops = { | 1125 | const 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, |