aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c97
1 files changed, 40 insertions, 57 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 051c7fe551dd..7772f02ba28e 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -25,6 +25,8 @@
25#include "btrfs_inode.h" 25#include "btrfs_inode.h"
26#include "extent_io.h" 26#include "extent_io.h"
27 27
28static struct kmem_cache *btrfs_ordered_extent_cache;
29
28static u64 entry_end(struct btrfs_ordered_extent *entry) 30static u64 entry_end(struct btrfs_ordered_extent *entry)
29{ 31{
30 if (entry->file_offset + entry->len < entry->file_offset) 32 if (entry->file_offset + entry->len < entry->file_offset)
@@ -187,7 +189,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
187 struct btrfs_ordered_extent *entry; 189 struct btrfs_ordered_extent *entry;
188 190
189 tree = &BTRFS_I(inode)->ordered_tree; 191 tree = &BTRFS_I(inode)->ordered_tree;
190 entry = kzalloc(sizeof(*entry), GFP_NOFS); 192 entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS);
191 if (!entry) 193 if (!entry)
192 return -ENOMEM; 194 return -ENOMEM;
193 195
@@ -421,7 +423,7 @@ void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
421 list_del(&sum->list); 423 list_del(&sum->list);
422 kfree(sum); 424 kfree(sum);
423 } 425 }
424 kfree(entry); 426 kmem_cache_free(btrfs_ordered_extent_cache, entry);
425 } 427 }
426} 428}
427 429
@@ -466,8 +468,7 @@ void btrfs_remove_ordered_extent(struct inode *inode,
466 * wait for all the ordered extents in a root. This is done when balancing 468 * wait for all the ordered extents in a root. This is done when balancing
467 * space between drives. 469 * space between drives.
468 */ 470 */
469void btrfs_wait_ordered_extents(struct btrfs_root *root, 471void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
470 int nocow_only, int delay_iput)
471{ 472{
472 struct list_head splice; 473 struct list_head splice;
473 struct list_head *cur; 474 struct list_head *cur;
@@ -482,15 +483,6 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root,
482 cur = splice.next; 483 cur = splice.next;
483 ordered = list_entry(cur, struct btrfs_ordered_extent, 484 ordered = list_entry(cur, struct btrfs_ordered_extent,
484 root_extent_list); 485 root_extent_list);
485 if (nocow_only &&
486 !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags) &&
487 !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) {
488 list_move(&ordered->root_extent_list,
489 &root->fs_info->ordered_extents);
490 cond_resched_lock(&root->fs_info->ordered_extent_lock);
491 continue;
492 }
493
494 list_del_init(&ordered->root_extent_list); 486 list_del_init(&ordered->root_extent_list);
495 atomic_inc(&ordered->refs); 487 atomic_inc(&ordered->refs);
496 488
@@ -775,7 +767,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
775 struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; 767 struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
776 u64 disk_i_size; 768 u64 disk_i_size;
777 u64 new_i_size; 769 u64 new_i_size;
778 u64 i_size_test;
779 u64 i_size = i_size_read(inode); 770 u64 i_size = i_size_read(inode);
780 struct rb_node *node; 771 struct rb_node *node;
781 struct rb_node *prev = NULL; 772 struct rb_node *prev = NULL;
@@ -835,55 +826,30 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
835 break; 826 break;
836 if (test->file_offset >= i_size) 827 if (test->file_offset >= i_size)
837 break; 828 break;
838 if (test->file_offset >= disk_i_size) 829 if (test->file_offset >= disk_i_size) {
830 /*
831 * we don't update disk_i_size now, so record this
832 * undealt i_size. Or we will not know the real
833 * i_size.
834 */
835 if (test->outstanding_isize < offset)
836 test->outstanding_isize = offset;
837 if (ordered &&
838 ordered->outstanding_isize >
839 test->outstanding_isize)
840 test->outstanding_isize =
841 ordered->outstanding_isize;
839 goto out; 842 goto out;
840 }
841 new_i_size = min_t(u64, offset, i_size);
842
843 /*
844 * at this point, we know we can safely update i_size to at least
845 * the offset from this ordered extent. But, we need to
846 * walk forward and see if ios from higher up in the file have
847 * finished.
848 */
849 if (ordered) {
850 node = rb_next(&ordered->rb_node);
851 } else {
852 if (prev)
853 node = rb_next(prev);
854 else
855 node = rb_first(&tree->tree);
856 }
857
858 /*
859 * We are looking for an area between our current extent and the next
860 * ordered extent to update the i_size to. There are 3 cases here
861 *
862 * 1) We don't actually have anything and we can update to i_size.
863 * 2) We have stuff but they already did their i_size update so again we
864 * can just update to i_size.
865 * 3) We have an outstanding ordered extent so the most we can update
866 * our disk_i_size to is the start of the next offset.
867 */
868 i_size_test = i_size;
869 for (; node; node = rb_next(node)) {
870 test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
871
872 if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
873 continue;
874 if (test->file_offset > offset) {
875 i_size_test = test->file_offset;
876 break;
877 } 843 }
878 } 844 }
845 new_i_size = min_t(u64, offset, i_size);
879 846
880 /* 847 /*
881 * i_size_test is the end of a region after this ordered 848 * Some ordered extents may completed before the current one, and
882 * extent where there are no ordered extents, we can safely set 849 * we hold the real i_size in ->outstanding_isize.
883 * disk_i_size to this.
884 */ 850 */
885 if (i_size_test > offset) 851 if (ordered && ordered->outstanding_isize > new_i_size)
886 new_i_size = min_t(u64, i_size_test, i_size); 852 new_i_size = min_t(u64, ordered->outstanding_isize, i_size);
887 BTRFS_I(inode)->disk_i_size = new_i_size; 853 BTRFS_I(inode)->disk_i_size = new_i_size;
888 ret = 0; 854 ret = 0;
889out: 855out:
@@ -984,3 +950,20 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
984 } 950 }
985 spin_unlock(&root->fs_info->ordered_extent_lock); 951 spin_unlock(&root->fs_info->ordered_extent_lock);
986} 952}
953
954int __init ordered_data_init(void)
955{
956 btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent",
957 sizeof(struct btrfs_ordered_extent), 0,
958 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
959 NULL);
960 if (!btrfs_ordered_extent_cache)
961 return -ENOMEM;
962 return 0;
963}
964
965void ordered_data_exit(void)
966{
967 if (btrfs_ordered_extent_cache)
968 kmem_cache_destroy(btrfs_ordered_extent_cache);
969}