Skip to content

Commit e5e03ad

Browse files
committed
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
2 parents 132ce5d + 02ee654 commit e5e03ad

File tree

7 files changed

+180
-48
lines changed

7 files changed

+180
-48
lines changed

fs/btrfs/ctree.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,10 +2436,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
24362436
if (p->reada != READA_NONE)
24372437
reada_for_search(fs_info, p, level, slot, key->objectid);
24382438

2439-
btrfs_release_path(p);
2440-
24412439
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,
24432441
&first_key);
24442442
if (!IS_ERR(tmp)) {
24452443
/*
@@ -2454,6 +2452,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
24542452
} else {
24552453
ret = PTR_ERR(tmp);
24562454
}
2455+
2456+
btrfs_release_path(p);
24572457
return ret;
24582458
}
24592459

@@ -5414,12 +5414,24 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
54145414
down_read(&fs_info->commit_root_sem);
54155415
left_level = btrfs_header_level(left_root->commit_root);
54165416
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+
}
54185424
extent_buffer_get(left_path->nodes[left_level]);
54195425

54205426
right_level = btrfs_header_level(right_root->commit_root);
54215427
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+
}
54235435
extent_buffer_get(right_path->nodes[right_level]);
54245436
up_read(&fs_info->commit_root_sem);
54255437

fs/btrfs/ctree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3182,6 +3182,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
31823182
u64 *orig_start, u64 *orig_block_len,
31833183
u64 *ram_bytes);
31843184

3185+
void __btrfs_del_delalloc_inode(struct btrfs_root *root,
3186+
struct btrfs_inode *inode);
31853187
struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry);
31863188
int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index);
31873189
int btrfs_unlink_inode(struct btrfs_trans_handle *trans,

fs/btrfs/disk-io.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,7 @@ void close_ctree(struct btrfs_fs_info *fs_info)
38183818
set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags);
38193819

38203820
btrfs_free_qgroup_config(fs_info);
3821+
ASSERT(list_empty(&fs_info->delalloc_roots));
38213822

38223823
if (percpu_counter_sum(&fs_info->delalloc_bytes)) {
38233824
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)
41254126

41264127
static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info)
41274128
{
4129+
/* cleanup FS via transaction */
4130+
btrfs_cleanup_transaction(fs_info);
4131+
41284132
mutex_lock(&fs_info->cleaner_mutex);
41294133
btrfs_run_delayed_iputs(fs_info);
41304134
mutex_unlock(&fs_info->cleaner_mutex);
41314135

41324136
down_write(&fs_info->cleanup_work_sem);
41334137
up_write(&fs_info->cleanup_work_sem);
4134-
4135-
/* cleanup FS via transaction */
4136-
btrfs_cleanup_transaction(fs_info);
41374138
}
41384139

41394140
static void btrfs_destroy_ordered_extents(struct btrfs_root *root)
@@ -4258,19 +4259,23 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root)
42584259
list_splice_init(&root->delalloc_inodes, &splice);
42594260

42604261
while (!list_empty(&splice)) {
4262+
struct inode *inode = NULL;
42614263
btrfs_inode = list_first_entry(&splice, struct btrfs_inode,
42624264
delalloc_inodes);
4263-
4264-
list_del_init(&btrfs_inode->delalloc_inodes);
4265-
clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
4266-
&btrfs_inode->runtime_flags);
4265+
__btrfs_del_delalloc_inode(root, btrfs_inode);
42674266
spin_unlock(&root->delalloc_lock);
42684267

