diff options
author | Adrian Hunter <ext-adrian.hunter@nokia.com> | 2008-09-12 05:27:47 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-09-17 07:23:26 -0400 |
commit | 6dcfac4f13d6b32fbaa60b64a23249999e66af8e (patch) | |
tree | 007884a8327658dc53252c7f1be9ab9daeb7ea14 /fs/ubifs | |
parent | 0855f310dff76ae42c5aac32f600f8f692bbd23f (diff) |
UBIFS: TNC / GC race fixes
- update GC sequence number if any nodes may have been moved
even if GC did not finish the LEB
- don't ignore error return when reading
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/gc.c | 14 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 2 |
2 files changed, 12 insertions, 4 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 13f1019c859f..02aba36fe3d4 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
@@ -334,15 +334,15 @@ 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 | 346 | ||
347 | /* Allow for races with TNC */ | 347 | /* Allow for races with TNC */ |
348 | c->gced_lnum = lnum; | 348 | c->gced_lnum = lnum; |
@@ -369,6 +369,14 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) | |||
369 | out: | 369 | out: |
370 | ubifs_scan_destroy(sleb); | 370 | ubifs_scan_destroy(sleb); |
371 | 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; | ||
372 | } | 380 | } |
373 | 381 | ||
374 | /** | 382 | /** |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 7da209ab9378..7634c5970887 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -1476,7 +1476,7 @@ again: | |||
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | err = fallible_read_node(c, key, &zbr, node); | 1478 | err = fallible_read_node(c, key, &zbr, node); |
1479 | if (maybe_leb_gced(c, zbr.lnum, gc_seq1)) { | 1479 | if (err <= 0 || maybe_leb_gced(c, zbr.lnum, gc_seq1)) { |
1480 | /* | 1480 | /* |
1481 | * The node may have been GC'ed out from under us so try again | 1481 | * The node may have been GC'ed out from under us so try again |
1482 | * while keeping the TNC mutex locked. | 1482 | * while keeping the TNC mutex locked. |