diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-08-26 16:48:18 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-08-27 18:47:54 -0400 |
commit | 90cbe3f3b4289abb39804bb0f7e78ad286e556fd (patch) | |
tree | fa8d131708938a2cb50f45295a0f5d3aa0ba0bc8 | |
parent | 4b97a99fa263096297816f64e45cac85d4fa8011 (diff) |
Update bcachefs sources to 753b29cc7989 bcachefs: opts.data_allowed should be OPT_FORMAT
-rw-r--r-- | .bcachefs_revision | 2 | ||||
-rw-r--r-- | libbcachefs/alloc_foreground.c | 1 | ||||
-rw-r--r-- | libbcachefs/bkey_buf.h | 6 | ||||
-rw-r--r-- | libbcachefs/btree_iter.c | 10 | ||||
-rw-r--r-- | libbcachefs/btree_journal_iter.h | 2 | ||||
-rw-r--r-- | libbcachefs/buckets.c | 30 | ||||
-rw-r--r-- | libbcachefs/buckets_types.h | 2 | ||||
-rw-r--r-- | libbcachefs/data_update.c | 8 | ||||
-rw-r--r-- | libbcachefs/disk_accounting.c | 36 | ||||
-rw-r--r-- | libbcachefs/extents.c | 12 | ||||
-rw-r--r-- | libbcachefs/fs-io-buffered.c | 13 | ||||
-rw-r--r-- | libbcachefs/fs.c | 8 | ||||
-rw-r--r-- | libbcachefs/journal_io.c | 31 | ||||
-rw-r--r-- | libbcachefs/opts.h | 2 | ||||
-rw-r--r-- | libbcachefs/rebalance.c | 21 | ||||
-rw-r--r-- | libbcachefs/sb-counters_format.h | 3 | ||||
-rw-r--r-- | libbcachefs/sb-errors_format.h | 3 | ||||
-rw-r--r-- | libbcachefs/super.c | 40 | ||||
-rw-r--r-- | libbcachefs/sysfs.c | 1 | ||||
-rw-r--r-- | libbcachefs/vstructs.h | 3 |
20 files changed, 160 insertions, 74 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision index b3f04e2b..d21b55fa 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -bd062cbcd84d5e7b007561be6e972fcdd283c7aa +753b29cc79897dd7f776fa09654196f5b25f8b96 diff --git a/libbcachefs/alloc_foreground.c b/libbcachefs/alloc_foreground.c index 0a5b3d31..f6ea4a82 100644 --- a/libbcachefs/alloc_foreground.c +++ b/libbcachefs/alloc_foreground.c @@ -1537,7 +1537,6 @@ void bch2_fs_alloc_debug_to_text(struct printbuf *out, struct bch_fs *c) prt_printf(out, "cached\t%llu\n", percpu_u64_get(&c->usage->cached)); prt_printf(out, "reserved\t%llu\n", percpu_u64_get(&c->usage->reserved)); prt_printf(out, "online_reserved\t%llu\n", percpu_u64_get(c->online_reserved)); - prt_printf(out, "nr_inodes\t%llu\n", percpu_u64_get(&c->usage->nr_inodes)); prt_newline(out); prt_printf(out, "freelist_wait\t%s\n", c->freelist_wait.list.first ? "waiting" : "empty"); diff --git a/libbcachefs/bkey_buf.h b/libbcachefs/bkey_buf.h index 0a1fc582..05a01bf8 100644 --- a/libbcachefs/bkey_buf.h +++ b/libbcachefs/bkey_buf.h @@ -29,7 +29,7 @@ static inline int bch2_bkey_buf_reassemble_noprof(struct bkey_buf *s, struct bch_fs *c, struct bkey_s_c k) { - bch2_bkey_buf_realloc(s, c, k.k->u64s); + bch2_bkey_buf_realloc_noprof(s, c, k.k->u64s); bkey_reassemble(s->k, k); return 0; } @@ -39,7 +39,7 @@ static inline int bch2_bkey_buf_copy_noprof(struct bkey_buf *s, struct bch_fs *c, struct bkey_i *src) { - bch2_bkey_buf_realloc(s, c, src->k.u64s); + bch2_bkey_buf_realloc_noprof(s, c, src->k.u64s); bkey_copy(s->k, src); return 0; } @@ -50,7 +50,7 @@ static inline int bch2_bkey_buf_unpack_noprof(struct bkey_buf *s, struct btree *b, struct bkey_packed *src) { - bch2_bkey_buf_realloc(s, c, BKEY_U64s + bkeyp_val_u64s(&b->format, src)); + bch2_bkey_buf_realloc_noprof(s, c, BKEY_U64s + bkeyp_val_u64s(&b->format, src)); bch2_bkey_unpack(b, s->k, src); return 0; } diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c index 76f430f9..1e152c67 100644 --- a/libbcachefs/btree_iter.c +++ b/libbcachefs/btree_iter.c @@ -3271,9 +3271,10 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size, unsigned long EBUG_ON(trans->mem_bytes); EBUG_ON(trans->mem_top); EBUG_ON(new_bytes > BTREE_TRANS_MEM_MAX); - + bool lock_dropped = false; - new_mem = allocate_dropping_locks_norelock(trans, lock_dropped, kmalloc(new_bytes, _gfp)); + new_mem = allocate_dropping_locks_norelock(trans, lock_dropped, + kmalloc(new_bytes, _gfp|__GFP_NOWARN)); if (!new_mem) { new_mem = mempool_alloc(&c->btree_trans_mem_pool, GFP_KERNEL); new_bytes = BTREE_TRANS_MEM_MAX; @@ -3525,7 +3526,7 @@ got_trans: if (s->max_mem) { unsigned expected_mem_bytes = roundup_pow_of_two(s->max_mem); - trans->mem = kmalloc(expected_mem_bytes, GFP_KERNEL); + trans->mem = kmalloc(expected_mem_bytes, GFP_KERNEL|__GFP_NOWARN); if (likely(trans->mem)) trans->mem_bytes = expected_mem_bytes; } @@ -3696,6 +3697,9 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans) prt_printf(out, "%i %s\n", task ? task->pid : 0, trans->fn); + if (trans->journal_replay_not_finished) + prt_printf(out, "has journal_keys ref\n"); + /* trans->paths is rcu protected vs. freeing */ guard(rcu)(); guard(printbuf_atomic)(out); diff --git a/libbcachefs/btree_journal_iter.h b/libbcachefs/btree_journal_iter.h index 8dc8e778..85d6969f 100644 --- a/libbcachefs/btree_journal_iter.h +++ b/libbcachefs/btree_journal_iter.h @@ -31,7 +31,7 @@ struct btree_and_journal_iter { static inline u32 journal_entry_radix_idx(struct bch_fs *c, u64 seq) { - return (seq - c->journal_entries_base_seq) & (~0U >> 1); + return seq - c->journal_entries_base_seq; } static inline struct bkey_i *journal_key_k(struct bch_fs *c, diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c index 280b169e..021f5cb7 100644 --- a/libbcachefs/buckets.c +++ b/libbcachefs/buckets.c @@ -63,8 +63,6 @@ __bch2_fs_usage_read_short(struct bch_fs *c) ret.used = min(ret.capacity, data + reserve_factor(reserved)); ret.free = ret.capacity - ret.used; - ret.nr_inodes = percpu_u64_get(&c->usage->nr_inodes); - return ret; } @@ -113,14 +111,26 @@ static int bch2_check_fix_ptr(struct btree_trans *trans, CLASS(bch2_dev_tryget_noerror, ca)(c, p.ptr.dev); if (!ca) { - if (fsck_err_on(p.ptr.dev != BCH_SB_MEMBER_INVALID, - trans, ptr_to_invalid_device, - "pointer to missing device %u\n" - "while marking %s", - p.ptr.dev, - (printbuf_reset(&buf), - bch2_bkey_val_to_text(&buf, c, k), buf.buf))) - *do_update = true; + if (p.ptr.dev == BCH_SB_MEMBER_INVALID) + return 0; + + if (test_bit(p.ptr.dev, c->devs_removed.d)) { + if (fsck_err(trans, ptr_to_removed_device, + "pointer to removed device %u\n" + "while marking %s", + p.ptr.dev, + (printbuf_reset(&buf), + bch2_bkey_val_to_text(&buf, c, k), buf.buf))) + *do_update = true; + } else { + if (fsck_err(trans, ptr_to_invalid_device, + "pointer to missing device %u\n" + "while marking %s", + p.ptr.dev, + (printbuf_reset(&buf), + bch2_bkey_val_to_text(&buf, c, k), buf.buf))) + *do_update = true; + } return 0; } diff --git a/libbcachefs/buckets_types.h b/libbcachefs/buckets_types.h index 0aed2500..7c726e90 100644 --- a/libbcachefs/buckets_types.h +++ b/libbcachefs/buckets_types.h @@ -78,14 +78,12 @@ struct bch_fs_usage_base { u64 data; u64 cached; u64 reserved; - u64 nr_inodes; }; struct bch_fs_usage_short { u64 capacity; u64 used; u64 free; - u64 nr_inodes; }; /* diff --git a/libbcachefs/data_update.c b/libbcachefs/data_update.c index a314d70c..2c997fdd 100644 --- a/libbcachefs/data_update.c +++ b/libbcachefs/data_update.c @@ -812,10 +812,14 @@ static int can_write_extent(struct bch_fs *c, struct data_update *m) break; } - if (!nr_replicas) { + if (nr_replicas < m->op.nr_replicas) { + prt_printf(&buf, "\nnr_replicas %u < %u", nr_replicas, m->op.nr_replicas); trace_data_update_done_no_rw_devs(c, buf.buf); - return bch_err_throw(c, data_update_done_no_rw_devs); } + + if (!nr_replicas) + return bch_err_throw(c, data_update_done_no_rw_devs); + if (nr_replicas < m->op.nr_replicas) return bch_err_throw(c, insufficient_devices); return 0; diff --git a/libbcachefs/disk_accounting.c b/libbcachefs/disk_accounting.c index 809c76b6..d6c91abc 100644 --- a/libbcachefs/disk_accounting.c +++ b/libbcachefs/disk_accounting.c @@ -11,6 +11,7 @@ #include "disk_accounting.h" #include "error.h" #include "journal_io.h" +#include "recovery_passes.h" #include "replicas.h" /* @@ -910,6 +911,40 @@ int bch2_accounting_read(struct bch_fs *c) u64 v[BCH_ACCOUNTING_MAX_COUNTERS]; bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false); + /* + * Check for underflow, schedule check_allocations + * necessary: + * + * XXX - see if we can factor this out to run on a bkey + * so we can check everything lazily, right now we don't + * check the non in-mem counters at all + */ + bool underflow = false; + for (unsigned j = 0; j < acc->k.data[i].nr_counters; j++) + underflow |= (s64) v[j] < 0; + + if (underflow) { + CLASS(printbuf, buf)(); + bch2_log_msg_start(c, &buf); + + prt_printf(&buf, "Accounting underflow for\n"); + bch2_accounting_key_to_text(&buf, &k); + + for (unsigned j = 0; j < acc->k.data[i].nr_counters; j++) + prt_printf(&buf, " %lli", v[j]); + + bool print = bch2_count_fsck_err(c, accounting_key_underflow, &buf); + unsigned pos = buf.pos; + ret = bch2_run_explicit_recovery_pass(c, &buf, + BCH_RECOVERY_PASS_check_allocations, 0); + print |= buf.pos != pos; + + if (print) + bch2_print_str(c, KERN_ERR, buf.buf); + if (ret) + return ret; + } + switch (k.type) { case BCH_DISK_ACCOUNTING_persistent_reserved: usage->reserved += v[0] * k.persistent_reserved.nr_replicas; @@ -1063,7 +1098,6 @@ void bch2_verify_accounting_clean(struct bch_fs *c) check(data); check(cached); check(reserved); - check(nr_inodes); WARN_ON(mismatch); } diff --git a/libbcachefs/extents.c b/libbcachefs/extents.c index 7ab03987..68a61f7b 100644 --- a/libbcachefs/extents.c +++ b/libbcachefs/extents.c @@ -157,7 +157,7 @@ static inline bool ptr_better(struct bch_fs *c, const struct extent_ptr_decoded p2, u64 p2_latency) { - struct bch_dev *ca2 = bch2_dev_rcu(c, p2.ptr.dev); + struct bch_dev *ca2 = bch2_dev_rcu_noerror(c, p2.ptr.dev); int failed_delta = dev_failed(ca1) - dev_failed(ca2); if (unlikely(failed_delta)) @@ -419,7 +419,7 @@ bool bch2_extent_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r) return false; /* Extents may not straddle buckets: */ - struct bch_dev *ca = bch2_dev_rcu(c, lp.ptr.dev); + struct bch_dev *ca = bch2_dev_rcu_noerror(c, lp.ptr.dev); bool same_bucket = ca && PTR_BUCKET_NR(ca, &lp.ptr) == PTR_BUCKET_NR(ca, &rp.ptr); if (!same_bucket) @@ -815,14 +815,14 @@ static inline unsigned __extent_ptr_durability(struct bch_dev *ca, struct extent unsigned bch2_extent_ptr_desired_durability(struct bch_fs *c, struct extent_ptr_decoded *p) { - struct bch_dev *ca = bch2_dev_rcu(c, p->ptr.dev); + struct bch_dev *ca = bch2_dev_rcu_noerror(c, p->ptr.dev); return ca ? __extent_ptr_durability(ca, p) : 0; } unsigned bch2_extent_ptr_durability(struct bch_fs *c, struct extent_ptr_decoded *p) { - struct bch_dev *ca = bch2_dev_rcu(c, p->ptr.dev); + struct bch_dev *ca = bch2_dev_rcu_noerror(c, p->ptr.dev); if (!ca || ca->mi.state == BCH_MEMBER_STATE_failed) return 0; @@ -1044,7 +1044,7 @@ bool bch2_bkey_has_target(struct bch_fs *c, struct bkey_s_c k, unsigned target) guard(rcu)(); bkey_for_each_ptr(ptrs, ptr) if (bch2_dev_in_target(c, ptr->dev, target) && - (ca = bch2_dev_rcu(c, ptr->dev)) && + (ca = bch2_dev_rcu_noerror(c, ptr->dev)) && (!ptr->cached || !dev_ptr_stale_rcu(ca, ptr))) return true; @@ -1228,7 +1228,7 @@ bool bch2_extent_normalize(struct bch_fs *c, struct bkey_s k) guard(rcu)(); bch2_bkey_drop_ptrs(k, ptr, ptr->cached && - (!(ca = bch2_dev_rcu(c, ptr->dev)) || + (!(ca = bch2_dev_rcu_noerror(c, ptr->dev)) || dev_ptr_stale_rcu(ca, ptr) > 0)); return bkey_deleted(k.k); diff --git a/libbcachefs/fs-io-buffered.c b/libbcachefs/fs-io-buffered.c index fd8beb51..9532f1a7 100644 --- a/libbcachefs/fs-io-buffered.c +++ b/libbcachefs/fs-io-buffered.c @@ -667,6 +667,17 @@ do_io: return 0; } +static int bch2_write_cache_pages(struct address_space *mapping, + struct writeback_control *wbc, void *data) +{ + struct folio *folio = NULL; + int error; + + while ((folio = writeback_iter(mapping, wbc, folio, &error))) + error = __bch2_writepage(folio, wbc, data); + return error; +} + int bch2_writepages(struct address_space *mapping, struct writeback_control *wbc) { struct bch_fs *c = mapping->host->i_sb->s_fs_info; @@ -675,7 +686,7 @@ int bch2_writepages(struct address_space *mapping, struct writeback_control *wbc bch2_inode_opts_get(&w->opts, c, &to_bch_ei(mapping->host)->ei_inode); blk_start_plug(&w->plug); - int ret = write_cache_pages(mapping, wbc, __bch2_writepage, w); + int ret = bch2_write_cache_pages(mapping, wbc, w); if (w->io) bch2_writepage_do_io(w); blk_finish_plug(&w->plug); diff --git a/libbcachefs/fs.c b/libbcachefs/fs.c index 0425238a..39ebcab1 100644 --- a/libbcachefs/fs.c +++ b/libbcachefs/fs.c @@ -8,6 +8,7 @@ #include "buckets.h" #include "chardev.h" #include "dirent.h" +#include "disk_accounting.h" #include "errcode.h" #include "extents.h" #include "fs.h" @@ -2247,7 +2248,12 @@ static int bch2_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bfree = usage.free >> shift; buf->f_bavail = avail_factor(usage.free) >> shift; - buf->f_files = usage.nr_inodes + avail_inodes; + u64 nr_inodes = 0; + struct disk_accounting_pos k; + disk_accounting_key_init(k, nr_inodes); + bch2_accounting_mem_read(c, disk_accounting_pos_to_bpos(&k), &nr_inodes, 1); + + buf->f_files = nr_inodes + avail_inodes; buf->f_ffree = avail_inodes; buf->f_fsid = uuid_to_fsid(c->sb.user_uuid.b); diff --git a/libbcachefs/journal_io.c b/libbcachefs/journal_io.c index c5458c61..0a9fbc76 100644 --- a/libbcachefs/journal_io.c +++ b/libbcachefs/journal_io.c @@ -152,6 +152,7 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, struct journal_replay **_i, *i, *dup; size_t bytes = vstruct_bytes(j); u64 last_seq = !JSET_NO_FLUSH(j) ? le64_to_cpu(j->last_seq) : 0; + u64 seq = le64_to_cpu(j->seq); CLASS(printbuf, buf)(); int ret = JOURNAL_ENTRY_ADD_OK; @@ -159,12 +160,11 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, last_seq = min(last_seq, c->opts.journal_rewind); if (!c->journal.oldest_seq_found_ondisk || - le64_to_cpu(j->seq) < c->journal.oldest_seq_found_ondisk) - c->journal.oldest_seq_found_ondisk = le64_to_cpu(j->seq); + seq < c->journal.oldest_seq_found_ondisk) + c->journal.oldest_seq_found_ondisk = seq; /* Is this entry older than the range we need? */ - if (!c->opts.read_entire_journal && - le64_to_cpu(j->seq) < jlist->last_seq) + if (!c->opts.read_entire_journal && seq < jlist->last_seq) return JOURNAL_ENTRY_ADD_OUT_OF_RANGE; /* @@ -173,7 +173,7 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, * within the range of +-2billion of the filrst one we find. */ if (!c->journal_entries_base_seq) - c->journal_entries_base_seq = max_t(s64, 1, le64_to_cpu(j->seq) - S32_MAX); + c->journal_entries_base_seq = max_t(s64, 1, seq - S32_MAX); /* Drop entries we don't need anymore */ if (last_seq > jlist->last_seq && !c->opts.read_entire_journal) { @@ -194,25 +194,33 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, /* Drop overwrites, log entries if we don't need them: */ if (!c->opts.retain_recovery_info && !c->opts.journal_rewind) { + vstruct_for_each_safe(j, src) + if (vstruct_end(src) > vstruct_end(j)) + goto nocompact; + struct jset_entry *dst = j->start; vstruct_for_each_safe(j, src) { if (src->type == BCH_JSET_ENTRY_log || src->type == BCH_JSET_ENTRY_overwrite) continue; - memcpy(dst, src, vstruct_bytes(src)); + memmove_u64s_down(dst, src, vstruct_u64s(src)); dst = vstruct_next(dst); } j->u64s = cpu_to_le32((u64 *) dst - j->_data); bytes = vstruct_bytes(j); } - +nocompact: jlist->last_seq = max(jlist->last_seq, last_seq); - _i = genradix_ptr_alloc(&c->journal_entries, - journal_entry_radix_idx(c, le64_to_cpu(j->seq)), - GFP_KERNEL); + if (seq < c->journal_entries_base_seq || + seq >= c->journal_entries_base_seq + U32_MAX) { + bch_err(c, "journal entry sequence numbers span too large a range: cannot reply, contact developers"); + return bch_err_throw(c, ENOMEM_journal_entry_add); + } + + _i = genradix_ptr_alloc(&c->journal_entries, journal_entry_radix_idx(c, seq), GFP_KERNEL); if (!_i) return bch_err_throw(c, ENOMEM_journal_entry_add); @@ -222,8 +230,6 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, */ dup = *_i; if (dup) { - BUG_ON(dup->j.seq != j->seq); - bool identical = bytes == vstruct_bytes(&dup->j) && !memcmp(j, &dup->j, bytes); bool not_identical = !identical && @@ -254,7 +260,6 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca, if (entry_ptr.csum_good && !identical) goto replace; - BUG_ON(dup->j.seq != j->seq); return ret; } replace: diff --git a/libbcachefs/opts.h b/libbcachefs/opts.h index 31a3abcb..f8828f46 100644 --- a/libbcachefs/opts.h +++ b/libbcachefs/opts.h @@ -539,7 +539,7 @@ enum fsck_err_opts { "n", "Data written to this device will be considered\n"\ "to have already been replicated n times") \ x(data_allowed, u8, \ - OPT_DEVICE, \ + OPT_DEVICE|OPT_FORMAT, \ OPT_BITFIELD(__bch2_data_types), \ BCH_MEMBER_DATA_ALLOWED, BIT(BCH_DATA_journal)|BIT(BCH_DATA_btree)|BIT(BCH_DATA_user),\ "types", "Allowed data types for this device: journal, btree, and/or user")\ diff --git a/libbcachefs/rebalance.c b/libbcachefs/rebalance.c index e1db63d7..25bf72dc 100644 --- a/libbcachefs/rebalance.c +++ b/libbcachefs/rebalance.c @@ -421,6 +421,7 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans, trace_rebalance_extent(c, buf.buf); } + count_event(c, rebalance_extent); return k; } @@ -478,11 +479,12 @@ out: return ret; } -static int do_rebalance_scan(struct moving_context *ctxt, u64 inum, u64 cookie) +static int do_rebalance_scan(struct moving_context *ctxt, + u64 inum, u64 cookie, u64 *sectors_scanned) { struct btree_trans *trans = ctxt->trans; struct bch_fs *c = trans->c; - struct bch_fs_rebalance *r = &trans->c->rebalance; + struct bch_fs_rebalance *r = &c->rebalance; bch2_move_stats_init(&r->scan_stats, "rebalance_scan"); ctxt->stats = &r->scan_stats; @@ -514,14 +516,16 @@ static int do_rebalance_scan(struct moving_context *ctxt, u64 inum, u64 cookie) bch2_clear_rebalance_needs_scan(trans, inum, cookie)); per_snapshot_io_opts_exit(&snapshot_io_opts); - bch2_move_stats_exit(&r->scan_stats, trans->c); + *sectors_scanned += atomic64_read(&r->scan_stats.sectors_seen); + bch2_move_stats_exit(&r->scan_stats, c); /* * Ensure that the rebalance_work entries we created are seen by the * next iteration of do_rebalance(), so we don't end up stuck in * rebalance_wait(): */ - atomic64_inc(&r->scan_stats.sectors_seen); + *sectors_scanned += 1; + bch2_btree_write_buffer_flush_sync(trans); return ret; @@ -561,6 +565,7 @@ static int do_rebalance(struct moving_context *ctxt) struct bch_fs *c = trans->c; struct bch_fs_rebalance *r = &c->rebalance; struct btree_iter extent_iter = {}; + u64 sectors_scanned = 0; u32 kick = r->kick; struct bpos work_pos = POS_MIN; @@ -570,7 +575,6 @@ static int do_rebalance(struct moving_context *ctxt) return ret; bch2_move_stats_init(&r->work_stats, "rebalance_work"); - bch2_move_stats_init(&r->scan_stats, "rebalance_scan"); while (!bch2_move_ratelimit(ctxt)) { if (!bch2_rebalance_enabled(c)) { @@ -587,19 +591,20 @@ static int do_rebalance(struct moving_context *ctxt) ret = k->k.type == KEY_TYPE_cookie ? do_rebalance_scan(ctxt, k->k.p.inode, - le64_to_cpu(bkey_i_to_cookie(k)->v.cookie)) + le64_to_cpu(bkey_i_to_cookie(k)->v.cookie), + §ors_scanned) : do_rebalance_extent(ctxt, k->k.p, &extent_iter); if (ret) break; } bch2_trans_iter_exit(&extent_iter); - bch2_move_stats_exit(&r->scan_stats, c); + bch2_move_stats_exit(&r->work_stats, c); if (!ret && !kthread_should_stop() && !atomic64_read(&r->work_stats.sectors_seen) && - !atomic64_read(&r->scan_stats.sectors_seen) && + !sectors_scanned && kick == r->kick) { bch2_moving_ctxt_flush_all(ctxt); bch2_trans_unlock_long(trans); diff --git a/libbcachefs/sb-counters_format.h b/libbcachefs/sb-counters_format.h index 96ad6492..17cd6176 100644 --- a/libbcachefs/sb-counters_format.h +++ b/libbcachefs/sb-counters_format.h @@ -35,6 +35,7 @@ enum counters_flags { x(io_move_noop, 92, TYPE_COUNTER) \ x(io_move_created_rebalance, 83, TYPE_COUNTER) \ x(io_move_evacuate_bucket, 84, TYPE_COUNTER) \ + x(rebalance_extent, 96, TYPE_COUNTER) \ x(bucket_invalidate, 3, TYPE_COUNTER) \ x(bucket_discard, 4, TYPE_COUNTER) \ x(bucket_discard_fast, 79, TYPE_COUNTER) \ @@ -127,7 +128,7 @@ struct bch_sb_field_counters { static inline void __maybe_unused check_bch_counter_ids_unique(void) { switch(0){ #define x(t, n, ...) case (n): - BCH_PERSISTENT_COUNTERS() + BCH_PERSISTENT_COUNTERS(); #undef x ; } diff --git a/libbcachefs/sb-errors_format.h b/libbcachefs/sb-errors_format.h index 5317b1bf..aa0ea1ec 100644 --- a/libbcachefs/sb-errors_format.h +++ b/libbcachefs/sb-errors_format.h @@ -328,6 +328,7 @@ enum bch_fsck_flags { x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \ x(accounting_key_version_0, 282, FSCK_AUTOFIX) \ x(accounting_key_nr_counters_wrong, 307, FSCK_AUTOFIX) \ + x(accounting_key_underflow, 325, FSCK_AUTOFIX) \ x(logged_op_but_clean, 283, FSCK_AUTOFIX) \ x(compression_opt_not_marked_in_sb, 295, FSCK_AUTOFIX) \ x(compression_type_not_marked_in_sb, 296, FSCK_AUTOFIX) \ @@ -336,7 +337,7 @@ enum bch_fsck_flags { x(dirent_stray_data_after_cf_name, 305, 0) \ x(rebalance_work_incorrectly_set, 309, FSCK_AUTOFIX) \ x(rebalance_work_incorrectly_unset, 310, FSCK_AUTOFIX) \ - x(MAX, 325, 0) + x(MAX, 326, 0) enum bch_sb_error_id { #define x(t, n, ...) BCH_FSCK_ERR_##t = n, diff --git a/libbcachefs/super.c b/libbcachefs/super.c index cc9d00e1..793c16fa 100644 --- a/libbcachefs/super.c +++ b/libbcachefs/super.c @@ -237,6 +237,7 @@ static int bch2_dev_alloc(struct bch_fs *, unsigned); static int bch2_dev_sysfs_online(struct bch_fs *, struct bch_dev *); static void bch2_dev_io_ref_stop(struct bch_dev *, int); static void __bch2_dev_read_only(struct bch_fs *, struct bch_dev *); +static int bch2_dev_attach_bdev(struct bch_fs *, struct bch_sb_handle *, struct printbuf *); struct bch_fs *bch2_dev_to_fs(dev_t dev) { @@ -988,11 +989,7 @@ static int bch2_fs_opt_version_init(struct bch_fs *c) } } - if (c->cf_encoding) - prt_printf(&p, "\nUsing 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)); + /* cf_encoding log message should be here, but it breaks xfstests - sigh */ if (c->opts.journal_rewind) prt_printf(&p, "\nrewinding journal, fsck required"); @@ -1008,8 +1005,9 @@ static int bch2_fs_opt_version_init(struct bch_fs *c) return ret; __le64 now = cpu_to_le64(ktime_get_real_seconds()); - for_each_online_member_rcu(c, ca) - bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = now; + scoped_guard(rcu) + for_each_online_member_rcu(c, ca) + bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = now; if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb)) ext->recovery_passes_required[0] |= @@ -1060,6 +1058,14 @@ static int bch2_fs_opt_version_init(struct bch_fs *c) bch2_print_str(c, KERN_INFO, p.buf); + /* this really should be part of our one multi line mount message, but - + * xfstests... */ + if (c->cf_encoding) + 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 (BCH_SB_INITIALIZED(c->disk_sb.sb)) { if (!(c->sb.features & (1ULL << BCH_FEATURE_new_extent_overwrite))) { bch_err(c, "feature new_extent_overwrite not set, filesystem no longer supported"); @@ -1313,6 +1319,16 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts, &c->clock_journal_res, (sizeof(struct jset_entry_clock) / sizeof(u64)) * 2); + scoped_guard(rwsem_write, &c->state_lock) + darray_for_each(*sbs, sb) { + CLASS(printbuf, err)(); + ret = bch2_dev_attach_bdev(c, sb, &err); + if (ret) { + bch_err(bch2_dev_locked(c, sb->sb->dev_idx), "%s", err.buf); + goto err; + } + } + ret = bch2_fs_opt_version_init(c); if (ret) goto err; @@ -2604,16 +2620,6 @@ struct bch_fs *bch2_fs_open(darray_const_str *devices, if (ret) goto err; - scoped_guard(rwsem_write, &c->state_lock) - darray_for_each(sbs, sb) { - CLASS(printbuf, err)(); - ret = bch2_dev_attach_bdev(c, sb, &err); - if (ret) { - bch_err(bch2_dev_locked(c, sb->sb->dev_idx), "%s", err.buf); - goto err; - } - } - if (!c->opts.nostart) { ret = bch2_fs_start(c); if (ret) diff --git a/libbcachefs/sysfs.c b/libbcachefs/sysfs.c index bd3fa9c3..6b071dcc 100644 --- a/libbcachefs/sysfs.c +++ b/libbcachefs/sysfs.c @@ -304,7 +304,6 @@ static void bch2_fs_usage_base_to_text(struct printbuf *out, struct bch_fs *c) prt_printf(out, "data:\t\t%llu\n", b.data); prt_printf(out, "cached:\t%llu\n", b.cached); prt_printf(out, "reserved:\t\t%llu\n", b.reserved); - prt_printf(out, "nr_inodes:\t%llu\n", b.nr_inodes); } static int bch2_read_fua_test(struct printbuf *out, struct bch_dev *ca) diff --git a/libbcachefs/vstructs.h b/libbcachefs/vstructs.h index 2ad338e2..446770ec 100644 --- a/libbcachefs/vstructs.h +++ b/libbcachefs/vstructs.h @@ -23,6 +23,9 @@ (size_t) (offsetof(_type, _data) + (_u64s) * sizeof(u64)); \ }) +#define vstruct_u64s(_s) \ + (offsetof(typeof(*(_s)), _data) / sizeof(u64) + __vstruct_u64s(_s)) + #define vstruct_bytes(_s) \ __vstruct_bytes(typeof(*(_s)), __vstruct_u64s(_s)) |