summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-06-27 11:51:17 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-06-27 11:51:17 -0400
commit572fa15cf07ebb440cad9dab57f801ddd0bf035c (patch)
tree8fb742aa6adeecf0cd3ee36a284257d07f385530
parent0eb4ad1d972af77b94073f328c85f958b53e3fdb (diff)
bcachefs: Fix a minor memory leak
-rw-r--r--fs/bcachefs/journal_reclaim.c2
-rw-r--r--fs/bcachefs/migrate.c2
-rw-r--r--fs/bcachefs/replicas.c27
3 files changed, 15 insertions, 16 deletions
diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c
index 4cabfb7c9646..394b72bb5518 100644
--- a/fs/bcachefs/journal_reclaim.c
+++ b/fs/bcachefs/journal_reclaim.c
@@ -394,7 +394,7 @@ int bch2_journal_flush_device_pins(struct journal *j, int dev_idx)
}
spin_unlock(&j->lock);
- bch2_replicas_gc_end(c, ret);
+ ret = bch2_replicas_gc_end(c, ret);
mutex_unlock(&c->replicas_gc_lock);
return ret;
diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c
index ea519102a228..a0a4c6891f41 100644
--- a/fs/bcachefs/migrate.c
+++ b/fs/bcachefs/migrate.c
@@ -160,7 +160,7 @@ retry:
ret = 0;
out:
- bch2_replicas_gc_end(c, ret);
+ ret = bch2_replicas_gc_end(c, ret);
mutex_unlock(&c->replicas_gc_lock);
return ret;
diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c
index 6c52d1d456c5..1e94d35fde96 100644
--- a/fs/bcachefs/replicas.c
+++ b/fs/bcachefs/replicas.c
@@ -215,10 +215,8 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c,
return 0;
err:
mutex_unlock(&c->sb_lock);
- if (new_gc)
- kfree(new_gc);
- if (new_r)
- kfree(new_r);
+ kfree(new_gc);
+ kfree(new_r);
return ret;
}
@@ -265,10 +263,9 @@ int bch2_mark_bkey_replicas(struct bch_fs *c,
return bch2_mark_replicas(c, data_type, bch2_bkey_dirty_devs(k));
}
-int bch2_replicas_gc_end(struct bch_fs *c, int err)
+int bch2_replicas_gc_end(struct bch_fs *c, int ret)
{
struct bch_replicas_cpu *new_r, *old_r;
- int ret = 0;
lockdep_assert_held(&c->replicas_gc_lock);
@@ -276,29 +273,31 @@ int bch2_replicas_gc_end(struct bch_fs *c, int err)
new_r = rcu_dereference_protected(c->replicas_gc,
lockdep_is_held(&c->sb_lock));
+ rcu_assign_pointer(c->replicas_gc, NULL);
- if (err) {
- rcu_assign_pointer(c->replicas_gc, NULL);
- kfree_rcu(new_r, rcu);
+ if (ret)
goto err;
- }
if (bch2_cpu_replicas_to_sb_replicas(c, new_r)) {
ret = -ENOSPC;
goto err;
}
+ bch2_write_super(c);
+
+ /* don't update in memory replicas until changes are persistent */
+
old_r = rcu_dereference_protected(c->replicas,
lockdep_is_held(&c->sb_lock));
rcu_assign_pointer(c->replicas, new_r);
- rcu_assign_pointer(c->replicas_gc, NULL);
kfree_rcu(old_r, rcu);
-
- bch2_write_super(c);
-err:
+out:
mutex_unlock(&c->sb_lock);
return ret;
+err:
+ kfree_rcu(new_r, rcu);
+ goto out;
}
int bch2_replicas_gc_start(struct bch_fs *c, unsigned typemask)