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 /fs/ecryptfs | |
| 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>
Diffstat (limited to 'fs/ecryptfs')
| -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 ab35b113003..a07441a0a87 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, |
