mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-09 00:00:17 +03:00
Update bcachefs sources to e6e58342e3ed bcachefs: Make sure opt_version_init() message gets logged before recovery
Some checks failed
build / bcachefs-tools-msrv (push) Has been cancelled
.deb build orchestrator / source-only (push) Has been cancelled
.deb build orchestrator / obs (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:plucky], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:plucky], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:questing], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:questing], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / reprotest (push) Has been cancelled
.deb build orchestrator / publish (push) Has been cancelled
Nix Flake actions / nix-matrix (push) Has been cancelled
Nix Flake actions / ${{ matrix.name }} (${{ matrix.system }}) (push) Has been cancelled
Some checks failed
build / bcachefs-tools-msrv (push) Has been cancelled
.deb build orchestrator / source-only (push) Has been cancelled
.deb build orchestrator / obs (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:plucky], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:plucky], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:questing], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:questing], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / reprotest (push) Has been cancelled
.deb build orchestrator / publish (push) Has been cancelled
Nix Flake actions / nix-matrix (push) Has been cancelled
Nix Flake actions / ${{ matrix.name }} (${{ matrix.system }}) (push) Has been cancelled
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
1096ea92d7
commit
b55368a5c0
@ -1 +1 @@
|
||||
59769576332d7d8685c85ccc68cf0554bd7c3024
|
||||
e6e58342e3ed07f712c7f13489fd333c24e3975e
|
||||
|
||||
@ -71,10 +71,10 @@ int cmd_reset_counters(int argc, char *argv[])
|
||||
|
||||
if (!to_reset.nr) {
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++)
|
||||
percpu_u64_set(&c->counters[i], 0);
|
||||
percpu_u64_set(&c->counters.now[i], 0);
|
||||
} else {
|
||||
darray_for_each(to_reset, i)
|
||||
percpu_u64_set(&c->counters[*i], 0);
|
||||
percpu_u64_set(&c->counters.now[*i], 0);
|
||||
}
|
||||
|
||||
scoped_guard(mutex, &c->sb_lock)
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "init/progress.h"
|
||||
#include "init/recovery.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "util/clock.h"
|
||||
#include "util/enumerated_ref.h"
|
||||
#include "util/varint.h"
|
||||
@ -1451,7 +1453,7 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
|
||||
bch2_btree_delete_range(c, BTREE_ID_alloc, start, end,
|
||||
BTREE_TRIGGER_norun) ?:
|
||||
bch2_dev_usage_remove(c, ca);
|
||||
bch_err_msg(ca, ret, "removing dev alloc info");
|
||||
bch_err_msg_dev(ca, ret, "removing dev alloc info");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -729,8 +729,8 @@ int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
*/
|
||||
while (bkey_lt(iter.pos, end)) {
|
||||
if (time_after(jiffies, last_updated + HZ * 10)) {
|
||||
bch_info(ca, "%s: currently at %llu/%llu",
|
||||
__func__, iter.pos.offset, ca->mi.nbuckets);
|
||||
bch_info_dev(ca, "%s: currently at %llu/%llu",
|
||||
__func__, iter.pos.offset, ca->mi.nbuckets);
|
||||
last_updated = jiffies;
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,11 @@
|
||||
#include "data/write.h"
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "journal/journal.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "util/clock.h"
|
||||
|
||||
#include <linux/math64.h>
|
||||
|
||||
@ -261,20 +261,13 @@
|
||||
|
||||
#include "journal/types.h"
|
||||
|
||||
#include "sb/counters_types.h"
|
||||
#include "sb/errors_types.h"
|
||||
#include "sb/members_types.h"
|
||||
|
||||
#include "snapshots/snapshot_types.h"
|
||||
#include "snapshots/subvolume_types.h"
|
||||
|
||||
#define count_event(_c, _name) this_cpu_inc((_c)->counters[BCH_COUNTER_##_name])
|
||||
|
||||
#define trace_and_count(_c, _name, ...) \
|
||||
do { \
|
||||
count_event(_c, _name); \
|
||||
trace_##_name(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define bch2_fs_init_fault(name) \
|
||||
dynamic_fault("bcachefs:bch_fs_init:" name)
|
||||
#define bch2_meta_read_fault(name) \
|
||||
@ -288,8 +281,8 @@ do { \
|
||||
|
||||
#ifdef BCACHEFS_LOG_PREFIX
|
||||
|
||||
#define bch2_log_msg(_c, fmt) "bcachefs (%s): " fmt, ((_c)->name)
|
||||
#define bch2_fmt_dev(_ca, fmt) "bcachefs (%s): " fmt "\n", ((_ca)->name)
|
||||
#define bch2_log_msg(_c, fmt) "bcachefs (%s): " fmt, bch2_fs_name(_c)
|
||||
#define bch2_fmt_dev(_ca, fmt) "bcachefs (%s): " fmt "\n", bch2_dev_name(_ca)
|
||||
#define bch2_fmt_dev_offset(_ca, _offset, fmt) "bcachefs (%s sector %llu): " fmt "\n", ((_ca)->name), (_offset)
|
||||
#define bch2_fmt_inum(_c, _inum, fmt) "bcachefs (%s inum %llu): " fmt "\n", ((_c)->name), (_inum)
|
||||
#define bch2_fmt_inum_offset(_c, _inum, _offset, fmt) \
|
||||
@ -357,6 +350,10 @@ do { \
|
||||
#define bch_verbose(c, ...) bch_log(c, KERN_DEBUG, __VA_ARGS__)
|
||||
#define bch_verbose_ratelimited(c, ...) bch_log_ratelimited(c, KERN_DEBUG, __VA_ARGS__)
|
||||
|
||||
#define bch_info_dev(ca, fmt, ...) \
|
||||
bch2_print(c, KERN_INFO bch2_fmt_dev(ca, fmt), ##__VA_ARGS__)
|
||||
#define bch_notice_dev(ca, fmt, ...) \
|
||||
bch2_print(c, KERN_NOTICE bch2_fmt_dev(ca, fmt), ##__VA_ARGS__)
|
||||
#define bch_err_dev(ca, fmt, ...) \
|
||||
bch2_print(c, KERN_ERR bch2_fmt_dev(ca, fmt), ##__VA_ARGS__)
|
||||
#define bch_err_dev_offset(ca, _offset, fmt, ...) \
|
||||
@ -399,6 +396,19 @@ do { \
|
||||
##__VA_ARGS__, bch2_err_str(_ret)); \
|
||||
} while (0)
|
||||
|
||||
#define bch_err_fn_dev(_ca, _ret) \
|
||||
do { \
|
||||
if (should_print_err(_ret)) \
|
||||
bch_err_dev(_ca, "%s(): error %s", __func__, bch2_err_str(_ret));\
|
||||
} while (0)
|
||||
|
||||
#define bch_err_msg_dev(_ca, _ret, _msg, ...) \
|
||||
do { \
|
||||
if (should_print_err(_ret)) \
|
||||
bch_err_dev(_ca, "%s(): error " _msg " %s", __func__, \
|
||||
##__VA_ARGS__, bch2_err_str(_ret)); \
|
||||
} while (0)
|
||||
|
||||
/* Parameters that are useful for debugging, but should always be compiled in: */
|
||||
#define BCH_DEBUG_PARAMS_ALWAYS() \
|
||||
BCH_DEBUG_PARAM(key_merging_disabled, \
|
||||
@ -934,7 +944,6 @@ struct bch_fs {
|
||||
bool btree_trans_barrier_initialized;
|
||||
|
||||
struct btree_key_cache btree_key_cache;
|
||||
unsigned btree_key_cache_btrees;
|
||||
|
||||
struct btree_write_buffer btree_write_buffer;
|
||||
|
||||
@ -949,6 +958,9 @@ struct bch_fs {
|
||||
*/
|
||||
struct workqueue_struct *write_ref_wq;
|
||||
|
||||
struct workqueue_struct *promote_wq;
|
||||
struct semaphore __percpu *promote_limit;
|
||||
|
||||
/* ALLOCATION */
|
||||
struct bch_devs_mask online_devs;
|
||||
struct bch_devs_mask rw_devs[BCH_DATA_NR];
|
||||
@ -1034,7 +1046,6 @@ struct bch_fs {
|
||||
struct mutex gc_gens_lock;
|
||||
|
||||
/* IO PATH */
|
||||
struct semaphore io_in_flight;
|
||||
struct bio_set bio_read;
|
||||
struct bio_set bio_read_split;
|
||||
struct bio_set bio_write;
|
||||
@ -1147,8 +1158,7 @@ struct bch_fs {
|
||||
|
||||
u64 last_bucket_seq_cleanup;
|
||||
|
||||
u64 counters_on_mount[BCH_COUNTER_NR];
|
||||
u64 __percpu *counters;
|
||||
struct bch_fs_counters counters;
|
||||
|
||||
struct bch2_time_stats times[BCH_TIME_STAT_NR];
|
||||
|
||||
@ -1165,7 +1175,7 @@ struct bch_fs {
|
||||
|
||||
static inline int __bch2_err_trace(struct bch_fs *c, int err)
|
||||
{
|
||||
this_cpu_inc(c->counters[BCH_COUNTER_error_throw]);
|
||||
this_cpu_inc(c->counters.now[BCH_COUNTER_error_throw]);
|
||||
trace_error_throw(c, err, _THIS_IP_);
|
||||
return err;
|
||||
}
|
||||
@ -1209,11 +1219,6 @@ static inline unsigned block_sectors(const struct bch_fs *c)
|
||||
return c->opts.block_size >> 9;
|
||||
}
|
||||
|
||||
static inline bool btree_id_cached(const struct bch_fs *c, enum btree_id btree)
|
||||
{
|
||||
return c->btree_key_cache_btrees & (1U << btree);
|
||||
}
|
||||
|
||||
static inline struct timespec64 bch2_time_to_timespec(const struct bch_fs *c, s64 time)
|
||||
{
|
||||
struct timespec64 t;
|
||||
@ -1301,4 +1306,14 @@ static inline const char *strip_bch2(const char *msg)
|
||||
return msg;
|
||||
}
|
||||
|
||||
static inline const char *bch2_fs_name(const struct bch_fs *c)
|
||||
{
|
||||
return c->name;
|
||||
}
|
||||
|
||||
static inline const char *bch2_dev_name(const struct bch_dev *ca)
|
||||
{
|
||||
return ca->name;
|
||||
}
|
||||
|
||||
#endif /* _BCACHEFS_H */
|
||||
|
||||
@ -860,7 +860,6 @@ LE64_BITMASK(BCH_SB_GC_RESERVE_BYTES, struct bch_sb, flags[2], 4, 64);
|
||||
LE64_BITMASK(BCH_SB_ERASURE_CODE, struct bch_sb, flags[3], 0, 16);
|
||||
LE64_BITMASK(BCH_SB_METADATA_TARGET, struct bch_sb, flags[3], 16, 28);
|
||||
LE64_BITMASK(BCH_SB_SHARD_INUMS, struct bch_sb, flags[3], 28, 29);
|
||||
LE64_BITMASK(BCH_SB_INODES_USE_KEY_CACHE,struct bch_sb, flags[3], 29, 30);
|
||||
LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DELAY,struct bch_sb, flags[3], 30, 62);
|
||||
LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DISABLED,struct bch_sb, flags[3], 62, 63);
|
||||
LE64_BITMASK(BCH_SB_MULTI_DEVICE, struct bch_sb, flags[3], 63, 64);
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
#include "journal/journal.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
|
||||
#include "journal/journal.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "sb/io.h"
|
||||
|
||||
#include "util/enumerated_ref.h"
|
||||
@ -216,6 +217,7 @@ static int btree_check_node_boundaries(struct btree_trans *trans, struct btree *
|
||||
|
||||
prt_str(&buf, "\nnext: ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&cur->key));
|
||||
prt_newline(&buf);
|
||||
|
||||
if (bpos_lt(expected_start, cur->data->min_key)) { /* gap */
|
||||
size_t nodes_found = 0;
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "snapshots/snapshot.h"
|
||||
|
||||
#include "util/enumerated_ref.h"
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include "journal/journal.h"
|
||||
#include "journal/reclaim.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "sb/members.h"
|
||||
#include "sb/io.h"
|
||||
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "journal/journal.h"
|
||||
#include "journal/read.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "snapshots/snapshot.h"
|
||||
|
||||
#include <linux/random.h>
|
||||
@ -3219,7 +3221,7 @@ void __bch2_trans_node_iter_init(struct btree_trans *trans,
|
||||
flags |= BTREE_ITER_snapshot_field;
|
||||
flags |= BTREE_ITER_all_snapshots;
|
||||
|
||||
if (!depth && btree_id_cached(trans->c, btree_id))
|
||||
if (!depth && btree_id_cached(btree_id))
|
||||
flags |= BTREE_ITER_with_key_cache;
|
||||
|
||||
bch2_trans_iter_init_common(trans, iter, btree_id, pos, locks_want, depth,
|
||||
@ -3348,9 +3350,15 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size, unsigned long
|
||||
|
||||
static inline void check_srcu_held_too_long(struct btree_trans *trans)
|
||||
{
|
||||
WARN(trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10),
|
||||
"btree trans held srcu lock (delaying memory reclaim) for %lu seconds",
|
||||
(jiffies - trans->srcu_lock_time) / HZ);
|
||||
if (unlikely(trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10))) {
|
||||
CLASS(printbuf, buf)();
|
||||
|
||||
prt_printf(&buf, "btree trans held srcu lock (delaying memory reclaim) for %lu seconds\n",
|
||||
(jiffies - trans->srcu_lock_time) / HZ);
|
||||
bch2_sb_recent_counters_to_text(&buf, &trans->c->counters);
|
||||
|
||||
WARN(true, "%s", buf.buf);
|
||||
}
|
||||
}
|
||||
|
||||
void bch2_trans_srcu_unlock(struct btree_trans *trans)
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
#include "btree/bset.h"
|
||||
#include "btree/types.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *);
|
||||
void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *,
|
||||
btree_path_idx_t, struct btree_path *);
|
||||
@ -485,12 +487,20 @@ static inline void bch2_btree_iter_set_snapshot(struct btree_iter *iter, u32 sna
|
||||
|
||||
void bch2_trans_iter_exit(struct btree_iter *);
|
||||
|
||||
static inline bool btree_id_cached(enum btree_id btree)
|
||||
{
|
||||
return BIT_ULL(btree) &
|
||||
(BIT_ULL(BTREE_ID_alloc)|
|
||||
BIT_ULL(BTREE_ID_inodes)|
|
||||
BIT_ULL(BTREE_ID_logged_ops));
|
||||
}
|
||||
|
||||
static inline enum btree_iter_update_trigger_flags
|
||||
bch2_btree_iter_flags(struct btree_trans *trans,
|
||||
unsigned btree_id, unsigned level,
|
||||
enum btree_iter_update_trigger_flags flags)
|
||||
{
|
||||
if (level || !btree_id_cached(trans->c, btree_id)) {
|
||||
if (level || !btree_id_cached(btree_id)) {
|
||||
flags &= ~BTREE_ITER_cached;
|
||||
flags &= ~BTREE_ITER_with_key_cache;
|
||||
} else if (!(flags & BTREE_ITER_cached))
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include "bcachefs.h"
|
||||
|
||||
#include "btree/cache.h"
|
||||
#include "btree/locking.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
static struct lock_class_key bch2_btree_node_lock_key;
|
||||
|
||||
void bch2_btree_lock_init(struct btree_bkey_cached_common *b,
|
||||
|
||||
@ -254,8 +254,8 @@ static int read_btree_nodes_worker(void *p)
|
||||
buckets_scanned++;
|
||||
|
||||
if (time_after(jiffies, last_print + HZ * 30)) {
|
||||
bch_info(ca, "%s: %2u%% done", __func__,
|
||||
(unsigned) div64_u64(buckets_scanned * 100, buckets_to_scan));
|
||||
bch_info_dev(ca, "%s: %2u%% done", __func__,
|
||||
(unsigned) div64_u64(buckets_scanned * 100, buckets_to_scan));
|
||||
last_print = jiffies;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
|
||||
#include "journal/seq_blacklist.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "sb/io.h"
|
||||
|
||||
#include "util/enumerated_ref.h"
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "snapshots/snapshot.h"
|
||||
|
||||
#include <linux/string_helpers.h>
|
||||
@ -507,7 +509,7 @@ int __must_check bch2_trans_update_ip(struct btree_trans *trans, struct btree_it
|
||||
if (!(flags & BTREE_UPDATE_key_cache_reclaim) &&
|
||||
!path->cached &&
|
||||
!path->level &&
|
||||
btree_id_cached(trans->c, path->btree_id)) {
|
||||
btree_id_cached(path->btree_id)) {
|
||||
try(bch2_trans_update_get_key_cache(trans, iter, path));
|
||||
|
||||
path_idx = iter->key_cache_path;
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "journal/reclaim.h"
|
||||
|
||||
static void bch2_btree_complete_write(struct bch_fs *c, struct btree *b,
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "util/enumerated_ref.h"
|
||||
|
||||
#include <linux/prefetch.h>
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "util/clock.h"
|
||||
|
||||
#include <linux/freezer.h>
|
||||
|
||||
@ -26,11 +26,12 @@
|
||||
#include "data/keylist.h"
|
||||
#include "data/reconcile.h"
|
||||
|
||||
#include "sb/io.h"
|
||||
|
||||
#include "init/error.h"
|
||||
#include "init/recovery.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "sb/io.h"
|
||||
|
||||
#include "util/enumerated_ref.h"
|
||||
#include "util/util.h"
|
||||
|
||||
@ -618,7 +619,7 @@ static void ec_validate_checksums(struct bch_fs *c, struct ec_stripe_buf *buf)
|
||||
bch2_csum_err_msg(&err, v->csum_type, want, got);
|
||||
prt_printf(&err, " for %ps at %u of\n ", (void *) _RET_IP_, i);
|
||||
bch2_bkey_val_to_text(&err, c, bkey_i_to_s_c(&buf->key));
|
||||
bch_err_ratelimited(ca, "%s", err.buf);
|
||||
bch_err_dev_ratelimited(ca, "%s", err.buf);
|
||||
|
||||
bch2_io_error(ca, BCH_MEMBER_ERROR_checksum);
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include "journal/reclaim.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "sb/io.h"
|
||||
|
||||
#include "snapshots/snapshot.h"
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
#include "init/error.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "snapshots/subvolume.h"
|
||||
|
||||
#include "util/clock.h"
|
||||
@ -223,6 +225,8 @@ static noinline void promote_free(struct bch_read_bio *rbio, int ret)
|
||||
async_object_list_del(c, promote, op->list_idx);
|
||||
async_object_list_del(c, rbio, rbio->list_idx);
|
||||
|
||||
up(per_cpu_ptr(c->promote_limit, op->cpu));
|
||||
|
||||
bch2_data_update_exit(&op->write, ret);
|
||||
|
||||
enumerated_ref_put(&c->writes, BCH_WRITE_REF_promote);
|
||||
@ -252,7 +256,7 @@ static noinline void promote_start(struct bch_read_bio *rbio)
|
||||
trace_and_count(op->write.op.c, io_read_promote, &rbio->bio);
|
||||
|
||||
INIT_WORK(&op->work, promote_start_work);
|
||||
queue_work(rbio->c->write_ref_wq, &op->work);
|
||||
queue_work(rbio->c->promote_wq, &op->work);
|
||||
}
|
||||
|
||||
static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
|
||||
@ -299,16 +303,23 @@ static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
|
||||
}
|
||||
|
||||
if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_promote))
|
||||
return ERR_PTR(-BCH_ERR_nopromote_no_writes);
|
||||
return ERR_PTR(bch_err_throw(c, nopromote_no_writes));
|
||||
|
||||
int cpu = raw_smp_processor_id();
|
||||
if (down_trylock(per_cpu_ptr(c->promote_limit, cpu))) {
|
||||
ret = bch_err_throw(c, nopromote_ratelimited);
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
struct promote_op *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||
if (!op) {
|
||||
ret = bch_err_throw(c, nopromote_enomem);
|
||||
goto err_put;
|
||||
goto err_up_limit;
|
||||
}
|
||||
|
||||
op->start_time = local_clock();
|
||||
op->pos = pos;
|
||||
op->cpu = cpu;
|
||||
|
||||
if (rhashtable_lookup_insert_fast(&c->promote_table, &op->hash,
|
||||
bch_promote_params)) {
|
||||
@ -347,6 +358,8 @@ err:
|
||||
bch2_bio_free_pages_pool(c, &op->write.op.wbio.bio);
|
||||
/* We may have added to the rhashtable and thus need rcu freeing: */
|
||||
kfree_rcu(op, rcu);
|
||||
err_up_limit:
|
||||
up(per_cpu_ptr(c->promote_limit, cpu));
|
||||
err_put:
|
||||
enumerated_ref_put(&c->writes, BCH_WRITE_REF_promote);
|
||||
return ERR_PTR(ret);
|
||||
@ -659,7 +672,7 @@ static void bch2_rbio_retry(struct work_struct *work)
|
||||
struct bch_io_failures failed = { .nr = 0 };
|
||||
|
||||
trace_io_read_retry(&rbio->bio);
|
||||
this_cpu_add(c->counters[BCH_COUNTER_io_read_retry],
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_io_read_retry],
|
||||
bvec_iter_sectors(rbio->bvec_iter));
|
||||
|
||||
{
|
||||
@ -829,7 +842,7 @@ static void bch2_read_decompress_err(struct work_struct *work)
|
||||
|
||||
struct bch_dev *ca = rbio->have_ioref ? bch2_dev_have_ref(c, rbio->pick.ptr.dev) : NULL;
|
||||
if (ca)
|
||||
bch_err_ratelimited(ca, "%s", buf.buf);
|
||||
bch_err_dev_ratelimited(ca, "%s", buf.buf);
|
||||
else
|
||||
bch_err_ratelimited(c, "%s", buf.buf);
|
||||
|
||||
@ -848,7 +861,7 @@ static void bch2_read_decrypt_err(struct work_struct *work)
|
||||
|
||||
struct bch_dev *ca = rbio->have_ioref ? bch2_dev_have_ref(c, rbio->pick.ptr.dev) : NULL;
|
||||
if (ca)
|
||||
bch_err_ratelimited(ca, "%s", buf.buf);
|
||||
bch_err_dev_ratelimited(ca, "%s", buf.buf);
|
||||
else
|
||||
bch_err_ratelimited(c, "%s", buf.buf);
|
||||
|
||||
@ -1100,7 +1113,7 @@ int __bch2_read_extent(struct btree_trans *trans, struct bch_read_bio *orig,
|
||||
swap(iter.bi_size, bytes);
|
||||
bio_advance_iter(&orig->bio, &iter, bytes);
|
||||
zero_fill_bio_iter(&orig->bio, iter);
|
||||
this_cpu_add(c->counters[BCH_COUNTER_io_read_inline],
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_io_read_inline],
|
||||
bvec_iter_sectors(iter));
|
||||
goto out_read_done;
|
||||
}
|
||||
@ -1304,9 +1317,9 @@ retry_pick:
|
||||
trace_and_count(c, io_read_bounce, &rbio->bio);
|
||||
|
||||
if (!u)
|
||||
this_cpu_add(c->counters[BCH_COUNTER_io_read], bio_sectors(&rbio->bio));
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_io_read], bio_sectors(&rbio->bio));
|
||||
else
|
||||
this_cpu_add(c->counters[BCH_COUNTER_io_move_read], bio_sectors(&rbio->bio));
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_io_move_read], bio_sectors(&rbio->bio));
|
||||
bch2_increment_clock(c, bio_sectors(&rbio->bio), READ);
|
||||
|
||||
/*
|
||||
@ -1400,7 +1413,7 @@ err:
|
||||
goto out_read_done;
|
||||
|
||||
hole:
|
||||
this_cpu_add(c->counters[BCH_COUNTER_io_read_hole],
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_io_read_hole],
|
||||
bvec_iter_sectors(iter));
|
||||
/*
|
||||
* won't normally happen in the data update (bch2_move_extent()) path,
|
||||
@ -1592,6 +1605,7 @@ void bch2_fs_io_read_exit(struct bch_fs *c)
|
||||
bioset_exit(&c->bio_read_split);
|
||||
bioset_exit(&c->bio_read);
|
||||
mempool_exit(&c->bio_bounce_bufs);
|
||||
free_percpu(c->promote_limit);
|
||||
}
|
||||
|
||||
static void *bio_bounce_buf_alloc_fn(gfp_t gfp, void *pool_data)
|
||||
@ -1606,6 +1620,14 @@ static void bio_bounce_buf_free_fn(void *p, void *pool_data)
|
||||
|
||||
int bch2_fs_io_read_init(struct bch_fs *c)
|
||||
{
|
||||
c->promote_limit = alloc_percpu(struct semaphore);
|
||||
if (!c->promote_limit)
|
||||
return bch_err_throw(c, ENOMEM_promote_limit_init);
|
||||
|
||||
int cpu;
|
||||
for_each_possible_cpu(cpu)
|
||||
sema_init(per_cpu_ptr(c->promote_limit, cpu), 32);
|
||||
|
||||
if (mempool_init(&c->bio_bounce_bufs,
|
||||
max_t(unsigned,
|
||||
c->opts.btree_node_size,
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "fs/inode.h"
|
||||
#include "fs/namei.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "snapshots/subvolume.h"
|
||||
|
||||
#include "util/clock.h"
|
||||
|
||||
@ -147,6 +147,12 @@ static inline void bch2_reconcile_wakeup(struct bch_fs *c)
|
||||
wake_up_process(p);
|
||||
}
|
||||
|
||||
static inline int bch2_reconcile_pending_wakeup(struct bch_fs *c)
|
||||
{
|
||||
return bch2_set_reconcile_needs_scan(c,
|
||||
(struct reconcile_scan) { .type = RECONCILE_SCAN_pending}, true);
|
||||
}
|
||||
|
||||
void bch2_reconcile_status_to_text(struct printbuf *, struct bch_fs *);
|
||||
void bch2_reconcile_scan_pending_to_text(struct printbuf *, struct bch_fs *);
|
||||
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "init/error.h"
|
||||
#include "init/fs.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "snapshots/snapshot.h"
|
||||
#include "snapshots/subvolume.h"
|
||||
|
||||
@ -307,7 +309,7 @@ static int data_update_index_update_key(struct btree_trans *trans,
|
||||
|
||||
if (trace_data_update_key_enabled())
|
||||
trace_data_update_key2(u, old, k, insert);
|
||||
this_cpu_add(c->counters[BCH_COUNTER_data_update_key], new->k.size);
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_data_update_key], new->k.size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -66,6 +66,7 @@ struct promote_op {
|
||||
#ifdef CONFIG_BCACHEFS_ASYNC_OBJECT_LISTS
|
||||
unsigned list_idx;
|
||||
#endif
|
||||
int cpu; /* for promote_limit */
|
||||
|
||||
struct rhash_head hash;
|
||||
struct bpos pos;
|
||||
|
||||
@ -1721,7 +1721,7 @@ CLOSURE_CALLBACK(bch2_write)
|
||||
}
|
||||
|
||||
if (!(op->flags & BCH_WRITE_move))
|
||||
this_cpu_add(c->counters[BCH_COUNTER_io_write], bio_sectors(bio));
|
||||
this_cpu_add(c->counters.now[BCH_COUNTER_io_write], bio_sectors(bio));
|
||||
bch2_increment_clock(c, bio_sectors(bio), WRITE);
|
||||
|
||||
data_len = min_t(u64, bio->bi_iter.bi_size,
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "journal/journal.h"
|
||||
#include "journal/reclaim.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "sb/errors.h"
|
||||
#include "sb/io.h"
|
||||
|
||||
@ -164,6 +165,7 @@ write_attribute(trigger_btree_updates);
|
||||
write_attribute(trigger_freelist_wakeup);
|
||||
write_attribute(trigger_recalc_capacity);
|
||||
write_attribute(trigger_reconcile_wakeup);
|
||||
write_attribute(trigger_reconcile_pending_wakeup);
|
||||
write_attribute(trigger_delete_dead_snapshots);
|
||||
write_attribute(trigger_emergency_read_only);
|
||||
read_attribute(gc_gens_pos);
|
||||
@ -229,6 +231,8 @@ read_attribute(io_timers_write);
|
||||
|
||||
read_attribute(moving_ctxts);
|
||||
|
||||
read_attribute(recent_counters);
|
||||
|
||||
#ifdef CONFIG_BCACHEFS_TESTS
|
||||
write_attribute(perf_test);
|
||||
#endif /* CONFIG_BCACHEFS_TESTS */
|
||||
@ -386,6 +390,9 @@ SHOW(bch2_fs)
|
||||
if (attr == &sysfs_moving_ctxts)
|
||||
bch2_fs_moving_ctxts_to_text(out, c);
|
||||
|
||||
if (attr == &sysfs_recent_counters)
|
||||
bch2_sb_recent_counters_to_text(out, &c->counters);
|
||||
|
||||
if (attr == &sysfs_write_refs)
|
||||
enumerated_ref_to_text(out, &c->writes, bch2_write_refs);
|
||||
|
||||
@ -477,6 +484,9 @@ STORE(bch2_fs)
|
||||
if (attr == &sysfs_trigger_reconcile_wakeup)
|
||||
bch2_reconcile_wakeup(c);
|
||||
|
||||
if (attr == &sysfs_trigger_reconcile_pending_wakeup)
|
||||
bch2_reconcile_pending_wakeup(c);
|
||||
|
||||
if (attr == &sysfs_trigger_delete_dead_snapshots)
|
||||
__bch2_delete_dead_snapshots(c);
|
||||
|
||||
@ -545,8 +555,8 @@ SHOW(bch2_fs_counters)
|
||||
|
||||
#define x(t, n, f, ...) \
|
||||
if (attr == &sysfs_##t) { \
|
||||
counter = percpu_u64_get(&c->counters[BCH_COUNTER_##t]);\
|
||||
counter_since_mount = counter - c->counters_on_mount[BCH_COUNTER_##t];\
|
||||
counter = percpu_u64_get(&c->counters.now[BCH_COUNTER_##t]);\
|
||||
counter_since_mount = counter - c->counters.mount[BCH_COUNTER_##t];\
|
||||
if (f & TYPE_SECTORS) { \
|
||||
counter <<= 9; \
|
||||
counter_since_mount <<= 9; \
|
||||
@ -625,6 +635,7 @@ struct attribute *bch2_fs_internal_files[] = {
|
||||
&sysfs_trigger_freelist_wakeup,
|
||||
&sysfs_trigger_recalc_capacity,
|
||||
&sysfs_trigger_reconcile_wakeup,
|
||||
&sysfs_trigger_reconcile_pending_wakeup,
|
||||
&sysfs_trigger_delete_dead_snapshots,
|
||||
&sysfs_trigger_emergency_read_only,
|
||||
|
||||
@ -633,6 +644,7 @@ struct attribute *bch2_fs_internal_files[] = {
|
||||
&sysfs_copy_gc_wait,
|
||||
|
||||
&sysfs_moving_ctxts,
|
||||
&sysfs_recent_counters,
|
||||
|
||||
&sysfs_internal_uuid,
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
x(ENOMEM, ENOMEM_bio_read_init) \
|
||||
x(ENOMEM, ENOMEM_bio_read_split_init) \
|
||||
x(ENOMEM, ENOMEM_bio_write_init) \
|
||||
x(ENOMEM, ENOMEM_promote_limit_init) \
|
||||
x(ENOMEM, ENOMEM_bio_bounce_pages_init) \
|
||||
x(ENOMEM, ENOMEM_writepage_bioset_init) \
|
||||
x(ENOMEM, ENOMEM_dio_read_bioset_init) \
|
||||
@ -373,6 +374,7 @@
|
||||
x(BCH_ERR_nopromote, nopromote_already_promoted) \
|
||||
x(BCH_ERR_nopromote, nopromote_unwritten) \
|
||||
x(BCH_ERR_nopromote, nopromote_congested) \
|
||||
x(BCH_ERR_nopromote, nopromote_ratelimited) \
|
||||
x(BCH_ERR_nopromote, nopromote_in_flight) \
|
||||
x(BCH_ERR_nopromote, nopromote_no_writes) \
|
||||
x(BCH_ERR_nopromote, nopromote_enomem) \
|
||||
|
||||
@ -356,7 +356,7 @@ int __bch2_inode_peek(struct btree_trans *trans,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = bkey_is_inode(k.k) ? 0 : -BCH_ERR_ENOENT_inode;
|
||||
ret = bkey_is_inode(k.k) ? 0 : bch_err_throw(trans->c, ENOENT_inode);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -384,20 +384,13 @@ int bch2_inode_find_by_inum_snapshot(struct btree_trans *trans,
|
||||
: -BCH_ERR_ENOENT_inode;
|
||||
}
|
||||
|
||||
int bch2_inode_find_by_inum_nowarn_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
int __bch2_inode_find_by_inum_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode,
|
||||
bool warn)
|
||||
{
|
||||
CLASS(btree_iter_uninit, iter)(trans);
|
||||
return bch2_inode_peek_nowarn(trans, &iter, inode, inum, 0);
|
||||
}
|
||||
|
||||
int bch2_inode_find_by_inum_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
CLASS(btree_iter_uninit, iter)(trans);
|
||||
return bch2_inode_peek(trans, &iter, inode, inum, 0);
|
||||
return __bch2_inode_peek(trans, &iter, inode, inum, 0, warn);
|
||||
}
|
||||
|
||||
int bch2_inode_find_by_inum(struct bch_fs *c, subvol_inum inum,
|
||||
|
||||
@ -137,11 +137,24 @@ static inline int bch2_inode_peek(struct btree_trans *trans,
|
||||
|
||||
int bch2_inode_find_by_inum_snapshot(struct btree_trans *, u64, u32,
|
||||
struct bch_inode_unpacked *, unsigned);
|
||||
int bch2_inode_find_by_inum_nowarn_trans(struct btree_trans *,
|
||||
subvol_inum,
|
||||
struct bch_inode_unpacked *);
|
||||
int bch2_inode_find_by_inum_trans(struct btree_trans *, subvol_inum,
|
||||
struct bch_inode_unpacked *);
|
||||
|
||||
int __bch2_inode_find_by_inum_trans(struct btree_trans *, subvol_inum,
|
||||
struct bch_inode_unpacked *, bool);
|
||||
|
||||
static inline int bch2_inode_find_by_inum_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
return __bch2_inode_find_by_inum_trans(trans, inum, inode, true);
|
||||
}
|
||||
|
||||
static inline int bch2_inode_find_by_inum_nowarn_trans(struct btree_trans *trans,
|
||||
subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
return __bch2_inode_find_by_inum_trans(trans, inum, inode, false);
|
||||
}
|
||||
|
||||
int bch2_inode_find_by_inum(struct bch_fs *, subvol_inum,
|
||||
struct bch_inode_unpacked *);
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ static long bch2_ioctl_disk_remove(struct bch_fs *c, struct bch_ioctl_disk arg)
|
||||
CLASS(printbuf, err)();
|
||||
int ret = bch2_dev_remove(c, ca, arg.flags, &err);
|
||||
if (ret)
|
||||
bch_err(ca, "%s", err.buf);
|
||||
bch_err_dev(ca, "%s", err.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ static long bch2_ioctl_disk_offline(struct bch_fs *c, struct bch_ioctl_disk arg)
|
||||
CLASS(printbuf, err)();
|
||||
int ret = bch2_dev_offline(c, ca, arg.flags, &err);
|
||||
if (ret)
|
||||
bch_err(ca, "%s", err.buf);
|
||||
bch_err_dev(ca, "%s", err.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ static long bch2_ioctl_disk_set_state(struct bch_fs *c,
|
||||
|
||||
CLASS(printbuf, err)();
|
||||
int ret = bch2_dev_set_state(c, ca, arg.new_state, arg.flags, &err);
|
||||
bch_err_msg(ca, ret, "setting device state");
|
||||
bch_err_msg_dev(ca, ret, "setting device state");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -605,7 +605,7 @@ static long bch2_ioctl_disk_resize(struct bch_fs *c,
|
||||
CLASS(printbuf, err)();
|
||||
int ret = bch2_dev_resize(c, ca, arg.nbuckets, &err);
|
||||
if (ret)
|
||||
bch_err(ca, "%s", err.buf);
|
||||
bch_err_dev(ca, "%s", err.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -570,7 +570,7 @@ int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca,
|
||||
if (new_state != BCH_MEMBER_STATE_rw)
|
||||
__bch2_dev_read_only(c, ca);
|
||||
|
||||
bch_notice(ca, "%s", bch2_member_states[new_state]);
|
||||
bch_notice_dev(ca, "%s", bch2_member_states[new_state]);
|
||||
|
||||
bool do_reconcile_scan =
|
||||
new_state == BCH_MEMBER_STATE_rw ||
|
||||
|
||||
@ -614,6 +614,8 @@ static void __bch2_fs_free(struct bch_fs *c)
|
||||
kfree(rcu_dereference_protected(c->disk_groups, 1));
|
||||
kfree(c->journal_seq_blacklist_table);
|
||||
|
||||
if (c->promote_wq)
|
||||
destroy_workqueue(c->promote_wq);
|
||||
if (c->write_ref_wq)
|
||||
destroy_workqueue(c->write_ref_wq);
|
||||
if (c->btree_write_submit_wq)
|
||||
@ -761,7 +763,9 @@ int bch2_fs_init_rw(struct bch_fs *c)
|
||||
!(c->btree_write_submit_wq = alloc_workqueue("bcachefs_btree_write_sumit",
|
||||
WQ_HIGHPRI|WQ_FREEZABLE|WQ_MEM_RECLAIM, 1)) ||
|
||||
!(c->write_ref_wq = alloc_workqueue("bcachefs_write_ref",
|
||||
WQ_FREEZABLE, 0)))
|
||||
WQ_FREEZABLE, 0)) ||
|
||||
!(c->promote_wq = alloc_workqueue("bcachefs_promotes",
|
||||
WQ_FREEZABLE, 2)))
|
||||
return bch_err_throw(c, ENOMEM_fs_other_alloc);
|
||||
|
||||
int ret = bch2_fs_btree_interior_update_init(c) ?:
|
||||
@ -1088,8 +1092,6 @@ static int bch2_fs_init(struct bch_fs *c, struct bch_sb *sb,
|
||||
|
||||
seqcount_init(&c->usage_lock);
|
||||
|
||||
sema_init(&c->io_in_flight, 128);
|
||||
|
||||
INIT_LIST_HEAD(&c->vfs_inodes_list);
|
||||
mutex_init(&c->vfs_inodes_lock);
|
||||
|
||||
@ -1126,11 +1128,6 @@ static int bch2_fs_init(struct bch_fs *c, struct bch_sb *sb,
|
||||
}
|
||||
#endif
|
||||
|
||||
c->btree_key_cache_btrees |= 1U << BTREE_ID_alloc;
|
||||
if (c->opts.inodes_use_key_cache)
|
||||
c->btree_key_cache_btrees |= 1U << BTREE_ID_inodes;
|
||||
c->btree_key_cache_btrees |= 1U << BTREE_ID_logged_ops;
|
||||
|
||||
c->block_bits = ilog2(block_sectors(c));
|
||||
c->btree_foreground_merge_threshold = BTREE_FOREGROUND_MERGE_THRESHOLD(c);
|
||||
|
||||
@ -1232,6 +1229,10 @@ static int bch2_fs_init(struct bch_fs *c, struct bch_sb *sb,
|
||||
darray_for_each(*sbs, sb)
|
||||
try(bch2_dev_attach_bdev(c, sb, out));
|
||||
|
||||
/*
|
||||
* Do this early, so that we never expose a filesystem object that
|
||||
* hasn't been version downgraded
|
||||
*/
|
||||
try(bch2_fs_opt_version_init(c, out));
|
||||
|
||||
/*
|
||||
@ -1391,9 +1392,9 @@ int bch2_fs_resize_on_mount(struct bch_fs *c)
|
||||
u64 new_nbuckets = div64_u64(get_capacity(ca->disk_sb.bdev->bd_disk),
|
||||
ca->mi.bucket_size);
|
||||
|
||||
bch_info(ca, "resizing to size %llu", new_nbuckets * ca->mi.bucket_size);
|
||||
bch_info_dev(ca, "resizing to size %llu", new_nbuckets * ca->mi.bucket_size);
|
||||
int ret = bch2_dev_buckets_resize(c, ca, new_nbuckets);
|
||||
bch_err_fn(ca, ret);
|
||||
bch_err_fn_dev(ca, ret);
|
||||
if (ret) {
|
||||
enumerated_ref_put(&ca->io_ref[READ],
|
||||
BCH_DEV_READ_REF_fs_resize_on_mount);
|
||||
@ -1492,6 +1493,12 @@ static struct bch_fs *__bch2_fs_open(darray_const_str *devices,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* Log opt_version_init() message before doing actual filesystem startup */
|
||||
CLASS(printbuf, msg_with_prefix)();
|
||||
prt_str(&msg_with_prefix, out->buf);
|
||||
bch2_print_str(c, KERN_INFO, msg_with_prefix.buf);
|
||||
printbuf_reset(out);
|
||||
|
||||
if (!c->opts.nostart) {
|
||||
ret = __bch2_fs_start(c, out);
|
||||
c->recovery_task = NULL;
|
||||
|
||||
@ -213,7 +213,7 @@ int bch2_dev_journal_bucket_delete(struct bch_dev *ca, u64 b)
|
||||
break;
|
||||
|
||||
if (pos == ja->nr) {
|
||||
bch_err(ca, "journal bucket %llu not found when deleting", b);
|
||||
bch_err_dev(ca, "journal bucket %llu not found when deleting", b);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ int bch2_dev_journal_alloc(struct bch_dev *ca, bool new_fs)
|
||||
|
||||
ret = bch2_set_nr_journal_buckets_loop(c, ca, nr, new_fs);
|
||||
err:
|
||||
bch_err_fn(ca, ret);
|
||||
bch_err_fn_dev(ca, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
#include "journal/seq_blacklist.h"
|
||||
#include "journal/write.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include "util/enumerated_ref.h"
|
||||
|
||||
static bool __journal_entry_is_open(union journal_res_state state)
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "journal/journal.h"
|
||||
#include "journal/reclaim.h"
|
||||
|
||||
#include "sb/counters.h"
|
||||
#include "sb/members.h"
|
||||
|
||||
#include <linux/kthread.h>
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "journal/write.h"
|
||||
|
||||
#include "sb/clean.h"
|
||||
#include "sb/counters.h"
|
||||
|
||||
#include <linux/ioprio.h>
|
||||
|
||||
|
||||
@ -252,11 +252,6 @@ enum fsck_err_opts {
|
||||
OPT_UINT(0, 8), \
|
||||
BCH_SB_SHARD_INUMS_NBITS, 0, \
|
||||
NULL, "Shard new inode numbers by CPU id") \
|
||||
x(inodes_use_key_cache, u8, \
|
||||
OPT_FS|OPT_FORMAT|OPT_MOUNT, \
|
||||
OPT_BOOL(), \
|
||||
BCH_SB_INODES_USE_KEY_CACHE, true, \
|
||||
NULL, "Use the btree key cache for the inodes btree") \
|
||||
x(btree_node_mem_ptr_optimization, u8, \
|
||||
OPT_FS|OPT_MOUNT|OPT_RUNTIME, \
|
||||
OPT_BOOL(), \
|
||||
|
||||
@ -54,14 +54,14 @@ int bch2_sb_counters_to_cpu(struct bch_fs *c)
|
||||
unsigned int nr = bch2_sb_counter_nr_entries(ctrs);
|
||||
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++)
|
||||
c->counters_on_mount[i] = 0;
|
||||
c->counters.mount[i] = 0;
|
||||
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++) {
|
||||
unsigned stable = counters_to_stable_map[i];
|
||||
if (stable < nr) {
|
||||
u64 v = le64_to_cpu(ctrs->d[stable]);
|
||||
percpu_u64_set(&c->counters[i], v);
|
||||
c->counters_on_mount[i] = v;
|
||||
percpu_u64_set(&c->counters.now[i], v);
|
||||
c->counters.mount[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,24 +86,70 @@ int bch2_sb_counters_from_cpu(struct bch_fs *c)
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++) {
|
||||
unsigned stable = counters_to_stable_map[i];
|
||||
if (stable < nr)
|
||||
ctrs->d[stable] = cpu_to_le64(percpu_u64_get(&c->counters[i]));
|
||||
ctrs->d[stable] = cpu_to_le64(percpu_u64_get(&c->counters.now[i]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bch2_sb_counters_work(struct work_struct *work)
|
||||
{
|
||||
struct bch_fs_counters *c = container_of(work, struct bch_fs_counters, work.work);
|
||||
|
||||
memmove((void *) c->recent + sizeof(u64) * BCH_COUNTER_NR,
|
||||
c->recent,
|
||||
sizeof(u64) *
|
||||
BCH_COUNTER_NR *
|
||||
(NR_RECENT_COUNTERS - 1));
|
||||
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++)
|
||||
c->recent[0][i] = percpu_u64_get(&c->now[i]);
|
||||
|
||||
queue_delayed_work(system_unbound_wq, &c->work, HZ / 2);
|
||||
}
|
||||
|
||||
void bch2_sb_recent_counters_to_text(struct printbuf *out, struct bch_fs_counters *c)
|
||||
{
|
||||
unsigned long active[BITS_TO_LONGS(BCH_COUNTER_NR)];
|
||||
memset(active, 0, sizeof(active));
|
||||
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++)
|
||||
if (c->recent[NR_RECENT_COUNTERS - 1][i] != percpu_u64_get(&c->now[i]))
|
||||
__set_bit(i, active);
|
||||
|
||||
for (unsigned i = 0; i < BCH_COUNTER_NR; i++) {
|
||||
if (!test_bit(i, active))
|
||||
continue;
|
||||
|
||||
prt_printf(out, "%s:", bch2_counter_names[i]);
|
||||
|
||||
u64 prev = percpu_u64_get(&c->now[i]);
|
||||
|
||||
for (unsigned j = 0; j < NR_RECENT_COUNTERS; j++) {
|
||||
prt_printf(out, "\t%llu", prev - c->recent[j][i]);
|
||||
prev = c->recent[j][i];
|
||||
}
|
||||
prt_newline(out);
|
||||
}
|
||||
}
|
||||
|
||||
void bch2_fs_counters_exit(struct bch_fs *c)
|
||||
{
|
||||
free_percpu(c->counters);
|
||||
cancel_delayed_work_sync(&c->counters.work);
|
||||
free_percpu(c->counters.now);
|
||||
}
|
||||
|
||||
int bch2_fs_counters_init(struct bch_fs *c)
|
||||
{
|
||||
c->counters = __alloc_percpu(sizeof(u64) * BCH_COUNTER_NR, sizeof(u64));
|
||||
if (!c->counters)
|
||||
c->counters.now = __alloc_percpu(sizeof(u64) * BCH_COUNTER_NR, sizeof(u64));
|
||||
if (!c->counters.now)
|
||||
return -BCH_ERR_ENOMEM_fs_counters_init;
|
||||
|
||||
return bch2_sb_counters_to_cpu(c);
|
||||
try(bch2_sb_counters_to_cpu(c));
|
||||
|
||||
INIT_DELAYED_WORK(&c->counters.work, bch2_sb_counters_work);
|
||||
queue_delayed_work(system_unbound_wq, &c->counters.work, HZ / 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_counters = {
|
||||
@ -130,8 +176,8 @@ long bch2_ioctl_query_counters(struct bch_fs *c,
|
||||
|
||||
if (stable < arg.nr) {
|
||||
u64 v = !(arg.flags & BCH_IOCTL_QUERY_COUNTERS_MOUNT)
|
||||
? percpu_u64_get(&c->counters[i])
|
||||
: c->counters_on_mount[i];
|
||||
? percpu_u64_get(&c->counters.now[i])
|
||||
: c->counters.mount[i];
|
||||
|
||||
try(put_user(v, &user_arg->d[stable]));
|
||||
}
|
||||
|
||||
@ -17,4 +17,14 @@ extern const struct bch_sb_field_ops bch_sb_field_ops_counters;
|
||||
long bch2_ioctl_query_counters(struct bch_fs *,
|
||||
struct bch_ioctl_query_counters __user *);
|
||||
|
||||
void bch2_sb_recent_counters_to_text(struct printbuf *out, struct bch_fs_counters *c);
|
||||
|
||||
#define count_event(_c, _name) this_cpu_inc((_c)->counters.now[BCH_COUNTER_##_name])
|
||||
|
||||
#define trace_and_count(_c, _name, ...) \
|
||||
do { \
|
||||
count_event(_c, _name); \
|
||||
trace_##_name(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#endif // _BCACHEFS_SB_COUNTERS_H
|
||||
|
||||
15
libbcachefs/sb/counters_types.h
Normal file
15
libbcachefs/sb/counters_types.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _BCACHEFS_SB_COUNTERS_TYPES_H
|
||||
#define _BCACHEFS_SB_COUNTERS_TYPES_H
|
||||
|
||||
struct bch_fs_counters {
|
||||
u64 mount[BCH_COUNTER_NR];
|
||||
u64 __percpu *now;
|
||||
|
||||
#define NR_RECENT_COUNTERS 20
|
||||
|
||||
u64 recent[NR_RECENT_COUNTERS][BCH_COUNTER_NR];
|
||||
struct delayed_work work;
|
||||
};
|
||||
|
||||
#endif /* _BCACHEFS_SB_COUNTERS_TYPES_H */
|
||||
@ -496,7 +496,8 @@ static struct bch_inode_info *bch2_inode_hash_init_insert(struct btree_trans *tr
|
||||
|
||||
}
|
||||
|
||||
struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum,
|
||||
bool warn)
|
||||
{
|
||||
struct bch_inode_info *inode = bch2_inode_hash_find(c, NULL, inum);
|
||||
if (inode)
|
||||
@ -507,8 +508,8 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct bch_subvolume subvol;
|
||||
int ret = lockrestart_do(trans,
|
||||
bch2_subvolume_get(trans, inum.subvol, true, &subvol) ?:
|
||||
bch2_inode_find_by_inum_trans(trans, inum, &inode_u) ?:
|
||||
bch2_subvolume_get(trans, inum.subvol, warn, &subvol) ?:
|
||||
__bch2_inode_find_by_inum_trans(trans, inum, &inode_u, warn) ?:
|
||||
PTR_ERR_OR_ZERO(inode = bch2_inode_hash_init_insert(trans, inum, &inode_u, &subvol)));
|
||||
|
||||
return ret ? ERR_PTR(ret) : &inode->v;
|
||||
@ -1583,7 +1584,7 @@ static struct inode *bch2_nfs_get_inode(struct super_block *sb,
|
||||
struct inode *vinode = bch2_vfs_inode_get(c, (subvol_inum) {
|
||||
.subvol = fid.subvol,
|
||||
.inum = fid.inum,
|
||||
});
|
||||
}, false);
|
||||
if (!IS_ERR(vinode) && vinode->i_generation != fid.gen) {
|
||||
iput(vinode);
|
||||
vinode = ERR_PTR(-ESTALE);
|
||||
@ -1624,7 +1625,8 @@ static struct dentry *bch2_get_parent(struct dentry *child)
|
||||
.inum = inode->ei_inode.bi_dir,
|
||||
};
|
||||
|
||||
return d_obtain_alias(bch2_vfs_inode_get(c, parent_inum));
|
||||
/* needs nowarn */
|
||||
return d_obtain_alias(bch2_vfs_inode_get(c, parent_inum, false));
|
||||
}
|
||||
|
||||
static int bch2_get_name(struct dentry *parent, char *name, struct dentry *child)
|
||||
@ -2225,7 +2227,7 @@ got_sb:
|
||||
generic_set_sb_d_ops(sb);
|
||||
#endif
|
||||
|
||||
vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM);
|
||||
vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM, true);
|
||||
ret = PTR_ERR_OR_ZERO(vinode);
|
||||
bch_err_msg(c, ret, "mounting: error getting root inode");
|
||||
if (ret)
|
||||
|
||||
@ -178,7 +178,7 @@ static inline int bch2_set_projid(struct bch_fs *c,
|
||||
KEY_TYPE_QUOTA_PREALLOC);
|
||||
}
|
||||
|
||||
struct inode *bch2_vfs_inode_get(struct bch_fs *, subvol_inum);
|
||||
struct inode *bch2_vfs_inode_get(struct bch_fs *, subvol_inum, bool);
|
||||
|
||||
/* returns 0 if we want to do the update, or error is passed up */
|
||||
typedef int (*inode_set_fn)(struct btree_trans *,
|
||||
|
||||
@ -72,7 +72,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
|
||||
if (ret)
|
||||
goto err1;
|
||||
|
||||
vinode = bch2_vfs_inode_get(c, inum);
|
||||
vinode = bch2_vfs_inode_get(c, inum, true);
|
||||
ret = PTR_ERR_OR_ZERO(vinode);
|
||||
if (ret)
|
||||
goto err1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user