diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-03-21 01:30:38 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-22 00:44:18 -0400 |
commit | 951e654f2ca67beee1dd4bd1fbd52c9fa1227aef (patch) | |
tree | 3622c834e5599e779bc59a3c3a871ec6714332b4 | |
parent | f951989978a9f4b0b03cc119b29c851f7a61b8b2 (diff) |
bcachefs: fix degraded writes, misc alloc path bugs
-rw-r--r-- | fs/bcachefs/alloc.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/bcachefs/alloc.c b/fs/bcachefs/alloc.c index ede44f73b7b4..cba399ee713c 100644 --- a/fs/bcachefs/alloc.c +++ b/fs/bcachefs/alloc.c @@ -1530,11 +1530,12 @@ struct write_point *bch2_alloc_sectors_start(struct bch_fs *c, nr_ptrs_have = wp->first_ptr; /* does writepoint have ptrs we don't want to use? */ - writepoint_for_each_ptr(wp, ob, i) - if (!dev_idx_in_target(c, ob->ptr.dev, target)) { - swap(wp->ptrs[i], wp->ptrs[wp->first_ptr]); - wp->first_ptr++; - } + if (target) + writepoint_for_each_ptr(wp, ob, i) + if (!dev_idx_in_target(c, ob->ptr.dev, target)) { + swap(wp->ptrs[i], wp->ptrs[wp->first_ptr]); + wp->first_ptr++; + } if (flags & BCH_WRITE_ONLY_SPECIFIED_DEVS) { ret = open_bucket_add_buckets(c, target, wp, devs_have, @@ -1551,7 +1552,7 @@ struct write_point *bch2_alloc_sectors_start(struct bch_fs *c, nr_replicas, reserve, cl); } - if (ret) + if (ret && ret != -EROFS) goto err; alloc_done: /* check for more than one cache: */ @@ -1584,6 +1585,13 @@ alloc_done: nr_ptrs_effective += ca->mi.durability; } + if (ret == -EROFS && + nr_ptrs_effective >= nr_replicas_required) + ret = 0; + + if (ret) + goto err; + if (nr_ptrs_effective > nr_replicas) { writepoint_for_each_ptr(wp, ob, i) { ca = bch_dev_bkey_exists(c, ob->ptr.dev); |