diff options
Diffstat (limited to 'fs/ubifs/gc.c')
| -rw-r--r-- | fs/ubifs/gc.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index d0f3dac29081..02aba36fe3d4 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
| @@ -334,15 +334,21 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) | |||
| 334 | 334 | ||
| 335 | err = move_nodes(c, sleb); | 335 | err = move_nodes(c, sleb); |
| 336 | if (err) | 336 | if (err) |
| 337 | goto out; | 337 | goto out_inc_seq; |
| 338 | 338 | ||
| 339 | err = gc_sync_wbufs(c); | 339 | err = gc_sync_wbufs(c); |
| 340 | if (err) | 340 | if (err) |
| 341 | goto out; | 341 | goto out_inc_seq; |
| 342 | 342 | ||
| 343 | err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0); | 343 | err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0); |
| 344 | if (err) | 344 | if (err) |
| 345 | goto out; | 345 | goto out_inc_seq; |
| 346 | |||
| 347 | /* Allow for races with TNC */ | ||
| 348 | c->gced_lnum = lnum; | ||
| 349 | smp_wmb(); | ||
| 350 | c->gc_seq += 1; | ||
| 351 | smp_wmb(); | ||
| 346 | 352 | ||
| 347 | if (c->gc_lnum == -1) { | 353 | if (c->gc_lnum == -1) { |
| 348 | c->gc_lnum = lnum; | 354 | c->gc_lnum = lnum; |
| @@ -363,6 +369,14 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) | |||
| 363 | out: | 369 | out: |
| 364 | ubifs_scan_destroy(sleb); | 370 | ubifs_scan_destroy(sleb); |
| 365 | return err; | 371 | return err; |
| 372 | |||
| 373 | out_inc_seq: | ||
| 374 | /* We may have moved at least some nodes so allow for races with TNC */ | ||
| 375 | c->gced_lnum = lnum; | ||
| 376 | smp_wmb(); | ||
| 377 | c->gc_seq += 1; | ||
| 378 | smp_wmb(); | ||
| 379 | goto out; | ||
| 366 | } | 380 | } |
| 367 | 381 | ||
| 368 | /** | 382 | /** |
