Commit 986bf6e
btrfs: avoid load/store tearing races when checking if an inode was logged
At inode_logged() we do a couple lockless checks for ->logged_trans, and
these are generally safe except the second one in case we get a load or
store tearing due to a concurrent call updating ->logged_trans (either at
btrfs_log_inode() or later at inode_logged()).
In the first case it's safe to compare to the current transaction ID since
once ->logged_trans is set the current transaction, we never set it to a
lower value.
In the second case, where we check if it's greater than zero, we are prone
to load/store tearing races, since we can have a concurrent task updating
to the current transaction ID with store tearing for example, instead of
updating with a single 64 bits write, to update with two 32 bits writes or
four 16 bits writes. In that case the reading side at inode_logged() could
see a positive value that does not match the current transaction and then
return a false negative.
Fix this by doing the second check while holding the inode's spinlock, add
some comments about it too. Also add the data_race() annotation to the
first check to avoid any reports from KCSAN (or similar tools) and comment
about it.
Fixes: 0f8ce49 ("btrfs: avoid inode logging during rename and link when possible")
Reviewed-by: Boris Burkov <[email protected]>
Signed-off-by: Filipe Manana <[email protected]>
Signed-off-by: David Sterba <[email protected]>1 parent 59a0dd4 commit 986bf6e
1 file changed
+21
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3382 | 3382 | | |
3383 | 3383 | | |
3384 | 3384 | | |
3385 | | - | |
| 3385 | + | |
| 3386 | + | |
| 3387 | + | |
| 3388 | + | |
| 3389 | + | |
3386 | 3390 | | |
3387 | 3391 | | |
3388 | 3392 | | |
3389 | | - | |
3390 | | - | |
| 3393 | + | |
| 3394 | + | |
| 3395 | + | |
| 3396 | + | |
| 3397 | + | |
| 3398 | + | |
| 3399 | + | |
| 3400 | + | |
3391 | 3401 | | |
3392 | | - | |
| 3402 | + | |
| 3403 | + | |
| 3404 | + | |
| 3405 | + | |
| 3406 | + | |
| 3407 | + | |
3393 | 3408 | | |
| 3409 | + | |
| 3410 | + | |
3394 | 3411 | | |
3395 | 3412 | | |
3396 | 3413 | | |
| |||
0 commit comments