Skip to content

Commit 8cc0e50

Browse files
author
Kent Overstreet
committed
bcachefs: Fix "trying to move an extent, but nr_replicas=0"
data_update_init() does a bunch of complicated stuff to decide how many replicas to add, since we only want to increase an extent's durability on an explicit rereplicate, but extent pointers may be on devices with different durability settings. There was a corner case when evacuating a device that had been set to durability=0 after data had been written to it, and extents on that device had already been rereplicated - then evacuate only needs to drop pointers on that device, not move them. So the assert for !m->op.nr_replicas was spurious; this was a perfectly legitimate case that needed to be handled. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 3f53d05 commit 8cc0e50

File tree

1 file changed

+12
-17
lines changed

1 file changed

+12
-17
lines changed

fs/bcachefs/data_update.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -695,16 +695,6 @@ int bch2_data_update_init(struct btree_trans *trans,
695695
* Increasing replication is an explicit operation triggered by
696696
* rereplicate, currently, so that users don't get an unexpected -ENOSPC
697697
*/
698-
if (!(m->data_opts.write_flags & BCH_WRITE_CACHED) &&
699-
!durability_required) {
700-
m->data_opts.kill_ptrs |= m->data_opts.rewrite_ptrs;
701-
m->data_opts.rewrite_ptrs = 0;
702-
/* if iter == NULL, it's just a promote */
703-
if (iter)
704-
ret = bch2_extent_drop_ptrs(trans, iter, k, m->data_opts);
705-
goto out;
706-
}
707-
708698
m->op.nr_replicas = min(durability_removing, durability_required) +
709699
m->data_opts.extra_replicas;
710700

@@ -716,17 +706,22 @@ int bch2_data_update_init(struct btree_trans *trans,
716706
if (!(durability_have + durability_removing))
717707
m->op.nr_replicas = max((unsigned) m->op.nr_replicas, 1);
718708

719-
if (!m->op.nr_replicas) {
720-
struct printbuf buf = PRINTBUF;
709+
m->op.nr_replicas_required = m->op.nr_replicas;
721710

722-
bch2_data_update_to_text(&buf, m);
723-
WARN(1, "trying to move an extent, but nr_replicas=0\n%s", buf.buf);
724-
printbuf_exit(&buf);
711+
/*
712+
* It might turn out that we don't need any new replicas, if the
713+
* replicas or durability settings have been changed since the extent
714+
* was written:
715+
*/
716+
if (!m->op.nr_replicas) {
717+
m->data_opts.kill_ptrs |= m->data_opts.rewrite_ptrs;
718+
m->data_opts.rewrite_ptrs = 0;
719+
/* if iter == NULL, it's just a promote */
720+
if (iter)
721+
ret = bch2_extent_drop_ptrs(trans, iter, k, m->data_opts);
725722
goto out;
726723
}
727724

728-
m->op.nr_replicas_required = m->op.nr_replicas;
729-
730725
if (reserve_sectors) {
731726
ret = bch2_disk_reservation_add(c, &m->op.res, reserve_sectors,
732727
m->data_opts.extra_replicas

0 commit comments

Comments
 (0)