diff options
Diffstat (limited to 'fs/btrfs')
49 files changed, 2663 insertions, 1036 deletions
diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index 398cbd517be2..aa976eced2d2 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig | |||
| @@ -9,12 +9,17 @@ config BTRFS_FS | |||
| 9 | select XOR_BLOCKS | 9 | select XOR_BLOCKS |
| 10 | 10 | ||
| 11 | help | 11 | help |
| 12 | Btrfs is a new filesystem with extents, writable snapshotting, | 12 | Btrfs is a general purpose copy-on-write filesystem with extents, |
| 13 | support for multiple devices and many more features. | 13 | writable snapshotting, support for multiple devices and many more |
| 14 | features focused on fault tolerance, repair and easy administration. | ||
| 14 | 15 | ||
| 15 | Btrfs is highly experimental, and THE DISK FORMAT IS NOT YET | 16 | The filesystem disk format is no longer unstable, and it's not |
| 16 | FINALIZED. You should say N here unless you are interested in | 17 | expected to change unless there are strong reasons to do so. If there |
| 17 | testing Btrfs with non-critical data. | 18 | is a format change, file systems with a unchanged format will |
| 19 | continue to be mountable and usable by newer kernels. | ||
| 20 | |||
| 21 | For more information, please see the web pages at | ||
| 22 | http://btrfs.wiki.kernel.org. | ||
| 18 | 23 | ||
| 19 | To compile this file system support as a module, choose M here. The | 24 | To compile this file system support as a module, choose M here. The |
| 20 | module will be called btrfs. | 25 | module will be called btrfs. |
| @@ -59,7 +64,8 @@ config BTRFS_FS_RUN_SANITY_TESTS | |||
| 59 | help | 64 | help |
| 60 | This will run some basic sanity tests on the free space cache | 65 | This will run some basic sanity tests on the free space cache |
| 61 | code to make sure it is acting as it should. These are mostly | 66 | code to make sure it is acting as it should. These are mostly |
| 62 | regression tests and are only really interesting to btrfs devlopers. | 67 | regression tests and are only really interesting to btrfs |
| 68 | developers. | ||
| 63 | 69 | ||
| 64 | If unsure, say N. | 70 | If unsure, say N. |
| 65 | 71 | ||
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..c1e0b0caf9cc 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(); |
| @@ -495,6 +495,7 @@ static int __btrfs_start_workers(struct btrfs_workers *workers) | |||
| 495 | spin_lock_irq(&workers->lock); | 495 | spin_lock_irq(&workers->lock); |
| 496 | if (workers->stopping) { | 496 | if (workers->stopping) { |
| 497 | spin_unlock_irq(&workers->lock); | 497 | spin_unlock_irq(&workers->lock); |
| 498 | ret = -EINVAL; | ||
| 498 | goto fail_kthread; | 499 | goto fail_kthread; |
| 499 | } | 500 | } |
| 500 | list_add_tail(&worker->worker_list, &workers->idle_list); | 501 | list_add_tail(&worker->worker_list, &workers->idle_list); |
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..b50764bef141 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
| @@ -77,6 +77,15 @@ | |||
| 77 | * the integrity of (super)-block write requests, do not | 77 | * the integrity of (super)-block write requests, do not |
| 78 | * enable the config option BTRFS_FS_CHECK_INTEGRITY to | 78 | * enable the config option BTRFS_FS_CHECK_INTEGRITY to |
| 79 | * include and compile the integrity check tool. | 79 | * include and compile the integrity check tool. |
| 80 | * | ||
| 81 | * Expect millions of lines of information in the kernel log with an | ||
| 82 | * enabled check_int_print_mask. Therefore set LOG_BUF_SHIFT in the | ||
| 83 | * kernel config to at least 26 (which is 64MB). Usually the value is | ||
| 84 | * limited to 21 (which is 2MB) in init/Kconfig. The file needs to be | ||
| 85 | * changed like this before LOG_BUF_SHIFT can be set to a high value: | ||
| 86 | * config LOG_BUF_SHIFT | ||
| 87 | * int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" | ||
| 88 | * range 12 30 | ||
| 80 | */ | 89 | */ |
| 81 | 90 | ||
| 82 | #include <linux/sched.h> | 91 | #include <linux/sched.h> |
| @@ -124,6 +133,7 @@ | |||
| 124 | #define BTRFSIC_PRINT_MASK_INITIAL_DATABASE 0x00000400 | 133 | #define BTRFSIC_PRINT_MASK_INITIAL_DATABASE 0x00000400 |
| 125 | #define BTRFSIC_PRINT_MASK_NUM_COPIES 0x00000800 | 134 | #define BTRFSIC_PRINT_MASK_NUM_COPIES 0x00000800 |
| 126 | #define BTRFSIC_PRINT_MASK_TREE_WITH_ALL_MIRRORS 0x00001000 | 135 | #define BTRFSIC_PRINT_MASK_TREE_WITH_ALL_MIRRORS 0x00001000 |
| 136 | #define BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE 0x00002000 | ||
| 127 | 137 | ||
| 128 | struct btrfsic_dev_state; | 138 | struct btrfsic_dev_state; |
| 129 | struct btrfsic_state; | 139 | struct btrfsic_state; |
| @@ -1038,7 +1048,7 @@ leaf_item_out_of_bounce_error: | |||
| 1038 | disk_item_offset, | 1048 | disk_item_offset, |
| 1039 | sizeof(struct btrfs_item)); | 1049 | sizeof(struct btrfs_item)); |
| 1040 | item_offset = btrfs_stack_item_offset(&disk_item); | 1050 | item_offset = btrfs_stack_item_offset(&disk_item); |
| 1041 | item_size = btrfs_stack_item_offset(&disk_item); | 1051 | item_size = btrfs_stack_item_size(&disk_item); |
| 1042 | disk_key = &disk_item.key; | 1052 | disk_key = &disk_item.key; |
| 1043 | type = btrfs_disk_key_type(disk_key); | 1053 | type = btrfs_disk_key_type(disk_key); |
| 1044 | 1054 | ||
| @@ -1900,7 +1910,9 @@ again: | |||
| 1900 | dev_state, | 1910 | dev_state, |
| 1901 | dev_bytenr); | 1911 | dev_bytenr); |
| 1902 | } | 1912 | } |
| 1903 | if (block->logical_bytenr != bytenr) { | 1913 | if (block->logical_bytenr != bytenr && |
| 1914 | !(!block->is_metadata && | ||
| 1915 | block->logical_bytenr == 0)) | ||
| 1904 | printk(KERN_INFO | 1916 | printk(KERN_INFO |
| 1905 | "Written block @%llu (%s/%llu/%d)" | 1917 | "Written block @%llu (%s/%llu/%d)" |
| 1906 | " found in hash table, %c," | 1918 | " found in hash table, %c," |
| @@ -1910,15 +1922,14 @@ again: | |||
| 1910 | block->mirror_num, | 1922 | block->mirror_num, |
| 1911 | btrfsic_get_block_type(state, block), | 1923 | btrfsic_get_block_type(state, block), |
| 1912 | block->logical_bytenr); | 1924 | block->logical_bytenr); |
| 1913 | block->logical_bytenr = bytenr; | 1925 | else if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) |
| 1914 | } else if (state->print_mask & | ||
| 1915 | BTRFSIC_PRINT_MASK_VERBOSE) | ||
| 1916 | printk(KERN_INFO | 1926 | printk(KERN_INFO |
| 1917 | "Written block @%llu (%s/%llu/%d)" | 1927 | "Written block @%llu (%s/%llu/%d)" |
| 1918 | " found in hash table, %c.\n", | 1928 | " found in hash table, %c.\n", |
| 1919 | bytenr, dev_state->name, dev_bytenr, | 1929 | bytenr, dev_state->name, dev_bytenr, |
| 1920 | block->mirror_num, | 1930 | block->mirror_num, |
| 1921 | btrfsic_get_block_type(state, block)); | 1931 | btrfsic_get_block_type(state, block)); |
| 1932 | block->logical_bytenr = bytenr; | ||
| 1922 | } else { | 1933 | } else { |
| 1923 | if (num_pages * PAGE_CACHE_SIZE < | 1934 | if (num_pages * PAGE_CACHE_SIZE < |
| 1924 | state->datablock_size) { | 1935 | state->datablock_size) { |
| @@ -2463,10 +2474,8 @@ static int btrfsic_process_written_superblock( | |||
| 2463 | } | 2474 | } |
| 2464 | } | 2475 | } |
| 2465 | 2476 | ||
| 2466 | if (-1 == btrfsic_check_all_ref_blocks(state, superblock, 0)) { | 2477 | if (WARN_ON(-1 == btrfsic_check_all_ref_blocks(state, superblock, 0))) |
| 2467 | WARN_ON(1); | ||
| 2468 | btrfsic_dump_tree(state); | 2478 | btrfsic_dump_tree(state); |
| 2469 | } | ||
| 2470 | 2479 | ||
| 2471 | return 0; | 2480 | return 0; |
| 2472 | } | 2481 | } |
| @@ -2906,7 +2915,7 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | |||
| 2906 | btrfsic_release_block_ctx(&block_ctx); | 2915 | btrfsic_release_block_ctx(&block_ctx); |
| 2907 | } | 2916 | } |
| 2908 | 2917 | ||
| 2909 | if (!match) { | 2918 | 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," | 2919 | 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," | 2920 | " buffer->log_bytenr=%llu, submit_bio(bdev=%s," |
| 2912 | " phys_bytenr=%llu)!\n", | 2921 | " phys_bytenr=%llu)!\n", |
| @@ -2923,7 +2932,6 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, | |||
| 2923 | bytenr, block_ctx.dev->name, | 2932 | bytenr, block_ctx.dev->name, |
| 2924 | block_ctx.dev_bytenr, mirror_num); | 2933 | block_ctx.dev_bytenr, mirror_num); |
| 2925 | } | 2934 | } |
| 2926 | WARN_ON(1); | ||
| 2927 | } | 2935 | } |
| 2928 | } | 2936 | } |
| 2929 | 2937 | ||
| @@ -3017,6 +3025,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio) | |||
| 3017 | (rw & WRITE) && NULL != bio->bi_io_vec) { | 3025 | (rw & WRITE) && NULL != bio->bi_io_vec) { |
| 3018 | unsigned int i; | 3026 | unsigned int i; |
| 3019 | u64 dev_bytenr; | 3027 | u64 dev_bytenr; |
| 3028 | u64 cur_bytenr; | ||
| 3020 | int bio_is_patched; | 3029 | int bio_is_patched; |
| 3021 | char **mapped_datav; | 3030 | char **mapped_datav; |
| 3022 | 3031 | ||
| @@ -3035,6 +3044,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio) | |||
| 3035 | GFP_NOFS); | 3044 | GFP_NOFS); |
| 3036 | if (!mapped_datav) | 3045 | if (!mapped_datav) |
| 3037 | goto leave; | 3046 | goto leave; |
| 3047 | cur_bytenr = dev_bytenr; | ||
| 3038 | for (i = 0; i < bio->bi_vcnt; i++) { | 3048 | for (i = 0; i < bio->bi_vcnt; i++) { |
| 3039 | BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_CACHE_SIZE); | 3049 | BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_CACHE_SIZE); |
| 3040 | mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page); | 3050 | mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page); |
| @@ -3046,16 +3056,13 @@ void btrfsic_submit_bio(int rw, struct bio *bio) | |||
| 3046 | kfree(mapped_datav); | 3056 | kfree(mapped_datav); |
| 3047 | goto leave; | 3057 | goto leave; |
| 3048 | } | 3058 | } |
| 3049 | if ((BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | | 3059 | if (dev_state->state->print_mask & |
| 3050 | BTRFSIC_PRINT_MASK_VERBOSE) == | 3060 | BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE) |
| 3051 | (dev_state->state->print_mask & | ||
| 3052 | (BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | | ||
| 3053 | BTRFSIC_PRINT_MASK_VERBOSE))) | ||
| 3054 | printk(KERN_INFO | 3061 | printk(KERN_INFO |
| 3055 | "#%u: page=%p, len=%u, offset=%u\n", | 3062 | "#%u: bytenr=%llu, len=%u, offset=%u\n", |
| 3056 | i, bio->bi_io_vec[i].bv_page, | 3063 | i, cur_bytenr, bio->bi_io_vec[i].bv_len, |
| 3057 | bio->bi_io_vec[i].bv_len, | ||
| 3058 | bio->bi_io_vec[i].bv_offset); | 3064 | bio->bi_io_vec[i].bv_offset); |
| 3065 | cur_bytenr += bio->bi_io_vec[i].bv_len; | ||
| 3059 | } | 3066 | } |
| 3060 | btrfsic_process_written_block(dev_state, dev_bytenr, | 3067 | btrfsic_process_written_block(dev_state, dev_bytenr, |
| 3061 | mapped_datav, bio->bi_vcnt, | 3068 | mapped_datav, bio->bi_vcnt, |
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..54ab86127f7a 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 | } |
| @@ -3105,11 +3111,6 @@ static inline u32 btrfs_level_size(struct btrfs_root *root, int level) | |||
| 3105 | ((unsigned long)(btrfs_leaf_data(leaf) + \ | 3111 | ((unsigned long)(btrfs_leaf_data(leaf) + \ |
| 3106 | btrfs_item_offset_nr(leaf, slot))) | 3112 | btrfs_item_offset_nr(leaf, slot))) |
| 3107 | 3113 | ||
| 3108 | static inline struct dentry *fdentry(struct file *file) | ||
| 3109 | { | ||
| 3110 | return file->f_path.dentry; | ||
| 3111 | } | ||
| 3112 | |||
| 3113 | static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info) | 3114 | static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info) |
| 3114 | { | 3115 | { |
| 3115 | return ((space_info->flags & BTRFS_BLOCK_GROUP_METADATA) && | 3116 | return ((space_info->flags & BTRFS_BLOCK_GROUP_METADATA) && |
| @@ -3308,7 +3309,6 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, | |||
| 3308 | struct btrfs_key *key, int lowest_level, | 3309 | struct btrfs_key *key, int lowest_level, |
| 3309 | u64 min_trans); | 3310 | u64 min_trans); |
| 3310 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | 3311 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, |
| 3311 | struct btrfs_key *max_key, | ||
| 3312 | struct btrfs_path *path, | 3312 | struct btrfs_path *path, |
| 3313 | u64 min_trans); | 3313 | u64 min_trans); |
| 3314 | enum btrfs_compare_tree_result { | 3314 | enum btrfs_compare_tree_result { |
| @@ -3613,9 +3613,6 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, | |||
| 3613 | struct btrfs_ordered_sum *sums); | 3613 | struct btrfs_ordered_sum *sums); |
| 3614 | int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, | 3614 | int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, |
| 3615 | struct bio *bio, u64 file_start, int contig); | 3615 | struct bio *bio, u64 file_start, int contig); |
| 3616 | int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | ||
| 3617 | struct btrfs_root *root, struct btrfs_path *path, | ||
| 3618 | u64 isize); | ||
| 3619 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | 3616 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, |
| 3620 | struct list_head *list, int search_commit); | 3617 | struct list_head *list, int search_commit); |
| 3621 | /* inode.c */ | 3618 | /* inode.c */ |
| @@ -3675,8 +3672,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | |||
| 3675 | u32 min_type); | 3672 | u32 min_type); |
| 3676 | 3673 | ||
| 3677 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); | 3674 | 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, | 3675 | 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, | 3676 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
| 3681 | struct extent_state **cached_state); | 3677 | struct extent_state **cached_state); |
| 3682 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 3678 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
| @@ -3745,9 +3741,6 @@ void btrfs_cleanup_defrag_inodes(struct btrfs_fs_info *fs_info); | |||
| 3745 | int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync); | 3741 | int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync); |
| 3746 | void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | 3742 | void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, |
| 3747 | int skip_pinned); | 3743 | int skip_pinned); |
| 3748 | int btrfs_replace_extent_cache(struct inode *inode, struct extent_map *replace, | ||
| 3749 | u64 start, u64 end, int skip_pinned, | ||
| 3750 | int modified); | ||
| 3751 | extern const struct file_operations btrfs_file_operations; | 3744 | extern const struct file_operations btrfs_file_operations; |
| 3752 | int __btrfs_drop_extents(struct btrfs_trans_handle *trans, | 3745 | int __btrfs_drop_extents(struct btrfs_trans_handle *trans, |
| 3753 | struct btrfs_root *root, struct inode *inode, | 3746 | struct btrfs_root *root, struct inode *inode, |
| @@ -3944,9 +3937,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
| 3944 | u64 end, struct btrfs_scrub_progress *progress, | 3937 | u64 end, struct btrfs_scrub_progress *progress, |
| 3945 | int readonly, int is_dev_replace); | 3938 | int readonly, int is_dev_replace); |
| 3946 | void btrfs_scrub_pause(struct btrfs_root *root); | 3939 | 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); | 3940 | 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); | 3941 | int btrfs_scrub_cancel(struct btrfs_fs_info *info); |
| 3951 | int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info, | 3942 | int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info, |
| 3952 | struct btrfs_device *dev); | 3943 | struct btrfs_device *dev); |
| @@ -4028,5 +4019,9 @@ static inline int btrfs_defrag_cancelled(struct btrfs_fs_info *fs_info) | |||
| 4028 | return signal_pending(current); | 4019 | return signal_pending(current); |
| 4029 | } | 4020 | } |
| 4030 | 4021 | ||
| 4022 | /* Sanity test specific functions */ | ||
| 4023 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
| 4024 | void btrfs_test_destroy_inode(struct inode *inode); | ||
| 4025 | #endif | ||
| 4031 | 4026 | ||
| 4032 | #endif | 4027 | #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..2cfc3dfff64f 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 | { |
| @@ -375,7 +366,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root, | |||
| 375 | dev_replace->tgtdev = tgt_device; | 366 | dev_replace->tgtdev = tgt_device; |
| 376 | 367 | ||
| 377 | printk_in_rcu(KERN_INFO | 368 | printk_in_rcu(KERN_INFO |
| 378 | "btrfs: dev_replace from %s (devid %llu) to %s) started\n", | 369 | "btrfs: dev_replace from %s (devid %llu) to %s started\n", |
| 379 | src_device->missing ? "<missing disk>" : | 370 | src_device->missing ? "<missing disk>" : |
| 380 | rcu_str_deref(src_device->name), | 371 | rcu_str_deref(src_device->name), |
| 381 | src_device->devid, | 372 | src_device->devid, |
| @@ -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..8072cfa8a3b1 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. */ |
| @@ -3528,7 +3517,6 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) | |||
| 3528 | int btrfs_commit_super(struct btrfs_root *root) | 3517 | int btrfs_commit_super(struct btrfs_root *root) |
| 3529 | { | 3518 | { |
| 3530 | struct btrfs_trans_handle *trans; | 3519 | struct btrfs_trans_handle *trans; |
| 3531 | int ret; | ||
| 3532 | 3520 | ||
| 3533 | mutex_lock(&root->fs_info->cleaner_mutex); | 3521 | mutex_lock(&root->fs_info->cleaner_mutex); |
| 3534 | btrfs_run_delayed_iputs(root); | 3522 | btrfs_run_delayed_iputs(root); |
| @@ -3542,25 +3530,7 @@ int btrfs_commit_super(struct btrfs_root *root) | |||
| 3542 | trans = btrfs_join_transaction(root); | 3530 | trans = btrfs_join_transaction(root); |
| 3543 | if (IS_ERR(trans)) | 3531 | if (IS_ERR(trans)) |
| 3544 | return PTR_ERR(trans); | 3532 | return PTR_ERR(trans); |
| 3545 | ret = btrfs_commit_transaction(trans, root); | 3533 | return btrfs_commit_transaction(trans, root); |
| 3546 | if (ret) | ||
| 3547 | return ret; | ||
| 3548 | /* run commit again to drop the original snapshot */ | ||
| 3549 | trans = btrfs_join_transaction(root); | ||
| 3550 | if (IS_ERR(trans)) | ||
| 3551 | return PTR_ERR(trans); | ||
| 3552 | ret = btrfs_commit_transaction(trans, root); | ||
| 3553 | if (ret) | ||
| 3554 | return ret; | ||
| 3555 | ret = btrfs_write_and_wait_transaction(NULL, root); | ||
| 3556 | if (ret) { | ||
| 3557 | btrfs_error(root->fs_info, ret, | ||
| 3558 | "Failed to sync btree inode to disk."); | ||
| 3559 | return ret; | ||
| 3560 | } | ||
| 3561 | |||
| 3562 | ret = write_ctree_super(NULL, root, 0); | ||
| 3563 | return ret; | ||
| 3564 | } | 3534 | } |
| 3565 | 3535 | ||
| 3566 | int close_ctree(struct btrfs_root *root) | 3536 | int close_ctree(struct btrfs_root *root) |
| @@ -3614,12 +3584,12 @@ int close_ctree(struct btrfs_root *root) | |||
| 3614 | percpu_counter_sum(&fs_info->delalloc_bytes)); | 3584 | percpu_counter_sum(&fs_info->delalloc_bytes)); |
| 3615 | } | 3585 | } |
| 3616 | 3586 | ||
| 3587 | del_fs_roots(fs_info); | ||
| 3588 | |||
| 3617 | btrfs_free_block_groups(fs_info); | 3589 | btrfs_free_block_groups(fs_info); |
| 3618 | 3590 | ||
| 3619 | btrfs_stop_all_workers(fs_info); | 3591 | btrfs_stop_all_workers(fs_info); |
| 3620 | 3592 | ||
| 3621 | del_fs_roots(fs_info); | ||
| 3622 | |||
| 3623 | free_root_pointers(fs_info, 1); | 3593 | free_root_pointers(fs_info, 1); |
| 3624 | 3594 | ||
| 3625 | iput(fs_info->btree_inode); | 3595 | iput(fs_info->btree_inode); |
| @@ -3669,10 +3639,20 @@ int btrfs_set_buffer_uptodate(struct extent_buffer *buf) | |||
| 3669 | 3639 | ||
| 3670 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | 3640 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) |
| 3671 | { | 3641 | { |
| 3672 | struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; | 3642 | struct btrfs_root *root; |
| 3673 | u64 transid = btrfs_header_generation(buf); | 3643 | u64 transid = btrfs_header_generation(buf); |
| 3674 | int was_dirty; | 3644 | int was_dirty; |
| 3675 | 3645 | ||
| 3646 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
| 3647 | /* | ||
| 3648 | * This is a fast path so only do this check if we have sanity tests | ||
| 3649 | * enabled. Normal people shouldn't be marking dummy buffers as dirty | ||
| 3650 | * outside of the sanity tests. | ||
| 3651 | */ | ||
| 3652 | if (unlikely(test_bit(EXTENT_BUFFER_DUMMY, &buf->bflags))) | ||
| 3653 | return; | ||
| 3654 | #endif | ||
| 3655 | root = BTRFS_I(buf->pages[0]->mapping->host)->root; | ||
| 3676 | btrfs_assert_tree_locked(buf); | 3656 | btrfs_assert_tree_locked(buf); |
| 3677 | if (transid != root->fs_info->generation) | 3657 | if (transid != root->fs_info->generation) |
| 3678 | WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, " | 3658 | WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, " |
| @@ -3802,7 +3782,8 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info) | |||
| 3802 | while (!list_empty(&splice)) { | 3782 | while (!list_empty(&splice)) { |
| 3803 | root = list_first_entry(&splice, struct btrfs_root, | 3783 | root = list_first_entry(&splice, struct btrfs_root, |
| 3804 | ordered_root); | 3784 | ordered_root); |
| 3805 | list_del_init(&root->ordered_root); | 3785 | list_move_tail(&root->ordered_root, |
| 3786 | &fs_info->ordered_roots); | ||
| 3806 | 3787 | ||
| 3807 | btrfs_destroy_ordered_extents(root); | 3788 | btrfs_destroy_ordered_extents(root); |
| 3808 | 3789 | ||
| @@ -3880,24 +3861,6 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | |||
| 3880 | return ret; | 3861 | return ret; |
| 3881 | } | 3862 | } |
| 3882 | 3863 | ||
| 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) | 3864 | static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) |
| 3902 | { | 3865 | { |
| 3903 | struct btrfs_inode *btrfs_inode; | 3866 | struct btrfs_inode *btrfs_inode; |
| @@ -4027,15 +3990,13 @@ again: | |||
| 4027 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | 3990 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, |
| 4028 | struct btrfs_root *root) | 3991 | struct btrfs_root *root) |
| 4029 | { | 3992 | { |
| 3993 | btrfs_destroy_ordered_operations(cur_trans, root); | ||
| 3994 | |||
| 4030 | btrfs_destroy_delayed_refs(cur_trans, root); | 3995 | 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 | 3996 | ||
| 4034 | cur_trans->state = TRANS_STATE_COMMIT_START; | 3997 | cur_trans->state = TRANS_STATE_COMMIT_START; |
| 4035 | wake_up(&root->fs_info->transaction_blocked_wait); | 3998 | wake_up(&root->fs_info->transaction_blocked_wait); |
| 4036 | 3999 | ||
| 4037 | btrfs_evict_pending_snapshots(cur_trans); | ||
| 4038 | |||
| 4039 | cur_trans->state = TRANS_STATE_UNBLOCKED; | 4000 | cur_trans->state = TRANS_STATE_UNBLOCKED; |
| 4040 | wake_up(&root->fs_info->transaction_wait); | 4001 | wake_up(&root->fs_info->transaction_wait); |
| 4041 | 4002 | ||
| @@ -4059,63 +4020,51 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | |||
| 4059 | static int btrfs_cleanup_transaction(struct btrfs_root *root) | 4020 | static int btrfs_cleanup_transaction(struct btrfs_root *root) |
| 4060 | { | 4021 | { |
| 4061 | struct btrfs_transaction *t; | 4022 | struct btrfs_transaction *t; |
| 4062 | LIST_HEAD(list); | ||
| 4063 | 4023 | ||
| 4064 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 4024 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
| 4065 | 4025 | ||
| 4066 | spin_lock(&root->fs_info->trans_lock); | 4026 | spin_lock(&root->fs_info->trans_lock); |
| 4067 | list_splice_init(&root->fs_info->trans_list, &list); | 4027 | while (!list_empty(&root->fs_info->trans_list)) { |
| 4068 | root->fs_info->running_transaction = NULL; | 4028 | t = list_first_entry(&root->fs_info->trans_list, |
| 4069 | spin_unlock(&root->fs_info->trans_lock); | 4029 | struct btrfs_transaction, list); |
| 4070 | 4030 | if (t->state >= TRANS_STATE_COMMIT_START) { | |
| 4071 | while (!list_empty(&list)) { | 4031 | atomic_inc(&t->use_count); |
| 4072 | t = list_entry(list.next, struct btrfs_transaction, list); | 4032 | spin_unlock(&root->fs_info->trans_lock); |
| 4073 | 4033 | btrfs_wait_for_commit(root, t->transid); | |
| 4074 | btrfs_destroy_ordered_operations(t, root); | 4034 | btrfs_put_transaction(t); |
| 4075 | 4035 | spin_lock(&root->fs_info->trans_lock); | |
| 4076 | btrfs_destroy_all_ordered_extents(root->fs_info); | 4036 | continue; |
| 4077 | 4037 | } | |
| 4078 | btrfs_destroy_delayed_refs(t, root); | 4038 | if (t == root->fs_info->running_transaction) { |
| 4079 | 4039 | t->state = TRANS_STATE_COMMIT_DOING; | |
| 4080 | /* | 4040 | spin_unlock(&root->fs_info->trans_lock); |
| 4081 | * FIXME: cleanup wait for commit | 4041 | /* |
| 4082 | * We needn't acquire the lock here, because we are during | 4042 | * 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. | 4043 | * handle open currently for this transaction. |
| 4084 | */ | 4044 | */ |
| 4085 | t->state = TRANS_STATE_COMMIT_START; | 4045 | wait_event(t->writer_wait, |
| 4086 | smp_mb(); | 4046 | atomic_read(&t->num_writers) == 0); |
| 4087 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) | 4047 | } else { |
| 4088 | wake_up(&root->fs_info->transaction_blocked_wait); | 4048 | spin_unlock(&root->fs_info->trans_lock); |
| 4089 | 4049 | } | |
| 4090 | btrfs_evict_pending_snapshots(t); | 4050 | 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 | 4051 | ||
| 4113 | atomic_set(&t->use_count, 0); | 4052 | spin_lock(&root->fs_info->trans_lock); |
| 4053 | if (t == root->fs_info->running_transaction) | ||
| 4054 | root->fs_info->running_transaction = NULL; | ||
| 4114 | list_del_init(&t->list); | 4055 | list_del_init(&t->list); |
| 4115 | memset(t, 0, sizeof(*t)); | 4056 | spin_unlock(&root->fs_info->trans_lock); |
| 4116 | kmem_cache_free(btrfs_transaction_cachep, t); | ||
| 4117 | } | ||
| 4118 | 4057 | ||
| 4058 | btrfs_put_transaction(t); | ||
| 4059 | trace_btrfs_transaction_commit(root); | ||
| 4060 | spin_lock(&root->fs_info->trans_lock); | ||
| 4061 | } | ||
| 4062 | spin_unlock(&root->fs_info->trans_lock); | ||
| 4063 | btrfs_destroy_all_ordered_extents(root->fs_info); | ||
| 4064 | btrfs_destroy_delayed_inodes(root); | ||
| 4065 | btrfs_assert_delayed_root_empty(root); | ||
| 4066 | btrfs_destroy_pinned_extent(root, root->fs_info->pinned_extents); | ||
| 4067 | btrfs_destroy_all_delalloc_inodes(root->fs_info); | ||
| 4119 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 4068 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
| 4120 | 4069 | ||
| 4121 | return 0; | 4070 | 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..8e457fca0a0b 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) { |
| @@ -1983,6 +1980,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, | |||
| 1983 | struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; | 1980 | struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; |
| 1984 | int ret; | 1981 | int ret; |
| 1985 | 1982 | ||
| 1983 | ASSERT(!(fs_info->sb->s_flags & MS_RDONLY)); | ||
| 1986 | BUG_ON(!mirror_num); | 1984 | BUG_ON(!mirror_num); |
| 1987 | 1985 | ||
| 1988 | /* we can't repair anything in raid56 yet */ | 1986 | /* we can't repair anything in raid56 yet */ |
| @@ -2039,6 +2037,9 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, | |||
| 2039 | unsigned long i, num_pages = num_extent_pages(eb->start, eb->len); | 2037 | unsigned long i, num_pages = num_extent_pages(eb->start, eb->len); |
| 2040 | int ret = 0; | 2038 | int ret = 0; |
| 2041 | 2039 | ||
| 2040 | if (root->fs_info->sb->s_flags & MS_RDONLY) | ||
| 2041 | return -EROFS; | ||
| 2042 | |||
| 2042 | for (i = 0; i < num_pages; i++) { | 2043 | for (i = 0; i < num_pages; i++) { |
| 2043 | struct page *p = extent_buffer_page(eb, i); | 2044 | struct page *p = extent_buffer_page(eb, i); |
| 2044 | ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE, | 2045 | ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE, |
| @@ -2060,12 +2061,12 @@ static int clean_io_failure(u64 start, struct page *page) | |||
| 2060 | u64 private; | 2061 | u64 private; |
| 2061 | u64 private_failure; | 2062 | u64 private_failure; |
| 2062 | struct io_failure_record *failrec; | 2063 | struct io_failure_record *failrec; |
| 2063 | struct btrfs_fs_info *fs_info; | 2064 | struct inode *inode = page->mapping->host; |
| 2065 | struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; | ||
| 2064 | struct extent_state *state; | 2066 | struct extent_state *state; |
| 2065 | int num_copies; | 2067 | int num_copies; |
| 2066 | int did_repair = 0; | 2068 | int did_repair = 0; |
| 2067 | int ret; | 2069 | int ret; |
| 2068 | struct inode *inode = page->mapping->host; | ||
| 2069 | 2070 | ||
| 2070 | private = 0; | 2071 | private = 0; |
| 2071 | ret = count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private, | 2072 | ret = count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private, |
| @@ -2088,6 +2089,8 @@ static int clean_io_failure(u64 start, struct page *page) | |||
| 2088 | did_repair = 1; | 2089 | did_repair = 1; |
| 2089 | goto out; | 2090 | goto out; |
| 2090 | } | 2091 | } |
| 2092 | if (fs_info->sb->s_flags & MS_RDONLY) | ||
| 2093 | goto out; | ||
| 2091 | 2094 | ||
| 2092 | spin_lock(&BTRFS_I(inode)->io_tree.lock); | 2095 | spin_lock(&BTRFS_I(inode)->io_tree.lock); |
| 2093 | state = find_first_extent_bit_state(&BTRFS_I(inode)->io_tree, | 2096 | state = find_first_extent_bit_state(&BTRFS_I(inode)->io_tree, |
| @@ -2097,7 +2100,6 @@ static int clean_io_failure(u64 start, struct page *page) | |||
| 2097 | 2100 | ||
| 2098 | if (state && state->start <= failrec->start && | 2101 | if (state && state->start <= failrec->start && |
| 2099 | state->end >= failrec->start + failrec->len - 1) { | 2102 | state->end >= failrec->start + failrec->len - 1) { |
| 2100 | fs_info = BTRFS_I(inode)->root->fs_info; | ||
| 2101 | num_copies = btrfs_num_copies(fs_info, failrec->logical, | 2103 | num_copies = btrfs_num_copies(fs_info, failrec->logical, |
| 2102 | failrec->len); | 2104 | failrec->len); |
| 2103 | if (num_copies > 1) { | 2105 | if (num_copies > 1) { |
| @@ -3569,9 +3571,8 @@ retry: | |||
| 3569 | * but no sense in crashing the users box for something | 3571 | * but no sense in crashing the users box for something |
| 3570 | * we can survive anyway. | 3572 | * we can survive anyway. |
| 3571 | */ | 3573 | */ |
| 3572 | if (!eb) { | 3574 | if (WARN_ON(!eb)) { |
| 3573 | spin_unlock(&mapping->private_lock); | 3575 | spin_unlock(&mapping->private_lock); |
| 3574 | WARN_ON(1); | ||
| 3575 | continue; | 3576 | continue; |
| 3576 | } | 3577 | } |
| 3577 | 3578 | ||
| @@ -4038,7 +4039,7 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, | |||
| 4038 | if (offset >= last) | 4039 | if (offset >= last) |
| 4039 | return NULL; | 4040 | return NULL; |
| 4040 | 4041 | ||
| 4041 | while(1) { | 4042 | while (1) { |
| 4042 | len = last - offset; | 4043 | len = last - offset; |
| 4043 | if (len == 0) | 4044 | if (len == 0) |
| 4044 | break; | 4045 | break; |
| @@ -4062,6 +4063,19 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, | |||
| 4062 | return NULL; | 4063 | return NULL; |
| 4063 | } | 4064 | } |
| 4064 | 4065 | ||
| 4066 | static noinline int count_ext_ref(u64 inum, u64 offset, u64 root_id, void *ctx) | ||
| 4067 | { | ||
| 4068 | unsigned long cnt = *((unsigned long *)ctx); | ||
| 4069 | |||
| 4070 | cnt++; | ||
| 4071 | *((unsigned long *)ctx) = cnt; | ||
| 4072 | |||
| 4073 | /* Now we're sure that the extent is shared. */ | ||
| 4074 | if (cnt > 1) | ||
| 4075 | return 1; | ||
| 4076 | return 0; | ||
| 4077 | } | ||
| 4078 | |||
| 4065 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 4079 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 4066 | __u64 start, __u64 len, get_extent_t *get_extent) | 4080 | __u64 start, __u64 len, get_extent_t *get_extent) |
| 4067 | { | 4081 | { |
| @@ -4128,7 +4142,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 4128 | last = found_key.offset; | 4142 | last = found_key.offset; |
| 4129 | last_for_get_extent = last + 1; | 4143 | last_for_get_extent = last + 1; |
| 4130 | } | 4144 | } |
| 4131 | btrfs_free_path(path); | 4145 | btrfs_release_path(path); |
| 4132 | 4146 | ||
| 4133 | /* | 4147 | /* |
| 4134 | * we might have some extents allocated but more delalloc past those | 4148 | * we might have some extents allocated but more delalloc past those |
| @@ -4198,7 +4212,24 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 4198 | flags |= (FIEMAP_EXTENT_DELALLOC | | 4212 | flags |= (FIEMAP_EXTENT_DELALLOC | |
| 4199 | FIEMAP_EXTENT_UNKNOWN); | 4213 | FIEMAP_EXTENT_UNKNOWN); |
| 4200 | } else { | 4214 | } else { |
| 4215 | unsigned long ref_cnt = 0; | ||
| 4216 | |||
| 4201 | disko = em->block_start + offset_in_extent; | 4217 | disko = em->block_start + offset_in_extent; |
| 4218 | |||
| 4219 | /* | ||
| 4220 | * As btrfs supports shared space, this information | ||
| 4221 | * can be exported to userspace tools via | ||
| 4222 | * flag FIEMAP_EXTENT_SHARED. | ||
| 4223 | */ | ||
| 4224 | ret = iterate_inodes_from_logical( | ||
| 4225 | em->block_start, | ||
| 4226 | BTRFS_I(inode)->root->fs_info, | ||
| 4227 | path, count_ext_ref, &ref_cnt); | ||
| 4228 | if (ret < 0 && ret != -ENOENT) | ||
| 4229 | goto out_free; | ||
| 4230 | |||
| 4231 | if (ref_cnt > 1) | ||
| 4232 | flags |= FIEMAP_EXTENT_SHARED; | ||
| 4202 | } | 4233 | } |
| 4203 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | 4234 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
| 4204 | flags |= FIEMAP_EXTENT_ENCODED; | 4235 | flags |= FIEMAP_EXTENT_ENCODED; |
| @@ -4230,6 +4261,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 4230 | out_free: | 4261 | out_free: |
| 4231 | free_extent_map(em); | 4262 | free_extent_map(em); |
| 4232 | out: | 4263 | out: |
| 4264 | btrfs_free_path(path); | ||
| 4233 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, | 4265 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, |
| 4234 | &cached_state, GFP_NOFS); | 4266 | &cached_state, GFP_NOFS); |
| 4235 | return ret; | 4267 | return ret; |
| @@ -4455,6 +4487,23 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb) | |||
| 4455 | } | 4487 | } |
| 4456 | } | 4488 | } |
| 4457 | 4489 | ||
| 4490 | struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, | ||
| 4491 | u64 start) | ||
| 4492 | { | ||
| 4493 | struct extent_buffer *eb; | ||
| 4494 | |||
| 4495 | rcu_read_lock(); | ||
| 4496 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | ||
| 4497 | if (eb && atomic_inc_not_zero(&eb->refs)) { | ||
| 4498 | rcu_read_unlock(); | ||
| 4499 | mark_extent_buffer_accessed(eb); | ||
| 4500 | return eb; | ||
| 4501 | } | ||
| 4502 | rcu_read_unlock(); | ||
| 4503 | |||
| 4504 | return NULL; | ||
| 4505 | } | ||
| 4506 | |||
| 4458 | struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | 4507 | struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, |
| 4459 | u64 start, unsigned long len) | 4508 | u64 start, unsigned long len) |
| 4460 | { | 4509 | { |
| @@ -4468,14 +4517,10 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
| 4468 | int uptodate = 1; | 4517 | int uptodate = 1; |
| 4469 | int ret; | 4518 | int ret; |
| 4470 | 4519 | ||
| 4471 | rcu_read_lock(); | 4520 | |
| 4472 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | 4521 | eb = find_extent_buffer(tree, start); |
| 4473 | if (eb && atomic_inc_not_zero(&eb->refs)) { | 4522 | if (eb) |
| 4474 | rcu_read_unlock(); | ||
| 4475 | mark_extent_buffer_accessed(eb); | ||
| 4476 | return eb; | 4523 | return eb; |
| 4477 | } | ||
| 4478 | rcu_read_unlock(); | ||
| 4479 | 4524 | ||
| 4480 | eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS); | 4525 | eb = __alloc_extent_buffer(tree, start, len, GFP_NOFS); |
| 4481 | if (!eb) | 4526 | if (!eb) |
| @@ -4534,24 +4579,17 @@ again: | |||
| 4534 | 4579 | ||
| 4535 | spin_lock(&tree->buffer_lock); | 4580 | spin_lock(&tree->buffer_lock); |
| 4536 | ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb); | 4581 | ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb); |
| 4582 | spin_unlock(&tree->buffer_lock); | ||
| 4583 | radix_tree_preload_end(); | ||
| 4537 | if (ret == -EEXIST) { | 4584 | if (ret == -EEXIST) { |
| 4538 | exists = radix_tree_lookup(&tree->buffer, | 4585 | exists = find_extent_buffer(tree, start); |
| 4539 | start >> PAGE_CACHE_SHIFT); | 4586 | if (exists) |
| 4540 | if (!atomic_inc_not_zero(&exists->refs)) { | 4587 | goto free_eb; |
| 4541 | spin_unlock(&tree->buffer_lock); | 4588 | else |
| 4542 | radix_tree_preload_end(); | ||
| 4543 | exists = NULL; | ||
| 4544 | goto again; | 4589 | 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 | } | 4590 | } |
| 4551 | /* add one reference for the tree */ | 4591 | /* add one reference for the tree */ |
| 4552 | check_buffer_tree_ref(eb); | 4592 | check_buffer_tree_ref(eb); |
| 4553 | spin_unlock(&tree->buffer_lock); | ||
| 4554 | radix_tree_preload_end(); | ||
| 4555 | 4593 | ||
| 4556 | /* | 4594 | /* |
| 4557 | * there is a race where release page may have | 4595 | * there is a race where release page may have |
| @@ -4582,23 +4620,6 @@ free_eb: | |||
| 4582 | return exists; | 4620 | return exists; |
| 4583 | } | 4621 | } |
| 4584 | 4622 | ||
| 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) | 4623 | static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) |
| 4603 | { | 4624 | { |
| 4604 | struct extent_buffer *eb = | 4625 | struct extent_buffer *eb = |
| @@ -5062,23 +5083,6 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, | |||
| 5062 | } | 5083 | } |
| 5063 | } | 5084 | } |
| 5064 | 5085 | ||
| 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) | 5086 | static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len) |
| 5083 | { | 5087 | { |
| 5084 | unsigned long distance = (src > dst) ? src - dst : dst - src; | 5088 | unsigned long distance = (src > dst) ? src - dst : dst - src; |
| @@ -5189,7 +5193,7 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | |||
| 5189 | 5193 | ||
| 5190 | cur = min_t(unsigned long, len, src_off_in_page + 1); | 5194 | cur = min_t(unsigned long, len, src_off_in_page + 1); |
| 5191 | cur = min(cur, dst_off_in_page + 1); | 5195 | cur = min(cur, dst_off_in_page + 1); |
| 5192 | move_pages(extent_buffer_page(dst, dst_i), | 5196 | copy_pages(extent_buffer_page(dst, dst_i), |
| 5193 | extent_buffer_page(dst, src_i), | 5197 | extent_buffer_page(dst, src_i), |
| 5194 | dst_off_in_page - cur + 1, | 5198 | dst_off_in_page - cur + 1, |
| 5195 | src_off_in_page - cur + 1, cur); | 5199 | 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..f1a77449d032 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) { |
| @@ -2133,7 +2129,8 @@ static noinline bool record_extent_backrefs(struct btrfs_path *path, | |||
| 2133 | old->extent_offset, fs_info, | 2129 | old->extent_offset, fs_info, |
| 2134 | path, record_one_backref, | 2130 | path, record_one_backref, |
| 2135 | old); | 2131 | old); |
| 2136 | BUG_ON(ret < 0 && ret != -ENOENT); | 2132 | if (ret < 0 && ret != -ENOENT) |
| 2133 | return false; | ||
| 2137 | 2134 | ||
| 2138 | /* no backref to be processed for this extent */ | 2135 | /* no backref to be processed for this extent */ |
| 2139 | if (!old->count) { | 2136 | if (!old->count) { |
| @@ -2367,10 +2364,23 @@ out_unlock: | |||
| 2367 | return ret; | 2364 | return ret; |
| 2368 | } | 2365 | } |
| 2369 | 2366 | ||
| 2367 | static void free_sa_defrag_extent(struct new_sa_defrag_extent *new) | ||
| 2368 | { | ||
| 2369 | struct old_sa_defrag_extent *old, *tmp; | ||
| 2370 | |||
| 2371 | if (!new) | ||
| 2372 | return; | ||
| 2373 | |||
| 2374 | list_for_each_entry_safe(old, tmp, &new->head, list) { | ||
| 2375 | list_del(&old->list); | ||
| 2376 | kfree(old); | ||
| 2377 | } | ||
| 2378 | kfree(new); | ||
| 2379 | } | ||
| 2380 | |||
| 2370 | static void relink_file_extents(struct new_sa_defrag_extent *new) | 2381 | static void relink_file_extents(struct new_sa_defrag_extent *new) |
| 2371 | { | 2382 | { |
| 2372 | struct btrfs_path *path; | 2383 | struct btrfs_path *path; |
| 2373 | struct old_sa_defrag_extent *old, *tmp; | ||
| 2374 | struct sa_defrag_extent_backref *backref; | 2384 | struct sa_defrag_extent_backref *backref; |
| 2375 | struct sa_defrag_extent_backref *prev = NULL; | 2385 | struct sa_defrag_extent_backref *prev = NULL; |
| 2376 | struct inode *inode; | 2386 | struct inode *inode; |
| @@ -2413,16 +2423,11 @@ static void relink_file_extents(struct new_sa_defrag_extent *new) | |||
| 2413 | kfree(prev); | 2423 | kfree(prev); |
| 2414 | 2424 | ||
| 2415 | btrfs_free_path(path); | 2425 | 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: | 2426 | out: |
| 2427 | free_sa_defrag_extent(new); | ||
| 2428 | |||
| 2422 | atomic_dec(&root->fs_info->defrag_running); | 2429 | atomic_dec(&root->fs_info->defrag_running); |
| 2423 | wake_up(&root->fs_info->transaction_wait); | 2430 | wake_up(&root->fs_info->transaction_wait); |
| 2424 | |||
| 2425 | kfree(new); | ||
| 2426 | } | 2431 | } |
| 2427 | 2432 | ||
| 2428 | static struct new_sa_defrag_extent * | 2433 | static struct new_sa_defrag_extent * |
| @@ -2432,7 +2437,7 @@ record_old_file_extents(struct inode *inode, | |||
| 2432 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2437 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 2433 | struct btrfs_path *path; | 2438 | struct btrfs_path *path; |
| 2434 | struct btrfs_key key; | 2439 | struct btrfs_key key; |
| 2435 | struct old_sa_defrag_extent *old, *tmp; | 2440 | struct old_sa_defrag_extent *old; |
| 2436 | struct new_sa_defrag_extent *new; | 2441 | struct new_sa_defrag_extent *new; |
| 2437 | int ret; | 2442 | int ret; |
| 2438 | 2443 | ||
| @@ -2480,7 +2485,7 @@ record_old_file_extents(struct inode *inode, | |||
| 2480 | if (slot >= btrfs_header_nritems(l)) { | 2485 | if (slot >= btrfs_header_nritems(l)) { |
| 2481 | ret = btrfs_next_leaf(root, path); | 2486 | ret = btrfs_next_leaf(root, path); |
| 2482 | if (ret < 0) | 2487 | if (ret < 0) |
| 2483 | goto out_free_list; | 2488 | goto out_free_path; |
| 2484 | else if (ret > 0) | 2489 | else if (ret > 0) |
| 2485 | break; | 2490 | break; |
| 2486 | continue; | 2491 | continue; |
| @@ -2509,7 +2514,7 @@ record_old_file_extents(struct inode *inode, | |||
| 2509 | 2514 | ||
| 2510 | old = kmalloc(sizeof(*old), GFP_NOFS); | 2515 | old = kmalloc(sizeof(*old), GFP_NOFS); |
| 2511 | if (!old) | 2516 | if (!old) |
| 2512 | goto out_free_list; | 2517 | goto out_free_path; |
| 2513 | 2518 | ||
| 2514 | offset = max(new->file_pos, key.offset); | 2519 | offset = max(new->file_pos, key.offset); |
| 2515 | end = min(new->file_pos + new->len, key.offset + num_bytes); | 2520 | end = min(new->file_pos + new->len, key.offset + num_bytes); |
| @@ -2531,15 +2536,10 @@ next: | |||
| 2531 | 2536 | ||
| 2532 | return new; | 2537 | return new; |
| 2533 | 2538 | ||
| 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: | 2539 | out_free_path: |
| 2540 | btrfs_free_path(path); | 2540 | btrfs_free_path(path); |
| 2541 | out_kfree: | 2541 | out_kfree: |
| 2542 | kfree(new); | 2542 | free_sa_defrag_extent(new); |
| 2543 | return NULL; | 2543 | return NULL; |
| 2544 | } | 2544 | } |
| 2545 | 2545 | ||
| @@ -2710,8 +2710,14 @@ out: | |||
| 2710 | btrfs_remove_ordered_extent(inode, ordered_extent); | 2710 | btrfs_remove_ordered_extent(inode, ordered_extent); |
| 2711 | 2711 | ||
| 2712 | /* for snapshot-aware defrag */ | 2712 | /* for snapshot-aware defrag */ |
| 2713 | if (new) | 2713 | if (new) { |
| 2714 | relink_file_extents(new); | 2714 | if (ret) { |
| 2715 | free_sa_defrag_extent(new); | ||
| 2716 | atomic_dec(&root->fs_info->defrag_running); | ||
| 2717 | } else { | ||
| 2718 | relink_file_extents(new); | ||
| 2719 | } | ||
| 2720 | } | ||
| 2715 | 2721 | ||
| 2716 | /* once for us */ | 2722 | /* once for us */ |
| 2717 | btrfs_put_ordered_extent(ordered_extent); | 2723 | btrfs_put_ordered_extent(ordered_extent); |
| @@ -2969,6 +2975,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) | |||
| 2969 | if (insert >= 1) { | 2975 | if (insert >= 1) { |
| 2970 | ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode)); | 2976 | ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode)); |
| 2971 | if (ret) { | 2977 | if (ret) { |
| 2978 | atomic_dec(&root->orphan_inodes); | ||
| 2972 | if (reserve) { | 2979 | if (reserve) { |
| 2973 | clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED, | 2980 | clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED, |
| 2974 | &BTRFS_I(inode)->runtime_flags); | 2981 | &BTRFS_I(inode)->runtime_flags); |
| @@ -3018,14 +3025,16 @@ static int btrfs_orphan_del(struct btrfs_trans_handle *trans, | |||
| 3018 | release_rsv = 1; | 3025 | release_rsv = 1; |
| 3019 | spin_unlock(&root->orphan_lock); | 3026 | spin_unlock(&root->orphan_lock); |
| 3020 | 3027 | ||
| 3021 | if (trans && delete_item) | 3028 | 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); | 3029 | atomic_dec(&root->orphan_inodes); |
| 3030 | if (trans) | ||
| 3031 | ret = btrfs_del_orphan_item(trans, root, | ||
| 3032 | btrfs_ino(inode)); | ||
| 3027 | } | 3033 | } |
| 3028 | 3034 | ||
| 3035 | if (release_rsv) | ||
| 3036 | btrfs_orphan_release_metadata(inode); | ||
| 3037 | |||
| 3029 | return ret; | 3038 | return ret; |
| 3030 | } | 3039 | } |
| 3031 | 3040 | ||
| @@ -3172,8 +3181,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 3172 | 3181 | ||
| 3173 | /* if we have links, this was a truncate, lets do that */ | 3182 | /* if we have links, this was a truncate, lets do that */ |
| 3174 | if (inode->i_nlink) { | 3183 | if (inode->i_nlink) { |
| 3175 | if (!S_ISREG(inode->i_mode)) { | 3184 | if (WARN_ON(!S_ISREG(inode->i_mode))) { |
| 3176 | WARN_ON(1); | ||
| 3177 | iput(inode); | 3185 | iput(inode); |
| 3178 | continue; | 3186 | continue; |
| 3179 | } | 3187 | } |
| @@ -3636,7 +3644,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | |||
| 3636 | int ret; | 3644 | int ret; |
| 3637 | ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len); | 3645 | ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len); |
| 3638 | if (!ret) { | 3646 | if (!ret) { |
| 3639 | btrfs_drop_nlink(inode); | 3647 | drop_nlink(inode); |
| 3640 | ret = btrfs_update_inode(trans, root, inode); | 3648 | ret = btrfs_update_inode(trans, root, inode); |
| 3641 | } | 3649 | } |
| 3642 | return ret; | 3650 | return ret; |
| @@ -4230,15 +4238,16 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
| 4230 | 4238 | ||
| 4231 | while (1) { | 4239 | while (1) { |
| 4232 | struct btrfs_ordered_extent *ordered; | 4240 | struct btrfs_ordered_extent *ordered; |
| 4233 | btrfs_wait_ordered_range(inode, hole_start, | 4241 | |
| 4234 | block_end - hole_start); | ||
| 4235 | lock_extent_bits(io_tree, hole_start, block_end - 1, 0, | 4242 | lock_extent_bits(io_tree, hole_start, block_end - 1, 0, |
| 4236 | &cached_state); | 4243 | &cached_state); |
| 4237 | ordered = btrfs_lookup_ordered_extent(inode, hole_start); | 4244 | ordered = btrfs_lookup_ordered_range(inode, hole_start, |
| 4245 | block_end - hole_start); | ||
| 4238 | if (!ordered) | 4246 | if (!ordered) |
| 4239 | break; | 4247 | break; |
| 4240 | unlock_extent_cached(io_tree, hole_start, block_end - 1, | 4248 | unlock_extent_cached(io_tree, hole_start, block_end - 1, |
| 4241 | &cached_state, GFP_NOFS); | 4249 | &cached_state, GFP_NOFS); |
| 4250 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
| 4242 | btrfs_put_ordered_extent(ordered); | 4251 | btrfs_put_ordered_extent(ordered); |
| 4243 | } | 4252 | } |
| 4244 | 4253 | ||
| @@ -4472,8 +4481,10 @@ void btrfs_evict_inode(struct inode *inode) | |||
| 4472 | trace_btrfs_inode_evict(inode); | 4481 | trace_btrfs_inode_evict(inode); |
| 4473 | 4482 | ||
| 4474 | truncate_inode_pages(&inode->i_data, 0); | 4483 | truncate_inode_pages(&inode->i_data, 0); |
| 4475 | if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || | 4484 | if (inode->i_nlink && |
| 4476 | btrfs_is_free_space_inode(inode))) | 4485 | ((btrfs_root_refs(&root->root_item) != 0 && |
| 4486 | root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) || | ||
| 4487 | btrfs_is_free_space_inode(inode))) | ||
| 4477 | goto no_delete; | 4488 | goto no_delete; |
| 4478 | 4489 | ||
| 4479 | if (is_bad_inode(inode)) { | 4490 | if (is_bad_inode(inode)) { |
| @@ -4490,7 +4501,8 @@ void btrfs_evict_inode(struct inode *inode) | |||
| 4490 | } | 4501 | } |
| 4491 | 4502 | ||
| 4492 | if (inode->i_nlink > 0) { | 4503 | if (inode->i_nlink > 0) { |
| 4493 | BUG_ON(btrfs_root_refs(&root->root_item) != 0); | 4504 | BUG_ON(btrfs_root_refs(&root->root_item) != 0 && |
| 4505 | root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID); | ||
| 4494 | goto no_delete; | 4506 | goto no_delete; |
| 4495 | } | 4507 | } |
| 4496 | 4508 | ||
| @@ -4731,14 +4743,7 @@ static void inode_tree_del(struct inode *inode) | |||
| 4731 | } | 4743 | } |
| 4732 | spin_unlock(&root->inode_lock); | 4744 | spin_unlock(&root->inode_lock); |
| 4733 | 4745 | ||
| 4734 | /* | 4746 | 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); | 4747 | synchronize_srcu(&root->fs_info->subvol_srcu); |
| 4743 | spin_lock(&root->inode_lock); | 4748 | spin_lock(&root->inode_lock); |
| 4744 | empty = RB_EMPTY_ROOT(&root->inode_tree); | 4749 | empty = RB_EMPTY_ROOT(&root->inode_tree); |
| @@ -4831,10 +4836,12 @@ static struct inode *btrfs_iget_locked(struct super_block *s, | |||
| 4831 | { | 4836 | { |
| 4832 | struct inode *inode; | 4837 | struct inode *inode; |
| 4833 | struct btrfs_iget_args args; | 4838 | struct btrfs_iget_args args; |
| 4839 | unsigned long hashval = btrfs_inode_hash(objectid, root); | ||
| 4840 | |||
| 4834 | args.ino = objectid; | 4841 | args.ino = objectid; |
| 4835 | args.root = root; | 4842 | args.root = root; |
| 4836 | 4843 | ||
| 4837 | inode = iget5_locked(s, objectid, btrfs_find_actor, | 4844 | inode = iget5_locked(s, hashval, btrfs_find_actor, |
| 4838 | btrfs_init_locked_inode, | 4845 | btrfs_init_locked_inode, |
| 4839 | (void *)&args); | 4846 | (void *)&args); |
| 4840 | return inode; | 4847 | return inode; |
| @@ -5048,7 +5055,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) | |||
| 5048 | continue; | 5055 | continue; |
| 5049 | } | 5056 | } |
| 5050 | 5057 | ||
| 5051 | item = btrfs_item_nr(leaf, slot); | 5058 | item = btrfs_item_nr(slot); |
| 5052 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 5059 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
| 5053 | 5060 | ||
| 5054 | if (found_key.objectid != key.objectid) | 5061 | if (found_key.objectid != key.objectid) |
| @@ -5454,7 +5461,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 5454 | BTRFS_INODE_NODATASUM; | 5461 | BTRFS_INODE_NODATASUM; |
| 5455 | } | 5462 | } |
| 5456 | 5463 | ||
| 5457 | insert_inode_hash(inode); | 5464 | btrfs_insert_inode_hash(inode); |
| 5458 | inode_tree_add(inode); | 5465 | inode_tree_add(inode); |
| 5459 | 5466 | ||
| 5460 | trace_btrfs_inode_new(inode); | 5467 | trace_btrfs_inode_new(inode); |
| @@ -5730,7 +5737,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 5730 | goto fail; | 5737 | goto fail; |
| 5731 | } | 5738 | } |
| 5732 | 5739 | ||
| 5733 | btrfs_inc_nlink(inode); | 5740 | inc_nlink(inode); |
| 5734 | inode_inc_iversion(inode); | 5741 | inode_inc_iversion(inode); |
| 5735 | inode->i_ctime = CURRENT_TIME; | 5742 | inode->i_ctime = CURRENT_TIME; |
| 5736 | ihold(inode); | 5743 | ihold(inode); |
| @@ -5860,7 +5867,7 @@ static noinline int uncompress_inline(struct btrfs_path *path, | |||
| 5860 | compress_type = btrfs_file_extent_compression(leaf, item); | 5867 | compress_type = btrfs_file_extent_compression(leaf, item); |
| 5861 | max_size = btrfs_file_extent_ram_bytes(leaf, item); | 5868 | max_size = btrfs_file_extent_ram_bytes(leaf, item); |
| 5862 | inline_size = btrfs_file_extent_inline_item_len(leaf, | 5869 | inline_size = btrfs_file_extent_inline_item_len(leaf, |
| 5863 | btrfs_item_nr(leaf, path->slots[0])); | 5870 | btrfs_item_nr(path->slots[0])); |
| 5864 | tmp = kmalloc(inline_size, GFP_NOFS); | 5871 | tmp = kmalloc(inline_size, GFP_NOFS); |
| 5865 | if (!tmp) | 5872 | if (!tmp) |
| 5866 | return -ENOMEM; | 5873 | return -ENOMEM; |
| @@ -5974,7 +5981,14 @@ again: | |||
| 5974 | found_type = btrfs_key_type(&found_key); | 5981 | found_type = btrfs_key_type(&found_key); |
| 5975 | if (found_key.objectid != objectid || | 5982 | if (found_key.objectid != objectid || |
| 5976 | found_type != BTRFS_EXTENT_DATA_KEY) { | 5983 | found_type != BTRFS_EXTENT_DATA_KEY) { |
| 5977 | goto not_found; | 5984 | /* |
| 5985 | * If we backup past the first extent we want to move forward | ||
| 5986 | * and see if there is an extent in front of us, otherwise we'll | ||
| 5987 | * say there is a hole for our whole search range which can | ||
| 5988 | * cause problems. | ||
| 5989 | */ | ||
| 5990 | extent_end = start; | ||
| 5991 | goto next; | ||
| 5978 | } | 5992 | } |
| 5979 | 5993 | ||
| 5980 | found_type = btrfs_file_extent_type(leaf, item); | 5994 | found_type = btrfs_file_extent_type(leaf, item); |
| @@ -5989,7 +6003,7 @@ again: | |||
| 5989 | size = btrfs_file_extent_inline_len(leaf, item); | 6003 | size = btrfs_file_extent_inline_len(leaf, item); |
| 5990 | extent_end = ALIGN(extent_start + size, root->sectorsize); | 6004 | extent_end = ALIGN(extent_start + size, root->sectorsize); |
| 5991 | } | 6005 | } |
| 5992 | 6006 | next: | |
| 5993 | if (start >= extent_end) { | 6007 | if (start >= extent_end) { |
| 5994 | path->slots[0]++; | 6008 | path->slots[0]++; |
| 5995 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | 6009 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { |
| @@ -6173,8 +6187,7 @@ insert: | |||
| 6173 | write_unlock(&em_tree->lock); | 6187 | write_unlock(&em_tree->lock); |
| 6174 | out: | 6188 | out: |
| 6175 | 6189 | ||
| 6176 | if (em) | 6190 | trace_btrfs_get_extent(root, em); |
| 6177 | trace_btrfs_get_extent(root, em); | ||
| 6178 | 6191 | ||
| 6179 | if (path) | 6192 | if (path) |
| 6180 | btrfs_free_path(path); | 6193 | btrfs_free_path(path); |
| @@ -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..a111622598b0 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" |
| @@ -321,7 +320,7 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) | |||
| 321 | 320 | ||
| 322 | static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | 321 | static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) |
| 323 | { | 322 | { |
| 324 | struct btrfs_fs_info *fs_info = btrfs_sb(fdentry(file)->d_sb); | 323 | struct btrfs_fs_info *fs_info = btrfs_sb(file_inode(file)->i_sb); |
| 325 | struct btrfs_device *device; | 324 | struct btrfs_device *device; |
| 326 | struct request_queue *q; | 325 | struct request_queue *q; |
| 327 | struct fstrim_range range; | 326 | struct fstrim_range range; |
| @@ -369,9 +368,13 @@ 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 | int i; |
| 373 | 372 | ||
| 374 | return !memcmp(uuid, empty_uuid, BTRFS_UUID_SIZE); | 373 | for (i = 0; i < BTRFS_UUID_SIZE; i++) { |
| 374 | if (uuid[i]) | ||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | return 1; | ||
| 375 | } | 378 | } |
| 376 | 379 | ||
| 377 | static noinline int create_subvol(struct inode *dir, | 380 | static noinline int create_subvol(struct inode *dir, |
| @@ -436,7 +439,7 @@ static noinline int create_subvol(struct inode *dir, | |||
| 436 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); | 439 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); |
| 437 | btrfs_set_header_owner(leaf, objectid); | 440 | btrfs_set_header_owner(leaf, objectid); |
| 438 | 441 | ||
| 439 | write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(leaf), | 442 | write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(), |
| 440 | BTRFS_FSID_SIZE); | 443 | BTRFS_FSID_SIZE); |
| 441 | write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, | 444 | write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, |
| 442 | btrfs_header_chunk_tree_uuid(leaf), | 445 | btrfs_header_chunk_tree_uuid(leaf), |
| @@ -574,7 +577,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, | |||
| 574 | if (ret) | 577 | if (ret) |
| 575 | return ret; | 578 | return ret; |
| 576 | 579 | ||
| 577 | btrfs_wait_ordered_extents(root); | 580 | btrfs_wait_ordered_extents(root, -1); |
| 578 | 581 | ||
| 579 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); | 582 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); |
| 580 | if (!pending_snapshot) | 583 | if (!pending_snapshot) |
| @@ -688,7 +691,7 @@ static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode) | |||
| 688 | * nfs_async_unlink(). | 691 | * nfs_async_unlink(). |
| 689 | */ | 692 | */ |
| 690 | 693 | ||
| 691 | static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir) | 694 | static int btrfs_may_delete(struct inode *dir, struct dentry *victim, int isdir) |
| 692 | { | 695 | { |
| 693 | int error; | 696 | int error; |
| 694 | 697 | ||
| @@ -842,7 +845,6 @@ static int find_new_extents(struct btrfs_root *root, | |||
| 842 | { | 845 | { |
| 843 | struct btrfs_path *path; | 846 | struct btrfs_path *path; |
| 844 | struct btrfs_key min_key; | 847 | struct btrfs_key min_key; |
| 845 | struct btrfs_key max_key; | ||
| 846 | struct extent_buffer *leaf; | 848 | struct extent_buffer *leaf; |
| 847 | struct btrfs_file_extent_item *extent; | 849 | struct btrfs_file_extent_item *extent; |
| 848 | int type; | 850 | int type; |
| @@ -857,15 +859,10 @@ static int find_new_extents(struct btrfs_root *root, | |||
| 857 | min_key.type = BTRFS_EXTENT_DATA_KEY; | 859 | min_key.type = BTRFS_EXTENT_DATA_KEY; |
| 858 | min_key.offset = *off; | 860 | min_key.offset = *off; |
| 859 | 861 | ||
| 860 | max_key.objectid = ino; | ||
| 861 | max_key.type = (u8)-1; | ||
| 862 | max_key.offset = (u64)-1; | ||
| 863 | |||
| 864 | path->keep_locks = 1; | 862 | path->keep_locks = 1; |
| 865 | 863 | ||
| 866 | while(1) { | 864 | while (1) { |
| 867 | ret = btrfs_search_forward(root, &min_key, &max_key, | 865 | ret = btrfs_search_forward(root, &min_key, path, newer_than); |
| 868 | path, newer_than); | ||
| 869 | if (ret != 0) | 866 | if (ret != 0) |
| 870 | goto none; | 867 | goto none; |
| 871 | if (min_key.objectid != ino) | 868 | if (min_key.objectid != ino) |
| @@ -1206,7 +1203,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
| 1206 | ra = &file->f_ra; | 1203 | ra = &file->f_ra; |
| 1207 | } | 1204 | } |
| 1208 | 1205 | ||
| 1209 | pages = kmalloc(sizeof(struct page *) * max_cluster, | 1206 | pages = kmalloc_array(max_cluster, sizeof(struct page *), |
| 1210 | GFP_NOFS); | 1207 | GFP_NOFS); |
| 1211 | if (!pages) { | 1208 | if (!pages) { |
| 1212 | ret = -ENOMEM; | 1209 | ret = -ENOMEM; |
| @@ -1893,7 +1890,6 @@ static noinline int search_ioctl(struct inode *inode, | |||
| 1893 | { | 1890 | { |
| 1894 | struct btrfs_root *root; | 1891 | struct btrfs_root *root; |
| 1895 | struct btrfs_key key; | 1892 | struct btrfs_key key; |
| 1896 | struct btrfs_key max_key; | ||
| 1897 | struct btrfs_path *path; | 1893 | struct btrfs_path *path; |
| 1898 | struct btrfs_ioctl_search_key *sk = &args->key; | 1894 | struct btrfs_ioctl_search_key *sk = &args->key; |
| 1899 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; | 1895 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; |
| @@ -1925,15 +1921,10 @@ static noinline int search_ioctl(struct inode *inode, | |||
| 1925 | key.type = sk->min_type; | 1921 | key.type = sk->min_type; |
| 1926 | key.offset = sk->min_offset; | 1922 | key.offset = sk->min_offset; |
| 1927 | 1923 | ||
| 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; | 1924 | path->keep_locks = 1; |
| 1933 | 1925 | ||
| 1934 | while(1) { | 1926 | while (1) { |
| 1935 | ret = btrfs_search_forward(root, &key, &max_key, path, | 1927 | ret = btrfs_search_forward(root, &key, path, sk->min_transid); |
| 1936 | sk->min_transid); | ||
| 1937 | if (ret != 0) { | 1928 | if (ret != 0) { |
| 1938 | if (ret > 0) | 1929 | if (ret > 0) |
| 1939 | ret = 0; | 1930 | ret = 0; |
| @@ -2018,7 +2009,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
| 2018 | key.type = BTRFS_INODE_REF_KEY; | 2009 | key.type = BTRFS_INODE_REF_KEY; |
| 2019 | key.offset = (u64)-1; | 2010 | key.offset = (u64)-1; |
| 2020 | 2011 | ||
| 2021 | while(1) { | 2012 | while (1) { |
| 2022 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 2013 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 2023 | if (ret < 0) | 2014 | if (ret < 0) |
| 2024 | goto out; | 2015 | goto out; |
| @@ -2047,7 +2038,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
| 2047 | } | 2038 | } |
| 2048 | 2039 | ||
| 2049 | *(ptr + len) = '/'; | 2040 | *(ptr + len) = '/'; |
| 2050 | read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len); | 2041 | read_extent_buffer(l, ptr, (unsigned long)(iref + 1), len); |
| 2051 | 2042 | ||
| 2052 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) | 2043 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) |
| 2053 | break; | 2044 | break; |
| @@ -2058,7 +2049,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
| 2058 | dirid = key.objectid; | 2049 | dirid = key.objectid; |
| 2059 | } | 2050 | } |
| 2060 | memmove(name, ptr, total_len); | 2051 | memmove(name, ptr, total_len); |
| 2061 | name[total_len]='\0'; | 2052 | name[total_len] = '\0'; |
| 2062 | ret = 0; | 2053 | ret = 0; |
| 2063 | out: | 2054 | out: |
| 2064 | btrfs_free_path(path); | 2055 | btrfs_free_path(path); |
| @@ -2098,7 +2089,7 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, | |||
| 2098 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, | 2089 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, |
| 2099 | void __user *arg) | 2090 | void __user *arg) |
| 2100 | { | 2091 | { |
| 2101 | struct dentry *parent = fdentry(file); | 2092 | struct dentry *parent = file->f_path.dentry; |
| 2102 | struct dentry *dentry; | 2093 | struct dentry *dentry; |
| 2103 | struct inode *dir = parent->d_inode; | 2094 | struct inode *dir = parent->d_inode; |
| 2104 | struct inode *inode; | 2095 | struct inode *inode; |
| @@ -2144,7 +2135,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
| 2144 | 2135 | ||
| 2145 | inode = dentry->d_inode; | 2136 | inode = dentry->d_inode; |
| 2146 | dest = BTRFS_I(inode)->root; | 2137 | dest = BTRFS_I(inode)->root; |
| 2147 | if (!capable(CAP_SYS_ADMIN)){ | 2138 | if (!capable(CAP_SYS_ADMIN)) { |
| 2148 | /* | 2139 | /* |
| 2149 | * Regular user. Only allow this with a special mount | 2140 | * Regular user. Only allow this with a special mount |
| 2150 | * option, when the user has write+exec access to the | 2141 | * option, when the user has write+exec access to the |
| @@ -2727,15 +2718,10 @@ static long btrfs_ioctl_file_extent_same(struct file *file, | |||
| 2727 | size = sizeof(tmp) + | 2718 | size = sizeof(tmp) + |
| 2728 | tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info); | 2719 | tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info); |
| 2729 | 2720 | ||
| 2730 | same = kmalloc(size, GFP_NOFS); | 2721 | same = memdup_user((struct btrfs_ioctl_same_args __user *)argp, size); |
| 2731 | if (!same) { | ||
| 2732 | ret = -EFAULT; | ||
| 2733 | goto out; | ||
| 2734 | } | ||
| 2735 | 2722 | ||
| 2736 | if (copy_from_user(same, | 2723 | if (IS_ERR(same)) { |
| 2737 | (struct btrfs_ioctl_same_args __user *)argp, size)) { | 2724 | ret = PTR_ERR(same); |
| 2738 | ret = -EFAULT; | ||
| 2739 | goto out; | 2725 | goto out; |
| 2740 | } | 2726 | } |
| 2741 | 2727 | ||
| @@ -3119,7 +3105,7 @@ out: | |||
| 3119 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | 3105 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, |
| 3120 | u64 off, u64 olen, u64 destoff) | 3106 | u64 off, u64 olen, u64 destoff) |
| 3121 | { | 3107 | { |
| 3122 | struct inode *inode = fdentry(file)->d_inode; | 3108 | struct inode *inode = file_inode(file); |
| 3123 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3109 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 3124 | struct fd src_file; | 3110 | struct fd src_file; |
| 3125 | struct inode *src; | 3111 | struct inode *src; |
| @@ -3679,9 +3665,10 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
| 3679 | 3665 | ||
| 3680 | switch (p->cmd) { | 3666 | switch (p->cmd) { |
| 3681 | case BTRFS_IOCTL_DEV_REPLACE_CMD_START: | 3667 | case BTRFS_IOCTL_DEV_REPLACE_CMD_START: |
| 3682 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3668 | if (root->fs_info->sb->s_flags & MS_RDONLY) { |
| 3683 | return -EROFS; | 3669 | ret = -EROFS; |
| 3684 | 3670 | goto out; | |
| 3671 | } | ||
| 3685 | if (atomic_xchg( | 3672 | if (atomic_xchg( |
| 3686 | &root->fs_info->mutually_exclusive_operation_running, | 3673 | &root->fs_info->mutually_exclusive_operation_running, |
| 3687 | 1)) { | 3674 | 1)) { |
| @@ -3707,7 +3694,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
| 3707 | 3694 | ||
| 3708 | if (copy_to_user(arg, p, sizeof(*p))) | 3695 | if (copy_to_user(arg, p, sizeof(*p))) |
| 3709 | ret = -EFAULT; | 3696 | ret = -EFAULT; |
| 3710 | 3697 | out: | |
| 3711 | kfree(p); | 3698 | kfree(p); |
| 3712 | return ret; | 3699 | return ret; |
| 3713 | } | 3700 | } |
| @@ -4317,7 +4304,7 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) | |||
| 4317 | 4304 | ||
| 4318 | static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) | 4305 | static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) |
| 4319 | { | 4306 | { |
| 4320 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 4307 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
| 4321 | 4308 | ||
| 4322 | if (!capable(CAP_SYS_ADMIN)) | 4309 | if (!capable(CAP_SYS_ADMIN)) |
| 4323 | return -EPERM; | 4310 | return -EPERM; |
| @@ -4557,9 +4544,15 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
| 4557 | return btrfs_ioctl_logical_to_ino(root, argp); | 4544 | return btrfs_ioctl_logical_to_ino(root, argp); |
| 4558 | case BTRFS_IOC_SPACE_INFO: | 4545 | case BTRFS_IOC_SPACE_INFO: |
| 4559 | return btrfs_ioctl_space_info(root, argp); | 4546 | return btrfs_ioctl_space_info(root, argp); |
| 4560 | case BTRFS_IOC_SYNC: | 4547 | case BTRFS_IOC_SYNC: { |
| 4561 | btrfs_sync_fs(file->f_dentry->d_sb, 1); | 4548 | int ret; |
| 4562 | return 0; | 4549 | |
| 4550 | ret = btrfs_start_delalloc_roots(root->fs_info, 0); | ||
| 4551 | if (ret) | ||
| 4552 | return ret; | ||
| 4553 | ret = btrfs_sync_fs(file->f_dentry->d_sb, 1); | ||
| 4554 | return ret; | ||
| 4555 | } | ||
| 4563 | case BTRFS_IOC_START_SYNC: | 4556 | case BTRFS_IOC_START_SYNC: |
| 4564 | return btrfs_ioctl_start_sync(root, argp); | 4557 | return btrfs_ioctl_start_sync(root, argp); |
| 4565 | case BTRFS_IOC_WAIT_SYNC: | 4558 | case BTRFS_IOC_WAIT_SYNC: |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index c702cb62f78a..69582d5b69d1 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,11 +629,16 @@ 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 | } |
| 641 | list_splice_tail(&splice, &fs_info->ordered_roots); | ||
| 627 | spin_unlock(&fs_info->ordered_root_lock); | 642 | spin_unlock(&fs_info->ordered_root_lock); |
| 628 | } | 643 | } |
| 629 | 644 | ||
| @@ -734,8 +749,9 @@ void btrfs_start_ordered_extent(struct inode *inode, | |||
| 734 | /* | 749 | /* |
| 735 | * Used to wait on ordered extents across a large range of bytes. | 750 | * Used to wait on ordered extents across a large range of bytes. |
| 736 | */ | 751 | */ |
| 737 | void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | 752 | int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) |
| 738 | { | 753 | { |
| 754 | int ret = 0; | ||
| 739 | u64 end; | 755 | u64 end; |
| 740 | u64 orig_end; | 756 | u64 orig_end; |
| 741 | struct btrfs_ordered_extent *ordered; | 757 | struct btrfs_ordered_extent *ordered; |
| @@ -751,8 +767,9 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
| 751 | /* start IO across the range first to instantiate any delalloc | 767 | /* start IO across the range first to instantiate any delalloc |
| 752 | * extents | 768 | * extents |
| 753 | */ | 769 | */ |
| 754 | filemap_fdatawrite_range(inode->i_mapping, start, orig_end); | 770 | ret = filemap_fdatawrite_range(inode->i_mapping, start, orig_end); |
| 755 | 771 | if (ret) | |
| 772 | return ret; | ||
| 756 | /* | 773 | /* |
| 757 | * So with compression we will find and lock a dirty page and clear the | 774 | * 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 | 775 | * first one as dirty, setup an async extent, and immediately return |
| @@ -768,10 +785,15 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
| 768 | * right and you are wrong. | 785 | * right and you are wrong. |
| 769 | */ | 786 | */ |
| 770 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | 787 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, |
| 771 | &BTRFS_I(inode)->runtime_flags)) | 788 | &BTRFS_I(inode)->runtime_flags)) { |
| 772 | filemap_fdatawrite_range(inode->i_mapping, start, orig_end); | 789 | ret = filemap_fdatawrite_range(inode->i_mapping, start, |
| 773 | 790 | orig_end); | |
| 774 | filemap_fdatawait_range(inode->i_mapping, start, orig_end); | 791 | if (ret) |
| 792 | return ret; | ||
| 793 | } | ||
| 794 | ret = filemap_fdatawait_range(inode->i_mapping, start, orig_end); | ||
| 795 | if (ret) | ||
| 796 | return ret; | ||
| 775 | 797 | ||
| 776 | end = orig_end; | 798 | end = orig_end; |
| 777 | while (1) { | 799 | while (1) { |
| @@ -782,17 +804,20 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
| 782 | btrfs_put_ordered_extent(ordered); | 804 | btrfs_put_ordered_extent(ordered); |
| 783 | break; | 805 | break; |
| 784 | } | 806 | } |
| 785 | if (ordered->file_offset + ordered->len < start) { | 807 | if (ordered->file_offset + ordered->len <= start) { |
| 786 | btrfs_put_ordered_extent(ordered); | 808 | btrfs_put_ordered_extent(ordered); |
| 787 | break; | 809 | break; |
| 788 | } | 810 | } |
| 789 | btrfs_start_ordered_extent(inode, ordered, 1); | 811 | btrfs_start_ordered_extent(inode, ordered, 1); |
| 790 | end = ordered->file_offset; | 812 | end = ordered->file_offset; |
| 813 | if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) | ||
| 814 | ret = -EIO; | ||
| 791 | btrfs_put_ordered_extent(ordered); | 815 | btrfs_put_ordered_extent(ordered); |
| 792 | if (end == 0 || end == start) | 816 | if (ret || end == 0 || end == start) |
| 793 | break; | 817 | break; |
| 794 | end--; | 818 | end--; |
| 795 | } | 819 | } |
| 820 | return ret; | ||
| 796 | } | 821 | } |
| 797 | 822 | ||
| 798 | /* | 823 | /* |
| @@ -1076,7 +1101,7 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, | |||
| 1076 | * if this file hasn't been changed since the last transaction | 1101 | * if this file hasn't been changed since the last transaction |
| 1077 | * commit, we can safely return without doing anything | 1102 | * commit, we can safely return without doing anything |
| 1078 | */ | 1103 | */ |
| 1079 | if (last_mod < root->fs_info->last_trans_committed) | 1104 | if (last_mod <= root->fs_info->last_trans_committed) |
| 1080 | return; | 1105 | return; |
| 1081 | 1106 | ||
| 1082 | spin_lock(&root->fs_info->ordered_root_lock); | 1107 | 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..561e2f16ba3e 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
| @@ -938,8 +938,10 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) | |||
| 938 | BTRFS_DEV_STAT_CORRUPTION_ERRS); | 938 | BTRFS_DEV_STAT_CORRUPTION_ERRS); |
| 939 | } | 939 | } |
| 940 | 940 | ||
| 941 | if (sctx->readonly && !sctx->is_dev_replace) | 941 | if (sctx->readonly) { |
| 942 | goto did_not_correct_error; | 942 | ASSERT(!sctx->is_dev_replace); |
| 943 | goto out; | ||
| 944 | } | ||
| 943 | 945 | ||
| 944 | if (!is_metadata && !have_csum) { | 946 | if (!is_metadata && !have_csum) { |
| 945 | struct scrub_fixup_nodatasum *fixup_nodatasum; | 947 | struct scrub_fixup_nodatasum *fixup_nodatasum; |
| @@ -2717,8 +2719,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
| 2717 | mutex_unlock(&fs_info->scrub_lock); | 2719 | mutex_unlock(&fs_info->scrub_lock); |
| 2718 | wake_up(&fs_info->scrub_pause_wait); | 2720 | wake_up(&fs_info->scrub_pause_wait); |
| 2719 | 2721 | ||
| 2720 | dev_replace->cursor_left = dev_replace->cursor_right; | ||
| 2721 | dev_replace->item_needs_writeback = 1; | ||
| 2722 | btrfs_put_block_group(cache); | 2722 | btrfs_put_block_group(cache); |
| 2723 | if (ret) | 2723 | if (ret) |
| 2724 | break; | 2724 | break; |
| @@ -2732,6 +2732,9 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
| 2732 | break; | 2732 | break; |
| 2733 | } | 2733 | } |
| 2734 | 2734 | ||
| 2735 | dev_replace->cursor_left = dev_replace->cursor_right; | ||
| 2736 | dev_replace->item_needs_writeback = 1; | ||
| 2737 | |||
| 2735 | key.offset = found_key.offset + length; | 2738 | key.offset = found_key.offset + length; |
| 2736 | btrfs_release_path(path); | 2739 | btrfs_release_path(path); |
| 2737 | } | 2740 | } |
| @@ -2783,7 +2786,6 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, | |||
| 2783 | { | 2786 | { |
| 2784 | int ret = 0; | 2787 | int ret = 0; |
| 2785 | 2788 | ||
| 2786 | mutex_lock(&fs_info->scrub_lock); | ||
| 2787 | if (fs_info->scrub_workers_refcnt == 0) { | 2789 | if (fs_info->scrub_workers_refcnt == 0) { |
| 2788 | if (is_dev_replace) | 2790 | if (is_dev_replace) |
| 2789 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1, | 2791 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1, |
| @@ -2813,21 +2815,17 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, | |||
| 2813 | } | 2815 | } |
| 2814 | ++fs_info->scrub_workers_refcnt; | 2816 | ++fs_info->scrub_workers_refcnt; |
| 2815 | out: | 2817 | out: |
| 2816 | mutex_unlock(&fs_info->scrub_lock); | ||
| 2817 | |||
| 2818 | return ret; | 2818 | return ret; |
| 2819 | } | 2819 | } |
| 2820 | 2820 | ||
| 2821 | static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info) | 2821 | static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info) |
| 2822 | { | 2822 | { |
| 2823 | mutex_lock(&fs_info->scrub_lock); | ||
| 2824 | if (--fs_info->scrub_workers_refcnt == 0) { | 2823 | if (--fs_info->scrub_workers_refcnt == 0) { |
| 2825 | btrfs_stop_workers(&fs_info->scrub_workers); | 2824 | btrfs_stop_workers(&fs_info->scrub_workers); |
| 2826 | btrfs_stop_workers(&fs_info->scrub_wr_completion_workers); | 2825 | btrfs_stop_workers(&fs_info->scrub_wr_completion_workers); |
| 2827 | btrfs_stop_workers(&fs_info->scrub_nocow_workers); | 2826 | btrfs_stop_workers(&fs_info->scrub_nocow_workers); |
| 2828 | } | 2827 | } |
| 2829 | WARN_ON(fs_info->scrub_workers_refcnt < 0); | 2828 | WARN_ON(fs_info->scrub_workers_refcnt < 0); |
| 2830 | mutex_unlock(&fs_info->scrub_lock); | ||
| 2831 | } | 2829 | } |
| 2832 | 2830 | ||
| 2833 | int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | 2831 | int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, |
| @@ -2888,23 +2886,18 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
| 2888 | return -EINVAL; | 2886 | return -EINVAL; |
| 2889 | } | 2887 | } |
| 2890 | 2888 | ||
| 2891 | ret = scrub_workers_get(fs_info, is_dev_replace); | ||
| 2892 | if (ret) | ||
| 2893 | return ret; | ||
| 2894 | 2889 | ||
| 2895 | mutex_lock(&fs_info->fs_devices->device_list_mutex); | 2890 | mutex_lock(&fs_info->fs_devices->device_list_mutex); |
| 2896 | dev = btrfs_find_device(fs_info, devid, NULL, NULL); | 2891 | dev = btrfs_find_device(fs_info, devid, NULL, NULL); |
| 2897 | if (!dev || (dev->missing && !is_dev_replace)) { | 2892 | if (!dev || (dev->missing && !is_dev_replace)) { |
| 2898 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2893 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
| 2899 | scrub_workers_put(fs_info); | ||
| 2900 | return -ENODEV; | 2894 | return -ENODEV; |
| 2901 | } | 2895 | } |
| 2902 | mutex_lock(&fs_info->scrub_lock); | ||
| 2903 | 2896 | ||
| 2897 | mutex_lock(&fs_info->scrub_lock); | ||
| 2904 | if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) { | 2898 | if (!dev->in_fs_metadata || dev->is_tgtdev_for_dev_replace) { |
| 2905 | mutex_unlock(&fs_info->scrub_lock); | 2899 | mutex_unlock(&fs_info->scrub_lock); |
| 2906 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2900 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
| 2907 | scrub_workers_put(fs_info); | ||
| 2908 | return -EIO; | 2901 | return -EIO; |
| 2909 | } | 2902 | } |
| 2910 | 2903 | ||
| @@ -2915,10 +2908,17 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
| 2915 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | 2908 | btrfs_dev_replace_unlock(&fs_info->dev_replace); |
| 2916 | mutex_unlock(&fs_info->scrub_lock); | 2909 | mutex_unlock(&fs_info->scrub_lock); |
| 2917 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | 2910 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); |
| 2918 | scrub_workers_put(fs_info); | ||
| 2919 | return -EINPROGRESS; | 2911 | return -EINPROGRESS; |
| 2920 | } | 2912 | } |
| 2921 | btrfs_dev_replace_unlock(&fs_info->dev_replace); | 2913 | btrfs_dev_replace_unlock(&fs_info->dev_replace); |
| 2914 | |||
| 2915 | ret = scrub_workers_get(fs_info, is_dev_replace); | ||
| 2916 | if (ret) { | ||
| 2917 | mutex_unlock(&fs_info->scrub_lock); | ||
| 2918 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
| 2919 | return ret; | ||
| 2920 | } | ||
| 2921 | |||
| 2922 | sctx = scrub_setup_ctx(dev, is_dev_replace); | 2922 | sctx = scrub_setup_ctx(dev, is_dev_replace); |
| 2923 | if (IS_ERR(sctx)) { | 2923 | if (IS_ERR(sctx)) { |
| 2924 | mutex_unlock(&fs_info->scrub_lock); | 2924 | mutex_unlock(&fs_info->scrub_lock); |
| @@ -2931,13 +2931,15 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
| 2931 | 2931 | ||
| 2932 | atomic_inc(&fs_info->scrubs_running); | 2932 | atomic_inc(&fs_info->scrubs_running); |
| 2933 | mutex_unlock(&fs_info->scrub_lock); | 2933 | mutex_unlock(&fs_info->scrub_lock); |
| 2934 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
| 2935 | 2934 | ||
| 2936 | if (!is_dev_replace) { | 2935 | if (!is_dev_replace) { |
| 2937 | down_read(&fs_info->scrub_super_lock); | 2936 | /* |
| 2937 | * by holding device list mutex, we can | ||
| 2938 | * kick off writing super in log tree sync. | ||
| 2939 | */ | ||
| 2938 | ret = scrub_supers(sctx, dev); | 2940 | ret = scrub_supers(sctx, dev); |
| 2939 | up_read(&fs_info->scrub_super_lock); | ||
| 2940 | } | 2941 | } |
| 2942 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
| 2941 | 2943 | ||
| 2942 | if (!ret) | 2944 | if (!ret) |
| 2943 | ret = scrub_enumerate_chunks(sctx, dev, start, end, | 2945 | ret = scrub_enumerate_chunks(sctx, dev, start, end, |
| @@ -2954,10 +2956,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
| 2954 | 2956 | ||
| 2955 | mutex_lock(&fs_info->scrub_lock); | 2957 | mutex_lock(&fs_info->scrub_lock); |
| 2956 | dev->scrub_device = NULL; | 2958 | dev->scrub_device = NULL; |
| 2959 | scrub_workers_put(fs_info); | ||
| 2957 | mutex_unlock(&fs_info->scrub_lock); | 2960 | mutex_unlock(&fs_info->scrub_lock); |
| 2958 | 2961 | ||
| 2959 | scrub_free_ctx(sctx); | 2962 | scrub_free_ctx(sctx); |
| 2960 | scrub_workers_put(fs_info); | ||
| 2961 | 2963 | ||
| 2962 | return ret; | 2964 | return ret; |
| 2963 | } | 2965 | } |
| @@ -2987,16 +2989,6 @@ void btrfs_scrub_continue(struct btrfs_root *root) | |||
| 2987 | wake_up(&fs_info->scrub_pause_wait); | 2989 | wake_up(&fs_info->scrub_pause_wait); |
| 2988 | } | 2990 | } |
| 2989 | 2991 | ||
| 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) | 2992 | int btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) |
| 3001 | { | 2993 | { |
| 3002 | mutex_lock(&fs_info->scrub_lock); | 2994 | 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..c6a872a8a468 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; |
| @@ -1453,7 +1480,7 @@ static void do_async_commit(struct work_struct *work) | |||
| 1453 | * We've got freeze protection passed with the transaction. | 1480 | * We've got freeze protection passed with the transaction. |
| 1454 | * Tell lockdep about it. | 1481 | * Tell lockdep about it. |
| 1455 | */ | 1482 | */ |
| 1456 | if (ac->newtrans->type < TRANS_JOIN_NOLOCK) | 1483 | if (ac->newtrans->type & __TRANS_FREEZABLE) |
| 1457 | rwsem_acquire_read( | 1484 | rwsem_acquire_read( |
| 1458 | &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], | 1485 | &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], |
| 1459 | 0, 1, _THIS_IP_); | 1486 | 0, 1, _THIS_IP_); |
| @@ -1494,7 +1521,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
| 1494 | * Tell lockdep we've released the freeze rwsem, since the | 1521 | * Tell lockdep we've released the freeze rwsem, since the |
| 1495 | * async commit thread will be the one to unlock it. | 1522 | * async commit thread will be the one to unlock it. |
| 1496 | */ | 1523 | */ |
| 1497 | if (trans->type < TRANS_JOIN_NOLOCK) | 1524 | if (ac->newtrans->type & __TRANS_FREEZABLE) |
| 1498 | rwsem_release( | 1525 | rwsem_release( |
| 1499 | &root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], | 1526 | &root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], |
| 1500 | 1, _THIS_IP_); | 1527 | 1, _THIS_IP_); |
| @@ -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..9f7fc51ca334 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, |
| @@ -3693,7 +3697,8 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
| 3693 | ret = btrfs_truncate_inode_items(trans, log, | 3697 | ret = btrfs_truncate_inode_items(trans, log, |
| 3694 | inode, 0, 0); | 3698 | inode, 0, 0); |
| 3695 | } else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING, | 3699 | } else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING, |
| 3696 | &BTRFS_I(inode)->runtime_flags)) { | 3700 | &BTRFS_I(inode)->runtime_flags) || |
| 3701 | inode_only == LOG_INODE_EXISTS) { | ||
| 3697 | if (inode_only == LOG_INODE_ALL) | 3702 | if (inode_only == LOG_INODE_ALL) |
| 3698 | fast_search = true; | 3703 | fast_search = true; |
| 3699 | max_key.type = BTRFS_XATTR_ITEM_KEY; | 3704 | max_key.type = BTRFS_XATTR_ITEM_KEY; |
| @@ -3719,7 +3724,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
| 3719 | 3724 | ||
| 3720 | while (1) { | 3725 | while (1) { |
| 3721 | ins_nr = 0; | 3726 | ins_nr = 0; |
| 3722 | ret = btrfs_search_forward(root, &min_key, &max_key, | 3727 | ret = btrfs_search_forward(root, &min_key, |
| 3723 | path, trans->transid); | 3728 | path, trans->transid); |
| 3724 | if (ret != 0) | 3729 | if (ret != 0) |
| 3725 | break; | 3730 | break; |
| @@ -3769,14 +3774,14 @@ next_slot: | |||
| 3769 | } | 3774 | } |
| 3770 | btrfs_release_path(path); | 3775 | btrfs_release_path(path); |
| 3771 | 3776 | ||
| 3772 | if (min_key.offset < (u64)-1) | 3777 | if (min_key.offset < (u64)-1) { |
| 3773 | min_key.offset++; | 3778 | min_key.offset++; |
| 3774 | else if (min_key.type < (u8)-1) | 3779 | } else if (min_key.type < max_key.type) { |
| 3775 | min_key.type++; | 3780 | min_key.type++; |
| 3776 | else if (min_key.objectid < (u64)-1) | 3781 | min_key.offset = 0; |
| 3777 | min_key.objectid++; | 3782 | } else { |
| 3778 | else | ||
| 3779 | break; | 3783 | break; |
| 3784 | } | ||
| 3780 | } | 3785 | } |
| 3781 | if (ins_nr) { | 3786 | if (ins_nr) { |
| 3782 | ret = copy_items(trans, inode, dst_path, src, ins_start_slot, | 3787 | ret = copy_items(trans, inode, dst_path, src, ins_start_slot, |
| @@ -3797,7 +3802,7 @@ log_extents: | |||
| 3797 | err = ret; | 3802 | err = ret; |
| 3798 | goto out_unlock; | 3803 | goto out_unlock; |
| 3799 | } | 3804 | } |
| 3800 | } else { | 3805 | } else if (inode_only == LOG_INODE_ALL) { |
| 3801 | struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree; | 3806 | struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree; |
| 3802 | struct extent_map *em, *n; | 3807 | struct extent_map *em, *n; |
| 3803 | 3808 | ||
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..92303f42baaa 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; |
| @@ -5388,17 +5394,15 @@ static int bio_size_ok(struct block_device *bdev, struct bio *bio, | |||
| 5388 | { | 5394 | { |
| 5389 | struct bio_vec *prev; | 5395 | struct bio_vec *prev; |
| 5390 | struct request_queue *q = bdev_get_queue(bdev); | 5396 | struct request_queue *q = bdev_get_queue(bdev); |
| 5391 | unsigned short max_sectors = queue_max_sectors(q); | 5397 | unsigned int max_sectors = queue_max_sectors(q); |
| 5392 | struct bvec_merge_data bvm = { | 5398 | struct bvec_merge_data bvm = { |
| 5393 | .bi_bdev = bdev, | 5399 | .bi_bdev = bdev, |
| 5394 | .bi_sector = sector, | 5400 | .bi_sector = sector, |
| 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; |
