diff options
| author | Adrian Hunter <ext-adrian.hunter@nokia.com> | 2008-09-12 12:27:47 +0300 | 
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2008-09-17 14:23:26 +0300 | 
| commit | 6dcfac4f13d6b32fbaa60b64a23249999e66af8e (patch) | |
| tree | 007884a8327658dc53252c7f1be9ab9daeb7ea14 | |
| 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>
| -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)  		err = move_nodes(c, sleb);  		if (err) -			goto out; +			goto out_inc_seq;  		err = gc_sync_wbufs(c);  		if (err) -			goto out; +			goto out_inc_seq;  		err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0);  		if (err) -			goto out; +			goto out_inc_seq;  		/* Allow for races with TNC */  		c->gced_lnum = lnum; @@ -369,6 +369,14 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)  out:  	ubifs_scan_destroy(sleb);  	return err; + +out_inc_seq: +	/* We may have moved at least some nodes so allow for races with TNC */ +	c->gced_lnum = lnum; +	smp_wmb(); +	c->gc_seq += 1; +	smp_wmb(); +	goto out;  }  /** 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:  	}  	err = fallible_read_node(c, key, &zbr, node); -	if (maybe_leb_gced(c, zbr.lnum, gc_seq1)) { +	if (err <= 0 || maybe_leb_gced(c, zbr.lnum, gc_seq1)) {  		/*  		 * The node may have been GC'ed out from under us so try again  		 * while keeping the TNC mutex locked. | 
