summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-06-19 13:12:31 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-06-19 13:12:31 -0400
commit10ed83353be8c8fcfb89b2e700fb8f2be0f8673c (patch)
treef02dd2c5d07c5d1402391fd63706383be5d00cd8
parent35c7f2b4e369fec62633de667339496c3e4544c8 (diff)
Update bcachefs sources to 20342b5217ca bcachefs: Plumb trans_kmalloc ip to trans_log_msg
-rw-r--r--.bcachefs_revision2
-rw-r--r--libbcachefs/alloc_background.c13
-rw-r--r--libbcachefs/bcachefs.h2
-rw-r--r--libbcachefs/btree_gc.c1
-rw-r--r--libbcachefs/btree_iter.c6
-rw-r--r--libbcachefs/btree_update.c29
-rw-r--r--libbcachefs/btree_update.h26
-rw-r--r--libbcachefs/btree_update_interior.c31
-rw-r--r--libbcachefs/data_update.c1
-rw-r--r--libbcachefs/dirent.c13
-rw-r--r--libbcachefs/dirent.h3
-rw-r--r--libbcachefs/errcode.h6
-rw-r--r--libbcachefs/error.c4
-rw-r--r--libbcachefs/fs-io.c2
-rw-r--r--libbcachefs/fs.c10
-rw-r--r--libbcachefs/fsck.c25
-rw-r--r--libbcachefs/inode.c6
-rw-r--r--libbcachefs/journal_io.c5
-rw-r--r--libbcachefs/recovery.c3
-rw-r--r--libbcachefs/sb-errors_format.h11
-rw-r--r--libbcachefs/sb-members.h16
-rw-r--r--libbcachefs/str_hash.c5
-rw-r--r--libbcachefs/str_hash.h2
-rw-r--r--libbcachefs/super.c15
24 files changed, 136 insertions, 101 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index 1509bf37..7375d5b0 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-4af8a1ac90dcd9028d5a53b4487aa0d3a47f3de4
+20342b5217ca8d5148ac9637ae6820030e0bcbf6
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index b228a5a6..66de4631 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -1406,6 +1406,9 @@ int bch2_check_discard_freespace_key(struct btree_trans *trans, struct btree_ite
: BCH_DATA_free;
struct printbuf buf = PRINTBUF;
+ unsigned fsck_flags = (async_repair ? FSCK_ERR_NO_LOG : 0)|
+ FSCK_CAN_FIX|FSCK_CAN_IGNORE;
+
struct bpos bucket = iter->pos;
bucket.offset &= ~(~0ULL << 56);
u64 genbits = iter->pos.offset & (~0ULL << 56);
@@ -1419,9 +1422,10 @@ int bch2_check_discard_freespace_key(struct btree_trans *trans, struct btree_ite
return ret;
if (!bch2_dev_bucket_exists(c, bucket)) {
- if (fsck_err(trans, need_discard_freespace_key_to_invalid_dev_bucket,
- "entry in %s btree for nonexistant dev:bucket %llu:%llu",
- bch2_btree_id_str(iter->btree_id), bucket.inode, bucket.offset))
+ if (__fsck_err(trans, fsck_flags,
+ need_discard_freespace_key_to_invalid_dev_bucket,
+ "entry in %s btree for nonexistant dev:bucket %llu:%llu",
+ bch2_btree_id_str(iter->btree_id), bucket.inode, bucket.offset))
goto delete;
ret = 1;
goto out;
@@ -1433,7 +1437,8 @@ int bch2_check_discard_freespace_key(struct btree_trans *trans, struct btree_ite
if (a->data_type != state ||
(state == BCH_DATA_free &&
genbits != alloc_freespace_genbits(*a))) {
- if (fsck_err(trans, need_discard_freespace_key_bad,
+ if (__fsck_err(trans, fsck_flags,
+ need_discard_freespace_key_bad,
"%s\nincorrectly set at %s:%llu:%llu:0 (free %u, genbits %llu should be %llu)",
(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf),
bch2_btree_id_str(iter->btree_id),
diff --git a/libbcachefs/bcachefs.h b/libbcachefs/bcachefs.h
index 8043943c..ac99a8ec 100644
--- a/libbcachefs/bcachefs.h
+++ b/libbcachefs/bcachefs.h
@@ -863,7 +863,7 @@ struct bch_fs {
DARRAY(enum bcachefs_metadata_version)
incompat_versions_requested;
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
struct unicode_map *cf_encoding;
#endif
diff --git a/libbcachefs/btree_gc.c b/libbcachefs/btree_gc.c
index 448f2a4a..697c6ecc 100644
--- a/libbcachefs/btree_gc.c
+++ b/libbcachefs/btree_gc.c
@@ -508,6 +508,7 @@ again:
* to handle a transaction restart - this code needs to be rewritten
* when we start doing online topology repair
*/
+ bch2_trans_unlock_long(trans);
if (mustfix_fsck_err_on(!have_child,
c, btree_node_topology_interior_node_empty,
"empty interior btree node at %s", buf.buf))
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c
index 06160399..96697d5c 100644
--- a/libbcachefs/btree_iter.c
+++ b/libbcachefs/btree_iter.c
@@ -3194,6 +3194,10 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size, unsigned long
if (WARN_ON_ONCE(new_bytes > BTREE_TRANS_MEM_MAX)) {
#ifdef CONFIG_BCACHEFS_TRANS_KMALLOC_TRACE
struct printbuf buf = PRINTBUF;
+ bch2_log_msg_start(c, &buf);
+ prt_printf(&buf, "bump allocator exceeded BTREE_TRANS_MEM_MAX (%u)\n",
+ BTREE_TRANS_MEM_MAX);
+
bch2_trans_kmalloc_trace_to_text(&buf, &trans->trans_kmalloc_trace);
bch2_print_str(c, KERN_ERR, buf.buf);
printbuf_exit(&buf);
@@ -3319,7 +3323,7 @@ u32 bch2_trans_begin(struct btree_trans *trans)
trans->restart_count++;
trans->mem_top = 0;
- if (trans->restarted == BCH_ERR_transaction_restart_mem_realloced) {
+ if (unlikely(trans->restarted == BCH_ERR_transaction_restart_mem_realloced)) {
EBUG_ON(!trans->mem || !trans->mem_bytes);
unsigned new_bytes = trans->realloc_bytes_required;
void *new_mem = krealloc(trans->mem, new_bytes, GFP_NOWAIT|__GFP_NOWARN);
diff --git a/libbcachefs/btree_update.c b/libbcachefs/btree_update.c
index e97e78c1..192c1e5e 100644
--- a/libbcachefs/btree_update.c
+++ b/libbcachefs/btree_update.c
@@ -546,23 +546,29 @@ int bch2_btree_insert_clone_trans(struct btree_trans *trans,
void *__bch2_trans_subbuf_alloc(struct btree_trans *trans,
struct btree_trans_subbuf *buf,
- unsigned u64s)
+ unsigned u64s, ulong ip)
{
unsigned new_top = buf->u64s + u64s;
- unsigned old_size = buf->size;
+ unsigned new_size = buf->size;
- if (new_top > buf->size)
- buf->size = roundup_pow_of_two(new_top);
+ BUG_ON(roundup_pow_of_two(new_top) > U16_MAX);
- void *n = bch2_trans_kmalloc_nomemzero(trans, buf->size * sizeof(u64));
+ if (new_top > new_size)
+ new_size = roundup_pow_of_two(new_top);
+
+ void *n = bch2_trans_kmalloc_nomemzero_ip(trans, new_size * sizeof(u64), ip);
if (IS_ERR(n))
return n;
+ unsigned offset = (u64 *) n - (u64 *) trans->mem;
+ BUG_ON(offset > U16_MAX);
+
if (buf->u64s)
memcpy(n,
btree_trans_subbuf_base(trans, buf),
- old_size * sizeof(u64));
+ buf->size * sizeof(u64));
buf->base = (u64 *) n - (u64 *) trans->mem;
+ buf->size = new_size;
void *p = btree_trans_subbuf_top(trans, buf);
buf->u64s = new_top;
@@ -807,11 +813,11 @@ int bch2_btree_bit_mod_buffered(struct btree_trans *trans, enum btree_id btree,
return bch2_trans_update_buffered(trans, btree, &k);
}
-static int __bch2_trans_log_str(struct btree_trans *trans, const char *str, unsigned len)
+static int __bch2_trans_log_str(struct btree_trans *trans, const char *str, unsigned len, ulong ip)
{
unsigned u64s = DIV_ROUND_UP(len, sizeof(u64));
- struct jset_entry *e = bch2_trans_jset_entry_alloc(trans, jset_u64s(u64s));
+ struct jset_entry *e = bch2_trans_jset_entry_alloc_ip(trans, jset_u64s(u64s), ip);
int ret = PTR_ERR_OR_ZERO(e);
if (ret)
return ret;
@@ -824,7 +830,7 @@ static int __bch2_trans_log_str(struct btree_trans *trans, const char *str, unsi
int bch2_trans_log_str(struct btree_trans *trans, const char *str)
{
- return __bch2_trans_log_str(trans, str, strlen(str));
+ return __bch2_trans_log_str(trans, str, strlen(str), _RET_IP_);
}
int bch2_trans_log_msg(struct btree_trans *trans, struct printbuf *buf)
@@ -833,13 +839,14 @@ int bch2_trans_log_msg(struct btree_trans *trans, struct printbuf *buf)
if (ret)
return ret;
- return __bch2_trans_log_str(trans, buf->buf, buf->pos);
+ return __bch2_trans_log_str(trans, buf->buf, buf->pos, _RET_IP_);
}
int bch2_trans_log_bkey(struct btree_trans *trans, enum btree_id btree,
unsigned level, struct bkey_i *k)
{
- struct jset_entry *e = bch2_trans_jset_entry_alloc(trans, jset_u64s(k->k.u64s));
+ struct jset_entry *e = bch2_trans_jset_entry_alloc_ip(trans,
+ jset_u64s(k->k.u64s), _RET_IP_);
int ret = PTR_ERR_OR_ZERO(e);
if (ret)
return ret;
diff --git a/libbcachefs/btree_update.h b/libbcachefs/btree_update.h
index 9feef1dc..e4b6e7d5 100644
--- a/libbcachefs/btree_update.h
+++ b/libbcachefs/btree_update.h
@@ -137,21 +137,29 @@ static inline void *btree_trans_subbuf_top(struct btree_trans *trans,
void *__bch2_trans_subbuf_alloc(struct btree_trans *,
struct btree_trans_subbuf *,
- unsigned);
+ unsigned, ulong);
static inline void *
-bch2_trans_subbuf_alloc(struct btree_trans *trans,
- struct btree_trans_subbuf *buf,
- unsigned u64s)
+bch2_trans_subbuf_alloc_ip(struct btree_trans *trans,
+ struct btree_trans_subbuf *buf,
+ unsigned u64s, ulong ip)
{
if (buf->u64s + u64s > buf->size)
- return __bch2_trans_subbuf_alloc(trans, buf, u64s);
+ return __bch2_trans_subbuf_alloc(trans, buf, u64s, ip);
void *p = btree_trans_subbuf_top(trans, buf);
buf->u64s += u64s;
return p;
}
+static inline void *
+bch2_trans_subbuf_alloc(struct btree_trans *trans,
+ struct btree_trans_subbuf *buf,
+ unsigned u64s)
+{
+ return bch2_trans_subbuf_alloc_ip(trans, buf, u64s, _THIS_IP_);
+}
+
static inline struct jset_entry *btree_trans_journal_entries_start(struct btree_trans *trans)
{
return btree_trans_subbuf_base(trans, &trans->journal_entries);
@@ -163,9 +171,15 @@ static inline struct jset_entry *btree_trans_journal_entries_top(struct btree_tr
}
static inline struct jset_entry *
+bch2_trans_jset_entry_alloc_ip(struct btree_trans *trans, unsigned u64s, ulong ip)
+{
+ return bch2_trans_subbuf_alloc_ip(trans, &trans->journal_entries, u64s, ip);
+}
+
+static inline struct jset_entry *
bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsigned u64s)
{
- return bch2_trans_subbuf_alloc(trans, &trans->journal_entries, u64s);
+ return bch2_trans_jset_entry_alloc_ip(trans, u64s, _THIS_IP_);
}
int bch2_btree_insert_clone_trans(struct btree_trans *, enum btree_id, struct bkey_i *);
diff --git a/libbcachefs/btree_update_interior.c b/libbcachefs/btree_update_interior.c
index 7bf1bd6a..d9ac09fa 100644
--- a/libbcachefs/btree_update_interior.c
+++ b/libbcachefs/btree_update_interior.c
@@ -290,8 +290,6 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
struct bch_fs *c = trans->c;
struct write_point *wp;
struct btree *b;
- BKEY_PADDED_ONSTACK(k, BKEY_BTREE_PTR_VAL_U64s_MAX) tmp;
- struct open_buckets obs = { .nr = 0 };
struct bch_devs_list devs_have = (struct bch_devs_list) { 0 };
enum bch_watermark watermark = flags & BCH_WATERMARK_MASK;
unsigned nr_reserve = watermark < BCH_WATERMARK_reclaim
@@ -310,8 +308,8 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
struct btree_alloc *a =
&c->btree_reserve_cache[--c->btree_reserve_cache_nr];
- obs = a->ob;
- bkey_copy(&tmp.k, &a->k);
+ bkey_copy(&b->key, &a->k);
+ b->ob = a->ob;
mutex_unlock(&c->btree_reserve_cache_lock);
goto out;
}
@@ -345,14 +343,12 @@ retry:
goto retry;
}
- bkey_btree_ptr_v2_init(&tmp.k);
- bch2_alloc_sectors_append_ptrs(c, wp, &tmp.k, btree_sectors(c), false);
+ bkey_btree_ptr_v2_init(&b->key);
+ bch2_alloc_sectors_append_ptrs(c, wp, &b->key, btree_sectors(c), false);
- bch2_open_bucket_get(c, wp, &obs);
+ bch2_open_bucket_get(c, wp, &b->ob);
bch2_alloc_sectors_done(c, wp);
out:
- bkey_copy(&b->key, &tmp.k);
- b->ob = obs;
six_unlock_write(&b->c.lock);
six_unlock_intent(&b->c.lock);
@@ -513,30 +509,25 @@ static int bch2_btree_reserve_get(struct btree_trans *trans,
unsigned flags,
struct closure *cl)
{
- struct btree *b;
- unsigned interior;
- int ret = 0;
-
BUG_ON(nr_nodes[0] + nr_nodes[1] > BTREE_RESERVE_MAX);
/*
* Protects reaping from the btree node cache and using the btree node
* open bucket reserve:
*/
- ret = bch2_btree_cache_cannibalize_lock(trans, cl);
+ int ret = bch2_btree_cache_cannibalize_lock(trans, cl);
if (ret)
return ret;
- for (interior = 0; interior < 2; interior++) {
+ for (unsigned interior = 0; interior < 2; interior++) {
struct prealloc_nodes *p = as->prealloc_nodes + interior;
while (p->nr < nr_nodes[interior]) {
- b = __bch2_btree_node_alloc(trans, &as->disk_res, cl,
- interior, target, flags);
- if (IS_ERR(b)) {
- ret = PTR_ERR(b);
+ struct btree *b = __bch2_btree_node_alloc(trans, &as->disk_res,
+ cl, interior, target, flags);
+ ret = PTR_ERR_OR_ZERO(b);
+ if (ret)
goto err;
- }
p->b[p->nr++] = b;
}
diff --git a/libbcachefs/data_update.c b/libbcachefs/data_update.c
index 5f117434..e848e210 100644
--- a/libbcachefs/data_update.c
+++ b/libbcachefs/data_update.c
@@ -249,6 +249,7 @@ static int data_update_invalid_bkey(struct data_update *m,
bch2_bkey_val_to_text(&buf, c, k);
prt_str(&buf, "\nnew: ");
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(insert));
+ prt_newline(&buf);
bch2_fs_emergency_read_only2(c, &buf);
diff --git a/libbcachefs/dirent.c b/libbcachefs/dirent.c
index 300f7cc8..308de4b2 100644
--- a/libbcachefs/dirent.c
+++ b/libbcachefs/dirent.c
@@ -18,7 +18,7 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
{
*out_cf = (struct qstr) QSTR_INIT(NULL, 0);
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
unsigned char *buf = bch2_trans_kmalloc(trans, BCH_NAME_MAX + 1);
int ret = PTR_ERR_OR_ZERO(buf);
if (ret)
@@ -31,7 +31,7 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
*out_cf = (struct qstr) QSTR_INIT(buf, ret);
return 0;
#else
- return -EOPNOTSUPP;
+ return bch_err_throw(trans->c, no_casefolding_without_utf8);
#endif
}
@@ -231,7 +231,8 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
prt_printf(out, " type %s", bch2_d_type_str(d.v->d_type));
}
-int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
+int bch2_dirent_init_name(struct bch_fs *c,
+ struct bkey_i_dirent *dirent,
const struct bch_hash_info *hash_info,
const struct qstr *name,
const struct qstr *cf_name)
@@ -251,7 +252,7 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
offsetof(struct bch_dirent, d_name) -
name->len);
} else {
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
memcpy(&dirent->v.d_cf_name_block.d_names[0], name->name, name->len);
char *cf_out = &dirent->v.d_cf_name_block.d_names[name->len];
@@ -278,7 +279,7 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
EBUG_ON(bch2_dirent_get_casefold_name(dirent_i_to_s_c(dirent)).len != cf_len);
#else
- return -EOPNOTSUPP;
+ return bch_err_throw(c, no_casefolding_without_utf8);
#endif
}
@@ -313,7 +314,7 @@ struct bkey_i_dirent *bch2_dirent_create_key(struct btree_trans *trans,
dirent->v.d_type = type;
dirent->v.d_unused = 0;
- int ret = bch2_dirent_init_name(dirent, hash_info, name, cf_name);
+ int ret = bch2_dirent_init_name(trans->c, dirent, hash_info, name, cf_name);
if (ret)
return ERR_PTR(ret);
diff --git a/libbcachefs/dirent.h b/libbcachefs/dirent.h
index 70fb0b58..1e17199c 100644
--- a/libbcachefs/dirent.h
+++ b/libbcachefs/dirent.h
@@ -59,7 +59,8 @@ static inline void dirent_copy_target(struct bkey_i_dirent *dst,
dst->v.d_type = src.v->d_type;
}
-int bch2_dirent_init_name(struct bkey_i_dirent *,
+int bch2_dirent_init_name(struct bch_fs *,
+ struct bkey_i_dirent *,
const struct bch_hash_info *,
const struct qstr *,
const struct qstr *);
diff --git a/libbcachefs/errcode.h b/libbcachefs/errcode.h
index 86a842f1..3118449d 100644
--- a/libbcachefs/errcode.h
+++ b/libbcachefs/errcode.h
@@ -5,6 +5,7 @@
#define BCH_ERRCODES() \
x(ERANGE, ERANGE_option_too_small) \
x(ERANGE, ERANGE_option_too_big) \
+ x(ERANGE, projid_too_big) \
x(EINVAL, injected) \
x(BCH_ERR_injected, injected_fs_start) \
x(EINVAL, mount_option) \
@@ -216,6 +217,11 @@
x(EINVAL, erasure_coding_found_btree_node) \
x(EINVAL, option_negative) \
x(EOPNOTSUPP, may_not_use_incompat_feature) \
+ x(EOPNOTSUPP, no_casefolding_without_utf8) \
+ x(EOPNOTSUPP, casefold_opt_is_dir_only) \
+ x(EOPNOTSUPP, unsupported_fsx_flag) \
+ x(EOPNOTSUPP, unsupported_fa_flag) \
+ x(EOPNOTSUPP, unsupported_fallocate_mode) \
x(EROFS, erofs_trans_commit) \
x(EROFS, erofs_no_writes) \
x(EROFS, erofs_journal_err) \
diff --git a/libbcachefs/error.c b/libbcachefs/error.c
index a8ec6aae..b2a6c041 100644
--- a/libbcachefs/error.c
+++ b/libbcachefs/error.c
@@ -621,7 +621,9 @@ print:
if (s)
s->ret = ret;
- if (trans)
+ if (trans &&
+ !(flags & FSCK_ERR_NO_LOG) &&
+ ret == -BCH_ERR_fsck_fix)
ret = bch2_trans_log_str(trans, bch2_sb_error_strs[err]) ?: ret;
err_unlock:
mutex_unlock(&c->fsck_error_msgs_lock);
diff --git a/libbcachefs/fs-io.c b/libbcachefs/fs-io.c
index a233f458..dc5f713e 100644
--- a/libbcachefs/fs-io.c
+++ b/libbcachefs/fs-io.c
@@ -841,7 +841,7 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
else if (mode == FALLOC_FL_COLLAPSE_RANGE)
ret = bchfs_fcollapse_finsert(inode, offset, len, false);
else
- ret = -EOPNOTSUPP;
+ ret = bch_err_throw(c, unsupported_fallocate_mode);
err:
bch2_pagecache_block_put(inode);
inode_unlock(&inode->v);
diff --git a/libbcachefs/fs.c b/libbcachefs/fs.c
index 3063a8dd..df42d58d 100644
--- a/libbcachefs/fs.c
+++ b/libbcachefs/fs.c
@@ -722,7 +722,7 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
if (IS_ERR(inode))
inode = NULL;
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
if (!inode && IS_CASEFOLDED(vdir)) {
/*
* Do not cache a negative dentry in casefolded directories
@@ -1695,10 +1695,10 @@ static int bch2_fileattr_set(struct mnt_idmap *idmap,
s.mask = map_defined(bch_flags_to_xflags);
s.flags |= map_flags_rev(bch_flags_to_xflags, fa->fsx_xflags);
if (fa->fsx_xflags)
- return -EOPNOTSUPP;
+ return bch_err_throw(c, unsupported_fsx_flag);
if (fa->fsx_projid >= U32_MAX)
- return -EINVAL;
+ return bch_err_throw(c, projid_too_big);
/*
* inode fields accessible via the xattr interface are stored with a +1
@@ -1721,7 +1721,7 @@ static int bch2_fileattr_set(struct mnt_idmap *idmap,
s.flags |= map_flags_rev(bch_flags_to_uflags, fa->flags);
if (fa->flags)
- return -EOPNOTSUPP;
+ return bch_err_throw(c, unsupported_fa_flag);
}
mutex_lock(&inode->ei_update_lock);
@@ -2564,7 +2564,7 @@ got_sb:
sb->s_shrink->seeks = 0;
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
sb->s_encoding = c->cf_encoding;
#endif
generic_set_sb_d_ops(sb);
diff --git a/libbcachefs/fsck.c b/libbcachefs/fsck.c
index 57ddc20a..4ceb28a6 100644
--- a/libbcachefs/fsck.c
+++ b/libbcachefs/fsck.c
@@ -728,14 +728,8 @@ static int snapshots_seen_update(struct bch_fs *c, struct snapshots_seen *s,
static bool key_visible_in_snapshot(struct bch_fs *c, struct snapshots_seen *seen,
u32 id, u32 ancestor)
{
- ssize_t i;
-
EBUG_ON(id > ancestor);
- /* @ancestor should be the snapshot most recently added to @seen */
- EBUG_ON(ancestor != seen->pos.snapshot);
- EBUG_ON(ancestor != darray_last(seen->ids));
-
if (id == ancestor)
return true;
@@ -751,11 +745,8 @@ static bool key_visible_in_snapshot(struct bch_fs *c, struct snapshots_seen *see
* numerically, since snapshot ID lists are kept sorted, so if we find
* an id that's an ancestor of @id we're done:
*/
-
- for (i = seen->ids.nr - 2;
- i >= 0 && seen->ids.data[i] >= id;
- --i)
- if (bch2_snapshot_is_ancestor(c, id, seen->ids.data[i]))
+ darray_for_each_reverse(seen->ids, i)
+ if (*i != ancestor && bch2_snapshot_is_ancestor(c, id, *i))
return false;
return true;
@@ -2311,7 +2302,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
*hash_info = bch2_hash_info_init(c, &i->inode);
dir->first_this_inode = false;
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
hash_info->cf_encoding = bch2_inode_casefold(c, &i->inode) ? c->cf_encoding : NULL;
#endif
@@ -2601,14 +2592,6 @@ int bch2_check_root(struct bch_fs *c)
return ret;
}
-static bool darray_u32_has(darray_u32 *d, u32 v)
-{
- darray_for_each(*d, i)
- if (*i == v)
- return true;
- return false;
-}
-
static int check_subvol_path(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k)
{
struct bch_fs *c = trans->c;
@@ -2641,7 +2624,7 @@ static int check_subvol_path(struct btree_trans *trans, struct btree_iter *iter,
u32 parent = le32_to_cpu(s.v->fs_path_parent);
- if (darray_u32_has(&subvol_path, parent)) {
+ if (darray_find(subvol_path, parent)) {
printbuf_reset(&buf);
prt_printf(&buf, "subvolume loop: ");
diff --git a/libbcachefs/inode.c b/libbcachefs/inode.c
index 53e5dc1f..95f3c0d4 100644
--- a/libbcachefs/inode.c
+++ b/libbcachefs/inode.c
@@ -1265,11 +1265,11 @@ int bch2_inode_set_casefold(struct btree_trans *trans, subvol_inum inum,
{
struct bch_fs *c = trans->c;
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
int ret = 0;
/* Not supported on individual files. */
if (!S_ISDIR(bi->bi_mode))
- return -EOPNOTSUPP;
+ return bch_err_throw(c, casefold_opt_is_dir_only);
/*
* Make sure the dir is empty, as otherwise we'd need to
@@ -1291,7 +1291,7 @@ int bch2_inode_set_casefold(struct btree_trans *trans, subvol_inum inum,
return bch2_maybe_propagate_has_case_insensitive(trans, inum, bi);
#else
bch_err(c, "Cannot use casefolding on a kernel without CONFIG_UNICODE");
- return -EOPNOTSUPP;
+ return bch_err_throw(c, no_casefolding_without_utf8);
#endif
}
diff --git a/libbcachefs/journal_io.c b/libbcachefs/journal_io.c
index afbf12e8..dd3f3434 100644
--- a/libbcachefs/journal_io.c
+++ b/libbcachefs/journal_io.c
@@ -1716,9 +1716,10 @@ static CLOSURE_CALLBACK(journal_write_done)
bch2_log_msg_start(c, &buf);
if (err == -BCH_ERR_journal_write_err)
- prt_printf(&buf, "unable to write journal to sufficient devices");
+ prt_printf(&buf, "unable to write journal to sufficient devices\n");
else
- prt_printf(&buf, "journal write error marking replicas: %s", bch2_err_str(err));
+ prt_printf(&buf, "journal write error marking replicas: %s\n",
+ bch2_err_str(err));
bch2_fs_emergency_read_only2(c, &buf);
diff --git a/libbcachefs/recovery.c b/libbcachefs/recovery.c
index fa5d1ef5..d0b7e3a3 100644
--- a/libbcachefs/recovery.c
+++ b/libbcachefs/recovery.c
@@ -607,6 +607,7 @@ static int read_btree_roots(struct bch_fs *c)
buf.buf, bch2_err_str(ret))) {
if (btree_id_is_alloc(i))
r->error = 0;
+ ret = 0;
}
}
@@ -1141,7 +1142,7 @@ fsck_err:
struct printbuf buf = PRINTBUF;
bch2_log_msg_start(c, &buf);
- prt_printf(&buf, "error in recovery: %s", bch2_err_str(ret));
+ prt_printf(&buf, "error in recovery: %s\n", bch2_err_str(ret));
bch2_fs_emergency_read_only2(c, &buf);
bch2_print_str(c, KERN_ERR, buf.buf);
diff --git a/libbcachefs/sb-errors_format.h b/libbcachefs/sb-errors_format.h
index f1aa4054..bb1eddd6 100644
--- a/libbcachefs/sb-errors_format.h
+++ b/libbcachefs/sb-errors_format.h
@@ -3,9 +3,10 @@
#define _BCACHEFS_SB_ERRORS_FORMAT_H
enum bch_fsck_flags {
- FSCK_CAN_FIX = 1 << 0,
- FSCK_CAN_IGNORE = 1 << 1,
- FSCK_AUTOFIX = 1 << 2,
+ FSCK_CAN_FIX = BIT(0),
+ FSCK_CAN_IGNORE = BIT(1),
+ FSCK_AUTOFIX = BIT(2),
+ FSCK_ERR_NO_LOG = BIT(3),
};
#define BCH_SB_ERRS() \
@@ -278,7 +279,7 @@ enum bch_fsck_flags {
x(root_subvol_missing, 238, 0) \
x(root_dir_missing, 239, 0) \
x(root_inode_not_dir, 240, 0) \
- x(dir_loop, 241, 0) \
+ x(dir_loop, 241, FSCK_AUTOFIX) \
x(hash_table_key_duplicate, 242, FSCK_AUTOFIX) \
x(hash_table_key_wrong_offset, 243, FSCK_AUTOFIX) \
x(unlinked_inode_not_on_deleted_list, 244, FSCK_AUTOFIX) \
@@ -295,7 +296,7 @@ enum bch_fsck_flags {
x(subvol_root_fs_path_parent_nonzero, 255, 0) \
x(subvol_children_not_set, 256, 0) \
x(subvol_children_bad, 257, 0) \
- x(subvol_loop, 258, 0) \
+ x(subvol_loop, 258, FSCK_AUTOFIX) \
x(subvol_unreachable, 259, FSCK_AUTOFIX) \
x(btree_node_bkey_bad_u64s, 260, 0) \
x(btree_node_topology_empty_interior_node, 261, 0) \
diff --git a/libbcachefs/sb-members.h b/libbcachefs/sb-members.h
index 8d8a8a85..5dcc2017 100644
--- a/libbcachefs/sb-members.h
+++ b/libbcachefs/sb-members.h
@@ -240,6 +240,10 @@ static inline struct bch_dev *bch2_dev_tryget_noerror(struct bch_fs *c, unsigned
return ca;
}
+DEFINE_CLASS(bch2_dev_tryget_noerror, struct bch_dev *,
+ bch2_dev_put(_T), bch2_dev_tryget_noerror(c, dev),
+ struct bch_fs *c, unsigned dev);
+
static inline struct bch_dev *bch2_dev_tryget(struct bch_fs *c, unsigned dev)
{
struct bch_dev *ca = bch2_dev_tryget_noerror(c, dev);
@@ -248,6 +252,10 @@ static inline struct bch_dev *bch2_dev_tryget(struct bch_fs *c, unsigned dev)
return ca;
}
+DEFINE_CLASS(bch2_dev_tryget, struct bch_dev *,
+ bch2_dev_put(_T), bch2_dev_tryget(c, dev),
+ struct bch_fs *c, unsigned dev);
+
static inline struct bch_dev *bch2_dev_bucket_tryget_noerror(struct bch_fs *c, struct bpos bucket)
{
struct bch_dev *ca = bch2_dev_tryget_noerror(c, bucket.inode);
@@ -258,6 +266,10 @@ static inline struct bch_dev *bch2_dev_bucket_tryget_noerror(struct bch_fs *c, s
return ca;
}
+DEFINE_CLASS(bch2_dev_bucket_tryget_noerror, struct bch_dev *,
+ bch2_dev_put(_T), bch2_dev_bucket_tryget_noerror(c, bucket),
+ struct bch_fs *c, struct bpos bucket);
+
void bch2_dev_bucket_missing(struct bch_dev *, u64);
static inline struct bch_dev *bch2_dev_bucket_tryget(struct bch_fs *c, struct bpos bucket)
@@ -271,6 +283,10 @@ static inline struct bch_dev *bch2_dev_bucket_tryget(struct bch_fs *c, struct bp
return ca;
}
+DEFINE_CLASS(bch2_dev_bucket_tryget, struct bch_dev *,
+ bch2_dev_put(_T), bch2_dev_bucket_tryget(c, bucket),
+ struct bch_fs *c, struct bpos bucket);
+
static inline struct bch_dev *bch2_dev_iterate_noerror(struct bch_fs *c, struct bch_dev *ca, unsigned dev_idx)
{
if (ca && ca->dev_idx == dev_idx)
diff --git a/libbcachefs/str_hash.c b/libbcachefs/str_hash.c
index 71b735a8..3e9f5922 100644
--- a/libbcachefs/str_hash.c
+++ b/libbcachefs/str_hash.c
@@ -38,6 +38,7 @@ static int bch2_fsck_rename_dirent(struct btree_trans *trans,
struct bkey_s_c_dirent old,
bool *updated_before_k_pos)
{
+ struct bch_fs *c = trans->c;
struct qstr old_name = bch2_dirent_get_name(old);
struct bkey_i_dirent *new = bch2_trans_kmalloc(trans, BKEY_U64s_MAX * sizeof(u64));
int ret = PTR_ERR_OR_ZERO(new);
@@ -60,7 +61,7 @@ static int bch2_fsck_rename_dirent(struct btree_trans *trans,
sprintf(renamed_buf, "%.*s.fsck_renamed-%u",
old_name.len, old_name.name, i));
- ret = bch2_dirent_init_name(new, hash_info, &renamed_name, NULL);
+ ret = bch2_dirent_init_name(c, new, hash_info, &renamed_name, NULL);
if (ret)
return ret;
@@ -79,7 +80,7 @@ static int bch2_fsck_rename_dirent(struct btree_trans *trans,
}
ret = ret ?: bch2_fsck_update_backpointers(trans, s, desc, hash_info, &new->k_i);
- bch_err_fn(trans->c, ret);
+ bch_err_fn(c, ret);
return ret;
}
diff --git a/libbcachefs/str_hash.h b/libbcachefs/str_hash.h
index 79d51aef..a49376df 100644
--- a/libbcachefs/str_hash.h
+++ b/libbcachefs/str_hash.h
@@ -48,7 +48,7 @@ bch2_hash_info_init(struct bch_fs *c, const struct bch_inode_unpacked *bi)
struct bch_hash_info info = {
.inum_snapshot = bi->bi_snapshot,
.type = INODE_STR_HASH(bi),
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
.cf_encoding = bch2_inode_casefold(c, bi) ? c->cf_encoding : NULL,
#endif
.siphash_key = { .k0 = bi->bi_hash_seed }
diff --git a/libbcachefs/super.c b/libbcachefs/super.c
index 69c097ff..b2fcae49 100644
--- a/libbcachefs/super.c
+++ b/libbcachefs/super.c
@@ -585,7 +585,7 @@ static void __bch2_fs_free(struct bch_fs *c)
for (unsigned i = 0; i < BCH_TIME_STAT_NR; i++)
bch2_time_stats_exit(&c->times[i]);
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
utf8_unload(c->cf_encoding);
#endif
@@ -1024,7 +1024,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts,
goto err;
}
-#ifdef CONFIG_UNICODE
+#if IS_ENABLED(CONFIG_UNICODE)
/* Default encoding until we can potentially have more as an option. */
c->cf_encoding = utf8_load(BCH_FS_DEFAULT_UTF8_ENCODING);
if (IS_ERR(c->cf_encoding)) {
@@ -1160,12 +1160,11 @@ int bch2_fs_start(struct bch_fs *c)
print_mount_opts(c);
-#ifdef CONFIG_UNICODE
- bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u",
- unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
- unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
- unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
-#endif
+ if (IS_ENABLED(CONFIG_UNICODE))
+ bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u",
+ unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
+ unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
+ unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
if (!bch2_fs_may_start(c))
return bch_err_throw(c, insufficient_devices_to_start);