]>
Commit | Line | Data |
---|---|---|
e9cea67c GKH |
1 | From ec125cfb7ae2157af3dd45dd8abe823e3e233eec Mon Sep 17 00:00:00 2001 |
2 | From: Robbie Ko <robbieko@synology.com> | |
3 | Date: Fri, 28 Oct 2016 10:48:26 +0800 | |
4 | Subject: Btrfs: fix deadlock caused by fsync when logging directory entries | |
5 | ||
6 | From: Robbie Ko <robbieko@synology.com> | |
7 | ||
8 | commit ec125cfb7ae2157af3dd45dd8abe823e3e233eec upstream. | |
9 | ||
10 | While logging new directory entries, at tree-log.c:log_new_dir_dentries(), | |
11 | after we call btrfs_search_forward() we get a leaf with a read lock on it, | |
12 | and without unlocking that leaf we can end up calling btrfs_iget() to get | |
13 | an inode pointer. The later (btrfs_iget()) can end up doing a read-only | |
14 | search on the same tree again, if the inode is not in memory already, which | |
15 | ends up causing a deadlock if some other task in the meanwhile started a | |
16 | write search on the tree and is attempting to write lock the same leaf | |
17 | that btrfs_search_forward() locked while holding write locks on upper | |
18 | levels of the tree blocking the read search from btrfs_iget(). In this | |
19 | scenario we get a deadlock. | |
20 | ||
21 | So fix this by releasing the search path before calling btrfs_iget() at | |
22 | tree-log.c:log_new_dir_dentries(). | |
23 | ||
24 | Example trace of such deadlock: | |
25 | ||
26 | [ 4077.478852] kworker/u24:10 D ffff88107fc90640 0 14431 2 0x00000000 | |
27 | [ 4077.486752] Workqueue: btrfs-endio-write btrfs_endio_write_helper [btrfs] | |
28 | [ 4077.494346] ffff880ffa56bad0 0000000000000046 0000000000009000 ffff880ffa56bfd8 | |
29 | [ 4077.502629] ffff880ffa56bfd8 ffff881016ce21c0 ffffffffa06ecb26 ffff88101a5d6138 | |
30 | [ 4077.510915] ffff880ebb5173b0 ffff880ffa56baf8 ffff880ebb517410 ffff881016ce21c0 | |
31 | [ 4077.519202] Call Trace: | |
32 | [ 4077.528752] [<ffffffffa06ed5ed>] ? btrfs_tree_lock+0xdd/0x2f0 [btrfs] | |
33 | [ 4077.536049] [<ffffffff81053680>] ? wake_up_atomic_t+0x30/0x30 | |
34 | [ 4077.542574] [<ffffffffa068cc1f>] ? btrfs_search_slot+0x79f/0xb10 [btrfs] | |
35 | [ 4077.550171] [<ffffffffa06a5073>] ? btrfs_lookup_file_extent+0x33/0x40 [btrfs] | |
36 | [ 4077.558252] [<ffffffffa06c600b>] ? __btrfs_drop_extents+0x13b/0xdf0 [btrfs] | |
37 | [ 4077.566140] [<ffffffffa06fc9e2>] ? add_delayed_data_ref+0xe2/0x150 [btrfs] | |
38 | [ 4077.573928] [<ffffffffa06fd629>] ? btrfs_add_delayed_data_ref+0x149/0x1d0 [btrfs] | |
39 | [ 4077.582399] [<ffffffffa06cf3c0>] ? __set_extent_bit+0x4c0/0x5c0 [btrfs] | |
40 | [ 4077.589896] [<ffffffffa06b4a64>] ? insert_reserved_file_extent.constprop.75+0xa4/0x320 [btrfs] | |
41 | [ 4077.599632] [<ffffffffa06b206d>] ? start_transaction+0x8d/0x470 [btrfs] | |
42 | [ 4077.607134] [<ffffffffa06bab57>] ? btrfs_finish_ordered_io+0x2e7/0x600 [btrfs] | |
43 | [ 4077.615329] [<ffffffff8104cbc2>] ? process_one_work+0x142/0x3d0 | |
44 | [ 4077.622043] [<ffffffff8104d729>] ? worker_thread+0x109/0x3b0 | |
45 | [ 4077.628459] [<ffffffff8104d620>] ? manage_workers.isra.26+0x270/0x270 | |
46 | [ 4077.635759] [<ffffffff81052b0f>] ? kthread+0xaf/0xc0 | |
47 | [ 4077.641404] [<ffffffff81052a60>] ? kthread_create_on_node+0x110/0x110 | |
48 | [ 4077.648696] [<ffffffff814a9ac8>] ? ret_from_fork+0x58/0x90 | |
49 | [ 4077.654926] [<ffffffff81052a60>] ? kthread_create_on_node+0x110/0x110 | |
50 | ||
51 | [ 4078.358087] kworker/u24:15 D ffff88107fcd0640 0 14436 2 0x00000000 | |
52 | [ 4078.365981] Workqueue: btrfs-endio-write btrfs_endio_write_helper [btrfs] | |
53 | [ 4078.373574] ffff880ffa57fad0 0000000000000046 0000000000009000 ffff880ffa57ffd8 | |
54 | [ 4078.381864] ffff880ffa57ffd8 ffff88103004d0a0 ffffffffa06ecb26 ffff88101a5d6138 | |
55 | [ 4078.390163] ffff880fbeffc298 ffff880ffa57faf8 ffff880fbeffc2f8 ffff88103004d0a0 | |
56 | [ 4078.398466] Call Trace: | |
57 | [ 4078.408019] [<ffffffffa06ed5ed>] ? btrfs_tree_lock+0xdd/0x2f0 [btrfs] | |
58 | [ 4078.415322] [<ffffffff81053680>] ? wake_up_atomic_t+0x30/0x30 | |
59 | [ 4078.421844] [<ffffffffa068cc1f>] ? btrfs_search_slot+0x79f/0xb10 [btrfs] | |
60 | [ 4078.429438] [<ffffffffa06a5073>] ? btrfs_lookup_file_extent+0x33/0x40 [btrfs] | |
61 | [ 4078.437518] [<ffffffffa06c600b>] ? __btrfs_drop_extents+0x13b/0xdf0 [btrfs] | |
62 | [ 4078.445404] [<ffffffffa06fc9e2>] ? add_delayed_data_ref+0xe2/0x150 [btrfs] | |
63 | [ 4078.453194] [<ffffffffa06fd629>] ? btrfs_add_delayed_data_ref+0x149/0x1d0 [btrfs] | |
64 | [ 4078.461663] [<ffffffffa06cf3c0>] ? __set_extent_bit+0x4c0/0x5c0 [btrfs] | |
65 | [ 4078.469161] [<ffffffffa06b4a64>] ? insert_reserved_file_extent.constprop.75+0xa4/0x320 [btrfs] | |
66 | [ 4078.478893] [<ffffffffa06b206d>] ? start_transaction+0x8d/0x470 [btrfs] | |
67 | [ 4078.486388] [<ffffffffa06bab57>] ? btrfs_finish_ordered_io+0x2e7/0x600 [btrfs] | |
68 | [ 4078.494561] [<ffffffff8104cbc2>] ? process_one_work+0x142/0x3d0 | |
69 | [ 4078.501278] [<ffffffff8104a507>] ? pwq_activate_delayed_work+0x27/0x40 | |
70 | [ 4078.508673] [<ffffffff8104d729>] ? worker_thread+0x109/0x3b0 | |
71 | [ 4078.515098] [<ffffffff8104d620>] ? manage_workers.isra.26+0x270/0x270 | |
72 | [ 4078.522396] [<ffffffff81052b0f>] ? kthread+0xaf/0xc0 | |
73 | [ 4078.528032] [<ffffffff81052a60>] ? kthread_create_on_node+0x110/0x110 | |
74 | [ 4078.535325] [<ffffffff814a9ac8>] ? ret_from_fork+0x58/0x90 | |
75 | [ 4078.541552] [<ffffffff81052a60>] ? kthread_create_on_node+0x110/0x110 | |
76 | ||
77 | [ 4079.355824] user-space-program D ffff88107fd30640 0 32020 1 0x00000000 | |
78 | [ 4079.363716] ffff880eae8eba10 0000000000000086 0000000000009000 ffff880eae8ebfd8 | |
79 | [ 4079.372003] ffff880eae8ebfd8 ffff881016c162c0 ffffffffa06ecb26 ffff88101a5d6138 | |
80 | [ 4079.380294] ffff880fbed4b4c8 ffff880eae8eba38 ffff880fbed4b528 ffff881016c162c0 | |
81 | [ 4079.388586] Call Trace: | |
82 | [ 4079.398134] [<ffffffffa06ed595>] ? btrfs_tree_lock+0x85/0x2f0 [btrfs] | |
83 | [ 4079.405431] [<ffffffff81053680>] ? wake_up_atomic_t+0x30/0x30 | |
84 | [ 4079.411955] [<ffffffffa06876fb>] ? btrfs_lock_root_node+0x2b/0x40 [btrfs] | |
85 | [ 4079.419644] [<ffffffffa068ce83>] ? btrfs_search_slot+0xa03/0xb10 [btrfs] | |
86 | [ 4079.427237] [<ffffffffa06aba52>] ? btrfs_buffer_uptodate+0x52/0x70 [btrfs] | |
87 | [ 4079.435041] [<ffffffffa0689b60>] ? generic_bin_search.constprop.38+0x80/0x190 [btrfs] | |
88 | [ 4079.443897] [<ffffffffa068ea44>] ? btrfs_insert_empty_items+0x74/0xd0 [btrfs] | |
89 | [ 4079.451975] [<ffffffffa072c443>] ? copy_items+0x128/0x850 [btrfs] | |
90 | [ 4079.458890] [<ffffffffa072da10>] ? btrfs_log_inode+0x629/0xbf3 [btrfs] | |
91 | [ 4079.466292] [<ffffffffa06f34a1>] ? btrfs_log_inode_parent+0xc61/0xf30 [btrfs] | |
92 | [ 4079.474373] [<ffffffffa06f45a9>] ? btrfs_log_dentry_safe+0x59/0x80 [btrfs] | |
93 | [ 4079.482161] [<ffffffffa06c298d>] ? btrfs_sync_file+0x20d/0x330 [btrfs] | |
94 | [ 4079.489558] [<ffffffff8112777c>] ? do_fsync+0x4c/0x80 | |
95 | [ 4079.495300] [<ffffffff81127a0a>] ? SyS_fdatasync+0xa/0x10 | |
96 | [ 4079.501422] [<ffffffff814a9b72>] ? system_call_fastpath+0x16/0x1b | |
97 | ||
98 | [ 4079.508334] user-space-program D ffff88107fc30640 0 32021 1 0x00000004 | |
99 | [ 4079.516226] ffff880eae8efbf8 0000000000000086 0000000000009000 ffff880eae8effd8 | |
100 | [ 4079.524513] ffff880eae8effd8 ffff881030279610 ffffffffa06ecb26 ffff88101a5d6138 | |
101 | [ 4079.532802] ffff880ebb671d88 ffff880eae8efc20 ffff880ebb671de8 ffff881030279610 | |
102 | [ 4079.541092] Call Trace: | |
103 | [ 4079.550642] [<ffffffffa06ed595>] ? btrfs_tree_lock+0x85/0x2f0 [btrfs] | |
104 | [ 4079.557941] [<ffffffff81053680>] ? wake_up_atomic_t+0x30/0x30 | |
105 | [ 4079.564463] [<ffffffffa068cc1f>] ? btrfs_search_slot+0x79f/0xb10 [btrfs] | |
106 | [ 4079.572058] [<ffffffffa06bb7d8>] ? btrfs_truncate_inode_items+0x168/0xb90 [btrfs] | |
107 | [ 4079.580526] [<ffffffffa06b04be>] ? join_transaction.isra.15+0x1e/0x3a0 [btrfs] | |
108 | [ 4079.588701] [<ffffffffa06b206d>] ? start_transaction+0x8d/0x470 [btrfs] | |
109 | [ 4079.596196] [<ffffffffa0690ac6>] ? block_rsv_add_bytes+0x16/0x50 [btrfs] | |
110 | [ 4079.603789] [<ffffffffa06bc2e9>] ? btrfs_truncate+0xe9/0x2e0 [btrfs] | |
111 | [ 4079.610994] [<ffffffffa06bd00b>] ? btrfs_setattr+0x30b/0x410 [btrfs] | |
112 | [ 4079.618197] [<ffffffff81117c1c>] ? notify_change+0x1dc/0x680 | |
113 | [ 4079.624625] [<ffffffff8123c8a4>] ? aa_path_perm+0xd4/0x160 | |
114 | [ 4079.630854] [<ffffffff810f4fcb>] ? do_truncate+0x5b/0x90 | |
115 | [ 4079.636889] [<ffffffff810f59fa>] ? do_sys_ftruncate.constprop.15+0x10a/0x160 | |
116 | [ 4079.644869] [<ffffffff8110d87b>] ? SyS_fcntl+0x5b/0x570 | |
117 | [ 4079.650805] [<ffffffff814a9b72>] ? system_call_fastpath+0x16/0x1b | |
118 | ||
119 | [ 4080.410607] user-space-program D ffff88107fc70640 0 32028 12639 0x00000004 | |
120 | [ 4080.418489] ffff880eaeccbbe0 0000000000000086 0000000000009000 ffff880eaeccbfd8 | |
121 | [ 4080.426778] ffff880eaeccbfd8 ffff880f317ef1e0 ffffffffa06ecb26 ffff88101a5d6138 | |
122 | [ 4080.435067] ffff880ef7e93928 ffff880f317ef1e0 ffff880eaeccbc08 ffff880f317ef1e0 | |
123 | [ 4080.443353] Call Trace: | |
124 | [ 4080.452920] [<ffffffffa06ed15d>] ? btrfs_tree_read_lock+0xdd/0x190 [btrfs] | |
125 | [ 4080.460703] [<ffffffff81053680>] ? wake_up_atomic_t+0x30/0x30 | |
126 | [ 4080.467225] [<ffffffffa06876bb>] ? btrfs_read_lock_root_node+0x2b/0x40 [btrfs] | |
127 | [ 4080.475400] [<ffffffffa068cc81>] ? btrfs_search_slot+0x801/0xb10 [btrfs] | |
128 | [ 4080.482994] [<ffffffffa06b2df0>] ? btrfs_clean_one_deleted_snapshot+0xe0/0xe0 [btrfs] | |
129 | [ 4080.491857] [<ffffffffa06a70a6>] ? btrfs_lookup_inode+0x26/0x90 [btrfs] | |
130 | [ 4080.499353] [<ffffffff810ec42f>] ? kmem_cache_alloc+0xaf/0xc0 | |
131 | [ 4080.505879] [<ffffffffa06bd905>] ? btrfs_iget+0xd5/0x5d0 [btrfs] | |
132 | [ 4080.512696] [<ffffffffa06caf04>] ? btrfs_get_token_64+0x104/0x120 [btrfs] | |
133 | [ 4080.520387] [<ffffffffa06f341f>] ? btrfs_log_inode_parent+0xbdf/0xf30 [btrfs] | |
134 | [ 4080.528469] [<ffffffffa06f45a9>] ? btrfs_log_dentry_safe+0x59/0x80 [btrfs] | |
135 | [ 4080.536258] [<ffffffffa06c298d>] ? btrfs_sync_file+0x20d/0x330 [btrfs] | |
136 | [ 4080.543657] [<ffffffff8112777c>] ? do_fsync+0x4c/0x80 | |
137 | [ 4080.549399] [<ffffffff81127a0a>] ? SyS_fdatasync+0xa/0x10 | |
138 | [ 4080.555534] [<ffffffff814a9b72>] ? system_call_fastpath+0x16/0x1b | |
139 | ||
140 | Signed-off-by: Robbie Ko <robbieko@synology.com> | |
141 | Reviewed-by: Filipe Manana <fdmanana@suse.com> | |
142 | Fixes: 2f2ff0ee5e43 (Btrfs: fix metadata inconsistencies after directory fsync) | |
143 | Signed-off-by: Filipe Manana <fdmanana@suse.com> | |
144 | [Modified changelog for clarity and correctness] | |
145 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
146 | ||
147 | --- | |
148 | fs/btrfs/tree-log.c | 4 ++-- | |
149 | 1 file changed, 2 insertions(+), 2 deletions(-) | |
150 | ||
151 | --- a/fs/btrfs/tree-log.c | |
152 | +++ b/fs/btrfs/tree-log.c | |
153 | @@ -5205,6 +5205,7 @@ process_leaf: | |
154 | if (di_key.type == BTRFS_ROOT_ITEM_KEY) | |
155 | continue; | |
156 | ||
157 | + btrfs_release_path(path); | |
158 | di_inode = btrfs_iget(root->fs_info->sb, &di_key, | |
159 | root, NULL); | |
160 | if (IS_ERR(di_inode)) { | |
161 | @@ -5214,13 +5215,12 @@ process_leaf: | |
162 | ||
163 | if (btrfs_inode_in_log(di_inode, trans->transid)) { | |
164 | iput(di_inode); | |
165 | - continue; | |
166 | + break; | |
167 | } | |
168 | ||
169 | ctx->log_new_dentries = false; | |
170 | if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK) | |
171 | log_mode = LOG_INODE_ALL; | |
172 | - btrfs_release_path(path); | |
173 | ret = btrfs_log_inode(trans, root, di_inode, | |
174 | log_mode, 0, LLONG_MAX, ctx); | |
175 | if (!ret && |