summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/bcachefs.h17
-rw-r--r--fs/bcachefs/btree_write_buffer.c10
-rw-r--r--fs/bcachefs/btree_write_buffer.h2
-rw-r--r--fs/bcachefs/data_update.c11
-rw-r--r--fs/bcachefs/data_update.h1
-rw-r--r--fs/bcachefs/disk_accounting.h10
-rw-r--r--fs/bcachefs/extents.c17
-rw-r--r--fs/bcachefs/extents.h1
-rw-r--r--fs/bcachefs/fs.c8
-rw-r--r--fs/bcachefs/move.c16
-rw-r--r--fs/bcachefs/sb-counters_format.h4
-rw-r--r--fs/bcachefs/trace.h5
12 files changed, 79 insertions, 23 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index cdf593c59922..16d08dfb5f19 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -386,14 +386,6 @@ do { \
##__VA_ARGS__, bch2_err_str(_ret)); \
} while (0)
-static inline int __bch2_err_trace(struct bch_fs *c, int err)
-{
- trace_error_throw(c, err, _THIS_IP_);
- return err;
-}
-
-#define bch_err_throw(_c, _err) __bch2_err_trace(_c, -BCH_ERR_##_err)
-
/* Parameters that are useful for debugging, but should always be compiled in: */
#define BCH_DEBUG_PARAMS_ALWAYS() \
BCH_DEBUG_PARAM(key_merging_disabled, \
@@ -1153,6 +1145,15 @@ struct bch_fs {
struct mutex fsck_error_counts_lock;
};
+static inline int __bch2_err_trace(struct bch_fs *c, int err)
+{
+ this_cpu_inc(c->counters[BCH_COUNTER_error_throw]);
+ trace_error_throw(c, err, _THIS_IP_);
+ return err;
+}
+
+#define bch_err_throw(_c, _err) __bch2_err_trace(_c, -BCH_ERR_##_err)
+
extern struct wait_queue_head bch2_read_only_wait;
static inline bool bch2_ro_ref_tryget(struct bch_fs *c)
diff --git a/fs/bcachefs/btree_write_buffer.c b/fs/bcachefs/btree_write_buffer.c
index afad11831e1d..755fb25a8eba 100644
--- a/fs/bcachefs/btree_write_buffer.c
+++ b/fs/bcachefs/btree_write_buffer.c
@@ -701,8 +701,16 @@ int bch2_accounting_key_to_wb_slowpath(struct bch_fs *c, enum btree_id btree,
struct bkey_i_accounting *k)
{
struct btree_write_buffer *wb = &c->btree_write_buffer;
- struct btree_write_buffered_key new = { .btree = btree };
+ if (trace_accounting_key_to_wb_slowpath_enabled()) {
+ CLASS(printbuf, buf)();
+ prt_printf(&buf, "have: %zu\n", wb->accounting.nr);
+ bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&k->k_i));
+ trace_accounting_key_to_wb_slowpath(c, buf.buf);
+ }
+ count_event(c, accounting_key_to_wb_slowpath);
+
+ struct btree_write_buffered_key new = { .btree = btree };
bkey_copy(&new.k, &k->k_i);
int ret = darray_push(&wb->accounting, new);
diff --git a/fs/bcachefs/btree_write_buffer.h b/fs/bcachefs/btree_write_buffer.h
index e484cd6b90b0..b862bdf67f58 100644
--- a/fs/bcachefs/btree_write_buffer.h
+++ b/fs/bcachefs/btree_write_buffer.h
@@ -95,7 +95,7 @@ static inline int bch2_journal_key_to_wb(struct bch_fs *c,
EBUG_ON(!dst->seq);
- return k->k.type == KEY_TYPE_accounting
+ return bch2_bkey_is_accounting_mem(&k->k)
? bch2_accounting_key_to_wb(c, btree, bkey_i_to_accounting(k))
: __bch2_journal_key_to_wb(c, dst, btree, k);
}
diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c
index 01838a3a189d..a314d70c6b8e 100644
--- a/fs/bcachefs/data_update.c
+++ b/fs/bcachefs/data_update.c
@@ -225,7 +225,7 @@ static void trace_io_move_created_rebalance2(struct data_update *m,
trace_io_move_created_rebalance(c, buf.buf);
- this_cpu_inc(c->counters[BCH_COUNTER_io_move_created_rebalance]);
+ count_event(c, io_move_created_rebalance);
}
noinline_for_stack
@@ -693,6 +693,15 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans,
if (ret)
return ret;
+ const union bch_extent_entry *entry;
+ struct extent_ptr_decoded p;
+ unsigned i = 0;
+ bkey_for_each_ptr_decode(k.k, bch2_bkey_ptrs_c(k), p, entry) {
+ if (data_opts->kill_ec_ptrs & BIT(i))
+ bch2_bkey_drop_ec(n, p.ptr.dev);
+ i++;
+ }
+
while (data_opts->kill_ptrs) {
unsigned i = 0, drop = __fls(data_opts->kill_ptrs);
diff --git a/fs/bcachefs/data_update.h b/fs/bcachefs/data_update.h
index 5e14d13568de..fc12aa65366f 100644
--- a/fs/bcachefs/data_update.h
+++ b/fs/bcachefs/data_update.h
@@ -12,6 +12,7 @@ struct moving_context;
struct data_update_opts {
unsigned rewrite_ptrs;
unsigned kill_ptrs;
+ unsigned kill_ec_ptrs;
u16 target;
u8 extra_replicas;
unsigned btree_insert_flags;
diff --git a/fs/bcachefs/disk_accounting.h b/fs/bcachefs/disk_accounting.h
index 43f4b21d0aab..cc73cce98a44 100644
--- a/fs/bcachefs/disk_accounting.h
+++ b/fs/bcachefs/disk_accounting.h
@@ -145,6 +145,16 @@ static inline bool bch2_accounting_is_mem(struct disk_accounting_pos *acc)
acc->type != BCH_DISK_ACCOUNTING_inum;
}
+static inline bool bch2_bkey_is_accounting_mem(struct bkey *k)
+{
+ if (k->type != KEY_TYPE_accounting)
+ return false;
+
+ struct disk_accounting_pos acc_k;
+ bpos_to_disk_accounting_pos(&acc_k, k->p);
+ return bch2_accounting_is_mem(&acc_k);
+}
+
/*
* Update in memory counters so they match the btree update we're doing; called
* from transaction commit path
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index b879a586b7f6..7ab0398707d8 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -995,6 +995,22 @@ void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev)
bch2_bkey_drop_ptrs_noerror(k, ptr, ptr->dev == dev);
}
+void bch2_bkey_drop_ec(struct bkey_i *k, unsigned dev)
+{
+ struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(k));
+ union bch_extent_entry *entry, *ec = NULL;
+
+ bkey_extent_entry_for_each(ptrs, entry) {
+ if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_stripe_ptr)
+ ec = entry;
+ else if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_ptr &&
+ entry->ptr.dev == dev) {
+ bch2_bkey_extent_entry_drop(k, ec);
+ return;
+ }
+ }
+}
+
const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c k, unsigned dev)
{
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
@@ -1757,3 +1773,4 @@ int bch2_cut_back_s(struct bpos where, struct bkey_s k)
memset(bkey_val_end(k), 0, val_u64s_delta * sizeof(u64));
return -val_u64s_delta;
}
+
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
index 35ee03cd5065..f6dcb17108cd 100644
--- a/fs/bcachefs/extents.h
+++ b/fs/bcachefs/extents.h
@@ -650,6 +650,7 @@ void bch2_bkey_drop_ptr(struct bkey_s, struct bch_extent_ptr *);
void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned);
void bch2_bkey_drop_device(struct bkey_s, unsigned);
+void bch2_bkey_drop_ec(struct bkey_i *k, unsigned);
#define bch2_bkey_drop_ptrs_noerror(_k, _ptr, _cond) \
do { \
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index 76d2647d9500..52722a5e8526 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -826,14 +826,6 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
bch2_inode_update_after_write(trans, inode, &inode_u,
ATTR_MTIME);
- if (inode_u.bi_subvol) {
- /*
- * Subvolume deletion is asynchronous, but we still want to tell
- * the VFS that it's been deleted here:
- */
- set_nlink(&inode->v, 0);
- }
-
if (IS_CASEFOLDED(vdir))
d_invalidate(dentry);
err:
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index 8457dd6b35ac..df6833416855 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -150,7 +150,7 @@ static void move_write_done(struct bch_write_op *op)
bch2_write_op_to_text(&buf, op);
trace_io_move_write_fail(c, buf.buf);
}
- this_cpu_inc(c->counters[BCH_COUNTER_io_move_write_fail]);
+ count_event(c, io_move_write_fail);
ctxt->write_error = true;
}
@@ -344,7 +344,7 @@ int bch2_move_extent(struct moving_context *ctxt,
if (!data_opts.rewrite_ptrs &&
!data_opts.extra_replicas &&
!data_opts.scrub) {
- if (data_opts.kill_ptrs) {
+ if (data_opts.kill_ptrs|data_opts.kill_ec_ptrs) {
this_cpu_add(c->counters[BCH_COUNTER_io_move_drop_only], k.k->size);
return bch2_extent_drop_ptrs(trans, iter, k, &io_opts, &data_opts);
} else {
@@ -1280,7 +1280,17 @@ static bool drop_extra_replicas_pred(struct bch_fs *c, void *arg,
i++;
}
- return data_opts->kill_ptrs != 0;
+ i = 0;
+ bkey_for_each_ptr_decode(k.k, bch2_bkey_ptrs_c(k), p, entry) {
+ if (p.has_ec && durability - p.ec.redundancy >= replicas) {
+ data_opts->kill_ec_ptrs |= BIT(i);
+ durability -= p.ec.redundancy;
+ }
+
+ i++;
+ }
+
+ return (data_opts->kill_ptrs|data_opts->kill_ec_ptrs) != 0;
}
static bool scrub_pred(struct bch_fs *c, void *_arg,
diff --git a/fs/bcachefs/sb-counters_format.h b/fs/bcachefs/sb-counters_format.h
index f3ea53a55384..44bc12573a0c 100644
--- a/fs/bcachefs/sb-counters_format.h
+++ b/fs/bcachefs/sb-counters_format.h
@@ -101,7 +101,9 @@ enum counters_flags {
x(trans_restart_write_buffer_flush, 75, TYPE_COUNTER) \
x(trans_restart_split_race, 76, TYPE_COUNTER) \
x(write_buffer_flush_slowpath, 77, TYPE_COUNTER) \
- x(write_buffer_flush_sync, 78, TYPE_COUNTER)
+ x(write_buffer_flush_sync, 78, TYPE_COUNTER) \
+ x(accounting_key_to_wb_slowpath, 94, TYPE_COUNTER) \
+ x(error_throw, 93, TYPE_COUNTER)
enum bch_persistent_counters {
#define x(t, n, ...) BCH_COUNTER_##t,
diff --git a/fs/bcachefs/trace.h b/fs/bcachefs/trace.h
index 3776a1403104..269cdf1a87a4 100644
--- a/fs/bcachefs/trace.h
+++ b/fs/bcachefs/trace.h
@@ -1179,6 +1179,11 @@ DEFINE_EVENT(transaction_event, trans_restart_write_buffer_flush,
TP_ARGS(trans, caller_ip)
);
+DEFINE_EVENT(fs_str, accounting_key_to_wb_slowpath,
+ TP_PROTO(struct bch_fs *c, const char *str),
+ TP_ARGS(c, str)
+);
+
TRACE_EVENT(path_downgrade,
TP_PROTO(struct btree_trans *trans,
unsigned long caller_ip,