4269-
btrfs_invalidate_inodes(btrfs_inode->root);
4270-
4268+
/*
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+
}
42714277
spin_lock(&root->delalloc_lock);
42724278
}
4273-
42744279
spin_unlock(&root->delalloc_lock);
42754280
}
42764281

@@ -4286,7 +4291,6 @@ static void btrfs_destroy_all_delalloc_inodes(struct btrfs_fs_info *fs_info)
42864291
while (!list_empty(&splice)) {
42874292
root = list_first_entry(&splice, struct btrfs_root,
42884293
delalloc_root);
4289-
list_del_init(&root->delalloc_root);
42904294
root = btrfs_grab_fs_root(root);
42914295
BUG_ON(!root);
42924296
spin_unlock(&fs_info->delalloc_root_lock);

fs/btrfs/inode.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,12 +1742,12 @@ static void btrfs_add_delalloc_inodes(struct btrfs_root *root,
17421742
spin_unlock(&root->delalloc_lock);
17431743
}
17441744

1745-
static void btrfs_del_delalloc_inode(struct btrfs_root *root,
1746-
struct btrfs_inode *inode)
1745+
1746+
void __btrfs_del_delalloc_inode(struct btrfs_root *root,
1747+
struct btrfs_inode *inode)
17471748
{
17481749
struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
17491750

1750-
spin_lock(&root->delalloc_lock);
17511751
if (!list_empty(&inode->delalloc_inodes)) {
17521752
list_del_init(&inode->delalloc_inodes);
17531753
clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
@@ -1760,6 +1760,13 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root,
17601760
spin_unlock(&fs_info->delalloc_root_lock);
17611761
}
17621762
}
1763+
}
1764+
1765+
static 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);
17631770
spin_unlock(&root->delalloc_lock);
17641771
}
17651772

fs/btrfs/props.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ static int prop_compression_apply(struct inode *inode,
380380
const char *value,
381381
size_t len)
382382
{
383+
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
383384
int type;
384385

385386
if (len == 0) {
@@ -390,14 +391,17 @@ static int prop_compression_apply(struct inode *inode,
390391
return 0;
391392
}
392393

393-
if (!strncmp("lzo", value, 3))
394+
if (!strncmp("lzo", value, 3)) {
394395
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)) {
396398
type = BTRFS_COMPRESS_ZLIB;
397-
else if (!strncmp("zstd", value, len))
399+
} else if (!strncmp("zstd", value, len)) {
398400
type = BTRFS_COMPRESS_ZSTD;
399-
else
401+
btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
402+
} else {
400403
return -EINVAL;
404+
}
401405

402406
BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
403407
BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS;

fs/btrfs/tree-log.c

Lines changed: 119 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4320,6 +4320,110 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
43204320
return ret;
43214321
}
43224322

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+
*/
4331+
static 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+
}
4421+
out:
4422+
btrfs_release_path(path);
4423+
btrfs_free_path(dst_path);
4424+
return ret;
4425+
}
4426+
43234427
static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
43244428
struct btrfs_root *root,
43254429
struct btrfs_inode *inode,
@@ -4362,6 +4466,11 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
43624466
if (em->generation <= test_gen)
43634467
continue;
43644468

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+
43654474
if (em->start < logged_start)
43664475
logged_start = em->start;
43674476
if ((em->start + em->len - 1) > logged_end)
@@ -4374,31 +4483,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
43744483
num++;
43754484
}
43764485

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-
44024486
list_sort(NULL, &extents, extent_cmp);
44034487
btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end);
44044488
/*
@@ -4443,6 +4527,9 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
44434527
up_write(&inode->dio_sem);
44444528

44454529
btrfs_release_path(path);
4530+
if (!ret)
4531+
ret = btrfs_log_prealloc_extents(trans, inode, path);
4532+
44464533
return ret;
44474534
}
44484535

@@ -4827,6 +4914,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
48274914
struct extent_map_tree *em_tree = &inode->extent_tree;
48284915
u64 logged_isize = 0;
48294916
bool need_log_inode_item = true;
4917+
bool xattrs_logged = false;
48304918

48314919
path = btrfs_alloc_path();
48324920
if (!path)
@@ -5128,6 +5216,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
51285216
err = btrfs_log_all_xattrs(trans, root, inode, path, dst_path);
51295217
if (err)
51305218
goto out_unlock;
5219+
xattrs_logged = true;
51315220
if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) {
51325221
btrfs_release_path(path);
51335222
btrfs_release_path(dst_path);
@@ -5140,6 +5229,11 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
51405229
btrfs_release_path(dst_path);
51415230
if (need_log_inode_item) {
51425231
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+
}
51435237
if (err)
51445238
goto out_unlock;
51455239
}

fs/btrfs/volumes.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4052,6 +4052,15 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
40524052
return 0;
40534053
}
40544054

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+
40554064
tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance");
40564065
return PTR_ERR_OR_ZERO(tsk);
40574066
}

0 commit comments

Comments
 (0)