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/compat_ioctl.c | 3 | ||||
| -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 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 14 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 183 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 2 | ||||
| -rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_dfrag.c | 106 | ||||
| -rw-r--r-- | fs/xfs/xfs_iget.c | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.c | 21 | ||||
| -rw-r--r-- | fs/xfs/xfs_rtalloc.c | 2 |
21 files changed, 439 insertions, 222 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/compat_ioctl.c b/fs/compat_ioctl.c index 332dd00f0894..c5c45de1a2ee 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -1005,6 +1005,9 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND) | |||
| 1005 | COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) | 1005 | COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) |
| 1006 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) | 1006 | COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) |
| 1007 | #endif | 1007 | #endif |
| 1008 | /* Big V (don't complain on serial console) */ | ||
| 1009 | IGNORE_IOCTL(VT_OPENQRY) | ||
| 1010 | IGNORE_IOCTL(VT_GETMODE) | ||
| 1008 | /* Little p (/dev/rtc, /dev/envctrl, etc.) */ | 1011 | /* Little p (/dev/rtc, /dev/envctrl, etc.) */ |
| 1009 | COMPATIBLE_IOCTL(RTC_AIE_ON) | 1012 | COMPATIBLE_IOCTL(RTC_AIE_ON) |
| 1010 | COMPATIBLE_IOCTL(RTC_AIE_OFF) | 1013 | COMPATIBLE_IOCTL(RTC_AIE_OFF) |
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, |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 09783cc444ac..77414db10dc2 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -954,16 +954,14 @@ xfs_fs_destroy_inode( | |||
| 954 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); | 954 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); |
| 955 | 955 | ||
| 956 | /* | 956 | /* |
| 957 | * If we have nothing to flush with this inode then complete the | 957 | * We always use background reclaim here because even if the |
| 958 | * teardown now, otherwise delay the flush operation. | 958 | * inode is clean, it still may be under IO and hence we have |
| 959 | * to take the flush lock. The background reclaim path handles | ||
| 960 | * this more efficiently than we can here, so simply let background | ||
| 961 | * reclaim tear down all inodes. | ||
| 959 | */ | 962 | */ |
| 960 | if (!xfs_inode_clean(ip)) { | ||
| 961 | xfs_inode_set_reclaim_tag(ip); | ||
| 962 | return; | ||
| 963 | } | ||
| 964 | |||
| 965 | out_reclaim: | 963 | out_reclaim: |
| 966 | xfs_ireclaim(ip); | 964 | xfs_inode_set_reclaim_tag(ip); |
| 967 | } | 965 | } |
| 968 | 966 | ||
| 969 | /* | 967 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 6fed97a8cd3e..1f5e4bb5e970 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
| @@ -65,7 +65,6 @@ xfs_inode_ag_lookup( | |||
| 65 | * as the tree is sparse and a gang lookup walks to find | 65 | * as the tree is sparse and a gang lookup walks to find |
| 66 | * the number of objects requested. | 66 | * the number of objects requested. |
| 67 | */ | 67 | */ |
| 68 | read_lock(&pag->pag_ici_lock); | ||
| 69 | if (tag == XFS_ICI_NO_TAG) { | 68 | if (tag == XFS_ICI_NO_TAG) { |
| 70 | nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, | 69 | nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, |
| 71 | (void **)&ip, *first_index, 1); | 70 | (void **)&ip, *first_index, 1); |
| @@ -74,7 +73,7 @@ xfs_inode_ag_lookup( | |||
| 74 | (void **)&ip, *first_index, 1, tag); | 73 | (void **)&ip, *first_index, 1, tag); |
| 75 | } | 74 | } |
| 76 | if (!nr_found) | 75 | if (!nr_found) |
| 77 | goto unlock; | 76 | return NULL; |
| 78 | 77 | ||
| 79 | /* | 78 | /* |
| 80 | * Update the index for the next lookup. Catch overflows | 79 | * Update the index for the next lookup. Catch overflows |
| @@ -84,13 +83,8 @@ xfs_inode_ag_lookup( | |||
| 84 | */ | 83 | */ |
| 85 | *first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1); | 84 | *first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1); |
| 86 | if (*first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) | 85 | if (*first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) |
| 87 | goto unlock; | 86 | return NULL; |
| 88 | |||
| 89 | return ip; | 87 | return ip; |
| 90 | |||
| 91 | unlock: | ||
| 92 | read_unlock(&pag->pag_ici_lock); | ||
| 93 | return NULL; | ||
| 94 | } | 88 | } |
| 95 | 89 | ||
| 96 | STATIC int | 90 | STATIC int |
| @@ -100,7 +94,8 @@ xfs_inode_ag_walk( | |||
| 100 | int (*execute)(struct xfs_inode *ip, | 94 | int (*execute)(struct xfs_inode *ip, |
| 101 | struct xfs_perag *pag, int flags), | 95 | struct xfs_perag *pag, int flags), |
| 102 | int flags, | 96 | int flags, |
| 103 | int tag) | 97 | int tag, |
| 98 | int exclusive) | ||
| 104 | { | 99 | { |
| 105 | struct xfs_perag *pag = &mp->m_perag[ag]; | 100 | struct xfs_perag *pag = &mp->m_perag[ag]; |
| 106 | uint32_t first_index; | 101 | uint32_t first_index; |
| @@ -114,10 +109,20 @@ restart: | |||
| 114 | int error = 0; | 109 | int error = 0; |
| 115 | xfs_inode_t *ip; | 110 | xfs_inode_t *ip; |
| 116 | 111 | ||
| 112 | if (exclusive) | ||
| 113 | write_lock(&pag->pag_ici_lock); | ||
| 114 | else | ||
| 115 | read_lock(&pag->pag_ici_lock); | ||
| 117 | ip = xfs_inode_ag_lookup(mp, pag, &first_index, tag); | 116 | ip = xfs_inode_ag_lookup(mp, pag, &first_index, tag); |
| 118 | if (!ip) | 117 | if (!ip) { |
| 118 | if (exclusive) | ||
| 119 | write_unlock(&pag->pag_ici_lock); | ||
| 120 | else | ||
| 121 | read_unlock(&pag->pag_ici_lock); | ||
| 119 | break; | 122 | break; |
| 123 | } | ||
| 120 | 124 | ||
| 125 | /* execute releases pag->pag_ici_lock */ | ||
| 121 | error = execute(ip, pag, flags); | 126 | error = execute(ip, pag, flags); |
| 122 | if (error == EAGAIN) { | 127 | if (error == EAGAIN) { |
| 123 | skipped++; | 128 | skipped++; |
| @@ -125,9 +130,8 @@ restart: | |||
| 125 | } | 130 | } |
| 126 | if (error) | 131 | if (error) |
| 127 | last_error = error; | 132 | last_error = error; |
| 128 | /* | 133 | |
| 129 | * bail out if the filesystem is corrupted. | 134 | /* bail out if the filesystem is corrupted. */ |
| 130 | */ | ||
| 131 | if (error == EFSCORRUPTED) | 135 | if (error == EFSCORRUPTED) |
| 132 | break; | 136 | break; |
| 133 | 137 | ||
| @@ -148,7 +152,8 @@ xfs_inode_ag_iterator( | |||
| 148 | int (*execute)(struct xfs_inode *ip, | 152 | int (*execute)(struct xfs_inode *ip, |
| 149 | struct xfs_perag *pag, int flags), | 153 | struct xfs_perag *pag, int flags), |
| 150 | int flags, | 154 | int flags, |
| 151 | int tag) | 155 | int tag, |
| 156 | int exclusive) | ||
| 152 | { | 157 | { |
| 153 | int error = 0; | 158 | int error = 0; |
| 154 | int last_error = 0; | 159 | int last_error = 0; |
| @@ -157,7 +162,8 @@ xfs_inode_ag_iterator( | |||
| 157 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { | 162 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { |
| 158 | if (!mp->m_perag[ag].pag_ici_init) | 163 | if (!mp->m_perag[ag].pag_ici_init) |
| 159 | continue; | 164 | continue; |
| 160 | error = xfs_inode_ag_walk(mp, ag, execute, flags, tag); | 165 | error = xfs_inode_ag_walk(mp, ag, execute, flags, tag, |
| 166 | exclusive); | ||
| 161 | if (error) { | 167 | if (error) { |
| 162 | last_error = error; | 168 | last_error = error; |
| 163 | if (error == EFSCORRUPTED) | 169 | if (error == EFSCORRUPTED) |
| @@ -174,30 +180,31 @@ xfs_sync_inode_valid( | |||
| 174 | struct xfs_perag *pag) | 180 | struct xfs_perag *pag) |
| 175 | { | 181 | { |
| 176 | struct inode *inode = VFS_I(ip); | 182 | struct inode *inode = VFS_I(ip); |
| 183 | int error = EFSCORRUPTED; | ||
| 177 | 184 | ||
| 178 | /* nothing to sync during shutdown */ | 185 | /* nothing to sync during shutdown */ |
| 179 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 186 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
| 180 | read_unlock(&pag->pag_ici_lock); | 187 | goto out_unlock; |
| 181 | return EFSCORRUPTED; | ||
| 182 | } | ||
| 183 | 188 | ||
| 184 | /* | 189 | /* avoid new or reclaimable inodes. Leave for reclaim code to flush */ |
| 185 | * If we can't get a reference on the inode, it must be in reclaim. | 190 | error = ENOENT; |
| 186 | * Leave it for the reclaim code to flush. Also avoid inodes that | 191 | if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM)) |
| 187 | * haven't been fully initialised. | 192 | goto out_unlock; |
| 188 | */ | ||
| 189 | if (!igrab(inode)) { | ||
| 190 | read_unlock(&pag->pag_ici_lock); | ||
| 191 | return ENOENT; | ||
| 192 | } | ||
| 193 | read_unlock(&pag->pag_ici_lock); | ||
| 194 | 193 | ||
| 195 | if (is_bad_inode(inode) || xfs_iflags_test(ip, XFS_INEW)) { | 194 | /* If we can't grab the inode, it must on it's way to reclaim. */ |
| 195 | if (!igrab(inode)) | ||
| 196 | goto out_unlock; | ||
| 197 | |||
| 198 | if (is_bad_inode(inode)) { | ||
| 196 | IRELE(ip); | 199 | IRELE(ip); |
| 197 | return ENOENT; | 200 | goto out_unlock; |
| 198 | } | 201 | } |
| 199 | 202 | ||
| 200 | return 0; | 203 | /* inode is valid */ |
| 204 | error = 0; | ||
| 205 | out_unlock: | ||
| 206 | read_unlock(&pag->pag_ici_lock); | ||
| 207 | return error; | ||
| 201 | } | 208 | } |
| 202 | 209 | ||
| 203 | STATIC int | 210 | STATIC int |
| @@ -282,7 +289,7 @@ xfs_sync_data( | |||
| 282 | ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0); | 289 | ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0); |
| 283 | 290 | ||
| 284 | error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, | 291 | error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, |
| 285 | XFS_ICI_NO_TAG); | 292 | XFS_ICI_NO_TAG, 0); |
| 286 | if (error) | 293 | if (error) |
| 287 | return XFS_ERROR(error); | 294 | return XFS_ERROR(error); |
| 288 | 295 | ||
| @@ -304,7 +311,7 @@ xfs_sync_attr( | |||
| 304 | ASSERT((flags & ~SYNC_WAIT) == 0); | 311 | ASSERT((flags & ~SYNC_WAIT) == 0); |
| 305 | 312 | ||
| 306 | return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, | 313 | return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, |
| 307 | XFS_ICI_NO_TAG); | 314 | XFS_ICI_NO_TAG, 0); |
| 308 | } | 315 | } |
| 309 | 316 | ||
| 310 | STATIC int | 317 | STATIC int |
| @@ -664,60 +671,6 @@ xfs_syncd_stop( | |||
| 664 | kthread_stop(mp->m_sync_task); | 671 | kthread_stop(mp->m_sync_task); |
| 665 | } | 672 | } |
| 666 | 673 | ||
| 667 | STATIC int | ||
| 668 | xfs_reclaim_inode( | ||
| 669 | xfs_inode_t *ip, | ||
| 670 | int sync_mode) | ||
| 671 | { | ||
| 672 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); | ||
| 673 | |||
| 674 | /* The hash lock here protects a thread in xfs_iget_core from | ||
| 675 | * racing with us on linking the inode back with a vnode. | ||
| 676 | * Once we have the XFS_IRECLAIM flag set it will not touch | ||
| 677 | * us. | ||
| 678 | */ | ||
| 679 | write_lock(&pag->pag_ici_lock); | ||
| 680 | spin_lock(&ip->i_flags_lock); | ||
| 681 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || | ||
| 682 | !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) { | ||
| 683 | spin_unlock(&ip->i_flags_lock); | ||
| 684 | write_unlock(&pag->pag_ici_lock); | ||
| 685 | return -EAGAIN; | ||
| 686 | } | ||
| 687 | __xfs_iflags_set(ip, XFS_IRECLAIM); | ||
| 688 | spin_unlock(&ip->i_flags_lock); | ||
| 689 | write_unlock(&pag->pag_ici_lock); | ||
| 690 | xfs_put_perag(ip->i_mount, pag); | ||
| 691 | |||
| 692 | /* | ||
| 693 | * If the inode is still dirty, then flush it out. If the inode | ||
| 694 | * is not in the AIL, then it will be OK to flush it delwri as | ||
| 695 | * long as xfs_iflush() does not keep any references to the inode. | ||
| 696 | * We leave that decision up to xfs_iflush() since it has the | ||
| 697 | * knowledge of whether it's OK to simply do a delwri flush of | ||
| 698 | * the inode or whether we need to wait until the inode is | ||
| 699 | * pulled from the AIL. | ||
| 700 | * We get the flush lock regardless, though, just to make sure | ||
| 701 | * we don't free it while it is being flushed. | ||
| 702 | */ | ||
| 703 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 704 | xfs_iflock(ip); | ||
| 705 | |||
| 706 | /* | ||
| 707 | * In the case of a forced shutdown we rely on xfs_iflush() to | ||
| 708 | * wait for the inode to be unpinned before returning an error. | ||
| 709 | */ | ||
| 710 | if (!is_bad_inode(VFS_I(ip)) && xfs_iflush(ip, sync_mode) == 0) { | ||
| 711 | /* synchronize with xfs_iflush_done */ | ||
| 712 | xfs_iflock(ip); | ||
| 713 | xfs_ifunlock(ip); | ||
| 714 | } | ||
| 715 | |||
| 716 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 717 | xfs_ireclaim(ip); | ||
| 718 | return 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | void | 674 | void |
| 722 | __xfs_inode_set_reclaim_tag( | 675 | __xfs_inode_set_reclaim_tag( |
| 723 | struct xfs_perag *pag, | 676 | struct xfs_perag *pag, |
| @@ -760,19 +713,55 @@ __xfs_inode_clear_reclaim_tag( | |||
| 760 | } | 713 | } |
| 761 | 714 | ||
| 762 | STATIC int | 715 | STATIC int |
| 763 | xfs_reclaim_inode_now( | 716 | xfs_reclaim_inode( |
| 764 | struct xfs_inode *ip, | 717 | struct xfs_inode *ip, |
| 765 | struct xfs_perag *pag, | 718 | struct xfs_perag *pag, |
| 766 | int flags) | 719 | int sync_mode) |
| 767 | { | 720 | { |
| 768 | /* ignore if already under reclaim */ | 721 | /* |
| 769 | if (xfs_iflags_test(ip, XFS_IRECLAIM)) { | 722 | * The radix tree lock here protects a thread in xfs_iget from racing |
| 770 | read_unlock(&pag->pag_ici_lock); | 723 | * with us starting reclaim on the inode. Once we have the |
| 724 | * XFS_IRECLAIM flag set it will not touch us. | ||
| 725 | */ | ||
| 726 | spin_lock(&ip->i_flags_lock); | ||
| 727 | ASSERT_ALWAYS(__xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ||
| 728 | if (__xfs_iflags_test(ip, XFS_IRECLAIM)) { | ||
| 729 | /* ignore as it is already under reclaim */ | ||
| 730 | spin_unlock(&ip->i_flags_lock); | ||
| 731 | write_unlock(&pag->pag_ici_lock); | ||
| 771 | return 0; | 732 | return 0; |
| 772 | } | 733 | } |
| 773 | read_unlock(&pag->pag_ici_lock); | 734 | __xfs_iflags_set(ip, XFS_IRECLAIM); |
| 735 | spin_unlock(&ip->i_flags_lock); | ||
| 736 | write_unlock(&pag->pag_ici_lock); | ||
| 774 | 737 | ||
| 775 | return xfs_reclaim_inode(ip, flags); | 738 | /* |
| 739 | * If the inode is still dirty, then flush it out. If the inode | ||
| 740 | * is not in the AIL, then it will be OK to flush it delwri as | ||
| 741 | * long as xfs_iflush() does not keep any references to the inode. | ||
| 742 | * We leave that decision up to xfs_iflush() since it has the | ||
| 743 | * knowledge of whether it's OK to simply do a delwri flush of | ||
| 744 | * the inode or whether we need to wait until the inode is | ||
| 745 | * pulled from the AIL. | ||
| 746 | * We get the flush lock regardless, though, just to make sure | ||
| 747 | * we don't free it while it is being flushed. | ||
| 748 | */ | ||
| 749 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 750 | xfs_iflock(ip); | ||
| 751 | |||
| 752 | /* | ||
| 753 | * In the case of a forced shutdown we rely on xfs_iflush() to | ||
| 754 | * wait for the inode to be unpinned before returning an error. | ||
| 755 | */ | ||
| 756 | if (!is_bad_inode(VFS_I(ip)) && xfs_iflush(ip, sync_mode) == 0) { | ||
| 757 | /* synchronize with xfs_iflush_done */ | ||
| 758 | xfs_iflock(ip); | ||
| 759 | xfs_ifunlock(ip); | ||
| 760 | } | ||
| 761 | |||
| 762 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 763 | xfs_ireclaim(ip); | ||
| 764 | return 0; | ||
| 776 | } | 765 | } |
| 777 | 766 | ||
| 778 | int | 767 | int |
| @@ -780,6 +769,6 @@ xfs_reclaim_inodes( | |||
| 780 | xfs_mount_t *mp, | 769 | xfs_mount_t *mp, |
| 781 | int mode) | 770 | int mode) |
| 782 | { | 771 | { |
| 783 | return xfs_inode_ag_iterator(mp, xfs_reclaim_inode_now, mode, | 772 | return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode, |
| 784 | XFS_ICI_RECLAIM_TAG); | 773 | XFS_ICI_RECLAIM_TAG, 1); |
| 785 | } | 774 | } |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index a500b4d91835..ea932b43335d 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
| @@ -54,6 +54,6 @@ void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, | |||
| 54 | int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag); | 54 | int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag); |
| 55 | int xfs_inode_ag_iterator(struct xfs_mount *mp, | 55 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
| 56 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), | 56 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), |
| 57 | int flags, int tag); | 57 | int flags, int tag, int write_lock); |
| 58 | 58 | ||
| 59 | #endif | 59 | #endif |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 71af76fe8a23..873e07e29074 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
| @@ -891,7 +891,7 @@ xfs_qm_dqrele_all_inodes( | |||
| 891 | uint flags) | 891 | uint flags) |
| 892 | { | 892 | { |
| 893 | ASSERT(mp->m_quotainfo); | 893 | ASSERT(mp->m_quotainfo); |
| 894 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG); | 894 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0); |
| 895 | } | 895 | } |
| 896 | 896 | ||
| 897 | /*------------------------------------------------------------------------*/ | 897 | /*------------------------------------------------------------------------*/ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index d1483a4f71b8..84ca1cf16a1e 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
| @@ -114,10 +114,82 @@ xfs_swapext( | |||
| 114 | return error; | 114 | return error; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | /* | ||
| 118 | * We need to check that the format of the data fork in the temporary inode is | ||
| 119 | * valid for the target inode before doing the swap. This is not a problem with | ||
| 120 | * attr1 because of the fixed fork offset, but attr2 has a dynamically sized | ||
| 121 | * data fork depending on the space the attribute fork is taking so we can get | ||
| 122 | * invalid formats on the target inode. | ||
| 123 | * | ||
| 124 | * E.g. target has space for 7 extents in extent format, temp inode only has | ||
| 125 | * space for 6. If we defragment down to 7 extents, then the tmp format is a | ||
| 126 | * btree, but when swapped it needs to be in extent format. Hence we can't just | ||
| 127 | * blindly swap data forks on attr2 filesystems. | ||
| 128 | * | ||
| 129 | * Note that we check the swap in both directions so that we don't end up with | ||
| 130 | * a corrupt temporary inode, either. | ||
| 131 | * | ||
| 132 | * Note that fixing the way xfs_fsr sets up the attribute fork in the source | ||
| 133 | * inode will prevent this situation from occurring, so all we do here is | ||
| 134 | * reject and log the attempt. basically we are putting the responsibility on | ||
| 135 | * userspace to get this right. | ||
| 136 | */ | ||
| 137 | static int | ||
| 138 | xfs_swap_extents_check_format( | ||
| 139 | xfs_inode_t *ip, /* target inode */ | ||
| 140 | xfs_inode_t *tip) /* tmp inode */ | ||
| 141 | { | ||
| 142 | |||
| 143 | /* Should never get a local format */ | ||
| 144 | if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || | ||
| 145 | tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) | ||
| 146 | return EINVAL; | ||
| 147 | |||
| 148 | /* | ||
| 149 | * if the target inode has less extents that then temporary inode then | ||
| 150 | * why did userspace call us? | ||
| 151 | */ | ||
| 152 | if (ip->i_d.di_nextents < tip->i_d.di_nextents) | ||
| 153 | return EINVAL; | ||
| 154 | |||
| 155 | /* | ||
| 156 | * if the target inode is in extent form and the temp inode is in btree | ||
| 157 | * form then we will end up with the target inode in the wrong format | ||
| 158 | * as we already know there are less extents in the temp inode. | ||
| 159 | */ | ||
| 160 | if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && | ||
| 161 | tip->i_d.di_format == XFS_DINODE_FMT_BTREE) | ||
| 162 | return EINVAL; | ||
| 163 | |||
| 164 | /* Check temp in extent form to max in target */ | ||
| 165 | if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && | ||
| 166 | XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) > ip->i_df.if_ext_max) | ||
| 167 | return EINVAL; | ||
| 168 | |||
| 169 | /* Check target in extent form to max in temp */ | ||
| 170 | if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && | ||
| 171 | XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max) | ||
| 172 | return EINVAL; | ||
| 173 | |||
| 174 | /* Check root block of temp in btree form to max in target */ | ||
| 175 | if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE && | ||
| 176 | XFS_IFORK_BOFF(ip) && | ||
| 177 | tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) | ||
| 178 | return EINVAL; | ||
| 179 | |||
| 180 | /* Check root block of target in btree form to max in temp */ | ||
| 181 | if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && | ||
| 182 | XFS_IFORK_BOFF(tip) && | ||
| 183 | ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) | ||
| 184 | return EINVAL; | ||
| 185 | |||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | |||
| 117 | int | 189 | int |
| 118 | xfs_swap_extents( | 190 | xfs_swap_extents( |
| 119 | xfs_inode_t *ip, | 191 | xfs_inode_t *ip, /* target inode */ |
| 120 | xfs_inode_t *tip, | 192 | xfs_inode_t *tip, /* tmp inode */ |
| 121 | xfs_swapext_t *sxp) | 193 | xfs_swapext_t *sxp) |
| 122 | { | 194 | { |
| 123 | xfs_mount_t *mp; | 195 | xfs_mount_t *mp; |
| @@ -161,13 +233,6 @@ xfs_swap_extents( | |||
| 161 | goto out_unlock; | 233 | goto out_unlock; |
| 162 | } | 234 | } |
| 163 | 235 | ||
| 164 | /* Should never get a local format */ | ||
| 165 | if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || | ||
| 166 | tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 167 | error = XFS_ERROR(EINVAL); | ||
| 168 | goto out_unlock; | ||
| 169 | } | ||
| 170 | |||
| 171 | if (VN_CACHED(VFS_I(tip)) != 0) { | 236 | if (VN_CACHED(VFS_I(tip)) != 0) { |
| 172 | error = xfs_flushinval_pages(tip, 0, -1, | 237 | error = xfs_flushinval_pages(tip, 0, -1, |
| 173 | FI_REMAPF_LOCKED); | 238 | FI_REMAPF_LOCKED); |
| @@ -189,13 +254,12 @@ xfs_swap_extents( | |||
| 189 | goto out_unlock; | 254 | goto out_unlock; |
| 190 | } | 255 | } |
| 191 | 256 | ||
| 192 | /* | 257 | /* check inode formats now that data is flushed */ |
| 193 | * If the target has extended attributes, the tmp file | 258 | error = xfs_swap_extents_check_format(ip, tip); |
| 194 | * must also in order to ensure the correct data fork | 259 | if (error) { |
| 195 | * format. | 260 | xfs_fs_cmn_err(CE_NOTE, mp, |
| 196 | */ | 261 | "%s: inode 0x%llx format is incompatible for exchanging.", |
| 197 | if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) { | 262 | __FILE__, ip->i_ino); |
| 198 | error = XFS_ERROR(EINVAL); | ||
| 199 | goto out_unlock; | 263 | goto out_unlock; |
| 200 | } | 264 | } |
| 201 | 265 | ||
| @@ -276,6 +340,16 @@ xfs_swap_extents( | |||
| 276 | *tifp = *tempifp; /* struct copy */ | 340 | *tifp = *tempifp; /* struct copy */ |
| 277 | 341 | ||
| 278 | /* | 342 | /* |
| 343 | * Fix the in-memory data fork values that are dependent on the fork | ||
| 344 | * offset in the inode. We can't assume they remain the same as attr2 | ||
| 345 | * has dynamic fork offsets. | ||
| 346 | */ | ||
| 347 | ifp->if_ext_max = XFS_IFORK_SIZE(ip, XFS_DATA_FORK) / | ||
| 348 | (uint)sizeof(xfs_bmbt_rec_t); | ||
| 349 | tifp->if_ext_max = XFS_IFORK_SIZE(tip, XFS_DATA_FORK) / | ||
| 350 | (uint)sizeof(xfs_bmbt_rec_t); | ||
| 351 | |||
| 352 | /* | ||
| 279 | * Fix the on-disk inode values | 353 | * Fix the on-disk inode values |
| 280 | */ | 354 | */ |
| 281 | tmp = (__uint64_t)ip->i_d.di_nblocks; | 355 | tmp = (__uint64_t)ip->i_d.di_nblocks; |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index fa402a6bbbcf..155e798f30a1 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -73,7 +73,6 @@ xfs_inode_alloc( | |||
| 73 | ASSERT(atomic_read(&ip->i_pincount) == 0); | 73 | ASSERT(atomic_read(&ip->i_pincount) == 0); |
| 74 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | 74 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); |
| 75 | ASSERT(completion_done(&ip->i_flush)); | 75 | ASSERT(completion_done(&ip->i_flush)); |
| 76 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | ||
| 77 | 76 | ||
| 78 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | 77 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); |
| 79 | 78 | ||
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 391d36b0e68c..ef77fd88c8e3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -2842,13 +2842,9 @@ xfs_iflush( | |||
| 2842 | 2842 | ||
| 2843 | /* | 2843 | /* |
| 2844 | * If the inode isn't dirty, then just release the inode flush lock and | 2844 | * If the inode isn't dirty, then just release the inode flush lock and |
| 2845 | * do nothing. Treat stale inodes the same; we cannot rely on the | 2845 | * do nothing. |
| 2846 | * backing buffer remaining stale in cache for the remaining life of | ||
| 2847 | * the stale inode and so xfs_itobp() below may give us a buffer that | ||
| 2848 | * no longer contains inodes below. Doing this stale check here also | ||
| 2849 | * avoids forcing the log on pinned, stale inodes. | ||
| 2850 | */ | 2846 | */ |
| 2851 | if (xfs_inode_clean(ip) || xfs_iflags_test(ip, XFS_ISTALE)) { | 2847 | if (xfs_inode_clean(ip)) { |
| 2852 | xfs_ifunlock(ip); | 2848 | xfs_ifunlock(ip); |
| 2853 | return 0; | 2849 | return 0; |
| 2854 | } | 2850 | } |
| @@ -2872,6 +2868,19 @@ xfs_iflush( | |||
| 2872 | xfs_iunpin_wait(ip); | 2868 | xfs_iunpin_wait(ip); |
| 2873 | 2869 | ||
| 2874 | /* | 2870 | /* |
| 2871 | * For stale inodes we cannot rely on the backing buffer remaining | ||
| 2872 | * stale in cache for the remaining life of the stale inode and so | ||
| 2873 | * xfs_itobp() below may give us a buffer that no longer contains | ||
| 2874 | * inodes below. We have to check this after ensuring the inode is | ||
| 2875 | * unpinned so that it is safe to reclaim the stale inode after the | ||
| 2876 | * flush call. | ||
| 2877 | */ | ||
| 2878 | if (xfs_iflags_test(ip, XFS_ISTALE)) { | ||
| 2879 | xfs_ifunlock(ip); | ||
| 2880 | return 0; | ||
| 2881 | } | ||
| 2882 | |||
| 2883 | /* | ||
| 2875 | * This may have been unpinned because the filesystem is shutting | 2884 | * This may have been unpinned because the filesystem is shutting |
| 2876 | * down forcibly. If that's the case we must not write this inode | 2885 | * down forcibly. If that's the case we must not write this inode |
| 2877 | * to disk, because the log record didn't make it to disk! | 2886 | * to disk, because the log record didn't make it to disk! |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 9e15a1185362..6be05f756d59 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
| @@ -1517,6 +1517,8 @@ xfs_rtfree_range( | |||
| 1517 | */ | 1517 | */ |
| 1518 | error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, | 1518 | error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, |
| 1519 | &postblock); | 1519 | &postblock); |
| 1520 | if (error) | ||
| 1521 | return error; | ||
| 1520 | /* | 1522 | /* |
| 1521 | * If there are blocks not being freed at the front of the | 1523 | * If there are blocks not being freed at the front of the |
| 1522 | * old extent, add summary data for them to be allocated. | 1524 | * old extent, add summary data for them to be allocated. |
