diff options
Diffstat (limited to 'libbcachefs/io.c')
-rw-r--r-- | libbcachefs/io.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/libbcachefs/io.c b/libbcachefs/io.c index f0fca861..d215973a 100644 --- a/libbcachefs/io.c +++ b/libbcachefs/io.c @@ -27,6 +27,7 @@ #include "journal.h" #include "keylist.h" #include "move.h" +#include "nocow_locking.h" #include "rebalance.h" #include "subvolume.h" #include "super.h" @@ -427,7 +428,7 @@ retry: opts.data_replicas, opts.data_replicas, RESERVE_none, 0, &cl, &wp); - if (ret == -EAGAIN) { + if (bch2_err_matches(ret, BCH_ERR_operation_blocked)) { bch2_trans_unlock(trans); closure_sync(&cl); goto retry; @@ -753,15 +754,17 @@ static void __bch2_write_index(struct bch_write_op *op) op->written += sectors_start - keylist_sectors(keys); - if (ret) { + if (ret && !bch2_err_matches(ret, EROFS)) { struct bkey_i *k = bch2_keylist_front(&op->insert_keys); bch_err_inum_offset_ratelimited(c, k->k.p.inode, k->k.p.offset << 9, "write error while doing btree update: %s", bch2_err_str(ret)); - goto err; } + + if (ret) + goto err; } out: /* If some a bucket wasn't written, we can't erasure code it: */ @@ -1362,13 +1365,16 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op) bch2_nocow_write_convert_one_unwritten(&trans, &iter, orig, k, op->new_i_size); })); - if (ret) { + if (ret && !bch2_err_matches(ret, EROFS)) { struct bkey_i *k = bch2_keylist_front(&op->insert_keys); bch_err_inum_offset_ratelimited(c, k->k.p.inode, k->k.p.offset << 9, "write error while doing btree update: %s", bch2_err_str(ret)); + } + + if (ret) { op->error = ret; break; } @@ -1406,7 +1412,7 @@ static void bch2_nocow_write(struct bch_write_op *op) struct { struct bpos b; unsigned gen; - two_state_lock_t *l; + struct nocow_lock_bucket *l; } buckets[BCH_REPLICAS_MAX]; unsigned nr_buckets = 0; u32 snapshot; @@ -1453,7 +1459,8 @@ retry: buckets[nr_buckets].b = PTR_BUCKET_POS(c, ptr); buckets[nr_buckets].gen = ptr->gen; buckets[nr_buckets].l = - bucket_nocow_lock(&c->nocow_locks, buckets[nr_buckets].b); + bucket_nocow_lock(&c->nocow_locks, + bucket_to_u64(buckets[nr_buckets].b)); prefetch(buckets[nr_buckets].l); nr_buckets++; @@ -1475,11 +1482,12 @@ retry: for (i = 0; i < nr_buckets; i++) { struct bch_dev *ca = bch_dev_bkey_exists(c, buckets[i].b.inode); - two_state_lock_t *l = buckets[i].l; + struct nocow_lock_bucket *l = buckets[i].l; bool stale; - if (!bch2_two_state_trylock(l, BUCKET_NOCOW_LOCK_UPDATE)) - __bch2_bucket_nocow_lock(&c->nocow_locks, l, BUCKET_NOCOW_LOCK_UPDATE); + __bch2_bucket_nocow_lock(&c->nocow_locks, l, + bucket_to_u64(buckets[i].b), + BUCKET_NOCOW_LOCK_UPDATE); rcu_read_lock(); stale = gen_after(*bucket_gen(ca, buckets[i].b.offset), buckets[i].gen); @@ -1627,7 +1635,7 @@ again: BCH_WRITE_ONLY_SPECIFIED_DEVS)) ? NULL : &op->cl, &wp)); if (unlikely(ret)) { - if (ret == -EAGAIN) + if (bch2_err_matches(ret, BCH_ERR_operation_blocked)) break; goto err; @@ -1775,7 +1783,7 @@ void bch2_write(struct closure *cl) if (c->opts.nochanges || !percpu_ref_tryget_live(&c->writes)) { - op->error = -EROFS; + op->error = -BCH_ERR_erofs_no_writes; goto err; } @@ -2905,11 +2913,6 @@ void bch2_fs_io_exit(struct bch_fs *c) int bch2_fs_io_init(struct bch_fs *c) { - unsigned i; - - for (i = 0; i < ARRAY_SIZE(c->nocow_locks.l); i++) - two_state_lock_init(&c->nocow_locks.l[i]); - if (bioset_init(&c->bio_read, 1, offsetof(struct bch_read_bio, bio), BIOSET_NEED_BVECS) || bioset_init(&c->bio_read_split, 1, offsetof(struct bch_read_bio, bio), |