aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/gc.c
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2008-09-12 05:27:47 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-09-17 07:23:26 -0400
commit6dcfac4f13d6b32fbaa60b64a23249999e66af8e (patch)
tree007884a8327658dc53252c7f1be9ab9daeb7ea14 /fs/ubifs/gc.c
parent0855f310dff76ae42c5aac32f600f8f692bbd23f (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/gc.c')
-rw-r--r--fs/ubifs/gc.c14
1 files changed, 11 insertions, 3 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)
369out: 369out:
370 ubifs_scan_destroy(sleb); 370 ubifs_scan_destroy(sleb);
371 return err; 371 return err;
372
373out_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/**