summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/alloc_background.c2
-rw-r--r--fs/bcachefs/btree_io.c24
-rw-r--r--fs/bcachefs/btree_node_scan.c16
-rw-r--r--fs/bcachefs/extents.c4
-rw-r--r--fs/bcachefs/io_write.c7
-rw-r--r--fs/bcachefs/journal.c9
-rw-r--r--fs/bcachefs/journal_io.c2
-rw-r--r--fs/bcachefs/recovery.c7
-rw-r--r--fs/bcachefs/super.c2
9 files changed, 42 insertions, 31 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index f1d35b7f3fc5..d5cb07c7f4d6 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -389,7 +389,7 @@ void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
if (k.k->type == KEY_TYPE_alloc_v4) {
void *src, *dst;
- *out = *bkey_s_c_to_alloc_v4(k).v;
+ bkey_val_copy(out, bkey_s_c_to_alloc_v4(k));
src = alloc_v4_backpointers(out);
SET_BCH_ALLOC_V4_BACKPOINTERS_START(out, BCH_ALLOC_V4_U64s);
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c
index bd86dd7151a1..83c836080ea2 100644
--- a/fs/bcachefs/btree_io.c
+++ b/fs/bcachefs/btree_io.c
@@ -1405,10 +1405,8 @@ static void btree_node_read_work(struct work_struct *work)
ret = bch2_bkey_pick_read_device(c,
bkey_i_to_s_c(&b->key),
&failed, &rb->pick, -1);
- if (ret <= 0) {
- set_btree_node_read_error(b);
+ if (ret <= 0)
break;
- }
ca = bch2_dev_get_ioref(c, rb->pick.ptr.dev, READ, BCH_DEV_READ_REF_btree_node_read);
rb->have_ioref = ca != NULL;
@@ -1442,27 +1440,21 @@ start:
bch2_maybe_corrupt_bio(bio, bch2_btree_read_corrupt_ratio);
ret = bch2_btree_node_read_done(c, ca, b, &failed, &buf);
- if (ret == -BCH_ERR_btree_node_read_err_want_retry ||
- ret == -BCH_ERR_btree_node_read_err_must_retry)
- continue;
-
- if (ret)
- set_btree_node_read_error(b);
-
- break;
+ if (ret != -BCH_ERR_btree_node_read_err_want_retry &&
+ ret != -BCH_ERR_btree_node_read_err_must_retry)
+ break;
}
bch2_io_failures_to_text(&buf, c, &failed);
- if (btree_node_read_error(b))
- bch2_btree_lost_data(c, &buf, b->c.btree_id);
-
/*
* only print retry success if we read from a replica with no errors
*/
- if (btree_node_read_error(b))
+ if (ret) {
+ set_btree_node_read_error(b);
+ bch2_btree_lost_data(c, &buf, b->c.btree_id);
prt_printf(&buf, "ret %s", bch2_err_str(ret));
- else if (failed.nr) {
+ } else if (failed.nr) {
if (!bch2_dev_io_failures(&failed, rb->pick.ptr.dev))
prt_printf(&buf, "retry success");
else
diff --git a/fs/bcachefs/btree_node_scan.c b/fs/bcachefs/btree_node_scan.c
index f4f958f4615d..4b7b5ca74ba1 100644
--- a/fs/bcachefs/btree_node_scan.c
+++ b/fs/bcachefs/btree_node_scan.c
@@ -158,14 +158,6 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
if (BTREE_NODE_ID(bn) >= BTREE_ID_NR_MAX)
return;
- bio_reset(bio, ca->disk_sb.bdev, REQ_OP_READ);
- bio->bi_iter.bi_sector = offset;
- bch2_bio_map(bio, b->data, c->opts.btree_node_size);
-
- submit_time = local_clock();
- submit_bio_wait(bio);
- bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, submit_time, !bio->bi_status);
-
rcu_read_lock();
struct found_btree_node n = {
.btree_id = BTREE_NODE_ID(bn),
@@ -182,6 +174,14 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
};
rcu_read_unlock();
+ bio_reset(bio, ca->disk_sb.bdev, REQ_OP_READ);
+ bio->bi_iter.bi_sector = offset;
+ bch2_bio_map(bio, b->data, c->opts.btree_node_size);
+
+ submit_time = local_clock();
+ submit_bio_wait(bio);
+ bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, submit_time, !bio->bi_status);
+
found_btree_node_to_key(&b->key, &n);
CLASS(printbuf, buf)();
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index 8152ef1cbbcd..b879a586b7f6 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -282,9 +282,9 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k,
if (have_pick)
return 1;
- if (!have_dirty_ptrs)
+ if (!have_dirty_ptrs && !bkey_is_btree_ptr(k.k))
return 0;
- if (have_missing_devs)
+ if (have_missing_devs || !have_dirty_ptrs)
return bch_err_throw(c, no_device_to_read_from);
if (have_csum_errors)
return bch_err_throw(c, data_read_csum_err);
diff --git a/fs/bcachefs/io_write.c b/fs/bcachefs/io_write.c
index d7620138e038..44b02d4b6502 100644
--- a/fs/bcachefs/io_write.c
+++ b/fs/bcachefs/io_write.c
@@ -89,7 +89,12 @@ void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw)
new = ewma_add(old, io_latency, 5);
} while (!atomic64_try_cmpxchg(latency, &old, new));
- bch2_congested_acct(ca, io_latency, now, rw);
+ /*
+ * Only track read latency for congestion accounting: writes are subject
+ * to heavy queuing delays from page cache writeback:
+ */
+ if (rw == READ)
+ bch2_congested_acct(ca, io_latency, now, rw);
__bch2_time_stats_update(&ca->io_latency[rw].stats, submit_time, now);
}
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
index de03e20f6e30..12b02717007a 100644
--- a/fs/bcachefs/journal.c
+++ b/fs/bcachefs/journal.c
@@ -182,6 +182,8 @@ journal_error_check_stuck(struct journal *j, int error, unsigned flags)
void bch2_journal_do_writes(struct journal *j)
{
+ struct bch_fs *c = container_of(j, struct bch_fs, journal);
+
for (u64 seq = journal_last_unwritten_seq(j);
seq <= journal_cur_seq(j);
seq++) {
@@ -196,6 +198,7 @@ void bch2_journal_do_writes(struct journal *j)
if (!journal_state_seq_count(j, j->reservations, seq)) {
j->seq_write_started = seq;
w->write_started = true;
+ closure_get(&c->cl);
closure_call(&w->io, bch2_journal_write, j->wq, NULL);
}
@@ -1469,6 +1472,10 @@ int bch2_fs_journal_start(struct journal *j, u64 last_seq, u64 cur_seq)
last_seq = cur_seq;
u64 nr = cur_seq - last_seq;
+ if (nr * sizeof(struct journal_entry_pin_list) > 1U << 30) {
+ bch_err(c, "too many ntjournal fifo (%llu open entries)", nr);
+ return bch_err_throw(c, ENOMEM_journal_pin_fifo);
+ }
/*
* Extra fudge factor, in case we crashed when the journal pin fifo was
@@ -1481,7 +1488,7 @@ int bch2_fs_journal_start(struct journal *j, u64 last_seq, u64 cur_seq)
nr = max(nr, JOURNAL_PIN);
init_fifo(&j->pin, roundup_pow_of_two(nr), GFP_KERNEL);
if (!j->pin.data) {
- bch_err(c, "error reallocating journal fifo (%llu open entries)", nr);
+ bch_err(c, "error allocating journal fifo (%llu open entries)", nr);
return bch_err_throw(c, ENOMEM_journal_pin_fifo);
}
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
index 2835250a14c4..47224666d07e 100644
--- a/fs/bcachefs/journal_io.c
+++ b/fs/bcachefs/journal_io.c
@@ -1820,6 +1820,8 @@ static CLOSURE_CALLBACK(journal_write_done)
if (do_discards)
bch2_do_discards(c);
+
+ closure_put(&c->cl);
}
static void journal_write_endio(struct bio *bio)
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 58c159e5f10d..304473dac268 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -67,13 +67,16 @@ int bch2_btree_lost_data(struct bch_fs *c,
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_backpointers_to_extents, 0, &write_sb) ?: ret;
#endif
+ write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_lru_entry_bad, ext->errors_silent);
+ write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_backpointer_to_missing_ptr, ext->errors_silent);
+ write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_data_type_wrong, ext->errors_silent);
+ write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_dirty_sectors_wrong, ext->errors_silent);
+
switch (btree) {
case BTREE_ID_alloc:
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_alloc_info, 0, &write_sb) ?: ret;
- write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_data_type_wrong, ext->errors_silent);
write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_gen_wrong, ext->errors_silent);
- write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_dirty_sectors_wrong, ext->errors_silent);
write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_cached_sectors_wrong, ext->errors_silent);
write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_stripe_wrong, ext->errors_silent);
write_sb |= !__test_and_set_bit_le64(BCH_FSCK_ERR_alloc_key_stripe_redundancy_wrong, ext->errors_silent);
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 0fc0b2221036..b3b2d8353a36 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -729,6 +729,8 @@ void __bch2_fs_stop(struct bch_fs *c)
cancel_work_sync(&ca->io_error_work);
cancel_work_sync(&c->read_only_work);
+
+ flush_work(&c->btree_interior_update_work);
}
void bch2_fs_free(struct bch_fs *c)