aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-20 15:04:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-20 15:04:27 -0400
commite5e03ad9e0f04cb3f478b914a3bf9c8f77ee9e94 (patch)
tree92effb8535e6f0f977403b4e534efb68a8febdad
parent132ce5d43adfd9b5da27ad17cc28a01cd2310f0a (diff)
parent02ee654d3a04563c67bfe658a05384548b9bb105 (diff)
Merge tag 'for-4.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "We've accumulated some fixes during the last week, some of them were in the works for a longer time but there are some newer ones too. Most of the fixes have a reproducer and fix user visible problems, also candidates for stable kernels. They IMHO qualify for a late rc, though I did not expect that many" * tag 'for-4.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix crash when trying to resume balance without the resume flag btrfs: Fix delalloc inodes invalidation during transaction abort btrfs: Split btrfs_del_delalloc_inode into 2 functions btrfs: fix reading stale metadata blocks after degraded raid1 mounts btrfs: property: Set incompat flag if lzo/zstd compression is set Btrfs: fix duplicate extents after fsync of file with prealloc extents Btrfs: fix xattr loss after power failure Btrfs: send, fix invalid access to commit roots due to concurrent snapshotting
-rw-r--r--fs/btrfs/ctree.c22
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/disk-io.c26
-rw-r--r--fs/btrfs/inode.c13
-rw-r--r--fs/btrfs/props.c12
-rw-r--r--fs/btrfs/tree-log.c144
-rw-r--r--fs/btrfs/volumes.c9
7 files changed, 180 insertions, 48 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 3fd44835b386..8c68961925b1 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2436,10 +2436,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
2436 if (p->reada != READA_NONE) 2436 if (p->reada != READA_NONE)
2437 reada_for_search(fs_info, p, level, slot, key->objectid); 2437 reada_for_search(fs_info, p, level, slot, key->objectid);
2438 2438
2439 btrfs_release_path(p);
2440
2441 ret = -EAGAIN; 2439 ret = -EAGAIN;
2442 tmp = read_tree_block(fs_info, blocknr, 0, parent_level - 1, 2440 tmp = read_tree_block(fs_info, blocknr, gen, parent_level - 1,
2443 &first_key); 2441 &first_key);
2444 if (!IS_ERR(tmp)) { 2442 if (!IS_ERR(tmp)) {
2445 /* 2443 /*
@@ -2454,6 +2452,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
2454 } else { 2452 } else {
2455 ret = PTR_ERR(tmp); 2453 ret = PTR_ERR(tmp);
2456 } 2454 }
2455
2456 btrfs_release_path(p);
2457 return ret; 2457 return ret;
2458} 2458}
2459 2459
@@ -5414,12 +5414,24 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
5414 down_read(&fs_info->commit_root_sem); 5414 down_read(&fs_info->commit_root_sem);
5415 left_level = btrfs_header_level(left_root->commit_root); 5415 left_level = btrfs_header_level(left_root->commit_root);
5416 left_root_level = left_level; 5416 left_root_level = left_level;
5417 left_path->nodes[left_level] = left_root->commit_root; 5417 left_path->nodes[left_level] =
5418 btrfs_clone_extent_buffer(left_root->commit_root);
5419 if (!left_path->nodes[left_level]) {
5420 up_read(&fs_info->commit_root_sem);
5421 ret = -ENOMEM;
5422 goto out;
5423 }
5418 extent_buffer_get(left_path->nodes[left_level]); 5424 extent_buffer_get(left_path->nodes[left_level]);
5419 5425
5420 right_level = btrfs_header_level(right_root->commit_root); 5426 right_level = btrfs_header_level(right_root->commit_root);
5421 right_root_level = right_level; 5427 right_root_level = right_level;
5422 right_path->nodes[right_level] = right_root->commit_root; 5428 right_path->nodes[right_level] =
5429 btrfs_clone_extent_buffer(right_root->commit_root);
5430 if (!right_path->nodes[right_level]) {
5431 up_read(&fs_info->commit_root_sem);
5432 ret = -ENOMEM;
5433 goto out;
5434 }
5423 extent_buffer_get(right_path->nodes[right_level]); 5435 extent_buffer_get(right_path->nodes[right_level]);
5424 up_read(&fs_info->commit_root_sem); 5436 up_read(&fs_info->commit_root_sem);
5425 5437
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2771cc56a622..0d422c9908b8 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3182,6 +3182,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
3182 u64 *orig_start, u64 *orig_block_len, 3182 u64 *orig_start, u64 *orig_block_len,
3183 u64 *ram_bytes); 3183 u64 *ram_bytes);
3184 3184
3185void __btrfs_del_delalloc_inode(struct btrfs_root *root,
3186 struct btrfs_inode *inode);
3185struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); 3187struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry);
3186int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index); 3188int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index);
3187int btrfs_unlink_inode(struct btrfs_trans_handle *trans, 3189int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 60caa68c3618..c3504b4d281b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3818,6 +3818,7 @@ void close_ctree(struct btrfs_fs_info *fs_info)
3818 set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags); 3818 set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags);
3819 3819
3820 btrfs_free_qgroup_config(fs_info); 3820 btrfs_free_qgroup_config(fs_info);
3821 ASSERT(list_empty(&fs_info->delalloc_roots));
3821 3822
3822 if (percpu_counter_sum(&fs_info->delalloc_bytes)) { 3823 if (percpu_counter_sum(&fs_info->delalloc_bytes)) {
3823 btrfs_info(fs_info, "at unmount delalloc count %lld", 3824 btrfs_info(fs_info, "at unmount delalloc count %lld",
@@ -4125,15 +4126,15 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info)
4125 4126
4126static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) 4127static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info)
4127{ 4128{
4129 /* cleanup FS via transaction */
4130 btrfs_cleanup_transaction(fs_info);
4131
4128 mutex_lock(&fs_info->cleaner_mutex); 4132 mutex_lock(&fs_info->cleaner_mutex);
4129 btrfs_run_delayed_iputs(fs_info); 4133 btrfs_run_delayed_iputs(fs_info);
4130 mutex_unlock(&fs_info->cleaner_mutex); 4134 mutex_unlock(&fs_info->cleaner_mutex);
4131 4135
4132 down_write(&fs_info->cleanup_work_sem); 4136 down_write(&fs_info->cleanup_work_sem);
4133 up_write(&fs_info->cleanup_work_sem); 4137 up_write(&fs_info->cleanup_work_sem);
4134
4135 /* cleanup FS via transaction */
4136 btrfs_cleanup_transaction(fs_info);
4137} 4138}
4138 4139
4139static void btrfs_destroy_ordered_extents(struct btrfs_root *root) 4140static void btrfs_destroy_ordered_extents(struct btrfs_root *root)
@@ -4258,19 +4259,23 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root)
4258 list_splice_init(&root->delalloc_inodes, &splice); 4259 list_splice_init(&root->delalloc_inodes, &splice);
4259 4260
4260 while (!list_empty(&splice)) { 4261 while (!list_empty(&splice)) {
4262 struct inode *inode = NULL;
4261 btrfs_inode = list_first_entry(&splice, struct btrfs_inode, 4263 btrfs_inode = list_first_entry(&splice, struct btrfs_inode,
4262 delalloc_inodes); 4264 delalloc_inodes);
4263 4265 __btrfs_del_delalloc_inode(root, btrfs_inode);
4264 list_del_init(&btrfs_inode->delalloc_inodes);
4265 clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
4266 &btrfs_inode->runtime_flags);
4267 spin_unlock(&root->delalloc_lock); 4266 spin_unlock(&root->delalloc_lock);
4268 4267
4269 btrfs_invalidate_inodes(btrfs_inode->root); 4268 /*
4270 4269 * Make sure we get a live inode and that it'll not disappear
4270 * meanwhile.
4271 */
4272 inode = igrab(&btrfs_inode->vfs_inode);
4273 if (inode) {
4274 invalidate_inode_pages2(inode->i_mapping);
4275 iput(inode);
4276 }
4271 spin_lock(&root->delalloc_lock); 4277 spin_lock(&root->delalloc_lock);
4272 } 4278 }
4273
4274 spin_unlock(&root->delalloc_lock); 4279 spin_unlock(&root->delalloc_lock);
4275} 4280}
4276 4281
@@ -4286,7 +4291,6 @@ static void btrfs_destroy_all_delalloc_inodes(struct btrfs_fs_info *fs_info)
4286 while (!list_empty(&splice)) { 4291 while (!list_empty(&splice)) {
4287 root = list_first_entry(&splice, struct btrfs_root, 4292 root = list_first_entry(&splice, struct btrfs_root,
4288 delalloc_root); 4293 delalloc_root);
4289 list_del_init(&root->delalloc_root);
4290 root = btrfs_grab_fs_root(root); 4294 root = btrfs_grab_fs_root(root);
4291 BUG_ON(!root); 4295 BUG_ON(!root);
4292 spin_unlock(&fs_info->delalloc_root_lock); 4296 spin_unlock(&fs_info->delalloc_root_lock);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d241285a0d2a..8e604e7071f1 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1742,12 +1742,12 @@ static void btrfs_add_delalloc_inodes(struct btrfs_root *root,
1742 spin_unlock(&root->delalloc_lock); 1742 spin_unlock(&root->delalloc_lock);
1743} 1743}
1744 1744
1745static void btrfs_del_delalloc_inode(struct btrfs_root *root, 1745
1746 struct btrfs_inode *inode) 1746void __btrfs_del_delalloc_inode(struct btrfs_root *root,
1747 struct btrfs_inode *inode)
1747{ 1748{
1748 struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb); 1749 struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
1749 1750
1750 spin_lock(&root->delalloc_lock);
1751 if (!list_empty(&inode->delalloc_inodes)) { 1751 if (!list_empty(&inode->delalloc_inodes)) {
1752 list_del_init(&inode->delalloc_inodes); 1752 list_del_init(&inode->delalloc_inodes);
1753 clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, 1753 clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
@@ -1760,6 +1760,13 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root,
1760 spin_unlock(&fs_info->delalloc_root_lock); 1760 spin_unlock(&fs_info->delalloc_root_lock);
1761 } 1761 }
1762 } 1762 }
1763}
1764
1765static void btrfs_del_delalloc_inode(struct btrfs_root *root,
1766 struct btrfs_inode *inode)
1767{
1768 spin_lock(&root->delalloc_lock);
1769 __btrfs_del_delalloc_inode(root, inode);
1763 spin_unlock(&root->delalloc_lock); 1770 spin_unlock(&root->delalloc_lock);
1764} 1771}
1765 1772
diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c
index 53a8c95828e3..dc6140013ae8 100644
--- a/fs/btrfs/props.c
+++ b/fs/btrfs/props.c
@@ -380,6 +380,7 @@ static int prop_compression_apply(struct inode *inode,
380 const char *value, 380 const char *value,
381 size_t len) 381 size_t len)
382{ 382{
383 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
383 int type; 384 int type;
384 385
385 if (len == 0) { 386 if (len == 0) {
@@ -390,14 +391,17 @@ static int prop_compression_apply(struct inode *inode,
390 return 0; 391 return 0;
391 } 392 }
392 393
393 if (!strncmp("lzo", value, 3)) 394 if (!strncmp("lzo", value, 3)) {
394 type = BTRFS_COMPRESS_LZO; 395 type = BTRFS_COMPRESS_LZO;
395 else if (!strncmp("zlib", value, 4)) 396 btrfs_set_fs_incompat(fs_info, COMPRESS_LZO);
397 } else if (!strncmp("zlib", value, 4)) {
396 type = BTRFS_COMPRESS_ZLIB; 398 type = BTRFS_COMPRESS_ZLIB;
397 else if (!strncmp("zstd", value, len)) 399 } else if (!strncmp("zstd", value, len)) {
398 type = BTRFS_COMPRESS_ZSTD; 400 type = BTRFS_COMPRESS_ZSTD;
399 else 401 btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
402 } else {
400 return -EINVAL; 403 return -EINVAL;
404 }
401 405
402 BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; 406 BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
403 BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; 407 BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 43758e30aa7a..8f23a94dab77 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4320,6 +4320,110 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
4320 return ret; 4320 return ret;
4321} 4321}
4322 4322
4323/*
4324 * Log all prealloc extents beyond the inode's i_size to make sure we do not
4325 * lose them after doing a fast fsync and replaying the log. We scan the
4326 * subvolume's root instead of iterating the inode's extent map tree because
4327 * otherwise we can log incorrect extent items based on extent map conversion.
4328 * That can happen due to the fact that extent maps are merged when they
4329 * are not in the extent map tree's list of modified extents.
4330 */
4331static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans,
4332 struct btrfs_inode *inode,
4333 struct btrfs_path *path)
4334{
4335 struct btrfs_root *root = inode->root;
4336 struct btrfs_key key;
4337 const u64 i_size = i_size_read(&inode->vfs_inode);
4338 const u64 ino = btrfs_ino(inode);
4339 struct btrfs_path *dst_path = NULL;
4340 u64 last_extent = (u64)-1;
4341 int ins_nr = 0;
4342 int start_slot;
4343 int ret;
4344
4345 if (!(inode->flags & BTRFS_INODE_PREALLOC))
4346 return 0;
4347
4348 key.objectid = ino;
4349 key.type = BTRFS_EXTENT_DATA_KEY;
4350 key.offset = i_size;
4351 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
4352 if (ret < 0)
4353 goto out;
4354
4355 while (true) {
4356 struct extent_buffer *leaf = path->nodes[0];
4357 int slot = path->slots[0];
4358
4359 if (slot >= btrfs_header_nritems(leaf)) {
4360 if (ins_nr > 0) {
4361 ret = copy_items(trans, inode, dst_path, path,
4362 &last_extent, start_slot,
4363 ins_nr, 1, 0);
4364 if (ret < 0)
4365 goto out;
4366 ins_nr = 0;
4367 }
4368 ret = btrfs_next_leaf(root, path);
4369 if (ret < 0)
4370 goto out;
4371 if (ret > 0) {
4372 ret = 0;
4373 break;
4374 }
4375 continue;
4376 }
4377
4378 btrfs_item_key_to_cpu(leaf, &key, slot);
4379 if (key.objectid > ino)
4380 break;
4381 if (WARN_ON_ONCE(key.objectid < ino) ||
4382 key.type < BTRFS_EXTENT_DATA_KEY ||
4383 key.offset < i_size) {
4384 path->slots[0]++;
4385 continue;
4386 }
4387 if (last_extent == (u64)-1) {
4388 last_extent = key.offset;
4389 /*
4390 * Avoid logging extent items logged in past fsync calls
4391 * and leading to duplicate keys in the log tree.
4392 */
4393 do {
4394 ret = btrfs_truncate_inode_items(trans,
4395 root->log_root,
4396 &inode->vfs_inode,
4397 i_size,
4398 BTRFS_EXTENT_DATA_KEY);
4399 } while (ret == -EAGAIN);
4400 if (ret)
4401 goto out;
4402 }
4403 if (ins_nr == 0)
4404 start_slot = slot;
4405 ins_nr++;
4406 path->slots[0]++;
4407 if (!dst_path) {
4408 dst_path = btrfs_alloc_path();
4409 if (!dst_path) {
4410 ret = -ENOMEM;
4411 goto out;
4412 }
4413 }
4414 }
4415 if (ins_nr > 0) {
4416 ret = copy_items(trans, inode, dst_path, path, &last_extent,
4417 start_slot, ins_nr, 1, 0);
4418 if (ret > 0)
4419 ret = 0;
4420 }
4421out:
4422 btrfs_release_path(path);
4423 btrfs_free_path(dst_path);
4424 return ret;
4425}
4426
4323static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, 4427static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
4324 struct btrfs_root *root, 4428 struct btrfs_root *root,
4325 struct btrfs_inode *inode, 4429 struct btrfs_inode *inode,
@@ -4362,6 +4466,11 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
4362 if (em->generation <= test_gen) 4466 if (em->generation <= test_gen)
4363 continue; 4467 continue;
4364 4468
4469 /* We log prealloc extents beyond eof later. */
4470 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) &&
4471 em->start >= i_size_read(&inode->vfs_inode))
4472 continue;
4473
4365 if (em->start < logged_start) 4474 if (em->start < logged_start)
4366 logged_start = em->start; 4475 logged_start = em->start;
4367 if ((em->start + em->len - 1) > logged_end) 4476 if ((em->start + em->len - 1) > logged_end)
@@ -4374,31 +4483,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
4374 num++; 4483 num++;
4375 } 4484 }
4376 4485
4377 /*
4378 * Add all prealloc extents beyond the inode's i_size to make sure we
4379 * don't lose them after doing a fast fsync and replaying the log.
4380 */
4381 if (inode->flags & BTRFS_INODE_PREALLOC) {
4382 struct rb_node *node;
4383
4384 for (node = rb_last(&tree->map); node; node = rb_prev(node)) {
4385 em = rb_entry(node, struct extent_map, rb_node);
4386 if (em->start < i_size_read(&inode->vfs_inode))
4387 break;
4388 if (!list_empty(&em->list))
4389 continue;
4390 /* Same as above loop. */
4391 if (++num > 32768) {
4392 list_del_init(&tree->modified_extents);
4393 ret = -EFBIG;
4394 goto process;
4395 }
4396 refcount_inc(&em->refs);
4397 set_bit(EXTENT_FLAG_LOGGING, &em->flags);
4398 list_add_tail(&em->list, &extents);
4399 }
4400 }
4401
4402 list_sort(NULL, &extents, extent_cmp); 4486 list_sort(NULL, &extents, extent_cmp);
4403 btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end); 4487 btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end);
4404 /* 4488 /*
@@ -4443,6 +4527,9 @@ process:
4443 up_write(&inode->dio_sem); 4527 up_write(&inode->dio_sem);
4444 4528
4445 btrfs_release_path(path); 4529 btrfs_release_path(path);
4530 if (!ret)
4531 ret = btrfs_log_prealloc_extents(trans, inode, path);
4532
4446 return ret; 4533 return ret;
4447} 4534}
4448 4535
@@ -4827,6 +4914,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
4827 struct extent_map_tree *em_tree = &inode->extent_tree; 4914 struct extent_map_tree *em_tree = &inode->extent_tree;
4828 u64 logged_isize = 0; 4915 u64 logged_isize = 0;
4829 bool need_log_inode_item = true; 4916 bool need_log_inode_item = true;
4917 bool xattrs_logged = false;
4830 4918
4831 path = btrfs_alloc_path(); 4919 path = btrfs_alloc_path();
4832 if (!path) 4920 if (!path)
@@ -5128,6 +5216,7 @@ next_key:
5128 err = btrfs_log_all_xattrs(trans, root, inode, path, dst_path); 5216 err = btrfs_log_all_xattrs(trans, root, inode, path, dst_path);
5129 if (err) 5217 if (err)
5130 goto out_unlock; 5218 goto out_unlock;
5219 xattrs_logged = true;
5131 if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) { 5220 if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) {
5132 btrfs_release_path(path); 5221 btrfs_release_path(path);
5133 btrfs_release_path(dst_path); 5222 btrfs_release_path(dst_path);
@@ -5140,6 +5229,11 @@ log_extents:
5140 btrfs_release_path(dst_path); 5229 btrfs_release_path(dst_path);
5141 if (need_log_inode_item) { 5230 if (need_log_inode_item) {
5142 err = log_inode_item(trans, log, dst_path, inode); 5231 err = log_inode_item(trans, log, dst_path, inode);
5232 if (!err && !xattrs_logged) {
5233 err = btrfs_log_all_xattrs(trans, root, inode, path,
5234 dst_path);
5235 btrfs_release_path(path);
5236 }
5143 if (err) 5237 if (err)
5144 goto out_unlock; 5238 goto out_unlock;
5145 } 5239 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 292266f6ab9c..be3fc701f389 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4052,6 +4052,15 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
4052 return 0; 4052 return 0;
4053 } 4053 }
4054 4054
4055 /*
4056 * A ro->rw remount sequence should continue with the paused balance
4057 * regardless of who pauses it, system or the user as of now, so set
4058 * the resume flag.
4059 */
4060 spin_lock(&fs_info->balance_lock);
4061 fs_info->balance_ctl->flags |= BTRFS_BALANCE_RESUME;
4062 spin_unlock(&fs_info->balance_lock);
4063
4055 tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); 4064 tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance");
4056 return PTR_ERR_OR_ZERO(tsk); 4065 return PTR_ERR_OR_ZERO(tsk);
4057} 4066}