Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6:
eCryptfs: Flush dirty pages in setattr
eCryptfs: Handle failed metadata read in lookup
eCryptfs: Add reference counting to lower files
eCryptfs: dput dentries returned from dget_parent
eCryptfs: Remove extra d_delete in ecryptfs_rmdir

+129 -80
+21
fs/ecryptfs/crypto.c
··· 1452 1452 crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; 1453 1453 } 1454 1454 1455 + void ecryptfs_i_size_init(const char *page_virt, struct inode *inode) 1456 + { 1457 + struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 1458 + struct ecryptfs_crypt_stat *crypt_stat; 1459 + u64 file_size; 1460 + 1461 + crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; 1462 + mount_crypt_stat = 1463 + &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat; 1464 + if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { 1465 + file_size = i_size_read(ecryptfs_inode_to_lower(inode)); 1466 + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 1467 + file_size += crypt_stat->metadata_size; 1468 + } else 1469 + file_size = get_unaligned_be64(page_virt); 1470 + i_size_write(inode, (loff_t)file_size); 1471 + crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED; 1472 + } 1473 + 1455 1474 /** 1456 1475 * ecryptfs_read_headers_virt 1457 1476 * @page_virt: The virtual address into which to read the headers ··· 1501 1482 rc = -EINVAL; 1502 1483 goto out; 1503 1484 } 1485 + if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) 1486 + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); 1504 1487 offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; 1505 1488 rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset), 1506 1489 &bytes_read);
+6 -1
fs/ecryptfs/ecryptfs_kernel.h
··· 269 269 #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00000800 270 270 #define ECRYPTFS_ENCFN_USE_FEK 0x00001000 271 271 #define ECRYPTFS_UNLINK_SIGS 0x00002000 272 + #define ECRYPTFS_I_SIZE_INITIALIZED 0x00004000 272 273 u32 flags; 273 274 unsigned int file_version; 274 275 size_t iv_bytes; ··· 296 295 struct ecryptfs_inode_info { 297 296 struct inode vfs_inode; 298 297 struct inode *wii_inode; 298 + struct mutex lower_file_mutex; 299 + atomic_t lower_file_count; 299 300 struct file *lower_file; 300 301 struct ecryptfs_crypt_stat crypt_stat; 301 302 }; ··· 629 626 int ecryptfs_interpose(struct dentry *hidden_dentry, 630 627 struct dentry *this_dentry, struct super_block *sb, 631 628 u32 flags); 629 + void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); 632 630 int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, 633 631 struct dentry *lower_dentry, 634 632 struct inode *ecryptfs_dir_inode); ··· 761 757 struct dentry *lower_dentry, 762 758 struct vfsmount *lower_mnt, 763 759 const struct cred *cred); 764 - int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); 760 + int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry); 761 + void ecryptfs_put_lower_file(struct inode *inode); 765 762 int 766 763 ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, 767 764 size_t *packet_size,
+12 -13
fs/ecryptfs/file.c
··· 191 191 | ECRYPTFS_ENCRYPTED); 192 192 } 193 193 mutex_unlock(&crypt_stat->cs_mutex); 194 - rc = ecryptfs_init_persistent_file(ecryptfs_dentry); 194 + rc = ecryptfs_get_lower_file(ecryptfs_dentry); 195 195 if (rc) { 196 196 printk(KERN_ERR "%s: Error attempting to initialize " 197 - "the persistent file for the dentry with name " 197 + "the lower file for the dentry with name " 198 198 "[%s]; rc = [%d]\n", __func__, 199 199 ecryptfs_dentry->d_name.name, rc); 200 200 goto out_free; ··· 202 202 if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) 203 203 == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { 204 204 rc = -EPERM; 205 - printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " 205 + printk(KERN_WARNING "%s: Lower file is RO; eCryptfs " 206 206 "file must hence be opened RO\n", __func__); 207 - goto out_free; 207 + goto out_put; 208 208 } 209 209 ecryptfs_set_file_lower( 210 210 file, ecryptfs_inode_to_private(inode)->lower_file); ··· 232 232 "Plaintext passthrough mode is not " 233 233 "enabled; returning -EIO\n"); 234 234 mutex_unlock(&crypt_stat->cs_mutex); 235 - goto out_free; 235 + goto out_put; 236 236 } 237 237 rc = 0; 238 - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); 238 + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED 239 + | ECRYPTFS_ENCRYPTED); 239 240 mutex_unlock(&crypt_stat->cs_mutex); 240 241 goto out; 241 242 } ··· 246 245 "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, 247 246 (unsigned long long)i_size_read(inode)); 248 247 goto out; 248 + out_put: 249 + ecryptfs_put_lower_file(inode); 249 250 out_free: 250 251 kmem_cache_free(ecryptfs_file_info_cache, 251 252 ecryptfs_file_to_private(file)); ··· 257 254 258 255 static int ecryptfs_flush(struct file *file, fl_owner_t td) 259 256 { 260 - int rc = 0; 261 - struct file *lower_file = NULL; 262 - 263 - lower_file = ecryptfs_file_to_lower(file); 264 - if (lower_file->f_op && lower_file->f_op->flush) 265 - rc = lower_file->f_op->flush(lower_file, td); 266 - return rc; 257 + return file->f_mode & FMODE_WRITE 258 + ? filemap_write_and_wait(file->f_mapping) : 0; 267 259 } 268 260 269 261 static int ecryptfs_release(struct inode *inode, struct file *file) 270 262 { 263 + ecryptfs_put_lower_file(inode); 271 264 kmem_cache_free(ecryptfs_file_info_cache, 272 265 ecryptfs_file_to_private(file)); 273 266 return 0;
+32 -28
fs/ecryptfs/inode.c
··· 168 168 "context; rc = [%d]\n", rc); 169 169 goto out; 170 170 } 171 - rc = ecryptfs_init_persistent_file(ecryptfs_dentry); 171 + rc = ecryptfs_get_lower_file(ecryptfs_dentry); 172 172 if (rc) { 173 173 printk(KERN_ERR "%s: Error attempting to initialize " 174 - "the persistent file for the dentry with name " 174 + "the lower file for the dentry with name " 175 175 "[%s]; rc = [%d]\n", __func__, 176 176 ecryptfs_dentry->d_name.name, rc); 177 177 goto out; 178 178 } 179 179 rc = ecryptfs_write_metadata(ecryptfs_dentry); 180 - if (rc) { 180 + if (rc) 181 181 printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); 182 - goto out; 183 - } 182 + ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); 184 183 out: 185 184 return rc; 186 185 } ··· 225 226 struct dentry *lower_dir_dentry; 226 227 struct vfsmount *lower_mnt; 227 228 struct inode *lower_inode; 228 - struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 229 229 struct ecryptfs_crypt_stat *crypt_stat; 230 230 char *page_virt = NULL; 231 - u64 file_size; 232 - int rc = 0; 231 + int put_lower = 0, rc = 0; 233 232 234 233 lower_dir_dentry = lower_dentry->d_parent; 235 234 lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( ··· 274 277 rc = -ENOMEM; 275 278 goto out; 276 279 } 277 - rc = ecryptfs_init_persistent_file(ecryptfs_dentry); 280 + rc = ecryptfs_get_lower_file(ecryptfs_dentry); 278 281 if (rc) { 279 282 printk(KERN_ERR "%s: Error attempting to initialize " 280 - "the persistent file for the dentry with name " 283 + "the lower file for the dentry with name " 281 284 "[%s]; rc = [%d]\n", __func__, 282 285 ecryptfs_dentry->d_name.name, rc); 283 286 goto out_free_kmem; 284 287 } 288 + put_lower = 1; 285 289 crypt_stat = &ecryptfs_inode_to_private( 286 290 ecryptfs_dentry->d_inode)->crypt_stat; 287 291 /* TODO: lock for crypt_stat comparison */ ··· 300 302 } 301 303 crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; 302 304 } 303 - mount_crypt_stat = &ecryptfs_superblock_to_private( 304 - ecryptfs_dentry->d_sb)->mount_crypt_stat; 305 - if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { 306 - if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 307 - file_size = (crypt_stat->metadata_size 308 - + i_size_read(lower_dentry->d_inode)); 309 - else 310 - file_size = i_size_read(lower_dentry->d_inode); 311 - } else { 312 - file_size = get_unaligned_be64(page_virt); 313 - } 314 - i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size); 305 + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); 315 306 out_free_kmem: 316 307 kmem_cache_free(ecryptfs_header_cache_2, page_virt); 317 308 goto out; ··· 309 322 mntput(lower_mnt); 310 323 d_drop(ecryptfs_dentry); 311 324 out: 325 + if (put_lower) 326 + ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); 312 327 return rc; 313 328 } 314 329 ··· 527 538 dget(lower_dentry); 528 539 rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); 529 540 dput(lower_dentry); 530 - if (!rc) 531 - d_delete(lower_dentry); 532 541 fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); 533 542 dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; 534 543 unlock_dir(lower_dir_dentry); ··· 597 610 fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); 598 611 out_lock: 599 612 unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 600 - dput(lower_new_dentry->d_parent); 601 - dput(lower_old_dentry->d_parent); 613 + dput(lower_new_dir_dentry); 614 + dput(lower_old_dir_dentry); 602 615 dput(lower_new_dentry); 603 616 dput(lower_old_dentry); 604 617 return rc; ··· 746 759 747 760 if (unlikely((ia->ia_size == i_size))) { 748 761 lower_ia->ia_valid &= ~ATTR_SIZE; 749 - goto out; 762 + return 0; 750 763 } 764 + rc = ecryptfs_get_lower_file(dentry); 765 + if (rc) 766 + return rc; 751 767 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 752 768 /* Switch on growing or shrinking file */ 753 769 if (ia->ia_size > i_size) { ··· 828 838 lower_ia->ia_valid &= ~ATTR_SIZE; 829 839 } 830 840 out: 841 + ecryptfs_put_lower_file(inode); 831 842 return rc; 832 843 } 833 844 ··· 904 913 905 914 mount_crypt_stat = &ecryptfs_superblock_to_private( 906 915 dentry->d_sb)->mount_crypt_stat; 916 + rc = ecryptfs_get_lower_file(dentry); 917 + if (rc) { 918 + mutex_unlock(&crypt_stat->cs_mutex); 919 + goto out; 920 + } 907 921 rc = ecryptfs_read_metadata(dentry); 922 + ecryptfs_put_lower_file(inode); 908 923 if (rc) { 909 924 if (!(mount_crypt_stat->flags 910 925 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { ··· 924 927 goto out; 925 928 } 926 929 rc = 0; 927 - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); 930 + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED 931 + | ECRYPTFS_ENCRYPTED); 928 932 } 929 933 } 930 934 mutex_unlock(&crypt_stat->cs_mutex); 935 + if (S_ISREG(inode->i_mode)) { 936 + rc = filemap_write_and_wait(inode->i_mapping); 937 + if (rc) 938 + goto out; 939 + fsstack_copy_attr_all(inode, lower_inode); 940 + } 931 941 memcpy(&lower_ia, ia, sizeof(lower_ia)); 932 942 if (ia->ia_valid & ATTR_FILE) 933 943 lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
+3 -3
fs/ecryptfs/kthread.c
··· 44 44 * @ignored: ignored 45 45 * 46 46 * The eCryptfs kernel thread that has the responsibility of getting 47 - * the lower persistent file with RW permissions. 47 + * the lower file with RW permissions. 48 48 * 49 49 * Returns zero on success; non-zero otherwise 50 50 */ ··· 141 141 int rc = 0; 142 142 143 143 /* Corresponding dput() and mntput() are done when the 144 - * persistent file is fput() when the eCryptfs inode is 145 - * destroyed. */ 144 + * lower file is fput() when all eCryptfs files for the inode are 145 + * released. */ 146 146 dget(lower_dentry); 147 147 mntget(lower_mnt); 148 148 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
+51 -23
fs/ecryptfs/main.c
··· 96 96 } 97 97 98 98 /** 99 - * ecryptfs_init_persistent_file 99 + * ecryptfs_init_lower_file 100 100 * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with 101 101 * the lower dentry and the lower mount set 102 102 * ··· 104 104 * inode. All I/O operations to the lower inode occur through that 105 105 * file. When the first eCryptfs dentry that interposes with the first 106 106 * lower dentry for that inode is created, this function creates the 107 - * persistent file struct and associates it with the eCryptfs 108 - * inode. When the eCryptfs inode is destroyed, the file is closed. 107 + * lower file struct and associates it with the eCryptfs 108 + * inode. When all eCryptfs files associated with the inode are released, the 109 + * file is closed. 109 110 * 110 - * The persistent file will be opened with read/write permissions, if 111 + * The lower file will be opened with read/write permissions, if 111 112 * possible. Otherwise, it is opened read-only. 112 113 * 113 - * This function does nothing if a lower persistent file is already 114 + * This function does nothing if a lower file is already 114 115 * associated with the eCryptfs inode. 115 116 * 116 117 * Returns zero on success; non-zero otherwise 117 118 */ 118 - int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) 119 + static int ecryptfs_init_lower_file(struct dentry *dentry, 120 + struct file **lower_file) 119 121 { 120 122 const struct cred *cred = current_cred(); 121 - struct ecryptfs_inode_info *inode_info = 122 - ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); 123 - int rc = 0; 123 + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 124 + struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); 125 + int rc; 124 126 125 - if (!inode_info->lower_file) { 126 - struct dentry *lower_dentry; 127 - struct vfsmount *lower_mnt = 128 - ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); 129 - 130 - lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 131 - rc = ecryptfs_privileged_open(&inode_info->lower_file, 132 - lower_dentry, lower_mnt, cred); 133 - if (rc) { 134 - printk(KERN_ERR "Error opening lower persistent file " 135 - "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 136 - "rc = [%d]\n", lower_dentry, lower_mnt, rc); 137 - inode_info->lower_file = NULL; 138 - } 127 + rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, 128 + cred); 129 + if (rc) { 130 + printk(KERN_ERR "Error opening lower file " 131 + "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 132 + "rc = [%d]\n", lower_dentry, lower_mnt, rc); 133 + (*lower_file) = NULL; 139 134 } 140 135 return rc; 136 + } 137 + 138 + int ecryptfs_get_lower_file(struct dentry *dentry) 139 + { 140 + struct ecryptfs_inode_info *inode_info = 141 + ecryptfs_inode_to_private(dentry->d_inode); 142 + int count, rc = 0; 143 + 144 + mutex_lock(&inode_info->lower_file_mutex); 145 + count = atomic_inc_return(&inode_info->lower_file_count); 146 + if (WARN_ON_ONCE(count < 1)) 147 + rc = -EINVAL; 148 + else if (count == 1) { 149 + rc = ecryptfs_init_lower_file(dentry, 150 + &inode_info->lower_file); 151 + if (rc) 152 + atomic_set(&inode_info->lower_file_count, 0); 153 + } 154 + mutex_unlock(&inode_info->lower_file_mutex); 155 + return rc; 156 + } 157 + 158 + void ecryptfs_put_lower_file(struct inode *inode) 159 + { 160 + struct ecryptfs_inode_info *inode_info; 161 + 162 + inode_info = ecryptfs_inode_to_private(inode); 163 + if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, 164 + &inode_info->lower_file_mutex)) { 165 + fput(inode_info->lower_file); 166 + inode_info->lower_file = NULL; 167 + mutex_unlock(&inode_info->lower_file_mutex); 168 + } 141 169 } 142 170 143 171 static struct inode *ecryptfs_get_inode(struct inode *lower_inode,
+4 -12
fs/ecryptfs/super.c
··· 55 55 if (unlikely(!inode_info)) 56 56 goto out; 57 57 ecryptfs_init_crypt_stat(&inode_info->crypt_stat); 58 + mutex_init(&inode_info->lower_file_mutex); 59 + atomic_set(&inode_info->lower_file_count, 0); 58 60 inode_info->lower_file = NULL; 59 61 inode = &inode_info->vfs_inode; 60 62 out: ··· 79 77 * 80 78 * This is used during the final destruction of the inode. All 81 79 * allocation of memory related to the inode, including allocated 82 - * memory in the crypt_stat struct, will be released here. This 83 - * function also fput()'s the persistent file for the lower inode. 80 + * memory in the crypt_stat struct, will be released here. 84 81 * There should be no chance that this deallocation will be missed. 85 82 */ 86 83 static void ecryptfs_destroy_inode(struct inode *inode) ··· 87 86 struct ecryptfs_inode_info *inode_info; 88 87 89 88 inode_info = ecryptfs_inode_to_private(inode); 90 - if (inode_info->lower_file) { 91 - struct dentry *lower_dentry = 92 - inode_info->lower_file->f_dentry; 93 - 94 - BUG_ON(!lower_dentry); 95 - if (lower_dentry->d_inode) { 96 - fput(inode_info->lower_file); 97 - inode_info->lower_file = NULL; 98 - } 99 - } 89 + BUG_ON(inode_info->lower_file); 100 90 ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); 101 91 call_rcu(&inode->i_rcu, ecryptfs_i_callback); 102 92 }