diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-07 17:06:04 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-10 20:25:10 -0500 |
commit | d9d414e3b9e0139e994caae55619b823bacfc3df (patch) | |
tree | b86477e4fd56dc8a78285988c81ee900f06a3af4 | |
parent | 02d304c0c1f2a111af4cf03446abf75135a5e18b (diff) |
foo
-rw-r--r-- | fs/bcachefs/buckets.c | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 05dd79090b35..79af65be33c5 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -335,6 +335,17 @@ static bool bucket_became_unavailable(struct bch_fs *c, (!c || c->gc_pos.phase == GC_PHASE_DONE); } +static s64 update_bad(struct bch_fs_usage *stats, + struct disk_reservation *disk_res) +{ + struct fs_usage_sum sum = __fs_usage_sum(*stats); + s64 added = sum.data + sum.reserved; + + if (added > (s64) (disk_res ? disk_res->sectors : 0)) + return added; + return 0; +} + void bch2_fs_usage_apply(struct bch_fs *c, struct bch_fs_usage *stats, struct disk_reservation *disk_res, @@ -349,6 +360,11 @@ void bch2_fs_usage_apply(struct bch_fs *c, * reservation: */ should_not_have_added = added - (s64) (disk_res ? disk_res->sectors : 0); + if (should_not_have_added > 0) + panic("added %lli reserved %llu\n", + added, + disk_res ? disk_res->sectors : 0); + if (WARN_ONCE(should_not_have_added > 0, "disk usage increased without a reservation")) { atomic64_sub(should_not_have_added, &c->sectors_available); @@ -484,7 +500,6 @@ void bch2_mark_alloc_bucket(struct bch_fs *c, struct bch_dev *ca, do { \ unsigned _res = (unsigned) (a) + (b); \ (a) = _res; \ - BUG_ON((a) != _res); \ } while (0) void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca, @@ -680,6 +695,8 @@ static void bch2_mark_stripe_ptr(struct bch_fs *c, bch2_stripes_heap_update(c, m, p.idx); } +static bool verbose; + static void bch2_mark_extent(struct bch_fs *c, struct bkey_s_c k, s64 sectors, enum bch_data_type data_type, struct gc_pos pos, @@ -717,6 +734,16 @@ static void bch2_mark_extent(struct bch_fs *c, struct bkey_s_c k, if (!p.ptr.cached) replicas++; + if (verbose) + pr_info("sectors %lli disk %lli adjusted %lli", + sectors, disk_sectors, + adjusted_disk_sectors); + + if (0 && adjusted_disk_sectors != disk_sectors) + pr_info("disk_sectors %lli adjusted %lli", + disk_sectors, + adjusted_disk_sectors); + if (p.ptr.cached) cached_sectors += adjusted_disk_sectors; else if (!p.ec_nr) @@ -895,6 +922,7 @@ void bch2_mark_update(struct btree_insert *trans, struct bch_fs_usage stats = { 0 }; struct gc_pos pos = gc_pos_btree_node(b); struct bkey_packed *_k; + s64 added; if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) bch2_mark_key(c, btree_node_type(b), bkey_i_to_s_c(insert->k), @@ -952,6 +980,72 @@ void bch2_mark_update(struct btree_insert *trans, bch2_btree_node_iter_advance(&node_iter, b); } + if ((added = update_bad(&stats, trans->disk_res))) { + char buf[200]; + s64 sectors; + + verbose = true; + + sectors = bpos_min(insert->k->k.p, b->key.k.p).offset - + bkey_start_offset(&insert->k->k); + + bch2_bkey_val_to_text(c, btree_node_type(b), + buf, sizeof(buf), + bkey_i_to_s_c(insert->k)); + pr_info("adding %lli\n%s", sectors, buf); + + node_iter = iter->l[0].iter; + + while ((_k = bch2_btree_node_iter_peek_filter(&node_iter, b, + KEY_TYPE_DISCARD))) { + struct bkey unpacked; + struct bkey_s_c k; + + k = bkey_disassemble(b, _k, &unpacked); + + if (btree_node_is_extents(b) + ? bkey_cmp(insert->k->k.p, bkey_start_pos(k.k)) <= 0 + : bkey_cmp(insert->k->k.p, k.k->p)) + break; + + sectors = 0; + + if (btree_node_is_extents(b)) { + switch (bch2_extent_overlap(&insert->k->k, k.k)) { + case BCH_EXTENT_OVERLAP_ALL: + sectors = -((s64) k.k->size); + break; + case BCH_EXTENT_OVERLAP_BACK: + sectors = bkey_start_offset(&insert->k->k) - + k.k->p.offset; + break; + case BCH_EXTENT_OVERLAP_FRONT: + sectors = bkey_start_offset(k.k) - + insert->k->k.p.offset; + break; + case BCH_EXTENT_OVERLAP_MIDDLE: + sectors = k.k->p.offset - insert->k->k.p.offset; + BUG_ON(sectors <= 0); + + pr_info("adding %lli", sectors); + sectors = bkey_start_offset(&insert->k->k) - + k.k->p.offset; + break; + } + } + + bch2_bkey_val_to_text(c, btree_node_type(b), + buf, sizeof(buf), k); + pr_info("subtracting %lli\n%s", sectors, buf); + + bch2_mark_key(c, btree_node_type(b), k, + false, sectors, + pos, &stats, trans->journal_res.seq, 0); + + bch2_btree_node_iter_advance(&node_iter, b); + } + } + bch2_fs_usage_apply(c, &stats, trans->disk_res, pos); } |