]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
8e7cb430997856a60dead3b82f6d7e805aa01833
[thirdparty/kernel/stable-queue.git] /
1 From foo@baz Sun May 27 16:52:54 CEST 2018
2 From: Qu Wenruo <wqu@suse.com>
3 Date: Tue, 19 Dec 2017 15:44:54 +0800
4 Subject: btrfs: qgroup: Fix root item corruption when multiple same source snapshots are created with quota enabled
5
6 From: Qu Wenruo <wqu@suse.com>
7
8 [ Upstream commit 4d31778aa2fa342f5f92ca4025b293a1729161d1 ]
9
10 When multiple pending snapshots referring to the same source subvolume
11 are executed, enabled quota will cause root item corruption, where root
12 items are using old bytenr (no backref in extent tree).
13
14 This can be triggered by fstests btrfs/152.
15
16 The cause is when source subvolume is still dirty, extra commit
17 (simplied transaction commit) of qgroup_account_snapshot() can skip
18 dirty roots not recorded in current transaction, making root item of
19 source subvolume not updated.
20
21 Fix it by forcing recording source subvolume in current transaction
22 before qgroup sub-transaction commit.
23
24 Reported-by: Justin Maggard <jmaggard@netgear.com>
25 Signed-off-by: Qu Wenruo <wqu@suse.com>
26 Reviewed-by: Filipe Manana <fdmanana@suse.com>
27 Signed-off-by: David Sterba <dsterba@suse.com>
28 Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 ---
31 fs/btrfs/transaction.c | 10 +++++++++-
32 1 file changed, 9 insertions(+), 1 deletion(-)
33
34 --- a/fs/btrfs/transaction.c
35 +++ b/fs/btrfs/transaction.c
36 @@ -319,7 +319,7 @@ static int record_root_in_trans(struct b
37 if ((test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
38 root->last_trans < trans->transid) || force) {
39 WARN_ON(root == fs_info->extent_root);
40 - WARN_ON(root->commit_root != root->node);
41 + WARN_ON(!force && root->commit_root != root->node);
42
43 /*
44 * see below for IN_TRANS_SETUP usage rules
45 @@ -1366,6 +1366,14 @@ static int qgroup_account_snapshot(struc
46 return 0;
47
48 /*
49 + * Ensure dirty @src will be commited. Or, after comming
50 + * commit_fs_roots() and switch_commit_roots(), any dirty but not
51 + * recorded root will never be updated again, causing an outdated root
52 + * item.
53 + */
54 + record_root_in_trans(trans, src, 1);
55 +
56 + /*
57 * We are going to commit transaction, see btrfs_commit_transaction()
58 * comment for reason locking tree_log_mutex
59 */