diff options
-rw-r--r-- | fs/bcachefs/journal_reclaim.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/migrate.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/replicas.c | 27 |
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) |