diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/bio.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/acl.c | 12 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 32 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 100 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 12 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/relocation.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 4 | ||||
| -rw-r--r-- | fs/ecryptfs/crypto.c | 4 | ||||
| -rw-r--r-- | fs/ecryptfs/file.c | 17 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 134 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 4 |
12 files changed, 235 insertions, 92 deletions
| @@ -78,7 +78,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) | |||
| 78 | 78 | ||
| 79 | i = 0; | 79 | i = 0; |
| 80 | while (i < bio_slab_nr) { | 80 | while (i < bio_slab_nr) { |
| 81 | struct bio_slab *bslab = &bio_slabs[i]; | 81 | bslab = &bio_slabs[i]; |
| 82 | 82 | ||
| 83 | if (!bslab->slab && entry == -1) | 83 | if (!bslab->slab && entry == -1) |
| 84 | entry = i; | 84 | entry = i; |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 2e9e69987a82..54f4798ab46a 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -112,12 +112,14 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans, | |||
| 112 | switch (type) { | 112 | switch (type) { |
| 113 | case ACL_TYPE_ACCESS: | 113 | case ACL_TYPE_ACCESS: |
| 114 | mode = inode->i_mode; | 114 | mode = inode->i_mode; |
| 115 | ret = posix_acl_equiv_mode(acl, &mode); | ||
| 116 | if (ret < 0) | ||
| 117 | return ret; | ||
| 118 | ret = 0; | ||
| 119 | inode->i_mode = mode; | ||
| 120 | name = POSIX_ACL_XATTR_ACCESS; | 115 | name = POSIX_ACL_XATTR_ACCESS; |
| 116 | if (acl) { | ||
| 117 | ret = posix_acl_equiv_mode(acl, &mode); | ||
| 118 | if (ret < 0) | ||
| 119 | return ret; | ||
| 120 | inode->i_mode = mode; | ||
| 121 | } | ||
| 122 | ret = 0; | ||
| 121 | break; | 123 | break; |
| 122 | case ACL_TYPE_DEFAULT: | 124 | case ACL_TYPE_DEFAULT: |
| 123 | if (!S_ISDIR(inode->i_mode)) | 125 | if (!S_ISDIR(inode->i_mode)) |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 56e50137d0e6..432a2da4641e 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -83,6 +83,17 @@ static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) | |||
| 83 | return (cache->flags & bits) == bits; | 83 | return (cache->flags & bits) == bits; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | void btrfs_get_block_group(struct btrfs_block_group_cache *cache) | ||
| 87 | { | ||
| 88 | atomic_inc(&cache->count); | ||
| 89 | } | ||
| 90 | |||
| 91 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache) | ||
| 92 | { | ||
| 93 | if (atomic_dec_and_test(&cache->count)) | ||
| 94 | kfree(cache); | ||
| 95 | } | ||
| 96 | |||
| 86 | /* | 97 | /* |
| 87 | * this adds the block group to the fs_info rb tree for the block group | 98 | * this adds the block group to the fs_info rb tree for the block group |
| 88 | * cache | 99 | * cache |
| @@ -156,7 +167,7 @@ block_group_cache_tree_search(struct btrfs_fs_info *info, u64 bytenr, | |||
| 156 | } | 167 | } |
| 157 | } | 168 | } |
| 158 | if (ret) | 169 | if (ret) |
| 159 | atomic_inc(&ret->count); | 170 | btrfs_get_block_group(ret); |
| 160 | spin_unlock(&info->block_group_cache_lock); | 171 | spin_unlock(&info->block_group_cache_lock); |
| 161 | 172 | ||
| 162 | return ret; | 173 | return ret; |
| @@ -407,6 +418,8 @@ err: | |||
| 407 | 418 | ||
| 408 | put_caching_control(caching_ctl); | 419 | put_caching_control(caching_ctl); |
| 409 | atomic_dec(&block_group->space_info->caching_threads); | 420 | atomic_dec(&block_group->space_info->caching_threads); |
| 421 | btrfs_put_block_group(block_group); | ||
| 422 | |||
| 410 | return 0; | 423 | return 0; |
| 411 | } | 424 | } |
| 412 | 425 | ||
| @@ -447,6 +460,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache) | |||
| 447 | up_write(&fs_info->extent_commit_sem); | 460 | up_write(&fs_info->extent_commit_sem); |
| 448 | 461 | ||
| 449 | atomic_inc(&cache->space_info->caching_threads); | 462 | atomic_inc(&cache->space_info->caching_threads); |
| 463 | btrfs_get_block_group(cache); | ||
| 450 | 464 | ||
| 451 | tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n", | 465 | tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n", |
| 452 | cache->key.objectid); | 466 | cache->key.objectid); |
| @@ -486,12 +500,6 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group( | |||
| 486 | return cache; | 500 | return cache; |
| 487 | } | 501 | } |
| 488 | 502 | ||
| 489 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache) | ||
| 490 | { | ||
| 491 | if (atomic_dec_and_test(&cache->count)) | ||
| 492 | kfree(cache); | ||
| 493 | } | ||
| 494 | |||
| 495 | static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | 503 | static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, |
| 496 | u64 flags) | 504 | u64 flags) |
| 497 | { | 505 | { |
| @@ -2582,7 +2590,7 @@ next_block_group(struct btrfs_root *root, | |||
| 2582 | if (node) { | 2590 | if (node) { |
| 2583 | cache = rb_entry(node, struct btrfs_block_group_cache, | 2591 | cache = rb_entry(node, struct btrfs_block_group_cache, |
| 2584 | cache_node); | 2592 | cache_node); |
| 2585 | atomic_inc(&cache->count); | 2593 | btrfs_get_block_group(cache); |
| 2586 | } else | 2594 | } else |
| 2587 | cache = NULL; | 2595 | cache = NULL; |
| 2588 | spin_unlock(&root->fs_info->block_group_cache_lock); | 2596 | spin_unlock(&root->fs_info->block_group_cache_lock); |
| @@ -4227,7 +4235,7 @@ search: | |||
| 4227 | u64 offset; | 4235 | u64 offset; |
| 4228 | int cached; | 4236 | int cached; |
| 4229 | 4237 | ||
| 4230 | atomic_inc(&block_group->count); | 4238 | btrfs_get_block_group(block_group); |
| 4231 | search_start = block_group->key.objectid; | 4239 | search_start = block_group->key.objectid; |
| 4232 | 4240 | ||
| 4233 | have_block_group: | 4241 | have_block_group: |
| @@ -4315,7 +4323,7 @@ have_block_group: | |||
| 4315 | 4323 | ||
| 4316 | btrfs_put_block_group(block_group); | 4324 | btrfs_put_block_group(block_group); |
| 4317 | block_group = last_ptr->block_group; | 4325 | block_group = last_ptr->block_group; |
| 4318 | atomic_inc(&block_group->count); | 4326 | btrfs_get_block_group(block_group); |
| 4319 | spin_unlock(&last_ptr->lock); | 4327 | spin_unlock(&last_ptr->lock); |
| 4320 | spin_unlock(&last_ptr->refill_lock); | 4328 | spin_unlock(&last_ptr->refill_lock); |
| 4321 | 4329 | ||
| @@ -7395,9 +7403,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
| 7395 | wait_block_group_cache_done(block_group); | 7403 | wait_block_group_cache_done(block_group); |
| 7396 | 7404 | ||
| 7397 | btrfs_remove_free_space_cache(block_group); | 7405 | btrfs_remove_free_space_cache(block_group); |
| 7398 | 7406 | btrfs_put_block_group(block_group); | |
| 7399 | WARN_ON(atomic_read(&block_group->count) != 1); | ||
| 7400 | kfree(block_group); | ||
| 7401 | 7407 | ||
| 7402 | spin_lock(&info->block_group_cache_lock); | 7408 | spin_lock(&info->block_group_cache_lock); |
| 7403 | } | 7409 | } |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index feaa13b105d9..c02033596f02 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -506,7 +506,8 @@ next_slot: | |||
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | static int extent_mergeable(struct extent_buffer *leaf, int slot, | 508 | static int extent_mergeable(struct extent_buffer *leaf, int slot, |
| 509 | u64 objectid, u64 bytenr, u64 *start, u64 *end) | 509 | u64 objectid, u64 bytenr, u64 orig_offset, |
| 510 | u64 *start, u64 *end) | ||
| 510 | { | 511 | { |
| 511 | struct btrfs_file_extent_item *fi; | 512 | struct btrfs_file_extent_item *fi; |
| 512 | struct btrfs_key key; | 513 | struct btrfs_key key; |
| @@ -522,6 +523,7 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot, | |||
| 522 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | 523 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); |
| 523 | if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG || | 524 | if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG || |
| 524 | btrfs_file_extent_disk_bytenr(leaf, fi) != bytenr || | 525 | btrfs_file_extent_disk_bytenr(leaf, fi) != bytenr || |
| 526 | btrfs_file_extent_offset(leaf, fi) != key.offset - orig_offset || | ||
| 525 | btrfs_file_extent_compression(leaf, fi) || | 527 | btrfs_file_extent_compression(leaf, fi) || |
| 526 | btrfs_file_extent_encryption(leaf, fi) || | 528 | btrfs_file_extent_encryption(leaf, fi) || |
| 527 | btrfs_file_extent_other_encoding(leaf, fi)) | 529 | btrfs_file_extent_other_encoding(leaf, fi)) |
| @@ -561,6 +563,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | |||
| 561 | u64 split; | 563 | u64 split; |
| 562 | int del_nr = 0; | 564 | int del_nr = 0; |
| 563 | int del_slot = 0; | 565 | int del_slot = 0; |
| 566 | int recow; | ||
| 564 | int ret; | 567 | int ret; |
| 565 | 568 | ||
| 566 | btrfs_drop_extent_cache(inode, start, end - 1, 0); | 569 | btrfs_drop_extent_cache(inode, start, end - 1, 0); |
| @@ -568,6 +571,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | |||
| 568 | path = btrfs_alloc_path(); | 571 | path = btrfs_alloc_path(); |
| 569 | BUG_ON(!path); | 572 | BUG_ON(!path); |
| 570 | again: | 573 | again: |
| 574 | recow = 0; | ||
| 571 | split = start; | 575 | split = start; |
| 572 | key.objectid = inode->i_ino; | 576 | key.objectid = inode->i_ino; |
| 573 | key.type = BTRFS_EXTENT_DATA_KEY; | 577 | key.type = BTRFS_EXTENT_DATA_KEY; |
| @@ -591,12 +595,60 @@ again: | |||
| 591 | bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); | 595 | bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
| 592 | num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); | 596 | num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); |
| 593 | orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi); | 597 | orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi); |
| 598 | memcpy(&new_key, &key, sizeof(new_key)); | ||
| 599 | |||
| 600 | if (start == key.offset && end < extent_end) { | ||
| 601 | other_start = 0; | ||
| 602 | other_end = start; | ||
| 603 | if (extent_mergeable(leaf, path->slots[0] - 1, | ||
| 604 | inode->i_ino, bytenr, orig_offset, | ||
| 605 | &other_start, &other_end)) { | ||
| 606 | new_key.offset = end; | ||
| 607 | btrfs_set_item_key_safe(trans, root, path, &new_key); | ||
| 608 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 609 | struct btrfs_file_extent_item); | ||
| 610 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
| 611 | extent_end - end); | ||
| 612 | btrfs_set_file_extent_offset(leaf, fi, | ||
| 613 | end - orig_offset); | ||
| 614 | fi = btrfs_item_ptr(leaf, path->slots[0] - 1, | ||
| 615 | struct btrfs_file_extent_item); | ||
| 616 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
| 617 | end - other_start); | ||
| 618 | btrfs_mark_buffer_dirty(leaf); | ||
| 619 | goto out; | ||
| 620 | } | ||
| 621 | } | ||
| 622 | |||
| 623 | if (start > key.offset && end == extent_end) { | ||
| 624 | other_start = end; | ||
| 625 | other_end = 0; | ||
| 626 | if (extent_mergeable(leaf, path->slots[0] + 1, | ||
| 627 | inode->i_ino, bytenr, orig_offset, | ||
| 628 | &other_start, &other_end)) { | ||
| 629 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 630 | struct btrfs_file_extent_item); | ||
| 631 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
| 632 | start - key.offset); | ||
| 633 | path->slots[0]++; | ||
| 634 | new_key.offset = start; | ||
| 635 | btrfs_set_item_key_safe(trans, root, path, &new_key); | ||
| 636 | |||
| 637 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 638 | struct btrfs_file_extent_item); | ||
| 639 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
| 640 | other_end - start); | ||
| 641 | btrfs_set_file_extent_offset(leaf, fi, | ||
| 642 | start - orig_offset); | ||
| 643 | btrfs_mark_buffer_dirty(leaf); | ||
| 644 | goto out; | ||
| 645 | } | ||
| 646 | } | ||
| 594 | 647 | ||
| 595 | while (start > key.offset || end < extent_end) { | 648 | while (start > key.offset || end < extent_end) { |
| 596 | if (key.offset == start) | 649 | if (key.offset == start) |
| 597 | split = end; | 650 | split = end; |
| 598 | 651 | ||
| 599 | memcpy(&new_key, &key, sizeof(new_key)); | ||
| 600 | new_key.offset = split; | 652 | new_key.offset = split; |
| 601 | ret = btrfs_duplicate_item(trans, root, path, &new_key); | 653 | ret = btrfs_duplicate_item(trans, root, path, &new_key); |
| 602 | if (ret == -EAGAIN) { | 654 | if (ret == -EAGAIN) { |
| @@ -631,15 +683,18 @@ again: | |||
| 631 | path->slots[0]--; | 683 | path->slots[0]--; |
| 632 | extent_end = end; | 684 | extent_end = end; |
| 633 | } | 685 | } |
| 686 | recow = 1; | ||
| 634 | } | 687 | } |
| 635 | 688 | ||
| 636 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 637 | struct btrfs_file_extent_item); | ||
| 638 | |||
| 639 | other_start = end; | 689 | other_start = end; |
| 640 | other_end = 0; | 690 | other_end = 0; |
| 641 | if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, | 691 | if (extent_mergeable(leaf, path->slots[0] + 1, |
| 642 | bytenr, &other_start, &other_end)) { | 692 | inode->i_ino, bytenr, orig_offset, |
| 693 | &other_start, &other_end)) { | ||
| 694 | if (recow) { | ||
| 695 | btrfs_release_path(root, path); | ||
| 696 | goto again; | ||
| 697 | } | ||
| 643 | extent_end = other_end; | 698 | extent_end = other_end; |
| 644 | del_slot = path->slots[0] + 1; | 699 | del_slot = path->slots[0] + 1; |
| 645 | del_nr++; | 700 | del_nr++; |
| @@ -650,8 +705,13 @@ again: | |||
| 650 | } | 705 | } |
| 651 | other_start = 0; | 706 | other_start = 0; |
| 652 | other_end = start; | 707 | other_end = start; |
| 653 | if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino, | 708 | if (extent_mergeable(leaf, path->slots[0] - 1, |
| 654 | bytenr, &other_start, &other_end)) { | 709 | inode->i_ino, bytenr, orig_offset, |
| 710 | &other_start, &other_end)) { | ||
| 711 | if (recow) { | ||
| 712 | btrfs_release_path(root, path); | ||
| 713 | goto again; | ||
| 714 | } | ||
| 655 | key.offset = other_start; | 715 | key.offset = other_start; |
| 656 | del_slot = path->slots[0]; | 716 | del_slot = path->slots[0]; |
| 657 | del_nr++; | 717 | del_nr++; |
| @@ -660,22 +720,22 @@ again: | |||
| 660 | inode->i_ino, orig_offset); | 720 | inode->i_ino, orig_offset); |
| 661 | BUG_ON(ret); | 721 | BUG_ON(ret); |
| 662 | } | 722 | } |
| 723 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 724 | struct btrfs_file_extent_item); | ||
| 663 | if (del_nr == 0) { | 725 | if (del_nr == 0) { |
| 664 | btrfs_set_file_extent_type(leaf, fi, | 726 | btrfs_set_file_extent_type(leaf, fi, |
| 665 | BTRFS_FILE_EXTENT_REG); | 727 | BTRFS_FILE_EXTENT_REG); |
| 666 | btrfs_mark_buffer_dirty(leaf); | 728 | btrfs_mark_buffer_dirty(leaf); |
| 667 | goto out; | 729 | } else { |
| 668 | } | 730 | btrfs_set_file_extent_type(leaf, fi, |
| 669 | 731 | BTRFS_FILE_EXTENT_REG); | |
| 670 | fi = btrfs_item_ptr(leaf, del_slot - 1, | 732 | btrfs_set_file_extent_num_bytes(leaf, fi, |
| 671 | struct btrfs_file_extent_item); | 733 | extent_end - key.offset); |
| 672 | btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); | 734 | btrfs_mark_buffer_dirty(leaf); |
| 673 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
| 674 | extent_end - key.offset); | ||
| 675 | btrfs_mark_buffer_dirty(leaf); | ||
| 676 | 735 | ||
| 677 | ret = btrfs_del_items(trans, root, path, del_slot, del_nr); | 736 | ret = btrfs_del_items(trans, root, path, del_slot, del_nr); |
| 678 | BUG_ON(ret); | 737 | BUG_ON(ret); |
| 738 | } | ||
| 679 | out: | 739 | out: |
| 680 | btrfs_free_path(path); | 740 | btrfs_free_path(path); |
| 681 | return 0; | 741 | return 0; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5440bab23635..b330e27c2d8b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -3796,6 +3796,12 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 3796 | 3796 | ||
| 3797 | if (location.type == BTRFS_INODE_ITEM_KEY) { | 3797 | if (location.type == BTRFS_INODE_ITEM_KEY) { |
| 3798 | inode = btrfs_iget(dir->i_sb, &location, root); | 3798 | inode = btrfs_iget(dir->i_sb, &location, root); |
| 3799 | if (unlikely(root->clean_orphans) && | ||
| 3800 | !(inode->i_sb->s_flags & MS_RDONLY)) { | ||
| 3801 | down_read(&root->fs_info->cleanup_work_sem); | ||
| 3802 | btrfs_orphan_cleanup(root); | ||
| 3803 | up_read(&root->fs_info->cleanup_work_sem); | ||
| 3804 | } | ||
| 3799 | return inode; | 3805 | return inode; |
| 3800 | } | 3806 | } |
| 3801 | 3807 | ||
| @@ -3995,7 +4001,11 @@ skip: | |||
| 3995 | 4001 | ||
| 3996 | /* Reached end of directory/root. Bump pos past the last item. */ | 4002 | /* Reached end of directory/root. Bump pos past the last item. */ |
| 3997 | if (key_type == BTRFS_DIR_INDEX_KEY) | 4003 | if (key_type == BTRFS_DIR_INDEX_KEY) |
| 3998 | filp->f_pos = INT_LIMIT(off_t); | 4004 | /* |
| 4005 | * 32-bit glibc will use getdents64, but then strtol - | ||
| 4006 | * so the last number we can serve is this. | ||
| 4007 | */ | ||
| 4008 | filp->f_pos = 0x7fffffff; | ||
| 3999 | else | 4009 | else |
| 4000 | filp->f_pos++; | 4010 | filp->f_pos++; |
| 4001 | nopos: | 4011 | nopos: |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index b10a49d4bc6a..5c2a9e78a949 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -626,6 +626,8 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
| 626 | 626 | ||
| 627 | if (ordered) | 627 | if (ordered) |
| 628 | offset = entry_end(ordered); | 628 | offset = entry_end(ordered); |
| 629 | else | ||
| 630 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | ||
| 629 | 631 | ||
| 630 | mutex_lock(&tree->mutex); | 632 | mutex_lock(&tree->mutex); |
| 631 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 633 | disk_i_size = BTRFS_I(inode)->disk_i_size; |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index a9728680eca8..ed3e4a2ec2c8 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -3281,8 +3281,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
| 3281 | return -ENOMEM; | 3281 | return -ENOMEM; |
| 3282 | 3282 | ||
| 3283 | path = btrfs_alloc_path(); | 3283 | path = btrfs_alloc_path(); |
| 3284 | if (!path) | 3284 | if (!path) { |
| 3285 | kfree(cluster); | ||
| 3285 | return -ENOMEM; | 3286 | return -ENOMEM; |
| 3287 | } | ||
| 3286 | 3288 | ||
| 3287 | rc->extents_found = 0; | 3289 | rc->extents_found = 0; |
| 3288 | rc->extents_skipped = 0; | 3290 | rc->extents_skipped = 0; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 198cff28766d..220dad5db017 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -2649,8 +2649,10 @@ again: | |||
| 2649 | em = lookup_extent_mapping(em_tree, logical, *length); | 2649 | em = lookup_extent_mapping(em_tree, logical, *length); |
| 2650 | read_unlock(&em_tree->lock); | 2650 | read_unlock(&em_tree->lock); |
| 2651 | 2651 | ||
| 2652 | if (!em && unplug_page) | 2652 | if (!em && unplug_page) { |
| 2653 | kfree(multi); | ||
| 2653 | return 0; | 2654 | return 0; |
| 2655 | } | ||
| 2654 | 2656 | ||
| 2655 | if (!em) { | 2657 | if (!em) { |
| 2656 | printk(KERN_CRIT "unable to find logical %llu len %llu\n", | 2658 | printk(KERN_CRIT "unable to find logical %llu len %llu\n", |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index fbb6e5eed697..7cb0a59f4b9d 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -1748,7 +1748,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, | |||
| 1748 | char *cipher_name, size_t *key_size) | 1748 | char *cipher_name, size_t *key_size) |
| 1749 | { | 1749 | { |
| 1750 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; | 1750 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; |
| 1751 | char *full_alg_name; | 1751 | char *full_alg_name = NULL; |
| 1752 | int rc; | 1752 | int rc; |
| 1753 | 1753 | ||
| 1754 | *key_tfm = NULL; | 1754 | *key_tfm = NULL; |
| @@ -1763,7 +1763,6 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, | |||
| 1763 | if (rc) | 1763 | if (rc) |
| 1764 | goto out; | 1764 | goto out; |
| 1765 | *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); | 1765 | *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); |
| 1766 | kfree(full_alg_name); | ||
| 1767 | if (IS_ERR(*key_tfm)) { | 1766 | if (IS_ERR(*key_tfm)) { |
| 1768 | rc = PTR_ERR(*key_tfm); | 1767 | rc = PTR_ERR(*key_tfm); |
| 1769 | printk(KERN_ERR "Unable to allocate crypto cipher with name " | 1768 | printk(KERN_ERR "Unable to allocate crypto cipher with name " |
| @@ -1786,6 +1785,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, | |||
| 1786 | goto out; | 1785 | goto out; |
| 1787 | } | 1786 | } |
| 1788 | out: | 1787 | out: |
| 1788 | kfree(full_alg_name); | ||
| 1789 | return rc; | 1789 | return rc; |
| 1790 | } | 1790 | } |
| 1791 | 1791 | ||
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 9e944057001b..678172b61be2 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
| @@ -158,7 +158,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
| 158 | struct dentry *ecryptfs_dentry = file->f_path.dentry; | 158 | struct dentry *ecryptfs_dentry = file->f_path.dentry; |
| 159 | /* Private value of ecryptfs_dentry allocated in | 159 | /* Private value of ecryptfs_dentry allocated in |
| 160 | * ecryptfs_lookup() */ | 160 | * ecryptfs_lookup() */ |
| 161 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 161 | struct dentry *lower_dentry; |
| 162 | struct ecryptfs_file_info *file_info; | 162 | struct ecryptfs_file_info *file_info; |
| 163 | 163 | ||
| 164 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 164 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
| @@ -191,13 +191,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
| 191 | | ECRYPTFS_ENCRYPTED); | 191 | | ECRYPTFS_ENCRYPTED); |
| 192 | } | 192 | } |
| 193 | mutex_unlock(&crypt_stat->cs_mutex); | 193 | mutex_unlock(&crypt_stat->cs_mutex); |
| 194 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) | ||
| 195 | && !(file->f_flags & O_RDONLY)) { | ||
| 196 | rc = -EPERM; | ||
| 197 | printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " | ||
| 198 | "file must hence be opened RO\n", __func__); | ||
| 199 | goto out; | ||
| 200 | } | ||
| 201 | if (!ecryptfs_inode_to_private(inode)->lower_file) { | 194 | if (!ecryptfs_inode_to_private(inode)->lower_file) { |
| 202 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 195 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); |
| 203 | if (rc) { | 196 | if (rc) { |
| @@ -208,6 +201,13 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
| 208 | goto out; | 201 | goto out; |
| 209 | } | 202 | } |
| 210 | } | 203 | } |
| 204 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) | ||
| 205 | && !(file->f_flags & O_RDONLY)) { | ||
| 206 | rc = -EPERM; | ||
| 207 | printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " | ||
| 208 | "file must hence be opened RO\n", __func__); | ||
| 209 | goto out; | ||
| 210 | } | ||
| 211 | ecryptfs_set_file_lower( | 211 | ecryptfs_set_file_lower( |
| 212 | file, ecryptfs_inode_to_private(inode)->lower_file); | 212 | file, ecryptfs_inode_to_private(inode)->lower_file); |
| 213 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 213 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
| @@ -299,7 +299,6 @@ static int ecryptfs_ioctl(struct inode *inode, struct file *file, | |||
| 299 | const struct file_operations ecryptfs_dir_fops = { | 299 | const struct file_operations ecryptfs_dir_fops = { |
| 300 | .readdir = ecryptfs_readdir, | 300 | .readdir = ecryptfs_readdir, |
| 301 | .ioctl = ecryptfs_ioctl, | 301 | .ioctl = ecryptfs_ioctl, |
| 302 | .mmap = generic_file_mmap, | ||
| 303 | .open = ecryptfs_open, | 302 | .open = ecryptfs_open, |
| 304 | .flush = ecryptfs_flush, | 303 | .flush = ecryptfs_flush, |
| 305 | .release = ecryptfs_release, | 304 | .release = ecryptfs_release, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 7f8545032930..4a430ab4115c 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -282,7 +282,8 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
| 282 | goto out; | 282 | goto out; |
| 283 | } | 283 | } |
| 284 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | 284 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, |
| 285 | ecryptfs_dir_inode->i_sb, 1); | 285 | ecryptfs_dir_inode->i_sb, |
| 286 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | ||
| 286 | if (rc) { | 287 | if (rc) { |
| 287 | printk(KERN_ERR "%s: Error interposing; rc = [%d]\n", | 288 | printk(KERN_ERR "%s: Error interposing; rc = [%d]\n", |
| 288 | __func__, rc); | 289 | __func__, rc); |
| @@ -463,9 +464,6 @@ out_lock: | |||
| 463 | unlock_dir(lower_dir_dentry); | 464 | unlock_dir(lower_dir_dentry); |
| 464 | dput(lower_new_dentry); | 465 | dput(lower_new_dentry); |
| 465 | dput(lower_old_dentry); | 466 | dput(lower_old_dentry); |
| 466 | d_drop(lower_old_dentry); | ||
| 467 | d_drop(new_dentry); | ||
| 468 | d_drop(old_dentry); | ||
| 469 | return rc; | 467 | return rc; |
| 470 | } | 468 | } |
| 471 | 469 | ||
| @@ -614,6 +612,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 614 | struct dentry *lower_new_dentry; | 612 | struct dentry *lower_new_dentry; |
| 615 | struct dentry *lower_old_dir_dentry; | 613 | struct dentry *lower_old_dir_dentry; |
| 616 | struct dentry *lower_new_dir_dentry; | 614 | struct dentry *lower_new_dir_dentry; |
| 615 | struct dentry *trap = NULL; | ||
| 617 | 616 | ||
| 618 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | 617 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
| 619 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | 618 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
| @@ -621,7 +620,17 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 621 | dget(lower_new_dentry); | 620 | dget(lower_new_dentry); |
| 622 | lower_old_dir_dentry = dget_parent(lower_old_dentry); | 621 | lower_old_dir_dentry = dget_parent(lower_old_dentry); |
| 623 | lower_new_dir_dentry = dget_parent(lower_new_dentry); | 622 | lower_new_dir_dentry = dget_parent(lower_new_dentry); |
| 624 | lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 623 | trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
| 624 | /* source should not be ancestor of target */ | ||
| 625 | if (trap == lower_old_dentry) { | ||
| 626 | rc = -EINVAL; | ||
| 627 | goto out_lock; | ||
| 628 | } | ||
| 629 | /* target should not be ancestor of source */ | ||
| 630 | if (trap == lower_new_dentry) { | ||
| 631 | rc = -ENOTEMPTY; | ||
| 632 | goto out_lock; | ||
| 633 | } | ||
| 625 | rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, | 634 | rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, |
| 626 | lower_new_dir_dentry->d_inode, lower_new_dentry); | 635 | lower_new_dir_dentry->d_inode, lower_new_dentry); |
| 627 | if (rc) | 636 | if (rc) |
| @@ -772,18 +781,23 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, | |||
| 772 | } | 781 | } |
| 773 | 782 | ||
| 774 | /** | 783 | /** |
| 775 | * ecryptfs_truncate | 784 | * truncate_upper |
| 776 | * @dentry: The ecryptfs layer dentry | 785 | * @dentry: The ecryptfs layer dentry |
| 777 | * @new_length: The length to expand the file to | 786 | * @ia: Address of the ecryptfs inode's attributes |
| 787 | * @lower_ia: Address of the lower inode's attributes | ||
| 778 | * | 788 | * |
| 779 | * Function to handle truncations modifying the size of the file. Note | 789 | * Function to handle truncations modifying the size of the file. Note |
| 780 | * that the file sizes are interpolated. When expanding, we are simply | 790 | * that the file sizes are interpolated. When expanding, we are simply |
| 781 | * writing strings of 0's out. When truncating, we need to modify the | 791 | * writing strings of 0's out. When truncating, we truncate the upper |
| 782 | * underlying file size according to the page index interpolations. | 792 | * inode and update the lower_ia according to the page index |
| 793 | * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return, | ||
| 794 | * the caller must use lower_ia in a call to notify_change() to perform | ||
| 795 | * the truncation of the lower inode. | ||
| 783 | * | 796 | * |
| 784 | * Returns zero on success; non-zero otherwise | 797 | * Returns zero on success; non-zero otherwise |
| 785 | */ | 798 | */ |
| 786 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | 799 | static int truncate_upper(struct dentry *dentry, struct iattr *ia, |
| 800 | struct iattr *lower_ia) | ||
| 787 | { | 801 | { |
| 788 | int rc = 0; | 802 | int rc = 0; |
| 789 | struct inode *inode = dentry->d_inode; | 803 | struct inode *inode = dentry->d_inode; |
| @@ -794,8 +808,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
| 794 | loff_t lower_size_before_truncate; | 808 | loff_t lower_size_before_truncate; |
| 795 | loff_t lower_size_after_truncate; | 809 | loff_t lower_size_after_truncate; |
| 796 | 810 | ||
| 797 | if (unlikely((new_length == i_size))) | 811 | if (unlikely((ia->ia_size == i_size))) { |
| 812 | lower_ia->ia_valid &= ~ATTR_SIZE; | ||
| 798 | goto out; | 813 | goto out; |
| 814 | } | ||
| 799 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 815 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
| 800 | /* Set up a fake ecryptfs file, this is used to interface with | 816 | /* Set up a fake ecryptfs file, this is used to interface with |
| 801 | * the file in the underlying filesystem so that the | 817 | * the file in the underlying filesystem so that the |
| @@ -815,28 +831,30 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
| 815 | &fake_ecryptfs_file, | 831 | &fake_ecryptfs_file, |
| 816 | ecryptfs_inode_to_private(dentry->d_inode)->lower_file); | 832 | ecryptfs_inode_to_private(dentry->d_inode)->lower_file); |
| 817 | /* Switch on growing or shrinking file */ | 833 | /* Switch on growing or shrinking file */ |
| 818 | if (new_length > i_size) { | 834 | if (ia->ia_size > i_size) { |
| 819 | char zero[] = { 0x00 }; | 835 | char zero[] = { 0x00 }; |
| 820 | 836 | ||
| 837 | lower_ia->ia_valid &= ~ATTR_SIZE; | ||
| 821 | /* Write a single 0 at the last position of the file; | 838 | /* Write a single 0 at the last position of the file; |
| 822 | * this triggers code that will fill in 0's throughout | 839 | * this triggers code that will fill in 0's throughout |
| 823 | * the intermediate portion of the previous end of the | 840 | * the intermediate portion of the previous end of the |
| 824 | * file and the new and of the file */ | 841 | * file and the new and of the file */ |
| 825 | rc = ecryptfs_write(&fake_ecryptfs_file, zero, | 842 | rc = ecryptfs_write(&fake_ecryptfs_file, zero, |
| 826 | (new_length - 1), 1); | 843 | (ia->ia_size - 1), 1); |
| 827 | } else { /* new_length < i_size_read(inode) */ | 844 | } else { /* ia->ia_size < i_size_read(inode) */ |
| 828 | /* We're chopping off all the pages down do the page | 845 | /* We're chopping off all the pages down to the page |
| 829 | * in which new_length is located. Fill in the end of | 846 | * in which ia->ia_size is located. Fill in the end of |
| 830 | * that page from (new_length & ~PAGE_CACHE_MASK) to | 847 | * that page from (ia->ia_size & ~PAGE_CACHE_MASK) to |
| 831 | * PAGE_CACHE_SIZE with zeros. */ | 848 | * PAGE_CACHE_SIZE with zeros. */ |
| 832 | size_t num_zeros = (PAGE_CACHE_SIZE | 849 | size_t num_zeros = (PAGE_CACHE_SIZE |
| 833 | - (new_length & ~PAGE_CACHE_MASK)); | 850 | - (ia->ia_size & ~PAGE_CACHE_MASK)); |
| 834 | 851 | ||
| 835 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 852 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
| 836 | rc = vmtruncate(inode, new_length); | 853 | rc = vmtruncate(inode, ia->ia_size); |
| 837 | if (rc) | 854 | if (rc) |
| 838 | goto out_free; | 855 | goto out_free; |
| 839 | rc = vmtruncate(lower_dentry->d_inode, new_length); | 856 | lower_ia->ia_size = ia->ia_size; |
| 857 | lower_ia->ia_valid |= ATTR_SIZE; | ||
| 840 | goto out_free; | 858 | goto out_free; |
| 841 | } | 859 | } |
| 842 | if (num_zeros) { | 860 | if (num_zeros) { |
| @@ -848,7 +866,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
| 848 | goto out_free; | 866 | goto out_free; |
| 849 | } | 867 | } |
| 850 | rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt, | 868 | rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt, |
| 851 | new_length, num_zeros); | 869 | ia->ia_size, num_zeros); |
| 852 | kfree(zeros_virt); | 870 | kfree(zeros_virt); |
| 853 | if (rc) { | 871 | if (rc) { |
| 854 | printk(KERN_ERR "Error attempting to zero out " | 872 | printk(KERN_ERR "Error attempting to zero out " |
| @@ -857,7 +875,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
| 857 | goto out_free; | 875 | goto out_free; |
| 858 | } | 876 | } |
| 859 | } | 877 | } |
| 860 | vmtruncate(inode, new_length); | 878 | vmtruncate(inode, ia->ia_size); |
| 861 | rc = ecryptfs_write_inode_size_to_metadata(inode); | 879 | rc = ecryptfs_write_inode_size_to_metadata(inode); |
| 862 | if (rc) { | 880 | if (rc) { |
| 863 | printk(KERN_ERR "Problem with " | 881 | printk(KERN_ERR "Problem with " |
| @@ -870,10 +888,12 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
| 870 | lower_size_before_truncate = | 888 | lower_size_before_truncate = |
| 871 | upper_size_to_lower_size(crypt_stat, i_size); | 889 | upper_size_to_lower_size(crypt_stat, i_size); |
| 872 | lower_size_after_truncate = | 890 | lower_size_after_truncate = |
| 873 | upper_size_to_lower_size(crypt_stat, new_length); | 891 | upper_size_to_lower_size(crypt_stat, ia->ia_size); |
| 874 | if (lower_size_after_truncate < lower_size_before_truncate) | 892 | if (lower_size_after_truncate < lower_size_before_truncate) { |
| 875 | vmtruncate(lower_dentry->d_inode, | 893 | lower_ia->ia_size = lower_size_after_truncate; |
| 876 | lower_size_after_truncate); | 894 | lower_ia->ia_valid |= ATTR_SIZE; |
| 895 | } else | ||
| 896 | lower_ia->ia_valid &= ~ATTR_SIZE; | ||
| 877 | } | 897 | } |
| 878 | out_free: | 898 | out_free: |
| 879 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | 899 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) |
| @@ -883,6 +903,33 @@ out: | |||
| 883 | return rc; | 903 | return rc; |
| 884 | } | 904 | } |
| 885 | 905 | ||
| 906 | /** | ||
| 907 | * ecryptfs_truncate | ||
| 908 | * @dentry: The ecryptfs layer dentry | ||
| 909 | * @new_length: The length to expand the file to | ||
| 910 | * | ||
| 911 | * Simple function that handles the truncation of an eCryptfs inode and | ||
| 912 | * its corresponding lower inode. | ||
| 913 | * | ||
| 914 | * Returns zero on success; non-zero otherwise | ||
| 915 | */ | ||
| 916 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | ||
| 917 | { | ||
| 918 | struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length }; | ||
| 919 | struct iattr lower_ia = { .ia_valid = 0 }; | ||
| 920 | int rc; | ||
| 921 | |||
| 922 | rc = truncate_upper(dentry, &ia, &lower_ia); | ||
| 923 | if (!rc && lower_ia.ia_valid & ATTR_SIZE) { | ||
| 924 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 925 | |||
| 926 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
| 927 | rc = notify_change(lower_dentry, &lower_ia); | ||
| 928 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
| 929 | } | ||
| 930 | return rc; | ||
| 931 | } | ||
| 932 | |||
| 886 | static int | 933 | static int |
| 887 | ecryptfs_permission(struct inode *inode, int mask) | 934 | ecryptfs_permission(struct inode *inode, int mask) |
| 888 | { | 935 | { |
| @@ -905,6 +952,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
| 905 | { | 952 | { |
| 906 | int rc = 0; | 953 | int rc = 0; |
| 907 | struct dentry *lower_dentry; | 954 | struct dentry *lower_dentry; |
| 955 | struct iattr lower_ia; | ||
| 908 | struct inode *inode; | 956 | struct inode *inode; |
| 909 | struct inode *lower_inode; | 957 | struct inode *lower_inode; |
| 910 | struct ecryptfs_crypt_stat *crypt_stat; | 958 | struct ecryptfs_crypt_stat *crypt_stat; |
| @@ -943,15 +991,11 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
| 943 | } | 991 | } |
| 944 | } | 992 | } |
| 945 | mutex_unlock(&crypt_stat->cs_mutex); | 993 | mutex_unlock(&crypt_stat->cs_mutex); |
| 994 | memcpy(&lower_ia, ia, sizeof(lower_ia)); | ||
| 995 | if (ia->ia_valid & ATTR_FILE) | ||
| 996 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); | ||
| 946 | if (ia->ia_valid & ATTR_SIZE) { | 997 | if (ia->ia_valid & ATTR_SIZE) { |
| 947 | ecryptfs_printk(KERN_DEBUG, | 998 | rc = truncate_upper(dentry, ia, &lower_ia); |
| 948 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", | ||
| 949 | ia->ia_valid, ATTR_SIZE); | ||
| 950 | rc = ecryptfs_truncate(dentry, ia->ia_size); | ||
| 951 | /* ecryptfs_truncate handles resizing of the lower file */ | ||
| 952 | ia->ia_valid &= ~ATTR_SIZE; | ||
| 953 | ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n", | ||
| 954 | ia->ia_valid); | ||
| 955 | if (rc < 0) | 999 | if (rc < 0) |
| 956 | goto out; | 1000 | goto out; |
| 957 | } | 1001 | } |
| @@ -960,17 +1004,32 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
| 960 | * mode change is for clearing setuid/setgid bits. Allow lower fs | 1004 | * mode change is for clearing setuid/setgid bits. Allow lower fs |
| 961 | * to interpret this in its own way. | 1005 | * to interpret this in its own way. |
| 962 | */ | 1006 | */ |
| 963 | if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) | 1007 | if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) |
| 964 | ia->ia_valid &= ~ATTR_MODE; | 1008 | lower_ia.ia_valid &= ~ATTR_MODE; |
| 965 | 1009 | ||
| 966 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1010 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
| 967 | rc = notify_change(lower_dentry, ia); | 1011 | rc = notify_change(lower_dentry, &lower_ia); |
| 968 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | 1012 | mutex_unlock(&lower_dentry->d_inode->i_mutex); |
| 969 | out: | 1013 | out: |
| 970 | fsstack_copy_attr_all(inode, lower_inode); | 1014 | fsstack_copy_attr_all(inode, lower_inode); |
| 971 | return rc; | 1015 | return rc; |
| 972 | } | 1016 | } |
| 973 | 1017 | ||
| 1018 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
| 1019 | struct kstat *stat) | ||
| 1020 | { | ||
| 1021 | struct kstat lower_stat; | ||
| 1022 | int rc; | ||
| 1023 | |||
| 1024 | rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry), | ||
| 1025 | ecryptfs_dentry_to_lower(dentry), &lower_stat); | ||
| 1026 | if (!rc) { | ||
| 1027 | generic_fillattr(dentry->d_inode, stat); | ||
| 1028 | stat->blocks = lower_stat.blocks; | ||
| 1029 | } | ||
| 1030 | return rc; | ||
| 1031 | } | ||
| 1032 | |||
| 974 | int | 1033 | int |
| 975 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 1034 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
| 976 | size_t size, int flags) | 1035 | size_t size, int flags) |
| @@ -1100,6 +1159,7 @@ const struct inode_operations ecryptfs_dir_iops = { | |||
| 1100 | const struct inode_operations ecryptfs_main_iops = { | 1159 | const struct inode_operations ecryptfs_main_iops = { |
| 1101 | .permission = ecryptfs_permission, | 1160 | .permission = ecryptfs_permission, |
| 1102 | .setattr = ecryptfs_setattr, | 1161 | .setattr = ecryptfs_setattr, |
| 1162 | .getattr = ecryptfs_getattr, | ||
| 1103 | .setxattr = ecryptfs_setxattr, | 1163 | .setxattr = ecryptfs_setxattr, |
| 1104 | .getxattr = ecryptfs_getxattr, | 1164 | .getxattr = ecryptfs_getxattr, |
| 1105 | .listxattr = ecryptfs_listxattr, | 1165 | .listxattr = ecryptfs_listxattr, |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 567bc4b9f70a..ea2f92101dfe 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -585,8 +585,8 @@ out: | |||
| 585 | * with as much information as it can before needing | 585 | * with as much information as it can before needing |
| 586 | * the lower filesystem. | 586 | * the lower filesystem. |
| 587 | * ecryptfs_read_super(): this accesses the lower filesystem and uses | 587 | * ecryptfs_read_super(): this accesses the lower filesystem and uses |
| 588 | * ecryptfs_interpolate to perform most of the linking | 588 | * ecryptfs_interpose to perform most of the linking |
| 589 | * ecryptfs_interpolate(): links the lower filesystem into ecryptfs | 589 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) |
| 590 | */ | 590 | */ |
| 591 | static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, | 591 | static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, |
| 592 | const char *dev_name, void *raw_data, | 592 | const char *dev_name, void *raw_data, |
