diff options
-rw-r--r-- | fs/btrfs/backref.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 4 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 123 | ||||
-rw-r--r-- | fs/btrfs/file.c | 10 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 24 | ||||
-rw-r--r-- | fs/btrfs/qgroup.c | 5 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 62 | ||||
-rw-r--r-- | fs/btrfs/tests/free-space-tests.c | 4 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 32 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 4 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 13 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 2 |
12 files changed, 219 insertions, 66 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 6dcdb2ec9211..d453d62ab0c6 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -355,7 +355,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | |||
355 | 355 | ||
356 | index = srcu_read_lock(&fs_info->subvol_srcu); | 356 | index = srcu_read_lock(&fs_info->subvol_srcu); |
357 | 357 | ||
358 | root = btrfs_read_fs_root_no_name(fs_info, &root_key); | 358 | root = btrfs_get_fs_root(fs_info, &root_key, false); |
359 | if (IS_ERR(root)) { | 359 | if (IS_ERR(root)) { |
360 | srcu_read_unlock(&fs_info->subvol_srcu, index); | 360 | srcu_read_unlock(&fs_info->subvol_srcu, index); |
361 | ret = PTR_ERR(root); | 361 | ret = PTR_ERR(root); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8c58191249cc..35489e7129a7 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -3416,6 +3416,7 @@ int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, | |||
3416 | struct btrfs_block_group_cache *btrfs_lookup_block_group( | 3416 | struct btrfs_block_group_cache *btrfs_lookup_block_group( |
3417 | struct btrfs_fs_info *info, | 3417 | struct btrfs_fs_info *info, |
3418 | u64 bytenr); | 3418 | u64 bytenr); |
3419 | void btrfs_get_block_group(struct btrfs_block_group_cache *cache); | ||
3419 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache); | 3420 | void btrfs_put_block_group(struct btrfs_block_group_cache *cache); |
3420 | int get_block_group_index(struct btrfs_block_group_cache *cache); | 3421 | int get_block_group_index(struct btrfs_block_group_cache *cache); |
3421 | struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, | 3422 | struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, |
@@ -3479,6 +3480,9 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
3479 | struct btrfs_root *root, u64 bytes_used, | 3480 | struct btrfs_root *root, u64 bytes_used, |
3480 | u64 type, u64 chunk_objectid, u64 chunk_offset, | 3481 | u64 type, u64 chunk_objectid, u64 chunk_offset, |
3481 | u64 size); | 3482 | u64 size); |
3483 | struct btrfs_trans_handle *btrfs_start_trans_remove_block_group( | ||
3484 | struct btrfs_fs_info *fs_info, | ||
3485 | const u64 chunk_offset); | ||
3482 | int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | 3486 | int btrfs_remove_block_group(struct btrfs_trans_handle *trans, |
3483 | struct btrfs_root *root, u64 group_start, | 3487 | struct btrfs_root *root, u64 group_start, |
3484 | struct extent_map *em); | 3488 | struct extent_map *em); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index acf3ed11cfb6..4b89680a1923 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -124,7 +124,7 @@ static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) | |||
124 | return (cache->flags & bits) == bits; | 124 | return (cache->flags & bits) == bits; |
125 | } | 125 | } |
126 | 126 | ||
127 | static void btrfs_get_block_group(struct btrfs_block_group_cache *cache) | 127 | void btrfs_get_block_group(struct btrfs_block_group_cache *cache) |
128 | { | 128 | { |
129 | atomic_inc(&cache->count); | 129 | atomic_inc(&cache->count); |
130 | } | 130 | } |
@@ -5915,19 +5915,6 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
5915 | set_extent_dirty(info->pinned_extents, | 5915 | set_extent_dirty(info->pinned_extents, |
5916 | bytenr, bytenr + num_bytes - 1, | 5916 | bytenr, bytenr + num_bytes - 1, |
5917 | GFP_NOFS | __GFP_NOFAIL); | 5917 | GFP_NOFS | __GFP_NOFAIL); |
5918 | /* | ||
5919 | * No longer have used bytes in this block group, queue | ||
5920 | * it for deletion. | ||
5921 | */ | ||
5922 | if (old_val == 0) { | ||
5923 | spin_lock(&info->unused_bgs_lock); | ||
5924 | if (list_empty(&cache->bg_list)) { | ||
5925 | btrfs_get_block_group(cache); | ||
5926 | list_add_tail(&cache->bg_list, | ||
5927 | &info->unused_bgs); | ||
5928 | } | ||
5929 | spin_unlock(&info->unused_bgs_lock); | ||
5930 | } | ||
5931 | } | 5918 | } |
5932 | 5919 | ||
5933 | spin_lock(&trans->transaction->dirty_bgs_lock); | 5920 | spin_lock(&trans->transaction->dirty_bgs_lock); |
@@ -5939,6 +5926,22 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
5939 | } | 5926 | } |
5940 | spin_unlock(&trans->transaction->dirty_bgs_lock); | 5927 | spin_unlock(&trans->transaction->dirty_bgs_lock); |
5941 | 5928 | ||
5929 | /* | ||
5930 | * No longer have used bytes in this block group, queue it for | ||
5931 | * deletion. We do this after adding the block group to the | ||
5932 | * dirty list to avoid races between cleaner kthread and space | ||
5933 | * cache writeout. | ||
5934 | */ | ||
5935 | if (!alloc && old_val == 0) { | ||
5936 | spin_lock(&info->unused_bgs_lock); | ||
5937 | if (list_empty(&cache->bg_list)) { | ||
5938 | btrfs_get_block_group(cache); | ||
5939 | list_add_tail(&cache->bg_list, | ||
5940 | &info->unused_bgs); | ||
5941 | } | ||
5942 | spin_unlock(&info->unused_bgs_lock); | ||
5943 | } | ||
5944 | |||
5942 | btrfs_put_block_group(cache); | 5945 | btrfs_put_block_group(cache); |
5943 | total -= num_bytes; | 5946 | total -= num_bytes; |
5944 | bytenr += num_bytes; | 5947 | bytenr += num_bytes; |
@@ -8105,21 +8108,47 @@ reada: | |||
8105 | } | 8108 | } |
8106 | 8109 | ||
8107 | /* | 8110 | /* |
8108 | * TODO: Modify related function to add related node/leaf to dirty_extent_root, | 8111 | * These may not be seen by the usual inc/dec ref code so we have to |
8109 | * for later qgroup accounting. | 8112 | * add them here. |
8110 | * | ||
8111 | * Current, this function does nothing. | ||
8112 | */ | 8113 | */ |
8114 | static int record_one_subtree_extent(struct btrfs_trans_handle *trans, | ||
8115 | struct btrfs_root *root, u64 bytenr, | ||
8116 | u64 num_bytes) | ||
8117 | { | ||
8118 | struct btrfs_qgroup_extent_record *qrecord; | ||
8119 | struct btrfs_delayed_ref_root *delayed_refs; | ||
8120 | |||
8121 | qrecord = kmalloc(sizeof(*qrecord), GFP_NOFS); | ||
8122 | if (!qrecord) | ||
8123 | return -ENOMEM; | ||
8124 | |||
8125 | qrecord->bytenr = bytenr; | ||
8126 | qrecord->num_bytes = num_bytes; | ||
8127 | qrecord->old_roots = NULL; | ||
8128 | |||
8129 | delayed_refs = &trans->transaction->delayed_refs; | ||
8130 | spin_lock(&delayed_refs->lock); | ||
8131 | if (btrfs_qgroup_insert_dirty_extent(delayed_refs, qrecord)) | ||
8132 | kfree(qrecord); | ||
8133 | spin_unlock(&delayed_refs->lock); | ||
8134 | |||
8135 | return 0; | ||
8136 | } | ||
8137 | |||
8113 | static int account_leaf_items(struct btrfs_trans_handle *trans, | 8138 | static int account_leaf_items(struct btrfs_trans_handle *trans, |
8114 | struct btrfs_root *root, | 8139 | struct btrfs_root *root, |
8115 | struct extent_buffer *eb) | 8140 | struct extent_buffer *eb) |
8116 | { | 8141 | { |
8117 | int nr = btrfs_header_nritems(eb); | 8142 | int nr = btrfs_header_nritems(eb); |
8118 | int i, extent_type; | 8143 | int i, extent_type, ret; |
8119 | struct btrfs_key key; | 8144 | struct btrfs_key key; |
8120 | struct btrfs_file_extent_item *fi; | 8145 | struct btrfs_file_extent_item *fi; |
8121 | u64 bytenr, num_bytes; | 8146 | u64 bytenr, num_bytes; |
8122 | 8147 | ||
8148 | /* We can be called directly from walk_up_proc() */ | ||
8149 | if (!root->fs_info->quota_enabled) | ||
8150 | return 0; | ||
8151 | |||
8123 | for (i = 0; i < nr; i++) { | 8152 | for (i = 0; i < nr; i++) { |
8124 | btrfs_item_key_to_cpu(eb, &key, i); | 8153 | btrfs_item_key_to_cpu(eb, &key, i); |
8125 | 8154 | ||
@@ -8138,6 +8167,10 @@ static int account_leaf_items(struct btrfs_trans_handle *trans, | |||
8138 | continue; | 8167 | continue; |
8139 | 8168 | ||
8140 | num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); | 8169 | num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); |
8170 | |||
8171 | ret = record_one_subtree_extent(trans, root, bytenr, num_bytes); | ||
8172 | if (ret) | ||
8173 | return ret; | ||
8141 | } | 8174 | } |
8142 | return 0; | 8175 | return 0; |
8143 | } | 8176 | } |
@@ -8206,8 +8239,6 @@ static int adjust_slots_upwards(struct btrfs_root *root, | |||
8206 | 8239 | ||
8207 | /* | 8240 | /* |
8208 | * root_eb is the subtree root and is locked before this function is called. | 8241 | * root_eb is the subtree root and is locked before this function is called. |
8209 | * TODO: Modify this function to mark all (including complete shared node) | ||
8210 | * to dirty_extent_root to allow it get accounted in qgroup. | ||
8211 | */ | 8242 | */ |
8212 | static int account_shared_subtree(struct btrfs_trans_handle *trans, | 8243 | static int account_shared_subtree(struct btrfs_trans_handle *trans, |
8213 | struct btrfs_root *root, | 8244 | struct btrfs_root *root, |
@@ -8285,6 +8316,11 @@ walk_down: | |||
8285 | btrfs_tree_read_lock(eb); | 8316 | btrfs_tree_read_lock(eb); |
8286 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | 8317 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); |
8287 | path->locks[level] = BTRFS_READ_LOCK_BLOCKING; | 8318 | path->locks[level] = BTRFS_READ_LOCK_BLOCKING; |
8319 | |||
8320 | ret = record_one_subtree_extent(trans, root, child_bytenr, | ||
8321 | root->nodesize); | ||
8322 | if (ret) | ||
8323 | goto out; | ||
8288 | } | 8324 | } |
8289 | 8325 | ||
8290 | if (level == 0) { | 8326 | if (level == 0) { |
@@ -10256,6 +10292,47 @@ out: | |||
10256 | return ret; | 10292 | return ret; |
10257 | } | 10293 | } |
10258 | 10294 | ||
10295 | struct btrfs_trans_handle * | ||
10296 | btrfs_start_trans_remove_block_group(struct btrfs_fs_info *fs_info, | ||
10297 | const u64 chunk_offset) | ||
10298 | { | ||
10299 | struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree; | ||
10300 | struct extent_map *em; | ||
10301 | struct map_lookup *map; | ||
10302 | unsigned int num_items; | ||
10303 | |||
10304 | read_lock(&em_tree->lock); | ||
10305 | em = lookup_extent_mapping(em_tree, chunk_offset, 1); | ||
10306 | read_unlock(&em_tree->lock); | ||
10307 | ASSERT(em && em->start == chunk_offset); | ||
10308 | |||
10309 | /* | ||
10310 | * We need to reserve 3 + N units from the metadata space info in order | ||
10311 | * to remove a block group (done at btrfs_remove_chunk() and at | ||
10312 | * btrfs_remove_block_group()), which are used for: | ||
10313 | * | ||
10314 | * 1 unit for adding the free space inode's orphan (located in the tree | ||
10315 | * of tree roots). | ||
10316 | * 1 unit for deleting the block group item (located in the extent | ||
10317 | * tree). | ||
10318 | * 1 unit for deleting the free space item (located in tree of tree | ||
10319 | * roots). | ||
10320 | * N units for deleting N device extent items corresponding to each | ||
10321 | * stripe (located in the device tree). | ||
10322 | * | ||
10323 | * In order to remove a block group we also need to reserve units in the | ||
10324 | * system space info in order to update the chunk tree (update one or | ||
10325 | * more device items and remove one chunk item), but this is done at | ||
10326 | * btrfs_remove_chunk() through a call to check_system_chunk(). | ||
10327 | */ | ||
10328 | map = (struct map_lookup *)em->bdev; | ||
10329 | num_items = 3 + map->num_stripes; | ||
10330 | free_extent_map(em); | ||
10331 | |||
10332 | return btrfs_start_transaction_fallback_global_rsv(fs_info->extent_root, | ||
10333 | num_items, 1); | ||
10334 | } | ||
10335 | |||
10259 | /* | 10336 | /* |
10260 | * Process the unused_bgs list and remove any that don't have any allocated | 10337 | * Process the unused_bgs list and remove any that don't have any allocated |
10261 | * space inside of them. | 10338 | * space inside of them. |
@@ -10322,8 +10399,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) | |||
10322 | * Want to do this before we do anything else so we can recover | 10399 | * Want to do this before we do anything else so we can recover |
10323 | * properly if we fail to join the transaction. | 10400 | * properly if we fail to join the transaction. |
10324 | */ | 10401 | */ |
10325 | /* 1 for btrfs_orphan_reserve_metadata() */ | 10402 | trans = btrfs_start_trans_remove_block_group(fs_info, |
10326 | trans = btrfs_start_transaction(root, 1); | 10403 | block_group->key.objectid); |
10327 | if (IS_ERR(trans)) { | 10404 | if (IS_ERR(trans)) { |
10328 | btrfs_dec_block_group_ro(root, block_group); | 10405 | btrfs_dec_block_group_ro(root, block_group); |
10329 | ret = PTR_ERR(trans); | 10406 | ret = PTR_ERR(trans); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 977e715f0bf2..72e73461c064 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1882,8 +1882,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
1882 | struct btrfs_log_ctx ctx; | 1882 | struct btrfs_log_ctx ctx; |
1883 | int ret = 0; | 1883 | int ret = 0; |
1884 | bool full_sync = 0; | 1884 | bool full_sync = 0; |
1885 | const u64 len = end - start + 1; | 1885 | u64 len; |
1886 | 1886 | ||
1887 | /* | ||
1888 | * The range length can be represented by u64, we have to do the typecasts | ||
1889 | * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync() | ||
1890 | */ | ||
1891 | len = (u64)end - (u64)start + 1; | ||
1887 | trace_btrfs_sync_file(file, datasync); | 1892 | trace_btrfs_sync_file(file, datasync); |
1888 | 1893 | ||
1889 | /* | 1894 | /* |
@@ -2071,8 +2076,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2071 | } | 2076 | } |
2072 | } | 2077 | } |
2073 | if (!full_sync) { | 2078 | if (!full_sync) { |
2074 | ret = btrfs_wait_ordered_range(inode, start, | 2079 | ret = btrfs_wait_ordered_range(inode, start, len); |
2075 | end - start + 1); | ||
2076 | if (ret) { | 2080 | if (ret) { |
2077 | btrfs_end_transaction(trans, root); | 2081 | btrfs_end_transaction(trans, root); |
2078 | goto out; | 2082 | goto out; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 994490d5fa64..a70c5790f8f5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4046,9 +4046,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | |||
4046 | */ | 4046 | */ |
4047 | static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir) | 4047 | static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir) |
4048 | { | 4048 | { |
4049 | struct btrfs_trans_handle *trans; | ||
4050 | struct btrfs_root *root = BTRFS_I(dir)->root; | 4049 | struct btrfs_root *root = BTRFS_I(dir)->root; |
4051 | int ret; | ||
4052 | 4050 | ||
4053 | /* | 4051 | /* |
4054 | * 1 for the possible orphan item | 4052 | * 1 for the possible orphan item |
@@ -4057,27 +4055,7 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir) | |||
4057 | * 1 for the inode ref | 4055 | * 1 for the inode ref |
4058 | * 1 for the inode | 4056 | * 1 for the inode |
4059 | */ | 4057 | */ |
4060 | trans = btrfs_start_transaction(root, 5); | 4058 | return btrfs_start_transaction_fallback_global_rsv(root, 5, 5); |
4061 | if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC) | ||
4062 | return trans; | ||
4063 | |||
4064 | if (PTR_ERR(trans) == -ENOSPC) { | ||
4065 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 5); | ||
4066 | |||
4067 | trans = btrfs_start_transaction(root, 0); | ||
4068 | if (IS_ERR(trans)) | ||
4069 | return trans; | ||
4070 | ret = btrfs_cond_migrate_bytes(root->fs_info, | ||
4071 | &root->fs_info->trans_block_rsv, | ||
4072 | num_bytes, 5); | ||
4073 | if (ret) { | ||
4074 | btrfs_end_transaction(trans, root); | ||
4075 | return ERR_PTR(ret); | ||
4076 | } | ||
4077 | trans->block_rsv = &root->fs_info->trans_block_rsv; | ||
4078 | trans->bytes_reserved = num_bytes; | ||
4079 | } | ||
4080 | return trans; | ||
4081 | } | 4059 | } |
4082 | 4060 | ||
4083 | static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | 4061 | static int btrfs_unlink(struct inode *dir, struct dentry *dentry) |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 93e12c18ffd7..5279fdae7142 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -993,9 +993,10 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, | |||
993 | mutex_lock(&fs_info->qgroup_ioctl_lock); | 993 | mutex_lock(&fs_info->qgroup_ioctl_lock); |
994 | if (!fs_info->quota_root) | 994 | if (!fs_info->quota_root) |
995 | goto out; | 995 | goto out; |
996 | spin_lock(&fs_info->qgroup_lock); | ||
997 | fs_info->quota_enabled = 0; | 996 | fs_info->quota_enabled = 0; |
998 | fs_info->pending_quota_state = 0; | 997 | fs_info->pending_quota_state = 0; |
998 | btrfs_qgroup_wait_for_completion(fs_info); | ||
999 | spin_lock(&fs_info->qgroup_lock); | ||
999 | quota_root = fs_info->quota_root; | 1000 | quota_root = fs_info->quota_root; |
1000 | fs_info->quota_root = NULL; | 1001 | fs_info->quota_root = NULL; |
1001 | fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON; | 1002 | fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON; |
@@ -1461,6 +1462,8 @@ struct btrfs_qgroup_extent_record | |||
1461 | struct btrfs_qgroup_extent_record *entry; | 1462 | struct btrfs_qgroup_extent_record *entry; |
1462 | u64 bytenr = record->bytenr; | 1463 | u64 bytenr = record->bytenr; |
1463 | 1464 | ||
1465 | assert_spin_locked(&delayed_refs->lock); | ||
1466 | |||
1464 | while (*p) { | 1467 | while (*p) { |
1465 | parent_node = *p; | 1468 | parent_node = *p; |
1466 | entry = rb_entry(parent_node, struct btrfs_qgroup_extent_record, | 1469 | entry = rb_entry(parent_node, struct btrfs_qgroup_extent_record, |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 2907a77fb1f6..b091d94ceef6 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -3432,7 +3432,9 @@ out: | |||
3432 | static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx, | 3432 | static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx, |
3433 | struct btrfs_device *scrub_dev, | 3433 | struct btrfs_device *scrub_dev, |
3434 | u64 chunk_offset, u64 length, | 3434 | u64 chunk_offset, u64 length, |
3435 | u64 dev_offset, int is_dev_replace) | 3435 | u64 dev_offset, |
3436 | struct btrfs_block_group_cache *cache, | ||
3437 | int is_dev_replace) | ||
3436 | { | 3438 | { |
3437 | struct btrfs_mapping_tree *map_tree = | 3439 | struct btrfs_mapping_tree *map_tree = |
3438 | &sctx->dev_root->fs_info->mapping_tree; | 3440 | &sctx->dev_root->fs_info->mapping_tree; |
@@ -3445,8 +3447,18 @@ static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx, | |||
3445 | em = lookup_extent_mapping(&map_tree->map_tree, chunk_offset, 1); | 3447 | em = lookup_extent_mapping(&map_tree->map_tree, chunk_offset, 1); |
3446 | read_unlock(&map_tree->map_tree.lock); | 3448 | read_unlock(&map_tree->map_tree.lock); |
3447 | 3449 | ||
3448 | if (!em) | 3450 | if (!em) { |
3449 | return -EINVAL; | 3451 | /* |
3452 | * Might have been an unused block group deleted by the cleaner | ||
3453 | * kthread or relocation. | ||
3454 | */ | ||
3455 | spin_lock(&cache->lock); | ||
3456 | if (!cache->removed) | ||
3457 | ret = -EINVAL; | ||
3458 | spin_unlock(&cache->lock); | ||
3459 | |||
3460 | return ret; | ||
3461 | } | ||
3450 | 3462 | ||
3451 | map = (struct map_lookup *)em->bdev; | 3463 | map = (struct map_lookup *)em->bdev; |
3452 | if (em->start != chunk_offset) | 3464 | if (em->start != chunk_offset) |
@@ -3483,6 +3495,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
3483 | u64 length; | 3495 | u64 length; |
3484 | u64 chunk_offset; | 3496 | u64 chunk_offset; |
3485 | int ret = 0; | 3497 | int ret = 0; |
3498 | int ro_set; | ||
3486 | int slot; | 3499 | int slot; |
3487 | struct extent_buffer *l; | 3500 | struct extent_buffer *l; |
3488 | struct btrfs_key key; | 3501 | struct btrfs_key key; |
@@ -3568,7 +3581,21 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
3568 | scrub_pause_on(fs_info); | 3581 | scrub_pause_on(fs_info); |
3569 | ret = btrfs_inc_block_group_ro(root, cache); | 3582 | ret = btrfs_inc_block_group_ro(root, cache); |
3570 | scrub_pause_off(fs_info); | 3583 | scrub_pause_off(fs_info); |
3571 | if (ret) { | 3584 | |
3585 | if (ret == 0) { | ||
3586 | ro_set = 1; | ||
3587 | } else if (ret == -ENOSPC) { | ||
3588 | /* | ||
3589 | * btrfs_inc_block_group_ro return -ENOSPC when it | ||
3590 | * failed in creating new chunk for metadata. | ||
3591 | * It is not a problem for scrub/replace, because | ||
3592 | * metadata are always cowed, and our scrub paused | ||
3593 | * commit_transactions. | ||
3594 | */ | ||
3595 | ro_set = 0; | ||
3596 | } else { | ||
3597 | btrfs_warn(fs_info, "failed setting block group ro, ret=%d\n", | ||
3598 | ret); | ||
3572 | btrfs_put_block_group(cache); | 3599 | btrfs_put_block_group(cache); |
3573 | break; | 3600 | break; |
3574 | } | 3601 | } |
@@ -3577,7 +3604,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
3577 | dev_replace->cursor_left = found_key.offset; | 3604 | dev_replace->cursor_left = found_key.offset; |
3578 | dev_replace->item_needs_writeback = 1; | 3605 | dev_replace->item_needs_writeback = 1; |
3579 | ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length, | 3606 | ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length, |
3580 | found_key.offset, is_dev_replace); | 3607 | found_key.offset, cache, is_dev_replace); |
3581 | 3608 | ||
3582 | /* | 3609 | /* |
3583 | * flush, submit all pending read and write bios, afterwards | 3610 | * flush, submit all pending read and write bios, afterwards |
@@ -3611,7 +3638,30 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
3611 | 3638 | ||
3612 | scrub_pause_off(fs_info); | 3639 | scrub_pause_off(fs_info); |
3613 | 3640 | ||
3614 | btrfs_dec_block_group_ro(root, cache); | 3641 | if (ro_set) |
3642 | btrfs_dec_block_group_ro(root, cache); | ||
3643 | |||
3644 | /* | ||
3645 | * We might have prevented the cleaner kthread from deleting | ||
3646 | * this block group if it was already unused because we raced | ||
3647 | * and set it to RO mode first. So add it back to the unused | ||
3648 | * list, otherwise it might not ever be deleted unless a manual | ||
3649 | * balance is triggered or it becomes used and unused again. | ||
3650 | */ | ||
3651 | spin_lock(&cache->lock); | ||
3652 | if (!cache->removed && !cache->ro && cache->reserved == 0 && | ||
3653 | btrfs_block_group_used(&cache->item) == 0) { | ||
3654 | spin_unlock(&cache->lock); | ||
3655 | spin_lock(&fs_info->unused_bgs_lock); | ||
3656 | if (list_empty(&cache->bg_list)) { | ||
3657 | btrfs_get_block_group(cache); | ||
3658 | list_add_tail(&cache->bg_list, | ||
3659 | &fs_info->unused_bgs); | ||
3660 | } | ||
3661 | spin_unlock(&fs_info->unused_bgs_lock); | ||
3662 | } else { | ||
3663 | spin_unlock(&cache->lock); | ||
3664 | } | ||
3615 | 3665 | ||
3616 | btrfs_put_block_group(cache); | 3666 | btrfs_put_block_group(cache); |
3617 | if (ret) | 3667 | if (ret) |
diff --git a/fs/btrfs/tests/free-space-tests.c b/fs/btrfs/tests/free-space-tests.c index c8c3d70c31ff..8b72b005bfb9 100644 --- a/fs/btrfs/tests/free-space-tests.c +++ b/fs/btrfs/tests/free-space-tests.c | |||
@@ -898,8 +898,10 @@ int btrfs_test_free_space_cache(void) | |||
898 | } | 898 | } |
899 | 899 | ||
900 | root = btrfs_alloc_dummy_root(); | 900 | root = btrfs_alloc_dummy_root(); |
901 | if (!root) | 901 | if (IS_ERR(root)) { |
902 | ret = PTR_ERR(root); | ||
902 | goto out; | 903 | goto out; |
904 | } | ||
903 | 905 | ||
904 | root->fs_info = btrfs_alloc_dummy_fs_info(); | 906 | root->fs_info = btrfs_alloc_dummy_fs_info(); |
905 | if (!root->fs_info) | 907 | if (!root->fs_info) |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 418c6a2ad7d8..3367a3c6f214 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -592,6 +592,38 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | |||
592 | return start_transaction(root, num_items, TRANS_START, | 592 | return start_transaction(root, num_items, TRANS_START, |
593 | BTRFS_RESERVE_FLUSH_ALL); | 593 | BTRFS_RESERVE_FLUSH_ALL); |
594 | } | 594 | } |
595 | struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv( | ||
596 | struct btrfs_root *root, | ||
597 | unsigned int num_items, | ||
598 | int min_factor) | ||
599 | { | ||
600 | struct btrfs_trans_handle *trans; | ||
601 | u64 num_bytes; | ||
602 | int ret; | ||
603 | |||
604 | trans = btrfs_start_transaction(root, num_items); | ||
605 | if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC) | ||
606 | return trans; | ||
607 | |||
608 | trans = btrfs_start_transaction(root, 0); | ||
609 | if (IS_ERR(trans)) | ||
610 | return trans; | ||
611 | |||
612 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); | ||
613 | ret = btrfs_cond_migrate_bytes(root->fs_info, | ||
614 | &root->fs_info->trans_block_rsv, | ||
615 | num_bytes, | ||
616 | min_factor); | ||
617 | if (ret) { | ||
618 | btrfs_end_transaction(trans, root); | ||
619 | return ERR_PTR(ret); | ||
620 | } | ||
621 | |||
622 | trans->block_rsv = &root->fs_info->trans_block_rsv; | ||
623 | trans->bytes_reserved = num_bytes; | ||
624 | |||
625 | return trans; | ||
626 | } | ||
595 | 627 | ||
596 | struct btrfs_trans_handle *btrfs_start_transaction_lflush( | 628 | struct btrfs_trans_handle *btrfs_start_transaction_lflush( |
597 | struct btrfs_root *root, | 629 | struct btrfs_root *root, |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index b05b2f64d913..0da21ca9b3fb 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -185,6 +185,10 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
185 | struct btrfs_root *root); | 185 | struct btrfs_root *root); |
186 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | 186 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, |
187 | unsigned int num_items); | 187 | unsigned int num_items); |
188 | struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv( | ||
189 | struct btrfs_root *root, | ||
190 | unsigned int num_items, | ||
191 | int min_factor); | ||
188 | struct btrfs_trans_handle *btrfs_start_transaction_lflush( | 192 | struct btrfs_trans_handle *btrfs_start_transaction_lflush( |
189 | struct btrfs_root *root, | 193 | struct btrfs_root *root, |
190 | unsigned int num_items); | 194 | unsigned int num_items); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a6df8fdc1312..456452206609 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1973,8 +1973,7 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info, | |||
1973 | if (srcdev->writeable) { | 1973 | if (srcdev->writeable) { |
1974 | fs_devices->rw_devices--; | 1974 | fs_devices->rw_devices--; |
1975 | /* zero out the old super if it is writable */ | 1975 | /* zero out the old super if it is writable */ |
1976 | btrfs_scratch_superblocks(srcdev->bdev, | 1976 | btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str); |
1977 | rcu_str_deref(srcdev->name)); | ||
1978 | } | 1977 | } |
1979 | 1978 | ||
1980 | if (srcdev->bdev) | 1979 | if (srcdev->bdev) |
@@ -2024,8 +2023,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
2024 | btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev); | 2023 | btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev); |
2025 | 2024 | ||
2026 | if (tgtdev->bdev) { | 2025 | if (tgtdev->bdev) { |
2027 | btrfs_scratch_superblocks(tgtdev->bdev, | 2026 | btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str); |
2028 | rcu_str_deref(tgtdev->name)); | ||
2029 | fs_info->fs_devices->open_devices--; | 2027 | fs_info->fs_devices->open_devices--; |
2030 | } | 2028 | } |
2031 | fs_info->fs_devices->num_devices--; | 2029 | fs_info->fs_devices->num_devices--; |
@@ -2853,7 +2851,8 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset) | |||
2853 | if (ret) | 2851 | if (ret) |
2854 | return ret; | 2852 | return ret; |
2855 | 2853 | ||
2856 | trans = btrfs_start_transaction(root, 0); | 2854 | trans = btrfs_start_trans_remove_block_group(root->fs_info, |
2855 | chunk_offset); | ||
2857 | if (IS_ERR(trans)) { | 2856 | if (IS_ERR(trans)) { |
2858 | ret = PTR_ERR(trans); | 2857 | ret = PTR_ERR(trans); |
2859 | btrfs_std_error(root->fs_info, ret, NULL); | 2858 | btrfs_std_error(root->fs_info, ret, NULL); |
@@ -3123,7 +3122,7 @@ static int chunk_profiles_filter(u64 chunk_type, | |||
3123 | return 1; | 3122 | return 1; |
3124 | } | 3123 | } |
3125 | 3124 | ||
3126 | static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset, | 3125 | static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset, |
3127 | struct btrfs_balance_args *bargs) | 3126 | struct btrfs_balance_args *bargs) |
3128 | { | 3127 | { |
3129 | struct btrfs_block_group_cache *cache; | 3128 | struct btrfs_block_group_cache *cache; |
@@ -3156,7 +3155,7 @@ static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset, | |||
3156 | return ret; | 3155 | return ret; |
3157 | } | 3156 | } |
3158 | 3157 | ||
3159 | static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info, | 3158 | static int chunk_usage_filter(struct btrfs_fs_info *fs_info, |
3160 | u64 chunk_offset, struct btrfs_balance_args *bargs) | 3159 | u64 chunk_offset, struct btrfs_balance_args *bargs) |
3161 | { | 3160 | { |
3162 | struct btrfs_block_group_cache *cache; | 3161 | struct btrfs_block_group_cache *cache; |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index ec5712372732..d5c84f6b1353 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -382,7 +382,7 @@ struct map_lookup { | |||
382 | #define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) | 382 | #define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) |
383 | #define BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6) | 383 | #define BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6) |
384 | #define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7) | 384 | #define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7) |
385 | #define BTRFS_BALANCE_ARGS_USAGE_RANGE (1ULL << 8) | 385 | #define BTRFS_BALANCE_ARGS_USAGE_RANGE (1ULL << 10) |
386 | 386 | ||
387 | #define BTRFS_BALANCE_ARGS_MASK \ | 387 | #define BTRFS_BALANCE_ARGS_MASK \ |
388 | (BTRFS_BALANCE_ARGS_PROFILES | \ | 388 | (BTRFS_BALANCE_ARGS_PROFILES | \ |