diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
| -rw-r--r-- | fs/ecryptfs/inode.c | 112 |
1 files changed, 94 insertions, 18 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 31ef5252f0fe..6c55113e7222 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -264,7 +264,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
| 264 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 264 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
| 265 | "to allocate ecryptfs_dentry_info struct\n", | 265 | "to allocate ecryptfs_dentry_info struct\n", |
| 266 | __func__); | 266 | __func__); |
| 267 | goto out_dput; | 267 | goto out_put; |
| 268 | } | 268 | } |
| 269 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); | 269 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); |
| 270 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); | 270 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); |
| @@ -339,14 +339,85 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
| 339 | out_free_kmem: | 339 | out_free_kmem: |
| 340 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 340 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
| 341 | goto out; | 341 | goto out; |
| 342 | out_dput: | 342 | out_put: |
| 343 | dput(lower_dentry); | 343 | dput(lower_dentry); |
| 344 | mntput(lower_mnt); | ||
| 344 | d_drop(ecryptfs_dentry); | 345 | d_drop(ecryptfs_dentry); |
| 345 | out: | 346 | out: |
| 346 | return rc; | 347 | return rc; |
| 347 | } | 348 | } |
| 348 | 349 | ||
| 349 | /** | 350 | /** |
| 351 | * ecryptfs_new_lower_dentry | ||
| 352 | * @ename: The name of the new dentry. | ||
| 353 | * @lower_dir_dentry: Parent directory of the new dentry. | ||
| 354 | * @nd: nameidata from last lookup. | ||
| 355 | * | ||
| 356 | * Create a new dentry or get it from lower parent dir. | ||
| 357 | */ | ||
| 358 | static struct dentry * | ||
| 359 | ecryptfs_new_lower_dentry(struct qstr *name, struct dentry *lower_dir_dentry, | ||
| 360 | struct nameidata *nd) | ||
| 361 | { | ||
| 362 | struct dentry *new_dentry; | ||
| 363 | struct dentry *tmp; | ||
| 364 | struct inode *lower_dir_inode; | ||
| 365 | |||
| 366 | lower_dir_inode = lower_dir_dentry->d_inode; | ||
| 367 | |||
| 368 | tmp = d_alloc(lower_dir_dentry, name); | ||
| 369 | if (!tmp) | ||
| 370 | return ERR_PTR(-ENOMEM); | ||
| 371 | |||
| 372 | mutex_lock(&lower_dir_inode->i_mutex); | ||
| 373 | new_dentry = lower_dir_inode->i_op->lookup(lower_dir_inode, tmp, nd); | ||
| 374 | mutex_unlock(&lower_dir_inode->i_mutex); | ||
| 375 | |||
| 376 | if (!new_dentry) | ||
| 377 | new_dentry = tmp; | ||
| 378 | else | ||
| 379 | dput(tmp); | ||
| 380 | |||
| 381 | return new_dentry; | ||
| 382 | } | ||
| 383 | |||
| 384 | |||
| 385 | /** | ||
| 386 | * ecryptfs_lookup_one_lower | ||
| 387 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | ||
| 388 | * @lower_dir_dentry: lower parent directory | ||
| 389 | * | ||
| 390 | * Get the lower dentry from vfs. If lower dentry does not exist yet, | ||
| 391 | * create it. | ||
| 392 | */ | ||
| 393 | static struct dentry * | ||
| 394 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, | ||
| 395 | struct dentry *lower_dir_dentry) | ||
| 396 | { | ||
| 397 | struct nameidata nd; | ||
| 398 | struct vfsmount *lower_mnt; | ||
| 399 | struct qstr *name; | ||
| 400 | int err; | ||
| 401 | |||
| 402 | name = &ecryptfs_dentry->d_name; | ||
| 403 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | ||
| 404 | ecryptfs_dentry->d_parent)); | ||
| 405 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); | ||
| 406 | mntput(lower_mnt); | ||
| 407 | |||
| 408 | if (!err) { | ||
| 409 | /* we dont need the mount */ | ||
| 410 | mntput(nd.path.mnt); | ||
| 411 | return nd.path.dentry; | ||
| 412 | } | ||
| 413 | if (err != -ENOENT) | ||
| 414 | return ERR_PTR(err); | ||
| 415 | |||
| 416 | /* create a new lower dentry */ | ||
| 417 | return ecryptfs_new_lower_dentry(name, lower_dir_dentry, &nd); | ||
| 418 | } | ||
| 419 | |||
| 420 | /** | ||
| 350 | * ecryptfs_lookup | 421 | * ecryptfs_lookup |
| 351 | * @ecryptfs_dir_inode: The eCryptfs directory inode | 422 | * @ecryptfs_dir_inode: The eCryptfs directory inode |
| 352 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | 423 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up |
| @@ -373,14 +444,12 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 373 | goto out_d_drop; | 444 | goto out_d_drop; |
| 374 | } | 445 | } |
| 375 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 446 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
| 376 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); | 447 | |
| 377 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, | 448 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
| 378 | lower_dir_dentry, | 449 | lower_dir_dentry); |
| 379 | ecryptfs_dentry->d_name.len); | ||
| 380 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | ||
| 381 | if (IS_ERR(lower_dentry)) { | 450 | if (IS_ERR(lower_dentry)) { |
| 382 | rc = PTR_ERR(lower_dentry); | 451 | rc = PTR_ERR(lower_dentry); |
| 383 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " | 452 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
| 384 | "[%d] on lower_dentry = [%s]\n", __func__, rc, | 453 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
| 385 | encrypted_and_encoded_name); | 454 | encrypted_and_encoded_name); |
| 386 | goto out_d_drop; | 455 | goto out_d_drop; |
| @@ -402,14 +471,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 402 | "filename; rc = [%d]\n", __func__, rc); | 471 | "filename; rc = [%d]\n", __func__, rc); |
| 403 | goto out_d_drop; | 472 | goto out_d_drop; |
| 404 | } | 473 | } |
| 405 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); | 474 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
| 406 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, | 475 | lower_dir_dentry); |
| 407 | lower_dir_dentry, | ||
| 408 | encrypted_and_encoded_name_size - 1); | ||
| 409 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | ||
| 410 | if (IS_ERR(lower_dentry)) { | 476 | if (IS_ERR(lower_dentry)) { |
| 411 | rc = PTR_ERR(lower_dentry); | 477 | rc = PTR_ERR(lower_dentry); |
| 412 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " | 478 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
| 413 | "[%d] on lower_dentry = [%s]\n", __func__, rc, | 479 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
| 414 | encrypted_and_encoded_name); | 480 | encrypted_and_encoded_name); |
| 415 | goto out_d_drop; | 481 | goto out_d_drop; |
| @@ -804,10 +870,20 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 804 | size_t num_zeros = (PAGE_CACHE_SIZE | 870 | size_t num_zeros = (PAGE_CACHE_SIZE |
| 805 | - (ia->ia_size & ~PAGE_CACHE_MASK)); | 871 | - (ia->ia_size & ~PAGE_CACHE_MASK)); |
| 806 | 872 | ||
| 873 | |||
| 874 | /* | ||
| 875 | * XXX(truncate) this should really happen at the begginning | ||
| 876 | * of ->setattr. But the code is too messy to that as part | ||
| 877 | * of a larger patch. ecryptfs is also totally missing out | ||
| 878 | * on the inode_change_ok check at the beginning of | ||
| 879 | * ->setattr while would include this. | ||
| 880 | */ | ||
| 881 | rc = inode_newsize_ok(inode, ia->ia_size); | ||
| 882 | if (rc) | ||
| 883 | goto out; | ||
| 884 | |||
| 807 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 885 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
| 808 | rc = simple_setsize(inode, ia->ia_size); | 886 | truncate_setsize(inode, ia->ia_size); |
| 809 | if (rc) | ||
| 810 | goto out; | ||
| 811 | lower_ia->ia_size = ia->ia_size; | 887 | lower_ia->ia_size = ia->ia_size; |
| 812 | lower_ia->ia_valid |= ATTR_SIZE; | 888 | lower_ia->ia_valid |= ATTR_SIZE; |
| 813 | goto out; | 889 | goto out; |
| @@ -830,7 +906,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 830 | goto out; | 906 | goto out; |
| 831 | } | 907 | } |
| 832 | } | 908 | } |
| 833 | simple_setsize(inode, ia->ia_size); | 909 | truncate_setsize(inode, ia->ia_size); |
| 834 | rc = ecryptfs_write_inode_size_to_metadata(inode); | 910 | rc = ecryptfs_write_inode_size_to_metadata(inode); |
| 835 | if (rc) { | 911 | if (rc) { |
| 836 | printk(KERN_ERR "Problem with " | 912 | printk(KERN_ERR "Problem with " |
