diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-01-29 15:55:23 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:00 -0400 |
commit | 291d673e6a22d9c6834e939f66c7cfef90669021 (patch) | |
tree | 841e9be40bb5fbf7c978c789ee67183cef596686 /fs/btrfs/inode.c | |
parent | 9c58309d6cf22471dacbcb6de54d00cef9ca20d4 (diff) |
Btrfs: Do delalloc accounting via hooks in the extent_state code
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 60 |
1 files changed, 24 insertions, 36 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 413b1012de53..5a38443a24ee 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -80,8 +80,6 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, | |||
80 | u64 thresh; | 80 | u64 thresh; |
81 | int ret = 0; | 81 | int ret = 0; |
82 | 82 | ||
83 | return 0; | ||
84 | |||
85 | if (for_del) | 83 | if (for_del) |
86 | thresh = total * 90; | 84 | thresh = total * 90; |
87 | else | 85 | else |
@@ -249,7 +247,6 @@ not_found: | |||
249 | static int run_delalloc_range(struct inode *inode, u64 start, u64 end) | 247 | static int run_delalloc_range(struct inode *inode, u64 start, u64 end) |
250 | { | 248 | { |
251 | struct btrfs_root *root = BTRFS_I(inode)->root; | 249 | struct btrfs_root *root = BTRFS_I(inode)->root; |
252 | u64 num_bytes; | ||
253 | int ret; | 250 | int ret; |
254 | mutex_lock(&root->fs_info->fs_mutex); | 251 | mutex_lock(&root->fs_info->fs_mutex); |
255 | if (btrfs_test_opt(root, NODATACOW) || | 252 | if (btrfs_test_opt(root, NODATACOW) || |
@@ -258,20 +255,34 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end) | |||
258 | else | 255 | else |
259 | ret = cow_file_range(inode, start, end); | 256 | ret = cow_file_range(inode, start, end); |
260 | 257 | ||
261 | spin_lock(&root->fs_info->delalloc_lock); | ||
262 | num_bytes = end + 1 - start; | ||
263 | if (root->fs_info->delalloc_bytes < num_bytes) { | ||
264 | printk("delalloc accounting error total %llu sub %llu\n", | ||
265 | root->fs_info->delalloc_bytes, num_bytes); | ||
266 | } else { | ||
267 | root->fs_info->delalloc_bytes -= num_bytes; | ||
268 | } | ||
269 | spin_unlock(&root->fs_info->delalloc_lock); | ||
270 | |||
271 | mutex_unlock(&root->fs_info->fs_mutex); | 258 | mutex_unlock(&root->fs_info->fs_mutex); |
272 | return ret; | 259 | return ret; |
273 | } | 260 | } |
274 | 261 | ||
262 | int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | ||
263 | unsigned long bits) | ||
264 | { | ||
265 | if ((bits & EXTENT_DELALLOC)) { | ||
266 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
267 | spin_lock(&root->fs_info->delalloc_lock); | ||
268 | root->fs_info->delalloc_bytes += end - start + 1; | ||
269 | spin_unlock(&root->fs_info->delalloc_lock); | ||
270 | } | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, | ||
275 | unsigned long bits) | ||
276 | { | ||
277 | if ((bits & EXTENT_DELALLOC)) { | ||
278 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
279 | spin_lock(&root->fs_info->delalloc_lock); | ||
280 | root->fs_info->delalloc_bytes -= end - start + 1; | ||
281 | spin_unlock(&root->fs_info->delalloc_lock); | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
285 | |||
275 | int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end) | 286 | int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end) |
276 | { | 287 | { |
277 | struct inode *inode = page->mapping->host; | 288 | struct inode *inode = page->mapping->host; |
@@ -908,28 +919,17 @@ static int btrfs_cow_one_page(struct inode *inode, struct page *page, | |||
908 | { | 919 | { |
909 | char *kaddr; | 920 | char *kaddr; |
910 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 921 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
911 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
912 | u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT; | 922 | u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT; |
913 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; | 923 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; |
914 | u64 existing_delalloc; | ||
915 | u64 delalloc_start; | ||
916 | int ret = 0; | 924 | int ret = 0; |
917 | 925 | ||
918 | WARN_ON(!PageLocked(page)); | 926 | WARN_ON(!PageLocked(page)); |
919 | set_page_extent_mapped(page); | 927 | set_page_extent_mapped(page); |
920 | 928 | ||
921 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | 929 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); |
922 | delalloc_start = page_start; | ||
923 | existing_delalloc = count_range_bits(&BTRFS_I(inode)->io_tree, | ||
924 | &delalloc_start, page_end, | ||
925 | PAGE_CACHE_SIZE, EXTENT_DELALLOC); | ||
926 | set_extent_delalloc(&BTRFS_I(inode)->io_tree, page_start, | 930 | set_extent_delalloc(&BTRFS_I(inode)->io_tree, page_start, |
927 | page_end, GFP_NOFS); | 931 | page_end, GFP_NOFS); |
928 | 932 | ||
929 | spin_lock(&root->fs_info->delalloc_lock); | ||
930 | root->fs_info->delalloc_bytes += PAGE_CACHE_SIZE - existing_delalloc; | ||
931 | spin_unlock(&root->fs_info->delalloc_lock); | ||
932 | |||
933 | if (zero_start != PAGE_CACHE_SIZE) { | 933 | if (zero_start != PAGE_CACHE_SIZE) { |
934 | kaddr = kmap(page); | 934 | kaddr = kmap(page); |
935 | memset(kaddr + zero_start, 0, PAGE_CACHE_SIZE - zero_start); | 935 | memset(kaddr + zero_start, 0, PAGE_CACHE_SIZE - zero_start); |
@@ -2456,8 +2456,6 @@ int btrfs_defrag_file(struct file *file) { | |||
2456 | unsigned long ra_index = 0; | 2456 | unsigned long ra_index = 0; |
2457 | u64 page_start; | 2457 | u64 page_start; |
2458 | u64 page_end; | 2458 | u64 page_end; |
2459 | u64 delalloc_start; | ||
2460 | u64 existing_delalloc; | ||
2461 | unsigned long i; | 2459 | unsigned long i; |
2462 | int ret; | 2460 | int ret; |
2463 | 2461 | ||
@@ -2491,19 +2489,9 @@ int btrfs_defrag_file(struct file *file) { | |||
2491 | page_end = page_start + PAGE_CACHE_SIZE - 1; | 2489 | page_end = page_start + PAGE_CACHE_SIZE - 1; |
2492 | 2490 | ||
2493 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | 2491 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); |
2494 | delalloc_start = page_start; | ||
2495 | existing_delalloc = | ||
2496 | count_range_bits(&BTRFS_I(inode)->io_tree, | ||
2497 | &delalloc_start, page_end, | ||
2498 | PAGE_CACHE_SIZE, EXTENT_DELALLOC); | ||
2499 | set_extent_delalloc(io_tree, page_start, | 2492 | set_extent_delalloc(io_tree, page_start, |
2500 | page_end, GFP_NOFS); | 2493 | page_end, GFP_NOFS); |
2501 | 2494 | ||
2502 | spin_lock(&root->fs_info->delalloc_lock); | ||
2503 | root->fs_info->delalloc_bytes += PAGE_CACHE_SIZE - | ||
2504 | existing_delalloc; | ||
2505 | spin_unlock(&root->fs_info->delalloc_lock); | ||
2506 | |||
2507 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 2495 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
2508 | set_page_dirty(page); | 2496 | set_page_dirty(page); |
2509 | unlock_page(page); | 2497 | unlock_page(page); |