diff options
Diffstat (limited to 'libbcachefs/buckets.c')
-rw-r--r-- | libbcachefs/buckets.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c index 396251d5..f9d41ffc 100644 --- a/libbcachefs/buckets.c +++ b/libbcachefs/buckets.c @@ -353,38 +353,45 @@ void bch2_mark_alloc_bucket(struct bch_dev *ca, struct bucket *g, })); } +#define saturated_add(ca, dst, src, max) \ +do { \ + BUG_ON((int) (dst) + (src) < 0); \ + if ((dst) == (max)) \ + ; \ + else if ((dst) + (src) <= (max)) \ + dst += (src); \ + else { \ + dst = (max); \ + trace_sectors_saturated(ca); \ + } \ +} while (0) + void bch2_mark_metadata_bucket(struct bch_dev *ca, struct bucket *g, - enum bucket_data_type type, - bool may_make_unavailable) + enum bucket_data_type type, + bool may_make_unavailable) { struct bucket_mark old, new; BUG_ON(!type); old = bucket_data_cmpxchg(ca, g, new, ({ + saturated_add(ca, new.dirty_sectors, ca->mi.bucket_size, + GC_MAX_SECTORS_USED); new.data_type = type; new.had_metadata = 1; })); - BUG_ON(old.cached_sectors); - BUG_ON(old.dirty_sectors); + if (old.data_type != type && + (old.data_type || + old.cached_sectors || + old.dirty_sectors)) + bch_err(ca->fs, "bucket %zu has multiple types of data (%u, %u)", + g - ca->buckets, old.data_type, new.data_type); + BUG_ON(!may_make_unavailable && bucket_became_unavailable(ca->fs, old, new)); } -#define saturated_add(ca, dst, src, max) \ -do { \ - BUG_ON((int) (dst) + (src) < 0); \ - if ((dst) == (max)) \ - ; \ - else if ((dst) + (src) <= (max)) \ - dst += (src); \ - else { \ - dst = (max); \ - trace_sectors_saturated(ca); \ - } \ -} while (0) - #if 0 /* Reverting this until the copygc + compression issue is fixed: */ @@ -431,6 +438,8 @@ static void bch2_mark_pointer(struct bch_fs *c, unsigned saturated; struct bch_dev *ca = c->devs[ptr->dev]; struct bucket *g = ca->buckets + PTR_BUCKET_NR(ca, ptr); + unsigned data_type = type == S_META + ? BUCKET_BTREE : BUCKET_DATA; unsigned old_sectors, new_sectors; int disk_sectors, compressed_sectors; @@ -494,13 +503,19 @@ static void bch2_mark_pointer(struct bch_fs *c, new.journal_seq = journal_seq; } } else { - new.data_type = type == S_META - ? BUCKET_BTREE : BUCKET_DATA; + new.data_type = data_type; } new.had_metadata |= is_meta_bucket(new); })); + if (old.data_type != data_type && + (old.data_type || + old.cached_sectors || + old.dirty_sectors)) + bch_err(ca->fs, "bucket %zu has multiple types of data (%u, %u)", + g - ca->buckets, old.data_type, new.data_type); + BUG_ON(!may_make_unavailable && bucket_became_unavailable(c, old, new)); |