diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 18:45:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 18:45:16 -0500 |
commit | 3aeb58ab6216d864821e8dafb248e8d77403f3e9 (patch) | |
tree | 88afc8b7594ed4648c4a098cdd60678b66f28b31 /fs | |
parent | 4fbf888accb39af423f271111d44e8186f053723 (diff) | |
parent | 91aef86f3b8ab0685d930a5468254384513d1c97 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs update frm Chris Mason:
"This is our usual merge window set of bug fixes, performance
improvements and cleanups. Miao Xie has some really nice
optimizations for writeback.
Josef also expanded our sanity checks quite a bit; these make up a big
chunk of the new lines"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (98 commits)
Btrfs: rename btrfs_start_all_delalloc_inodes
Btrfs: don't wait for the completion of all the ordered extents
Btrfs: don't wait for all the async delalloc when shrinking delalloc
Btrfs: fix the confusion between delalloc bytes and metadata bytes
Btrfs: pick up the code for the item number calculation in flush_space()
Btrfs: wait for the ordered extent only when we want
Btrfs: remove unnecessary initialization and memory barrior in shrink_delalloc()
Btrfs: avoid unnecessary scrub workers allocation
Btrfs: check file extent type before anything else
btrfs: Remove useless variable in write_ctree_super()
btrfs: Fix checkpatch.pl warning of spacing issues
btrfs: Replace kmalloc with kmalloc_array
btrfs: Enclose macros with complex values within parenthesis
btrfs: Use WARN_ON()'s return value in place of WARN_ON(1)
btrfs: Remove redundant local zero structure
btrfs: Pack struct btrfs_device
btrfs: Replace multiple atomic_inc() with atomic_add()
btrfs: Add helper function for free_root_pointers()
Btrfs: fix a crash when running balance and defrag concurrently
Btrfs: do not run snapshot-aware defragment on error
...
Diffstat (limited to 'fs')
48 files changed, 2600 insertions, 973 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index a91a6a355cc5..1a44e42d602a 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -14,4 +14,6 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ | |||
14 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o | 14 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o |
15 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o | 15 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o |
16 | 16 | ||
17 | btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o | 17 | btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \ |
18 | tests/extent-buffer-tests.o tests/btrfs-tests.o \ | ||
19 | tests/extent-io-tests.o tests/inode-tests.o | ||
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index e15d2b0d8d3b..0890c83643e9 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -229,7 +229,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, | |||
229 | if (ret > 0) { | 229 | if (ret > 0) { |
230 | /* we need an acl */ | 230 | /* we need an acl */ |
231 | ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); | 231 | ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); |
232 | } else { | 232 | } else if (ret < 0) { |
233 | cache_no_acl(inode); | 233 | cache_no_acl(inode); |
234 | } | 234 | } |
235 | } else { | 235 | } else { |
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 08cc08f037a6..8aec751fa464 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
@@ -262,7 +262,7 @@ static struct btrfs_work *get_next_work(struct btrfs_worker_thread *worker, | |||
262 | struct btrfs_work *work = NULL; | 262 | struct btrfs_work *work = NULL; |
263 | struct list_head *cur = NULL; | 263 | struct list_head *cur = NULL; |
264 | 264 | ||
265 | if(!list_empty(prio_head)) | 265 | if (!list_empty(prio_head)) |
266 | cur = prio_head->next; | 266 | cur = prio_head->next; |
267 | 267 | ||
268 | smp_mb(); | 268 | smp_mb(); |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 0552a599b28f..3775947429b2 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -185,6 +185,9 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id, | |||
185 | { | 185 | { |
186 | struct __prelim_ref *ref; | 186 | struct __prelim_ref *ref; |
187 | 187 | ||
188 | if (root_id == BTRFS_DATA_RELOC_TREE_OBJECTID) | ||
189 | return 0; | ||
190 | |||
188 | ref = kmem_cache_alloc(btrfs_prelim_ref_cache, gfp_mask); | 191 | ref = kmem_cache_alloc(btrfs_prelim_ref_cache, gfp_mask); |
189 | if (!ref) | 192 | if (!ref) |
190 | return -ENOMEM; | 193 | return -ENOMEM; |
@@ -323,8 +326,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | |||
323 | 326 | ||
324 | eb = path->nodes[level]; | 327 | eb = path->nodes[level]; |
325 | while (!eb) { | 328 | while (!eb) { |
326 | if (!level) { | 329 | if (WARN_ON(!level)) { |
327 | WARN_ON(1); | ||
328 | ret = 1; | 330 | ret = 1; |
329 | goto out; | 331 | goto out; |
330 | } | 332 | } |
@@ -1619,7 +1621,7 @@ static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root, | |||
1619 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | 1621 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); |
1620 | btrfs_release_path(path); | 1622 | btrfs_release_path(path); |
1621 | 1623 | ||
1622 | item = btrfs_item_nr(eb, slot); | 1624 | item = btrfs_item_nr(slot); |
1623 | iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); | 1625 | iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); |
1624 | 1626 | ||
1625 | for (cur = 0; cur < btrfs_item_size(eb, item); cur += len) { | 1627 | for (cur = 0; cur < btrfs_item_size(eb, item); cur += len) { |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 71f074e1870b..ac0b39db27d1 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #ifndef __BTRFS_I__ | 19 | #ifndef __BTRFS_I__ |
20 | #define __BTRFS_I__ | 20 | #define __BTRFS_I__ |
21 | 21 | ||
22 | #include <linux/hash.h> | ||
22 | #include "extent_map.h" | 23 | #include "extent_map.h" |
23 | #include "extent_io.h" | 24 | #include "extent_io.h" |
24 | #include "ordered-data.h" | 25 | #include "ordered-data.h" |
@@ -179,6 +180,25 @@ static inline struct btrfs_inode *BTRFS_I(struct inode *inode) | |||
179 | return container_of(inode, struct btrfs_inode, vfs_inode); | 180 | return container_of(inode, struct btrfs_inode, vfs_inode); |
180 | } | 181 | } |
181 | 182 | ||
183 | static inline unsigned long btrfs_inode_hash(u64 objectid, | ||
184 | const struct btrfs_root *root) | ||
185 | { | ||
186 | u64 h = objectid ^ (root->objectid * GOLDEN_RATIO_PRIME); | ||
187 | |||
188 | #if BITS_PER_LONG == 32 | ||
189 | h = (h >> 32) ^ (h & 0xffffffff); | ||
190 | #endif | ||
191 | |||
192 | return (unsigned long)h; | ||
193 | } | ||
194 | |||
195 | static inline void btrfs_insert_inode_hash(struct inode *inode) | ||
196 | { | ||
197 | unsigned long h = btrfs_inode_hash(inode->i_ino, BTRFS_I(inode)->root); | ||
198 | |||
199 | __insert_inode_hash(inode, h); | ||
200 | } | ||
201 | |||
182 | static inline u64 btrfs_ino(struct inode *inode) | 202 | static inline u64 btrfs_ino(struct inode *inode) |
183 | { | 203 | { |
184 | u64 ino = BTRFS_I(inode)->location.objectid; | 204 | u64 ino = BTRFS_I(inode)->location.objectid; |
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 1c47be187240..e0aab4456974 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -1038,7 +1038,7 @@ leaf_item_out_of_bounce_error: | |||
1038 | disk_item_offset, | 1038 | disk_item_offset, |
1039 | sizeof(struct btrfs_item)); | 1039 | sizeof(struct btrfs_item)); |
1040 | item_offset = btrfs_stack_item_offset(&disk_item); | 1040 | item_offset = btrfs_stack_item_offset(&disk_item); |
1041 | item_size = btrfs_stack_item_offset(&disk_item); | 1041 | item_size = btrfs_stack_item_size(&disk_item); |
1042 | disk_key = &disk_item.key; | 1042 | disk_key = &disk_item.key; |
1043 | type = btrfs_disk_key_type(disk_key); | 1043 | type = btrfs_disk_key_type(disk_key); |
1044 | 1044 | ||
@@ -1900,7 +1900,9 @@ again: | |||
1900 | dev_state, | 1900 | dev_state, |
1901 | dev_bytenr); | 1901 | dev_bytenr); |
1902 | } | 1902 | } |
1903 | if (block->logical_bytenr != bytenr) { | 1903 | if (block->logical_bytenr != bytenr && |
1904 | !(!block->is_metadata && | ||
1905 | block->logical_bytenr == 0)) | ||
1904 | printk(KERN_INFO | 1906 | printk(KERN_INFO |
1905 | "Written block @%llu (%s/%llu/%d)" | 1907 | "Written block @%llu (%s/%llu/%d)" |
1906 | " found in hash table, %c," | 1908 | " found in hash table, %c," |
@@ -1910,15 +1912,14 @@ again: | |||
1910 | block->mirror_num, | 1912 | block->mirror_num, |
1911 | btrfsic_get_block_type(state, block), | 1913 | btrfsic_get_block_type(state, block), |
1912 | block->logical_bytenr); | 1914 | block->logical_bytenr); |
1913 | block->logical_bytenr = bytenr; | 1915 | else if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) |
1914 | } else if (state->print_mask & | ||
1915 | BTRFSIC_PRINT_MASK_VERBOSE) | ||
1916 | printk(KERN_INFO | 1916 | printk(KERN_INFO |
1917 | "Written block @%llu (%s/%llu/%d)" | 1917 | "Written block @%llu (%s/%llu/%d)" |
1918 | " found in hash table, %c.\n", | 1918 | " found in hash table, %c.\n", |
1919 | bytenr, dev_state->name, dev_bytenr, | 1919 | bytenr, dev_state->name, dev_bytenr, |
1920 | block->mirror_num, | 1920 | block->mirror_num, |
1921 | btrfsic_get_block_type(state, block)); | 1921 | btrfsic_get_block_type(state, block)); |
1922 | block->logical_bytenr = bytenr; | ||
1922 | } else { | 1923 | } else { |
1923 | if (num_pages * PAGE_CACHE_SIZE < | 1924 | if (num_pages * PAGE_CACHE_SIZE < |
1924 | state->datablock_size) { | 1925 | state->datablock_size) { |
@@ -2463,10 +2464,8 @@ static int btrfsic_process_written_superblock( | |||
2463 | } | 2464 | } |
2464 | } | 2465 | } |
2465 | 2466 | ||
2466 | if (-1 == btrfsic_check_all_ref_blocks(state, superblock, 0)) { | 2467 | if (WARN_ON(-1 == btrfsic_check_all_ref_blocks(state, superblock, 0))) |
2467 | WARN_ON(1); | ||
2468 | btrfsic_dump_tree(state); | 2468 | btrfsic_dump_tree(state); |
2469 | } | ||
2470 | 2469 | ||
2471 | return 0; | 2470 | return 0; |
2472 | } | 2471 | } |
@@ -2906,7 +2905,7 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | |||
2906 | btrfsic_release_block_ctx(&block_ctx); | 2905 | btrfsic_release_block_ctx(&block_ctx); |
2907 | } | 2906 | } |
2908 | 2907 | ||
2909 | if (!match) { | 2908 | if (WARN_ON(!match)) { |
2910 | printk(KERN_INFO "btrfs: attempt to write M-block which contains logical bytenr that doesn't map to dev+physical bytenr of submit_bio," | 2909 | printk(KERN_INFO "btrfs: attempt to write M-block which contains logical bytenr that doesn't map to dev+physical bytenr of submit_bio," |
2911 | " buffer->log_bytenr=%llu, submit_bio(bdev=%s," | 2910 | " buffer->log_bytenr=%llu, submit_bio(bdev=%s," |
2912 | " phys_bytenr=%llu)!\n", | 2911 | " phys_bytenr=%llu)!\n", |
@@ -2923,7 +2922,6 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | |||
2923 | bytenr, block_ctx.dev->name, | 2922 | bytenr, block_ctx.dev->name, |
2924 | block_ctx.dev_bytenr, mirror_num); | 2923 | block_ctx.dev_bytenr, mirror_num); |
2925 | } | 2924 | } |
2926 | WARN_ON(1); | ||
2927 | } | 2925 | } |
2928 | } | 2926 | } |
2929 | 2927 | ||
diff --git a/fs/btrfs/compat.h b/fs/btrfs/compat.h deleted file mode 100644 index 7c4503ef6efd..000000000000 --- a/fs/btrfs/compat.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _COMPAT_H_ | ||
2 | #define _COMPAT_H_ | ||
3 | |||
4 | #define btrfs_drop_nlink(inode) drop_nlink(inode) | ||
5 | #define btrfs_inc_nlink(inode) inc_nlink(inode) | ||
6 | |||
7 | #endif /* _COMPAT_H_ */ | ||
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 6aad98cb343f..1499b27b4186 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/writeback.h> | 32 | #include <linux/writeback.h> |
33 | #include <linux/bit_spinlock.h> | 33 | #include <linux/bit_spinlock.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include "compat.h" | ||
36 | #include "ctree.h" | 35 | #include "ctree.h" |
37 | #include "disk-io.h" | 36 | #include "disk-io.h" |
38 | #include "transaction.h" | 37 | #include "transaction.h" |
@@ -360,7 +359,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, | |||
360 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 359 | bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; |
361 | 360 | ||
362 | bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); | 361 | bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); |
363 | if(!bio) { | 362 | if (!bio) { |
364 | kfree(cb); | 363 | kfree(cb); |
365 | return -ENOMEM; | 364 | return -ENOMEM; |
366 | } | 365 | } |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 61b5bcd57b7e..316136bd6dd7 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -274,7 +274,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
274 | else | 274 | else |
275 | btrfs_set_header_owner(cow, new_root_objectid); | 275 | btrfs_set_header_owner(cow, new_root_objectid); |
276 | 276 | ||
277 | write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(cow), | 277 | write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(), |
278 | BTRFS_FSID_SIZE); | 278 | BTRFS_FSID_SIZE); |
279 | 279 | ||
280 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 280 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
@@ -996,7 +996,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
996 | else | 996 | else |
997 | btrfs_set_header_owner(cow, root->root_key.objectid); | 997 | btrfs_set_header_owner(cow, root->root_key.objectid); |
998 | 998 | ||
999 | write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(cow), | 999 | write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(), |
1000 | BTRFS_FSID_SIZE); | 1000 | BTRFS_FSID_SIZE); |
1001 | 1001 | ||
1002 | ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); | 1002 | ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); |
@@ -1285,11 +1285,10 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1285 | free_extent_buffer(eb_root); | 1285 | free_extent_buffer(eb_root); |
1286 | blocksize = btrfs_level_size(root, old_root->level); | 1286 | blocksize = btrfs_level_size(root, old_root->level); |
1287 | old = read_tree_block(root, logical, blocksize, 0); | 1287 | old = read_tree_block(root, logical, blocksize, 0); |
1288 | if (!old || !extent_buffer_uptodate(old)) { | 1288 | if (WARN_ON(!old || !extent_buffer_uptodate(old))) { |
1289 | free_extent_buffer(old); | 1289 | free_extent_buffer(old); |
1290 | pr_warn("btrfs: failed to read tree block %llu from get_old_root\n", | 1290 | pr_warn("btrfs: failed to read tree block %llu from get_old_root\n", |
1291 | logical); | 1291 | logical); |
1292 | WARN_ON(1); | ||
1293 | } else { | 1292 | } else { |
1294 | eb = btrfs_clone_extent_buffer(old); | 1293 | eb = btrfs_clone_extent_buffer(old); |
1295 | free_extent_buffer(old); | 1294 | free_extent_buffer(old); |
@@ -2758,7 +2757,7 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, | |||
2758 | int level; | 2757 | int level; |
2759 | int lowest_unlock = 1; | 2758 | int lowest_unlock = 1; |
2760 | u8 lowest_level = 0; | 2759 | u8 lowest_level = 0; |
2761 | int prev_cmp; | 2760 | int prev_cmp = -1; |
2762 | 2761 | ||
2763 | lowest_level = p->lowest_level; | 2762 | lowest_level = p->lowest_level; |
2764 | WARN_ON(p->nodes[0] != NULL); | 2763 | WARN_ON(p->nodes[0] != NULL); |
@@ -2769,7 +2768,6 @@ int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, | |||
2769 | } | 2768 | } |
2770 | 2769 | ||
2771 | again: | 2770 | again: |
2772 | prev_cmp = -1; | ||
2773 | b = get_old_root(root, time_seq); | 2771 | b = get_old_root(root, time_seq); |
2774 | level = btrfs_header_level(b); | 2772 | level = btrfs_header_level(b); |
2775 | p->locks[level] = BTRFS_READ_LOCK; | 2773 | p->locks[level] = BTRFS_READ_LOCK; |
@@ -2787,6 +2785,11 @@ again: | |||
2787 | */ | 2785 | */ |
2788 | btrfs_unlock_up_safe(p, level + 1); | 2786 | btrfs_unlock_up_safe(p, level + 1); |
2789 | 2787 | ||
2788 | /* | ||
2789 | * Since we can unwind eb's we want to do a real search every | ||
2790 | * time. | ||
2791 | */ | ||
2792 | prev_cmp = -1; | ||
2790 | ret = key_search(b, key, level, &prev_cmp, &slot); | 2793 | ret = key_search(b, key, level, &prev_cmp, &slot); |
2791 | 2794 | ||
2792 | if (level != 0) { | 2795 | if (level != 0) { |
@@ -3148,7 +3151,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, | |||
3148 | btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); | 3151 | btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); |
3149 | btrfs_set_header_owner(c, root->root_key.objectid); | 3152 | btrfs_set_header_owner(c, root->root_key.objectid); |
3150 | 3153 | ||
3151 | write_extent_buffer(c, root->fs_info->fsid, btrfs_header_fsid(c), | 3154 | write_extent_buffer(c, root->fs_info->fsid, btrfs_header_fsid(), |
3152 | BTRFS_FSID_SIZE); | 3155 | BTRFS_FSID_SIZE); |
3153 | 3156 | ||
3154 | write_extent_buffer(c, root->fs_info->chunk_tree_uuid, | 3157 | write_extent_buffer(c, root->fs_info->chunk_tree_uuid, |
@@ -3287,7 +3290,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
3287 | btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV); | 3290 | btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV); |
3288 | btrfs_set_header_owner(split, root->root_key.objectid); | 3291 | btrfs_set_header_owner(split, root->root_key.objectid); |
3289 | write_extent_buffer(split, root->fs_info->fsid, | 3292 | write_extent_buffer(split, root->fs_info->fsid, |
3290 | btrfs_header_fsid(split), BTRFS_FSID_SIZE); | 3293 | btrfs_header_fsid(), BTRFS_FSID_SIZE); |
3291 | write_extent_buffer(split, root->fs_info->chunk_tree_uuid, | 3294 | write_extent_buffer(split, root->fs_info->chunk_tree_uuid, |
3292 | btrfs_header_chunk_tree_uuid(split), | 3295 | btrfs_header_chunk_tree_uuid(split), |
3293 | BTRFS_UUID_SIZE); | 3296 | BTRFS_UUID_SIZE); |
@@ -3337,8 +3340,8 @@ static int leaf_space_used(struct extent_buffer *l, int start, int nr) | |||
3337 | if (!nr) | 3340 | if (!nr) |
3338 | return 0; | 3341 | return 0; |
3339 | btrfs_init_map_token(&token); | 3342 | btrfs_init_map_token(&token); |
3340 | start_item = btrfs_item_nr(l, start); | 3343 | start_item = btrfs_item_nr(start); |
3341 | end_item = btrfs_item_nr(l, end); | 3344 | end_item = btrfs_item_nr(end); |
3342 | data_len = btrfs_token_item_offset(l, start_item, &token) + | 3345 | data_len = btrfs_token_item_offset(l, start_item, &token) + |
3343 | btrfs_token_item_size(l, start_item, &token); | 3346 | btrfs_token_item_size(l, start_item, &token); |
3344 | data_len = data_len - btrfs_token_item_offset(l, end_item, &token); | 3347 | data_len = data_len - btrfs_token_item_offset(l, end_item, &token); |
@@ -3406,7 +3409,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, | |||
3406 | slot = path->slots[1]; | 3409 | slot = path->slots[1]; |
3407 | i = left_nritems - 1; | 3410 | i = left_nritems - 1; |
3408 | while (i >= nr) { | 3411 | while (i >= nr) { |
3409 | item = btrfs_item_nr(left, i); | 3412 | item = btrfs_item_nr(i); |
3410 | 3413 | ||
3411 | if (!empty && push_items > 0) { | 3414 | if (!empty && push_items > 0) { |
3412 | if (path->slots[0] > i) | 3415 | if (path->slots[0] > i) |
@@ -3470,7 +3473,7 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, | |||
3470 | btrfs_set_header_nritems(right, right_nritems); | 3473 | btrfs_set_header_nritems(right, right_nritems); |
3471 | push_space = BTRFS_LEAF_DATA_SIZE(root); | 3474 | push_space = BTRFS_LEAF_DATA_SIZE(root); |
3472 | for (i = 0; i < right_nritems; i++) { | 3475 | for (i = 0; i < right_nritems; i++) { |
3473 | item = btrfs_item_nr(right, i); | 3476 | item = btrfs_item_nr(i); |
3474 | push_space -= btrfs_token_item_size(right, item, &token); | 3477 | push_space -= btrfs_token_item_size(right, item, &token); |
3475 | btrfs_set_token_item_offset(right, item, push_space, &token); | 3478 | btrfs_set_token_item_offset(right, item, push_space, &token); |
3476 | } | 3479 | } |
@@ -3612,7 +3615,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, | |||
3612 | nr = min(right_nritems - 1, max_slot); | 3615 | nr = min(right_nritems - 1, max_slot); |
3613 | 3616 | ||
3614 | for (i = 0; i < nr; i++) { | 3617 | for (i = 0; i < nr; i++) { |
3615 | item = btrfs_item_nr(right, i); | 3618 | item = btrfs_item_nr(i); |
3616 | 3619 | ||
3617 | if (!empty && push_items > 0) { | 3620 | if (!empty && push_items > 0) { |
3618 | if (path->slots[0] < i) | 3621 | if (path->slots[0] < i) |
@@ -3639,8 +3642,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, | |||
3639 | ret = 1; | 3642 | ret = 1; |
3640 | goto out; | 3643 | goto out; |
3641 | } | 3644 | } |
3642 | if (!empty && push_items == btrfs_header_nritems(right)) | 3645 | WARN_ON(!empty && push_items == btrfs_header_nritems(right)); |
3643 | WARN_ON(1); | ||
3644 | 3646 | ||
3645 | /* push data from right to left */ | 3647 | /* push data from right to left */ |
3646 | copy_extent_buffer(left, right, | 3648 | copy_extent_buffer(left, right, |
@@ -3663,7 +3665,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, | |||
3663 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { | 3665 | for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { |
3664 | u32 ioff; | 3666 | u32 ioff; |
3665 | 3667 | ||
3666 | item = btrfs_item_nr(left, i); | 3668 | item = btrfs_item_nr(i); |
3667 | 3669 | ||
3668 | ioff = btrfs_token_item_offset(left, item, &token); | 3670 | ioff = btrfs_token_item_offset(left, item, &token); |
3669 | btrfs_set_token_item_offset(left, item, | 3671 | btrfs_set_token_item_offset(left, item, |
@@ -3694,7 +3696,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, | |||
3694 | btrfs_set_header_nritems(right, right_nritems); | 3696 | btrfs_set_header_nritems(right, right_nritems); |
3695 | push_space = BTRFS_LEAF_DATA_SIZE(root); | 3697 | push_space = BTRFS_LEAF_DATA_SIZE(root); |
3696 | for (i = 0; i < right_nritems; i++) { | 3698 | for (i = 0; i < right_nritems; i++) { |
3697 | item = btrfs_item_nr(right, i); | 3699 | item = btrfs_item_nr(i); |
3698 | 3700 | ||
3699 | push_space = push_space - btrfs_token_item_size(right, | 3701 | push_space = push_space - btrfs_token_item_size(right, |
3700 | item, &token); | 3702 | item, &token); |
@@ -3835,7 +3837,7 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, | |||
3835 | btrfs_item_end_nr(l, mid); | 3837 | btrfs_item_end_nr(l, mid); |
3836 | 3838 | ||
3837 | for (i = 0; i < nritems; i++) { | 3839 | for (i = 0; i < nritems; i++) { |
3838 | struct btrfs_item *item = btrfs_item_nr(right, i); | 3840 | struct btrfs_item *item = btrfs_item_nr(i); |
3839 | u32 ioff; | 3841 | u32 ioff; |
3840 | 3842 | ||
3841 | ioff = btrfs_token_item_offset(right, item, &token); | 3843 | ioff = btrfs_token_item_offset(right, item, &token); |
@@ -4016,7 +4018,7 @@ again: | |||
4016 | data_size > BTRFS_LEAF_DATA_SIZE(root)) { | 4018 | data_size > BTRFS_LEAF_DATA_SIZE(root)) { |
4017 | if (data_size && !tried_avoid_double) | 4019 | if (data_size && !tried_avoid_double) |
4018 | goto push_for_double; | 4020 | goto push_for_double; |
4019 | split = 2 ; | 4021 | split = 2; |
4020 | } | 4022 | } |
4021 | } | 4023 | } |
4022 | } | 4024 | } |
@@ -4042,7 +4044,7 @@ again: | |||
4042 | btrfs_set_header_owner(right, root->root_key.objectid); | 4044 | btrfs_set_header_owner(right, root->root_key.objectid); |
4043 | btrfs_set_header_level(right, 0); | 4045 | btrfs_set_header_level(right, 0); |
4044 | write_extent_buffer(right, root->fs_info->fsid, | 4046 | write_extent_buffer(right, root->fs_info->fsid, |
4045 | btrfs_header_fsid(right), BTRFS_FSID_SIZE); | 4047 | btrfs_header_fsid(), BTRFS_FSID_SIZE); |
4046 | 4048 | ||
4047 | write_extent_buffer(right, root->fs_info->chunk_tree_uuid, | 4049 | write_extent_buffer(right, root->fs_info->chunk_tree_uuid, |
4048 | btrfs_header_chunk_tree_uuid(right), | 4050 | btrfs_header_chunk_tree_uuid(right), |
@@ -4177,7 +4179,7 @@ static noinline int split_item(struct btrfs_trans_handle *trans, | |||
4177 | 4179 | ||
4178 | btrfs_set_path_blocking(path); | 4180 | btrfs_set_path_blocking(path); |
4179 | 4181 | ||
4180 | item = btrfs_item_nr(leaf, path->slots[0]); | 4182 | item = btrfs_item_nr(path->slots[0]); |
4181 | orig_offset = btrfs_item_offset(leaf, item); | 4183 | orig_offset = btrfs_item_offset(leaf, item); |
4182 | item_size = btrfs_item_size(leaf, item); | 4184 | item_size = btrfs_item_size(leaf, item); |
4183 | 4185 | ||
@@ -4200,7 +4202,7 @@ static noinline int split_item(struct btrfs_trans_handle *trans, | |||
4200 | btrfs_cpu_key_to_disk(&disk_key, new_key); | 4202 | btrfs_cpu_key_to_disk(&disk_key, new_key); |
4201 | btrfs_set_item_key(leaf, &disk_key, slot); | 4203 | btrfs_set_item_key(leaf, &disk_key, slot); |
4202 | 4204 | ||
4203 | new_item = btrfs_item_nr(leaf, slot); | 4205 | new_item = btrfs_item_nr(slot); |
4204 | 4206 | ||
4205 | btrfs_set_item_offset(leaf, new_item, orig_offset); | 4207 | btrfs_set_item_offset(leaf, new_item, orig_offset); |
4206 | btrfs_set_item_size(leaf, new_item, item_size - split_offset); | 4208 | btrfs_set_item_size(leaf, new_item, item_size - split_offset); |
@@ -4339,7 +4341,7 @@ void btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path, | |||
4339 | /* first correct the data pointers */ | 4341 | /* first correct the data pointers */ |
4340 | for (i = slot; i < nritems; i++) { | 4342 | for (i = slot; i < nritems; i++) { |
4341 | u32 ioff; | 4343 | u32 ioff; |
4342 | item = btrfs_item_nr(leaf, i); | 4344 | item = btrfs_item_nr(i); |
4343 | 4345 | ||
4344 | ioff = btrfs_token_item_offset(leaf, item, &token); | 4346 | ioff = btrfs_token_item_offset(leaf, item, &token); |
4345 | btrfs_set_token_item_offset(leaf, item, | 4347 | btrfs_set_token_item_offset(leaf, item, |
@@ -4387,7 +4389,7 @@ void btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path, | |||
4387 | fixup_low_keys(root, path, &disk_key, 1); | 4389 | fixup_low_keys(root, path, &disk_key, 1); |
4388 | } | 4390 | } |
4389 | 4391 | ||
4390 | item = btrfs_item_nr(leaf, slot); | 4392 | item = btrfs_item_nr(slot); |
4391 | btrfs_set_item_size(leaf, item, new_size); | 4393 | btrfs_set_item_size(leaf, item, new_size); |
4392 | btrfs_mark_buffer_dirty(leaf); | 4394 | btrfs_mark_buffer_dirty(leaf); |
4393 | 4395 | ||
@@ -4441,7 +4443,7 @@ void btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, | |||
4441 | /* first correct the data pointers */ | 4443 | /* first correct the data pointers */ |
4442 | for (i = slot; i < nritems; i++) { | 4444 | for (i = slot; i < nritems; i++) { |
4443 | u32 ioff; | 4445 | u32 ioff; |
4444 | item = btrfs_item_nr(leaf, i); | 4446 | item = btrfs_item_nr(i); |
4445 | 4447 | ||
4446 | ioff = btrfs_token_item_offset(leaf, item, &token); | 4448 | ioff = btrfs_token_item_offset(leaf, item, &token); |
4447 | btrfs_set_token_item_offset(leaf, item, | 4449 | btrfs_set_token_item_offset(leaf, item, |
@@ -4455,7 +4457,7 @@ void btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, | |||
4455 | 4457 | ||
4456 | data_end = old_data; | 4458 | data_end = old_data; |
4457 | old_size = btrfs_item_size_nr(leaf, slot); | 4459 | old_size = btrfs_item_size_nr(leaf, slot); |
4458 | item = btrfs_item_nr(leaf, slot); | 4460 | item = btrfs_item_nr(slot); |
4459 | btrfs_set_item_size(leaf, item, old_size + data_size); | 4461 | btrfs_set_item_size(leaf, item, old_size + data_size); |
4460 | btrfs_mark_buffer_dirty(leaf); | 4462 | btrfs_mark_buffer_dirty(leaf); |
4461 | 4463 | ||
@@ -4514,7 +4516,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, | |||
4514 | for (i = slot; i < nritems; i++) { | 4516 | for (i = slot; i < nritems; i++) { |
4515 | u32 ioff; | 4517 | u32 ioff; |
4516 | 4518 | ||
4517 | item = btrfs_item_nr(leaf, i); | 4519 | item = btrfs_item_nr( i); |
4518 | ioff = btrfs_token_item_offset(leaf, item, &token); | 4520 | ioff = btrfs_token_item_offset(leaf, item, &token); |
4519 | btrfs_set_token_item_offset(leaf, item, | 4521 | btrfs_set_token_item_offset(leaf, item, |
4520 | ioff - total_data, &token); | 4522 | ioff - total_data, &token); |
@@ -4535,7 +4537,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, | |||
4535 | for (i = 0; i < nr; i++) { | 4537 | for (i = 0; i < nr; i++) { |
4536 | btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); | 4538 | btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); |
4537 | btrfs_set_item_key(leaf, &disk_key, slot + i); | 4539 | btrfs_set_item_key(leaf, &disk_key, slot + i); |
4538 | item = btrfs_item_nr(leaf, slot + i); | 4540 | item = btrfs_item_nr(slot + i); |
4539 | btrfs_set_token_item_offset(leaf, item, | 4541 | btrfs_set_token_item_offset(leaf, item, |
4540 | data_end - data_size[i], &token); | 4542 | data_end - data_size[i], &token); |
4541 | data_end -= data_size[i]; | 4543 | data_end -= data_size[i]; |
@@ -4730,7 +4732,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
4730 | for (i = slot + nr; i < nritems; i++) { | 4732 | for (i = slot + nr; i < nritems; i++) { |
4731 | u32 ioff; | 4733 | u32 ioff; |
4732 | 4734 | ||
4733 | item = btrfs_item_nr(leaf, i); | 4735 | item = btrfs_item_nr(i); |
4734 | ioff = btrfs_token_item_offset(leaf, item, &token); | 4736 | ioff = btrfs_token_item_offset(leaf, item, &token); |
4735 | btrfs_set_token_item_offset(leaf, item, | 4737 | btrfs_set_token_item_offset(leaf, item, |
4736 | ioff + dsize, &token); | 4738 | ioff + dsize, &token); |
@@ -4823,14 +4825,18 @@ static int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
4823 | 4825 | ||
4824 | btrfs_item_key_to_cpu(path->nodes[0], &key, 0); | 4826 | btrfs_item_key_to_cpu(path->nodes[0], &key, 0); |
4825 | 4827 | ||
4826 | if (key.offset > 0) | 4828 | if (key.offset > 0) { |
4827 | key.offset--; | 4829 | key.offset--; |
4828 | else if (key.type > 0) | 4830 | } else if (key.type > 0) { |
4829 | key.type--; | 4831 | key.type--; |
4830 | else if (key.objectid > 0) | 4832 | key.offset = (u64)-1; |
4833 | } else if (key.objectid > 0) { | ||
4831 | key.objectid--; | 4834 | key.objectid--; |
4832 | else | 4835 | key.type = (u8)-1; |
4836 | key.offset = (u64)-1; | ||
4837 | } else { | ||
4833 | return 1; | 4838 | return 1; |
4839 | } | ||
4834 | 4840 | ||
4835 | btrfs_release_path(path); | 4841 | btrfs_release_path(path); |
4836 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 4842 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
@@ -4866,7 +4872,6 @@ static int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
4866 | * was nothing in the tree that matched the search criteria. | 4872 | * was nothing in the tree that matched the search criteria. |
4867 | */ | 4873 | */ |
4868 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | 4874 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, |
4869 | struct btrfs_key *max_key, | ||
4870 | struct btrfs_path *path, | 4875 | struct btrfs_path *path, |
4871 | u64 min_trans) | 4876 | u64 min_trans) |
4872 | { | 4877 | { |
@@ -4911,10 +4916,8 @@ again: | |||
4911 | * If it is too old, old, skip to the next one. | 4916 | * If it is too old, old, skip to the next one. |
4912 | */ | 4917 | */ |
4913 | while (slot < nritems) { | 4918 | while (slot < nritems) { |
4914 | u64 blockptr; | ||
4915 | u64 gen; | 4919 | u64 gen; |
4916 | 4920 | ||
4917 | blockptr = btrfs_node_blockptr(cur, slot); | ||
4918 | gen = btrfs_node_ptr_generation(cur, slot); | 4921 | gen = btrfs_node_ptr_generation(cur, slot); |
4919 | if (gen < min_trans) { | 4922 | if (gen < min_trans) { |
4920 | slot++; | 4923 | slot++; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0506f40ede83..aea4433081dc 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -47,6 +47,12 @@ extern struct kmem_cache *btrfs_path_cachep; | |||
47 | extern struct kmem_cache *btrfs_free_space_cachep; | 47 | extern struct kmem_cache *btrfs_free_space_cachep; |
48 | struct btrfs_ordered_sum; | 48 | struct btrfs_ordered_sum; |
49 | 49 | ||
50 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
51 | #define STATIC noinline | ||
52 | #else | ||
53 | #define STATIC static noinline | ||
54 | #endif | ||
55 | |||
50 | #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ | 56 | #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ |
51 | 57 | ||
52 | #define BTRFS_MAX_MIRRORS 3 | 58 | #define BTRFS_MAX_MIRRORS 3 |
@@ -1580,7 +1586,6 @@ struct btrfs_fs_info { | |||
1580 | atomic_t scrubs_paused; | 1586 | atomic_t scrubs_paused; |
1581 | atomic_t scrub_cancel_req; | 1587 | atomic_t scrub_cancel_req; |
1582 | wait_queue_head_t scrub_pause_wait; | 1588 | wait_queue_head_t scrub_pause_wait; |
1583 | struct rw_semaphore scrub_super_lock; | ||
1584 | int scrub_workers_refcnt; | 1589 | int scrub_workers_refcnt; |
1585 | struct btrfs_workers scrub_workers; | 1590 | struct btrfs_workers scrub_workers; |
1586 | struct btrfs_workers scrub_wr_completion_workers; | 1591 | struct btrfs_workers scrub_wr_completion_workers; |
@@ -1724,7 +1729,9 @@ struct btrfs_root { | |||
1724 | int ref_cows; | 1729 | int ref_cows; |
1725 | int track_dirty; | 1730 | int track_dirty; |
1726 | int in_radix; | 1731 | int in_radix; |
1727 | 1732 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | |
1733 | int dummy_root; | ||
1734 | #endif | ||
1728 | u64 defrag_trans_start; | 1735 | u64 defrag_trans_start; |
1729 | struct btrfs_key defrag_progress; | 1736 | struct btrfs_key defrag_progress; |
1730 | struct btrfs_key defrag_max; | 1737 | struct btrfs_key defrag_max; |
@@ -2461,8 +2468,7 @@ static inline unsigned long btrfs_item_nr_offset(int nr) | |||
2461 | sizeof(struct btrfs_item) * nr; | 2468 | sizeof(struct btrfs_item) * nr; |
2462 | } | 2469 | } |
2463 | 2470 | ||
2464 | static inline struct btrfs_item *btrfs_item_nr(struct extent_buffer *eb, | 2471 | static inline struct btrfs_item *btrfs_item_nr(int nr) |
2465 | int nr) | ||
2466 | { | 2472 | { |
2467 | return (struct btrfs_item *)btrfs_item_nr_offset(nr); | 2473 | return (struct btrfs_item *)btrfs_item_nr_offset(nr); |
2468 | } | 2474 | } |
@@ -2475,30 +2481,30 @@ static inline u32 btrfs_item_end(struct extent_buffer *eb, | |||
2475 | 2481 | ||
2476 | static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) | 2482 | static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) |
2477 | { | 2483 | { |
2478 | return btrfs_item_end(eb, btrfs_item_nr(eb, nr)); | 2484 | return btrfs_item_end(eb, btrfs_item_nr(nr)); |
2479 | } | 2485 | } |
2480 | 2486 | ||
2481 | static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) | 2487 | static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) |
2482 | { | 2488 | { |
2483 | return btrfs_item_offset(eb, btrfs_item_nr(eb, nr)); | 2489 | return btrfs_item_offset(eb, btrfs_item_nr(nr)); |
2484 | } | 2490 | } |
2485 | 2491 | ||
2486 | static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) | 2492 | static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) |
2487 | { | 2493 | { |
2488 | return btrfs_item_size(eb, btrfs_item_nr(eb, nr)); | 2494 | return btrfs_item_size(eb, btrfs_item_nr(nr)); |
2489 | } | 2495 | } |
2490 | 2496 | ||
2491 | static inline void btrfs_item_key(struct extent_buffer *eb, | 2497 | static inline void btrfs_item_key(struct extent_buffer *eb, |
2492 | struct btrfs_disk_key *disk_key, int nr) | 2498 | struct btrfs_disk_key *disk_key, int nr) |
2493 | { | 2499 | { |
2494 | struct btrfs_item *item = btrfs_item_nr(eb, nr); | 2500 | struct btrfs_item *item = btrfs_item_nr(nr); |
2495 | read_eb_member(eb, item, struct btrfs_item, key, disk_key); | 2501 | read_eb_member(eb, item, struct btrfs_item, key, disk_key); |
2496 | } | 2502 | } |
2497 | 2503 | ||
2498 | static inline void btrfs_set_item_key(struct extent_buffer *eb, | 2504 | static inline void btrfs_set_item_key(struct extent_buffer *eb, |
2499 | struct btrfs_disk_key *disk_key, int nr) | 2505 | struct btrfs_disk_key *disk_key, int nr) |
2500 | { | 2506 | { |
2501 | struct btrfs_item *item = btrfs_item_nr(eb, nr); | 2507 | struct btrfs_item *item = btrfs_item_nr(nr); |
2502 | write_eb_member(eb, item, struct btrfs_item, key, disk_key); | 2508 | write_eb_member(eb, item, struct btrfs_item, key, disk_key); |
2503 | } | 2509 | } |
2504 | 2510 | ||
@@ -2666,7 +2672,7 @@ static inline void btrfs_set_header_backref_rev(struct extent_buffer *eb, | |||
2666 | btrfs_set_header_flags(eb, flags); | 2672 | btrfs_set_header_flags(eb, flags); |
2667 | } | 2673 | } |
2668 | 2674 | ||
2669 | static inline unsigned long btrfs_header_fsid(struct extent_buffer *eb) | 2675 | static inline unsigned long btrfs_header_fsid(void) |
2670 | { | 2676 | { |
2671 | return offsetof(struct btrfs_header, fsid); | 2677 | return offsetof(struct btrfs_header, fsid); |
2672 | } | 2678 | } |
@@ -3308,7 +3314,6 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, | |||
3308 | struct btrfs_key *key, int lowest_level, | 3314 | struct btrfs_key *key, int lowest_level, |
3309 | u64 min_trans); | 3315 | u64 min_trans); |
3310 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | 3316 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, |
3311 | struct btrfs_key *max_key, | ||
3312 | struct btrfs_path *path, | 3317 | struct btrfs_path *path, |
3313 | u64 min_trans); | 3318 | u64 min_trans); |
3314 | enum btrfs_compare_tree_result { | 3319 | enum btrfs_compare_tree_result { |
@@ -3675,8 +3680,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | |||
3675 | u32 min_type); | 3680 | u32 min_type); |
3676 | 3681 | ||
3677 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); | 3682 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); |
3678 | int btrfs_start_all_delalloc_inodes(struct btrfs_fs_info *fs_info, | 3683 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput); |
3679 | int delay_iput); | ||
3680 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 3684 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
3681 | struct extent_state **cached_state); | 3685 | struct extent_state **cached_state); |
3682 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 3686 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
@@ -3944,9 +3948,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
3944 | u64 end, struct btrfs_scrub_progress *progress, | 3948 | u64 end, struct btrfs_scrub_progress *progress, |
3945 | int readonly, int is_dev_replace); | 3949 | int readonly, int is_dev_replace); |
3946 | void btrfs_scrub_pause(struct btrfs_root *root); | 3950 | void btrfs_scrub_pause(struct btrfs_root *root); |
3947 | void btrfs_scrub_pause_super(struct btrfs_root *root); | ||
3948 | void btrfs_scrub_continue(struct btrfs_root *root); | 3951 | void btrfs_scrub_continue(struct btrfs_root *root); |
3949 | void btrfs_scrub_continue_super(struct btrfs_root *root); | ||
3950 | int btrfs_scrub_cancel(struct btrfs_fs_info *info); | 3952 | int btrfs_scrub_cancel(struct btrfs_fs_info *info); |
3951 | int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info, | 3953 | int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info, |
3952 | struct btrfs_device *dev); | 3954 | struct btrfs_device *dev); |
@@ -4028,5 +4030,9 @@ static inline int btrfs_defrag_cancelled(struct btrfs_fs_info *fs_info) | |||
4028 | return signal_pending(current); | 4030 | return signal_pending(current); |
4029 | } | 4031 | } |
4030 | 4032 | ||
4033 | /* Sanity test specific functions */ | ||
4034 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
4035 | void btrfs_test_destroy_inode(struct inode *inode); | ||
4036 | #endif | ||
4031 | 4037 | ||
4032 | #endif | 4038 | #endif |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index cbd9523ad09c..8d292fbae659 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -108,8 +108,8 @@ static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) | |||
108 | return node; | 108 | return node; |
109 | } | 109 | } |
110 | btrfs_inode->delayed_node = node; | 110 | btrfs_inode->delayed_node = node; |
111 | atomic_inc(&node->refs); /* can be accessed */ | 111 | /* can be accessed and cached in the inode */ |
112 | atomic_inc(&node->refs); /* cached in the inode */ | 112 | atomic_add(2, &node->refs); |
113 | spin_unlock(&root->inode_lock); | 113 | spin_unlock(&root->inode_lock); |
114 | return node; | 114 | return node; |
115 | } | 115 | } |
@@ -138,8 +138,8 @@ again: | |||
138 | return ERR_PTR(-ENOMEM); | 138 | return ERR_PTR(-ENOMEM); |
139 | btrfs_init_delayed_node(node, root, ino); | 139 | btrfs_init_delayed_node(node, root, ino); |
140 | 140 | ||
141 | atomic_inc(&node->refs); /* cached in the btrfs inode */ | 141 | /* cached in the btrfs inode and can be accessed */ |
142 | atomic_inc(&node->refs); /* can be accessed */ | 142 | atomic_add(2, &node->refs); |
143 | 143 | ||
144 | ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); | 144 | ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); |
145 | if (ret) { | 145 | if (ret) { |
@@ -649,14 +649,13 @@ static int btrfs_delayed_inode_reserve_metadata( | |||
649 | goto out; | 649 | goto out; |
650 | 650 | ||
651 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 651 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
652 | if (!ret) | 652 | if (!WARN_ON(ret)) |
653 | goto out; | 653 | goto out; |
654 | 654 | ||
655 | /* | 655 | /* |
656 | * Ok this is a problem, let's just steal from the global rsv | 656 | * Ok this is a problem, let's just steal from the global rsv |
657 | * since this really shouldn't happen that often. | 657 | * since this really shouldn't happen that often. |
658 | */ | 658 | */ |
659 | WARN_ON(1); | ||
660 | ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, | 659 | ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, |
661 | dst_rsv, num_bytes); | 660 | dst_rsv, num_bytes); |
662 | goto out; | 661 | goto out; |
@@ -771,13 +770,13 @@ static int btrfs_batch_insert_items(struct btrfs_root *root, | |||
771 | */ | 770 | */ |
772 | btrfs_set_path_blocking(path); | 771 | btrfs_set_path_blocking(path); |
773 | 772 | ||
774 | keys = kmalloc(sizeof(struct btrfs_key) * nitems, GFP_NOFS); | 773 | keys = kmalloc_array(nitems, sizeof(struct btrfs_key), GFP_NOFS); |
775 | if (!keys) { | 774 | if (!keys) { |
776 | ret = -ENOMEM; | 775 | ret = -ENOMEM; |
777 | goto out; | 776 | goto out; |
778 | } | 777 | } |
779 | 778 | ||
780 | data_size = kmalloc(sizeof(u32) * nitems, GFP_NOFS); | 779 | data_size = kmalloc_array(nitems, sizeof(u32), GFP_NOFS); |
781 | if (!data_size) { | 780 | if (!data_size) { |
782 | ret = -ENOMEM; | 781 | ret = -ENOMEM; |
783 | goto error; | 782 | goto error; |
@@ -1174,8 +1173,10 @@ int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
1174 | mutex_unlock(&delayed_node->mutex); | 1173 | mutex_unlock(&delayed_node->mutex); |
1175 | 1174 | ||
1176 | path = btrfs_alloc_path(); | 1175 | path = btrfs_alloc_path(); |
1177 | if (!path) | 1176 | if (!path) { |
1177 | btrfs_release_delayed_node(delayed_node); | ||
1178 | return -ENOMEM; | 1178 | return -ENOMEM; |
1179 | } | ||
1179 | path->leave_spinning = 1; | 1180 | path->leave_spinning = 1; |
1180 | 1181 | ||
1181 | block_rsv = trans->block_rsv; | 1182 | block_rsv = trans->block_rsv; |
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 9efb94e95858..342f9fd411e3 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include <linux/math64.h> | 27 | #include <linux/math64.h> |
28 | #include <asm/div64.h> | 28 | #include <asm/div64.h> |
29 | #include "compat.h" | ||
30 | #include "ctree.h" | 29 | #include "ctree.h" |
31 | #include "extent_map.h" | 30 | #include "extent_map.h" |
32 | #include "disk-io.h" | 31 | #include "disk-io.h" |
@@ -38,7 +37,6 @@ | |||
38 | #include "rcu-string.h" | 37 | #include "rcu-string.h" |
39 | #include "dev-replace.h" | 38 | #include "dev-replace.h" |
40 | 39 | ||
41 | static u64 btrfs_get_seconds_since_1970(void); | ||
42 | static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | 40 | static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, |
43 | int scrub_ret); | 41 | int scrub_ret); |
44 | static void btrfs_dev_replace_update_device_in_mapping_tree( | 42 | static void btrfs_dev_replace_update_device_in_mapping_tree( |
@@ -296,13 +294,6 @@ void btrfs_after_dev_replace_commit(struct btrfs_fs_info *fs_info) | |||
296 | dev_replace->cursor_left_last_write_of_item; | 294 | dev_replace->cursor_left_last_write_of_item; |
297 | } | 295 | } |
298 | 296 | ||
299 | static u64 btrfs_get_seconds_since_1970(void) | ||
300 | { | ||
301 | struct timespec t = CURRENT_TIME_SEC; | ||
302 | |||
303 | return t.tv_sec; | ||
304 | } | ||
305 | |||
306 | int btrfs_dev_replace_start(struct btrfs_root *root, | 297 | int btrfs_dev_replace_start(struct btrfs_root *root, |
307 | struct btrfs_ioctl_dev_replace_args *args) | 298 | struct btrfs_ioctl_dev_replace_args *args) |
308 | { | 299 | { |
@@ -390,7 +381,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
390 | * go to the tgtdev as well (refer to btrfs_map_block()). | 381 | * go to the tgtdev as well (refer to btrfs_map_block()). |
391 | */ | 382 | */ |
392 | dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED; | 383 | dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED; |
393 | dev_replace->time_started = btrfs_get_seconds_since_1970(); | 384 | dev_replace->time_started = get_seconds(); |
394 | dev_replace->cursor_left = 0; | 385 | dev_replace->cursor_left = 0; |
395 | dev_replace->committed_cursor_left = 0; | 386 | dev_replace->committed_cursor_left = 0; |
396 | dev_replace->cursor_left_last_write_of_item = 0; | 387 | dev_replace->cursor_left_last_write_of_item = 0; |
@@ -400,7 +391,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
400 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; | 391 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; |
401 | btrfs_dev_replace_unlock(dev_replace); | 392 | btrfs_dev_replace_unlock(dev_replace); |
402 | 393 | ||
403 | btrfs_wait_all_ordered_extents(root->fs_info); | 394 | btrfs_wait_ordered_roots(root->fs_info, -1); |
404 | 395 | ||
405 | /* force writing the updated state information to disk */ | 396 | /* force writing the updated state information to disk */ |
406 | trans = btrfs_start_transaction(root, 0); | 397 | trans = btrfs_start_transaction(root, 0); |
@@ -470,12 +461,12 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
470 | * flush all outstanding I/O and inode extent mappings before the | 461 | * flush all outstanding I/O and inode extent mappings before the |
471 | * copy operation is declared as being finished | 462 | * copy operation is declared as being finished |
472 | */ | 463 | */ |
473 | ret = btrfs_start_all_delalloc_inodes(root->fs_info, 0); | 464 | ret = btrfs_start_delalloc_roots(root->fs_info, 0); |
474 | if (ret) { | 465 | if (ret) { |
475 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); | 466 | mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); |
476 | return ret; | 467 | return ret; |
477 | } | 468 | } |
478 | btrfs_wait_all_ordered_extents(root->fs_info); | 469 | btrfs_wait_ordered_roots(root->fs_info, -1); |
479 | 470 | ||
480 | trans = btrfs_start_transaction(root, 0); | 471 | trans = btrfs_start_transaction(root, 0); |
481 | if (IS_ERR(trans)) { | 472 | if (IS_ERR(trans)) { |
@@ -493,7 +484,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
493 | : BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED; | 484 | : BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED; |
494 | dev_replace->tgtdev = NULL; | 485 | dev_replace->tgtdev = NULL; |
495 | dev_replace->srcdev = NULL; | 486 | dev_replace->srcdev = NULL; |
496 | dev_replace->time_stopped = btrfs_get_seconds_since_1970(); | 487 | dev_replace->time_stopped = get_seconds(); |
497 | dev_replace->item_needs_writeback = 1; | 488 | dev_replace->item_needs_writeback = 1; |
498 | 489 | ||
499 | if (scrub_ret) { | 490 | if (scrub_ret) { |
@@ -650,6 +641,9 @@ static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) | |||
650 | u64 result; | 641 | u64 result; |
651 | int ret; | 642 | int ret; |
652 | 643 | ||
644 | if (fs_info->sb->s_flags & MS_RDONLY) | ||
645 | return -EROFS; | ||
646 | |||
653 | mutex_lock(&dev_replace->lock_finishing_cancel_unmount); | 647 | mutex_lock(&dev_replace->lock_finishing_cancel_unmount); |
654 | btrfs_dev_replace_lock(dev_replace); | 648 | btrfs_dev_replace_lock(dev_replace); |
655 | switch (dev_replace->replace_state) { | 649 | switch (dev_replace->replace_state) { |
@@ -668,7 +662,7 @@ static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) | |||
668 | break; | 662 | break; |
669 | } | 663 | } |
670 | dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED; | 664 | dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED; |
671 | dev_replace->time_stopped = btrfs_get_seconds_since_1970(); | 665 | dev_replace->time_stopped = get_seconds(); |
672 | dev_replace->item_needs_writeback = 1; | 666 | dev_replace->item_needs_writeback = 1; |
673 | btrfs_dev_replace_unlock(dev_replace); | 667 | btrfs_dev_replace_unlock(dev_replace); |
674 | btrfs_scrub_cancel(fs_info); | 668 | btrfs_scrub_cancel(fs_info); |
@@ -703,7 +697,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info) | |||
703 | case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: | 697 | case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: |
704 | dev_replace->replace_state = | 698 | dev_replace->replace_state = |
705 | BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED; | 699 | BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED; |
706 | dev_replace->time_stopped = btrfs_get_seconds_since_1970(); | 700 | dev_replace->time_stopped = get_seconds(); |
707 | dev_replace->item_needs_writeback = 1; | 701 | dev_replace->item_needs_writeback = 1; |
708 | pr_info("btrfs: suspending dev_replace for unmount\n"); | 702 | pr_info("btrfs: suspending dev_replace for unmount\n"); |
709 | break; | 703 | break; |
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 79e594e341c7..c031ea3fd70f 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c | |||
@@ -58,7 +58,7 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle | |||
58 | return ERR_PTR(ret); | 58 | return ERR_PTR(ret); |
59 | WARN_ON(ret > 0); | 59 | WARN_ON(ret > 0); |
60 | leaf = path->nodes[0]; | 60 | leaf = path->nodes[0]; |
61 | item = btrfs_item_nr(leaf, path->slots[0]); | 61 | item = btrfs_item_nr(path->slots[0]); |
62 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); | 62 | ptr = btrfs_item_ptr(leaf, path->slots[0], char); |
63 | BUG_ON(data_size > btrfs_item_size(leaf, item)); | 63 | BUG_ON(data_size > btrfs_item_size(leaf, item)); |
64 | ptr += btrfs_item_size(leaf, item) - data_size; | 64 | ptr += btrfs_item_size(leaf, item) - data_size; |
@@ -474,8 +474,10 @@ int verify_dir_item(struct btrfs_root *root, | |||
474 | } | 474 | } |
475 | 475 | ||
476 | /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */ | 476 | /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */ |
477 | if (btrfs_dir_data_len(leaf, dir_item) > BTRFS_MAX_XATTR_SIZE(root)) { | 477 | if ((btrfs_dir_data_len(leaf, dir_item) + |
478 | printk(KERN_CRIT "btrfs: invalid dir item data len: %u\n", | 478 | btrfs_dir_name_len(leaf, dir_item)) > BTRFS_MAX_XATTR_SIZE(root)) { |
479 | printk(KERN_CRIT "btrfs: invalid dir item name + data len: %u + %u\n", | ||
480 | (unsigned)btrfs_dir_name_len(leaf, dir_item), | ||
479 | (unsigned)btrfs_dir_data_len(leaf, dir_item)); | 481 | (unsigned)btrfs_dir_data_len(leaf, dir_item)); |
480 | return 1; | 482 | return 1; |
481 | } | 483 | } |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62176ad89846..4c4ed0bb3da1 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/uuid.h> | 33 | #include <linux/uuid.h> |
34 | #include <linux/semaphore.h> | 34 | #include <linux/semaphore.h> |
35 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
36 | #include "compat.h" | ||
37 | #include "ctree.h" | 36 | #include "ctree.h" |
38 | #include "disk-io.h" | 37 | #include "disk-io.h" |
39 | #include "transaction.h" | 38 | #include "transaction.h" |
@@ -64,7 +63,6 @@ static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t, | |||
64 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root); | 63 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root); |
65 | static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | 64 | static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, |
66 | struct btrfs_root *root); | 65 | struct btrfs_root *root); |
67 | static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t); | ||
68 | static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root); | 66 | static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root); |
69 | static int btrfs_destroy_marked_extents(struct btrfs_root *root, | 67 | static int btrfs_destroy_marked_extents(struct btrfs_root *root, |
70 | struct extent_io_tree *dirty_pages, | 68 | struct extent_io_tree *dirty_pages, |
@@ -477,14 +475,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
477 | if (page != eb->pages[0]) | 475 | if (page != eb->pages[0]) |
478 | return 0; | 476 | return 0; |
479 | found_start = btrfs_header_bytenr(eb); | 477 | found_start = btrfs_header_bytenr(eb); |
480 | if (found_start != start) { | 478 | if (WARN_ON(found_start != start || !PageUptodate(page))) |
481 | WARN_ON(1); | ||
482 | return 0; | 479 | return 0; |
483 | } | ||
484 | if (!PageUptodate(page)) { | ||
485 | WARN_ON(1); | ||
486 | return 0; | ||
487 | } | ||
488 | csum_tree_block(root, eb, 0); | 480 | csum_tree_block(root, eb, 0); |
489 | return 0; | 481 | return 0; |
490 | } | 482 | } |
@@ -496,7 +488,7 @@ static int check_tree_block_fsid(struct btrfs_root *root, | |||
496 | u8 fsid[BTRFS_UUID_SIZE]; | 488 | u8 fsid[BTRFS_UUID_SIZE]; |
497 | int ret = 1; | 489 | int ret = 1; |
498 | 490 | ||
499 | read_extent_buffer(eb, fsid, btrfs_header_fsid(eb), BTRFS_FSID_SIZE); | 491 | read_extent_buffer(eb, fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); |
500 | while (fs_devices) { | 492 | while (fs_devices) { |
501 | if (!memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE)) { | 493 | if (!memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE)) { |
502 | ret = 0; | 494 | ret = 0; |
@@ -1105,8 +1097,7 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | |||
1105 | { | 1097 | { |
1106 | struct inode *btree_inode = root->fs_info->btree_inode; | 1098 | struct inode *btree_inode = root->fs_info->btree_inode; |
1107 | struct extent_buffer *eb; | 1099 | struct extent_buffer *eb; |
1108 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree, | 1100 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree, bytenr); |
1109 | bytenr, blocksize); | ||
1110 | return eb; | 1101 | return eb; |
1111 | } | 1102 | } |
1112 | 1103 | ||
@@ -1229,14 +1220,18 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
1229 | atomic_set(&root->refs, 1); | 1220 | atomic_set(&root->refs, 1); |
1230 | root->log_transid = 0; | 1221 | root->log_transid = 0; |
1231 | root->last_log_commit = 0; | 1222 | root->last_log_commit = 0; |
1232 | extent_io_tree_init(&root->dirty_log_pages, | 1223 | if (fs_info) |
1233 | fs_info->btree_inode->i_mapping); | 1224 | extent_io_tree_init(&root->dirty_log_pages, |
1225 | fs_info->btree_inode->i_mapping); | ||
1234 | 1226 | ||
1235 | memset(&root->root_key, 0, sizeof(root->root_key)); | 1227 | memset(&root->root_key, 0, sizeof(root->root_key)); |
1236 | memset(&root->root_item, 0, sizeof(root->root_item)); | 1228 | memset(&root->root_item, 0, sizeof(root->root_item)); |
1237 | memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); | 1229 | memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); |
1238 | memset(&root->root_kobj, 0, sizeof(root->root_kobj)); | 1230 | memset(&root->root_kobj, 0, sizeof(root->root_kobj)); |
1239 | root->defrag_trans_start = fs_info->generation; | 1231 | if (fs_info) |
1232 | root->defrag_trans_start = fs_info->generation; | ||
1233 | else | ||
1234 | root->defrag_trans_start = 0; | ||
1240 | init_completion(&root->kobj_unregister); | 1235 | init_completion(&root->kobj_unregister); |
1241 | root->defrag_running = 0; | 1236 | root->defrag_running = 0; |
1242 | root->root_key.objectid = objectid; | 1237 | root->root_key.objectid = objectid; |
@@ -1253,6 +1248,22 @@ static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info) | |||
1253 | return root; | 1248 | return root; |
1254 | } | 1249 | } |
1255 | 1250 | ||
1251 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
1252 | /* Should only be used by the testing infrastructure */ | ||
1253 | struct btrfs_root *btrfs_alloc_dummy_root(void) | ||
1254 | { | ||
1255 | struct btrfs_root *root; | ||
1256 | |||
1257 | root = btrfs_alloc_root(NULL); | ||
1258 | if (!root) | ||
1259 | return ERR_PTR(-ENOMEM); | ||
1260 | __setup_root(4096, 4096, 4096, 4096, root, NULL, 1); | ||
1261 | root->dummy_root = 1; | ||
1262 | |||
1263 | return root; | ||
1264 | } | ||
1265 | #endif | ||
1266 | |||
1256 | struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, | 1267 | struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, |
1257 | struct btrfs_fs_info *fs_info, | 1268 | struct btrfs_fs_info *fs_info, |
1258 | u64 objectid) | 1269 | u64 objectid) |
@@ -1292,7 +1303,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, | |||
1292 | btrfs_set_header_owner(leaf, objectid); | 1303 | btrfs_set_header_owner(leaf, objectid); |
1293 | root->node = leaf; | 1304 | root->node = leaf; |
1294 | 1305 | ||
1295 | write_extent_buffer(leaf, fs_info->fsid, btrfs_header_fsid(leaf), | 1306 | write_extent_buffer(leaf, fs_info->fsid, btrfs_header_fsid(), |
1296 | BTRFS_FSID_SIZE); | 1307 | BTRFS_FSID_SIZE); |
1297 | write_extent_buffer(leaf, fs_info->chunk_tree_uuid, | 1308 | write_extent_buffer(leaf, fs_info->chunk_tree_uuid, |
1298 | btrfs_header_chunk_tree_uuid(leaf), | 1309 | btrfs_header_chunk_tree_uuid(leaf), |
@@ -1379,7 +1390,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | |||
1379 | root->node = leaf; | 1390 | root->node = leaf; |
1380 | 1391 | ||
1381 | write_extent_buffer(root->node, root->fs_info->fsid, | 1392 | write_extent_buffer(root->node, root->fs_info->fsid, |
1382 | btrfs_header_fsid(root->node), BTRFS_FSID_SIZE); | 1393 | btrfs_header_fsid(), BTRFS_FSID_SIZE); |
1383 | btrfs_mark_buffer_dirty(root->node); | 1394 | btrfs_mark_buffer_dirty(root->node); |
1384 | btrfs_tree_unlock(root->node); | 1395 | btrfs_tree_unlock(root->node); |
1385 | return root; | 1396 | return root; |
@@ -1780,6 +1791,9 @@ sleep: | |||
1780 | wake_up_process(root->fs_info->cleaner_kthread); | 1791 | wake_up_process(root->fs_info->cleaner_kthread); |
1781 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 1792 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
1782 | 1793 | ||
1794 | if (unlikely(test_bit(BTRFS_FS_STATE_ERROR, | ||
1795 | &root->fs_info->fs_state))) | ||
1796 | btrfs_cleanup_transaction(root); | ||
1783 | if (!try_to_freeze()) { | 1797 | if (!try_to_freeze()) { |
1784 | set_current_state(TASK_INTERRUPTIBLE); | 1798 | set_current_state(TASK_INTERRUPTIBLE); |
1785 | if (!kthread_should_stop() && | 1799 | if (!kthread_should_stop() && |
@@ -2013,50 +2027,28 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info) | |||
2013 | btrfs_stop_workers(&fs_info->qgroup_rescan_workers); | 2027 | btrfs_stop_workers(&fs_info->qgroup_rescan_workers); |
2014 | } | 2028 | } |
2015 | 2029 | ||
2030 | static void free_root_extent_buffers(struct btrfs_root *root) | ||
2031 | { | ||
2032 | if (root) { | ||
2033 | free_extent_buffer(root->node); | ||
2034 | free_extent_buffer(root->commit_root); | ||
2035 | root->node = NULL; | ||
2036 | root->commit_root = NULL; | ||
2037 | } | ||
2038 | } | ||
2039 | |||
2016 | /* helper to cleanup tree roots */ | 2040 | /* helper to cleanup tree roots */ |
2017 | static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | 2041 | static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) |
2018 | { | 2042 | { |
2019 | free_extent_buffer(info->tree_root->node); | 2043 | free_root_extent_buffers(info->tree_root); |
2020 | free_extent_buffer(info->tree_root->commit_root); | 2044 | |
2021 | info->tree_root->node = NULL; | 2045 | free_root_extent_buffers(info->dev_root); |
2022 | info->tree_root->commit_root = NULL; | 2046 | free_root_extent_buffers(info->extent_root); |
2023 | 2047 | free_root_extent_buffers(info->csum_root); | |
2024 | if (info->dev_root) { | 2048 | free_root_extent_buffers(info->quota_root); |
2025 | free_extent_buffer(info->dev_root->node); | 2049 | free_root_extent_buffers(info->uuid_root); |
2026 | free_extent_buffer(info->dev_root->commit_root); | 2050 | if (chunk_root) |
2027 | info->dev_root->node = NULL; | 2051 | free_root_extent_buffers(info->chunk_root); |
2028 | info->dev_root->commit_root = NULL; | ||
2029 | } | ||
2030 | if (info->extent_root) { | ||
2031 | free_extent_buffer(info->extent_root->node); | ||
2032 | free_extent_buffer(info->extent_root->commit_root); | ||
2033 | info->extent_root->node = NULL; | ||
2034 | info->extent_root->commit_root = NULL; | ||
2035 | } | ||
2036 | if (info->csum_root) { | ||
2037 | free_extent_buffer(info->csum_root->node); | ||
2038 | free_extent_buffer(info->csum_root->commit_root); | ||
2039 | info->csum_root->node = NULL; | ||
2040 | info->csum_root->commit_root = NULL; | ||
2041 | } | ||
2042 | if (info->quota_root) { | ||
2043 | free_extent_buffer(info->quota_root->node); | ||
2044 | free_extent_buffer(info->quota_root->commit_root); | ||
2045 | info->quota_root->node = NULL; | ||
2046 | info->quota_root->commit_root = NULL; | ||
2047 | } | ||
2048 | if (info->uuid_root) { | ||
2049 | free_extent_buffer(info->uuid_root->node); | ||
2050 | free_extent_buffer(info->uuid_root->commit_root); | ||
2051 | info->uuid_root->node = NULL; | ||
2052 | info->uuid_root->commit_root = NULL; | ||
2053 | } | ||
2054 | if (chunk_root) { | ||
2055 | free_extent_buffer(info->chunk_root->node); | ||
2056 | free_extent_buffer(info->chunk_root->commit_root); | ||
2057 | info->chunk_root->node = NULL; | ||
2058 | info->chunk_root->commit_root = NULL; | ||
2059 | } | ||
2060 | } | 2052 | } |
2061 | 2053 | ||
2062 | static void del_fs_roots(struct btrfs_fs_info *fs_info) | 2054 | static void del_fs_roots(struct btrfs_fs_info *fs_info) |
@@ -2230,7 +2222,6 @@ int open_ctree(struct super_block *sb, | |||
2230 | atomic_set(&fs_info->scrubs_paused, 0); | 2222 | atomic_set(&fs_info->scrubs_paused, 0); |
2231 | atomic_set(&fs_info->scrub_cancel_req, 0); | 2223 | atomic_set(&fs_info->scrub_cancel_req, 0); |
2232 | init_waitqueue_head(&fs_info->scrub_pause_wait); | 2224 | init_waitqueue_head(&fs_info->scrub_pause_wait); |
2233 | init_rwsem(&fs_info->scrub_super_lock); | ||
2234 | fs_info->scrub_workers_refcnt = 0; | 2225 | fs_info->scrub_workers_refcnt = 0; |
2235 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY | 2226 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
2236 | fs_info->check_integrity_print_mask = 0; | 2227 | fs_info->check_integrity_print_mask = 0; |
@@ -2272,7 +2263,7 @@ int open_ctree(struct super_block *sb, | |||
2272 | sizeof(struct btrfs_key)); | 2263 | sizeof(struct btrfs_key)); |
2273 | set_bit(BTRFS_INODE_DUMMY, | 2264 | set_bit(BTRFS_INODE_DUMMY, |
2274 | &BTRFS_I(fs_info->btree_inode)->runtime_flags); | 2265 | &BTRFS_I(fs_info->btree_inode)->runtime_flags); |
2275 | insert_inode_hash(fs_info->btree_inode); | 2266 | btrfs_insert_inode_hash(fs_info->btree_inode); |
2276 | 2267 | ||
2277 | spin_lock_init(&fs_info->block_group_cache_lock); | 2268 | spin_lock_init(&fs_info->block_group_cache_lock); |
2278 | fs_info->block_group_cache_tree = RB_ROOT; | 2269 | fs_info->block_group_cache_tree = RB_ROOT; |
@@ -2670,6 +2661,7 @@ retry_root_backup: | |||
2670 | 2661 | ||
2671 | btrfs_set_root_node(&tree_root->root_item, tree_root->node); | 2662 | btrfs_set_root_node(&tree_root->root_item, tree_root->node); |
2672 | tree_root->commit_root = btrfs_root_node(tree_root); | 2663 | tree_root->commit_root = btrfs_root_node(tree_root); |
2664 | btrfs_set_root_refs(&tree_root->root_item, 1); | ||
2673 | 2665 | ||
2674 | location.objectid = BTRFS_EXTENT_TREE_OBJECTID; | 2666 | location.objectid = BTRFS_EXTENT_TREE_OBJECTID; |
2675 | location.type = BTRFS_ROOT_ITEM_KEY; | 2667 | location.type = BTRFS_ROOT_ITEM_KEY; |
@@ -3448,10 +3440,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
3448 | int write_ctree_super(struct btrfs_trans_handle *trans, | 3440 | int write_ctree_super(struct btrfs_trans_handle *trans, |
3449 | struct btrfs_root *root, int max_mirrors) | 3441 | struct btrfs_root *root, int max_mirrors) |
3450 | { | 3442 | { |
3451 | int ret; | 3443 | return write_all_supers(root, max_mirrors); |
3452 | |||
3453 | ret = write_all_supers(root, max_mirrors); | ||
3454 | return ret; | ||
3455 | } | 3444 | } |
3456 | 3445 | ||
3457 | /* Drop a fs root from the radix tree and free it. */ | 3446 | /* Drop a fs root from the radix tree and free it. */ |
@@ -3614,12 +3603,12 @@ int close_ctree(struct btrfs_root *root) | |||
3614 | percpu_counter_sum(&fs_info->delalloc_bytes)); | 3603 | percpu_counter_sum(&fs_info->delalloc_bytes)); |
3615 | } | 3604 | } |
3616 | 3605 | ||
3606 | del_fs_roots(fs_info); | ||
3607 | |||
3617 | btrfs_free_block_groups(fs_info); | 3608 | btrfs_free_block_groups(fs_info); |
3618 | 3609 | ||
3619 | btrfs_stop_all_workers(fs_info); | 3610 | btrfs_stop_all_workers(fs_info); |
3620 | 3611 | ||
3621 | del_fs_roots(fs_info); | ||
3622 | |||
3623 | free_root_pointers(fs_info, 1); | 3612 | free_root_pointers(fs_info, 1); |
3624 | 3613 | ||
3625 | iput(fs_info->btree_inode); | 3614 | iput(fs_info->btree_inode); |
@@ -3669,10 +3658,20 @@ int btrfs_set_buffer_uptodate(struct extent_buffer *buf) | |||
3669 | 3658 | ||
3670 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | 3659 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) |
3671 | { | 3660 | { |
3672 | struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; | 3661 | struct btrfs_root *root; |
3673 | u64 transid = btrfs_header_generation(buf); | 3662 | u64 transid = btrfs_header_generation(buf); |
3674 | int was_dirty; | 3663 | int was_dirty; |
3675 | 3664 | ||
3665 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
3666 | /* | ||
3667 | * This is a fast path so only do this check if we have sanity tests | ||
3668 | * enabled. Normal people shouldn't be marking dummy buffers as dirty | ||
3669 | * outside of the sanity tests. | ||
3670 | */ | ||
3671 | if (unlikely(test_bit(EXTENT_BUFFER_DUMMY, &buf->bflags))) | ||
3672 | return; | ||
3673 | #endif | ||
3674 | root = BTRFS_I(buf->pages[0]->mapping->host)->root; | ||
3676 | btrfs_assert_tree_locked(buf); | 3675 | btrfs_assert_tree_locked(buf); |
3677 | if (transid != root->fs_info->generation) | 3676 | if (transid != root->fs_info->generation) |
3678 | WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, " | 3677 | WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, " |
@@ -3802,7 +3801,8 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info) | |||
3802 | while (!list_empty(&splice)) { | 3801 | while (!list_empty(&splice)) { |
3803 | root = list_first_entry(&splice, struct btrfs_root, | 3802 | root = list_first_entry(&splice, struct btrfs_root, |
3804 | ordered_root); | 3803 | ordered_root); |
3805 | list_del_init(&root->ordered_root); | 3804 | list_move_tail(&root->ordered_root, |
3805 | &fs_info->ordered_roots); | ||
3806 | 3806 | ||
3807 | btrfs_destroy_ordered_extents(root); | 3807 | btrfs_destroy_ordered_extents(root); |
3808 | 3808 | ||
@@ -3880,24 +3880,6 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | |||
3880 | return ret; | 3880 | return ret; |
3881 | } | 3881 | } |
3882 | 3882 | ||
3883 | static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t) | ||
3884 | { | ||
3885 | struct btrfs_pending_snapshot *snapshot; | ||
3886 | struct list_head splice; | ||
3887 | |||
3888 | INIT_LIST_HEAD(&splice); | ||
3889 | |||
3890 | list_splice_init(&t->pending_snapshots, &splice); | ||
3891 | |||
3892 | while (!list_empty(&splice)) { | ||
3893 | snapshot = list_entry(splice.next, | ||
3894 | struct btrfs_pending_snapshot, | ||
3895 | list); | ||
3896 | snapshot->error = -ECANCELED; | ||
3897 | list_del_init(&snapshot->list); | ||
3898 | } | ||
3899 | } | ||
3900 | |||
3901 | static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) | 3883 | static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) |
3902 | { | 3884 | { |
3903 | struct btrfs_inode *btrfs_inode; | 3885 | struct btrfs_inode *btrfs_inode; |
@@ -4027,15 +4009,13 @@ again: | |||
4027 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | 4009 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, |
4028 | struct btrfs_root *root) | 4010 | struct btrfs_root *root) |
4029 | { | 4011 | { |
4012 | btrfs_destroy_ordered_operations(cur_trans, root); | ||
4013 | |||
4030 | btrfs_destroy_delayed_refs(cur_trans, root); | 4014 | btrfs_destroy_delayed_refs(cur_trans, root); |
4031 | btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv, | ||
4032 | cur_trans->dirty_pages.dirty_bytes); | ||
4033 | 4015 | ||
4034 | cur_trans->state = TRANS_STATE_COMMIT_START; | 4016 | cur_trans->state = TRANS_STATE_COMMIT_START; |
4035 | wake_up(&root->fs_info->transaction_blocked_wait); | 4017 | wake_up(&root->fs_info->transaction_blocked_wait); |
4036 | 4018 | ||
4037 | btrfs_evict_pending_snapshots(cur_trans); | ||
4038 | |||
4039 | cur_trans->state = TRANS_STATE_UNBLOCKED; | 4019 | cur_trans->state = TRANS_STATE_UNBLOCKED; |
4040 | wake_up(&root->fs_info->transaction_wait); | 4020 | wake_up(&root->fs_info->transaction_wait); |
4041 | 4021 | ||
@@ -4059,63 +4039,51 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | |||
4059 | static int btrfs_cleanup_transaction(struct btrfs_root *root) | 4039 | static int btrfs_cleanup_transaction(struct btrfs_root *root) |
4060 | { | 4040 | { |
4061 | struct btrfs_transaction *t; | 4041 | struct btrfs_transaction *t; |
4062 | LIST_HEAD(list); | ||
4063 | 4042 | ||
4064 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 4043 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
4065 | 4044 | ||
4066 | spin_lock(&root->fs_info->trans_lock); | 4045 | spin_lock(&root->fs_info->trans_lock); |
4067 | list_splice_init(&root->fs_info->trans_list, &list); | 4046 | while (!list_empty(&root->fs_info->trans_list)) { |
4068 | root->fs_info->running_transaction = NULL; | 4047 | t = list_first_entry(&root->fs_info->trans_list, |
4069 | spin_unlock(&root->fs_info->trans_lock); | 4048 | struct btrfs_transaction, list); |
4070 | 4049 | if (t->state >= TRANS_STATE_COMMIT_START) { | |
4071 | while (!list_empty(&list)) { | 4050 | atomic_inc(&t->use_count); |
4072 | t = list_entry(list.next, struct btrfs_transaction, list); | 4051 | spin_unlock(&root->fs_info->trans_lock); |
4073 | 4052 | btrfs_wait_for_commit(root, t->transid); | |
4074 | btrfs_destroy_ordered_operations(t, root); | 4053 | btrfs_put_transaction(t); |
4075 | 4054 | spin_lock(&root->fs_info->trans_lock); | |
4076 | btrfs_destroy_all_ordered_extents(root->fs_info); | 4055 | continue; |
4077 | 4056 | } | |
4078 | btrfs_destroy_delayed_refs(t, root); | 4057 | if (t == root->fs_info->running_transaction) { |
4079 | 4058 | t->state = TRANS_STATE_COMMIT_DOING; | |
4080 | /* | 4059 | spin_unlock(&root->fs_info->trans_lock); |
4081 | * FIXME: cleanup wait for commit | 4060 | /* |
4082 | * We needn't acquire the lock here, because we are during | 4061 | * We wait for 0 num_writers since we don't hold a trans |
4083 | * the umount, there is no other task which will change it. | 4062 | * handle open currently for this transaction. |
4084 | */ | 4063 | */ |
4085 | t->state = TRANS_STATE_COMMIT_START; | 4064 | wait_event(t->writer_wait, |
4086 | smp_mb(); | 4065 | atomic_read(&t->num_writers) == 0); |
4087 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) | 4066 | } else { |
4088 | wake_up(&root->fs_info->transaction_blocked_wait); | 4067 | spin_unlock(&root->fs_info->trans_lock); |
4089 | 4068 | } | |
4090 | btrfs_evict_pending_snapshots(t); | 4069 | btrfs_cleanup_one_transaction(t, root); |
4091 | |||
4092 | t->state = TRANS_STATE_UNBLOCKED; | ||
4093 | smp_mb(); | ||
4094 | if (waitqueue_active(&root->fs_info->transaction_wait)) | ||
4095 | wake_up(&root->fs_info->transaction_wait); | ||
4096 | |||
4097 | btrfs_destroy_delayed_inodes(root); | ||
4098 | btrfs_assert_delayed_root_empty(root); | ||
4099 | |||
4100 | btrfs_destroy_all_delalloc_inodes(root->fs_info); | ||
4101 | |||
4102 | btrfs_destroy_marked_extents(root, &t->dirty_pages, | ||
4103 | EXTENT_DIRTY); | ||
4104 | |||
4105 | btrfs_destroy_pinned_extent(root, | ||
4106 | root->fs_info->pinned_extents); | ||
4107 | |||
4108 | t->state = TRANS_STATE_COMPLETED; | ||
4109 | smp_mb(); | ||
4110 | if (waitqueue_active(&t->commit_wait)) | ||
4111 | wake_up(&t->commit_wait); | ||
4112 | 4070 | ||
4113 | atomic_set(&t->use_count, 0); | 4071 | spin_lock(&root->fs_info->trans_lock); |
4072 | if (t == root->fs_info->running_transaction) | ||
4073 | root->fs_info->running_transaction = NULL; | ||
4114 | list_del_init(&t->list); | 4074 | list_del_init(&t->list); |
4115 | memset(t, 0, sizeof(*t)); | 4075 | spin_unlock(&root->fs_info->trans_lock); |
4116 | kmem_cache_free(btrfs_transaction_cachep, t); | ||
4117 | } | ||
4118 | 4076 | ||
4077 | btrfs_put_transaction(t); | ||
4078 | trace_btrfs_transaction_commit(root); | ||
4079 | spin_lock(&root->fs_info->trans_lock); | ||
4080 | } | ||
4081 | spin_unlock(&root->fs_info->trans_lock); | ||
4082 | btrfs_destroy_all_ordered_extents(root->fs_info); | ||
4083 | btrfs_destroy_delayed_inodes(root); | ||
4084 | btrfs_assert_delayed_root_empty(root); | ||
4085 | btrfs_destroy_pinned_extent(root, root->fs_info->pinned_extents); | ||
4086 | btrfs_destroy_all_delalloc_inodes(root->fs_info); | ||
4119 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 4087 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
4120 | 4088 | ||
4121 | return 0; | 4089 | return 0; |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 5ce2a7da8b11..53059df350f8 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -86,6 +86,10 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, | |||
86 | struct btrfs_root *root); | 86 | struct btrfs_root *root); |
87 | void btrfs_free_fs_root(struct btrfs_root *root); | 87 | void btrfs_free_fs_root(struct btrfs_root *root); |
88 | 88 | ||
89 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
90 | struct btrfs_root *btrfs_alloc_dummy_root(void); | ||
91 | #endif | ||
92 | |||
89 | /* | 93 | /* |
90 | * This function is used to grab the root, and avoid it is freed when we | 94 | * This function is used to grab the root, and avoid it is freed when we |
91 | * access it. But it doesn't ensure that the tree is not dropped. | 95 | * access it. But it doesn't ensure that the tree is not dropped. |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 4b8691607373..41422a3de8ed 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include "btrfs_inode.h" | 5 | #include "btrfs_inode.h" |
6 | #include "print-tree.h" | 6 | #include "print-tree.h" |
7 | #include "export.h" | 7 | #include "export.h" |
8 | #include "compat.h" | ||
9 | 8 | ||
10 | #define BTRFS_FID_SIZE_NON_CONNECTABLE (offsetof(struct btrfs_fid, \ | 9 | #define BTRFS_FID_SIZE_NON_CONNECTABLE (offsetof(struct btrfs_fid, \ |
11 | parent_objectid) / 4) | 10 | parent_objectid) / 4) |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d58bef130a41..45d98d01028f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/ratelimit.h> | 26 | #include <linux/ratelimit.h> |
27 | #include <linux/percpu_counter.h> | 27 | #include <linux/percpu_counter.h> |
28 | #include "compat.h" | ||
29 | #include "hash.h" | 28 | #include "hash.h" |
30 | #include "ctree.h" | 29 | #include "ctree.h" |
31 | #include "disk-io.h" | 30 | #include "disk-io.h" |
@@ -1551,9 +1550,8 @@ again: | |||
1551 | if (ret && !insert) { | 1550 | if (ret && !insert) { |
1552 | err = -ENOENT; | 1551 | err = -ENOENT; |
1553 | goto out; | 1552 | goto out; |
1554 | } else if (ret) { | 1553 | } else if (WARN_ON(ret)) { |
1555 | err = -EIO; | 1554 | err = -EIO; |
1556 | WARN_ON(1); | ||
1557 | goto out; | 1555 | goto out; |
1558 | } | 1556 | } |
1559 | 1557 | ||
@@ -1979,7 +1977,6 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1979 | struct btrfs_extent_item *item; | 1977 | struct btrfs_extent_item *item; |
1980 | u64 refs; | 1978 | u64 refs; |
1981 | int ret; | 1979 | int ret; |
1982 | int err = 0; | ||
1983 | 1980 | ||
1984 | path = btrfs_alloc_path(); | 1981 | path = btrfs_alloc_path(); |
1985 | if (!path) | 1982 | if (!path) |
@@ -1992,14 +1989,9 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1992 | path, bytenr, num_bytes, parent, | 1989 | path, bytenr, num_bytes, parent, |
1993 | root_objectid, owner, offset, | 1990 | root_objectid, owner, offset, |
1994 | refs_to_add, extent_op); | 1991 | refs_to_add, extent_op); |
1995 | if (ret == 0) | 1992 | if (ret != -EAGAIN) |
1996 | goto out; | 1993 | goto out; |
1997 | 1994 | ||
1998 | if (ret != -EAGAIN) { | ||
1999 | err = ret; | ||
2000 | goto out; | ||
2001 | } | ||
2002 | |||
2003 | leaf = path->nodes[0]; | 1995 | leaf = path->nodes[0]; |
2004 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 1996 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
2005 | refs = btrfs_extent_refs(leaf, item); | 1997 | refs = btrfs_extent_refs(leaf, item); |
@@ -2021,7 +2013,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
2021 | btrfs_abort_transaction(trans, root, ret); | 2013 | btrfs_abort_transaction(trans, root, ret); |
2022 | out: | 2014 | out: |
2023 | btrfs_free_path(path); | 2015 | btrfs_free_path(path); |
2024 | return err; | 2016 | return ret; |
2025 | } | 2017 | } |
2026 | 2018 | ||
2027 | static int run_delayed_data_ref(struct btrfs_trans_handle *trans, | 2019 | static int run_delayed_data_ref(struct btrfs_trans_handle *trans, |
@@ -2137,15 +2129,28 @@ again: | |||
2137 | } | 2129 | } |
2138 | if (ret > 0) { | 2130 | if (ret > 0) { |
2139 | if (metadata) { | 2131 | if (metadata) { |
2140 | btrfs_release_path(path); | 2132 | if (path->slots[0] > 0) { |
2141 | metadata = 0; | 2133 | path->slots[0]--; |
2134 | btrfs_item_key_to_cpu(path->nodes[0], &key, | ||
2135 | path->slots[0]); | ||
2136 | if (key.objectid == node->bytenr && | ||
2137 | key.type == BTRFS_EXTENT_ITEM_KEY && | ||
2138 | key.offset == node->num_bytes) | ||
2139 | ret = 0; | ||
2140 | } | ||
2141 | if (ret > 0) { | ||
2142 | btrfs_release_path(path); | ||
2143 | metadata = 0; | ||
2142 | 2144 | ||
2143 | key.offset = node->num_bytes; | 2145 | key.objectid = node->bytenr; |
2144 | key.type = BTRFS_EXTENT_ITEM_KEY; | 2146 | key.offset = node->num_bytes; |
2145 | goto again; | 2147 | key.type = BTRFS_EXTENT_ITEM_KEY; |
2148 | goto again; | ||
2149 | } | ||
2150 | } else { | ||
2151 | err = -EIO; | ||
2152 | goto out; | ||
2146 | } | 2153 | } |
2147 | err = -EIO; | ||
2148 | goto out; | ||
2149 | } | 2154 | } |
2150 | 2155 | ||
2151 | leaf = path->nodes[0]; | 2156 | leaf = path->nodes[0]; |
@@ -2234,8 +2239,12 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, | |||
2234 | { | 2239 | { |
2235 | int ret = 0; | 2240 | int ret = 0; |
2236 | 2241 | ||
2237 | if (trans->aborted) | 2242 | if (trans->aborted) { |
2243 | if (insert_reserved) | ||
2244 | btrfs_pin_extent(root, node->bytenr, | ||
2245 | node->num_bytes, 1); | ||
2238 | return 0; | 2246 | return 0; |
2247 | } | ||
2239 | 2248 | ||
2240 | if (btrfs_delayed_ref_is_head(node)) { | 2249 | if (btrfs_delayed_ref_is_head(node)) { |
2241 | struct btrfs_delayed_ref_head *head; | 2250 | struct btrfs_delayed_ref_head *head; |
@@ -2411,6 +2420,14 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
2411 | btrfs_free_delayed_extent_op(extent_op); | 2420 | btrfs_free_delayed_extent_op(extent_op); |
2412 | 2421 | ||
2413 | if (ret) { | 2422 | if (ret) { |
2423 | /* | ||
2424 | * Need to reset must_insert_reserved if | ||
2425 | * there was an error so the abort stuff | ||
2426 | * can cleanup the reserved space | ||
2427 | * properly. | ||
2428 | */ | ||
2429 | if (must_insert_reserved) | ||
2430 | locked_ref->must_insert_reserved = 1; | ||
2414 | btrfs_debug(fs_info, "run_delayed_extent_op returned %d", ret); | 2431 | btrfs_debug(fs_info, "run_delayed_extent_op returned %d", ret); |
2415 | spin_lock(&delayed_refs->lock); | 2432 | spin_lock(&delayed_refs->lock); |
2416 | btrfs_delayed_ref_unlock(locked_ref); | 2433 | btrfs_delayed_ref_unlock(locked_ref); |
@@ -3197,8 +3214,7 @@ again: | |||
3197 | if (ret) | 3214 | if (ret) |
3198 | goto out_put; | 3215 | goto out_put; |
3199 | 3216 | ||
3200 | ret = btrfs_truncate_free_space_cache(root, trans, path, | 3217 | ret = btrfs_truncate_free_space_cache(root, trans, inode); |
3201 | inode); | ||
3202 | if (ret) | 3218 | if (ret) |
3203 | goto out_put; | 3219 | goto out_put; |
3204 | } | 3220 | } |
@@ -3318,10 +3334,9 @@ again: | |||
3318 | last = cache->key.objectid + cache->key.offset; | 3334 | last = cache->key.objectid + cache->key.offset; |
3319 | 3335 | ||
3320 | err = write_one_cache_group(trans, root, path, cache); | 3336 | err = write_one_cache_group(trans, root, path, cache); |
3337 | btrfs_put_block_group(cache); | ||
3321 | if (err) /* File system offline */ | 3338 | if (err) /* File system offline */ |
3322 | goto out; | 3339 | goto out; |
3323 | |||
3324 | btrfs_put_block_group(cache); | ||
3325 | } | 3340 | } |
3326 | 3341 | ||
3327 | while (1) { | 3342 | while (1) { |
@@ -3605,10 +3620,9 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes) | |||
3605 | /* make sure bytes are sectorsize aligned */ | 3620 | /* make sure bytes are sectorsize aligned */ |
3606 | bytes = ALIGN(bytes, root->sectorsize); | 3621 | bytes = ALIGN(bytes, root->sectorsize); |
3607 | 3622 | ||
3608 | if (root == root->fs_info->tree_root || | 3623 | if (btrfs_is_free_space_inode(inode)) { |
3609 | BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID) { | ||
3610 | alloc_chunk = 0; | ||
3611 | committed = 1; | 3624 | committed = 1; |
3625 | ASSERT(current->journal_info); | ||
3612 | } | 3626 | } |
3613 | 3627 | ||
3614 | data_sinfo = fs_info->data_sinfo; | 3628 | data_sinfo = fs_info->data_sinfo; |
@@ -3636,6 +3650,16 @@ again: | |||
3636 | spin_unlock(&data_sinfo->lock); | 3650 | spin_unlock(&data_sinfo->lock); |
3637 | alloc: | 3651 | alloc: |
3638 | alloc_target = btrfs_get_alloc_profile(root, 1); | 3652 | alloc_target = btrfs_get_alloc_profile(root, 1); |
3653 | /* | ||
3654 | * It is ugly that we don't call nolock join | ||
3655 | * transaction for the free space inode case here. | ||
3656 | * But it is safe because we only do the data space | ||
3657 | * reservation for the free space cache in the | ||
3658 | * transaction context, the common join transaction | ||
3659 | * just increase the counter of the current transaction | ||
3660 | * handler, doesn't try to acquire the trans_lock of | ||
3661 | * the fs. | ||
3662 | */ | ||
3639 | trans = btrfs_join_transaction(root); | 3663 | trans = btrfs_join_transaction(root); |
3640 | if (IS_ERR(trans)) | 3664 | if (IS_ERR(trans)) |
3641 | return PTR_ERR(trans); | 3665 | return PTR_ERR(trans); |
@@ -3681,6 +3705,9 @@ commit_trans: | |||
3681 | goto again; | 3705 | goto again; |
3682 | } | 3706 | } |
3683 | 3707 | ||
3708 | trace_btrfs_space_reservation(root->fs_info, | ||
3709 | "space_info:enospc", | ||
3710 | data_sinfo->flags, bytes, 1); | ||
3684 | return -ENOSPC; | 3711 | return -ENOSPC; |
3685 | } | 3712 | } |
3686 | data_sinfo->bytes_may_use += bytes; | 3713 | data_sinfo->bytes_may_use += bytes; |
@@ -3989,12 +4016,26 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, | |||
3989 | * the filesystem is readonly(all dirty pages are written to | 4016 | * the filesystem is readonly(all dirty pages are written to |
3990 | * the disk). | 4017 | * the disk). |
3991 | */ | 4018 | */ |
3992 | btrfs_start_all_delalloc_inodes(root->fs_info, 0); | 4019 | btrfs_start_delalloc_roots(root->fs_info, 0); |
3993 | if (!current->journal_info) | 4020 | if (!current->journal_info) |
3994 | btrfs_wait_all_ordered_extents(root->fs_info); | 4021 | btrfs_wait_ordered_roots(root->fs_info, -1); |
3995 | } | 4022 | } |
3996 | } | 4023 | } |
3997 | 4024 | ||
4025 | static inline int calc_reclaim_items_nr(struct btrfs_root *root, u64 to_reclaim) | ||
4026 | { | ||
4027 | u64 bytes; | ||
4028 | int nr; | ||
4029 | |||
4030 | bytes = btrfs_calc_trans_metadata_size(root, 1); | ||
4031 | nr = (int)div64_u64(to_reclaim, bytes); | ||
4032 | if (!nr) | ||
4033 | nr = 1; | ||
4034 | return nr; | ||
4035 | } | ||
4036 | |||
4037 | #define EXTENT_SIZE_PER_ITEM (256 * 1024) | ||
4038 | |||
3998 | /* | 4039 | /* |
3999 | * shrink metadata reservation for delalloc | 4040 | * shrink metadata reservation for delalloc |
4000 | */ | 4041 | */ |
@@ -4007,24 +4048,30 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
4007 | u64 delalloc_bytes; | 4048 | u64 delalloc_bytes; |
4008 | u64 max_reclaim; | 4049 | u64 max_reclaim; |
4009 | long time_left; | 4050 | long time_left; |
4010 | unsigned long nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT; | 4051 | unsigned long nr_pages; |
4011 | int loops = 0; | 4052 | int loops; |
4053 | int items; | ||
4012 | enum btrfs_reserve_flush_enum flush; | 4054 | enum btrfs_reserve_flush_enum flush; |
4013 | 4055 | ||
4056 | /* Calc the number of the pages we need flush for space reservation */ | ||
4057 | items = calc_reclaim_items_nr(root, to_reclaim); | ||
4058 | to_reclaim = items * EXTENT_SIZE_PER_ITEM; | ||
4059 | |||
4014 | trans = (struct btrfs_trans_handle *)current->journal_info; | 4060 | trans = (struct btrfs_trans_handle *)current->journal_info; |
4015 | block_rsv = &root->fs_info->delalloc_block_rsv; | 4061 | block_rsv = &root->fs_info->delalloc_block_rsv; |
4016 | space_info = block_rsv->space_info; | 4062 | space_info = block_rsv->space_info; |
4017 | 4063 | ||
4018 | smp_mb(); | ||
4019 | delalloc_bytes = percpu_counter_sum_positive( | 4064 | delalloc_bytes = percpu_counter_sum_positive( |
4020 | &root->fs_info->delalloc_bytes); | 4065 | &root->fs_info->delalloc_bytes); |
4021 | if (delalloc_bytes == 0) { | 4066 | if (delalloc_bytes == 0) { |
4022 | if (trans) | 4067 | if (trans) |
4023 | return; | 4068 | return; |
4024 | btrfs_wait_all_ordered_extents(root->fs_info); | 4069 | if (wait_ordered) |
4070 | btrfs_wait_ordered_roots(root->fs_info, items); | ||
4025 | return; | 4071 | return; |
4026 | } | 4072 | } |
4027 | 4073 | ||
4074 | loops = 0; | ||
4028 | while (delalloc_bytes && loops < 3) { | 4075 | while (delalloc_bytes && loops < 3) { |
4029 | max_reclaim = min(delalloc_bytes, to_reclaim); | 4076 | max_reclaim = min(delalloc_bytes, to_reclaim); |
4030 | nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; | 4077 | nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; |
@@ -4033,9 +4080,19 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
4033 | * We need to wait for the async pages to actually start before | 4080 | * We need to wait for the async pages to actually start before |
4034 | * we do anything. | 4081 | * we do anything. |
4035 | */ | 4082 | */ |
4036 | wait_event(root->fs_info->async_submit_wait, | 4083 | max_reclaim = atomic_read(&root->fs_info->async_delalloc_pages); |
4037 | !atomic_read(&root->fs_info->async_delalloc_pages)); | 4084 | if (!max_reclaim) |
4085 | goto skip_async; | ||
4086 | |||
4087 | if (max_reclaim <= nr_pages) | ||
4088 | max_reclaim = 0; | ||
4089 | else | ||
4090 | max_reclaim -= nr_pages; | ||
4038 | 4091 | ||
4092 | wait_event(root->fs_info->async_submit_wait, | ||
4093 | atomic_read(&root->fs_info->async_delalloc_pages) <= | ||
4094 | (int)max_reclaim); | ||
4095 | skip_async: | ||
4039 | if (!trans) | 4096 | if (!trans) |
4040 | flush = BTRFS_RESERVE_FLUSH_ALL; | 4097 | flush = BTRFS_RESERVE_FLUSH_ALL; |
4041 | else | 4098 | else |
@@ -4049,13 +4106,12 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, | |||
4049 | 4106 | ||
4050 | loops++; | 4107 | loops++; |
4051 | if (wait_ordered && !trans) { | 4108 | if (wait_ordered && !trans) { |
4052 | btrfs_wait_all_ordered_extents(root->fs_info); | 4109 | btrfs_wait_ordered_roots(root->fs_info, items); |
4053 | } else { | 4110 | } else { |
4054 | time_left = schedule_timeout_killable(1); | 4111 | time_left = schedule_timeout_killable(1); |
4055 | if (time_left) | 4112 | if (time_left) |
4056 | break; | 4113 | break; |
4057 | } | 4114 | } |
4058 | smp_mb(); | ||
4059 | delalloc_bytes = percpu_counter_sum_positive( | 4115 | delalloc_bytes = percpu_counter_sum_positive( |
4060 | &root->fs_info->delalloc_bytes); | 4116 | &root->fs_info->delalloc_bytes); |
4061 | } | 4117 | } |
@@ -4140,16 +4196,11 @@ static int flush_space(struct btrfs_root *root, | |||
4140 | switch (state) { | 4196 | switch (state) { |
4141 | case FLUSH_DELAYED_ITEMS_NR: | 4197 | case FLUSH_DELAYED_ITEMS_NR: |
4142 | case FLUSH_DELAYED_ITEMS: | 4198 | case FLUSH_DELAYED_ITEMS: |
4143 | if (state == FLUSH_DELAYED_ITEMS_NR) { | 4199 | if (state == FLUSH_DELAYED_ITEMS_NR) |
4144 | u64 bytes = btrfs_calc_trans_metadata_size(root, 1); | 4200 | nr = calc_reclaim_items_nr(root, num_bytes) * 2; |
4145 | 4201 | else | |
4146 | nr = (int)div64_u64(num_bytes, bytes); | ||
4147 | if (!nr) | ||
4148 | nr = 1; | ||
4149 | nr *= 2; | ||
4150 | } else { | ||
4151 | nr = -1; | 4202 | nr = -1; |
4152 | } | 4203 | |
4153 | trans = btrfs_join_transaction(root); | 4204 | trans = btrfs_join_transaction(root); |
4154 | if (IS_ERR(trans)) { | 4205 | if (IS_ERR(trans)) { |
4155 | ret = PTR_ERR(trans); | 4206 | ret = PTR_ERR(trans); |
@@ -4332,6 +4383,10 @@ out: | |||
4332 | !block_rsv_use_bytes(global_rsv, orig_bytes)) | 4383 | !block_rsv_use_bytes(global_rsv, orig_bytes)) |
4333 | ret = 0; | 4384 | ret = 0; |
4334 | } | 4385 | } |
4386 | if (ret == -ENOSPC) | ||
4387 | trace_btrfs_space_reservation(root->fs_info, | ||
4388 | "space_info:enospc", | ||
4389 | space_info->flags, orig_bytes, 1); | ||
4335 | if (flushing) { | 4390 | if (flushing) { |
4336 | spin_lock(&space_info->lock); | 4391 | spin_lock(&space_info->lock); |
4337 | space_info->flush = 0; | 4392 | space_info->flush = 0; |
@@ -4986,7 +5041,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4986 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | 5041 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); |
4987 | 5042 | ||
4988 | if (to_reserve) | 5043 | if (to_reserve) |
4989 | trace_btrfs_space_reservation(root->fs_info,"delalloc", | 5044 | trace_btrfs_space_reservation(root->fs_info, "delalloc", |
4990 | btrfs_ino(inode), to_reserve, 1); | 5045 | btrfs_ino(inode), to_reserve, 1); |
4991 | block_rsv_add_bytes(block_rsv, to_reserve, 1); | 5046 | block_rsv_add_bytes(block_rsv, to_reserve, 1); |
4992 | 5047 | ||
@@ -5264,6 +5319,8 @@ static int pin_down_extent(struct btrfs_root *root, | |||
5264 | 5319 | ||
5265 | set_extent_dirty(root->fs_info->pinned_extents, bytenr, | 5320 | set_extent_dirty(root->fs_info->pinned_extents, bytenr, |
5266 | bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL); | 5321 | bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL); |
5322 | if (reserved) | ||
5323 | trace_btrfs_reserved_extent_free(root, bytenr, num_bytes); | ||
5267 | return 0; | 5324 | return 0; |
5268 | } | 5325 | } |
5269 | 5326 | ||
@@ -5718,9 +5775,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5718 | } | 5775 | } |
5719 | extent_slot = path->slots[0]; | 5776 | extent_slot = path->slots[0]; |
5720 | } | 5777 | } |
5721 | } else if (ret == -ENOENT) { | 5778 | } else if (WARN_ON(ret == -ENOENT)) { |
5722 | btrfs_print_leaf(extent_root, path->nodes[0]); | 5779 | btrfs_print_leaf(extent_root, path->nodes[0]); |
5723 | WARN_ON(1); | ||
5724 | btrfs_err(info, | 5780 | btrfs_err(info, |
5725 | "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset %llu", | 5781 | "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset %llu", |
5726 | bytenr, parent, root_objectid, owner_objectid, | 5782 | bytenr, parent, root_objectid, owner_objectid, |
@@ -5967,6 +6023,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
5967 | 6023 | ||
5968 | btrfs_add_free_space(cache, buf->start, buf->len); | 6024 | btrfs_add_free_space(cache, buf->start, buf->len); |
5969 | btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE); | 6025 | btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE); |
6026 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); | ||
5970 | pin = 0; | 6027 | pin = 0; |
5971 | } | 6028 | } |
5972 | out: | 6029 | out: |
@@ -6594,8 +6651,6 @@ again: | |||
6594 | } | 6651 | } |
6595 | } | 6652 | } |
6596 | 6653 | ||
6597 | trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); | ||
6598 | |||
6599 | return ret; | 6654 | return ret; |
6600 | } | 6655 | } |
6601 | 6656 | ||
@@ -6707,6 +6762,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
6707 | ins->objectid, ins->offset); | 6762 | ins->objectid, ins->offset); |
6708 | BUG(); | 6763 | BUG(); |
6709 | } | 6764 | } |
6765 | trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); | ||
6710 | return ret; | 6766 | return ret; |
6711 | } | 6767 | } |
6712 | 6768 | ||
@@ -6731,13 +6787,18 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
6731 | size += sizeof(*block_info); | 6787 | size += sizeof(*block_info); |
6732 | 6788 | ||
6733 | path = btrfs_alloc_path(); | 6789 | path = btrfs_alloc_path(); |
6734 | if (!path) | 6790 | if (!path) { |
6791 | btrfs_free_and_pin_reserved_extent(root, ins->objectid, | ||
6792 | root->leafsize); | ||
6735 | return -ENOMEM; | 6793 | return -ENOMEM; |
6794 | } | ||
6736 | 6795 | ||
6737 | path->leave_spinning = 1; | 6796 | path->leave_spinning = 1; |
6738 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, | 6797 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, |
6739 | ins, size); | 6798 | ins, size); |
6740 | if (ret) { | 6799 | if (ret) { |
6800 | btrfs_free_and_pin_reserved_extent(root, ins->objectid, | ||
6801 | root->leafsize); | ||
6741 | btrfs_free_path(path); | 6802 | btrfs_free_path(path); |
6742 | return ret; | 6803 | return ret; |
6743 | } | 6804 | } |
@@ -6779,6 +6840,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
6779 | ins->objectid, ins->offset); | 6840 | ins->objectid, ins->offset); |
6780 | BUG(); | 6841 | BUG(); |
6781 | } | 6842 | } |
6843 | |||
6844 | trace_btrfs_reserved_extent_alloc(root, ins->objectid, root->leafsize); | ||
6782 | return ret; | 6845 | return ret; |
6783 | } | 6846 | } |
6784 | 6847 | ||
@@ -7983,7 +8046,7 @@ u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) | |||
7983 | 8046 | ||
7984 | spin_lock(&sinfo->lock); | 8047 | spin_lock(&sinfo->lock); |
7985 | 8048 | ||
7986 | for(i = 0; i < BTRFS_NR_RAID_TYPES; i++) | 8049 | for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) |
7987 | if (!list_empty(&sinfo->block_groups[i])) | 8050 | if (!list_empty(&sinfo->block_groups[i])) |
7988 | free_bytes += __btrfs_get_ro_block_group_free_space( | 8051 | free_bytes += __btrfs_get_ro_block_group_free_space( |
7989 | &sinfo->block_groups[i]); | 8052 | &sinfo->block_groups[i]); |
@@ -8271,15 +8334,14 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
8271 | 8334 | ||
8272 | release_global_block_rsv(info); | 8335 | release_global_block_rsv(info); |
8273 | 8336 | ||
8274 | while(!list_empty(&info->space_info)) { | 8337 | while (!list_empty(&info->space_info)) { |
8275 | space_info = list_entry(info->space_info.next, | 8338 | space_info = list_entry(info->space_info.next, |
8276 | struct btrfs_space_info, | 8339 | struct btrfs_space_info, |
8277 | list); | 8340 | list); |
8278 | if (btrfs_test_opt(info->tree_root, ENOSPC_DEBUG)) { | 8341 | if (btrfs_test_opt(info->tree_root, ENOSPC_DEBUG)) { |
8279 | if (space_info->bytes_pinned > 0 || | 8342 | if (WARN_ON(space_info->bytes_pinned > 0 || |
8280 | space_info->bytes_reserved > 0 || | 8343 | space_info->bytes_reserved > 0 || |
8281 | space_info->bytes_may_use > 0) { | 8344 | space_info->bytes_may_use > 0)) { |
8282 | WARN_ON(1); | ||
8283 | dump_space_info(space_info, 0, 0); | 8345 | dump_space_info(space_info, 0, 0); |
8284 | } | 8346 | } |
8285 | } | 8347 | } |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 51731b76900d..856bc2b2192c 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -13,13 +13,13 @@ | |||
13 | #include <linux/cleancache.h> | 13 | #include <linux/cleancache.h> |
14 | #include "extent_io.h" | 14 | #include "extent_io.h" |
15 | #include "extent_map.h" | 15 | #include "extent_map.h" |
16 | #include "compat.h" | ||
17 | #include "ctree.h" | 16 | #include "ctree.h" |
18 | #include "btrfs_inode.h" | 17 | #include "btrfs_inode.h" |
19 | #include "volumes.h" | 18 | #include "volumes.h" |
20 | #include "check-integrity.h" | 19 | #include "check-integrity.h" |
21 | #include "locking.h" | 20 | #include "locking.h" |
22 | #include "rcu-string.h" | 21 | #include "rcu-string.h" |
22 | #include "backref.h" | ||
23 | 23 | ||
24 | static struct kmem_cache *extent_state_cache; | 24 | static struct kmem_cache *extent_state_cache; |
25 | static struct kmem_cache *extent_buffer_cache; | 25 | static struct kmem_cache *extent_buffer_cache; |
@@ -1597,11 +1597,10 @@ done: | |||
1597 | * | 1597 | * |
1598 | * 1 is returned if we find something, 0 if nothing was in the tree | 1598 | * 1 is returned if we find something, 0 if nothing was in the tree |
1599 | */ | 1599 | */ |
1600 | static noinline u64 find_lock_delalloc_range(struct inode *inode, | 1600 | STATIC u64 find_lock_delalloc_range(struct inode *inode, |
1601 | struct extent_io_tree *tree, | 1601 | struct extent_io_tree *tree, |
1602 | struct page *locked_page, | 1602 | struct page *locked_page, u64 *start, |
1603 | u64 *start, u64 *end, | 1603 | u64 *end, u64 max_bytes) |
1604 | u64 max_bytes) | ||
1605 | { | 1604 | { |
1606 | u64 delalloc_start; | 1605 | u64 delalloc_start; |
1607 | u64 delalloc_end; | 1606 | u64 delalloc_end; |
@@ -1740,10 +1739,8 @@ u64 count_range_bits(struct extent_io_tree *tree, | |||
1740 | u64 last = 0; | 1739 | u64 last = 0; |
1741 | int found = 0; | 1740 | int found = 0; |
1742 | 1741 | ||
1743 | if (search_end <= cur_start) { | 1742 | if (WARN_ON(search_end <= cur_start)) |
1744 | WARN_ON(1); | ||
1745 | return 0; | 1743 | return 0; |
1746 | } | ||
1747 | 1744 | ||
1748 | spin_lock(&tree->lock); | 1745 | spin_lock(&tree->lock); |
1749 | if (cur_start == 0 && bits == EXTENT_DIRTY) { | 1746 | if (cur_start == 0 && bits == EXTENT_DIRTY) { |
@@ -3569,9 +3566,8 @@ retry: | |||
3569 | * but no sense in crashing the users box for something | 3566 | * but no sense in crashing the users box for something |
3570 | * we can survive anyway. | 3567 | * we can survive anyway. |
3571 | */ | 3568 | */ |
3572 | if (!eb) { | 3569 | if (WARN_ON(!eb)) { |
3573 | spin_unlock(&mapping->private_lock); | 3570 | spin_unlock(&mapping->private_lock); |
3574 | WARN_ON(1); | ||
3575 | continue; | 3571 | continue; |
3576 | } | 3572 | } |
3577 | 3573 | ||
@@ -4038,7 +4034,7 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, | |||
4038 | if (offset >= last) | 4034 | if (offset >= last) |
4039 | return NULL; | 4035 | return NULL; |
4040 | 4036 | ||
4041 | while(1) { | 4037 | while (1) { |
4042 | len = last - offset; | 4038 | len = last - offset; |
4043 | if (len == 0) | 4039 | if (len == 0) |
4044 | break; | 4040 | break; |
@@ -4062,6 +4058,19 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, | |||
4062 | return NULL; | 4058 | return NULL; |
4063 | } | 4059 | } |
4064 | 4060 | ||
4061 | static noinline int count_ext_ref(u64 inum, u64 offset, u64 root_id, void *ctx) | ||
4062 | { | ||
4063 | unsigned long cnt = *((unsigned long *)ctx); | ||
4064 | |||
4065 | cnt++; | ||
4066 | *((unsigned long *)ctx) = cnt; | ||
4067 | |||
4068 | /* Now we're sure that the extent is shared. */ | ||
4069 | if (cnt > 1) | ||
4070 | return 1; | ||
4071 | return 0; | ||
4072 | } | ||
4073 | |||
4065 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 4074 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
4066 | __u64 start, __u64 len, get_extent_t *get_extent) | 4075 | __u64 start, __u64 len, get_extent_t *get_extent) |
4067 | { | 4076 | { |
@@ -4128,7 +4137,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4128 | last = found_key.offset; | 4137 | last = found_key.offset; |
4129 | last_for_get_extent = last + 1; | 4138 | last_for_get_extent = last + 1; |
4130 | } | 4139 | } |
4131 | btrfs_free_path(path); | 4140 | btrfs_release_path(path); |
4132 | 4141 | ||
4133 | /* | 4142 | /* |
4134 | * we might have some extents allocated but more delalloc past those | 4143 | * we might have some extents allocated but more delalloc past those |
@@ -4198,7 +4207,24 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4198 | flags |= (FIEMAP_EXTENT_DELALLOC | | 4207 | flags |= (FIEMAP_EXTENT_DELALLOC | |
4199 | FIEMAP_EXTENT_UNKNOWN); | 4208 | FIEMAP_EXTENT_UNKNOWN); |
4200 | } else { | 4209 | } else { |
4210 | unsigned long ref_cnt = 0; | ||
4211 | |||
4201 | disko = em->block_start + offset_in_extent; | 4212 | disko = em->block_start + offset_in_extent; |
4213 | |||
4214 | /* | ||
4215 | * As btrfs supports shared space, this information | ||
4216 | * can be exported to userspace tools via | ||
4217 | * flag FIEMAP_EXTENT_SHARED. | ||
4218 | */ | ||
4219 | ret = iterate_inodes_from_logical( | ||
4220 | em->block_start, | ||
4221 | BTRFS_I(inode)->root->fs_info, | ||
4222 | path, count_ext_ref, &ref_cnt); | ||
4223 | if (ret < 0 && ret != -ENOENT) | ||
4224 | goto out_free; | ||
4225 | |||
4226 | if (ref_cnt > 1) | ||
4227 | flags |= FIEMAP_EXTENT_SHARED; | ||
4202 | } | 4228 | } |
4203 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | 4229 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
4204 | flags |= FIEMAP_EXTENT_ENCODED; | 4230 | flags |= FIEMAP_EXTENT_ENCODED; |
@@ -4230,6 +4256,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4230 | out_free: | 4256 | out_free: |
4231 | free_extent_map(em); | 4257 | free_extent_map(em); |
4232 | out: | 4258 | out: |
4259 | btrfs_free_path(path); | ||
4233 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, | 4260 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, |
4234 | &cached_state, GFP_NOFS); | 4261 | &cached_state, GFP_NOFS); |
4235 | return ret; | 4262 | return ret; |
@@ -4455,6 +4482,23 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb) | |||
4455 | } | 4482 | } |
4456 | } | 4483 | } |
4457 | 4484 | ||
4485 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | ||
4486 | u64 start) | ||
4487 | { | ||
4488 | struct extent_buffer *eb; | ||
4489 | |||
4490 | rcu_read_lock(); | ||
4491 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | ||
4492 | if (eb && atomic_inc_not_zero(&eb->refs)) { | ||
4493 | rcu_read_unlock(); | ||
4494 | mark_extent_buffer_accessed(eb); | ||
4495 | return eb; | ||
4496 | } | ||
4497 | rcu_read_unlock(); | ||
4498 | |||
4499 | return NULL; | ||
4500 | } | ||
4501 | |||
4458 | struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | 4502 | struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, |
4459 | u64 start, unsigned long len) | 4503 | u64 start, unsigned long len) |
4460 | { | 4504 | { |
@@ -4468,14 +4512,10 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
4468 | int uptodate = 1; | 4512 | int uptodate = 1; |
4469 | int ret; | 4513 | int ret; |
4470 | 4514 | ||
4471 | rcu_read_lock(); | 4515 | |
4472 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | 4516 | eb = find_extent_buffer(tree, start); |
4473 | if (eb && atomic_inc_not_zero(&eb->refs)) { | 4517 | if (eb) |
4474 | rcu_read_unlock(); | ||
4475 | mark_extent_buffer_accessed(eb); | ||
4476 | return eb; | 4518 | return eb; |
4477 | } | ||
4478 | rcu_read_unlock(); | ||
4479 | 4519 | ||
4480 | eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS); | 4520 | eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS); |
4481 | if (!eb) | 4521 | if (!eb) |
@@ -4534,24 +4574,17 @@ again: | |||
4534 | 4574 | ||
4535 | spin_lock(&tree->buffer_lock); | 4575 | spin_lock(&tree->buffer_lock); |
4536 | ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb); | 4576 | ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb); |
4577 | spin_unlock(&tree->buffer_lock); | ||
4578 | radix_tree_preload_end(); | ||
4537 | if (ret == -EEXIST) { | 4579 | if (ret == -EEXIST) { |
4538 | exists = radix_tree_lookup(&tree->buffer, | 4580 | exists = find_extent_buffer(tree, start); |
4539 | start >> PAGE_CACHE_SHIFT); | 4581 | if (exists) |
4540 | if (!atomic_inc_not_zero(&exists->refs)) { | 4582 | goto free_eb; |
4541 | spin_unlock(&tree->buffer_lock); | 4583 | else |
4542 | radix_tree_preload_end(); | ||
4543 | exists = NULL; | ||
4544 | goto again; | 4584 | goto again; |
4545 | } | ||
4546 | spin_unlock(&tree->buffer_lock); | ||
4547 | radix_tree_preload_end(); | ||
4548 | mark_extent_buffer_accessed(exists); | ||
4549 | goto free_eb; | ||
4550 | } | 4585 | } |
4551 | /* add one reference for the tree */ | 4586 | /* add one reference for the tree */ |
4552 | check_buffer_tree_ref(eb); | 4587 | check_buffer_tree_ref(eb); |
4553 | spin_unlock(&tree->buffer_lock); | ||
4554 | radix_tree_preload_end(); | ||
4555 | 4588 | ||
4556 | /* | 4589 | /* |
4557 | * there is a race where release page may have | 4590 | * there is a race where release page may have |
@@ -4582,23 +4615,6 @@ free_eb: | |||
4582 | return exists; | 4615 | return exists; |
4583 | } | 4616 | } |
4584 | 4617 | ||
4585 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | ||
4586 | u64 start, unsigned long len) | ||
4587 | { | ||
4588 | struct extent_buffer *eb; | ||
4589 | |||
4590 | rcu_read_lock(); | ||
4591 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | ||
4592 | if (eb && atomic_inc_not_zero(&eb->refs)) { | ||
4593 | rcu_read_unlock(); | ||
4594 | mark_extent_buffer_accessed(eb); | ||
4595 | return eb; | ||
4596 | } | ||
4597 | rcu_read_unlock(); | ||
4598 | |||
4599 | return NULL; | ||
4600 | } | ||
4601 | |||
4602 | static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) | 4618 | static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) |
4603 | { | 4619 | { |
4604 | struct extent_buffer *eb = | 4620 | struct extent_buffer *eb = |
@@ -5062,23 +5078,6 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, | |||
5062 | } | 5078 | } |
5063 | } | 5079 | } |
5064 | 5080 | ||
5065 | static void move_pages(struct page *dst_page, struct page *src_page, | ||
5066 | unsigned long dst_off, unsigned long src_off, | ||
5067 | unsigned long len) | ||
5068 | { | ||
5069 | char *dst_kaddr = page_address(dst_page); | ||
5070 | if (dst_page == src_page) { | ||
5071 | memmove(dst_kaddr + dst_off, dst_kaddr + src_off, len); | ||
5072 | } else { | ||
5073 | char *src_kaddr = page_address(src_page); | ||
5074 | char *p = dst_kaddr + dst_off + len; | ||
5075 | char *s = src_kaddr + src_off + len; | ||
5076 | |||
5077 | while (len--) | ||
5078 | *--p = *--s; | ||
5079 | } | ||
5080 | } | ||
5081 | |||
5082 | static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len) | 5081 | static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len) |
5083 | { | 5082 | { |
5084 | unsigned long distance = (src > dst) ? src - dst : dst - src; | 5083 | unsigned long distance = (src > dst) ? src - dst : dst - src; |
@@ -5189,7 +5188,7 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | |||
5189 | 5188 | ||
5190 | cur = min_t(unsigned long, len, src_off_in_page + 1); | 5189 | cur = min_t(unsigned long, len, src_off_in_page + 1); |
5191 | cur = min(cur, dst_off_in_page + 1); | 5190 | cur = min(cur, dst_off_in_page + 1); |
5192 | move_pages(extent_buffer_page(dst, dst_i), | 5191 | copy_pages(extent_buffer_page(dst, dst_i), |
5193 | extent_buffer_page(dst, src_i), | 5192 | extent_buffer_page(dst, src_i), |
5194 | dst_off_in_page - cur + 1, | 5193 | dst_off_in_page - cur + 1, |
5195 | src_off_in_page - cur + 1, cur); | 5194 | src_off_in_page - cur + 1, cur); |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 6dbc645f1f3d..19620c58f096 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -271,7 +271,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
271 | struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len); | 271 | struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len); |
272 | struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); | 272 | struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); |
273 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | 273 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, |
274 | u64 start, unsigned long len); | 274 | u64 start); |
275 | void free_extent_buffer(struct extent_buffer *eb); | 275 | void free_extent_buffer(struct extent_buffer *eb); |
276 | void free_extent_buffer_stale(struct extent_buffer *eb); | 276 | void free_extent_buffer_stale(struct extent_buffer *eb); |
277 | #define WAIT_NONE 0 | 277 | #define WAIT_NONE 0 |
@@ -345,4 +345,10 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, | |||
345 | int end_extent_writepage(struct page *page, int err, u64 start, u64 end); | 345 | int end_extent_writepage(struct page *page, int err, u64 start, u64 end); |
346 | int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, | 346 | int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, |
347 | int mirror_num); | 347 | int mirror_num); |
348 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
349 | noinline u64 find_lock_delalloc_range(struct inode *inode, | ||
350 | struct extent_io_tree *tree, | ||
351 | struct page *locked_page, u64 *start, | ||
352 | u64 *end, u64 max_bytes); | ||
353 | #endif | ||
348 | #endif | 354 | #endif |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 61adc44b7805..93fba716d7f8 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -3,10 +3,10 @@ | |||
3 | 3 | ||
4 | #include <linux/rbtree.h> | 4 | #include <linux/rbtree.h> |
5 | 5 | ||
6 | #define EXTENT_MAP_LAST_BYTE (u64)-4 | 6 | #define EXTENT_MAP_LAST_BYTE ((u64)-4) |
7 | #define EXTENT_MAP_HOLE (u64)-3 | 7 | #define EXTENT_MAP_HOLE ((u64)-3) |
8 | #define EXTENT_MAP_INLINE (u64)-2 | 8 | #define EXTENT_MAP_INLINE ((u64)-2) |
9 | #define EXTENT_MAP_DELALLOC (u64)-1 | 9 | #define EXTENT_MAP_DELALLOC ((u64)-1) |
10 | 10 | ||
11 | /* bits for the flags field */ | 11 | /* bits for the flags field */ |
12 | #define EXTENT_FLAG_PINNED 0 /* this entry not yet on disk, don't free it */ | 12 | #define EXTENT_FLAG_PINNED 0 /* this entry not yet on disk, don't free it */ |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 4f53159bdb9d..6f3848860283 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -329,6 +329,9 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | |||
329 | u64 csum_end; | 329 | u64 csum_end; |
330 | u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); | 330 | u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); |
331 | 331 | ||
332 | ASSERT(start == ALIGN(start, root->sectorsize) && | ||
333 | (end + 1) == ALIGN(end + 1, root->sectorsize)); | ||
334 | |||
332 | path = btrfs_alloc_path(); | 335 | path = btrfs_alloc_path(); |
333 | if (!path) | 336 | if (!path) |
334 | return -ENOMEM; | 337 | return -ENOMEM; |
@@ -846,10 +849,8 @@ insert: | |||
846 | path->leave_spinning = 0; | 849 | path->leave_spinning = 0; |
847 | if (ret < 0) | 850 | if (ret < 0) |
848 | goto fail_unlock; | 851 | goto fail_unlock; |
849 | if (ret != 0) { | 852 | if (WARN_ON(ret != 0)) |
850 | WARN_ON(1); | ||
851 | goto fail_unlock; | 853 | goto fail_unlock; |
852 | } | ||
853 | leaf = path->nodes[0]; | 854 | leaf = path->nodes[0]; |
854 | csum: | 855 | csum: |
855 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 856 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 72da4df53c9a..82d0342763c5 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include "print-tree.h" | 39 | #include "print-tree.h" |
40 | #include "tree-log.h" | 40 | #include "tree-log.h" |
41 | #include "locking.h" | 41 | #include "locking.h" |
42 | #include "compat.h" | ||
43 | #include "volumes.h" | 42 | #include "volumes.h" |
44 | 43 | ||
45 | static struct kmem_cache *btrfs_inode_defrag_cachep; | 44 | static struct kmem_cache *btrfs_inode_defrag_cachep; |
@@ -370,7 +369,7 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info) | |||
370 | u64 root_objectid = 0; | 369 | u64 root_objectid = 0; |
371 | 370 | ||
372 | atomic_inc(&fs_info->defrag_running); | 371 | atomic_inc(&fs_info->defrag_running); |
373 | while(1) { | 372 | while (1) { |
374 | /* Pause the auto defragger. */ | 373 | /* Pause the auto defragger. */ |
375 | if (test_bit(BTRFS_FS_STATE_REMOUNTING, | 374 | if (test_bit(BTRFS_FS_STATE_REMOUNTING, |
376 | &fs_info->fs_state)) | 375 | &fs_info->fs_state)) |
@@ -1281,6 +1280,7 @@ again: | |||
1281 | } | 1280 | } |
1282 | wait_on_page_writeback(pages[i]); | 1281 | wait_on_page_writeback(pages[i]); |
1283 | } | 1282 | } |
1283 | faili = num_pages - 1; | ||
1284 | err = 0; | 1284 | err = 0; |
1285 | if (start_pos < inode->i_size) { | 1285 | if (start_pos < inode->i_size) { |
1286 | struct btrfs_ordered_extent *ordered; | 1286 | struct btrfs_ordered_extent *ordered; |
@@ -1299,8 +1299,10 @@ again: | |||
1299 | unlock_page(pages[i]); | 1299 | unlock_page(pages[i]); |
1300 | page_cache_release(pages[i]); | 1300 | page_cache_release(pages[i]); |
1301 | } | 1301 | } |
1302 | btrfs_wait_ordered_range(inode, start_pos, | 1302 | err = btrfs_wait_ordered_range(inode, start_pos, |
1303 | last_pos - start_pos); | 1303 | last_pos - start_pos); |
1304 | if (err) | ||
1305 | goto fail; | ||
1304 | goto again; | 1306 | goto again; |
1305 | } | 1307 | } |
1306 | if (ordered) | 1308 | if (ordered) |
@@ -1809,8 +1811,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
1809 | atomic_inc(&root->log_batch); | 1811 | atomic_inc(&root->log_batch); |
1810 | full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, | 1812 | full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, |
1811 | &BTRFS_I(inode)->runtime_flags); | 1813 | &BTRFS_I(inode)->runtime_flags); |
1812 | if (full_sync) | 1814 | if (full_sync) { |
1813 | btrfs_wait_ordered_range(inode, start, end - start + 1); | 1815 | ret = btrfs_wait_ordered_range(inode, start, end - start + 1); |
1816 | if (ret) { | ||
1817 | mutex_unlock(&inode->i_mutex); | ||
1818 | goto out; | ||
1819 | } | ||
1820 | } | ||
1814 | atomic_inc(&root->log_batch); | 1821 | atomic_inc(&root->log_batch); |
1815 | 1822 | ||
1816 | /* | 1823 | /* |
@@ -1876,27 +1883,20 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
1876 | mutex_unlock(&inode->i_mutex); | 1883 | mutex_unlock(&inode->i_mutex); |
1877 | 1884 | ||
1878 | if (ret != BTRFS_NO_LOG_SYNC) { | 1885 | if (ret != BTRFS_NO_LOG_SYNC) { |
1879 | if (ret > 0) { | 1886 | if (!ret) { |
1880 | /* | ||
1881 | * If we didn't already wait for ordered extents we need | ||
1882 | * to do that now. | ||
1883 | */ | ||
1884 | if (!full_sync) | ||
1885 | btrfs_wait_ordered_range(inode, start, | ||
1886 | end - start + 1); | ||
1887 | ret = btrfs_commit_transaction(trans, root); | ||
1888 | } else { | ||
1889 | ret = btrfs_sync_log(trans, root); | 1887 | ret = btrfs_sync_log(trans, root); |
1890 | if (ret == 0) { | 1888 | if (!ret) { |
1891 | ret = btrfs_end_transaction(trans, root); | 1889 | ret = btrfs_end_transaction(trans, root); |
1892 | } else { | 1890 | goto out; |
1893 | if (!full_sync) | ||
1894 | btrfs_wait_ordered_range(inode, start, | ||
1895 | end - | ||
1896 | start + 1); | ||
1897 | ret = btrfs_commit_transaction(trans, root); | ||
1898 | } | 1891 | } |
1899 | } | 1892 | } |
1893 | if (!full_sync) { | ||
1894 | ret = btrfs_wait_ordered_range(inode, start, | ||
1895 | end - start + 1); | ||
1896 | if (ret) | ||
1897 | goto out; | ||
1898 | } | ||
1899 | ret = btrfs_commit_transaction(trans, root); | ||
1900 | } else { | 1900 | } else { |
1901 | ret = btrfs_end_transaction(trans, root); | 1901 | ret = btrfs_end_transaction(trans, root); |
1902 | } | 1902 | } |
@@ -2067,7 +2067,9 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
2067 | bool same_page = ((offset >> PAGE_CACHE_SHIFT) == | 2067 | bool same_page = ((offset >> PAGE_CACHE_SHIFT) == |
2068 | ((offset + len - 1) >> PAGE_CACHE_SHIFT)); | 2068 | ((offset + len - 1) >> PAGE_CACHE_SHIFT)); |
2069 | 2069 | ||
2070 | btrfs_wait_ordered_range(inode, offset, len); | 2070 | ret = btrfs_wait_ordered_range(inode, offset, len); |
2071 | if (ret) | ||
2072 | return ret; | ||
2071 | 2073 | ||
2072 | mutex_lock(&inode->i_mutex); | 2074 | mutex_lock(&inode->i_mutex); |
2073 | /* | 2075 | /* |
@@ -2136,8 +2138,12 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
2136 | btrfs_put_ordered_extent(ordered); | 2138 | btrfs_put_ordered_extent(ordered); |
2137 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, | 2139 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, |
2138 | lockend, &cached_state, GFP_NOFS); | 2140 | lockend, &cached_state, GFP_NOFS); |
2139 | btrfs_wait_ordered_range(inode, lockstart, | 2141 | ret = btrfs_wait_ordered_range(inode, lockstart, |
2140 | lockend - lockstart + 1); | 2142 | lockend - lockstart + 1); |
2143 | if (ret) { | ||
2144 | mutex_unlock(&inode->i_mutex); | ||
2145 | return ret; | ||
2146 | } | ||
2141 | } | 2147 | } |
2142 | 2148 | ||
2143 | path = btrfs_alloc_path(); | 2149 | path = btrfs_alloc_path(); |
@@ -2308,7 +2314,10 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2308 | * wait for ordered IO before we have any locks. We'll loop again | 2314 | * wait for ordered IO before we have any locks. We'll loop again |
2309 | * below with the locks held. | 2315 | * below with the locks held. |
2310 | */ | 2316 | */ |
2311 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); | 2317 | ret = btrfs_wait_ordered_range(inode, alloc_start, |
2318 | alloc_end - alloc_start); | ||
2319 | if (ret) | ||
2320 | goto out; | ||
2312 | 2321 | ||
2313 | locked_end = alloc_end - 1; | 2322 | locked_end = alloc_end - 1; |
2314 | while (1) { | 2323 | while (1) { |
@@ -2332,8 +2341,10 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2332 | * we can't wait on the range with the transaction | 2341 | * we can't wait on the range with the transaction |
2333 | * running or with the extent lock held | 2342 | * running or with the extent lock held |
2334 | */ | 2343 | */ |
2335 | btrfs_wait_ordered_range(inode, alloc_start, | 2344 | ret = btrfs_wait_ordered_range(inode, alloc_start, |
2336 | alloc_end - alloc_start); | 2345 | alloc_end - alloc_start); |
2346 | if (ret) | ||
2347 | goto out; | ||
2337 | } else { | 2348 | } else { |
2338 | if (ordered) | 2349 | if (ordered) |
2339 | btrfs_put_ordered_extent(ordered); | 2350 | btrfs_put_ordered_extent(ordered); |
@@ -2405,14 +2416,12 @@ out_reserve_fail: | |||
2405 | static int find_desired_extent(struct inode *inode, loff_t *offset, int whence) | 2416 | static int find_desired_extent(struct inode *inode, loff_t *offset, int whence) |
2406 | { | 2417 | { |
2407 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2418 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2408 | struct extent_map *em; | 2419 | struct extent_map *em = NULL; |
2409 | struct extent_state *cached_state = NULL; | 2420 | struct extent_state *cached_state = NULL; |
2410 | u64 lockstart = *offset; | 2421 | u64 lockstart = *offset; |
2411 | u64 lockend = i_size_read(inode); | 2422 | u64 lockend = i_size_read(inode); |
2412 | u64 start = *offset; | 2423 | u64 start = *offset; |
2413 | u64 orig_start = *offset; | ||
2414 | u64 len = i_size_read(inode); | 2424 | u64 len = i_size_read(inode); |
2415 | u64 last_end = 0; | ||
2416 | int ret = 0; | 2425 | int ret = 0; |
2417 | 2426 | ||
2418 | lockend = max_t(u64, root->sectorsize, lockend); | 2427 | lockend = max_t(u64, root->sectorsize, lockend); |
@@ -2429,89 +2438,35 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int whence) | |||
2429 | lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, 0, | 2438 | lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, 0, |
2430 | &cached_state); | 2439 | &cached_state); |
2431 | 2440 | ||
2432 | /* | 2441 | while (start < inode->i_size) { |
2433 | * Delalloc is such a pain. If we have a hole and we have pending | ||
2434 | * delalloc for a portion of the hole we will get back a hole that | ||
2435 | * exists for the entire range since it hasn't been actually written | ||
2436 | * yet. So to take care of this case we need to look for an extent just | ||
2437 | * before the position we want in case there is outstanding delalloc | ||
2438 | * going on here. | ||
2439 | */ | ||
2440 | if (whence == SEEK_HOLE && start != 0) { | ||
2441 | if (start <= root->sectorsize) | ||
2442 | em = btrfs_get_extent_fiemap(inode, NULL, 0, 0, | ||
2443 | root->sectorsize, 0); | ||
2444 | else | ||
2445 | em = btrfs_get_extent_fiemap(inode, NULL, 0, | ||
2446 | start - root->sectorsize, | ||
2447 | root->sectorsize, 0); | ||
2448 | if (IS_ERR(em)) { | ||
2449 | ret = PTR_ERR(em); | ||
2450 | goto out; | ||
2451 | } | ||
2452 | last_end = em->start + em->len; | ||
2453 | if (em->block_start == EXTENT_MAP_DELALLOC) | ||
2454 | last_end = min_t(u64, last_end, inode->i_size); | ||
2455 | free_extent_map(em); | ||
2456 | } | ||
2457 | |||
2458 | while (1) { | ||
2459 | em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0); | 2442 | em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0); |
2460 | if (IS_ERR(em)) { | 2443 | if (IS_ERR(em)) { |
2461 | ret = PTR_ERR(em); | 2444 | ret = PTR_ERR(em); |
2445 | em = NULL; | ||
2462 | break; | 2446 | break; |
2463 | } | 2447 | } |
2464 | 2448 | ||
2465 | if (em->block_start == EXTENT_MAP_HOLE) { | 2449 | if (whence == SEEK_HOLE && |
2466 | if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { | 2450 | (em->block_start == EXTENT_MAP_HOLE || |
2467 | if (last_end <= orig_start) { | 2451 | test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) |
2468 | free_extent_map(em); | 2452 | break; |
2469 | ret = -ENXIO; | 2453 | else if (whence == SEEK_DATA && |
2470 | break; | 2454 | (em->block_start != EXTENT_MAP_HOLE && |
2471 | } | 2455 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) |
2472 | } | 2456 | break; |
2473 | |||
2474 | if (whence == SEEK_HOLE) { | ||
2475 | *offset = start; | ||
2476 | free_extent_map(em); | ||
2477 | break; | ||
2478 | } | ||
2479 | } else { | ||
2480 | if (whence == SEEK_DATA) { | ||
2481 | if (em->block_start == EXTENT_MAP_DELALLOC) { | ||
2482 | if (start >= inode->i_size) { | ||
2483 | free_extent_map(em); | ||
2484 | ret = -ENXIO; | ||
2485 | break; | ||
2486 | } | ||
2487 | } | ||
2488 | |||
2489 | if (!test_bit(EXTENT_FLAG_PREALLOC, | ||
2490 | &em->flags)) { | ||
2491 | *offset = start; | ||
2492 | free_extent_map(em); | ||
2493 | break; | ||
2494 | } | ||
2495 | } | ||
2496 | } | ||
2497 | 2457 | ||
2498 | start = em->start + em->len; | 2458 | start = em->start + em->len; |
2499 | last_end = em->start + em->len; | ||
2500 | |||
2501 | if (em->block_start == EXTENT_MAP_DELALLOC) | ||
2502 | last_end = min_t(u64, last_end, inode->i_size); | ||
2503 | |||
2504 | if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { | ||
2505 | free_extent_map(em); | ||
2506 | ret = -ENXIO; | ||
2507 | break; | ||
2508 | } | ||
2509 | free_extent_map(em); | 2459 | free_extent_map(em); |
2460 | em = NULL; | ||
2510 | cond_resched(); | 2461 | cond_resched(); |
2511 | } | 2462 | } |
2512 | if (!ret) | 2463 | free_extent_map(em); |
2513 | *offset = min(*offset, inode->i_size); | 2464 | if (!ret) { |
2514 | out: | 2465 | if (whence == SEEK_DATA && start >= inode->i_size) |
2466 | ret = -ENXIO; | ||
2467 | else | ||
2468 | *offset = min_t(loff_t, start, inode->i_size); | ||
2469 | } | ||
2515 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, | 2470 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, |
2516 | &cached_state, GFP_NOFS); | 2471 | &cached_state, GFP_NOFS); |
2517 | return ret; | 2472 | return ret; |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index b4f9904c4c6b..057be95b1e1e 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -218,7 +218,6 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_root *root, | |||
218 | 218 | ||
219 | int btrfs_truncate_free_space_cache(struct btrfs_root *root, | 219 | int btrfs_truncate_free_space_cache(struct btrfs_root *root, |
220 | struct btrfs_trans_handle *trans, | 220 | struct btrfs_trans_handle *trans, |
221 | struct btrfs_path *path, | ||
222 | struct inode *inode) | 221 | struct inode *inode) |
223 | { | 222 | { |
224 | int ret = 0; | 223 | int ret = 0; |
@@ -1009,8 +1008,13 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
1009 | if (ret) | 1008 | if (ret) |
1010 | goto out; | 1009 | goto out; |
1011 | 1010 | ||
1012 | 1011 | ret = btrfs_wait_ordered_range(inode, 0, (u64)-1); | |
1013 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 1012 | if (ret) { |
1013 | clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, | ||
1014 | EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL, | ||
1015 | GFP_NOFS); | ||
1016 | goto out; | ||
1017 | } | ||
1014 | 1018 | ||
1015 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; | 1019 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; |
1016 | key.offset = offset; | 1020 | key.offset = offset; |
@@ -2276,7 +2280,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, | |||
2276 | goto out; | 2280 | goto out; |
2277 | 2281 | ||
2278 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | 2282 | entry = rb_entry(node, struct btrfs_free_space, offset_index); |
2279 | while(1) { | 2283 | while (1) { |
2280 | if (entry->bytes < bytes && entry->bytes > *max_extent_size) | 2284 | if (entry->bytes < bytes && entry->bytes > *max_extent_size) |
2281 | *max_extent_size = entry->bytes; | 2285 | *max_extent_size = entry->bytes; |
2282 | 2286 | ||
@@ -2967,19 +2971,15 @@ out: | |||
2967 | 2971 | ||
2968 | int btrfs_write_out_ino_cache(struct btrfs_root *root, | 2972 | int btrfs_write_out_ino_cache(struct btrfs_root *root, |
2969 | struct btrfs_trans_handle *trans, | 2973 | struct btrfs_trans_handle *trans, |
2970 | struct btrfs_path *path) | 2974 | struct btrfs_path *path, |
2975 | struct inode *inode) | ||
2971 | { | 2976 | { |
2972 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | 2977 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
2973 | struct inode *inode; | ||
2974 | int ret; | 2978 | int ret; |
2975 | 2979 | ||
2976 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | 2980 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) |
2977 | return 0; | 2981 | return 0; |
2978 | 2982 | ||
2979 | inode = lookup_free_ino_inode(root, path); | ||
2980 | if (IS_ERR(inode)) | ||
2981 | return 0; | ||
2982 | |||
2983 | ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0); | 2983 | ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0); |
2984 | if (ret) { | 2984 | if (ret) { |
2985 | btrfs_delalloc_release_metadata(inode, inode->i_size); | 2985 | btrfs_delalloc_release_metadata(inode, inode->i_size); |
@@ -2990,7 +2990,6 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, | |||
2990 | #endif | 2990 | #endif |
2991 | } | 2991 | } |
2992 | 2992 | ||
2993 | iput(inode); | ||
2994 | return ret; | 2993 | return ret; |
2995 | } | 2994 | } |
2996 | 2995 | ||
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h index e737f92cf6d0..0cf4977ef70d 100644 --- a/fs/btrfs/free-space-cache.h +++ b/fs/btrfs/free-space-cache.h | |||
@@ -58,7 +58,6 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_root *root, | |||
58 | struct btrfs_block_rsv *rsv); | 58 | struct btrfs_block_rsv *rsv); |
59 | int btrfs_truncate_free_space_cache(struct btrfs_root *root, | 59 | int btrfs_truncate_free_space_cache(struct btrfs_root *root, |
60 | struct btrfs_trans_handle *trans, | 60 | struct btrfs_trans_handle *trans, |
61 | struct btrfs_path *path, | ||
62 | struct inode *inode); | 61 | struct inode *inode); |
63 | int load_free_space_cache(struct btrfs_fs_info *fs_info, | 62 | int load_free_space_cache(struct btrfs_fs_info *fs_info, |
64 | struct btrfs_block_group_cache *block_group); | 63 | struct btrfs_block_group_cache *block_group); |
@@ -76,7 +75,8 @@ int load_free_ino_cache(struct btrfs_fs_info *fs_info, | |||
76 | struct btrfs_root *root); | 75 | struct btrfs_root *root); |
77 | int btrfs_write_out_ino_cache(struct btrfs_root *root, | 76 | int btrfs_write_out_ino_cache(struct btrfs_root *root, |
78 | struct btrfs_trans_handle *trans, | 77 | struct btrfs_trans_handle *trans, |
79 | struct btrfs_path *path); | 78 | struct btrfs_path *path, |
79 | struct inode *inode); | ||
80 | 80 | ||
81 | void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group); | 81 | void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group); |
82 | int __btrfs_add_free_space(struct btrfs_free_space_ctl *ctl, | 82 | int __btrfs_add_free_space(struct btrfs_free_space_ctl *ctl, |
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c index e0b7034d6343..ec82fae07097 100644 --- a/fs/btrfs/inode-item.c +++ b/fs/btrfs/inode-item.c | |||
@@ -369,7 +369,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, | |||
369 | goto out; | 369 | goto out; |
370 | 370 | ||
371 | leaf = path->nodes[0]; | 371 | leaf = path->nodes[0]; |
372 | item = btrfs_item_nr(leaf, path->slots[0]); | 372 | item = btrfs_item_nr(path->slots[0]); |
373 | ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char); | 373 | ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char); |
374 | ptr += btrfs_item_size(leaf, item) - ins_len; | 374 | ptr += btrfs_item_size(leaf, item) - ins_len; |
375 | extref = (struct btrfs_inode_extref *)ptr; | 375 | extref = (struct btrfs_inode_extref *)ptr; |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 2c66ddbbe670..ab485e57b6fe 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -78,10 +78,8 @@ again: | |||
78 | btrfs_transaction_in_commit(fs_info)) { | 78 | btrfs_transaction_in_commit(fs_info)) { |
79 | leaf = path->nodes[0]; | 79 | leaf = path->nodes[0]; |
80 | 80 | ||
81 | if (btrfs_header_nritems(leaf) == 0) { | 81 | if (WARN_ON(btrfs_header_nritems(leaf) == 0)) |
82 | WARN_ON(1); | ||
83 | break; | 82 | break; |
84 | } | ||
85 | 83 | ||
86 | /* | 84 | /* |
87 | * Save the key so we can advances forward | 85 | * Save the key so we can advances forward |
@@ -237,7 +235,7 @@ again: | |||
237 | start_caching(root); | 235 | start_caching(root); |
238 | 236 | ||
239 | if (objectid <= root->cache_progress || | 237 | if (objectid <= root->cache_progress || |
240 | objectid > root->highest_objectid) | 238 | objectid >= root->highest_objectid) |
241 | __btrfs_add_free_space(ctl, objectid, 1); | 239 | __btrfs_add_free_space(ctl, objectid, 1); |
242 | else | 240 | else |
243 | __btrfs_add_free_space(pinned, objectid, 1); | 241 | __btrfs_add_free_space(pinned, objectid, 1); |
@@ -412,8 +410,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
412 | return 0; | 410 | return 0; |
413 | 411 | ||
414 | /* Don't save inode cache if we are deleting this root */ | 412 | /* Don't save inode cache if we are deleting this root */ |
415 | if (btrfs_root_refs(&root->root_item) == 0 && | 413 | if (btrfs_root_refs(&root->root_item) == 0) |
416 | root != root->fs_info->tree_root) | ||
417 | return 0; | 414 | return 0; |
418 | 415 | ||
419 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | 416 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) |
@@ -467,7 +464,7 @@ again: | |||
467 | } | 464 | } |
468 | 465 | ||
469 | if (i_size_read(inode) > 0) { | 466 | if (i_size_read(inode) > 0) { |
470 | ret = btrfs_truncate_free_space_cache(root, trans, path, inode); | 467 | ret = btrfs_truncate_free_space_cache(root, trans, inode); |
471 | if (ret) { | 468 | if (ret) { |
472 | if (ret != -ENOSPC) | 469 | if (ret != -ENOSPC) |
473 | btrfs_abort_transaction(trans, root, ret); | 470 | btrfs_abort_transaction(trans, root, ret); |
@@ -504,7 +501,7 @@ again: | |||
504 | } | 501 | } |
505 | btrfs_free_reserved_data_space(inode, prealloc); | 502 | btrfs_free_reserved_data_space(inode, prealloc); |
506 | 503 | ||
507 | ret = btrfs_write_out_ino_cache(root, trans, path); | 504 | ret = btrfs_write_out_ino_cache(root, trans, path, inode); |
508 | out_put: | 505 | out_put: |
509 | iput(inode); | 506 | iput(inode); |
510 | out_release: | 507 | out_release: |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 51e3afa78354..da8d2f696ac5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/btrfs.h> | 43 | #include <linux/btrfs.h> |
44 | #include <linux/blkdev.h> | 44 | #include <linux/blkdev.h> |
45 | #include <linux/posix_acl_xattr.h> | 45 | #include <linux/posix_acl_xattr.h> |
46 | #include "compat.h" | ||
47 | #include "ctree.h" | 46 | #include "ctree.h" |
48 | #include "disk-io.h" | 47 | #include "disk-io.h" |
49 | #include "transaction.h" | 48 | #include "transaction.h" |
@@ -844,7 +843,10 @@ static noinline int cow_file_range(struct inode *inode, | |||
844 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 843 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
845 | int ret = 0; | 844 | int ret = 0; |
846 | 845 | ||
847 | BUG_ON(btrfs_is_free_space_inode(inode)); | 846 | if (btrfs_is_free_space_inode(inode)) { |
847 | WARN_ON_ONCE(1); | ||
848 | return -EINVAL; | ||
849 | } | ||
848 | 850 | ||
849 | num_bytes = ALIGN(end - start + 1, blocksize); | 851 | num_bytes = ALIGN(end - start + 1, blocksize); |
850 | num_bytes = max(blocksize, num_bytes); | 852 | num_bytes = max(blocksize, num_bytes); |
@@ -1178,10 +1180,8 @@ static noinline int run_delalloc_nocow(struct inode *inode, | |||
1178 | while (1) { | 1180 | while (1) { |
1179 | ret = btrfs_lookup_file_extent(trans, root, path, ino, | 1181 | ret = btrfs_lookup_file_extent(trans, root, path, ino, |
1180 | cur_offset, 0); | 1182 | cur_offset, 0); |
1181 | if (ret < 0) { | 1183 | if (ret < 0) |
1182 | btrfs_abort_transaction(trans, root, ret); | ||
1183 | goto error; | 1184 | goto error; |
1184 | } | ||
1185 | if (ret > 0 && path->slots[0] > 0 && check_prev) { | 1185 | if (ret > 0 && path->slots[0] > 0 && check_prev) { |
1186 | leaf = path->nodes[0]; | 1186 | leaf = path->nodes[0]; |
1187 | btrfs_item_key_to_cpu(leaf, &found_key, | 1187 | btrfs_item_key_to_cpu(leaf, &found_key, |
@@ -1195,10 +1195,8 @@ next_slot: | |||
1195 | leaf = path->nodes[0]; | 1195 | leaf = path->nodes[0]; |
1196 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | 1196 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { |
1197 | ret = btrfs_next_leaf(root, path); | 1197 | ret = btrfs_next_leaf(root, path); |
1198 | if (ret < 0) { | 1198 | if (ret < 0) |
1199 | btrfs_abort_transaction(trans, root, ret); | ||
1200 | goto error; | 1199 | goto error; |
1201 | } | ||
1202 | if (ret > 0) | 1200 | if (ret > 0) |
1203 | break; | 1201 | break; |
1204 | leaf = path->nodes[0]; | 1202 | leaf = path->nodes[0]; |
@@ -1289,10 +1287,8 @@ out_check: | |||
1289 | ret = cow_file_range(inode, locked_page, | 1287 | ret = cow_file_range(inode, locked_page, |
1290 | cow_start, found_key.offset - 1, | 1288 | cow_start, found_key.offset - 1, |
1291 | page_started, nr_written, 1); | 1289 | page_started, nr_written, 1); |
1292 | if (ret) { | 1290 | if (ret) |
1293 | btrfs_abort_transaction(trans, root, ret); | ||
1294 | goto error; | 1291 | goto error; |
1295 | } | ||
1296 | cow_start = (u64)-1; | 1292 | cow_start = (u64)-1; |
1297 | } | 1293 | } |
1298 | 1294 | ||
@@ -1339,10 +1335,8 @@ out_check: | |||
1339 | BTRFS_DATA_RELOC_TREE_OBJECTID) { | 1335 | BTRFS_DATA_RELOC_TREE_OBJECTID) { |
1340 | ret = btrfs_reloc_clone_csums(inode, cur_offset, | 1336 | ret = btrfs_reloc_clone_csums(inode, cur_offset, |
1341 | num_bytes); | 1337 | num_bytes); |
1342 | if (ret) { | 1338 | if (ret) |
1343 | btrfs_abort_transaction(trans, root, ret); | ||
1344 | goto error; | 1339 | goto error; |
1345 | } | ||
1346 | } | 1340 | } |
1347 | 1341 | ||
1348 | extent_clear_unlock_delalloc(inode, cur_offset, | 1342 | extent_clear_unlock_delalloc(inode, cur_offset, |
@@ -1364,10 +1358,8 @@ out_check: | |||
1364 | if (cow_start != (u64)-1) { | 1358 | if (cow_start != (u64)-1) { |
1365 | ret = cow_file_range(inode, locked_page, cow_start, end, | 1359 | ret = cow_file_range(inode, locked_page, cow_start, end, |
1366 | page_started, nr_written, 1); | 1360 | page_started, nr_written, 1); |
1367 | if (ret) { | 1361 | if (ret) |
1368 | btrfs_abort_transaction(trans, root, ret); | ||
1369 | goto error; | 1362 | goto error; |
1370 | } | ||
1371 | } | 1363 | } |
1372 | 1364 | ||
1373 | error: | 1365 | error: |
@@ -1551,7 +1543,13 @@ static void btrfs_clear_bit_hook(struct inode *inode, | |||
1551 | spin_unlock(&BTRFS_I(inode)->lock); | 1543 | spin_unlock(&BTRFS_I(inode)->lock); |
1552 | } | 1544 | } |
1553 | 1545 | ||
1554 | if (*bits & EXTENT_DO_ACCOUNTING) | 1546 | /* |
1547 | * We don't reserve metadata space for space cache inodes so we | ||
1548 | * don't need to call dellalloc_release_metadata if there is an | ||
1549 | * error. | ||
1550 | */ | ||
1551 | if (*bits & EXTENT_DO_ACCOUNTING && | ||
1552 | root != root->fs_info->tree_root) | ||
1555 | btrfs_delalloc_release_metadata(inode, len); | 1553 | btrfs_delalloc_release_metadata(inode, len); |
1556 | 1554 | ||
1557 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID | 1555 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID |
@@ -2041,10 +2039,8 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id, | |||
2041 | key.offset = offset; | 2039 | key.offset = offset; |
2042 | 2040 | ||
2043 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 2041 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
2044 | if (ret < 0) { | 2042 | if (WARN_ON(ret < 0)) |
2045 | WARN_ON(1); | ||
2046 | return ret; | 2043 | return ret; |
2047 | } | ||
2048 | ret = 0; | 2044 | ret = 0; |
2049 | 2045 | ||
2050 | while (1) { | 2046 | while (1) { |
@@ -2367,10 +2363,23 @@ out_unlock: | |||
2367 | return ret; | 2363 | return ret; |
2368 | } | 2364 | } |
2369 | 2365 | ||
2366 | static void free_sa_defrag_extent(struct new_sa_defrag_extent *new) | ||
2367 | { | ||
2368 | struct old_sa_defrag_extent *old, *tmp; | ||
2369 | |||
2370 | if (!new) | ||
2371 | return; | ||
2372 | |||
2373 | list_for_each_entry_safe(old, tmp, &new->head, list) { | ||
2374 | list_del(&old->list); | ||
2375 | kfree(old); | ||
2376 | } | ||
2377 | kfree(new); | ||
2378 | } | ||
2379 | |||
2370 | static void relink_file_extents(struct new_sa_defrag_extent *new) | 2380 | static void relink_file_extents(struct new_sa_defrag_extent *new) |
2371 | { | 2381 | { |
2372 | struct btrfs_path *path; | 2382 | struct btrfs_path *path; |
2373 | struct old_sa_defrag_extent *old, *tmp; | ||
2374 | struct sa_defrag_extent_backref *backref; | 2383 | struct sa_defrag_extent_backref *backref; |
2375 | struct sa_defrag_extent_backref *prev = NULL; | 2384 | struct sa_defrag_extent_backref *prev = NULL; |
2376 | struct inode *inode; | 2385 | struct inode *inode; |
@@ -2413,16 +2422,11 @@ static void relink_file_extents(struct new_sa_defrag_extent *new) | |||
2413 | kfree(prev); | 2422 | kfree(prev); |
2414 | 2423 | ||
2415 | btrfs_free_path(path); | 2424 | btrfs_free_path(path); |
2416 | |||
2417 | list_for_each_entry_safe(old, tmp, &new->head, list) { | ||
2418 | list_del(&old->list); | ||
2419 | kfree(old); | ||
2420 | } | ||
2421 | out: | 2425 | out: |
2426 | free_sa_defrag_extent(new); | ||
2427 | |||
2422 | atomic_dec(&root->fs_info->defrag_running); | 2428 | atomic_dec(&root->fs_info->defrag_running); |
2423 | wake_up(&root->fs_info->transaction_wait); | 2429 | wake_up(&root->fs_info->transaction_wait); |
2424 | |||
2425 | kfree(new); | ||
2426 | } | 2430 | } |
2427 | 2431 | ||
2428 | static struct new_sa_defrag_extent * | 2432 | static struct new_sa_defrag_extent * |
@@ -2432,7 +2436,7 @@ record_old_file_extents(struct inode *inode, | |||
2432 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2436 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2433 | struct btrfs_path *path; | 2437 | struct btrfs_path *path; |
2434 | struct btrfs_key key; | 2438 | struct btrfs_key key; |
2435 | struct old_sa_defrag_extent *old, *tmp; | 2439 | struct old_sa_defrag_extent *old; |
2436 | struct new_sa_defrag_extent *new; | 2440 | struct new_sa_defrag_extent *new; |
2437 | int ret; | 2441 | int ret; |
2438 | 2442 | ||
@@ -2480,7 +2484,7 @@ record_old_file_extents(struct inode *inode, | |||
2480 | if (slot >= btrfs_header_nritems(l)) { | 2484 | if (slot >= btrfs_header_nritems(l)) { |
2481 | ret = btrfs_next_leaf(root, path); | 2485 | ret = btrfs_next_leaf(root, path); |
2482 | if (ret < 0) | 2486 | if (ret < 0) |
2483 | goto out_free_list; | 2487 | goto out_free_path; |
2484 | else if (ret > 0) | 2488 | else if (ret > 0) |
2485 | break; | 2489 | break; |
2486 | continue; | 2490 | continue; |
@@ -2509,7 +2513,7 @@ record_old_file_extents(struct inode *inode, | |||
2509 | 2513 | ||
2510 | old = kmalloc(sizeof(*old), GFP_NOFS); | 2514 | old = kmalloc(sizeof(*old), GFP_NOFS); |
2511 | if (!old) | 2515 | if (!old) |
2512 | goto out_free_list; | 2516 | goto out_free_path; |
2513 | 2517 | ||
2514 | offset = max(new->file_pos, key.offset); | 2518 | offset = max(new->file_pos, key.offset); |
2515 | end = min(new->file_pos + new->len, key.offset + num_bytes); | 2519 | end = min(new->file_pos + new->len, key.offset + num_bytes); |
@@ -2531,15 +2535,10 @@ next: | |||
2531 | 2535 | ||
2532 | return new; | 2536 | return new; |
2533 | 2537 | ||
2534 | out_free_list: | ||
2535 | list_for_each_entry_safe(old, tmp, &new->head, list) { | ||
2536 | list_del(&old->list); | ||
2537 | kfree(old); | ||
2538 | } | ||
2539 | out_free_path: | 2538 | out_free_path: |
2540 | btrfs_free_path(path); | 2539 | btrfs_free_path(path); |
2541 | out_kfree: | 2540 | out_kfree: |
2542 | kfree(new); | 2541 | free_sa_defrag_extent(new); |
2543 | return NULL; | 2542 | return NULL; |
2544 | } | 2543 | } |
2545 | 2544 | ||
@@ -2710,8 +2709,14 @@ out: | |||
2710 | btrfs_remove_ordered_extent(inode, ordered_extent); | 2709 | btrfs_remove_ordered_extent(inode, ordered_extent); |
2711 | 2710 | ||
2712 | /* for snapshot-aware defrag */ | 2711 | /* for snapshot-aware defrag */ |
2713 | if (new) | 2712 | if (new) { |
2714 | relink_file_extents(new); | 2713 | if (ret) { |
2714 | free_sa_defrag_extent(new); | ||
2715 | atomic_dec(&root->fs_info->defrag_running); | ||
2716 | } else { | ||
2717 | relink_file_extents(new); | ||
2718 | } | ||
2719 | } | ||
2715 | 2720 | ||
2716 | /* once for us */ | 2721 | /* once for us */ |
2717 | btrfs_put_ordered_extent(ordered_extent); | 2722 | btrfs_put_ordered_extent(ordered_extent); |
@@ -2969,6 +2974,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) | |||
2969 | if (insert >= 1) { | 2974 | if (insert >= 1) { |
2970 | ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode)); | 2975 | ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode)); |
2971 | if (ret) { | 2976 | if (ret) { |
2977 | atomic_dec(&root->orphan_inodes); | ||
2972 | if (reserve) { | 2978 | if (reserve) { |
2973 | clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED, | 2979 | clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED, |
2974 | &BTRFS_I(inode)->runtime_flags); | 2980 | &BTRFS_I(inode)->runtime_flags); |
@@ -3018,14 +3024,16 @@ static int btrfs_orphan_del(struct btrfs_trans_handle *trans, | |||
3018 | release_rsv = 1; | 3024 | release_rsv = 1; |
3019 | spin_unlock(&root->orphan_lock); | 3025 | spin_unlock(&root->orphan_lock); |
3020 | 3026 | ||
3021 | if (trans && delete_item) | 3027 | if (delete_item) { |
3022 | ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode)); | ||
3023 | |||
3024 | if (release_rsv) { | ||
3025 | btrfs_orphan_release_metadata(inode); | ||
3026 | atomic_dec(&root->orphan_inodes); | 3028 | atomic_dec(&root->orphan_inodes); |
3029 | if (trans) | ||
3030 | ret = btrfs_del_orphan_item(trans, root, | ||
3031 | btrfs_ino(inode)); | ||
3027 | } | 3032 | } |
3028 | 3033 | ||
3034 | if (release_rsv) | ||
3035 | btrfs_orphan_release_metadata(inode); | ||
3036 | |||
3029 | return ret; | 3037 | return ret; |
3030 | } | 3038 | } |
3031 | 3039 | ||
@@ -3172,8 +3180,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
3172 | 3180 | ||
3173 | /* if we have links, this was a truncate, lets do that */ | 3181 | /* if we have links, this was a truncate, lets do that */ |
3174 | if (inode->i_nlink) { | 3182 | if (inode->i_nlink) { |
3175 | if (!S_ISREG(inode->i_mode)) { | 3183 | if (WARN_ON(!S_ISREG(inode->i_mode))) { |
3176 | WARN_ON(1); | ||
3177 | iput(inode); | 3184 | iput(inode); |
3178 | continue; | 3185 | continue; |
3179 | } | 3186 | } |
@@ -3636,7 +3643,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | |||
3636 | int ret; | 3643 | int ret; |
3637 | ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len); | 3644 | ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len); |
3638 | if (!ret) { | 3645 | if (!ret) { |
3639 | btrfs_drop_nlink(inode); | 3646 | drop_nlink(inode); |
3640 | ret = btrfs_update_inode(trans, root, inode); | 3647 | ret = btrfs_update_inode(trans, root, inode); |
3641 | } | 3648 | } |
3642 | return ret; | 3649 | return ret; |
@@ -4230,15 +4237,16 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
4230 | 4237 | ||
4231 | while (1) { | 4238 | while (1) { |
4232 | struct btrfs_ordered_extent *ordered; | 4239 | struct btrfs_ordered_extent *ordered; |
4233 | btrfs_wait_ordered_range(inode, hole_start, | 4240 | |
4234 | block_end - hole_start); | ||
4235 | lock_extent_bits(io_tree, hole_start, block_end - 1, 0, | 4241 | lock_extent_bits(io_tree, hole_start, block_end - 1, 0, |
4236 | &cached_state); | 4242 | &cached_state); |
4237 | ordered = btrfs_lookup_ordered_extent(inode, hole_start); | 4243 | ordered = btrfs_lookup_ordered_range(inode, hole_start, |
4244 | block_end - hole_start); | ||
4238 | if (!ordered) | 4245 | if (!ordered) |
4239 | break; | 4246 | break; |
4240 | unlock_extent_cached(io_tree, hole_start, block_end - 1, | 4247 | unlock_extent_cached(io_tree, hole_start, block_end - 1, |
4241 | &cached_state, GFP_NOFS); | 4248 | &cached_state, GFP_NOFS); |
4249 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
4242 | btrfs_put_ordered_extent(ordered); | 4250 | btrfs_put_ordered_extent(ordered); |
4243 | } | 4251 | } |
4244 | 4252 | ||
@@ -4472,8 +4480,10 @@ void btrfs_evict_inode(struct inode *inode) | |||
4472 | trace_btrfs_inode_evict(inode); | 4480 | trace_btrfs_inode_evict(inode); |
4473 | 4481 | ||
4474 | truncate_inode_pages(&inode->i_data, 0); | 4482 | truncate_inode_pages(&inode->i_data, 0); |
4475 | if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || | 4483 | if (inode->i_nlink && |
4476 | btrfs_is_free_space_inode(inode))) | 4484 | ((btrfs_root_refs(&root->root_item) != 0 && |
4485 | root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) || | ||
4486 | btrfs_is_free_space_inode(inode))) | ||
4477 | goto no_delete; | 4487 | goto no_delete; |
4478 | 4488 | ||
4479 | if (is_bad_inode(inode)) { | 4489 | if (is_bad_inode(inode)) { |
@@ -4490,7 +4500,8 @@ void btrfs_evict_inode(struct inode *inode) | |||
4490 | } | 4500 | } |
4491 | 4501 | ||
4492 | if (inode->i_nlink > 0) { | 4502 | if (inode->i_nlink > 0) { |
4493 | BUG_ON(btrfs_root_refs(&root->root_item) != 0); | 4503 | BUG_ON(btrfs_root_refs(&root->root_item) != 0 && |
4504 | root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID); | ||
4494 | goto no_delete; | 4505 | goto no_delete; |
4495 | } | 4506 | } |
4496 | 4507 | ||
@@ -4731,14 +4742,7 @@ static void inode_tree_del(struct inode *inode) | |||
4731 | } | 4742 | } |
4732 | spin_unlock(&root->inode_lock); | 4743 | spin_unlock(&root->inode_lock); |
4733 | 4744 | ||
4734 | /* | 4745 | if (empty && btrfs_root_refs(&root->root_item) == 0) { |
4735 | * Free space cache has inodes in the tree root, but the tree root has a | ||
4736 | * root_refs of 0, so this could end up dropping the tree root as a | ||
4737 | * snapshot, so we need the extra !root->fs_info->tree_root check to | ||
4738 | * make sure we don't drop it. | ||
4739 | */ | ||
4740 | if (empty && btrfs_root_refs(&root->root_item) == 0 && | ||
4741 | root != root->fs_info->tree_root) { | ||
4742 | synchronize_srcu(&root->fs_info->subvol_srcu); | 4746 | synchronize_srcu(&root->fs_info->subvol_srcu); |
4743 | spin_lock(&root->inode_lock); | 4747 | spin_lock(&root->inode_lock); |
4744 | empty = RB_EMPTY_ROOT(&root->inode_tree); | 4748 | empty = RB_EMPTY_ROOT(&root->inode_tree); |
@@ -4831,10 +4835,12 @@ static struct inode *btrfs_iget_locked(struct super_block *s, | |||
4831 | { | 4835 | { |
4832 | struct inode *inode; | 4836 | struct inode *inode; |
4833 | struct btrfs_iget_args args; | 4837 | struct btrfs_iget_args args; |
4838 | unsigned long hashval = btrfs_inode_hash(objectid, root); | ||
4839 | |||
4834 | args.ino = objectid; | 4840 | args.ino = objectid; |
4835 | args.root = root; | 4841 | args.root = root; |
4836 | 4842 | ||
4837 | inode = iget5_locked(s, objectid, btrfs_find_actor, | 4843 | inode = iget5_locked(s, hashval, btrfs_find_actor, |
4838 | btrfs_init_locked_inode, | 4844 | btrfs_init_locked_inode, |
4839 | (void *)&args); | 4845 | (void *)&args); |
4840 | return inode; | 4846 | return inode; |
@@ -5048,7 +5054,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) | |||
5048 | continue; | 5054 | continue; |
5049 | } | 5055 | } |
5050 | 5056 | ||
5051 | item = btrfs_item_nr(leaf, slot); | 5057 | item = btrfs_item_nr(slot); |
5052 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 5058 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
5053 | 5059 | ||
5054 | if (found_key.objectid != key.objectid) | 5060 | if (found_key.objectid != key.objectid) |
@@ -5454,7 +5460,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
5454 | BTRFS_INODE_NODATASUM; | 5460 | BTRFS_INODE_NODATASUM; |
5455 | } | 5461 | } |
5456 | 5462 | ||
5457 | insert_inode_hash(inode); | 5463 | btrfs_insert_inode_hash(inode); |
5458 | inode_tree_add(inode); | 5464 | inode_tree_add(inode); |
5459 | 5465 | ||
5460 | trace_btrfs_inode_new(inode); | 5466 | trace_btrfs_inode_new(inode); |
@@ -5730,7 +5736,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
5730 | goto fail; | 5736 | goto fail; |
5731 | } | 5737 | } |
5732 | 5738 | ||
5733 | btrfs_inc_nlink(inode); | 5739 | inc_nlink(inode); |
5734 | inode_inc_iversion(inode); | 5740 | inode_inc_iversion(inode); |
5735 | inode->i_ctime = CURRENT_TIME; | 5741 | inode->i_ctime = CURRENT_TIME; |
5736 | ihold(inode); | 5742 | ihold(inode); |
@@ -5860,7 +5866,7 @@ static noinline int uncompress_inline(struct btrfs_path *path, | |||
5860 | compress_type = btrfs_file_extent_compression(leaf, item); | 5866 | compress_type = btrfs_file_extent_compression(leaf, item); |
5861 | max_size = btrfs_file_extent_ram_bytes(leaf, item); | 5867 | max_size = btrfs_file_extent_ram_bytes(leaf, item); |
5862 | inline_size = btrfs_file_extent_inline_item_len(leaf, | 5868 | inline_size = btrfs_file_extent_inline_item_len(leaf, |
5863 | btrfs_item_nr(leaf, path->slots[0])); | 5869 | btrfs_item_nr(path->slots[0])); |
5864 | tmp = kmalloc(inline_size, GFP_NOFS); | 5870 | tmp = kmalloc(inline_size, GFP_NOFS); |
5865 | if (!tmp) | 5871 | if (!tmp) |
5866 | return -ENOMEM; | 5872 | return -ENOMEM; |
@@ -5974,7 +5980,14 @@ again: | |||
5974 | found_type = btrfs_key_type(&found_key); | 5980 | found_type = btrfs_key_type(&found_key); |
5975 | if (found_key.objectid != objectid || | 5981 | if (found_key.objectid != objectid || |
5976 | found_type != BTRFS_EXTENT_DATA_KEY) { | 5982 | found_type != BTRFS_EXTENT_DATA_KEY) { |
5977 | goto not_found; | 5983 | /* |
5984 | * If we backup past the first extent we want to move forward | ||
5985 | * and see if there is an extent in front of us, otherwise we'll | ||
5986 | * say there is a hole for our whole search range which can | ||
5987 | * cause problems. | ||
5988 | */ | ||
5989 | extent_end = start; | ||
5990 | goto next; | ||
5978 | } | 5991 | } |
5979 | 5992 | ||
5980 | found_type = btrfs_file_extent_type(leaf, item); | 5993 | found_type = btrfs_file_extent_type(leaf, item); |
@@ -5989,7 +6002,7 @@ again: | |||
5989 | size = btrfs_file_extent_inline_len(leaf, item); | 6002 | size = btrfs_file_extent_inline_len(leaf, item); |
5990 | extent_end = ALIGN(extent_start + size, root->sectorsize); | 6003 | extent_end = ALIGN(extent_start + size, root->sectorsize); |
5991 | } | 6004 | } |
5992 | 6005 | next: | |
5993 | if (start >= extent_end) { | 6006 | if (start >= extent_end) { |
5994 | path->slots[0]++; | 6007 | path->slots[0]++; |
5995 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | 6008 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { |
@@ -6249,7 +6262,7 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag | |||
6249 | /* adjust the range_start to make sure it doesn't | 6262 | /* adjust the range_start to make sure it doesn't |
6250 | * go backwards from the start they passed in | 6263 | * go backwards from the start they passed in |
6251 | */ | 6264 | */ |
6252 | range_start = max(start,range_start); | 6265 | range_start = max(start, range_start); |
6253 | found = found_end - range_start; | 6266 | found = found_end - range_start; |
6254 | 6267 | ||
6255 | if (found > 0) { | 6268 | if (found > 0) { |
@@ -7053,7 +7066,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
7053 | } | 7066 | } |
7054 | } else { | 7067 | } else { |
7055 | submit_len += bvec->bv_len; | 7068 | submit_len += bvec->bv_len; |
7056 | nr_pages ++; | 7069 | nr_pages++; |
7057 | bvec++; | 7070 | bvec++; |
7058 | } | 7071 | } |
7059 | } | 7072 | } |
@@ -7222,7 +7235,9 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7222 | * outstanding dirty pages are on disk. | 7235 | * outstanding dirty pages are on disk. |
7223 | */ | 7236 | */ |
7224 | count = iov_length(iov, nr_segs); | 7237 | count = iov_length(iov, nr_segs); |
7225 | btrfs_wait_ordered_range(inode, offset, count); | 7238 | ret = btrfs_wait_ordered_range(inode, offset, count); |
7239 | if (ret) | ||
7240 | return ret; | ||
7226 | 7241 | ||
7227 | if (rw & WRITE) { | 7242 | if (rw & WRITE) { |
7228 | /* | 7243 | /* |
@@ -7563,7 +7578,10 @@ static int btrfs_truncate(struct inode *inode) | |||
7563 | u64 mask = root->sectorsize - 1; | 7578 | u64 mask = root->sectorsize - 1; |
7564 | u64 min_size = btrfs_calc_trunc_metadata_size(root, 1); | 7579 | u64 min_size = btrfs_calc_trunc_metadata_size(root, 1); |
7565 | 7580 | ||
7566 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); | 7581 | ret = btrfs_wait_ordered_range(inode, inode->i_size & (~mask), |
7582 | (u64)-1); | ||
7583 | if (ret) | ||
7584 | return ret; | ||
7567 | 7585 | ||
7568 | /* | 7586 | /* |
7569 | * Yes ladies and gentelment, this is indeed ugly. The fact is we have | 7587 | * Yes ladies and gentelment, this is indeed ugly. The fact is we have |
@@ -7787,6 +7805,14 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
7787 | return inode; | 7805 | return inode; |
7788 | } | 7806 | } |
7789 | 7807 | ||
7808 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
7809 | void btrfs_test_destroy_inode(struct inode *inode) | ||
7810 | { | ||
7811 | btrfs_drop_extent_cache(inode, 0, (u64)-1, 0); | ||
7812 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); | ||
7813 | } | ||
7814 | #endif | ||
7815 | |||
7790 | static void btrfs_i_callback(struct rcu_head *head) | 7816 | static void btrfs_i_callback(struct rcu_head *head) |
7791 | { | 7817 | { |
7792 | struct inode *inode = container_of(head, struct inode, i_rcu); | 7818 | struct inode *inode = container_of(head, struct inode, i_rcu); |
@@ -7857,8 +7883,7 @@ int btrfs_drop_inode(struct inode *inode) | |||
7857 | return 1; | 7883 | return 1; |
7858 | 7884 | ||
7859 | /* the snap/subvol tree is on deleting */ | 7885 | /* the snap/subvol tree is on deleting */ |
7860 | if (btrfs_root_refs(&root->root_item) == 0 && | 7886 | if (btrfs_root_refs(&root->root_item) == 0) |
7861 | root != root->fs_info->tree_root) | ||
7862 | return 1; | 7887 | return 1; |
7863 | else | 7888 | else |
7864 | return generic_drop_inode(inode); | 7889 | return generic_drop_inode(inode); |
@@ -7995,8 +8020,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
7995 | if (ret == -EEXIST) { | 8020 | if (ret == -EEXIST) { |
7996 | /* we shouldn't get | 8021 | /* we shouldn't get |
7997 | * eexist without a new_inode */ | 8022 | * eexist without a new_inode */ |
7998 | if (!new_inode) { | 8023 | if (WARN_ON(!new_inode)) { |
7999 | WARN_ON(1); | ||
8000 | return ret; | 8024 | return ret; |
8001 | } | 8025 | } |
8002 | } else { | 8026 | } else { |
@@ -8144,18 +8168,24 @@ out_notrans: | |||
8144 | static void btrfs_run_delalloc_work(struct btrfs_work *work) | 8168 | static void btrfs_run_delalloc_work(struct btrfs_work *work) |
8145 | { | 8169 | { |
8146 | struct btrfs_delalloc_work *delalloc_work; | 8170 | struct btrfs_delalloc_work *delalloc_work; |
8171 | struct inode *inode; | ||
8147 | 8172 | ||
8148 | delalloc_work = container_of(work, struct btrfs_delalloc_work, | 8173 | delalloc_work = container_of(work, struct btrfs_delalloc_work, |
8149 | work); | 8174 | work); |
8150 | if (delalloc_work->wait) | 8175 | inode = delalloc_work->inode; |
8151 | btrfs_wait_ordered_range(delalloc_work->inode, 0, (u64)-1); | 8176 | if (delalloc_work->wait) { |
8152 | else | 8177 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
8153 | filemap_flush(delalloc_work->inode->i_mapping); | 8178 | } else { |
8179 | filemap_flush(inode->i_mapping); | ||
8180 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | ||
8181 | &BTRFS_I(inode)->runtime_flags)) | ||
8182 | filemap_flush(inode->i_mapping); | ||
8183 | } | ||
8154 | 8184 | ||
8155 | if (delalloc_work->delay_iput) | 8185 | if (delalloc_work->delay_iput) |
8156 | btrfs_add_delayed_iput(delalloc_work->inode); | 8186 | btrfs_add_delayed_iput(inode); |
8157 | else | 8187 | else |
8158 | iput(delalloc_work->inode); | 8188 | iput(inode); |
8159 | complete(&delalloc_work->completion); | 8189 | complete(&delalloc_work->completion); |
8160 | } | 8190 | } |
8161 | 8191 | ||
@@ -8276,8 +8306,7 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) | |||
8276 | return ret; | 8306 | return ret; |
8277 | } | 8307 | } |
8278 | 8308 | ||
8279 | int btrfs_start_all_delalloc_inodes(struct btrfs_fs_info *fs_info, | 8309 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput) |
8280 | int delay_iput) | ||
8281 | { | 8310 | { |
8282 | struct btrfs_root *root; | 8311 | struct btrfs_root *root; |
8283 | struct list_head splice; | 8312 | struct list_head splice; |
@@ -8337,14 +8366,14 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
8337 | int err; | 8366 | int err; |
8338 | int drop_inode = 0; | 8367 | int drop_inode = 0; |
8339 | u64 objectid; | 8368 | u64 objectid; |
8340 | u64 index = 0 ; | 8369 | u64 index = 0; |
8341 | int name_len; | 8370 | int name_len; |
8342 | int datasize; | 8371 | int datasize; |
8343 | unsigned long ptr; | 8372 | unsigned long ptr; |
8344 | struct btrfs_file_extent_item *ei; | 8373 | struct btrfs_file_extent_item *ei; |
8345 | struct extent_buffer *leaf; | 8374 | struct extent_buffer *leaf; |
8346 | 8375 | ||
8347 | name_len = strlen(symname) + 1; | 8376 | name_len = strlen(symname); |
8348 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) | 8377 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) |
8349 | return -ENAMETOOLONG; | 8378 | return -ENAMETOOLONG; |
8350 | 8379 | ||
@@ -8432,7 +8461,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
8432 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 8461 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
8433 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | 8462 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; |
8434 | inode_set_bytes(inode, name_len); | 8463 | inode_set_bytes(inode, name_len); |
8435 | btrfs_i_size_write(inode, name_len - 1); | 8464 | btrfs_i_size_write(inode, name_len); |
8436 | err = btrfs_update_inode(trans, root, inode); | 8465 | err = btrfs_update_inode(trans, root, inode); |
8437 | if (err) | 8466 | if (err) |
8438 | drop_inode = 1; | 8467 | drop_inode = 1; |
@@ -8491,6 +8520,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
8491 | ins.offset, 0, 0, 0, | 8520 | ins.offset, 0, 0, 0, |
8492 | BTRFS_FILE_EXTENT_PREALLOC); | 8521 | BTRFS_FILE_EXTENT_PREALLOC); |
8493 | if (ret) { | 8522 | if (ret) { |
8523 | btrfs_free_reserved_extent(root, ins.objectid, | ||
8524 | ins.offset); | ||
8494 | btrfs_abort_transaction(trans, root, ret); | 8525 | btrfs_abort_transaction(trans, root, ret); |
8495 | if (own_trans) | 8526 | if (own_trans) |
8496 | btrfs_end_transaction(trans, root); | 8527 | btrfs_end_transaction(trans, root); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9d46f60cb943..1d04b5559e61 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/uuid.h> | 44 | #include <linux/uuid.h> |
45 | #include <linux/btrfs.h> | 45 | #include <linux/btrfs.h> |
46 | #include <linux/uaccess.h> | 46 | #include <linux/uaccess.h> |
47 | #include "compat.h" | ||
48 | #include "ctree.h" | 47 | #include "ctree.h" |
49 | #include "disk-io.h" | 48 | #include "disk-io.h" |
50 | #include "transaction.h" | 49 | #include "transaction.h" |
@@ -369,9 +368,8 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
369 | 368 | ||
370 | int btrfs_is_empty_uuid(u8 *uuid) | 369 | int btrfs_is_empty_uuid(u8 *uuid) |
371 | { | 370 | { |
372 | static char empty_uuid[BTRFS_UUID_SIZE] = {0}; | 371 | BUILD_BUG_ON(BTRFS_UUID_SIZE > PAGE_SIZE); |
373 | 372 | return !memcmp(uuid, empty_zero_page, BTRFS_UUID_SIZE); | |
374 | return !memcmp(uuid, empty_uuid, BTRFS_UUID_SIZE); | ||
375 | } | 373 | } |
376 | 374 | ||
377 | static noinline int create_subvol(struct inode *dir, | 375 | static noinline int create_subvol(struct inode *dir, |
@@ -436,7 +434,7 @@ static noinline int create_subvol(struct inode *dir, | |||
436 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); | 434 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); |
437 | btrfs_set_header_owner(leaf, objectid); | 435 | btrfs_set_header_owner(leaf, objectid); |
438 | 436 | ||
439 | write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(leaf), | 437 | write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(), |
440 | BTRFS_FSID_SIZE); | 438 | BTRFS_FSID_SIZE); |
441 | write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, | 439 | write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, |
442 | btrfs_header_chunk_tree_uuid(leaf), | 440 | btrfs_header_chunk_tree_uuid(leaf), |
@@ -574,7 +572,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, | |||
574 | if (ret) | 572 | if (ret) |
575 | return ret; | 573 | return ret; |
576 | 574 | ||
577 | btrfs_wait_ordered_extents(root); | 575 | btrfs_wait_ordered_extents(root, -1); |
578 | 576 | ||
579 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); | 577 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); |
580 | if (!pending_snapshot) | 578 | if (!pending_snapshot) |
@@ -688,7 +686,7 @@ static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode) | |||
688 | * nfs_async_unlink(). | 686 | * nfs_async_unlink(). |
689 | */ | 687 | */ |
690 | 688 | ||
691 | static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir) | 689 | static int btrfs_may_delete(struct inode *dir, struct dentry *victim, int isdir) |
692 | { | 690 | { |
693 | int error; | 691 | int error; |
694 | 692 | ||
@@ -842,7 +840,6 @@ static int find_new_extents(struct btrfs_root *root, | |||
842 | { | 840 | { |
843 | struct btrfs_path *path; | 841 | struct btrfs_path *path; |
844 | struct btrfs_key min_key; | 842 | struct btrfs_key min_key; |
845 | struct btrfs_key max_key; | ||
846 | struct extent_buffer *leaf; | 843 | struct extent_buffer *leaf; |
847 | struct btrfs_file_extent_item *extent; | 844 | struct btrfs_file_extent_item *extent; |
848 | int type; | 845 | int type; |
@@ -857,15 +854,10 @@ static int find_new_extents(struct btrfs_root *root, | |||
857 | min_key.type = BTRFS_EXTENT_DATA_KEY; | 854 | min_key.type = BTRFS_EXTENT_DATA_KEY; |
858 | min_key.offset = *off; | 855 | min_key.offset = *off; |
859 | 856 | ||
860 | max_key.objectid = ino; | ||
861 | max_key.type = (u8)-1; | ||
862 | max_key.offset = (u64)-1; | ||
863 | |||
864 | path->keep_locks = 1; | 857 | path->keep_locks = 1; |
865 | 858 | ||
866 | while(1) { | 859 | while (1) { |
867 | ret = btrfs_search_forward(root, &min_key, &max_key, | 860 | ret = btrfs_search_forward(root, &min_key, path, newer_than); |
868 | path, newer_than); | ||
869 | if (ret != 0) | 861 | if (ret != 0) |
870 | goto none; | 862 | goto none; |
871 | if (min_key.objectid != ino) | 863 | if (min_key.objectid != ino) |
@@ -1206,7 +1198,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1206 | ra = &file->f_ra; | 1198 | ra = &file->f_ra; |
1207 | } | 1199 | } |
1208 | 1200 | ||
1209 | pages = kmalloc(sizeof(struct page *) * max_cluster, | 1201 | pages = kmalloc_array(max_cluster, sizeof(struct page *), |
1210 | GFP_NOFS); | 1202 | GFP_NOFS); |
1211 | if (!pages) { | 1203 | if (!pages) { |
1212 | ret = -ENOMEM; | 1204 | ret = -ENOMEM; |
@@ -1893,7 +1885,6 @@ static noinline int search_ioctl(struct inode *inode, | |||
1893 | { | 1885 | { |
1894 | struct btrfs_root *root; | 1886 | struct btrfs_root *root; |
1895 | struct btrfs_key key; | 1887 | struct btrfs_key key; |
1896 | struct btrfs_key max_key; | ||
1897 | struct btrfs_path *path; | 1888 | struct btrfs_path *path; |
1898 | struct btrfs_ioctl_search_key *sk = &args->key; | 1889 | struct btrfs_ioctl_search_key *sk = &args->key; |
1899 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; | 1890 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; |
@@ -1925,15 +1916,10 @@ static noinline int search_ioctl(struct inode *inode, | |||
1925 | key.type = sk->min_type; | 1916 | key.type = sk->min_type; |
1926 | key.offset = sk->min_offset; | 1917 | key.offset = sk->min_offset; |
1927 | 1918 | ||
1928 | max_key.objectid = sk->max_objectid; | ||
1929 | max_key.type = sk->max_type; | ||
1930 | max_key.offset = sk->max_offset; | ||
1931 | |||
1932 | path->keep_locks = 1; | 1919 | path->keep_locks = 1; |
1933 | 1920 | ||
1934 | while(1) { | 1921 | while (1) { |
1935 | ret = btrfs_search_forward(root, &key, &max_key, path, | 1922 | ret = btrfs_search_forward(root, &key, path, sk->min_transid); |
1936 | sk->min_transid); | ||
1937 | if (ret != 0) { | 1923 | if (ret != 0) { |
1938 | if (ret > 0) | 1924 | if (ret > 0) |
1939 | ret = 0; | 1925 | ret = 0; |
@@ -2018,7 +2004,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
2018 | key.type = BTRFS_INODE_REF_KEY; | 2004 | key.type = BTRFS_INODE_REF_KEY; |
2019 | key.offset = (u64)-1; | 2005 | key.offset = (u64)-1; |
2020 | 2006 | ||
2021 | while(1) { | 2007 | while (1) { |
2022 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 2008 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
2023 | if (ret < 0) | 2009 | if (ret < 0) |
2024 | goto out; | 2010 | goto out; |
@@ -2047,7 +2033,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
2047 | } | 2033 | } |
2048 | 2034 | ||
2049 | *(ptr + len) = '/'; | 2035 | *(ptr + len) = '/'; |
2050 | read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len); | 2036 | read_extent_buffer(l, ptr, (unsigned long)(iref + 1), len); |
2051 | 2037 | ||
2052 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) | 2038 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) |
2053 | break; | 2039 | break; |
@@ -2058,7 +2044,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
2058 | dirid = key.objectid; | 2044 | dirid = key.objectid; |
2059 | } | 2045 | } |
2060 | memmove(name, ptr, total_len); | 2046 | memmove(name, ptr, total_len); |
2061 | name[total_len]='\0'; | 2047 | name[total_len] = '\0'; |
2062 | ret = 0; | 2048 | ret = 0; |
2063 | out: | 2049 | out: |
2064 | btrfs_free_path(path); | 2050 | btrfs_free_path(path); |
@@ -2144,7 +2130,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2144 | 2130 | ||
2145 | inode = dentry->d_inode; | 2131 | inode = dentry->d_inode; |
2146 | dest = BTRFS_I(inode)->root; | 2132 | dest = BTRFS_I(inode)->root; |
2147 | if (!capable(CAP_SYS_ADMIN)){ | 2133 | if (!capable(CAP_SYS_ADMIN)) { |
2148 | /* | 2134 | /* |
2149 | * Regular user. Only allow this with a special mount | 2135 | * Regular user. Only allow this with a special mount |
2150 | * option, when the user has write+exec access to the | 2136 | * option, when the user has write+exec access to the |
@@ -2727,15 +2713,10 @@ static long btrfs_ioctl_file_extent_same(struct file *file, | |||
2727 | size = sizeof(tmp) + | 2713 | size = sizeof(tmp) + |
2728 | tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info); | 2714 | tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info); |
2729 | 2715 | ||
2730 | same = kmalloc(size, GFP_NOFS); | 2716 | same = memdup_user((struct btrfs_ioctl_same_args __user *)argp, size); |
2731 | if (!same) { | ||
2732 | ret = -EFAULT; | ||
2733 | goto out; | ||
2734 | } | ||
2735 | 2717 | ||
2736 | if (copy_from_user(same, | 2718 | if (IS_ERR(same)) { |
2737 | (struct btrfs_ioctl_same_args __user *)argp, size)) { | 2719 | ret = PTR_ERR(same); |
2738 | ret = -EFAULT; | ||
2739 | goto out; | 2720 | goto out; |
2740 | } | 2721 | } |
2741 | 2722 | ||
@@ -3679,9 +3660,10 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
3679 | 3660 | ||
3680 | switch (p->cmd) { | 3661 | switch (p->cmd) { |
3681 | case BTRFS_IOCTL_DEV_REPLACE_CMD_START: | 3662 | case BTRFS_IOCTL_DEV_REPLACE_CMD_START: |
3682 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3663 | if (root->fs_info->sb->s_flags & MS_RDONLY) { |
3683 | return -EROFS; | 3664 | ret = -EROFS; |
3684 | 3665 | goto out; | |
3666 | } | ||
3685 | if (atomic_xchg( | 3667 | if (atomic_xchg( |
3686 | &root->fs_info->mutually_exclusive_operation_running, | 3668 | &root->fs_info->mutually_exclusive_operation_running, |
3687 | 1)) { | 3669 | 1)) { |
@@ -3707,7 +3689,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
3707 | 3689 | ||
3708 | if (copy_to_user(arg, p, sizeof(*p))) | 3690 | if (copy_to_user(arg, p, sizeof(*p))) |
3709 | ret = -EFAULT; | 3691 | ret = -EFAULT; |
3710 | 3692 | out: | |
3711 | kfree(p); | 3693 | kfree(p); |
3712 | return ret; | 3694 | return ret; |
3713 | } | 3695 | } |
@@ -4557,9 +4539,15 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
4557 | return btrfs_ioctl_logical_to_ino(root, argp); | 4539 | return btrfs_ioctl_logical_to_ino(root, argp); |
4558 | case BTRFS_IOC_SPACE_INFO: | 4540 | case BTRFS_IOC_SPACE_INFO: |
4559 | return btrfs_ioctl_space_info(root, argp); | 4541 | return btrfs_ioctl_space_info(root, argp); |
4560 | case BTRFS_IOC_SYNC: | 4542 | case BTRFS_IOC_SYNC: { |
4561 | btrfs_sync_fs(file->f_dentry->d_sb, 1); | 4543 | int ret; |
4562 | return 0; | 4544 | |
4545 | ret = btrfs_start_delalloc_roots(root->fs_info, 0); | ||
4546 | if (ret) | ||
4547 | return ret; | ||
4548 | ret = btrfs_sync_fs(file->f_dentry->d_sb, 1); | ||
4549 | return ret; | ||
4550 | } | ||
4563 | case BTRFS_IOC_START_SYNC: | 4551 | case BTRFS_IOC_START_SYNC: |
4564 | return btrfs_ioctl_start_sync(root, argp); | 4552 | return btrfs_ioctl_start_sync(root, argp); |
4565 | case BTRFS_IOC_WAIT_SYNC: | 4553 | case BTRFS_IOC_WAIT_SYNC: |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index c702cb62f78a..25a8f3812f14 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -537,7 +537,9 @@ void btrfs_remove_ordered_extent(struct inode *inode, | |||
537 | */ | 537 | */ |
538 | if (RB_EMPTY_ROOT(&tree->tree) && | 538 | if (RB_EMPTY_ROOT(&tree->tree) && |
539 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { | 539 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { |
540 | spin_lock(&root->fs_info->ordered_root_lock); | ||
540 | list_del_init(&BTRFS_I(inode)->ordered_operations); | 541 | list_del_init(&BTRFS_I(inode)->ordered_operations); |
542 | spin_unlock(&root->fs_info->ordered_root_lock); | ||
541 | } | 543 | } |
542 | 544 | ||
543 | if (!root->nr_ordered_extents) { | 545 | if (!root->nr_ordered_extents) { |
@@ -563,10 +565,11 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work) | |||
563 | * wait for all the ordered extents in a root. This is done when balancing | 565 | * wait for all the ordered extents in a root. This is done when balancing |
564 | * space between drives. | 566 | * space between drives. |
565 | */ | 567 | */ |
566 | void btrfs_wait_ordered_extents(struct btrfs_root *root) | 568 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) |
567 | { | 569 | { |
568 | struct list_head splice, works; | 570 | struct list_head splice, works; |
569 | struct btrfs_ordered_extent *ordered, *next; | 571 | struct btrfs_ordered_extent *ordered, *next; |
572 | int count = 0; | ||
570 | 573 | ||
571 | INIT_LIST_HEAD(&splice); | 574 | INIT_LIST_HEAD(&splice); |
572 | INIT_LIST_HEAD(&works); | 575 | INIT_LIST_HEAD(&works); |
@@ -574,7 +577,7 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root) | |||
574 | mutex_lock(&root->fs_info->ordered_operations_mutex); | 577 | mutex_lock(&root->fs_info->ordered_operations_mutex); |
575 | spin_lock(&root->ordered_extent_lock); | 578 | spin_lock(&root->ordered_extent_lock); |
576 | list_splice_init(&root->ordered_extents, &splice); | 579 | list_splice_init(&root->ordered_extents, &splice); |
577 | while (!list_empty(&splice)) { | 580 | while (!list_empty(&splice) && nr) { |
578 | ordered = list_first_entry(&splice, struct btrfs_ordered_extent, | 581 | ordered = list_first_entry(&splice, struct btrfs_ordered_extent, |
579 | root_extent_list); | 582 | root_extent_list); |
580 | list_move_tail(&ordered->root_extent_list, | 583 | list_move_tail(&ordered->root_extent_list, |
@@ -589,7 +592,11 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root) | |||
589 | 592 | ||
590 | cond_resched(); | 593 | cond_resched(); |
591 | spin_lock(&root->ordered_extent_lock); | 594 | spin_lock(&root->ordered_extent_lock); |
595 | if (nr != -1) | ||
596 | nr--; | ||
597 | count++; | ||
592 | } | 598 | } |
599 | list_splice_tail(&splice, &root->ordered_extents); | ||
593 | spin_unlock(&root->ordered_extent_lock); | 600 | spin_unlock(&root->ordered_extent_lock); |
594 | 601 | ||
595 | list_for_each_entry_safe(ordered, next, &works, work_list) { | 602 | list_for_each_entry_safe(ordered, next, &works, work_list) { |
@@ -599,18 +606,21 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root) | |||
599 | cond_resched(); | 606 | cond_resched(); |
600 | } | 607 | } |
601 | mutex_unlock(&root->fs_info->ordered_operations_mutex); | 608 | mutex_unlock(&root->fs_info->ordered_operations_mutex); |
609 | |||
610 | return count; | ||
602 | } | 611 | } |
603 | 612 | ||
604 | void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info) | 613 | void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr) |
605 | { | 614 | { |
606 | struct btrfs_root *root; | 615 | struct btrfs_root *root; |
607 | struct list_head splice; | 616 | struct list_head splice; |
617 | int done; | ||
608 | 618 | ||
609 | INIT_LIST_HEAD(&splice); | 619 | INIT_LIST_HEAD(&splice); |
610 | 620 | ||
611 | spin_lock(&fs_info->ordered_root_lock); | 621 | spin_lock(&fs_info->ordered_root_lock); |
612 | list_splice_init(&fs_info->ordered_roots, &splice); | 622 | list_splice_init(&fs_info->ordered_roots, &splice); |
613 | while (!list_empty(&splice)) { | 623 | while (!list_empty(&splice) && nr) { |
614 | root = list_first_entry(&splice, struct btrfs_root, | 624 | root = list_first_entry(&splice, struct btrfs_root, |
615 | ordered_root); | 625 | ordered_root); |
616 | root = btrfs_grab_fs_root(root); | 626 | root = btrfs_grab_fs_root(root); |
@@ -619,10 +629,14 @@ void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info) | |||
619 | &fs_info->ordered_roots); | 629 | &fs_info->ordered_roots); |
620 | spin_unlock(&fs_info->ordered_root_lock); | 630 | spin_unlock(&fs_info->ordered_root_lock); |
621 | 631 | ||
622 | btrfs_wait_ordered_extents(root); | 632 | done = btrfs_wait_ordered_extents(root, nr); |
623 | btrfs_put_fs_root(root); | 633 | btrfs_put_fs_root(root); |
624 | 634 | ||
625 | spin_lock(&fs_info->ordered_root_lock); | 635 | spin_lock(&fs_info->ordered_root_lock); |
636 | if (nr != -1) { | ||
637 | nr -= done; | ||
638 | WARN_ON(nr < 0); | ||
639 | } | ||
626 | } | 640 | } |
627 | spin_unlock(&fs_info->ordered_root_lock); | 641 | spin_unlock(&fs_info->ordered_root_lock); |
628 | } | 642 | } |
@@ -734,8 +748,9 @@ void btrfs_start_ordered_extent(struct inode *inode, | |||
734 | /* | 748 | /* |
735 | * Used to wait on ordered extents across a large range of bytes. | 749 | * Used to wait on ordered extents across a large range of bytes. |
736 | */ | 750 | */ |
737 | void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | 751 | int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) |
738 | { | 752 | { |
753 | int ret = 0; | ||
739 | u64 end; | 754 | u64 end; |
740 | u64 orig_end; | 755 | u64 orig_end; |
741 | struct btrfs_ordered_extent *ordered; | 756 | struct btrfs_ordered_extent *ordered; |
@@ -751,8 +766,9 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
751 | /* start IO across the range first to instantiate any delalloc | 766 | /* start IO across the range first to instantiate any delalloc |
752 | * extents | 767 | * extents |
753 | */ | 768 | */ |
754 | filemap_fdatawrite_range(inode->i_mapping, start, orig_end); | 769 | ret = filemap_fdatawrite_range(inode->i_mapping, start, orig_end); |
755 | 770 | if (ret) | |
771 | return ret; | ||
756 | /* | 772 | /* |
757 | * So with compression we will find and lock a dirty page and clear the | 773 | * So with compression we will find and lock a dirty page and clear the |
758 | * first one as dirty, setup an async extent, and immediately return | 774 | * first one as dirty, setup an async extent, and immediately return |
@@ -768,10 +784,15 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
768 | * right and you are wrong. | 784 | * right and you are wrong. |
769 | */ | 785 | */ |
770 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | 786 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, |
771 | &BTRFS_I(inode)->runtime_flags)) | 787 | &BTRFS_I(inode)->runtime_flags)) { |
772 | filemap_fdatawrite_range(inode->i_mapping, start, orig_end); | 788 | ret = filemap_fdatawrite_range(inode->i_mapping, start, |
773 | 789 | orig_end); | |
774 | filemap_fdatawait_range(inode->i_mapping, start, orig_end); | 790 | if (ret) |
791 | return ret; | ||
792 | } | ||
793 | ret = filemap_fdatawait_range(inode->i_mapping, start, orig_end); | ||
794 | if (ret) | ||
795 | return ret; | ||
775 | 796 | ||
776 | end = orig_end; | 797 | end = orig_end; |
777 | while (1) { | 798 | while (1) { |
@@ -788,11 +809,14 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
788 | } | 809 | } |
789 | btrfs_start_ordered_extent(inode, ordered, 1); | 810 | btrfs_start_ordered_extent(inode, ordered, 1); |
790 | end = ordered->file_offset; | 811 | end = ordered->file_offset; |
812 | if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) | ||
813 | ret = -EIO; | ||
791 | btrfs_put_ordered_extent(ordered); | 814 | btrfs_put_ordered_extent(ordered); |
792 | if (end == 0 || end == start) | 815 | if (ret || end == 0 || end == start) |
793 | break; | 816 | break; |
794 | end--; | 817 | end--; |
795 | } | 818 | } |
819 | return ret; | ||
796 | } | 820 | } |
797 | 821 | ||
798 | /* | 822 | /* |
@@ -1076,7 +1100,7 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, | |||
1076 | * if this file hasn't been changed since the last transaction | 1100 | * if this file hasn't been changed since the last transaction |
1077 | * commit, we can safely return without doing anything | 1101 | * commit, we can safely return without doing anything |
1078 | */ | 1102 | */ |
1079 | if (last_mod < root->fs_info->last_trans_committed) | 1103 | if (last_mod <= root->fs_info->last_trans_committed) |
1080 | return; | 1104 | return; |
1081 | 1105 | ||
1082 | spin_lock(&root->fs_info->ordered_root_lock); | 1106 | spin_lock(&root->fs_info->ordered_root_lock); |
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 0c0b35612d7a..9b0450f7ac20 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h | |||
@@ -180,7 +180,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, | |||
180 | u64 file_offset); | 180 | u64 file_offset); |
181 | void btrfs_start_ordered_extent(struct inode *inode, | 181 | void btrfs_start_ordered_extent(struct inode *inode, |
182 | struct btrfs_ordered_extent *entry, int wait); | 182 | struct btrfs_ordered_extent *entry, int wait); |
183 | void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len); | 183 | int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len); |
184 | struct btrfs_ordered_extent * | 184 | struct btrfs_ordered_extent * |
185 | btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset); | 185 | btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset); |
186 | struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode, | 186 | struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode, |
@@ -195,8 +195,8 @@ int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans, | |||
195 | void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, | 195 | void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, |
196 | struct btrfs_root *root, | 196 | struct btrfs_root *root, |
197 | struct inode *inode); | 197 | struct inode *inode); |
198 | void btrfs_wait_ordered_extents(struct btrfs_root *root); | 198 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr); |
199 | void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info); | 199 | void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr); |
200 | void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode); | 200 | void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode); |
201 | void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid); | 201 | void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid); |
202 | void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid); | 202 | void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid); |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 0088bedc8631..417053b17181 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -193,7 +193,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
193 | btrfs_info(root->fs_info, "leaf %llu total ptrs %d free space %d", | 193 | btrfs_info(root->fs_info, "leaf %llu total ptrs %d free space %d", |
194 | btrfs_header_bytenr(l), nr, btrfs_leaf_free_space(root, l)); | 194 | btrfs_header_bytenr(l), nr, btrfs_leaf_free_space(root, l)); |
195 | for (i = 0 ; i < nr ; i++) { | 195 | for (i = 0 ; i < nr ; i++) { |
196 | item = btrfs_item_nr(l, i); | 196 | item = btrfs_item_nr(i); |
197 | btrfs_item_key_to_cpu(l, &key, i); | 197 | btrfs_item_key_to_cpu(l, &key, i); |
198 | type = btrfs_key_type(&key); | 198 | type = btrfs_key_type(&key); |
199 | printk(KERN_INFO "\titem %d key (%llu %u %llu) itemoff %d " | 199 | printk(KERN_INFO "\titem %d key (%llu %u %llu) itemoff %d " |
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index d0ecfbd9cc9f..24ac21840a9a 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/raid/xor.h> | 33 | #include <linux/raid/xor.h> |
34 | #include <linux/vmalloc.h> | 34 | #include <linux/vmalloc.h> |
35 | #include <asm/div64.h> | 35 | #include <asm/div64.h> |
36 | #include "compat.h" | ||
37 | #include "ctree.h" | 36 | #include "ctree.h" |
38 | #include "extent_map.h" | 37 | #include "extent_map.h" |
39 | #include "disk-io.h" | 38 | #include "disk-io.h" |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 4a355726151e..ce459a7cb16d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1383,6 +1383,7 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans, | |||
1383 | { | 1383 | { |
1384 | struct btrfs_root *reloc_root; | 1384 | struct btrfs_root *reloc_root; |
1385 | struct reloc_control *rc = root->fs_info->reloc_ctl; | 1385 | struct reloc_control *rc = root->fs_info->reloc_ctl; |
1386 | struct btrfs_block_rsv *rsv; | ||
1386 | int clear_rsv = 0; | 1387 | int clear_rsv = 0; |
1387 | int ret; | 1388 | int ret; |
1388 | 1389 | ||
@@ -1396,13 +1397,14 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans, | |||
1396 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) | 1397 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) |
1397 | return 0; | 1398 | return 0; |
1398 | 1399 | ||
1399 | if (!trans->block_rsv) { | 1400 | if (!trans->reloc_reserved) { |
1401 | rsv = trans->block_rsv; | ||
1400 | trans->block_rsv = rc->block_rsv; | 1402 | trans->block_rsv = rc->block_rsv; |
1401 | clear_rsv = 1; | 1403 | clear_rsv = 1; |
1402 | } | 1404 | } |
1403 | reloc_root = create_reloc_root(trans, root, root->root_key.objectid); | 1405 | reloc_root = create_reloc_root(trans, root, root->root_key.objectid); |
1404 | if (clear_rsv) | 1406 | if (clear_rsv) |
1405 | trans->block_rsv = NULL; | 1407 | trans->block_rsv = rsv; |
1406 | 1408 | ||
1407 | ret = __add_reloc_root(reloc_root); | 1409 | ret = __add_reloc_root(reloc_root); |
1408 | BUG_ON(ret < 0); | 1410 | BUG_ON(ret < 0); |
@@ -1775,8 +1777,7 @@ again: | |||
1775 | new_ptr_gen = 0; | 1777 | new_ptr_gen = 0; |
1776 | } | 1778 | } |
1777 | 1779 | ||
1778 | if (new_bytenr > 0 && new_bytenr == old_bytenr) { | 1780 | if (WARN_ON(new_bytenr > 0 && new_bytenr == old_bytenr)) { |
1779 | WARN_ON(1); | ||
1780 | ret = level; | 1781 | ret = level; |
1781 | break; | 1782 | break; |
1782 | } | 1783 | } |
@@ -2058,7 +2059,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, | |||
2058 | LIST_HEAD(inode_list); | 2059 | LIST_HEAD(inode_list); |
2059 | struct btrfs_key key; | 2060 | struct btrfs_key key; |
2060 | struct btrfs_key next_key; | 2061 | struct btrfs_key next_key; |
2061 | struct btrfs_trans_handle *trans; | 2062 | struct btrfs_trans_handle *trans = NULL; |
2062 | struct btrfs_root *reloc_root; | 2063 | struct btrfs_root *reloc_root; |
2063 | struct btrfs_root_item *root_item; | 2064 | struct btrfs_root_item *root_item; |
2064 | struct btrfs_path *path; | 2065 | struct btrfs_path *path; |
@@ -2107,18 +2108,19 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, | |||
2107 | memset(&next_key, 0, sizeof(next_key)); | 2108 | memset(&next_key, 0, sizeof(next_key)); |
2108 | 2109 | ||
2109 | while (1) { | 2110 | while (1) { |
2110 | trans = btrfs_start_transaction(root, 0); | ||
2111 | BUG_ON(IS_ERR(trans)); | ||
2112 | trans->block_rsv = rc->block_rsv; | ||
2113 | |||
2114 | ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved, | 2111 | ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved, |
2115 | BTRFS_RESERVE_FLUSH_ALL); | 2112 | BTRFS_RESERVE_FLUSH_ALL); |
2116 | if (ret) { | 2113 | if (ret) { |
2117 | BUG_ON(ret != -EAGAIN); | 2114 | err = ret; |
2118 | ret = btrfs_commit_transaction(trans, root); | 2115 | goto out; |
2119 | BUG_ON(ret); | ||
2120 | continue; | ||
2121 | } | 2116 | } |
2117 | trans = btrfs_start_transaction(root, 0); | ||
2118 | if (IS_ERR(trans)) { | ||
2119 | err = PTR_ERR(trans); | ||
2120 | trans = NULL; | ||
2121 | goto out; | ||
2122 | } | ||
2123 | trans->block_rsv = rc->block_rsv; | ||
2122 | 2124 | ||
2123 | replaced = 0; | 2125 | replaced = 0; |
2124 | max_level = level; | 2126 | max_level = level; |
@@ -2164,6 +2166,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, | |||
2164 | root_item->drop_level = level; | 2166 | root_item->drop_level = level; |
2165 | 2167 | ||
2166 | btrfs_end_transaction_throttle(trans, root); | 2168 | btrfs_end_transaction_throttle(trans, root); |
2169 | trans = NULL; | ||
2167 | 2170 | ||
2168 | btrfs_btree_balance_dirty(root); | 2171 | btrfs_btree_balance_dirty(root); |
2169 | 2172 | ||
@@ -2192,7 +2195,8 @@ out: | |||
2192 | btrfs_update_reloc_root(trans, root); | 2195 | btrfs_update_reloc_root(trans, root); |
2193 | } | 2196 | } |
2194 | 2197 | ||
2195 | btrfs_end_transaction_throttle(trans, root); | 2198 | if (trans) |
2199 | btrfs_end_transaction_throttle(trans, root); | ||
2196 | 2200 | ||
2197 | btrfs_btree_balance_dirty(root); | 2201 | btrfs_btree_balance_dirty(root); |
2198 | 2202 | ||
@@ -3258,7 +3262,7 @@ static int add_tree_block(struct reloc_control *rc, | |||
3258 | struct rb_node *rb_node; | 3262 | struct rb_node *rb_node; |
3259 | u32 item_size; | 3263 | u32 item_size; |
3260 | int level = -1; | 3264 | int level = -1; |
3261 | int generation; | 3265 | u64 generation; |
3262 | 3266 | ||
3263 | eb = path->nodes[0]; | 3267 | eb = path->nodes[0]; |
3264 | item_size = btrfs_item_size_nr(eb, path->slots[0]); | 3268 | item_size = btrfs_item_size_nr(eb, path->slots[0]); |
@@ -3407,7 +3411,6 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info, | |||
3407 | struct inode *inode, u64 ino) | 3411 | struct inode *inode, u64 ino) |
3408 | { | 3412 | { |
3409 | struct btrfs_key key; | 3413 | struct btrfs_key key; |
3410 | struct btrfs_path *path; | ||
3411 | struct btrfs_root *root = fs_info->tree_root; | 3414 | struct btrfs_root *root = fs_info->tree_root; |
3412 | struct btrfs_trans_handle *trans; | 3415 | struct btrfs_trans_handle *trans; |
3413 | int ret = 0; | 3416 | int ret = 0; |
@@ -3432,22 +3435,14 @@ truncate: | |||
3432 | if (ret) | 3435 | if (ret) |
3433 | goto out; | 3436 | goto out; |
3434 | 3437 | ||
3435 | path = btrfs_alloc_path(); | ||
3436 | if (!path) { | ||
3437 | ret = -ENOMEM; | ||
3438 | goto out; | ||
3439 | } | ||
3440 | |||
3441 | trans = btrfs_join_transaction(root); | 3438 | trans = btrfs_join_transaction(root); |
3442 | if (IS_ERR(trans)) { | 3439 | if (IS_ERR(trans)) { |
3443 | btrfs_free_path(path); | ||
3444 | ret = PTR_ERR(trans); | 3440 | ret = PTR_ERR(trans); |
3445 | goto out; | 3441 | goto out; |
3446 | } | 3442 | } |
3447 | 3443 | ||
3448 | ret = btrfs_truncate_free_space_cache(root, trans, path, inode); | 3444 | ret = btrfs_truncate_free_space_cache(root, trans, inode); |
3449 | 3445 | ||
3450 | btrfs_free_path(path); | ||
3451 | btrfs_end_transaction(trans, root); | 3446 | btrfs_end_transaction(trans, root); |
3452 | btrfs_btree_balance_dirty(root); | 3447 | btrfs_btree_balance_dirty(root); |
3453 | out: | 3448 | out: |
@@ -3549,10 +3544,8 @@ static int find_data_references(struct reloc_control *rc, | |||
3549 | err = ret; | 3544 | err = ret; |
3550 | goto out; | 3545 | goto out; |
3551 | } | 3546 | } |
3552 | if (ret > 0) { | 3547 | if (WARN_ON(ret > 0)) |
3553 | WARN_ON(1); | ||
3554 | goto out; | 3548 | goto out; |
3555 | } | ||
3556 | 3549 | ||
3557 | leaf = path->nodes[0]; | 3550 | leaf = path->nodes[0]; |
3558 | nritems = btrfs_header_nritems(leaf); | 3551 | nritems = btrfs_header_nritems(leaf); |
@@ -3572,11 +3565,9 @@ static int find_data_references(struct reloc_control *rc, | |||
3572 | } | 3565 | } |
3573 | 3566 | ||
3574 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | 3567 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
3575 | if (key.objectid != ref_objectid || | 3568 | if (WARN_ON(key.objectid != ref_objectid || |
3576 | key.type != BTRFS_EXTENT_DATA_KEY) { | 3569 | key.type != BTRFS_EXTENT_DATA_KEY)) |
3577 | WARN_ON(1); | ||
3578 | break; | 3570 | break; |
3579 | } | ||
3580 | 3571 | ||
3581 | fi = btrfs_item_ptr(leaf, path->slots[0], | 3572 | fi = btrfs_item_ptr(leaf, path->slots[0], |
3582 | struct btrfs_file_extent_item); | 3573 | struct btrfs_file_extent_item); |
@@ -4001,16 +3992,6 @@ restart: | |||
4001 | } | 3992 | } |
4002 | } | 3993 | } |
4003 | 3994 | ||
4004 | ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5); | ||
4005 | if (ret < 0) { | ||
4006 | if (ret != -ENOSPC) { | ||
4007 | err = ret; | ||
4008 | WARN_ON(1); | ||
4009 | break; | ||
4010 | } | ||
4011 | rc->commit_transaction = 1; | ||
4012 | } | ||
4013 | |||
4014 | if (rc->commit_transaction) { | 3995 | if (rc->commit_transaction) { |
4015 | rc->commit_transaction = 0; | 3996 | rc->commit_transaction = 0; |
4016 | ret = btrfs_commit_transaction(trans, rc->extent_root); | 3997 | ret = btrfs_commit_transaction(trans, rc->extent_root); |
@@ -4241,12 +4222,12 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) | |||
4241 | printk(KERN_INFO "btrfs: relocating block group %llu flags %llu\n", | 4222 | printk(KERN_INFO "btrfs: relocating block group %llu flags %llu\n", |
4242 | rc->block_group->key.objectid, rc->block_group->flags); | 4223 | rc->block_group->key.objectid, rc->block_group->flags); |
4243 | 4224 | ||
4244 | ret = btrfs_start_all_delalloc_inodes(fs_info, 0); | 4225 | ret = btrfs_start_delalloc_roots(fs_info, 0); |
4245 | if (ret < 0) { | 4226 | if (ret < 0) { |
4246 | err = ret; | 4227 | err = ret; |
4247 | goto out; | 4228 | goto out; |
4248 | } | 4229 | } |
4249 | btrfs_wait_all_ordered_extents(fs_info); | 4230 | btrfs_wait_ordered_roots(fs_info, -1); |
4250 | 4231 | ||
4251 | while (1) { | 4232 | while (1) { |
4252 | mutex_lock(&fs_info->cleaner_mutex); | 4233 | mutex_lock(&fs_info->cleaner_mutex); |
@@ -4264,7 +4245,12 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) | |||
4264 | rc->extents_found); | 4245 | rc->extents_found); |
4265 | 4246 | ||
4266 | if (rc->stage == MOVE_DATA_EXTENTS && rc->found_file_extent) { | 4247 | if (rc->stage == MOVE_DATA_EXTENTS && rc->found_file_extent) { |
4267 | btrfs_wait_ordered_range(rc->data_inode, 0, (u64)-1); | 4248 | ret = btrfs_wait_ordered_range(rc->data_inode, 0, |
4249 | (u64)-1); | ||
4250 | if (ret) { | ||
4251 | err = ret; | ||
4252 | goto out; | ||
4253 | } | ||
4268 | invalidate_mapping_pages(rc->data_inode->i_mapping, | 4254 | invalidate_mapping_pages(rc->data_inode->i_mapping, |
4269 | 0, -1); | 4255 | 0, -1); |
4270 | rc->stage = UPDATE_DATA_PTRS; | 4256 | rc->stage = UPDATE_DATA_PTRS; |
@@ -4481,6 +4467,7 @@ int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len) | |||
4481 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4467 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4482 | int ret; | 4468 | int ret; |
4483 | u64 disk_bytenr; | 4469 | u64 disk_bytenr; |
4470 | u64 new_bytenr; | ||
4484 | LIST_HEAD(list); | 4471 | LIST_HEAD(list); |
4485 | 4472 | ||
4486 | ordered = btrfs_lookup_ordered_extent(inode, file_pos); | 4473 | ordered = btrfs_lookup_ordered_extent(inode, file_pos); |
@@ -4492,13 +4479,24 @@ int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len) | |||
4492 | if (ret) | 4479 | if (ret) |
4493 | goto out; | 4480 | goto out; |
4494 | 4481 | ||
4495 | disk_bytenr = ordered->start; | ||
4496 | while (!list_empty(&list)) { | 4482 | while (!list_empty(&list)) { |
4497 | sums = list_entry(list.next, struct btrfs_ordered_sum, list); | 4483 | sums = list_entry(list.next, struct btrfs_ordered_sum, list); |
4498 | list_del_init(&sums->list); | 4484 | list_del_init(&sums->list); |
4499 | 4485 | ||
4500 | sums->bytenr = disk_bytenr; | 4486 | /* |
4501 | disk_bytenr += sums->len; | 4487 | * We need to offset the new_bytenr based on where the csum is. |
4488 | * We need to do this because we will read in entire prealloc | ||
4489 | * extents but we may have written to say the middle of the | ||
4490 | * prealloc extent, so we need to make sure the csum goes with | ||
4491 | * the right disk offset. | ||
4492 | * | ||
4493 | * We can do this because the data reloc inode refers strictly | ||
4494 | * to the on disk bytes, so we don't have to worry about | ||
4495 | * disk_len vs real len like with real inodes since it's all | ||
4496 | * disk length. | ||
4497 | */ | ||
4498 | new_bytenr = ordered->start + (sums->bytenr - disk_bytenr); | ||
4499 | sums->bytenr = new_bytenr; | ||
4502 | 4500 | ||
4503 | btrfs_add_ordered_sum(inode, ordered, sums); | 4501 | btrfs_add_ordered_sum(inode, ordered, sums); |
4504 | } | 4502 | } |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index a18e0e23f6a6..2544805544f0 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -2717,8 +2717,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
2717 | mutex_unlock(&fs_info->scrub_lock); | 2717 | mutex_unlock(&fs_info->scrub_lock); |
2718 | wake_up(&fs_info->scrub_pause_wait); | 2718 | wake_up(&fs_info->scrub_pause_wait); |
2719 | 2719 | ||
2720 | dev_replace->cursor_left = dev_replace->cursor_right; | ||
2721 | dev_replace->item_needs_writeback = 1; | ||
2722 | btrfs_put_block_group(cache); | 2720 | btrfs_put_block_group(cache); |
2723 | if (ret) | 2721 | if (ret) |
2724 | break; | 2722 | break; |
@@ -2732,6 +2730,9 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
2732 | break; | 2730 | break; |
2733 | } | 2731 | } |
2734 | 2732 | ||
2733 | dev_replace->cursor_left = dev_replace->cursor_right; | ||
2734 | dev_replace->item_needs_writeback = 1; | ||
2735 | |||
2735 | key.offset = found_key.offset + length; | 2736 | key.offset = found_key.offset + length; |
2736 | btrfs_release_path(path); | 2737 | btrfs_release_path(path); |
2737 | } | 2738 | } |
@@ -2783,7 +2784,6 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, | |||
2783 | { | 2784 | { |
2784 | int ret = 0; | 2785 | int ret = 0; |
2785 | 2786 | ||
2786 | mutex_lock(&fs_info->scrub_lock); | ||
2787 | if (fs_info->scrub_workers_refcnt == 0) { | 2787 | if (fs_info->scrub_workers_refcnt == 0) { |
2788 | if (is_dev_replace) | 2788 | if (is_dev_replace) |
2789 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1, | 2789 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1, |
@@ -2813,21 +2813,17 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, | |||
2813 | } | 2813 | } |
2814 | ++fs_info->scrub_workers_refcnt; | 2814 | ++fs_info->scrub_workers_refcnt; |
2815 | out: | 2815 | out: |
2816 | mutex_unlock(&fs_info->scrub_lock); | ||
2817 | |||
2818 | return ret; | 2816 | return ret; |
2819 | } | 2817 | } |
2820 | 2818 | ||
2821 | static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info) | 2819 | static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info) |
2822 | { | 2820 | { |
2823 | mutex_lock(&fs_info->scrub_lock); | ||
2824 | if (--fs_info->scrub_workers_refcnt == 0) { | 2821 | if (--fs_info->scrub_workers_refcnt == 0) { |
2825 | btrfs_stop_workers(&fs_info->scrub_workers); | 2822 | btrfs_stop_workers(&fs_info->scrub_workers); |
2826 | btrfs_stop_workers(&fs_info->scrub_wr_completion_workers); | 2823 | btrfs_stop_workers(&fs_info->scrub_wr_completion_workers); |
2827 | btrfs_stop_workers(&fs_info->scrub_nocow_workers); | 2824 | btrfs_stop_workers(&fs_info->scrub_nocow_workers); |
2828 | } | 2825 | } |
2829 | WARN_ON(fs_info->scrub_workers_refcnt < 0); | 2826 | WARN_ON(fs_info->scrub_workers_refcnt < 0); |
2830 | mutex_unlock(&fs_info->scrub_lock); | ||
2831 | } | 2827 | } |
2832 | 2828 | ||
2833 | int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | 2829 | int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, |
@@ -2888,23 +2884,18 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
2888 | return -EINVAL; | 2884 | return -EINVAL; |
2889 | } | 2885 | } |
2890 | 2886 | ||
2891 | ret = scrub_workers_get(fs_info, is_dev_replace); | ||
2892 | if (ret) | ||
2893 | return ret; | ||
2894 | 2887 | ||
2895 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | 2888 | mutex_lock(&fs_info->fs_devices->device_list_mutex); |
2896 | dev = btrfs_find_device(fs_info, devid, NULL, NULL); | 2889 | dev = btrfs_find_device(fs_info, devid, NULL, NULL); |
2897 | if (!dev || (dev->missing && !is_dev_replace)) { | 2890 | if (!dev || (dev->missing && !is_dev_replace)) { |
2898 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2891 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
2899 | scrub_workers_put(fs_info); | ||
2900 | return -ENODEV; | 2892 | return -ENODEV; |
2901 | } | 2893 | } |
2902 | mutex_lock(&fs_info->scrub_lock); | ||
2903 | 2894 | ||
2895 | mutex_lock(&fs_info->scrub_lock); | ||
2904 | if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) { | 2896 | if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) { |
2905 | mutex_unlock(&fs_info->scrub_lock); | 2897 | mutex_unlock(&fs_info->scrub_lock); |
2906 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2898 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
2907 | scrub_workers_put(fs_info); | ||
2908 | return -EIO; | 2899 | return -EIO; |
2909 | } | 2900 | } |
2910 | 2901 | ||
@@ -2915,10 +2906,17 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
2915 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | 2906 | btrfs_dev_replace_unlock(&fs_info->dev_replace); |
2916 | mutex_unlock(&fs_info->scrub_lock); | 2907 | mutex_unlock(&fs_info->scrub_lock); |
2917 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2908 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
2918 | scrub_workers_put(fs_info); | ||
2919 | return -EINPROGRESS; | 2909 | return -EINPROGRESS; |
2920 | } | 2910 | } |
2921 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | 2911 | btrfs_dev_replace_unlock(&fs_info->dev_replace); |
2912 | |||
2913 | ret = scrub_workers_get(fs_info, is_dev_replace); | ||
2914 | if (ret) { | ||
2915 | mutex_unlock(&fs_info->scrub_lock); | ||
2916 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
2917 | return ret; | ||
2918 | } | ||
2919 | |||
2922 | sctx = scrub_setup_ctx(dev, is_dev_replace); | 2920 | sctx = scrub_setup_ctx(dev, is_dev_replace); |
2923 | if (IS_ERR(sctx)) { | 2921 | if (IS_ERR(sctx)) { |
2924 | mutex_unlock(&fs_info->scrub_lock); | 2922 | mutex_unlock(&fs_info->scrub_lock); |
@@ -2931,13 +2929,15 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
2931 | 2929 | ||
2932 | atomic_inc(&fs_info->scrubs_running); | 2930 | atomic_inc(&fs_info->scrubs_running); |
2933 | mutex_unlock(&fs_info->scrub_lock); | 2931 | mutex_unlock(&fs_info->scrub_lock); |
2934 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
2935 | 2932 | ||
2936 | if (!is_dev_replace) { | 2933 | if (!is_dev_replace) { |
2937 | down_read(&fs_info->scrub_super_lock); | 2934 | /* |
2935 | * by holding device list mutex, we can | ||
2936 | * kick off writing super in log tree sync. | ||
2937 | */ | ||
2938 | ret = scrub_supers(sctx, dev); | 2938 | ret = scrub_supers(sctx, dev); |
2939 | up_read(&fs_info->scrub_super_lock); | ||
2940 | } | 2939 | } |
2940 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
2941 | 2941 | ||
2942 | if (!ret) | 2942 | if (!ret) |
2943 | ret = scrub_enumerate_chunks(sctx, dev, start, end, | 2943 | ret = scrub_enumerate_chunks(sctx, dev, start, end, |
@@ -2954,10 +2954,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
2954 | 2954 | ||
2955 | mutex_lock(&fs_info->scrub_lock); | 2955 | mutex_lock(&fs_info->scrub_lock); |
2956 | dev->scrub_device = NULL; | 2956 | dev->scrub_device = NULL; |
2957 | scrub_workers_put(fs_info); | ||
2957 | mutex_unlock(&fs_info->scrub_lock); | 2958 | mutex_unlock(&fs_info->scrub_lock); |
2958 | 2959 | ||
2959 | scrub_free_ctx(sctx); | 2960 | scrub_free_ctx(sctx); |
2960 | scrub_workers_put(fs_info); | ||
2961 | 2961 | ||
2962 | return ret; | 2962 | return ret; |
2963 | } | 2963 | } |
@@ -2987,16 +2987,6 @@ void btrfs_scrub_continue(struct btrfs_root *root) | |||
2987 | wake_up(&fs_info->scrub_pause_wait); | 2987 | wake_up(&fs_info->scrub_pause_wait); |
2988 | } | 2988 | } |
2989 | 2989 | ||
2990 | void btrfs_scrub_pause_super(struct btrfs_root *root) | ||
2991 | { | ||
2992 | down_write(&root->fs_info->scrub_super_lock); | ||
2993 | } | ||
2994 | |||
2995 | void btrfs_scrub_continue_super(struct btrfs_root *root) | ||
2996 | { | ||
2997 | up_write(&root->fs_info->scrub_super_lock); | ||
2998 | } | ||
2999 | |||
3000 | int btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) | 2990 | int btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) |
3001 | { | 2991 | { |
3002 | mutex_lock(&fs_info->scrub_lock); | 2992 | mutex_lock(&fs_info->scrub_lock); |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index e46e0ed74925..6837fe87f3a6 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -121,7 +121,6 @@ struct send_ctx { | |||
121 | struct list_head name_cache_list; | 121 | struct list_head name_cache_list; |
122 | int name_cache_size; | 122 | int name_cache_size; |
123 | 123 | ||
124 | struct file *cur_inode_filp; | ||
125 | char *read_buf; | 124 | char *read_buf; |
126 | }; | 125 | }; |
127 | 126 | ||
@@ -565,10 +564,8 @@ static int begin_cmd(struct send_ctx *sctx, int cmd) | |||
565 | { | 564 | { |
566 | struct btrfs_cmd_header *hdr; | 565 | struct btrfs_cmd_header *hdr; |
567 | 566 | ||
568 | if (!sctx->send_buf) { | 567 | if (WARN_ON(!sctx->send_buf)) |
569 | WARN_ON(1); | ||
570 | return -EINVAL; | 568 | return -EINVAL; |
571 | } | ||
572 | 569 | ||
573 | BUG_ON(sctx->send_size); | 570 | BUG_ON(sctx->send_size); |
574 | 571 | ||
@@ -791,7 +788,7 @@ static int iterate_inode_ref(struct btrfs_root *root, struct btrfs_path *path, | |||
791 | if (found_key->type == BTRFS_INODE_REF_KEY) { | 788 | if (found_key->type == BTRFS_INODE_REF_KEY) { |
792 | ptr = (unsigned long)btrfs_item_ptr(eb, slot, | 789 | ptr = (unsigned long)btrfs_item_ptr(eb, slot, |
793 | struct btrfs_inode_ref); | 790 | struct btrfs_inode_ref); |
794 | item = btrfs_item_nr(eb, slot); | 791 | item = btrfs_item_nr(slot); |
795 | total = btrfs_item_size(eb, item); | 792 | total = btrfs_item_size(eb, item); |
796 | elem_size = sizeof(*iref); | 793 | elem_size = sizeof(*iref); |
797 | } else { | 794 | } else { |
@@ -905,7 +902,7 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path, | |||
905 | 902 | ||
906 | eb = path->nodes[0]; | 903 | eb = path->nodes[0]; |
907 | slot = path->slots[0]; | 904 | slot = path->slots[0]; |
908 | item = btrfs_item_nr(eb, slot); | 905 | item = btrfs_item_nr(slot); |
909 | di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); | 906 | di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); |
910 | cur = 0; | 907 | cur = 0; |
911 | len = 0; | 908 | len = 0; |
@@ -2120,77 +2117,6 @@ out: | |||
2120 | } | 2117 | } |
2121 | 2118 | ||
2122 | /* | 2119 | /* |
2123 | * Called for regular files when sending extents data. Opens a struct file | ||
2124 | * to read from the file. | ||
2125 | */ | ||
2126 | static int open_cur_inode_file(struct send_ctx *sctx) | ||
2127 | { | ||
2128 | int ret = 0; | ||
2129 | struct btrfs_key key; | ||
2130 | struct path path; | ||
2131 | struct inode *inode; | ||
2132 | struct dentry *dentry; | ||
2133 | struct file *filp; | ||
2134 | int new = 0; | ||
2135 | |||
2136 | if (sctx->cur_inode_filp) | ||
2137 | goto out; | ||
2138 | |||
2139 | key.objectid = sctx->cur_ino; | ||
2140 | key.type = BTRFS_INODE_ITEM_KEY; | ||
2141 | key.offset = 0; | ||
2142 | |||
2143 | inode = btrfs_iget(sctx->send_root->fs_info->sb, &key, sctx->send_root, | ||
2144 | &new); | ||
2145 | if (IS_ERR(inode)) { | ||
2146 | ret = PTR_ERR(inode); | ||
2147 | goto out; | ||
2148 | } | ||
2149 | |||
2150 | dentry = d_obtain_alias(inode); | ||
2151 | inode = NULL; | ||
2152 | if (IS_ERR(dentry)) { | ||
2153 | ret = PTR_ERR(dentry); | ||
2154 | goto out; | ||
2155 | } | ||
2156 | |||
2157 | path.mnt = sctx->mnt; | ||
2158 | path.dentry = dentry; | ||
2159 | filp = dentry_open(&path, O_RDONLY | O_LARGEFILE, current_cred()); | ||
2160 | dput(dentry); | ||
2161 | dentry = NULL; | ||
2162 | if (IS_ERR(filp)) { | ||
2163 | ret = PTR_ERR(filp); | ||
2164 | goto out; | ||
2165 | } | ||
2166 | sctx->cur_inode_filp = filp; | ||
2167 | |||
2168 | out: | ||
2169 | /* | ||
2170 | * no xxxput required here as every vfs op | ||
2171 | * does it by itself on failure | ||
2172 | */ | ||
2173 | return ret; | ||
2174 | } | ||
2175 | |||
2176 | /* | ||
2177 | * Closes the struct file that was created in open_cur_inode_file | ||
2178 | */ | ||
2179 | static int close_cur_inode_file(struct send_ctx *sctx) | ||
2180 | { | ||
2181 | int ret = 0; | ||
2182 | |||
2183 | if (!sctx->cur_inode_filp) | ||
2184 | goto out; | ||
2185 | |||
2186 | ret = filp_close(sctx->cur_inode_filp, NULL); | ||
2187 | sctx->cur_inode_filp = NULL; | ||
2188 | |||
2189 | out: | ||
2190 | return ret; | ||
2191 | } | ||
2192 | |||
2193 | /* | ||
2194 | * Sends a BTRFS_SEND_C_SUBVOL command/item to userspace | 2120 | * Sends a BTRFS_SEND_C_SUBVOL command/item to userspace |
2195 | */ | 2121 | */ |
2196 | static int send_subvol_begin(struct send_ctx *sctx) | 2122 | static int send_subvol_begin(struct send_ctx *sctx) |
@@ -3622,6 +3548,72 @@ out: | |||
3622 | return ret; | 3548 | return ret; |
3623 | } | 3549 | } |
3624 | 3550 | ||
3551 | static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len) | ||
3552 | { | ||
3553 | struct btrfs_root *root = sctx->send_root; | ||
3554 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
3555 | struct inode *inode; | ||
3556 | struct page *page; | ||
3557 | char *addr; | ||
3558 | struct btrfs_key key; | ||
3559 | pgoff_t index = offset >> PAGE_CACHE_SHIFT; | ||
3560 | pgoff_t last_index; | ||
3561 | unsigned pg_offset = offset & ~PAGE_CACHE_MASK; | ||
3562 | ssize_t ret = 0; | ||
3563 | |||
3564 | key.objectid = sctx->cur_ino; | ||
3565 | key.type = BTRFS_INODE_ITEM_KEY; | ||
3566 | key.offset = 0; | ||
3567 | |||
3568 | inode = btrfs_iget(fs_info->sb, &key, root, NULL); | ||
3569 | if (IS_ERR(inode)) | ||
3570 | return PTR_ERR(inode); | ||
3571 | |||
3572 | if (offset + len > i_size_read(inode)) { | ||
3573 | if (offset > i_size_read(inode)) | ||
3574 | len = 0; | ||
3575 | else | ||
3576 | len = offset - i_size_read(inode); | ||
3577 | } | ||
3578 | if (len == 0) | ||
3579 | goto out; | ||
3580 | |||
3581 | last_index = (offset + len - 1) >> PAGE_CACHE_SHIFT; | ||
3582 | while (index <= last_index) { | ||
3583 | unsigned cur_len = min_t(unsigned, len, | ||
3584 | PAGE_CACHE_SIZE - pg_offset); | ||
3585 | page = find_or_create_page(inode->i_mapping, index, GFP_NOFS); | ||
3586 | if (!page) { | ||
3587 | ret = -ENOMEM; | ||
3588 | break; | ||
3589 | } | ||
3590 | |||
3591 | if (!PageUptodate(page)) { | ||
3592 | btrfs_readpage(NULL, page); | ||
3593 | lock_page(page); | ||
3594 | if (!PageUptodate(page)) { | ||
3595 | unlock_page(page); | ||
3596 | page_cache_release(page); | ||
3597 | ret = -EIO; | ||
3598 | break; | ||
3599 | } | ||
3600 | } | ||
3601 | |||
3602 | addr = kmap(page); | ||
3603 | memcpy(sctx->read_buf + ret, addr + pg_offset, cur_len); | ||
3604 | kunmap(page); | ||
3605 | unlock_page(page); | ||
3606 | page_cache_release(page); | ||
3607 | index++; | ||
3608 | pg_offset = 0; | ||
3609 | len -= cur_len; | ||
3610 | ret += cur_len; | ||
3611 | } | ||
3612 | out: | ||
3613 | iput(inode); | ||
3614 | return ret; | ||
3615 | } | ||
3616 | |||
3625 | /* | 3617 | /* |
3626 | * Read some bytes from the current inode/file and send a write command to | 3618 | * Read some bytes from the current inode/file and send a write command to |
3627 | * user space. | 3619 | * user space. |
@@ -3630,35 +3622,20 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len) | |||
3630 | { | 3622 | { |
3631 | int ret = 0; | 3623 | int ret = 0; |
3632 | struct fs_path *p; | 3624 | struct fs_path *p; |
3633 | loff_t pos = offset; | 3625 | ssize_t num_read = 0; |
3634 | int num_read = 0; | ||
3635 | mm_segment_t old_fs; | ||
3636 | 3626 | ||
3637 | p = fs_path_alloc(); | 3627 | p = fs_path_alloc(); |
3638 | if (!p) | 3628 | if (!p) |
3639 | return -ENOMEM; | 3629 | return -ENOMEM; |
3640 | 3630 | ||
3641 | /* | ||
3642 | * vfs normally only accepts user space buffers for security reasons. | ||
3643 | * we only read from the file and also only provide the read_buf buffer | ||
3644 | * to vfs. As this buffer does not come from a user space call, it's | ||
3645 | * ok to temporary allow kernel space buffers. | ||
3646 | */ | ||
3647 | old_fs = get_fs(); | ||
3648 | set_fs(KERNEL_DS); | ||
3649 | |||
3650 | verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len); | 3631 | verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len); |
3651 | 3632 | ||
3652 | ret = open_cur_inode_file(sctx); | 3633 | num_read = fill_read_buf(sctx, offset, len); |
3653 | if (ret < 0) | 3634 | if (num_read <= 0) { |
3654 | goto out; | 3635 | if (num_read < 0) |
3655 | 3636 | ret = num_read; | |
3656 | ret = vfs_read(sctx->cur_inode_filp, sctx->read_buf, len, &pos); | ||
3657 | if (ret < 0) | ||
3658 | goto out; | ||
3659 | num_read = ret; | ||
3660 | if (!num_read) | ||
3661 | goto out; | 3637 | goto out; |
3638 | } | ||
3662 | 3639 | ||
3663 | ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); | 3640 | ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); |
3664 | if (ret < 0) | 3641 | if (ret < 0) |
@@ -3677,7 +3654,6 @@ verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len); | |||
3677 | tlv_put_failure: | 3654 | tlv_put_failure: |
3678 | out: | 3655 | out: |
3679 | fs_path_free(p); | 3656 | fs_path_free(p); |
3680 | set_fs(old_fs); | ||
3681 | if (ret < 0) | 3657 | if (ret < 0) |
3682 | return ret; | 3658 | return ret; |
3683 | return num_read; | 3659 | return num_read; |
@@ -3926,16 +3902,16 @@ static int is_extent_unchanged(struct send_ctx *sctx, | |||
3926 | while (key.offset < ekey->offset + left_len) { | 3902 | while (key.offset < ekey->offset + left_len) { |
3927 | ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); | 3903 | ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); |
3928 | right_type = btrfs_file_extent_type(eb, ei); | 3904 | right_type = btrfs_file_extent_type(eb, ei); |
3929 | right_disknr = btrfs_file_extent_disk_bytenr(eb, ei); | ||
3930 | right_len = btrfs_file_extent_num_bytes(eb, ei); | ||
3931 | right_offset = btrfs_file_extent_offset(eb, ei); | ||
3932 | right_gen = btrfs_file_extent_generation(eb, ei); | ||
3933 | |||
3934 | if (right_type != BTRFS_FILE_EXTENT_REG) { | 3905 | if (right_type != BTRFS_FILE_EXTENT_REG) { |
3935 | ret = 0; | 3906 | ret = 0; |
3936 | goto out; | 3907 | goto out; |
3937 | } | 3908 | } |
3938 | 3909 | ||
3910 | right_disknr = btrfs_file_extent_disk_bytenr(eb, ei); | ||
3911 | right_len = btrfs_file_extent_num_bytes(eb, ei); | ||
3912 | right_offset = btrfs_file_extent_offset(eb, ei); | ||
3913 | right_gen = btrfs_file_extent_generation(eb, ei); | ||
3914 | |||
3939 | /* | 3915 | /* |
3940 | * Are we at extent 8? If yes, we know the extent is changed. | 3916 | * Are we at extent 8? If yes, we know the extent is changed. |
3941 | * This may only happen on the first iteration. | 3917 | * This may only happen on the first iteration. |
@@ -4222,10 +4198,6 @@ static int changed_inode(struct send_ctx *sctx, | |||
4222 | u64 left_gen = 0; | 4198 | u64 left_gen = 0; |
4223 | u64 right_gen = 0; | 4199 | u64 right_gen = 0; |
4224 | 4200 | ||
4225 | ret = close_cur_inode_file(sctx); | ||
4226 | if (ret < 0) | ||
4227 | goto out; | ||
4228 | |||
4229 | sctx->cur_ino = key->objectid; | 4201 | sctx->cur_ino = key->objectid; |
4230 | sctx->cur_inode_new_gen = 0; | 4202 | sctx->cur_inode_new_gen = 0; |
4231 | 4203 | ||
@@ -4686,11 +4658,6 @@ static int send_subvol(struct send_ctx *sctx) | |||
4686 | } | 4658 | } |
4687 | 4659 | ||
4688 | out: | 4660 | out: |
4689 | if (!ret) | ||
4690 | ret = close_cur_inode_file(sctx); | ||
4691 | else | ||
4692 | close_cur_inode_file(sctx); | ||
4693 | |||
4694 | free_recorded_refs(sctx); | 4661 | free_recorded_refs(sctx); |
4695 | return ret; | 4662 | return ret; |
4696 | } | 4663 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index e913328d0f2a..2d8ac1bf0cf9 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/cleancache.h> | 42 | #include <linux/cleancache.h> |
43 | #include <linux/ratelimit.h> | 43 | #include <linux/ratelimit.h> |
44 | #include <linux/btrfs.h> | 44 | #include <linux/btrfs.h> |
45 | #include "compat.h" | ||
46 | #include "delayed-inode.h" | 45 | #include "delayed-inode.h" |
47 | #include "ctree.h" | 46 | #include "ctree.h" |
48 | #include "disk-io.h" | 47 | #include "disk-io.h" |
@@ -921,7 +920,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
921 | return 0; | 920 | return 0; |
922 | } | 921 | } |
923 | 922 | ||
924 | btrfs_wait_all_ordered_extents(fs_info); | 923 | btrfs_wait_ordered_roots(fs_info, -1); |
925 | 924 | ||
926 | trans = btrfs_attach_transaction_barrier(root); | 925 | trans = btrfs_attach_transaction_barrier(root); |
927 | if (IS_ERR(trans)) { | 926 | if (IS_ERR(trans)) { |
@@ -1330,6 +1329,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1330 | * this also happens on 'umount -rf' or on shutdown, when | 1329 | * this also happens on 'umount -rf' or on shutdown, when |
1331 | * the filesystem is busy. | 1330 | * the filesystem is busy. |
1332 | */ | 1331 | */ |
1332 | |||
1333 | /* wait for the uuid_scan task to finish */ | ||
1334 | down(&fs_info->uuid_tree_rescan_sem); | ||
1335 | /* avoid complains from lockdep et al. */ | ||
1336 | up(&fs_info->uuid_tree_rescan_sem); | ||
1337 | |||
1333 | sb->s_flags |= MS_RDONLY; | 1338 | sb->s_flags |= MS_RDONLY; |
1334 | 1339 | ||
1335 | btrfs_dev_replace_suspend_for_unmount(fs_info); | 1340 | btrfs_dev_replace_suspend_for_unmount(fs_info); |
@@ -1465,7 +1470,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1465 | nr_devices = fs_info->fs_devices->open_devices; | 1470 | nr_devices = fs_info->fs_devices->open_devices; |
1466 | BUG_ON(!nr_devices); | 1471 | BUG_ON(!nr_devices); |
1467 | 1472 | ||
1468 | devices_info = kmalloc(sizeof(*devices_info) * nr_devices, | 1473 | devices_info = kmalloc_array(nr_devices, sizeof(*devices_info), |
1469 | GFP_NOFS); | 1474 | GFP_NOFS); |
1470 | if (!devices_info) | 1475 | if (!devices_info) |
1471 | return -ENOMEM; | 1476 | return -ENOMEM; |
@@ -1789,7 +1794,25 @@ static void btrfs_print_info(void) | |||
1789 | 1794 | ||
1790 | static int btrfs_run_sanity_tests(void) | 1795 | static int btrfs_run_sanity_tests(void) |
1791 | { | 1796 | { |
1792 | return btrfs_test_free_space_cache(); | 1797 | int ret; |
1798 | |||
1799 | ret = btrfs_init_test_fs(); | ||
1800 | if (ret) | ||
1801 | return ret; | ||
1802 | |||
1803 | ret = btrfs_test_free_space_cache(); | ||
1804 | if (ret) | ||
1805 | goto out; | ||
1806 | ret = btrfs_test_extent_buffer_operations(); | ||
1807 | if (ret) | ||
1808 | goto out; | ||
1809 | ret = btrfs_test_extent_io(); | ||
1810 | if (ret) | ||
1811 | goto out; | ||
1812 | ret = btrfs_test_inodes(); | ||
1813 | out: | ||
1814 | btrfs_destroy_test_fs(); | ||
1815 | return ret; | ||
1793 | } | 1816 | } |
1794 | 1817 | ||
1795 | static int __init init_btrfs_fs(void) | 1818 | static int __init init_btrfs_fs(void) |
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c new file mode 100644 index 000000000000..757ef00a75a4 --- /dev/null +++ b/fs/btrfs/tests/btrfs-tests.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Fusion IO. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/fs.h> | ||
20 | #include <linux/mount.h> | ||
21 | #include <linux/magic.h> | ||
22 | #include "btrfs-tests.h" | ||
23 | #include "../ctree.h" | ||
24 | |||
25 | static struct vfsmount *test_mnt = NULL; | ||
26 | |||
27 | static const struct super_operations btrfs_test_super_ops = { | ||
28 | .alloc_inode = btrfs_alloc_inode, | ||
29 | .destroy_inode = btrfs_test_destroy_inode, | ||
30 | }; | ||
31 | |||
32 | static struct dentry *btrfs_test_mount(struct file_system_type *fs_type, | ||
33 | int flags, const char *dev_name, | ||
34 | void *data) | ||
35 | { | ||
36 | return mount_pseudo(fs_type, "btrfs_test:", &btrfs_test_super_ops, | ||
37 | NULL, BTRFS_TEST_MAGIC); | ||
38 | } | ||
39 | |||
40 | static struct file_system_type test_type = { | ||
41 | .name = "btrfs_test_fs", | ||
42 | .mount = btrfs_test_mount, | ||
43 | .kill_sb = kill_anon_super, | ||
44 | }; | ||
45 | |||
46 | struct inode *btrfs_new_test_inode(void) | ||
47 | { | ||
48 | return new_inode(test_mnt->mnt_sb); | ||
49 | } | ||
50 | |||
51 | int btrfs_init_test_fs(void) | ||
52 | { | ||
53 | int ret; | ||
54 | |||
55 | ret = register_filesystem(&test_type); | ||
56 | if (ret) { | ||
57 | printk(KERN_ERR "btrfs: cannot register test file system\n"); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | test_mnt = kern_mount(&test_type); | ||
62 | if (IS_ERR(test_mnt)) { | ||
63 | printk(KERN_ERR "btrfs: cannot mount test file system\n"); | ||
64 | unregister_filesystem(&test_type); | ||
65 | return ret; | ||
66 | } | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | void btrfs_destroy_test_fs(void) | ||
71 | { | ||
72 | kern_unmount(test_mnt); | ||
73 | unregister_filesystem(&test_type); | ||
74 | } | ||
diff --git a/fs/btrfs/tests/btrfs-tests.h b/fs/btrfs/tests/btrfs-tests.h index 580877625776..b353bc806ca0 100644 --- a/fs/btrfs/tests/btrfs-tests.h +++ b/fs/btrfs/tests/btrfs-tests.h | |||
@@ -24,11 +24,36 @@ | |||
24 | #define test_msg(fmt, ...) pr_info("btrfs: selftest: " fmt, ##__VA_ARGS__) | 24 | #define test_msg(fmt, ...) pr_info("btrfs: selftest: " fmt, ##__VA_ARGS__) |
25 | 25 | ||
26 | int btrfs_test_free_space_cache(void); | 26 | int btrfs_test_free_space_cache(void); |
27 | int btrfs_test_extent_buffer_operations(void); | ||
28 | int btrfs_test_extent_io(void); | ||
29 | int btrfs_test_inodes(void); | ||
30 | int btrfs_init_test_fs(void); | ||
31 | void btrfs_destroy_test_fs(void); | ||
32 | struct inode *btrfs_new_test_inode(void); | ||
27 | #else | 33 | #else |
28 | static inline int btrfs_test_free_space_cache(void) | 34 | static inline int btrfs_test_free_space_cache(void) |
29 | { | 35 | { |
30 | return 0; | 36 | return 0; |
31 | } | 37 | } |
38 | static inline int btrfs_test_extent_buffer_operations(void) | ||
39 | { | ||
40 | return 0; | ||
41 | } | ||
42 | static inline int btrfs_init_test_fs(void) | ||
43 | { | ||
44 | return 0; | ||
45 | } | ||
46 | static inline void btrfs_destroy_test_fs(void) | ||
47 | { | ||
48 | } | ||
49 | static inline int btrfs_test_extent_io(void) | ||
50 | { | ||
51 | return 0; | ||
52 | } | ||
53 | static inline int btrfs_test_inodes(void) | ||
54 | { | ||
55 | return 0; | ||
56 | } | ||
32 | #endif | 57 | #endif |
33 | 58 | ||
34 | #endif | 59 | #endif |
diff --git a/fs/btrfs/tests/extent-buffer-tests.c b/fs/btrfs/tests/extent-buffer-tests.c new file mode 100644 index 000000000000..cc286ce97d1e --- /dev/null +++ b/fs/btrfs/tests/extent-buffer-tests.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Fusion IO. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/slab.h> | ||
20 | #include "btrfs-tests.h" | ||
21 | #include "../ctree.h" | ||
22 | #include "../extent_io.h" | ||
23 | #include "../disk-io.h" | ||
24 | |||
25 | static int test_btrfs_split_item(void) | ||
26 | { | ||
27 | struct btrfs_path *path; | ||
28 | struct btrfs_root *root; | ||
29 | struct extent_buffer *eb; | ||
30 | struct btrfs_item *item; | ||
31 | char *value = "mary had a little lamb"; | ||
32 | char *split1 = "mary had a little"; | ||
33 | char *split2 = " lamb"; | ||
34 | char *split3 = "mary"; | ||
35 | char *split4 = " had a little"; | ||
36 | char buf[32]; | ||
37 | struct btrfs_key key; | ||
38 | u32 value_len = strlen(value); | ||
39 | int ret = 0; | ||
40 | |||
41 | test_msg("Running btrfs_split_item tests\n"); | ||
42 | |||
43 | root = btrfs_alloc_dummy_root(); | ||
44 | if (IS_ERR(root)) { | ||
45 | test_msg("Could not allocate root\n"); | ||
46 | return PTR_ERR(root); | ||
47 | } | ||
48 | |||
49 | path = btrfs_alloc_path(); | ||
50 | if (!path) { | ||
51 | test_msg("Could not allocate path\n"); | ||
52 | kfree(root); | ||
53 | return -ENOMEM; | ||
54 | } | ||
55 | |||
56 | path->nodes[0] = eb = alloc_dummy_extent_buffer(0, 4096); | ||
57 | if (!eb) { | ||
58 | test_msg("Could not allocate dummy buffer\n"); | ||
59 | ret = -ENOMEM; | ||
60 | goto out; | ||
61 | } | ||
62 | path->slots[0] = 0; | ||
63 | |||
64 | key.objectid = 0; | ||
65 | key.type = BTRFS_EXTENT_CSUM_KEY; | ||
66 | key.offset = 0; | ||
67 | |||
68 | setup_items_for_insert(root, path, &key, &value_len, value_len, | ||
69 | value_len + sizeof(struct btrfs_item), 1); | ||
70 | item = btrfs_item_nr(0); | ||
71 | write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0), | ||
72 | value_len); | ||
73 | |||
74 | key.offset = 3; | ||
75 | |||
76 | /* | ||
77 | * Passing NULL trans here should be safe because we have plenty of | ||
78 | * space in this leaf to split the item without having to split the | ||
79 | * leaf. | ||
80 | */ | ||
81 | ret = btrfs_split_item(NULL, root, path, &key, 17); | ||
82 | if (ret) { | ||
83 | test_msg("Split item failed %d\n", ret); | ||
84 | goto out; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Read the first slot, it should have the original key and contain only | ||
89 | * 'mary had a little' | ||
90 | */ | ||
91 | btrfs_item_key_to_cpu(eb, &key, 0); | ||
92 | if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY || | ||
93 | key.offset != 0) { | ||
94 | test_msg("Invalid key at slot 0\n"); | ||
95 | ret = -EINVAL; | ||
96 | goto out; | ||
97 | } | ||
98 | |||
99 | item = btrfs_item_nr(0); | ||
100 | if (btrfs_item_size(eb, item) != strlen(split1)) { | ||
101 | test_msg("Invalid len in the first split\n"); | ||
102 | ret = -EINVAL; | ||
103 | goto out; | ||
104 | } | ||
105 | |||
106 | read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0), | ||
107 | strlen(split1)); | ||
108 | if (memcmp(buf, split1, strlen(split1))) { | ||
109 | test_msg("Data in the buffer doesn't match what it should " | ||
110 | "in the first split have='%.*s' want '%s'\n", | ||
111 | (int)strlen(split1), buf, split1); | ||
112 | ret = -EINVAL; | ||
113 | goto out; | ||
114 | } | ||
115 | |||
116 | btrfs_item_key_to_cpu(eb, &key, 1); | ||
117 | if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY || | ||
118 | key.offset != 3) { | ||
119 | test_msg("Invalid key at slot 1\n"); | ||
120 | ret = -EINVAL; | ||
121 | goto out; | ||
122 | } | ||
123 | |||
124 | item = btrfs_item_nr(1); | ||
125 | if (btrfs_item_size(eb, item) != strlen(split2)) { | ||
126 | test_msg("Invalid len in the second split\n"); | ||
127 | ret = -EINVAL; | ||
128 | goto out; | ||
129 | } | ||
130 | |||
131 | read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1), | ||
132 | strlen(split2)); | ||
133 | if (memcmp(buf, split2, strlen(split2))) { | ||
134 | test_msg("Data in the buffer doesn't match what it should " | ||
135 | "in the second split\n"); | ||
136 | ret = -EINVAL; | ||
137 | goto out; | ||
138 | } | ||
139 | |||
140 | key.offset = 1; | ||
141 | /* Do it again so we test memmoving the other items in the leaf */ | ||
142 | ret = btrfs_split_item(NULL, root, path, &key, 4); | ||
143 | if (ret) { | ||
144 | test_msg("Second split item failed %d\n", ret); | ||
145 | goto out; | ||
146 | } | ||
147 | |||
148 | btrfs_item_key_to_cpu(eb, &key, 0); | ||
149 | if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY || | ||
150 | key.offset != 0) { | ||
151 | test_msg("Invalid key at slot 0\n"); | ||
152 | ret = -EINVAL; | ||
153 | goto out; | ||
154 | } | ||
155 | |||
156 | item = btrfs_item_nr(0); | ||
157 | if (btrfs_item_size(eb, item) != strlen(split3)) { | ||
158 | test_msg("Invalid len in the first split\n"); | ||
159 | ret = -EINVAL; | ||
160 | goto out; | ||
161 | } | ||
162 | |||
163 | read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 0), | ||
164 | strlen(split3)); | ||
165 | if (memcmp(buf, split3, strlen(split3))) { | ||
166 | test_msg("Data in the buffer doesn't match what it should " | ||
167 | "in the third split"); | ||
168 | ret = -EINVAL; | ||
169 | goto out; | ||
170 | } | ||
171 | |||
172 | btrfs_item_key_to_cpu(eb, &key, 1); | ||
173 | if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY || | ||
174 | key.offset != 1) { | ||
175 | test_msg("Invalid key at slot 1\n"); | ||
176 | ret = -EINVAL; | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | item = btrfs_item_nr(1); | ||
181 | if (btrfs_item_size(eb, item) != strlen(split4)) { | ||
182 | test_msg("Invalid len in the second split\n"); | ||
183 | ret = -EINVAL; | ||
184 | goto out; | ||
185 | } | ||
186 | |||
187 | read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 1), | ||
188 | strlen(split4)); | ||
189 | if (memcmp(buf, split4, strlen(split4))) { | ||
190 | test_msg("Data in the buffer doesn't match what it should " | ||
191 | "in the fourth split\n"); | ||
192 | ret = -EINVAL; | ||
193 | goto out; | ||
194 | } | ||
195 | |||
196 | btrfs_item_key_to_cpu(eb, &key, 2); | ||
197 | if (key.objectid != 0 || key.type != BTRFS_EXTENT_CSUM_KEY || | ||
198 | key.offset != 3) { | ||
199 | test_msg("Invalid key at slot 2\n"); | ||
200 | ret = -EINVAL; | ||
201 | goto out; | ||
202 | } | ||
203 | |||
204 | item = btrfs_item_nr(2); | ||
205 | if (btrfs_item_size(eb, item) != strlen(split2)) { | ||
206 | test_msg("Invalid len in the second split\n"); | ||
207 | ret = -EINVAL; | ||
208 | goto out; | ||
209 | } | ||
210 | |||
211 | read_extent_buffer(eb, buf, btrfs_item_ptr_offset(eb, 2), | ||
212 | strlen(split2)); | ||
213 | if (memcmp(buf, split2, strlen(split2))) { | ||
214 | test_msg("Data in the buffer doesn't match what it should " | ||
215 | "in the last chunk\n"); | ||
216 | ret = -EINVAL; | ||
217 | goto out; | ||
218 | } | ||
219 | out: | ||
220 | btrfs_free_path(path); | ||
221 | kfree(root); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | int btrfs_test_extent_buffer_operations(void) | ||
226 | { | ||
227 | test_msg("Running extent buffer operation tests"); | ||
228 | return test_btrfs_split_item(); | ||
229 | } | ||
diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c new file mode 100644 index 000000000000..7e99c2f98dd0 --- /dev/null +++ b/fs/btrfs/tests/extent-io-tests.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Fusion IO. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/pagemap.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include "btrfs-tests.h" | ||
22 | #include "../extent_io.h" | ||
23 | |||
24 | #define PROCESS_UNLOCK (1 << 0) | ||
25 | #define PROCESS_RELEASE (1 << 1) | ||
26 | #define PROCESS_TEST_LOCKED (1 << 2) | ||
27 | |||
28 | static noinline int process_page_range(struct inode *inode, u64 start, u64 end, | ||
29 | unsigned long flags) | ||
30 | { | ||
31 | int ret; | ||
32 | struct page *pages[16]; | ||
33 | unsigned long index = start >> PAGE_CACHE_SHIFT; | ||
34 | unsigned long end_index = end >> PAGE_CACHE_SHIFT; | ||
35 | unsigned long nr_pages = end_index - index + 1; | ||
36 | int i; | ||
37 | int count = 0; | ||
38 | int loops = 0; | ||
39 | |||
40 | while (nr_pages > 0) { | ||
41 | ret = find_get_pages_contig(inode->i_mapping, index, | ||
42 | min_t(unsigned long, nr_pages, | ||
43 | ARRAY_SIZE(pages)), pages); | ||
44 | for (i = 0; i < ret; i++) { | ||
45 | if (flags & PROCESS_TEST_LOCKED && | ||
46 | !PageLocked(pages[i])) | ||
47 | count++; | ||
48 | if (flags & PROCESS_UNLOCK && PageLocked(pages[i])) | ||
49 | unlock_page(pages[i]); | ||
50 | page_cache_release(pages[i]); | ||
51 | if (flags & PROCESS_RELEASE) | ||
52 | page_cache_release(pages[i]); | ||
53 | } | ||
54 | nr_pages -= ret; | ||
55 | index += ret; | ||
56 | cond_resched(); | ||
57 | loops++; | ||
58 | if (loops > 100000) { | ||
59 | printk(KERN_ERR "stuck in a loop, start %Lu, end %Lu, nr_pages %lu, ret %d\n", start, end, nr_pages, ret); | ||
60 | break; | ||
61 | } | ||
62 | } | ||
63 | return count; | ||
64 | } | ||
65 | |||
66 | static int test_find_delalloc(void) | ||
67 | { | ||
68 | struct inode *inode; | ||
69 | struct extent_io_tree tmp; | ||
70 | struct page *page; | ||
71 | struct page *locked_page = NULL; | ||
72 | unsigned long index = 0; | ||
73 | u64 total_dirty = 256 * 1024 * 1024; | ||
74 | u64 max_bytes = 128 * 1024 * 1024; | ||
75 | u64 start, end, test_start; | ||
76 | u64 found; | ||
77 | int ret = -EINVAL; | ||
78 | |||
79 | inode = btrfs_new_test_inode(); | ||
80 | if (!inode) { | ||
81 | test_msg("Failed to allocate test inode\n"); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | extent_io_tree_init(&tmp, &inode->i_data); | ||
86 | |||
87 | /* | ||
88 | * First go through and create and mark all of our pages dirty, we pin | ||
89 | * everything to make sure our pages don't get evicted and screw up our | ||
90 | * test. | ||
91 | */ | ||
92 | for (index = 0; index < (total_dirty >> PAGE_CACHE_SHIFT); index++) { | ||
93 | page = find_or_create_page(inode->i_mapping, index, GFP_NOFS); | ||
94 | if (!page) { | ||
95 | test_msg("Failed to allocate test page\n"); | ||
96 | ret = -ENOMEM; | ||
97 | goto out; | ||
98 | } | ||
99 | SetPageDirty(page); | ||
100 | if (index) { | ||
101 | unlock_page(page); | ||
102 | } else { | ||
103 | page_cache_get(page); | ||
104 | locked_page = page; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | /* Test this scenario | ||
109 | * |--- delalloc ---| | ||
110 | * |--- search ---| | ||
111 | */ | ||
112 | set_extent_delalloc(&tmp, 0, 4095, NULL, GFP_NOFS); | ||
113 | start = 0; | ||
114 | end = 0; | ||
115 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
116 | &end, max_bytes); | ||
117 | if (!found) { | ||
118 | test_msg("Should have found at least one delalloc\n"); | ||
119 | goto out_bits; | ||
120 | } | ||
121 | if (start != 0 || end != 4095) { | ||
122 | test_msg("Expected start 0 end 4095, got start %Lu end %Lu\n", | ||
123 | start, end); | ||
124 | goto out_bits; | ||
125 | } | ||
126 | unlock_extent(&tmp, start, end); | ||
127 | unlock_page(locked_page); | ||
128 | page_cache_release(locked_page); | ||
129 | |||
130 | /* | ||
131 | * Test this scenario | ||
132 | * | ||
133 | * |--- delalloc ---| | ||
134 | * |--- search ---| | ||
135 | */ | ||
136 | test_start = 64 * 1024 * 1024; | ||
137 | locked_page = find_lock_page(inode->i_mapping, | ||
138 | test_start >> PAGE_CACHE_SHIFT); | ||
139 | if (!locked_page) { | ||
140 | test_msg("Couldn't find the locked page\n"); | ||
141 | goto out_bits; | ||
142 | } | ||
143 | set_extent_delalloc(&tmp, 4096, max_bytes - 1, NULL, GFP_NOFS); | ||
144 | start = test_start; | ||
145 | end = 0; | ||
146 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
147 | &end, max_bytes); | ||
148 | if (!found) { | ||
149 | test_msg("Couldn't find delalloc in our range\n"); | ||
150 | goto out_bits; | ||
151 | } | ||
152 | if (start != test_start || end != max_bytes - 1) { | ||
153 | test_msg("Expected start %Lu end %Lu, got start %Lu, end " | ||
154 | "%Lu\n", test_start, max_bytes - 1, start, end); | ||
155 | goto out_bits; | ||
156 | } | ||
157 | if (process_page_range(inode, start, end, | ||
158 | PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) { | ||
159 | test_msg("There were unlocked pages in the range\n"); | ||
160 | goto out_bits; | ||
161 | } | ||
162 | unlock_extent(&tmp, start, end); | ||
163 | /* locked_page was unlocked above */ | ||
164 | page_cache_release(locked_page); | ||
165 | |||
166 | /* | ||
167 | * Test this scenario | ||
168 | * |--- delalloc ---| | ||
169 | * |--- search ---| | ||
170 | */ | ||
171 | test_start = max_bytes + 4096; | ||
172 | locked_page = find_lock_page(inode->i_mapping, test_start >> | ||
173 | PAGE_CACHE_SHIFT); | ||
174 | if (!locked_page) { | ||
175 | test_msg("Could'nt find the locked page\n"); | ||
176 | goto out_bits; | ||
177 | } | ||
178 | start = test_start; | ||
179 | end = 0; | ||
180 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
181 | &end, max_bytes); | ||
182 | if (found) { | ||
183 | test_msg("Found range when we shouldn't have\n"); | ||
184 | goto out_bits; | ||
185 | } | ||
186 | if (end != (u64)-1) { | ||
187 | test_msg("Did not return the proper end offset\n"); | ||
188 | goto out_bits; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Test this scenario | ||
193 | * [------- delalloc -------| | ||
194 | * [max_bytes]|-- search--| | ||
195 | * | ||
196 | * We are re-using our test_start from above since it works out well. | ||
197 | */ | ||
198 | set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, NULL, GFP_NOFS); | ||
199 | start = test_start; | ||
200 | end = 0; | ||
201 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
202 | &end, max_bytes); | ||
203 | if (!found) { | ||
204 | test_msg("Didn't find our range\n"); | ||
205 | goto out_bits; | ||
206 | } | ||
207 | if (start != test_start || end != total_dirty - 1) { | ||
208 | test_msg("Expected start %Lu end %Lu, got start %Lu end %Lu\n", | ||
209 | test_start, total_dirty - 1, start, end); | ||
210 | goto out_bits; | ||
211 | } | ||
212 | if (process_page_range(inode, start, end, | ||
213 | PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) { | ||
214 | test_msg("Pages in range were not all locked\n"); | ||
215 | goto out_bits; | ||
216 | } | ||
217 | unlock_extent(&tmp, start, end); | ||
218 | |||
219 | /* | ||
220 | * Now to test where we run into a page that is no longer dirty in the | ||
221 | * range we want to find. | ||
222 | */ | ||
223 | page = find_get_page(inode->i_mapping, (max_bytes + (1 * 1024 * 1024)) | ||
224 | >> PAGE_CACHE_SHIFT); | ||
225 | if (!page) { | ||
226 | test_msg("Couldn't find our page\n"); | ||
227 | goto out_bits; | ||
228 | } | ||
229 | ClearPageDirty(page); | ||
230 | page_cache_release(page); | ||
231 | |||
232 | /* We unlocked it in the previous test */ | ||
233 | lock_page(locked_page); | ||
234 | start = test_start; | ||
235 | end = 0; | ||
236 | /* | ||
237 | * Currently if we fail to find dirty pages in the delalloc range we | ||
238 | * will adjust max_bytes down to PAGE_CACHE_SIZE and then re-search. If | ||
239 | * this changes at any point in the future we will need to fix this | ||
240 | * tests expected behavior. | ||
241 | */ | ||
242 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
243 | &end, max_bytes); | ||
244 | if (!found) { | ||
245 | test_msg("Didn't find our range\n"); | ||
246 | goto out_bits; | ||
247 | } | ||
248 | if (start != test_start && end != test_start + PAGE_CACHE_SIZE - 1) { | ||
249 | test_msg("Expected start %Lu end %Lu, got start %Lu end %Lu\n", | ||
250 | test_start, test_start + PAGE_CACHE_SIZE - 1, start, | ||
251 | end); | ||
252 | goto out_bits; | ||
253 | } | ||
254 | if (process_page_range(inode, start, end, PROCESS_TEST_LOCKED | | ||
255 | PROCESS_UNLOCK)) { | ||
256 | test_msg("Pages in range were not all locked\n"); | ||
257 | goto out_bits; | ||
258 | } | ||
259 | ret = 0; | ||
260 | out_bits: | ||
261 | clear_extent_bits(&tmp, 0, total_dirty - 1, | ||
262 | (unsigned long)-1, GFP_NOFS); | ||
263 | out: | ||
264 | if (locked_page) | ||
265 | page_cache_release(locked_page); | ||
266 | process_page_range(inode, 0, total_dirty - 1, | ||
267 | PROCESS_UNLOCK | PROCESS_RELEASE); | ||
268 | iput(inode); | ||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | int btrfs_test_extent_io(void) | ||
273 | { | ||
274 | test_msg("Running find delalloc tests\n"); | ||
275 | return test_find_delalloc(); | ||
276 | } | ||
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c new file mode 100644 index 000000000000..397d1f99a8eb --- /dev/null +++ b/fs/btrfs/tests/inode-tests.c | |||
@@ -0,0 +1,955 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Fusion IO. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include "btrfs-tests.h" | ||
20 | #include "../ctree.h" | ||
21 | #include "../btrfs_inode.h" | ||
22 | #include "../disk-io.h" | ||
23 | #include "../extent_io.h" | ||
24 | #include "../volumes.h" | ||
25 | |||
26 | static struct btrfs_fs_info *alloc_dummy_fs_info(void) | ||
27 | { | ||
28 | struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info), | ||
29 | GFP_NOFS); | ||
30 | if (!fs_info) | ||
31 | return fs_info; | ||
32 | fs_info->fs_devices = kzalloc(sizeof(struct btrfs_fs_devices), | ||
33 | GFP_NOFS); | ||
34 | if (!fs_info->fs_devices) { | ||
35 | kfree(fs_info); | ||
36 | return NULL; | ||
37 | } | ||
38 | return fs_info; | ||
39 | } | ||
40 | static void free_dummy_root(struct btrfs_root *root) | ||
41 | { | ||
42 | if (!root) | ||
43 | return; | ||
44 | if (root->fs_info) { | ||
45 | kfree(root->fs_info->fs_devices); | ||
46 | kfree(root->fs_info); | ||
47 | } | ||
48 | if (root->node) | ||
49 | free_extent_buffer(root->node); | ||
50 | kfree(root); | ||
51 | } | ||
52 | |||
53 | static void insert_extent(struct btrfs_root *root, u64 start, u64 len, | ||
54 | u64 ram_bytes, u64 offset, u64 disk_bytenr, | ||
55 | u64 disk_len, u32 type, u8 compression, int slot) | ||
56 | { | ||
57 | struct btrfs_path path; | ||
58 | struct btrfs_file_extent_item *fi; | ||
59 | struct extent_buffer *leaf = root->node; | ||
60 | struct btrfs_key key; | ||
61 | u32 value_len = sizeof(struct btrfs_file_extent_item); | ||
62 | |||
63 | if (type == BTRFS_FILE_EXTENT_INLINE) | ||
64 | value_len += len; | ||
65 | memset(&path, 0, sizeof(path)); | ||
66 | |||
67 | path.nodes[0] = leaf; | ||
68 | path.slots[0] = slot; | ||
69 | |||
70 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; | ||
71 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
72 | key.offset = start; | ||
73 | |||
74 | setup_items_for_insert(root, &path, &key, &value_len, value_len, | ||
75 | value_len + sizeof(struct btrfs_item), 1); | ||
76 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | ||
77 | btrfs_set_file_extent_generation(leaf, fi, 1); | ||
78 | btrfs_set_file_extent_type(leaf, fi, type); | ||
79 | btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr); | ||
80 | btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len); | ||
81 | btrfs_set_file_extent_offset(leaf, fi, offset); | ||
82 | btrfs_set_file_extent_num_bytes(leaf, fi, len); | ||
83 | btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes); | ||
84 | btrfs_set_file_extent_compression(leaf, fi, compression); | ||
85 | btrfs_set_file_extent_encryption(leaf, fi, 0); | ||
86 | btrfs_set_file_extent_other_encoding(leaf, fi, 0); | ||
87 | } | ||
88 | |||
89 | static void insert_inode_item_key(struct btrfs_root *root) | ||
90 | { | ||
91 | struct btrfs_path path; | ||
92 | struct extent_buffer *leaf = root->node; | ||
93 | struct btrfs_key key; | ||
94 | u32 value_len = 0; | ||
95 | |||
96 | memset(&path, 0, sizeof(path)); | ||
97 | |||
98 | path.nodes[0] = leaf; | ||
99 | path.slots[0] = 0; | ||
100 | |||
101 | key.objectid = BTRFS_INODE_ITEM_KEY; | ||
102 | key.type = BTRFS_INODE_ITEM_KEY; | ||
103 | key.offset = 0; | ||
104 | |||
105 | setup_items_for_insert(root, &path, &key, &value_len, value_len, | ||
106 | value_len + sizeof(struct btrfs_item), 1); | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Build the most complicated map of extents the earth has ever seen. We want | ||
111 | * this so we can test all of the corner cases of btrfs_get_extent. Here is a | ||
112 | * diagram of how the extents will look though this may not be possible we still | ||
113 | * want to make sure everything acts normally (the last number is not inclusive) | ||
114 | * | ||
115 | * [0 - 5][5 - 6][6 - 10][10 - 4096][ 4096 - 8192 ][8192 - 12288] | ||
116 | * [hole ][inline][ hole ][ regular ][regular1 split][ hole ] | ||
117 | * | ||
118 | * [ 12288 - 20480][20480 - 24576][ 24576 - 28672 ][28672 - 36864][36864 - 45056] | ||
119 | * [regular1 split][ prealloc1 ][prealloc1 written][ prealloc1 ][ compressed ] | ||
120 | * | ||
121 | * [45056 - 49152][49152-53248][53248-61440][61440-65536][ 65536+81920 ] | ||
122 | * [ compressed1 ][ regular ][compressed1][ regular ][ hole but no extent] | ||
123 | * | ||
124 | * [81920-86016] | ||
125 | * [ regular ] | ||
126 | */ | ||
127 | static void setup_file_extents(struct btrfs_root *root) | ||
128 | { | ||
129 | int slot = 0; | ||
130 | u64 disk_bytenr = 1 * 1024 * 1024; | ||
131 | u64 offset = 0; | ||
132 | |||
133 | /* First we want a hole */ | ||
134 | insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0, | ||
135 | slot); | ||
136 | slot++; | ||
137 | offset += 5; | ||
138 | |||
139 | /* | ||
140 | * Now we want an inline extent, I don't think this is possible but hey | ||
141 | * why not? Also keep in mind if we have an inline extent it counts as | ||
142 | * the whole first page. If we were to expand it we would have to cow | ||
143 | * and we wouldn't have an inline extent anymore. | ||
144 | */ | ||
145 | insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0, | ||
146 | slot); | ||
147 | slot++; | ||
148 | offset = 4096; | ||
149 | |||
150 | /* Now another hole */ | ||
151 | insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0, | ||
152 | slot); | ||
153 | slot++; | ||
154 | offset += 4; | ||
155 | |||
156 | /* Now for a regular extent */ | ||
157 | insert_extent(root, offset, 4095, 4095, 0, disk_bytenr, 4096, | ||
158 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
159 | slot++; | ||
160 | disk_bytenr += 4096; | ||
161 | offset += 4095; | ||
162 | |||
163 | /* | ||
164 | * Now for 3 extents that were split from a hole punch so we test | ||
165 | * offsets properly. | ||
166 | */ | ||
167 | insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384, | ||
168 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
169 | slot++; | ||
170 | offset += 4096; | ||
171 | insert_extent(root, offset, 4096, 4096, 0, 0, 0, BTRFS_FILE_EXTENT_REG, | ||
172 | 0, slot); | ||
173 | slot++; | ||
174 | offset += 4096; | ||
175 | insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384, | ||
176 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
177 | slot++; | ||
178 | offset += 8192; | ||
179 | disk_bytenr += 16384; | ||
180 | |||
181 | /* Now for a unwritten prealloc extent */ | ||
182 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096, | ||
183 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); | ||
184 | slot++; | ||
185 | offset += 4096; | ||
186 | |||
187 | /* | ||
188 | * We want to jack up disk_bytenr a little more so the em stuff doesn't | ||
189 | * merge our records. | ||
190 | */ | ||
191 | disk_bytenr += 8192; | ||
192 | |||
193 | /* | ||
194 | * Now for a partially written prealloc extent, basically the same as | ||
195 | * the hole punch example above. Ram_bytes never changes when you mark | ||
196 | * extents written btw. | ||
197 | */ | ||
198 | insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384, | ||
199 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); | ||
200 | slot++; | ||
201 | offset += 4096; | ||
202 | insert_extent(root, offset, 4096, 16384, 4096, disk_bytenr, 16384, | ||
203 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
204 | slot++; | ||
205 | offset += 4096; | ||
206 | insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384, | ||
207 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); | ||
208 | slot++; | ||
209 | offset += 8192; | ||
210 | disk_bytenr += 16384; | ||
211 | |||
212 | /* Now a normal compressed extent */ | ||
213 | insert_extent(root, offset, 8192, 8192, 0, disk_bytenr, 4096, | ||
214 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); | ||
215 | slot++; | ||
216 | offset += 8192; | ||
217 | /* No merges */ | ||
218 | disk_bytenr += 8192; | ||
219 | |||
220 | /* Now a split compressed extent */ | ||
221 | insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 4096, | ||
222 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); | ||
223 | slot++; | ||
224 | offset += 4096; | ||
225 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr + 4096, 4096, | ||
226 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
227 | slot++; | ||
228 | offset += 4096; | ||
229 | insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 4096, | ||
230 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); | ||
231 | slot++; | ||
232 | offset += 8192; | ||
233 | disk_bytenr += 8192; | ||
234 | |||
235 | /* Now extents that have a hole but no hole extent */ | ||
236 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096, | ||
237 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
238 | slot++; | ||
239 | offset += 16384; | ||
240 | disk_bytenr += 4096; | ||
241 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096, | ||
242 | BTRFS_FILE_EXTENT_REG, 0, slot); | ||
243 | } | ||
244 | |||
245 | static unsigned long prealloc_only = 0; | ||
246 | static unsigned long compressed_only = 0; | ||
247 | static unsigned long vacancy_only = 0; | ||
248 | |||
249 | static noinline int test_btrfs_get_extent(void) | ||
250 | { | ||
251 | struct inode *inode = NULL; | ||
252 | struct btrfs_root *root = NULL; | ||
253 | struct extent_map *em = NULL; | ||
254 | u64 orig_start; | ||
255 | u64 disk_bytenr; | ||
256 | u64 offset; | ||
257 | int ret = -ENOMEM; | ||
258 | |||
259 | inode = btrfs_new_test_inode(); | ||
260 | if (!inode) { | ||
261 | test_msg("Couldn't allocate inode\n"); | ||
262 | return ret; | ||
263 | } | ||
264 | |||
265 | BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; | ||
266 | BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; | ||
267 | BTRFS_I(inode)->location.offset = 0; | ||
268 | |||
269 | root = btrfs_alloc_dummy_root(); | ||
270 | if (IS_ERR(root)) { | ||
271 | test_msg("Couldn't allocate root\n"); | ||
272 | goto out; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * We do this since btrfs_get_extent wants to assign em->bdev to | ||
277 | * root->fs_info->fs_devices->latest_bdev. | ||
278 | */ | ||
279 | root->fs_info = alloc_dummy_fs_info(); | ||
280 | if (!root->fs_info) { | ||
281 | test_msg("Couldn't allocate dummy fs info\n"); | ||
282 | goto out; | ||
283 | } | ||
284 | |||
285 | root->node = alloc_dummy_extent_buffer(0, 4096); | ||
286 | if (!root->node) { | ||
287 | test_msg("Couldn't allocate dummy buffer\n"); | ||
288 | goto out; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * We will just free a dummy node if it's ref count is 2 so we need an | ||
293 | * extra ref so our searches don't accidently release our page. | ||
294 | */ | ||
295 | extent_buffer_get(root->node); | ||
296 | btrfs_set_header_nritems(root->node, 0); | ||
297 | btrfs_set_header_level(root->node, 0); | ||
298 | ret = -EINVAL; | ||
299 | |||
300 | /* First with no extents */ | ||
301 | BTRFS_I(inode)->root = root; | ||
302 | em = btrfs_get_extent(inode, NULL, 0, 0, 4096, 0); | ||
303 | if (IS_ERR(em)) { | ||
304 | em = NULL; | ||
305 | test_msg("Got an error when we shouldn't have\n"); | ||
306 | goto out; | ||
307 | } | ||
308 | if (em->block_start != EXTENT_MAP_HOLE) { | ||
309 | test_msg("Expected a hole, got %llu\n", em->block_start); | ||
310 | goto out; | ||
311 | } | ||
312 | if (!test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { | ||
313 | test_msg("Vacancy flag wasn't set properly\n"); | ||
314 | goto out; | ||
315 | } | ||
316 | free_extent_map(em); | ||
317 | btrfs_drop_extent_cache(inode, 0, (u64)-1, 0); | ||
318 | |||
319 | /* | ||
320 | * All of the magic numbers are based on the mapping setup in | ||
321 | * setup_file_extents, so if you change anything there you need to | ||
322 | * update the comment and update the expected values below. | ||
323 | */ | ||
324 | setup_file_extents(root); | ||
325 | |||
326 | em = btrfs_get_extent(inode, NULL, 0, 0, (u64)-1, 0); | ||
327 | if (IS_ERR(em)) { | ||
328 | test_msg("Got an error when we shouldn't have\n"); | ||
329 | goto out; | ||
330 | } | ||
331 | if (em->block_start != EXTENT_MAP_HOLE) { | ||
332 | test_msg("Expected a hole, got %llu\n", em->block_start); | ||
333 | goto out; | ||
334 | } | ||
335 | if (em->start != 0 || em->len != 5) { | ||
336 | test_msg("Unexpected extent wanted start 0 len 5, got start " | ||
337 | "%llu len %llu\n", em->start, em->len); | ||
338 | goto out; | ||
339 | } | ||
340 | if (em->flags != 0) { | ||
341 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
342 | goto out; | ||
343 | } | ||
344 | offset = em->start + em->len; | ||
345 | free_extent_map(em); | ||
346 | |||
347 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
348 | if (IS_ERR(em)) { | ||
349 | test_msg("Got an error when we shouldn't have\n"); | ||
350 | goto out; | ||
351 | } | ||
352 | if (em->block_start != EXTENT_MAP_INLINE) { | ||
353 | test_msg("Expected an inline, got %llu\n", em->block_start); | ||
354 | goto out; | ||
355 | } | ||
356 | if (em->start != offset || em->len != 4091) { | ||
357 | test_msg("Unexpected extent wanted start %llu len 1, got start " | ||
358 | "%llu len %llu\n", offset, em->start, em->len); | ||
359 | goto out; | ||
360 | } | ||
361 | if (em->flags != 0) { | ||
362 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
363 | goto out; | ||
364 | } | ||
365 | /* | ||
366 | * We don't test anything else for inline since it doesn't get set | ||
367 | * unless we have a page for it to write into. Maybe we should change | ||
368 | * this? | ||
369 | */ | ||
370 | offset = em->start + em->len; | ||
371 | free_extent_map(em); | ||
372 | |||
373 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
374 | if (IS_ERR(em)) { | ||
375 | test_msg("Got an error when we shouldn't have\n"); | ||
376 | goto out; | ||
377 | } | ||
378 | if (em->block_start != EXTENT_MAP_HOLE) { | ||
379 | test_msg("Expected a hole, got %llu\n", em->block_start); | ||
380 | goto out; | ||
381 | } | ||
382 | if (em->start != offset || em->len != 4) { | ||
383 | test_msg("Unexpected extent wanted start %llu len 4, got start " | ||
384 | "%llu len %llu\n", offset, em->start, em->len); | ||
385 | goto out; | ||
386 | } | ||
387 | if (em->flags != 0) { | ||
388 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
389 | goto out; | ||
390 | } | ||
391 | offset = em->start + em->len; | ||
392 | free_extent_map(em); | ||
393 | |||
394 | /* Regular extent */ | ||
395 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
396 | if (IS_ERR(em)) { | ||
397 | test_msg("Got an error when we shouldn't have\n"); | ||
398 | goto out; | ||
399 | } | ||
400 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
401 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
402 | goto out; | ||
403 | } | ||
404 | if (em->start != offset || em->len != 4095) { | ||
405 | test_msg("Unexpected extent wanted start %llu len 4095, got " | ||
406 | "start %llu len %llu\n", offset, em->start, em->len); | ||
407 | goto out; | ||
408 | } | ||
409 | if (em->flags != 0) { | ||
410 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
411 | goto out; | ||
412 | } | ||
413 | if (em->orig_start != em->start) { | ||
414 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
415 | em->orig_start); | ||
416 | goto out; | ||
417 | } | ||
418 | offset = em->start + em->len; | ||
419 | free_extent_map(em); | ||
420 | |||
421 | /* The next 3 are split extents */ | ||
422 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
423 | if (IS_ERR(em)) { | ||
424 | test_msg("Got an error when we shouldn't have\n"); | ||
425 | goto out; | ||
426 | } | ||
427 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
428 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
429 | goto out; | ||
430 | } | ||
431 | if (em->start != offset || em->len != 4096) { | ||
432 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
433 | "start %llu len %llu\n", offset, em->start, em->len); | ||
434 | goto out; | ||
435 | } | ||
436 | if (em->flags != 0) { | ||
437 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
438 | goto out; | ||
439 | } | ||
440 | if (em->orig_start != em->start) { | ||
441 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
442 | em->orig_start); | ||
443 | goto out; | ||
444 | } | ||
445 | disk_bytenr = em->block_start; | ||
446 | orig_start = em->start; | ||
447 | offset = em->start + em->len; | ||
448 | free_extent_map(em); | ||
449 | |||
450 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
451 | if (IS_ERR(em)) { | ||
452 | test_msg("Got an error when we shouldn't have\n"); | ||
453 | goto out; | ||
454 | } | ||
455 | if (em->block_start != EXTENT_MAP_HOLE) { | ||
456 | test_msg("Expected a hole, got %llu\n", em->block_start); | ||
457 | goto out; | ||
458 | } | ||
459 | if (em->start != offset || em->len != 4096) { | ||
460 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
461 | "start %llu len %llu\n", offset, em->start, em->len); | ||
462 | goto out; | ||
463 | } | ||
464 | if (em->flags != 0) { | ||
465 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
466 | goto out; | ||
467 | } | ||
468 | offset = em->start + em->len; | ||
469 | free_extent_map(em); | ||
470 | |||
471 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
472 | if (IS_ERR(em)) { | ||
473 | test_msg("Got an error when we shouldn't have\n"); | ||
474 | goto out; | ||
475 | } | ||
476 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
477 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
478 | goto out; | ||
479 | } | ||
480 | if (em->start != offset || em->len != 8192) { | ||
481 | test_msg("Unexpected extent wanted start %llu len 8192, got " | ||
482 | "start %llu len %llu\n", offset, em->start, em->len); | ||
483 | goto out; | ||
484 | } | ||
485 | if (em->flags != 0) { | ||
486 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
487 | goto out; | ||
488 | } | ||
489 | if (em->orig_start != orig_start) { | ||
490 | test_msg("Wrong orig offset, want %llu, have %llu\n", | ||
491 | orig_start, em->orig_start); | ||
492 | goto out; | ||
493 | } | ||
494 | disk_bytenr += (em->start - orig_start); | ||
495 | if (em->block_start != disk_bytenr) { | ||
496 | test_msg("Wrong block start, want %llu, have %llu\n", | ||
497 | disk_bytenr, em->block_start); | ||
498 | goto out; | ||
499 | } | ||
500 | offset = em->start + em->len; | ||
501 | free_extent_map(em); | ||
502 | |||
503 | /* Prealloc extent */ | ||
504 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
505 | if (IS_ERR(em)) { | ||
506 | test_msg("Got an error when we shouldn't have\n"); | ||
507 | goto out; | ||
508 | } | ||
509 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
510 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
511 | goto out; | ||
512 | } | ||
513 | if (em->start != offset || em->len != 4096) { | ||
514 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
515 | "start %llu len %llu\n", offset, em->start, em->len); | ||
516 | goto out; | ||
517 | } | ||
518 | if (em->flags != prealloc_only) { | ||
519 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
520 | prealloc_only, em->flags); | ||
521 | goto out; | ||
522 | } | ||
523 | if (em->orig_start != em->start) { | ||
524 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
525 | em->orig_start); | ||
526 | goto out; | ||
527 | } | ||
528 | offset = em->start + em->len; | ||
529 | free_extent_map(em); | ||
530 | |||
531 | /* The next 3 are a half written prealloc extent */ | ||
532 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
533 | if (IS_ERR(em)) { | ||
534 | test_msg("Got an error when we shouldn't have\n"); | ||
535 | goto out; | ||
536 | } | ||
537 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
538 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
539 | goto out; | ||
540 | } | ||
541 | if (em->start != offset || em->len != 4096) { | ||
542 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
543 | "start %llu len %llu\n", offset, em->start, em->len); | ||
544 | goto out; | ||
545 | } | ||
546 | if (em->flags != prealloc_only) { | ||
547 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
548 | prealloc_only, em->flags); | ||
549 | goto out; | ||
550 | } | ||
551 | if (em->orig_start != em->start) { | ||
552 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
553 | em->orig_start); | ||
554 | goto out; | ||
555 | } | ||
556 | disk_bytenr = em->block_start; | ||
557 | orig_start = em->start; | ||
558 | offset = em->start + em->len; | ||
559 | free_extent_map(em); | ||
560 | |||
561 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
562 | if (IS_ERR(em)) { | ||
563 | test_msg("Got an error when we shouldn't have\n"); | ||
564 | goto out; | ||
565 | } | ||
566 | if (em->block_start >= EXTENT_MAP_HOLE) { | ||
567 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
568 | goto out; | ||
569 | } | ||
570 | if (em->start != offset || em->len != 4096) { | ||
571 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
572 | "start %llu len %llu\n", offset, em->start, em->len); | ||
573 | goto out; | ||
574 | } | ||
575 | if (em->flags != 0) { | ||
576 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
577 | goto out; | ||
578 | } | ||
579 | if (em->orig_start != orig_start) { | ||
580 | test_msg("Unexpected orig offset, wanted %llu, have %llu\n", | ||
581 | orig_start, em->orig_start); | ||
582 | goto out; | ||
583 | } | ||
584 | if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) { | ||
585 | test_msg("Unexpected block start, wanted %llu, have %llu\n", | ||
586 | disk_bytenr + (em->start - em->orig_start), | ||
587 | em->block_start); | ||
588 | goto out; | ||
589 | } | ||
590 | offset = em->start + em->len; | ||
591 | free_extent_map(em); | ||
592 | |||
593 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
594 | if (IS_ERR(em)) { | ||
595 | test_msg("Got an error when we shouldn't have\n"); | ||
596 | goto out; | ||
597 | } | ||
598 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
599 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
600 | goto out; | ||
601 | } | ||
602 | if (em->start != offset || em->len != 8192) { | ||
603 | test_msg("Unexpected extent wanted start %llu len 8192, got " | ||
604 | "start %llu len %llu\n", offset, em->start, em->len); | ||
605 | goto out; | ||
606 | } | ||
607 | if (em->flags != prealloc_only) { | ||
608 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
609 | prealloc_only, em->flags); | ||
610 | goto out; | ||
611 | } | ||
612 | if (em->orig_start != orig_start) { | ||
613 | test_msg("Wrong orig offset, want %llu, have %llu\n", orig_start, | ||
614 | em->orig_start); | ||
615 | goto out; | ||
616 | } | ||
617 | if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) { | ||
618 | test_msg("Unexpected block start, wanted %llu, have %llu\n", | ||
619 | disk_bytenr + (em->start - em->orig_start), | ||
620 | em->block_start); | ||
621 | goto out; | ||
622 | } | ||
623 | offset = em->start + em->len; | ||
624 | free_extent_map(em); | ||
625 | |||
626 | /* Now for the compressed extent */ | ||
627 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
628 | if (IS_ERR(em)) { | ||
629 | test_msg("Got an error when we shouldn't have\n"); | ||
630 | goto out; | ||
631 | } | ||
632 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
633 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
634 | goto out; | ||
635 | } | ||
636 | if (em->start != offset || em->len != 8192) { | ||
637 | test_msg("Unexpected extent wanted start %llu len 8192, got " | ||
638 | "start %llu len %llu\n", offset, em->start, em->len); | ||
639 | goto out; | ||
640 | } | ||
641 | if (em->flags != compressed_only) { | ||
642 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
643 | compressed_only, em->flags); | ||
644 | goto out; | ||
645 | } | ||
646 | if (em->orig_start != em->start) { | ||
647 | test_msg("Wrong orig offset, want %llu, have %llu\n", | ||
648 | em->start, em->orig_start); | ||
649 | goto out; | ||
650 | } | ||
651 | if (em->compress_type != BTRFS_COMPRESS_ZLIB) { | ||
652 | test_msg("Unexpected compress type, wanted %d, got %d\n", | ||
653 | BTRFS_COMPRESS_ZLIB, em->compress_type); | ||
654 | goto out; | ||
655 | } | ||
656 | offset = em->start + em->len; | ||
657 | free_extent_map(em); | ||
658 | |||
659 | /* Split compressed extent */ | ||
660 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
661 | if (IS_ERR(em)) { | ||
662 | test_msg("Got an error when we shouldn't have\n"); | ||
663 | goto out; | ||
664 | } | ||
665 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
666 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
667 | goto out; | ||
668 | } | ||
669 | if (em->start != offset || em->len != 4096) { | ||
670 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
671 | "start %llu len %llu\n", offset, em->start, em->len); | ||
672 | goto out; | ||
673 | } | ||
674 | if (em->flags != compressed_only) { | ||
675 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
676 | compressed_only, em->flags); | ||
677 | goto out; | ||
678 | } | ||
679 | if (em->orig_start != em->start) { | ||
680 | test_msg("Wrong orig offset, want %llu, have %llu\n", | ||
681 | em->start, em->orig_start); | ||
682 | goto out; | ||
683 | } | ||
684 | if (em->compress_type != BTRFS_COMPRESS_ZLIB) { | ||
685 | test_msg("Unexpected compress type, wanted %d, got %d\n", | ||
686 | BTRFS_COMPRESS_ZLIB, em->compress_type); | ||
687 | goto out; | ||
688 | } | ||
689 | disk_bytenr = em->block_start; | ||
690 | orig_start = em->start; | ||
691 | offset = em->start + em->len; | ||
692 | free_extent_map(em); | ||
693 | |||
694 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
695 | if (IS_ERR(em)) { | ||
696 | test_msg("Got an error when we shouldn't have\n"); | ||
697 | goto out; | ||
698 | } | ||
699 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
700 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
701 | goto out; | ||
702 | } | ||
703 | if (em->start != offset || em->len != 4096) { | ||
704 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
705 | "start %llu len %llu\n", offset, em->start, em->len); | ||
706 | goto out; | ||
707 | } | ||
708 | if (em->flags != 0) { | ||
709 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
710 | goto out; | ||
711 | } | ||
712 | if (em->orig_start != em->start) { | ||
713 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
714 | em->orig_start); | ||
715 | goto out; | ||
716 | } | ||
717 | offset = em->start + em->len; | ||
718 | free_extent_map(em); | ||
719 | |||
720 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
721 | if (IS_ERR(em)) { | ||
722 | test_msg("Got an error when we shouldn't have\n"); | ||
723 | goto out; | ||
724 | } | ||
725 | if (em->block_start != disk_bytenr) { | ||
726 | test_msg("Block start does not match, want %llu got %llu\n", | ||
727 | disk_bytenr, em->block_start); | ||
728 | goto out; | ||
729 | } | ||
730 | if (em->start != offset || em->len != 8192) { | ||
731 | test_msg("Unexpected extent wanted start %llu len 8192, got " | ||
732 | "start %llu len %llu\n", offset, em->start, em->len); | ||
733 | goto out; | ||
734 | } | ||
735 | if (em->flags != compressed_only) { | ||
736 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
737 | compressed_only, em->flags); | ||
738 | goto out; | ||
739 | } | ||
740 | if (em->orig_start != orig_start) { | ||
741 | test_msg("Wrong orig offset, want %llu, have %llu\n", | ||
742 | em->start, orig_start); | ||
743 | goto out; | ||
744 | } | ||
745 | if (em->compress_type != BTRFS_COMPRESS_ZLIB) { | ||
746 | test_msg("Unexpected compress type, wanted %d, got %d\n", | ||
747 | BTRFS_COMPRESS_ZLIB, em->compress_type); | ||
748 | goto out; | ||
749 | } | ||
750 | offset = em->start + em->len; | ||
751 | free_extent_map(em); | ||
752 | |||
753 | /* A hole between regular extents but no hole extent */ | ||
754 | em = btrfs_get_extent(inode, NULL, 0, offset + 6, 4096, 0); | ||
755 | if (IS_ERR(em)) { | ||
756 | test_msg("Got an error when we shouldn't have\n"); | ||
757 | goto out; | ||
758 | } | ||
759 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
760 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
761 | goto out; | ||
762 | } | ||
763 | if (em->start != offset || em->len != 4096) { | ||
764 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
765 | "start %llu len %llu\n", offset, em->start, em->len); | ||
766 | goto out; | ||
767 | } | ||
768 | if (em->flags != 0) { | ||
769 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
770 | goto out; | ||
771 | } | ||
772 | if (em->orig_start != em->start) { | ||
773 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
774 | em->orig_start); | ||
775 | goto out; | ||
776 | } | ||
777 | offset = em->start + em->len; | ||
778 | free_extent_map(em); | ||
779 | |||
780 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096 * 1024, 0); | ||
781 | if (IS_ERR(em)) { | ||
782 | test_msg("Got an error when we shouldn't have\n"); | ||
783 | goto out; | ||
784 | } | ||
785 | if (em->block_start != EXTENT_MAP_HOLE) { | ||
786 | test_msg("Expected a hole extent, got %llu\n", em->block_start); | ||
787 | goto out; | ||
788 | } | ||
789 | /* | ||
790 | * Currently we just return a length that we requested rather than the | ||
791 | * length of the actual hole, if this changes we'll have to change this | ||
792 | * test. | ||
793 | */ | ||
794 | if (em->start != offset || em->len != 12288) { | ||
795 | test_msg("Unexpected extent wanted start %llu len 12288, got " | ||
796 | "start %llu len %llu\n", offset, em->start, em->len); | ||
797 | goto out; | ||
798 | } | ||
799 | if (em->flags != vacancy_only) { | ||
800 | test_msg("Unexpected flags set, want %lu have %lu\n", | ||
801 | vacancy_only, em->flags); | ||
802 | goto out; | ||
803 | } | ||
804 | if (em->orig_start != em->start) { | ||
805 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
806 | em->orig_start); | ||
807 | goto out; | ||
808 | } | ||
809 | offset = em->start + em->len; | ||
810 | free_extent_map(em); | ||
811 | |||
812 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | ||
813 | if (IS_ERR(em)) { | ||
814 | test_msg("Got an error when we shouldn't have\n"); | ||
815 | goto out; | ||
816 | } | ||
817 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
818 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
819 | goto out; | ||
820 | } | ||
821 | if (em->start != offset || em->len != 4096) { | ||
822 | test_msg("Unexpected extent wanted start %llu len 4096, got " | ||
823 | "start %llu len %llu\n", offset, em->start, em->len); | ||
824 | goto out; | ||
825 | } | ||
826 | if (em->flags != 0) { | ||
827 | test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); | ||
828 | goto out; | ||
829 | } | ||
830 | if (em->orig_start != em->start) { | ||
831 | test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, | ||
832 | em->orig_start); | ||
833 | goto out; | ||
834 | } | ||
835 | ret = 0; | ||
836 | out: | ||
837 | if (!IS_ERR(em)) | ||
838 | free_extent_map(em); | ||
839 | iput(inode); | ||
840 | free_dummy_root(root); | ||
841 | return ret; | ||
842 | } | ||
843 | |||
844 | static int test_hole_first(void) | ||
845 | { | ||
846 | struct inode *inode = NULL; | ||
847 | struct btrfs_root *root = NULL; | ||
848 | struct extent_map *em = NULL; | ||
849 | int ret = -ENOMEM; | ||
850 | |||
851 | inode = btrfs_new_test_inode(); | ||
852 | if (!inode) { | ||
853 | test_msg("Couldn't allocate inode\n"); | ||
854 | return ret; | ||
855 | } | ||
856 | |||
857 | BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; | ||
858 | BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; | ||
859 | BTRFS_I(inode)->location.offset = 0; | ||
860 | |||
861 | root = btrfs_alloc_dummy_root(); | ||
862 | if (IS_ERR(root)) { | ||
863 | test_msg("Couldn't allocate root\n"); | ||
864 | goto out; | ||
865 | } | ||
866 | |||
867 | root->fs_info = alloc_dummy_fs_info(); | ||
868 | if (!root->fs_info) { | ||
869 | test_msg("Couldn't allocate dummy fs info\n"); | ||
870 | goto out; | ||
871 | } | ||
872 | |||
873 | root->node = alloc_dummy_extent_buffer(0, 4096); | ||
874 | if (!root->node) { | ||
875 | test_msg("Couldn't allocate dummy buffer\n"); | ||
876 | goto out; | ||
877 | } | ||
878 | |||
879 | extent_buffer_get(root->node); | ||
880 | btrfs_set_header_nritems(root->node, 0); | ||
881 | btrfs_set_header_level(root->node, 0); | ||
882 | BTRFS_I(inode)->root = root; | ||
883 | ret = -EINVAL; | ||
884 | |||
885 | /* | ||
886 | * Need a blank inode item here just so we don't confuse | ||
887 | * btrfs_get_extent. | ||
888 | */ | ||
889 | insert_inode_item_key(root); | ||
890 | insert_extent(root, 4096, 4096, 4096, 0, 4096, 4096, | ||
891 | BTRFS_FILE_EXTENT_REG, 0, 1); | ||
892 | em = btrfs_get_extent(inode, NULL, 0, 0, 8192, 0); | ||
893 | if (IS_ERR(em)) { | ||
894 | test_msg("Got an error when we shouldn't have\n"); | ||
895 | goto out; | ||
896 | } | ||
897 | if (em->block_start != EXTENT_MAP_HOLE) { | ||
898 | test_msg("Expected a hole, got %llu\n", em->block_start); | ||
899 | goto out; | ||
900 | } | ||
901 | if (em->start != 0 || em->len != 4096) { | ||
902 | test_msg("Unexpected extent wanted start 0 len 4096, got start " | ||
903 | "%llu len %llu\n", em->start, em->len); | ||
904 | goto out; | ||
905 | } | ||
906 | if (em->flags != vacancy_only) { | ||
907 | test_msg("Wrong flags, wanted %lu, have %lu\n", vacancy_only, | ||
908 | em->flags); | ||
909 | goto out; | ||
910 | } | ||
911 | free_extent_map(em); | ||
912 | |||
913 | em = btrfs_get_extent(inode, NULL, 0, 4096, 8192, 0); | ||
914 | if (IS_ERR(em)) { | ||
915 | test_msg("Got an error when we shouldn't have\n"); | ||
916 | goto out; | ||
917 | } | ||
918 | if (em->block_start != 4096) { | ||
919 | test_msg("Expected a real extent, got %llu\n", em->block_start); | ||
920 | goto out; | ||
921 | } | ||
922 | if (em->start != 4096 || em->len != 4096) { | ||
923 | test_msg("Unexpected extent wanted start 4096 len 4096, got " | ||
924 | "start %llu len %llu\n", em->start, em->len); | ||
925 | goto out; | ||
926 | } | ||
927 | if (em->flags != 0) { | ||
928 | test_msg("Unexpected flags set, wanted 0 got %lu\n", | ||
929 | em->flags); | ||
930 | goto out; | ||
931 | } | ||
932 | ret = 0; | ||
933 | out: | ||
934 | if (!IS_ERR(em)) | ||
935 | free_extent_map(em); | ||
936 | iput(inode); | ||
937 | free_dummy_root(root); | ||
938 | return ret; | ||
939 | } | ||
940 | |||
941 | int btrfs_test_inodes(void) | ||
942 | { | ||
943 | int ret; | ||
944 | |||
945 | set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only); | ||
946 | set_bit(EXTENT_FLAG_VACANCY, &vacancy_only); | ||
947 | set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only); | ||
948 | |||
949 | test_msg("Running btrfs_get_extent tests\n"); | ||
950 | ret = test_btrfs_get_extent(); | ||
951 | if (ret) | ||
952 | return ret; | ||
953 | test_msg("Running hole first btrfs_get_extent test\n"); | ||
954 | return test_hole_first(); | ||
955 | } | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8c81bdc1ef9b..57c16b46afbd 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -57,7 +57,7 @@ static unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = { | |||
57 | __TRANS_JOIN_NOLOCK), | 57 | __TRANS_JOIN_NOLOCK), |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static void put_transaction(struct btrfs_transaction *transaction) | 60 | void btrfs_put_transaction(struct btrfs_transaction *transaction) |
61 | { | 61 | { |
62 | WARN_ON(atomic_read(&transaction->use_count) == 0); | 62 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
63 | if (atomic_dec_and_test(&transaction->use_count)) { | 63 | if (atomic_dec_and_test(&transaction->use_count)) { |
@@ -332,7 +332,7 @@ static void wait_current_trans(struct btrfs_root *root) | |||
332 | wait_event(root->fs_info->transaction_wait, | 332 | wait_event(root->fs_info->transaction_wait, |
333 | cur_trans->state >= TRANS_STATE_UNBLOCKED || | 333 | cur_trans->state >= TRANS_STATE_UNBLOCKED || |
334 | cur_trans->aborted); | 334 | cur_trans->aborted); |
335 | put_transaction(cur_trans); | 335 | btrfs_put_transaction(cur_trans); |
336 | } else { | 336 | } else { |
337 | spin_unlock(&root->fs_info->trans_lock); | 337 | spin_unlock(&root->fs_info->trans_lock); |
338 | } | 338 | } |
@@ -353,6 +353,17 @@ static int may_wait_transaction(struct btrfs_root *root, int type) | |||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | static inline bool need_reserve_reloc_root(struct btrfs_root *root) | ||
357 | { | ||
358 | if (!root->fs_info->reloc_ctl || | ||
359 | !root->ref_cows || | ||
360 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID || | ||
361 | root->reloc_root) | ||
362 | return false; | ||
363 | |||
364 | return true; | ||
365 | } | ||
366 | |||
356 | static struct btrfs_trans_handle * | 367 | static struct btrfs_trans_handle * |
357 | start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | 368 | start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, |
358 | enum btrfs_reserve_flush_enum flush) | 369 | enum btrfs_reserve_flush_enum flush) |
@@ -360,8 +371,9 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | |||
360 | struct btrfs_trans_handle *h; | 371 | struct btrfs_trans_handle *h; |
361 | struct btrfs_transaction *cur_trans; | 372 | struct btrfs_transaction *cur_trans; |
362 | u64 num_bytes = 0; | 373 | u64 num_bytes = 0; |
363 | int ret; | ||
364 | u64 qgroup_reserved = 0; | 374 | u64 qgroup_reserved = 0; |
375 | bool reloc_reserved = false; | ||
376 | int ret; | ||
365 | 377 | ||
366 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) | 378 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) |
367 | return ERR_PTR(-EROFS); | 379 | return ERR_PTR(-EROFS); |
@@ -390,6 +402,14 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | |||
390 | } | 402 | } |
391 | 403 | ||
392 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); | 404 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); |
405 | /* | ||
406 | * Do the reservation for the relocation root creation | ||
407 | */ | ||
408 | if (unlikely(need_reserve_reloc_root(root))) { | ||
409 | num_bytes += root->nodesize; | ||
410 | reloc_reserved = true; | ||
411 | } | ||
412 | |||
393 | ret = btrfs_block_rsv_add(root, | 413 | ret = btrfs_block_rsv_add(root, |
394 | &root->fs_info->trans_block_rsv, | 414 | &root->fs_info->trans_block_rsv, |
395 | num_bytes, flush); | 415 | num_bytes, flush); |
@@ -451,6 +471,7 @@ again: | |||
451 | h->delayed_ref_elem.seq = 0; | 471 | h->delayed_ref_elem.seq = 0; |
452 | h->type = type; | 472 | h->type = type; |
453 | h->allocating_chunk = false; | 473 | h->allocating_chunk = false; |
474 | h->reloc_reserved = false; | ||
454 | INIT_LIST_HEAD(&h->qgroup_ref_list); | 475 | INIT_LIST_HEAD(&h->qgroup_ref_list); |
455 | INIT_LIST_HEAD(&h->new_bgs); | 476 | INIT_LIST_HEAD(&h->new_bgs); |
456 | 477 | ||
@@ -466,6 +487,7 @@ again: | |||
466 | h->transid, num_bytes, 1); | 487 | h->transid, num_bytes, 1); |
467 | h->block_rsv = &root->fs_info->trans_block_rsv; | 488 | h->block_rsv = &root->fs_info->trans_block_rsv; |
468 | h->bytes_reserved = num_bytes; | 489 | h->bytes_reserved = num_bytes; |
490 | h->reloc_reserved = reloc_reserved; | ||
469 | } | 491 | } |
470 | h->qgroup_reserved = qgroup_reserved; | 492 | h->qgroup_reserved = qgroup_reserved; |
471 | 493 | ||
@@ -610,7 +632,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
610 | } | 632 | } |
611 | 633 | ||
612 | wait_for_commit(root, cur_trans); | 634 | wait_for_commit(root, cur_trans); |
613 | put_transaction(cur_trans); | 635 | btrfs_put_transaction(cur_trans); |
614 | out: | 636 | out: |
615 | return ret; | 637 | return ret; |
616 | } | 638 | } |
@@ -735,7 +757,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
735 | smp_mb(); | 757 | smp_mb(); |
736 | if (waitqueue_active(&cur_trans->writer_wait)) | 758 | if (waitqueue_active(&cur_trans->writer_wait)) |
737 | wake_up(&cur_trans->writer_wait); | 759 | wake_up(&cur_trans->writer_wait); |
738 | put_transaction(cur_trans); | 760 | btrfs_put_transaction(cur_trans); |
739 | 761 | ||
740 | if (current->journal_info == trans) | 762 | if (current->journal_info == trans) |
741 | current->journal_info = NULL; | 763 | current->journal_info = NULL; |
@@ -744,8 +766,10 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
744 | btrfs_run_delayed_iputs(root); | 766 | btrfs_run_delayed_iputs(root); |
745 | 767 | ||
746 | if (trans->aborted || | 768 | if (trans->aborted || |
747 | test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) | 769 | test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) { |
770 | wake_up_process(info->transaction_kthread); | ||
748 | err = -EIO; | 771 | err = -EIO; |
772 | } | ||
749 | assert_qgroups_uptodate(trans); | 773 | assert_qgroups_uptodate(trans); |
750 | 774 | ||
751 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 775 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
@@ -948,16 +972,19 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
948 | return ret; | 972 | return ret; |
949 | 973 | ||
950 | ret = btrfs_run_dev_stats(trans, root->fs_info); | 974 | ret = btrfs_run_dev_stats(trans, root->fs_info); |
951 | WARN_ON(ret); | 975 | if (ret) |
976 | return ret; | ||
952 | ret = btrfs_run_dev_replace(trans, root->fs_info); | 977 | ret = btrfs_run_dev_replace(trans, root->fs_info); |
953 | WARN_ON(ret); | 978 | if (ret) |
954 | 979 | return ret; | |
955 | ret = btrfs_run_qgroups(trans, root->fs_info); | 980 | ret = btrfs_run_qgroups(trans, root->fs_info); |
956 | BUG_ON(ret); | 981 | if (ret) |
982 | return ret; | ||
957 | 983 | ||
958 | /* run_qgroups might have added some more refs */ | 984 | /* run_qgroups might have added some more refs */ |
959 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 985 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
960 | BUG_ON(ret); | 986 | if (ret) |
987 | return ret; | ||
961 | 988 | ||
962 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { | 989 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { |
963 | next = fs_info->dirty_cowonly_roots.next; | 990 | next = fs_info->dirty_cowonly_roots.next; |
@@ -1510,7 +1537,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1510 | if (current->journal_info == trans) | 1537 | if (current->journal_info == trans) |
1511 | current->journal_info = NULL; | 1538 | current->journal_info = NULL; |
1512 | 1539 | ||
1513 | put_transaction(cur_trans); | 1540 | btrfs_put_transaction(cur_trans); |
1514 | return 0; | 1541 | return 0; |
1515 | } | 1542 | } |
1516 | 1543 | ||
@@ -1552,8 +1579,10 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1552 | root->fs_info->running_transaction = NULL; | 1579 | root->fs_info->running_transaction = NULL; |
1553 | spin_unlock(&root->fs_info->trans_lock); | 1580 | spin_unlock(&root->fs_info->trans_lock); |
1554 | 1581 | ||
1555 | put_transaction(cur_trans); | 1582 | if (trans->type & __TRANS_FREEZABLE) |
1556 | put_transaction(cur_trans); | 1583 | sb_end_intwrite(root->fs_info->sb); |
1584 | btrfs_put_transaction(cur_trans); | ||
1585 | btrfs_put_transaction(cur_trans); | ||
1557 | 1586 | ||
1558 | trace_btrfs_transaction_commit(root); | 1587 | trace_btrfs_transaction_commit(root); |
1559 | 1588 | ||
@@ -1571,15 +1600,19 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
1571 | int ret; | 1600 | int ret; |
1572 | 1601 | ||
1573 | ret = btrfs_run_delayed_items(trans, root); | 1602 | ret = btrfs_run_delayed_items(trans, root); |
1574 | if (ret) | ||
1575 | return ret; | ||
1576 | |||
1577 | /* | 1603 | /* |
1578 | * running the delayed items may have added new refs. account | 1604 | * running the delayed items may have added new refs. account |
1579 | * them now so that they hinder processing of more delayed refs | 1605 | * them now so that they hinder processing of more delayed refs |
1580 | * as little as possible. | 1606 | * as little as possible. |
1581 | */ | 1607 | */ |
1582 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | 1608 | if (ret) { |
1609 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1610 | return ret; | ||
1611 | } | ||
1612 | |||
1613 | ret = btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1614 | if (ret) | ||
1615 | return ret; | ||
1583 | 1616 | ||
1584 | /* | 1617 | /* |
1585 | * rename don't use btrfs_join_transaction, so, once we | 1618 | * rename don't use btrfs_join_transaction, so, once we |
@@ -1596,14 +1629,14 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
1596 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) | 1629 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) |
1597 | { | 1630 | { |
1598 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) | 1631 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) |
1599 | return btrfs_start_all_delalloc_inodes(fs_info, 1); | 1632 | return btrfs_start_delalloc_roots(fs_info, 1); |
1600 | return 0; | 1633 | return 0; |
1601 | } | 1634 | } |
1602 | 1635 | ||
1603 | static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) | 1636 | static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) |
1604 | { | 1637 | { |
1605 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) | 1638 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) |
1606 | btrfs_wait_all_ordered_extents(fs_info); | 1639 | btrfs_wait_ordered_roots(fs_info, -1); |
1607 | } | 1640 | } |
1608 | 1641 | ||
1609 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | 1642 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, |
@@ -1669,7 +1702,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1669 | 1702 | ||
1670 | wait_for_commit(root, cur_trans); | 1703 | wait_for_commit(root, cur_trans); |
1671 | 1704 | ||
1672 | put_transaction(cur_trans); | 1705 | btrfs_put_transaction(cur_trans); |
1673 | 1706 | ||
1674 | return ret; | 1707 | return ret; |
1675 | } | 1708 | } |
@@ -1686,7 +1719,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1686 | 1719 | ||
1687 | wait_for_commit(root, prev_trans); | 1720 | wait_for_commit(root, prev_trans); |
1688 | 1721 | ||
1689 | put_transaction(prev_trans); | 1722 | btrfs_put_transaction(prev_trans); |
1690 | } else { | 1723 | } else { |
1691 | spin_unlock(&root->fs_info->trans_lock); | 1724 | spin_unlock(&root->fs_info->trans_lock); |
1692 | } | 1725 | } |
@@ -1885,8 +1918,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1885 | list_del_init(&cur_trans->list); | 1918 | list_del_init(&cur_trans->list); |
1886 | spin_unlock(&root->fs_info->trans_lock); | 1919 | spin_unlock(&root->fs_info->trans_lock); |
1887 | 1920 | ||
1888 | put_transaction(cur_trans); | 1921 | btrfs_put_transaction(cur_trans); |
1889 | put_transaction(cur_trans); | 1922 | btrfs_put_transaction(cur_trans); |
1890 | 1923 | ||
1891 | if (trans->type & __TRANS_FREEZABLE) | 1924 | if (trans->type & __TRANS_FREEZABLE) |
1892 | sb_end_intwrite(root->fs_info->sb); | 1925 | sb_end_intwrite(root->fs_info->sb); |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 5c2af8491621..7657d115067d 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -92,6 +92,7 @@ struct btrfs_trans_handle { | |||
92 | short aborted; | 92 | short aborted; |
93 | short adding_csums; | 93 | short adding_csums; |
94 | bool allocating_chunk; | 94 | bool allocating_chunk; |
95 | bool reloc_reserved; | ||
95 | unsigned int type; | 96 | unsigned int type; |
96 | /* | 97 | /* |
97 | * this root is only needed to validate that the root passed to | 98 | * this root is only needed to validate that the root passed to |
@@ -166,4 +167,5 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, | |||
166 | struct extent_io_tree *dirty_pages, int mark); | 167 | struct extent_io_tree *dirty_pages, int mark); |
167 | int btrfs_transaction_blocked(struct btrfs_fs_info *info); | 168 | int btrfs_transaction_blocked(struct btrfs_fs_info *info); |
168 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info); | 169 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info); |
170 | void btrfs_put_transaction(struct btrfs_transaction *transaction); | ||
169 | #endif | 171 | #endif |
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index 94e05c1f118a..76928ca97741 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c | |||
@@ -37,7 +37,6 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
37 | int ret = 0; | 37 | int ret = 0; |
38 | int wret; | 38 | int wret; |
39 | int level; | 39 | int level; |
40 | int is_extent = 0; | ||
41 | int next_key_ret = 0; | 40 | int next_key_ret = 0; |
42 | u64 last_ret = 0; | 41 | u64 last_ret = 0; |
43 | u64 min_trans = 0; | 42 | u64 min_trans = 0; |
@@ -50,7 +49,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
50 | goto out; | 49 | goto out; |
51 | } | 50 | } |
52 | 51 | ||
53 | if (root->ref_cows == 0 && !is_extent) | 52 | if (root->ref_cows == 0) |
54 | goto out; | 53 | goto out; |
55 | 54 | ||
56 | if (btrfs_test_opt(root, SSD)) | 55 | if (btrfs_test_opt(root, SSD)) |
@@ -85,7 +84,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
85 | 84 | ||
86 | path->keep_locks = 1; | 85 | path->keep_locks = 1; |
87 | 86 | ||
88 | ret = btrfs_search_forward(root, &key, NULL, path, min_trans); | 87 | ret = btrfs_search_forward(root, &key, path, min_trans); |
89 | if (ret < 0) | 88 | if (ret < 0) |
90 | goto out; | 89 | goto out; |
91 | if (ret > 0) { | 90 | if (ret > 0) { |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 79f057c0619a..744553c83fe2 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "locking.h" | 26 | #include "locking.h" |
27 | #include "print-tree.h" | 27 | #include "print-tree.h" |
28 | #include "backref.h" | 28 | #include "backref.h" |
29 | #include "compat.h" | ||
30 | #include "tree-log.h" | 29 | #include "tree-log.h" |
31 | #include "hash.h" | 30 | #include "hash.h" |
32 | 31 | ||
@@ -936,7 +935,7 @@ again: | |||
936 | parent_objectid, | 935 | parent_objectid, |
937 | victim_name, | 936 | victim_name, |
938 | victim_name_len)) { | 937 | victim_name_len)) { |
939 | btrfs_inc_nlink(inode); | 938 | inc_nlink(inode); |
940 | btrfs_release_path(path); | 939 | btrfs_release_path(path); |
941 | 940 | ||
942 | ret = btrfs_unlink_inode(trans, root, dir, | 941 | ret = btrfs_unlink_inode(trans, root, dir, |
@@ -1006,7 +1005,7 @@ again: | |||
1006 | victim_parent = read_one_inode(root, | 1005 | victim_parent = read_one_inode(root, |
1007 | parent_objectid); | 1006 | parent_objectid); |
1008 | if (victim_parent) { | 1007 | if (victim_parent) { |
1009 | btrfs_inc_nlink(inode); | 1008 | inc_nlink(inode); |
1010 | btrfs_release_path(path); | 1009 | btrfs_release_path(path); |
1011 | 1010 | ||
1012 | ret = btrfs_unlink_inode(trans, root, | 1011 | ret = btrfs_unlink_inode(trans, root, |
@@ -1113,11 +1112,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1113 | struct extent_buffer *eb, int slot, | 1112 | struct extent_buffer *eb, int slot, |
1114 | struct btrfs_key *key) | 1113 | struct btrfs_key *key) |
1115 | { | 1114 | { |
1116 | struct inode *dir; | 1115 | struct inode *dir = NULL; |
1117 | struct inode *inode; | 1116 | struct inode *inode = NULL; |
1118 | unsigned long ref_ptr; | 1117 | unsigned long ref_ptr; |
1119 | unsigned long ref_end; | 1118 | unsigned long ref_end; |
1120 | char *name; | 1119 | char *name = NULL; |
1121 | int namelen; | 1120 | int namelen; |
1122 | int ret; | 1121 | int ret; |
1123 | int search_done = 0; | 1122 | int search_done = 0; |
@@ -1150,13 +1149,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1150 | * care of the rest | 1149 | * care of the rest |
1151 | */ | 1150 | */ |
1152 | dir = read_one_inode(root, parent_objectid); | 1151 | dir = read_one_inode(root, parent_objectid); |
1153 | if (!dir) | 1152 | if (!dir) { |
1154 | return -ENOENT; | 1153 | ret = -ENOENT; |
1154 | goto out; | ||
1155 | } | ||
1155 | 1156 | ||
1156 | inode = read_one_inode(root, inode_objectid); | 1157 | inode = read_one_inode(root, inode_objectid); |
1157 | if (!inode) { | 1158 | if (!inode) { |
1158 | iput(dir); | 1159 | ret = -EIO; |
1159 | return -EIO; | 1160 | goto out; |
1160 | } | 1161 | } |
1161 | 1162 | ||
1162 | while (ref_ptr < ref_end) { | 1163 | while (ref_ptr < ref_end) { |
@@ -1169,14 +1170,16 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1169 | */ | 1170 | */ |
1170 | if (!dir) | 1171 | if (!dir) |
1171 | dir = read_one_inode(root, parent_objectid); | 1172 | dir = read_one_inode(root, parent_objectid); |
1172 | if (!dir) | 1173 | if (!dir) { |
1173 | return -ENOENT; | 1174 | ret = -ENOENT; |
1175 | goto out; | ||
1176 | } | ||
1174 | } else { | 1177 | } else { |
1175 | ret = ref_get_fields(eb, ref_ptr, &namelen, &name, | 1178 | ret = ref_get_fields(eb, ref_ptr, &namelen, &name, |
1176 | &ref_index); | 1179 | &ref_index); |
1177 | } | 1180 | } |
1178 | if (ret) | 1181 | if (ret) |
1179 | return ret; | 1182 | goto out; |
1180 | 1183 | ||
1181 | /* if we already have a perfect match, we're done */ | 1184 | /* if we already have a perfect match, we're done */ |
1182 | if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), | 1185 | if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), |
@@ -1196,12 +1199,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1196 | parent_objectid, | 1199 | parent_objectid, |
1197 | ref_index, name, namelen, | 1200 | ref_index, name, namelen, |
1198 | &search_done); | 1201 | &search_done); |
1199 | if (ret == 1) { | 1202 | if (ret) { |
1200 | ret = 0; | 1203 | if (ret == 1) |
1204 | ret = 0; | ||
1201 | goto out; | 1205 | goto out; |
1202 | } | 1206 | } |
1203 | if (ret) | ||
1204 | goto out; | ||
1205 | } | 1207 | } |
1206 | 1208 | ||
1207 | /* insert our name */ | 1209 | /* insert our name */ |
@@ -1215,6 +1217,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1215 | 1217 | ||
1216 | ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; | 1218 | ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; |
1217 | kfree(name); | 1219 | kfree(name); |
1220 | name = NULL; | ||
1218 | if (log_ref_ver) { | 1221 | if (log_ref_ver) { |
1219 | iput(dir); | 1222 | iput(dir); |
1220 | dir = NULL; | 1223 | dir = NULL; |
@@ -1225,6 +1228,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
1225 | ret = overwrite_item(trans, root, path, eb, slot, key); | 1228 | ret = overwrite_item(trans, root, path, eb, slot, key); |
1226 | out: | 1229 | out: |
1227 | btrfs_release_path(path); | 1230 | btrfs_release_path(path); |
1231 | kfree(name); | ||
1228 | iput(dir); | 1232 | iput(dir); |
1229 | iput(inode); | 1233 | iput(inode); |
1230 | return ret; | 1234 | return ret; |
@@ -1307,6 +1311,7 @@ static int count_inode_refs(struct btrfs_root *root, | |||
1307 | break; | 1311 | break; |
1308 | path->slots[0]--; | 1312 | path->slots[0]--; |
1309 | } | 1313 | } |
1314 | process_slot: | ||
1310 | btrfs_item_key_to_cpu(path->nodes[0], &key, | 1315 | btrfs_item_key_to_cpu(path->nodes[0], &key, |
1311 | path->slots[0]); | 1316 | path->slots[0]); |
1312 | if (key.objectid != ino || | 1317 | if (key.objectid != ino || |
@@ -1327,6 +1332,10 @@ static int count_inode_refs(struct btrfs_root *root, | |||
1327 | 1332 | ||
1328 | if (key.offset == 0) | 1333 | if (key.offset == 0) |
1329 | break; | 1334 | break; |
1335 | if (path->slots[0] > 0) { | ||
1336 | path->slots[0]--; | ||
1337 | goto process_slot; | ||
1338 | } | ||
1330 | key.offset--; | 1339 | key.offset--; |
1331 | btrfs_release_path(path); | 1340 | btrfs_release_path(path); |
1332 | } | 1341 | } |
@@ -1480,7 +1489,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, | |||
1480 | if (!inode->i_nlink) | 1489 | if (!inode->i_nlink) |
1481 | set_nlink(inode, 1); | 1490 | set_nlink(inode, 1); |
1482 | else | 1491 | else |
1483 | btrfs_inc_nlink(inode); | 1492 | inc_nlink(inode); |
1484 | ret = btrfs_update_inode(trans, root, inode); | 1493 | ret = btrfs_update_inode(trans, root, inode); |
1485 | } else if (ret == -EEXIST) { | 1494 | } else if (ret == -EEXIST) { |
1486 | ret = 0; | 1495 | ret = 0; |
@@ -1823,7 +1832,7 @@ again: | |||
1823 | dir_key->offset, | 1832 | dir_key->offset, |
1824 | name, name_len, 0); | 1833 | name, name_len, 0); |
1825 | } | 1834 | } |
1826 | if (IS_ERR_OR_NULL(log_di)) { | 1835 | if (!log_di || (IS_ERR(log_di) && PTR_ERR(log_di) == -ENOENT)) { |
1827 | btrfs_dir_item_key_to_cpu(eb, di, &location); | 1836 | btrfs_dir_item_key_to_cpu(eb, di, &location); |
1828 | btrfs_release_path(path); | 1837 | btrfs_release_path(path); |
1829 | btrfs_release_path(log_path); | 1838 | btrfs_release_path(log_path); |
@@ -1841,7 +1850,7 @@ again: | |||
1841 | goto out; | 1850 | goto out; |
1842 | } | 1851 | } |
1843 | 1852 | ||
1844 | btrfs_inc_nlink(inode); | 1853 | inc_nlink(inode); |
1845 | ret = btrfs_unlink_inode(trans, root, dir, inode, | 1854 | ret = btrfs_unlink_inode(trans, root, dir, inode, |
1846 | name, name_len); | 1855 | name, name_len); |
1847 | if (!ret) | 1856 | if (!ret) |
@@ -1860,6 +1869,9 @@ again: | |||
1860 | goto again; | 1869 | goto again; |
1861 | ret = 0; | 1870 | ret = 0; |
1862 | goto out; | 1871 | goto out; |
1872 | } else if (IS_ERR(log_di)) { | ||
1873 | kfree(name); | ||
1874 | return PTR_ERR(log_di); | ||
1863 | } | 1875 | } |
1864 | btrfs_release_path(log_path); | 1876 | btrfs_release_path(log_path); |
1865 | kfree(name); | 1877 | kfree(name); |
@@ -2118,8 +2130,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
2118 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 2130 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
2119 | cur = path->nodes[*level]; | 2131 | cur = path->nodes[*level]; |
2120 | 2132 | ||
2121 | if (btrfs_header_level(cur) != *level) | 2133 | WARN_ON(btrfs_header_level(cur) != *level); |
2122 | WARN_ON(1); | ||
2123 | 2134 | ||
2124 | if (path->slots[*level] >= | 2135 | if (path->slots[*level] >= |
2125 | btrfs_header_nritems(cur)) | 2136 | btrfs_header_nritems(cur)) |
@@ -2151,11 +2162,13 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
2151 | return ret; | 2162 | return ret; |
2152 | } | 2163 | } |
2153 | 2164 | ||
2154 | btrfs_tree_lock(next); | 2165 | if (trans) { |
2155 | btrfs_set_lock_blocking(next); | 2166 | btrfs_tree_lock(next); |
2156 | clean_tree_block(trans, root, next); | 2167 | btrfs_set_lock_blocking(next); |
2157 | btrfs_wait_tree_block_writeback(next); | 2168 | clean_tree_block(trans, root, next); |
2158 | btrfs_tree_unlock(next); | 2169 | btrfs_wait_tree_block_writeback(next); |
2170 | btrfs_tree_unlock(next); | ||
2171 | } | ||
2159 | 2172 | ||
2160 | WARN_ON(root_owner != | 2173 | WARN_ON(root_owner != |
2161 | BTRFS_TREE_LOG_OBJECTID); | 2174 | BTRFS_TREE_LOG_OBJECTID); |
@@ -2227,11 +2240,13 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, | |||
2227 | 2240 | ||
2228 | next = path->nodes[*level]; | 2241 | next = path->nodes[*level]; |
2229 | 2242 | ||
2230 | btrfs_tree_lock(next); | 2243 | if (trans) { |
2231 | btrfs_set_lock_blocking(next); | 2244 | btrfs_tree_lock(next); |
2232 | clean_tree_block(trans, root, next); | 2245 | btrfs_set_lock_blocking(next); |
2233 | btrfs_wait_tree_block_writeback(next); | 2246 | clean_tree_block(trans, root, next); |
2234 | btrfs_tree_unlock(next); | 2247 | btrfs_wait_tree_block_writeback(next); |
2248 | btrfs_tree_unlock(next); | ||
2249 | } | ||
2235 | 2250 | ||
2236 | WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID); | 2251 | WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID); |
2237 | ret = btrfs_free_and_pin_reserved_extent(root, | 2252 | ret = btrfs_free_and_pin_reserved_extent(root, |
@@ -2301,11 +2316,13 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, | |||
2301 | 2316 | ||
2302 | next = path->nodes[orig_level]; | 2317 | next = path->nodes[orig_level]; |
2303 | 2318 | ||
2304 | btrfs_tree_lock(next); | 2319 | if (trans) { |
2305 | btrfs_set_lock_blocking(next); | 2320 | btrfs_tree_lock(next); |
2306 | clean_tree_block(trans, log, next); | 2321 | btrfs_set_lock_blocking(next); |
2307 | btrfs_wait_tree_block_writeback(next); | 2322 | clean_tree_block(trans, log, next); |
2308 | btrfs_tree_unlock(next); | 2323 | btrfs_wait_tree_block_writeback(next); |
2324 | btrfs_tree_unlock(next); | ||
2325 | } | ||
2309 | 2326 | ||
2310 | WARN_ON(log->root_key.objectid != | 2327 | WARN_ON(log->root_key.objectid != |
2311 | BTRFS_TREE_LOG_OBJECTID); | 2328 | BTRFS_TREE_LOG_OBJECTID); |
@@ -2571,9 +2588,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2571 | * the running transaction open, so a full commit can't hop | 2588 | * the running transaction open, so a full commit can't hop |
2572 | * in and cause problems either. | 2589 | * in and cause problems either. |
2573 | */ | 2590 | */ |
2574 | btrfs_scrub_pause_super(root); | ||
2575 | ret = write_ctree_super(trans, root->fs_info->tree_root, 1); | 2591 | ret = write_ctree_super(trans, root->fs_info->tree_root, 1); |
2576 | btrfs_scrub_continue_super(root); | ||
2577 | if (ret) { | 2592 | if (ret) { |
2578 | btrfs_abort_transaction(trans, root, ret); | 2593 | btrfs_abort_transaction(trans, root, ret); |
2579 | goto out_wake_log_root; | 2594 | goto out_wake_log_root; |
@@ -2608,13 +2623,10 @@ static void free_log_tree(struct btrfs_trans_handle *trans, | |||
2608 | .process_func = process_one_buffer | 2623 | .process_func = process_one_buffer |
2609 | }; | 2624 | }; |
2610 | 2625 | ||
2611 | if (trans) { | 2626 | ret = walk_log_tree(trans, log, &wc); |
2612 | ret = walk_log_tree(trans, log, &wc); | 2627 | /* I don't think this can happen but just in case */ |
2613 | 2628 | if (ret) | |
2614 | /* I don't think this can happen but just in case */ | 2629 | btrfs_abort_transaction(trans, log, ret); |
2615 | if (ret) | ||
2616 | btrfs_abort_transaction(trans, log, ret); | ||
2617 | } | ||
2618 | 2630 | ||
2619 | while (1) { | 2631 | while (1) { |
2620 | ret = find_first_extent_bit(&log->dirty_log_pages, | 2632 | ret = find_first_extent_bit(&log->dirty_log_pages, |
@@ -2867,7 +2879,6 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2867 | u64 min_offset, u64 *last_offset_ret) | 2879 | u64 min_offset, u64 *last_offset_ret) |
2868 | { | 2880 | { |
2869 | struct btrfs_key min_key; | 2881 | struct btrfs_key min_key; |
2870 | struct btrfs_key max_key; | ||
2871 | struct btrfs_root *log = root->log_root; | 2882 | struct btrfs_root *log = root->log_root; |
2872 | struct extent_buffer *src; | 2883 | struct extent_buffer *src; |
2873 | int err = 0; | 2884 | int err = 0; |
@@ -2879,9 +2890,6 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2879 | u64 ino = btrfs_ino(inode); | 2890 | u64 ino = btrfs_ino(inode); |
2880 | 2891 | ||
2881 | log = root->log_root; | 2892 | log = root->log_root; |
2882 | max_key.objectid = ino; | ||
2883 | max_key.offset = (u64)-1; | ||
2884 | max_key.type = key_type; | ||
2885 | 2893 | ||
2886 | min_key.objectid = ino; | 2894 | min_key.objectid = ino; |
2887 | min_key.type = key_type; | 2895 | min_key.type = key_type; |
@@ -2889,8 +2897,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2889 | 2897 | ||
2890 | path->keep_locks = 1; | 2898 | path->keep_locks = 1; |
2891 | 2899 | ||
2892 | ret = btrfs_search_forward(root, &min_key, &max_key, | 2900 | ret = btrfs_search_forward(root, &min_key, path, trans->transid); |
2893 | path, trans->transid); | ||
2894 | 2901 | ||
2895 | /* | 2902 | /* |
2896 | * we didn't find anything from this transaction, see if there | 2903 | * we didn't find anything from this transaction, see if there |
@@ -2943,10 +2950,8 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, | |||
2943 | 2950 | ||
2944 | /* find the first key from this transaction again */ | 2951 | /* find the first key from this transaction again */ |
2945 | ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); | 2952 | ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); |
2946 | if (ret != 0) { | 2953 | if (WARN_ON(ret != 0)) |
2947 | WARN_ON(1); | ||
2948 | goto done; | 2954 | goto done; |
2949 | } | ||
2950 | 2955 | ||
2951 | /* | 2956 | /* |
2952 | * we have a block from this transaction, log every item in it | 2957 | * we have a block from this transaction, log every item in it |
@@ -3172,11 +3177,10 @@ static int log_inode_item(struct btrfs_trans_handle *trans, | |||
3172 | struct inode *inode) | 3177 | struct inode *inode) |
3173 | { | 3178 | { |
3174 | struct btrfs_inode_item *inode_item; | 3179 | struct btrfs_inode_item *inode_item; |
3175 | struct btrfs_key key; | ||
3176 | int ret; | 3180 | int ret; |
3177 | 3181 | ||
3178 | memcpy(&key, &BTRFS_I(inode)->location, sizeof(key)); | 3182 | ret = btrfs_insert_empty_item(trans, log, path, |
3179 | ret = btrfs_insert_empty_item(trans, log, path, &key, | 3183 | &BTRFS_I(inode)->location, |
3180 | sizeof(*inode_item)); | 3184 | sizeof(*inode_item)); |
3181 | if (ret && ret != -EEXIST) | 3185 | if (ret && ret != -EEXIST) |
3182 | return ret; | 3186 | return ret; |
@@ -3375,7 +3379,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
3375 | btrfs_set_token_file_extent_type(leaf, fi, | 3379 | btrfs_set_token_file_extent_type(leaf, fi, |
3376 | BTRFS_FILE_EXTENT_REG, | 3380 | BTRFS_FILE_EXTENT_REG, |
3377 | &token); | 3381 | &token); |
3378 | if (em->block_start == 0) | 3382 | if (em->block_start == EXTENT_MAP_HOLE) |
3379 | skip_csum = true; | 3383 | skip_csum = true; |
3380 | } | 3384 | } |
3381 | 3385 | ||
@@ -3417,11 +3421,6 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
3417 | if (skip_csum) | 3421 | if (skip_csum) |
3418 | return 0; | 3422 | return 0; |
3419 | 3423 | ||
3420 | if (em->compress_type) { | ||
3421 | csum_offset = 0; | ||
3422 | csum_len = block_len; | ||
3423 | } | ||
3424 | |||
3425 | /* | 3424 | /* |
3426 | * First check and see if our csums are on our outstanding ordered | 3425 | * First check and see if our csums are on our outstanding ordered |
3427 | * extents. | 3426 | * extents. |
@@ -3505,8 +3504,13 @@ unlocked: | |||
3505 | if (!mod_len || ret) | 3504 | if (!mod_len || ret) |
3506 | return ret; | 3505 | return ret; |
3507 | 3506 | ||
3508 | csum_offset = mod_start - em->start; | 3507 | if (em->compress_type) { |
3509 | csum_len = mod_len; | 3508 | csum_offset = 0; |
3509 | csum_len = block_len; | ||
3510 | } else { | ||
3511 | csum_offset = mod_start - em->start; | ||
3512 | csum_len = mod_len; | ||
3513 | } | ||
3510 | 3514 | ||
3511 | /* block start is already adjusted for the file extent offset. */ | 3515 | /* block start is already adjusted for the file extent offset. */ |
3512 | ret = btrfs_lookup_csums_range(log->fs_info->csum_root, | 3516 | ret = btrfs_lookup_csums_range(log->fs_info->csum_root, |
@@ -3719,7 +3723,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
3719 | 3723 | ||
3720 | while (1) { | 3724 | while (1) { |
3721 | ins_nr = 0; | 3725 | ins_nr = 0; |
3722 | ret = btrfs_search_forward(root, &min_key, &max_key, | 3726 | ret = btrfs_search_forward(root, &min_key, |
3723 | path, trans->transid); | 3727 | path, trans->transid); |
3724 | if (ret != 0) | 3728 | if (ret != 0) |
3725 | break; | 3729 | break; |
@@ -3769,14 +3773,14 @@ next_slot: | |||
3769 | } | 3773 | } |
3770 | btrfs_release_path(path); | 3774 | btrfs_release_path(path); |
3771 | 3775 | ||
3772 | if (min_key.offset < (u64)-1) | 3776 | if (min_key.offset < (u64)-1) { |
3773 | min_key.offset++; | 3777 | min_key.offset++; |
3774 | else if (min_key.type < (u8)-1) | 3778 | } else if (min_key.type < max_key.type) { |
3775 | min_key.type++; | 3779 | min_key.type++; |
3776 | else if (min_key.objectid < (u64)-1) | 3780 | min_key.offset = 0; |
3777 | min_key.objectid++; | 3781 | } else { |
3778 | else | ||
3779 | break; | 3782 | break; |
3783 | } | ||
3780 | } | 3784 | } |
3781 | if (ins_nr) { | 3785 | if (ins_nr) { |
3782 | ret = copy_items(trans, inode, dst_path, src, ins_start_slot, | 3786 | ret = copy_items(trans, inode, dst_path, src, ins_start_slot, |
diff --git a/fs/btrfs/uuid-tree.c b/fs/btrfs/uuid-tree.c index dd0dea3766f7..fbda90004fe9 100644 --- a/fs/btrfs/uuid-tree.c +++ b/fs/btrfs/uuid-tree.c | |||
@@ -260,7 +260,6 @@ int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info, | |||
260 | { | 260 | { |
261 | struct btrfs_root *root = fs_info->uuid_root; | 261 | struct btrfs_root *root = fs_info->uuid_root; |
262 | struct btrfs_key key; | 262 | struct btrfs_key key; |
263 | struct btrfs_key max_key; | ||
264 | struct btrfs_path *path; | 263 | struct btrfs_path *path; |
265 | int ret = 0; | 264 | int ret = 0; |
266 | struct extent_buffer *leaf; | 265 | struct extent_buffer *leaf; |
@@ -277,13 +276,10 @@ int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info, | |||
277 | key.objectid = 0; | 276 | key.objectid = 0; |
278 | key.type = 0; | 277 | key.type = 0; |
279 | key.offset = 0; | 278 | key.offset = 0; |
280 | max_key.objectid = (u64)-1; | ||
281 | max_key.type = (u8)-1; | ||
282 | max_key.offset = (u64)-1; | ||
283 | 279 | ||
284 | again_search_slot: | 280 | again_search_slot: |
285 | path->keep_locks = 1; | 281 | path->keep_locks = 1; |
286 | ret = btrfs_search_forward(root, &key, &max_key, path, 0); | 282 | ret = btrfs_search_forward(root, &key, path, 0); |
287 | if (ret) { | 283 | if (ret) { |
288 | if (ret > 0) | 284 | if (ret > 0) |
289 | ret = 0; | 285 | ret = 0; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 043b215769c2..0db637097862 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/raid/pq.h> | 28 | #include <linux/raid/pq.h> |
29 | #include <linux/semaphore.h> | 29 | #include <linux/semaphore.h> |
30 | #include <asm/div64.h> | 30 | #include <asm/div64.h> |
31 | #include "compat.h" | ||
32 | #include "ctree.h" | 31 | #include "ctree.h" |
33 | #include "extent_map.h" | 32 | #include "extent_map.h" |
34 | #include "disk-io.h" | 33 | #include "disk-io.h" |
@@ -666,7 +665,8 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
666 | if (device->bdev) | 665 | if (device->bdev) |
667 | fs_devices->open_devices--; | 666 | fs_devices->open_devices--; |
668 | 667 | ||
669 | if (device->writeable && !device->is_tgtdev_for_dev_replace) { | 668 | if (device->writeable && |
669 | device->devid != BTRFS_DEV_REPLACE_DEVID) { | ||
670 | list_del_init(&device->dev_alloc_list); | 670 | list_del_init(&device->dev_alloc_list); |
671 | fs_devices->rw_devices--; | 671 | fs_devices->rw_devices--; |
672 | } | 672 | } |
@@ -2041,6 +2041,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
2041 | device->in_fs_metadata = 1; | 2041 | device->in_fs_metadata = 1; |
2042 | device->is_tgtdev_for_dev_replace = 0; | 2042 | device->is_tgtdev_for_dev_replace = 0; |
2043 | device->mode = FMODE_EXCL; | 2043 | device->mode = FMODE_EXCL; |
2044 | device->dev_stats_valid = 1; | ||
2044 | set_blocksize(device->bdev, 4096); | 2045 | set_blocksize(device->bdev, 4096); |
2045 | 2046 | ||
2046 | if (seeding_dev) { | 2047 | if (seeding_dev) { |
@@ -2208,6 +2209,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path, | |||
2208 | device->in_fs_metadata = 1; | 2209 | device->in_fs_metadata = 1; |
2209 | device->is_tgtdev_for_dev_replace = 1; | 2210 | device->is_tgtdev_for_dev_replace = 1; |
2210 | device->mode = FMODE_EXCL; | 2211 | device->mode = FMODE_EXCL; |
2212 | device->dev_stats_valid = 1; | ||
2211 | set_blocksize(device->bdev, 4096); | 2213 | set_blocksize(device->bdev, 4096); |
2212 | device->fs_devices = fs_info->fs_devices; | 2214 | device->fs_devices = fs_info->fs_devices; |
2213 | list_add(&device->dev_list, &fs_info->fs_devices->devices); | 2215 | list_add(&device->dev_list, &fs_info->fs_devices->devices); |
@@ -2550,8 +2552,7 @@ again: | |||
2550 | failed = 0; | 2552 | failed = 0; |
2551 | retried = true; | 2553 | retried = true; |
2552 | goto again; | 2554 | goto again; |
2553 | } else if (failed && retried) { | 2555 | } else if (WARN_ON(failed && retried)) { |
2554 | WARN_ON(1); | ||
2555 | ret = -ENOSPC; | 2556 | ret = -ENOSPC; |
2556 | } | 2557 | } |
2557 | error: | 2558 | error: |
@@ -3423,6 +3424,9 @@ int btrfs_pause_balance(struct btrfs_fs_info *fs_info) | |||
3423 | 3424 | ||
3424 | int btrfs_cancel_balance(struct btrfs_fs_info *fs_info) | 3425 | int btrfs_cancel_balance(struct btrfs_fs_info *fs_info) |
3425 | { | 3426 | { |
3427 | if (fs_info->sb->s_flags & MS_RDONLY) | ||
3428 | return -EROFS; | ||
3429 | |||
3426 | mutex_lock(&fs_info->balance_mutex); | 3430 | mutex_lock(&fs_info->balance_mutex); |
3427 | if (!fs_info->balance_ctl) { | 3431 | if (!fs_info->balance_ctl) { |
3428 | mutex_unlock(&fs_info->balance_mutex); | 3432 | mutex_unlock(&fs_info->balance_mutex); |
@@ -3488,7 +3492,7 @@ static int btrfs_uuid_scan_kthread(void *data) | |||
3488 | path->keep_locks = 1; | 3492 | path->keep_locks = 1; |
3489 | 3493 | ||
3490 | while (1) { | 3494 | while (1) { |
3491 | ret = btrfs_search_forward(root, &key, &max_key, path, 0); | 3495 | ret = btrfs_search_forward(root, &key, path, 0); |
3492 | if (ret) { | 3496 | if (ret) { |
3493 | if (ret > 0) | 3497 | if (ret > 0) |
3494 | ret = 0; | 3498 | ret = 0; |
@@ -4488,6 +4492,7 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len) | |||
4488 | btrfs_crit(fs_info, "Invalid mapping for %Lu-%Lu, got " | 4492 | btrfs_crit(fs_info, "Invalid mapping for %Lu-%Lu, got " |
4489 | "%Lu-%Lu\n", logical, logical+len, em->start, | 4493 | "%Lu-%Lu\n", logical, logical+len, em->start, |
4490 | em->start + em->len); | 4494 | em->start + em->len); |
4495 | free_extent_map(em); | ||
4491 | return 1; | 4496 | return 1; |
4492 | } | 4497 | } |
4493 | 4498 | ||
@@ -4668,6 +4673,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
4668 | btrfs_crit(fs_info, "found a bad mapping, wanted %Lu, " | 4673 | btrfs_crit(fs_info, "found a bad mapping, wanted %Lu, " |
4669 | "found %Lu-%Lu\n", logical, em->start, | 4674 | "found %Lu-%Lu\n", logical, em->start, |
4670 | em->start + em->len); | 4675 | em->start + em->len); |
4676 | free_extent_map(em); | ||
4671 | return -EINVAL; | 4677 | return -EINVAL; |
4672 | } | 4678 | } |
4673 | 4679 | ||
@@ -4895,7 +4901,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, | |||
4895 | num_stripes = map->num_stripes; | 4901 | num_stripes = map->num_stripes; |
4896 | max_errors = nr_parity_stripes(map); | 4902 | max_errors = nr_parity_stripes(map); |
4897 | 4903 | ||
4898 | raid_map = kmalloc(sizeof(u64) * num_stripes, | 4904 | raid_map = kmalloc_array(num_stripes, sizeof(u64), |
4899 | GFP_NOFS); | 4905 | GFP_NOFS); |
4900 | if (!raid_map) { | 4906 | if (!raid_map) { |
4901 | ret = -ENOMEM; | 4907 | ret = -ENOMEM; |
@@ -5395,10 +5401,8 @@ static int bio_size_ok(struct block_device *bdev, struct bio *bio, | |||
5395 | .bi_rw = bio->bi_rw, | 5401 | .bi_rw = bio->bi_rw, |
5396 | }; | 5402 | }; |
5397 | 5403 | ||
5398 | if (bio->bi_vcnt == 0) { | 5404 | if (WARN_ON(bio->bi_vcnt == 0)) |
5399 | WARN_ON(1); | ||
5400 | return 1; | 5405 | return 1; |
5401 | } | ||
5402 | 5406 | ||
5403 | prev = &bio->bi_io_vec[bio->bi_vcnt - 1]; | 5407 | prev = &bio->bi_io_vec[bio->bi_vcnt - 1]; |
5404 | if (bio_sectors(bio) > max_sectors) | 5408 | if (bio_sectors(bio) > max_sectors) |
@@ -5631,10 +5635,8 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, | |||
5631 | struct btrfs_device *dev; | 5635 | struct btrfs_device *dev; |
5632 | u64 tmp; | 5636 | u64 tmp; |
5633 | 5637 | ||
5634 | if (!devid && !fs_info) { | 5638 | if (WARN_ON(!devid && !fs_info)) |
5635 | WARN_ON(1); | ||
5636 | return ERR_PTR(-EINVAL); | 5639 | return ERR_PTR(-EINVAL); |
5637 | } | ||
5638 | 5640 | ||
5639 | dev = __alloc_device(); | 5641 | dev = __alloc_device(); |
5640 | if (IS_ERR(dev)) | 5642 | if (IS_ERR(dev)) |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index b72f540c8b29..8b3cd142b373 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -43,9 +43,8 @@ struct btrfs_device { | |||
43 | /* WRITE_SYNC bios */ | 43 | /* WRITE_SYNC bios */ |
44 | struct btrfs_pending_bios pending_sync_bios; | 44 | struct btrfs_pending_bios pending_sync_bios; |
45 | 45 | ||
46 | int running_pending; | ||
47 | u64 generation; | 46 | u64 generation; |
48 | 47 | int running_pending; | |
49 | int writeable; | 48 | int writeable; |
50 | int in_fs_metadata; | 49 | int in_fs_metadata; |
51 | int missing; | 50 | int missing; |
@@ -53,11 +52,11 @@ struct btrfs_device { | |||
53 | int is_tgtdev_for_dev_replace; | 52 | int is_tgtdev_for_dev_replace; |
54 | 53 | ||
55 | spinlock_t io_lock; | 54 | spinlock_t io_lock; |
55 | /* the mode sent to blkdev_get */ | ||
56 | fmode_t mode; | ||
56 | 57 | ||
57 | struct block_device *bdev; | 58 | struct block_device *bdev; |
58 | 59 | ||
59 | /* the mode sent to blkdev_get */ | ||
60 | fmode_t mode; | ||
61 | 60 | ||
62 | struct rcu_string *name; | 61 | struct rcu_string *name; |
63 | 62 | ||
@@ -78,16 +77,21 @@ struct btrfs_device { | |||
78 | 77 | ||
79 | /* optimal io width for this device */ | 78 | /* optimal io width for this device */ |
80 | u32 io_width; | 79 | u32 io_width; |
80 | /* type and info about this device */ | ||
81 | u64 type; | ||
81 | 82 | ||
82 | /* minimal io size for this device */ | 83 | /* minimal io size for this device */ |
83 | u32 sector_size; | 84 | u32 sector_size; |
84 | 85 | ||
85 | /* type and info about this device */ | ||
86 | u64 type; | ||
87 | 86 | ||
88 | /* physical drive uuid (or lvm uuid) */ | 87 | /* physical drive uuid (or lvm uuid) */ |
89 | u8 uuid[BTRFS_UUID_SIZE]; | 88 | u8 uuid[BTRFS_UUID_SIZE]; |
90 | 89 | ||
90 | /* for sending down flush barriers */ | ||
91 | int nobarriers; | ||
92 | struct bio *flush_bio; | ||
93 | struct completion flush_wait; | ||
94 | |||
91 | /* per-device scrub information */ | 95 | /* per-device scrub information */ |
92 | struct scrub_ctx *scrub_device; | 96 | struct scrub_ctx *scrub_device; |
93 | 97 | ||
@@ -103,10 +107,6 @@ struct btrfs_device { | |||
103 | struct radix_tree_root reada_zones; | 107 | struct radix_tree_root reada_zones; |
104 | struct radix_tree_root reada_extents; | 108 | struct radix_tree_root reada_extents; |
105 | 109 | ||
106 | /* for sending down flush barriers */ | ||
107 | struct bio *flush_bio; | ||
108 | struct completion flush_wait; | ||
109 | int nobarriers; | ||
110 | 110 | ||
111 | /* disk I/O failure stats. For detailed description refer to | 111 | /* disk I/O failure stats. For detailed description refer to |
112 | * enum btrfs_dev_stat_values in ioctl.h */ | 112 | * enum btrfs_dev_stat_values in ioctl.h */ |
@@ -132,7 +132,9 @@ struct btrfs_fs_devices { | |||
132 | 132 | ||
133 | /* all of the devices in the FS, protected by a mutex | 133 | /* all of the devices in the FS, protected by a mutex |
134 | * so we can safely walk it to write out the supers without | 134 | * so we can safely walk it to write out the supers without |
135 | * worrying about add/remove by the multi-device code | 135 | * worrying about add/remove by the multi-device code. |
136 | * Scrubbing super can kick off supers writing by holding | ||
137 | * this mutex lock. | ||
136 | */ | 138 | */ |
137 | struct mutex device_list_mutex; | 139 | struct mutex device_list_mutex; |
138 | struct list_head devices; | 140 | struct list_head devices; |