aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r--fs/ecryptfs/inode.c70
1 files changed, 67 insertions, 3 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 1548be26b5e6..e77a2ec71aa5 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -282,7 +282,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
282 struct dentry *lower_dentry; 282 struct dentry *lower_dentry;
283 struct vfsmount *lower_mnt; 283 struct vfsmount *lower_mnt;
284 char *encoded_name; 284 char *encoded_name;
285 unsigned int encoded_namelen; 285 int encoded_namelen;
286 struct ecryptfs_crypt_stat *crypt_stat = NULL; 286 struct ecryptfs_crypt_stat *crypt_stat = NULL;
287 struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 287 struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
288 char *page_virt = NULL; 288 char *page_virt = NULL;
@@ -473,7 +473,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
473 struct dentry *lower_dir_dentry; 473 struct dentry *lower_dir_dentry;
474 umode_t mode; 474 umode_t mode;
475 char *encoded_symname; 475 char *encoded_symname;
476 unsigned int encoded_symlen; 476 int encoded_symlen;
477 struct ecryptfs_crypt_stat *crypt_stat = NULL; 477 struct ecryptfs_crypt_stat *crypt_stat = NULL;
478 478
479 lower_dentry = ecryptfs_dentry_to_lower(dentry); 479 lower_dentry = ecryptfs_dentry_to_lower(dentry);
@@ -800,6 +800,25 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
800 goto out_fput; 800 goto out_fput;
801 } 801 }
802 } else { /* new_length < i_size_read(inode) */ 802 } else { /* new_length < i_size_read(inode) */
803 pgoff_t index = 0;
804 int end_pos_in_page = -1;
805
806 if (new_length != 0) {
807 index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
808 end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
809 }
810 if (end_pos_in_page != (PAGE_CACHE_SIZE - 1)) {
811 if ((rc = ecryptfs_write_zeros(&fake_ecryptfs_file,
812 index,
813 (end_pos_in_page + 1),
814 ((PAGE_CACHE_SIZE - 1)
815 - end_pos_in_page)))) {
816 printk(KERN_ERR "Error attempting to zero out "
817 "the remainder of the end page on "
818 "reducing truncate; rc = [%d]\n", rc);
819 goto out_fput;
820 }
821 }
803 vmtruncate(inode, new_length); 822 vmtruncate(inode, new_length);
804 rc = ecryptfs_write_inode_size_to_metadata( 823 rc = ecryptfs_write_inode_size_to_metadata(
805 lower_file, lower_dentry->d_inode, inode, dentry, 824 lower_file, lower_dentry->d_inode, inode, dentry,
@@ -875,9 +894,54 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
875 struct ecryptfs_crypt_stat *crypt_stat; 894 struct ecryptfs_crypt_stat *crypt_stat;
876 895
877 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 896 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
878 lower_dentry = ecryptfs_dentry_to_lower(dentry); 897 if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
898 ecryptfs_init_crypt_stat(crypt_stat);
879 inode = dentry->d_inode; 899 inode = dentry->d_inode;
880 lower_inode = ecryptfs_inode_to_lower(inode); 900 lower_inode = ecryptfs_inode_to_lower(inode);
901 lower_dentry = ecryptfs_dentry_to_lower(dentry);
902 mutex_lock(&crypt_stat->cs_mutex);
903 if (S_ISDIR(dentry->d_inode->i_mode))
904 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
905 else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
906 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
907 struct vfsmount *lower_mnt;
908 struct file *lower_file = NULL;
909 struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
910 int lower_flags;
911
912 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
913 lower_flags = O_RDONLY;
914 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry,
915 lower_mnt, lower_flags))) {
916 printk(KERN_ERR
917 "Error opening lower file; rc = [%d]\n", rc);
918 mutex_unlock(&crypt_stat->cs_mutex);
919 goto out;
920 }
921 mount_crypt_stat = &ecryptfs_superblock_to_private(
922 dentry->d_sb)->mount_crypt_stat;
923 if ((rc = ecryptfs_read_metadata(dentry, lower_file))) {
924 if (!(mount_crypt_stat->flags
925 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
926 rc = -EIO;
927 printk(KERN_WARNING "Attempt to read file that "
928 "is not in a valid eCryptfs format, "
929 "and plaintext passthrough mode is not "
930 "enabled; returning -EIO\n");
931
932 mutex_unlock(&crypt_stat->cs_mutex);
933 fput(lower_file);
934 goto out;
935 }
936 rc = 0;
937 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
938 mutex_unlock(&crypt_stat->cs_mutex);
939 fput(lower_file);
940 goto out;
941 }
942 fput(lower_file);
943 }
944 mutex_unlock(&crypt_stat->cs_mutex);
881 if (ia->ia_valid & ATTR_SIZE) { 945 if (ia->ia_valid & ATTR_SIZE) {
882 ecryptfs_printk(KERN_DEBUG, 946 ecryptfs_printk(KERN_DEBUG,
883 "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", 947 "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n",