Commit 3d00930
committed
deadlock between spa_errlog_lock and dp_config_rwlock
There is a lock order inversion deadlock between `spa_errlog_lock` and
`dp_config_rwlock`:
A thread in `spa_delete_dataset_errlog()` is running from a sync task.
It is holding the `dp_config_rwlock` for writer (see
`dsl_sync_task_sync()`), and waiting for the `spa_errlog_lock`.
A thread in `dsl_pool_config_enter()` is holding the `spa_errlog_lock`
(see `spa_get_errlog_size()`) and waiting for the `dp_config_rwlock` (as
reader).
Note that this was introduced by #12812.
This commit address this by defining the lock ordering to be
dp_config_rwlock first, then spa_errlog_lock / spa_errlist_lock.
spa_get_errlog() and spa_get_errlog_size() can acquire the locks in this
order, and then process_error_block() and get_head_and_birth_txg() can
verify that the dp_config_rwlock is already held.
Additionally, a buffer overrun in `spa_get_errlog()` is corrected. Many
code paths didn't check if `*count` got to zero, instead continuing to
overwrite past the beginning of the userspace buffer at `uaddr`.
Tested by having some errors in the pool (via `zinject -t data
/path/to/file`), one thread running `zpool iostat 0.001`, and another
thread runs `zfs destroy` (in a loop, although it hits the first time).
This reproduces the problem easily without the fix, and works with the
fix.
Closes #14239
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>1 parent 5f73bbb commit 3d00930
File tree
8 files changed
+132
-204
lines changed- cmd
- include/sys
- lib/libzfs
- module/zfs
8 files changed
+132
-204
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6313 | 6313 | | |
6314 | 6314 | | |
6315 | 6315 | | |
6316 | | - | |
| 6316 | + | |
6317 | 6317 | | |
6318 | 6318 | | |
6319 | 6319 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1146 | 1146 | | |
1147 | 1147 | | |
1148 | 1148 | | |
1149 | | - | |
| 1149 | + | |
1150 | 1150 | | |
1151 | 1151 | | |
1152 | 1152 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4133 | 4133 | | |
4134 | 4134 | | |
4135 | 4135 | | |
4136 | | - | |
4137 | | - | |
4138 | | - | |
| 4136 | + | |
| 4137 | + | |
| 4138 | + | |
| 4139 | + | |
| 4140 | + | |
| 4141 | + | |
4139 | 4142 | | |
4140 | 4143 | | |
4141 | | - | |
4142 | | - | |
4143 | | - | |
| 4144 | + | |
| 4145 | + | |
4144 | 4146 | | |
4145 | | - | |
4146 | | - | |
4147 | | - | |
4148 | | - | |
4149 | | - | |
4150 | | - | |
4151 | 4147 | | |
4152 | 4148 | | |
| 4149 | + | |
| 4150 | + | |
| 4151 | + | |
| 4152 | + | |
4153 | 4153 | | |
4154 | 4154 | | |
4155 | | - | |
| 4155 | + | |
4156 | 4156 | | |
4157 | | - | |
4158 | | - | |
4159 | | - | |
4160 | | - | |
4161 | | - | |
4162 | | - | |
| 4157 | + | |
4163 | 4158 | | |
4164 | 4159 | | |
4165 | 4160 | | |
| |||
4177 | 4172 | | |
4178 | 4173 | | |
4179 | 4174 | | |
4180 | | - | |
4181 | | - | |
4182 | | - | |
| 4175 | + | |
| 4176 | + | |
4183 | 4177 | | |
4184 | | - | |
| 4178 | + | |
4185 | 4179 | | |
4186 | 4180 | | |
4187 | 4181 | | |
4188 | 4182 | | |
4189 | 4183 | | |
4190 | 4184 | | |
4191 | | - | |
| 4185 | + | |
4192 | 4186 | | |
4193 | 4187 | | |
4194 | 4188 | | |
| |||
4215 | 4209 | | |
4216 | 4210 | | |
4217 | 4211 | | |
4218 | | - | |
| 4212 | + | |
4219 | 4213 | | |
4220 | 4214 | | |
4221 | 4215 | | |
4222 | | - | |
| 4216 | + | |
4223 | 4217 | | |
4224 | 4218 | | |
4225 | 4219 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
225 | | - | |
226 | 225 | | |
227 | 226 | | |
228 | 227 | | |
| |||
392 | 391 | | |
393 | 392 | | |
394 | 393 | | |
| 394 | + | |
395 | 395 | | |
396 | 396 | | |
397 | 397 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
944 | 944 | | |
945 | 945 | | |
946 | 946 | | |
947 | | - | |
| 947 | + | |
948 | 948 | | |
949 | 949 | | |
950 | | - | |
| 950 | + | |
951 | 951 | | |
952 | 952 | | |
953 | | - | |
| 953 | + | |
954 | 954 | | |
955 | 955 | | |
956 | 956 | | |
| |||
1013 | 1013 | | |
1014 | 1014 | | |
1015 | 1015 | | |
1016 | | - | |
| 1016 | + | |
1017 | 1017 | | |
1018 | 1018 | | |
1019 | 1019 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5543 | 5543 | | |
5544 | 5544 | | |
5545 | 5545 | | |
5546 | | - | |
| 5546 | + | |
5547 | 5547 | | |
5548 | 5548 | | |
5549 | 5549 | | |
| |||
0 commit comments