Commit ef07b74
btrfs: fix race between logging inode and checking if it was logged before
There's a race between checking if an inode was logged before and logging
an inode that can cause us to mark an inode as not logged just after it
was logged by a concurrent task:
1) We have inode X which was not logged before neither in the current
transaction not in past transaction since the inode was loaded into
memory, so it's ->logged_trans value is 0;
2) We are at transaction N;
3) Task A calls inode_logged() against inode X, sees that ->logged_trans
is 0 and there is a log tree and so it proceeds to search in the log
tree for an inode item for inode X. It doesn't see any, but before
it sets ->logged_trans to N - 1...
3) Task B calls btrfs_log_inode() against inode X, logs the inode and
sets ->logged_trans to N;
4) Task A now sets ->logged_trans to N - 1;
5) At this point anyone calling inode_logged() gets 0 (inode not logged)
since ->logged_trans is greater than 0 and less than N, but our inode
was really logged. As a consequence operations like rename, unlink and
link that happen afterwards in the current transaction end up not
updating the log when they should.
Fix this by ensuring inode_logged() only updates ->logged_trans in case
the inode item is not found in the log tree if after tacking the inode's
lock (spinlock struct btrfs_inode::lock) the ->logged_trans value is still
zero, since the inode lock is what protects setting ->logged_trans at
btrfs_log_inode().
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 5bb0087 commit ef07b74
1 file changed
+30
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3340 | 3340 | | |
3341 | 3341 | | |
3342 | 3342 | | |
| 3343 | + | |
| 3344 | + | |
| 3345 | + | |
| 3346 | + | |
| 3347 | + | |
| 3348 | + | |
| 3349 | + | |
| 3350 | + | |
| 3351 | + | |
| 3352 | + | |
| 3353 | + | |
| 3354 | + | |
| 3355 | + | |
| 3356 | + | |
| 3357 | + | |
| 3358 | + | |
| 3359 | + | |
| 3360 | + | |
| 3361 | + | |
| 3362 | + | |
| 3363 | + | |
| 3364 | + | |
| 3365 | + | |
| 3366 | + | |
| 3367 | + | |
3343 | 3368 | | |
3344 | 3369 | | |
3345 | 3370 | | |
| |||
3374 | 3399 | | |
3375 | 3400 | | |
3376 | 3401 | | |
3377 | | - | |
3378 | | - | |
3379 | | - | |
3380 | | - | |
| 3402 | + | |
| 3403 | + | |
3381 | 3404 | | |
3382 | 3405 | | |
3383 | 3406 | | |
| |||
3431 | 3454 | | |
3432 | 3455 | | |
3433 | 3456 | | |
3434 | | - | |
3435 | | - | |
| 3457 | + | |
3436 | 3458 | | |
3437 | 3459 | | |
3438 | 3460 | | |
3439 | 3461 | | |
3440 | 3462 | | |
3441 | 3463 | | |
3442 | 3464 | | |
| 3465 | + | |
3443 | 3466 | | |
| 3467 | + | |
3444 | 3468 | | |
3445 | 3469 | | |
3446 | 3470 | | |
| |||
0 commit comments