summaryrefslogtreecommitdiff
path: root/libbcachefs/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/io.c')
-rw-r--r--libbcachefs/io.c35
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),