summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bcachefs_revision2
-rw-r--r--bch_bindgen/src/bkey.rs80
-rw-r--r--libbcachefs/alloc_background.c9
-rw-r--r--libbcachefs/backpointers.c8
-rw-r--r--libbcachefs/bcachefs_format.h2
-rw-r--r--libbcachefs/btree_update.c2
-rw-r--r--libbcachefs/errcode.c15
-rw-r--r--libbcachefs/errcode.h1
-rw-r--r--libbcachefs/fs-io-buffered.c21
-rw-r--r--libbcachefs/journal.c5
-rw-r--r--libbcachefs/journal.h4
-rw-r--r--libbcachefs/journal_reclaim.c2
-rw-r--r--libbcachefs/journal_types.h2
-rw-r--r--libbcachefs/snapshot.c2
-rw-r--r--libbcachefs/super-io.c1
-rw-r--r--libbcachefs/super.c6
-rw-r--r--libbcachefs/trace.h19
-rw-r--r--linux/time_stats.c8
18 files changed, 109 insertions, 80 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index c2426462..4f5b2097 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-c887148ebf9989ce8bdf6f814d4342ba5bf465fa
+a623b3063d5d6ab6652314028531060d5a0d192e
diff --git a/bch_bindgen/src/bkey.rs b/bch_bindgen/src/bkey.rs
index d4830839..258e2434 100644
--- a/bch_bindgen/src/bkey.rs
+++ b/bch_bindgen/src/bkey.rs
@@ -61,46 +61,48 @@ impl<'a, 'b> BkeySC<'a> {
}
pub fn v(&'a self) -> BkeyValC {
- let ty: c::bch_bkey_type = unsafe { transmute(self.k.type_ as u32) };
+ unsafe {
+ let ty: c::bch_bkey_type = transmute(self.k.type_ as u32);
- use c::bch_bkey_type::*;
- use BkeyValC::*;
- match ty {
- KEY_TYPE_deleted => deleted,
- KEY_TYPE_whiteout => whiteout,
- KEY_TYPE_error => error,
- KEY_TYPE_cookie => cookie(unsafe { transmute(self.v) }),
- KEY_TYPE_hash_whiteout => hash_whiteout(unsafe { transmute(self.v) }),
- KEY_TYPE_btree_ptr => btree_ptr(unsafe { transmute(self.v) }),
- KEY_TYPE_extent => extent(unsafe { transmute(self.v) }),
- KEY_TYPE_reservation => reservation(unsafe { transmute(self.v) }),
- KEY_TYPE_inode => inode(unsafe { transmute(self.v) }),
- KEY_TYPE_inode_generation => inode_generation(unsafe { transmute(self.v) }),
- KEY_TYPE_dirent => dirent(unsafe { transmute(self.v) }),
- KEY_TYPE_xattr => xattr(unsafe { transmute(self.v) }),
- KEY_TYPE_alloc => alloc(unsafe { transmute(self.v) }),
- KEY_TYPE_quota => quota(unsafe { transmute(self.v) }),
- KEY_TYPE_stripe => stripe(unsafe { transmute(self.v) }),
- KEY_TYPE_reflink_p => reflink_p(unsafe { transmute(self.v) }),
- KEY_TYPE_reflink_v => reflink_v(unsafe { transmute(self.v) }),
- KEY_TYPE_inline_data => inline_data(unsafe { transmute(self.v) }),
- KEY_TYPE_btree_ptr_v2 => btree_ptr_v2(unsafe { transmute(self.v) }),
- KEY_TYPE_indirect_inline_data => indirect_inline_data(unsafe { transmute(self.v) }),
- KEY_TYPE_alloc_v2 => alloc_v2(unsafe { transmute(self.v) }),
- KEY_TYPE_subvolume => subvolume(unsafe { transmute(self.v) }),
- KEY_TYPE_snapshot => snapshot(unsafe { transmute(self.v) }),
- KEY_TYPE_inode_v2 => inode_v2(unsafe { transmute(self.v) }),
- KEY_TYPE_alloc_v3 => inode_v3(unsafe { transmute(self.v) }),
- KEY_TYPE_set => set,
- KEY_TYPE_lru => lru(unsafe { transmute(self.v) }),
- KEY_TYPE_alloc_v4 => alloc_v4(unsafe { transmute(self.v) }),
- KEY_TYPE_backpointer => backpointer(unsafe { transmute(self.v) }),
- KEY_TYPE_inode_v3 => inode_v3(unsafe { transmute(self.v) }),
- KEY_TYPE_bucket_gens => bucket_gens(unsafe { transmute(self.v) }),
- KEY_TYPE_snapshot_tree => snapshot_tree(unsafe { transmute(self.v) }),
- KEY_TYPE_logged_op_truncate => logged_op_truncate(unsafe { transmute(self.v) }),
- KEY_TYPE_logged_op_finsert => logged_op_finsert(unsafe { transmute(self.v) }),
- KEY_TYPE_MAX => unreachable!(),
+ use c::bch_bkey_type::*;
+ use BkeyValC::*;
+ match ty {
+ KEY_TYPE_deleted => deleted,
+ KEY_TYPE_whiteout => whiteout,
+ KEY_TYPE_error => error,
+ KEY_TYPE_cookie => cookie(transmute(self.v)),
+ KEY_TYPE_hash_whiteout => hash_whiteout(transmute(self.v)),
+ KEY_TYPE_btree_ptr => btree_ptr(transmute(self.v)),
+ KEY_TYPE_extent => extent(transmute(self.v)),
+ KEY_TYPE_reservation => reservation(transmute(self.v)),
+ KEY_TYPE_inode => inode(transmute(self.v)),
+ KEY_TYPE_inode_generation => inode_generation(transmute(self.v)),
+ KEY_TYPE_dirent => dirent(transmute(self.v)),
+ KEY_TYPE_xattr => xattr(transmute(self.v)),
+ KEY_TYPE_alloc => alloc(transmute(self.v)),
+ KEY_TYPE_quota => quota(transmute(self.v)),
+ KEY_TYPE_stripe => stripe(transmute(self.v)),
+ KEY_TYPE_reflink_p => reflink_p(transmute(self.v)),
+ KEY_TYPE_reflink_v => reflink_v(transmute(self.v)),
+ KEY_TYPE_inline_data => inline_data(transmute(self.v)),
+ KEY_TYPE_btree_ptr_v2 => btree_ptr_v2(transmute(self.v)),
+ KEY_TYPE_indirect_inline_data => indirect_inline_data(transmute(self.v)),
+ KEY_TYPE_alloc_v2 => alloc_v2(transmute(self.v)),
+ KEY_TYPE_subvolume => subvolume(transmute(self.v)),
+ KEY_TYPE_snapshot => snapshot(transmute(self.v)),
+ KEY_TYPE_inode_v2 => inode_v2(transmute(self.v)),
+ KEY_TYPE_alloc_v3 => inode_v3(transmute(self.v)),
+ KEY_TYPE_set => set,
+ KEY_TYPE_lru => lru(transmute(self.v)),
+ KEY_TYPE_alloc_v4 => alloc_v4(transmute(self.v)),
+ KEY_TYPE_backpointer => backpointer(transmute(self.v)),
+ KEY_TYPE_inode_v3 => inode_v3(transmute(self.v)),
+ KEY_TYPE_bucket_gens => bucket_gens(transmute(self.v)),
+ KEY_TYPE_snapshot_tree => snapshot_tree(transmute(self.v)),
+ KEY_TYPE_logged_op_truncate => logged_op_truncate(transmute(self.v)),
+ KEY_TYPE_logged_op_finsert => logged_op_finsert(transmute(self.v)),
+ KEY_TYPE_MAX => unreachable!(),
+ }
}
}
}
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index 4de4036d..ccd6cbfd 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -1878,10 +1878,11 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
if (!got_bucket)
break;
- blkdev_issue_discard(ca->disk_sb.bdev,
- bucket.offset * ca->mi.bucket_size,
- ca->mi.bucket_size,
- GFP_KERNEL);
+ if (ca->mi.discard && !c->opts.nochanges)
+ blkdev_issue_discard(ca->disk_sb.bdev,
+ bucket.offset * ca->mi.bucket_size,
+ ca->mi.bucket_size,
+ GFP_KERNEL);
int ret = bch2_trans_do(c, NULL, NULL,
BCH_WATERMARK_btree|
diff --git a/libbcachefs/backpointers.c b/libbcachefs/backpointers.c
index 23fe9378..f2b33fe4 100644
--- a/libbcachefs/backpointers.c
+++ b/libbcachefs/backpointers.c
@@ -68,9 +68,11 @@ void bch2_backpointer_to_text(struct printbuf *out, const struct bch_backpointer
void bch2_backpointer_k_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
{
- prt_str(out, "bucket=");
- bch2_bpos_to_text(out, bp_pos_to_bucket(c, k.k->p));
- prt_str(out, " ");
+ if (bch2_dev_exists2(c, k.k->p.inode)) {
+ prt_str(out, "bucket=");
+ bch2_bpos_to_text(out, bp_pos_to_bucket(c, k.k->p));
+ prt_str(out, " ");
+ }
bch2_backpointer_to_text(out, bkey_s_c_to_backpointer(k).v);
}
diff --git a/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h
index 9f45f833..bff8750a 100644
--- a/libbcachefs/bcachefs_format.h
+++ b/libbcachefs/bcachefs_format.h
@@ -653,7 +653,7 @@ struct bch_encrypted_key {
/*
* If this field is present in the superblock, it stores an encryption key which
- * is used to encrypt all other data/metadata. The key will normally be encrypted
+ * is used encrypt all other data/metadata. The key will normally be encrypted
* with the key userspace provides, but if encryption has been turned off we'll
* just store the master key unencrypted in the superblock so we can access the
* previously encrypted data.
diff --git a/libbcachefs/btree_update.c b/libbcachefs/btree_update.c
index cbb7cf21..f58e5b33 100644
--- a/libbcachefs/btree_update.c
+++ b/libbcachefs/btree_update.c
@@ -848,7 +848,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
if (ret)
goto err;
- if (!test_bit(JOURNAL_STARTED, &c->journal.flags)) {
+ if (!test_bit(JOURNAL_RUNNING, &c->journal.flags)) {
ret = darray_make_room(&c->journal.early_journal_entries, jset_u64s(u64s));
if (ret)
goto err;
diff --git a/libbcachefs/errcode.c b/libbcachefs/errcode.c
index d260ff9b..43557beb 100644
--- a/libbcachefs/errcode.c
+++ b/libbcachefs/errcode.c
@@ -2,6 +2,7 @@
#include "bcachefs.h"
#include "errcode.h"
+#include "trace.h"
#include <linux/errname.h>
@@ -49,15 +50,17 @@ bool __bch2_err_matches(int err, int class)
return err == class;
}
-int __bch2_err_class(int err)
+int __bch2_err_class(int bch_err)
{
- err = -err;
- BUG_ON((unsigned) err >= BCH_ERR_MAX);
+ int std_err = -bch_err;
+ BUG_ON((unsigned) std_err >= BCH_ERR_MAX);
- while (err >= BCH_ERR_START && bch2_errcode_parents[err - BCH_ERR_START])
- err = bch2_errcode_parents[err - BCH_ERR_START];
+ while (std_err >= BCH_ERR_START && bch2_errcode_parents[std_err - BCH_ERR_START])
+ std_err = bch2_errcode_parents[std_err - BCH_ERR_START];
+
+ trace_error_downcast(bch_err, std_err, _RET_IP_);
- return -err;
+ return -std_err;
}
const char *bch2_blk_status_to_str(blk_status_t status)
diff --git a/libbcachefs/errcode.h b/libbcachefs/errcode.h
index fe3fc14d..e960a6ea 100644
--- a/libbcachefs/errcode.h
+++ b/libbcachefs/errcode.h
@@ -78,6 +78,7 @@
x(ENOMEM, ENOMEM_fs_name_alloc) \
x(ENOMEM, ENOMEM_fs_other_alloc) \
x(ENOMEM, ENOMEM_dev_alloc) \
+ x(ENOMEM, ENOMEM_disk_accounting) \
x(ENOSPC, ENOSPC_disk_reservation) \
x(ENOSPC, ENOSPC_bucket_alloc) \
x(ENOSPC, ENOSPC_disk_label_add) \
diff --git a/libbcachefs/fs-io-buffered.c b/libbcachefs/fs-io-buffered.c
index 73c12e56..27710cdd 100644
--- a/libbcachefs/fs-io-buffered.c
+++ b/libbcachefs/fs-io-buffered.c
@@ -303,18 +303,6 @@ void bch2_readahead(struct readahead_control *ractl)
darray_exit(&readpages_iter.folios);
}
-static void __bchfs_readfolio(struct bch_fs *c, struct bch_read_bio *rbio,
- subvol_inum inum, struct folio *folio)
-{
- bch2_folio_create(folio, __GFP_NOFAIL);
-
- rbio->bio.bi_opf = REQ_OP_READ|REQ_SYNC;
- rbio->bio.bi_iter.bi_sector = folio_sector(folio);
- BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
-
- bch2_trans_run(c, (bchfs_read(trans, rbio, inum, NULL), 0));
-}
-
static void bch2_read_single_folio_end_io(struct bio *bio)
{
complete(bio->bi_private);
@@ -329,6 +317,9 @@ int bch2_read_single_folio(struct folio *folio, struct address_space *mapping)
int ret;
DECLARE_COMPLETION_ONSTACK(done);
+ if (!bch2_folio_create(folio, GFP_KERNEL))
+ return -ENOMEM;
+
bch2_inode_opts_get(&opts, c, &inode->ei_inode);
rbio = rbio_init(bio_alloc_bioset(NULL, 1, REQ_OP_READ, GFP_KERNEL, &c->bio_read),
@@ -336,7 +327,11 @@ int bch2_read_single_folio(struct folio *folio, struct address_space *mapping)
rbio->bio.bi_private = &done;
rbio->bio.bi_end_io = bch2_read_single_folio_end_io;
- __bchfs_readfolio(c, rbio, inode_inum(inode), folio);
+ rbio->bio.bi_opf = REQ_OP_READ|REQ_SYNC;
+ rbio->bio.bi_iter.bi_sector = folio_sector(folio);
+ BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
+
+ bch2_trans_run(c, (bchfs_read(trans, rbio, inode_inum(inode), NULL), 0));
wait_for_completion(&done);
ret = blk_status_to_errno(rbio->bio.bi_status);
diff --git a/libbcachefs/journal.c b/libbcachefs/journal.c
index 46dc25ad..d717e90a 100644
--- a/libbcachefs/journal.c
+++ b/libbcachefs/journal.c
@@ -1183,12 +1183,13 @@ void bch2_fs_journal_stop(struct journal *j)
bch2_journal_meta(j);
journal_quiesce(j);
+ cancel_delayed_work_sync(&j->write_work);
BUG_ON(!bch2_journal_error(j) &&
test_bit(JOURNAL_REPLAY_DONE, &j->flags) &&
j->last_empty_seq != journal_cur_seq(j));
- cancel_delayed_work_sync(&j->write_work);
+ clear_bit(JOURNAL_RUNNING, &j->flags);
}
int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
@@ -1262,7 +1263,7 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
spin_lock(&j->lock);
- set_bit(JOURNAL_STARTED, &j->flags);
+ set_bit(JOURNAL_RUNNING, &j->flags);
j->last_flush_write = jiffies;
j->reservations.idx = j->reservations.unwritten_idx = journal_cur_seq(j);
diff --git a/libbcachefs/journal.h b/libbcachefs/journal.h
index 7c7528f8..4b8c709b 100644
--- a/libbcachefs/journal.h
+++ b/libbcachefs/journal.h
@@ -372,7 +372,7 @@ static inline int bch2_journal_res_get(struct journal *j, struct journal_res *re
int ret;
EBUG_ON(res->ref);
- EBUG_ON(!test_bit(JOURNAL_STARTED, &j->flags));
+ EBUG_ON(!test_bit(JOURNAL_RUNNING, &j->flags));
res->u64s = u64s;
@@ -418,7 +418,7 @@ struct bch_dev;
static inline void bch2_journal_set_replay_done(struct journal *j)
{
- BUG_ON(!test_bit(JOURNAL_STARTED, &j->flags));
+ BUG_ON(!test_bit(JOURNAL_RUNNING, &j->flags));
set_bit(JOURNAL_REPLAY_DONE, &j->flags);
}
diff --git a/libbcachefs/journal_reclaim.c b/libbcachefs/journal_reclaim.c
index ab811c0d..5e3a6d63 100644
--- a/libbcachefs/journal_reclaim.c
+++ b/libbcachefs/journal_reclaim.c
@@ -831,7 +831,7 @@ bool bch2_journal_flush_pins(struct journal *j, u64 seq_to_flush)
/* time_stats this */
bool did_work = false;
- if (!test_bit(JOURNAL_STARTED, &j->flags))
+ if (!test_bit(JOURNAL_RUNNING, &j->flags))
return false;
closure_wait_event(&j->async_wait,
diff --git a/libbcachefs/journal_types.h b/libbcachefs/journal_types.h
index 011f7a0d..508d0ede 100644
--- a/libbcachefs/journal_types.h
+++ b/libbcachefs/journal_types.h
@@ -131,7 +131,7 @@ enum journal_space_from {
enum journal_flags {
JOURNAL_REPLAY_DONE,
- JOURNAL_STARTED,
+ JOURNAL_RUNNING,
JOURNAL_MAY_SKIP_FLUSH,
JOURNAL_NEED_FLUSH_WRITE,
};
diff --git a/libbcachefs/snapshot.c b/libbcachefs/snapshot.c
index 45f67e8b..ac6ba04d 100644
--- a/libbcachefs/snapshot.c
+++ b/libbcachefs/snapshot.c
@@ -728,7 +728,7 @@ static int check_snapshot(struct btree_trans *trans,
return 0;
memset(&s, 0, sizeof(s));
- memcpy(&s, k.v, bkey_val_bytes(k.k));
+ memcpy(&s, k.v, min(sizeof(s), bkey_val_bytes(k.k)));
id = le32_to_cpu(s.parent);
if (id) {
diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c
index a3a9e85a..38a50732 100644
--- a/libbcachefs/super-io.c
+++ b/libbcachefs/super-io.c
@@ -804,7 +804,6 @@ got_super:
goto err;
}
- ret = 0;
sb->have_layout = true;
ret = bch2_sb_validate(sb, &err, READ);
diff --git a/libbcachefs/super.c b/libbcachefs/super.c
index a7f9de22..46da8204 100644
--- a/libbcachefs/super.c
+++ b/libbcachefs/super.c
@@ -286,8 +286,13 @@ static void __bch2_fs_read_only(struct bch_fs *c)
if (test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags) &&
!test_bit(BCH_FS_emergency_ro, &c->flags))
set_bit(BCH_FS_clean_shutdown, &c->flags);
+
bch2_fs_journal_stop(&c->journal);
+ bch_info(c, "%sshutdown complete, journal seq %llu",
+ test_bit(BCH_FS_clean_shutdown, &c->flags) ? "" : "un",
+ c->journal.seq_ondisk);
+
/*
* After stopping journal:
*/
@@ -461,6 +466,7 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
* at least one non-flush write in the journal or recovery will fail:
*/
set_bit(JOURNAL_NEED_FLUSH_WRITE, &c->journal.flags);
+ set_bit(JOURNAL_RUNNING, &c->journal.flags);
for_each_rw_member(c, ca)
bch2_dev_allocator_add(c, ca);
diff --git a/libbcachefs/trace.h b/libbcachefs/trace.h
index 293b90d7..6aa81d1e 100644
--- a/libbcachefs/trace.h
+++ b/libbcachefs/trace.h
@@ -1431,6 +1431,25 @@ DEFINE_EVENT(fs_str, data_update,
TP_ARGS(c, str)
);
+TRACE_EVENT(error_downcast,
+ TP_PROTO(int bch_err, int std_err, unsigned long ip),
+ TP_ARGS(bch_err, std_err, ip),
+
+ TP_STRUCT__entry(
+ __array(char, bch_err, 32 )
+ __array(char, std_err, 32 )
+ __array(char, ip, 32 )
+ ),
+
+ TP_fast_assign(
+ strscpy(__entry->bch_err, bch2_err_str(bch_err), sizeof(__entry->bch_err));
+ strscpy(__entry->std_err, bch2_err_str(std_err), sizeof(__entry->std_err));
+ snprintf(__entry->ip, sizeof(__entry->ip), "%ps", (void *) ip);
+ ),
+
+ TP_printk("%s -> %s %s", __entry->bch_err, __entry->std_err, __entry->ip)
+);
+
#endif /* _TRACE_BCACHEFS_H */
/* This part must be outside protection */
diff --git a/linux/time_stats.c b/linux/time_stats.c
index 0b90c80c..d7dd64ba 100644
--- a/linux/time_stats.c
+++ b/linux/time_stats.c
@@ -313,7 +313,7 @@ void time_stats_to_json(struct seq_buf *out, struct time_stats *stats,
seq_buf_printf(out, " \"stddev\": %llu\n", d_stddev);
seq_buf_printf(out, " },\n");
- seq_buf_printf(out, " \"frequency_ns\": {\n");
+ seq_buf_printf(out, " \"between_ns\": {\n");
seq_buf_printf(out, " \"min\": %llu,\n", stats->min_freq);
seq_buf_printf(out, " \"max\": %llu,\n", stats->max_freq);
seq_buf_printf(out, " \"mean\": %llu,\n", f_mean);
@@ -323,14 +323,14 @@ void time_stats_to_json(struct seq_buf *out, struct time_stats *stats,
f_mean = mean_and_variance_weighted_get_mean(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT);
f_stddev = mean_and_variance_weighted_get_stddev(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT);
- seq_buf_printf(out, " \"frequency_ewma_ns\": {\n");
+ seq_buf_printf(out, " \"between_ewma_ns\": {\n");
seq_buf_printf(out, " \"mean\": %llu,\n", f_mean);
seq_buf_printf(out, " \"stddev\": %llu\n", f_stddev);
if (quantiles) {
u64 last_q = 0;
- /* close frequency_ewma_ns but signal more items */
+ /* close between_ewma_ns but signal more items */
seq_buf_printf(out, " },\n");
seq_buf_printf(out, " \"quantiles_ns\": [\n");
@@ -345,7 +345,7 @@ void time_stats_to_json(struct seq_buf *out, struct time_stats *stats,
}
seq_buf_printf(out, " ]\n");
} else {
- /* close frequency_ewma_ns without dumping further */
+ /* close between_ewma_ns without dumping further */
seq_buf_printf(out, " }\n");
}