Commit d62ab355 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix bch2_trans_mark_dev_sb()

Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 73a117d2
...@@ -254,9 +254,9 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, ...@@ -254,9 +254,9 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c,
{ {
struct bkey_alloc_unpacked u = bch2_alloc_unpack(k); struct bkey_alloc_unpacked u = bch2_alloc_unpack(k);
pr_buf(out, "gen %u oldest_gen %u data_type %u", pr_buf(out, "gen %u oldest_gen %u data_type %s",
u.gen, u.oldest_gen, u.data_type); u.gen, u.oldest_gen, bch2_data_types[u.data_type]);
#define x(_name, ...) pr_buf(out, #_name " %llu ", (u64) u._name); #define x(_name, ...) pr_buf(out, " " #_name " %llu", (u64) u._name);
BCH_ALLOC_FIELDS_V2() BCH_ALLOC_FIELDS_V2()
#undef x #undef x
} }
......
...@@ -2024,22 +2024,6 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans, ...@@ -2024,22 +2024,6 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
goto out; goto out;
} }
if ((unsigned) (u.dirty_sectors + sectors) > ca->mi.bucket_size) {
bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
"bucket %llu:%llu gen %u data type %s sector count overflow: %u + %u > %u\n"
"while marking %s",
iter->pos.inode, iter->pos.offset, u.gen,
bch2_data_types[u.data_type ?: type],
u.dirty_sectors, sectors, ca->mi.bucket_size,
bch2_data_types[type]);
ret = -EIO;
goto out;
}
if (u.data_type == type &&
u.dirty_sectors == sectors)
goto out;
u.data_type = type; u.data_type = type;
u.dirty_sectors = sectors; u.dirty_sectors = sectors;
...@@ -2051,53 +2035,44 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans, ...@@ -2051,53 +2035,44 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
} }
int bch2_trans_mark_metadata_bucket(struct btree_trans *trans, int bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
struct disk_reservation *res,
struct bch_dev *ca, size_t b, struct bch_dev *ca, size_t b,
enum bch_data_type type, enum bch_data_type type,
unsigned sectors) unsigned sectors)
{ {
return __bch2_trans_do(trans, res, NULL, 0, return __bch2_trans_do(trans, NULL, NULL, 0,
__bch2_trans_mark_metadata_bucket(trans, ca, b, BCH_DATA_journal, __bch2_trans_mark_metadata_bucket(trans, ca, b, type, sectors));
ca->mi.bucket_size));
} }
static int bch2_trans_mark_metadata_sectors(struct btree_trans *trans, static int bch2_trans_mark_metadata_sectors(struct btree_trans *trans,
struct disk_reservation *res,
struct bch_dev *ca, struct bch_dev *ca,
u64 start, u64 end, u64 start, u64 end,
enum bch_data_type type, enum bch_data_type type,
u64 *bucket, unsigned *bucket_sectors) u64 *bucket, unsigned *bucket_sectors)
{ {
int ret;
do { do {
u64 b = sector_to_bucket(ca, start); u64 b = sector_to_bucket(ca, start);
unsigned sectors = unsigned sectors =
min_t(u64, bucket_to_sector(ca, b + 1), end) - start; min_t(u64, bucket_to_sector(ca, b + 1), end) - start;
if (b != *bucket) { if (b != *bucket && *bucket_sectors) {
if (*bucket_sectors) { int ret = bch2_trans_mark_metadata_bucket(trans, ca, *bucket,
ret = bch2_trans_mark_metadata_bucket(trans, res, ca, type, *bucket_sectors);
*bucket, type, *bucket_sectors); if (ret)
if (ret) return ret;
return ret;
}
*bucket = b; *bucket_sectors = 0;
*bucket_sectors = 0;
} }
*bucket = b;
*bucket_sectors += sectors; *bucket_sectors += sectors;
start += sectors; start += sectors;
} while (!ret && start < end); } while (start < end);
return 0; return 0;
} }
static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
struct disk_reservation *res, struct bch_dev *ca)
struct bch_dev *ca)
{ {
struct bch_sb_layout *layout = &ca->disk_sb.sb->layout; struct bch_sb_layout *layout = &ca->disk_sb.sb->layout;
u64 bucket = 0; u64 bucket = 0;
...@@ -2108,14 +2083,14 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, ...@@ -2108,14 +2083,14 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
u64 offset = le64_to_cpu(layout->sb_offset[i]); u64 offset = le64_to_cpu(layout->sb_offset[i]);
if (offset == BCH_SB_SECTOR) { if (offset == BCH_SB_SECTOR) {
ret = bch2_trans_mark_metadata_sectors(trans, res, ca, ret = bch2_trans_mark_metadata_sectors(trans, ca,
0, BCH_SB_SECTOR, 0, BCH_SB_SECTOR,
BCH_DATA_sb, &bucket, &bucket_sectors); BCH_DATA_sb, &bucket, &bucket_sectors);
if (ret) if (ret)
return ret; return ret;
} }
ret = bch2_trans_mark_metadata_sectors(trans, res, ca, offset, ret = bch2_trans_mark_metadata_sectors(trans, ca, offset,
offset + (1 << layout->sb_max_size_bits), offset + (1 << layout->sb_max_size_bits),
BCH_DATA_sb, &bucket, &bucket_sectors); BCH_DATA_sb, &bucket, &bucket_sectors);
if (ret) if (ret)
...@@ -2123,14 +2098,14 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, ...@@ -2123,14 +2098,14 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
} }
if (bucket_sectors) { if (bucket_sectors) {
ret = bch2_trans_mark_metadata_bucket(trans, res, ca, ret = bch2_trans_mark_metadata_bucket(trans, ca,
bucket, BCH_DATA_sb, bucket_sectors); bucket, BCH_DATA_sb, bucket_sectors);
if (ret) if (ret)
return ret; return ret;
} }
for (i = 0; i < ca->journal.nr; i++) { for (i = 0; i < ca->journal.nr; i++) {
ret = bch2_trans_mark_metadata_bucket(trans, res, ca, ret = bch2_trans_mark_metadata_bucket(trans, ca,
ca->journal.buckets[i], ca->journal.buckets[i],
BCH_DATA_journal, ca->mi.bucket_size); BCH_DATA_journal, ca->mi.bucket_size);
if (ret) if (ret)
...@@ -2140,12 +2115,10 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, ...@@ -2140,12 +2115,10 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
return 0; return 0;
} }
int bch2_trans_mark_dev_sb(struct bch_fs *c, int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca)
struct disk_reservation *res,
struct bch_dev *ca)
{ {
return bch2_trans_do(c, res, NULL, 0, return bch2_trans_do(c, NULL, NULL, 0,
__bch2_trans_mark_dev_sb(&trans, res, ca)); __bch2_trans_mark_dev_sb(&trans, ca));
} }
/* Disk reservations: */ /* Disk reservations: */
......
...@@ -253,11 +253,9 @@ int bch2_trans_mark_update(struct btree_trans *, struct btree_iter *iter, ...@@ -253,11 +253,9 @@ int bch2_trans_mark_update(struct btree_trans *, struct btree_iter *iter,
struct bkey_i *insert, unsigned); struct bkey_i *insert, unsigned);
void bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *); void bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *);
int bch2_trans_mark_metadata_bucket(struct btree_trans *, int bch2_trans_mark_metadata_bucket(struct btree_trans *, struct bch_dev *,
struct disk_reservation *, struct bch_dev *, size_t, enum bch_data_type, unsigned);
size_t, enum bch_data_type, unsigned); int bch2_trans_mark_dev_sb(struct bch_fs *, struct bch_dev *);
int bch2_trans_mark_dev_sb(struct bch_fs *, struct disk_reservation *,
struct bch_dev *);
/* disk reservations: */ /* disk reservations: */
......
...@@ -59,6 +59,11 @@ struct bch_dev_usage { ...@@ -59,6 +59,11 @@ struct bch_dev_usage {
struct { struct {
u64 buckets; u64 buckets;
u64 sectors; /* _compressed_ sectors: */ u64 sectors; /* _compressed_ sectors: */
/*
* XXX
* Why do we have this? Isn't it just buckets * bucket_size -
* sectors?
*/
u64 fragmented; u64 fragmented;
} d[BCH_DATA_NR]; } d[BCH_DATA_NR];
}; };
......
...@@ -864,7 +864,7 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr, ...@@ -864,7 +864,7 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
if (c && !new_fs) if (c && !new_fs)
ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL, ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
bch2_trans_mark_metadata_bucket(&trans, NULL, ca, bch2_trans_mark_metadata_bucket(&trans, ca,
bucket, BCH_DATA_journal, bucket, BCH_DATA_journal,
ca->mi.bucket_size)); ca->mi.bucket_size));
......
...@@ -1333,10 +1333,12 @@ int bch2_fs_initialize(struct bch_fs *c) ...@@ -1333,10 +1333,12 @@ int bch2_fs_initialize(struct bch_fs *c)
* Write out the superblock and journal buckets, now that we can do * Write out the superblock and journal buckets, now that we can do
* btree updates * btree updates
*/ */
err = "error writing alloc info"; err = "error marking superblock and journal";
ret = bch2_alloc_write(c, 0); for_each_member_device(ca, c, i) {
if (ret) ret = bch2_trans_mark_dev_sb(c, ca);
goto err; if (ret)
goto err;
}
bch2_inode_init(c, &root_inode, 0, 0, bch2_inode_init(c, &root_inode, 0, 0,
S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0, NULL); S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0, NULL);
......
...@@ -1670,7 +1670,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path) ...@@ -1670,7 +1670,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
bch2_dev_usage_journal_reserve(c); bch2_dev_usage_journal_reserve(c);
err = "error marking superblock"; err = "error marking superblock";
ret = bch2_trans_mark_dev_sb(c, NULL, ca); ret = bch2_trans_mark_dev_sb(c, ca);
if (ret) if (ret)
goto err_late; goto err_late;
...@@ -1730,7 +1730,7 @@ int bch2_dev_online(struct bch_fs *c, const char *path) ...@@ -1730,7 +1730,7 @@ int bch2_dev_online(struct bch_fs *c, const char *path)
ca = bch_dev_locked(c, dev_idx); ca = bch_dev_locked(c, dev_idx);
if (bch2_trans_mark_dev_sb(c, NULL, ca)) { if (bch2_trans_mark_dev_sb(c, ca)) {
err = "bch2_trans_mark_dev_sb() error"; err = "bch2_trans_mark_dev_sb() error";
goto err; goto err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment