Skip to content

Commit

Permalink
Update bcachefs sources to 8c94740b1bf8 bcachefs: Add missing vaidati…
Browse files Browse the repository at this point in the history
…on for jset_entry_data_usage
  • Loading branch information
Kent Overstreet committed Nov 26, 2023
1 parent 138397d commit 3a0cc86
Show file tree
Hide file tree
Showing 36 changed files with 610 additions and 426 deletions.
2 changes: 1 addition & 1 deletion .bcachefs_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
783085c3cc440183ba5e987b1aa7791cc1ca42ba
8c94740b1bf8645d3398170f41c9c88b78332252
120 changes: 45 additions & 75 deletions libbcachefs/alloc_background.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,33 +261,30 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k,
case BCH_DATA_free:
case BCH_DATA_need_gc_gens:
case BCH_DATA_need_discard:
bkey_fsck_err_on(a.v->dirty_sectors ||
a.v->cached_sectors ||
a.v->stripe, c, err,
alloc_key_empty_but_have_data,
bkey_fsck_err_on(bch2_bucket_sectors(*a.v) || a.v->stripe,
c, err, alloc_key_empty_but_have_data,
"empty data type free but have data");
break;
case BCH_DATA_sb:
case BCH_DATA_journal:
case BCH_DATA_btree:
case BCH_DATA_user:
case BCH_DATA_parity:
bkey_fsck_err_on(!a.v->dirty_sectors, c, err,
alloc_key_dirty_sectors_0,
bkey_fsck_err_on(!bch2_bucket_sectors_dirty(*a.v),
c, err, alloc_key_dirty_sectors_0,
"data_type %s but dirty_sectors==0",
bch2_data_types[a.v->data_type]);
break;
case BCH_DATA_cached:
bkey_fsck_err_on(!a.v->cached_sectors ||
a.v->dirty_sectors ||
a.v->stripe, c, err,
alloc_key_cached_inconsistency,
bch2_bucket_sectors_dirty(*a.v) ||
a.v->stripe,
c, err, alloc_key_cached_inconsistency,
"data type inconsistency");

bkey_fsck_err_on(!a.v->io_time[READ] &&
c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_to_lru_refs,
c, err,
alloc_key_cached_but_read_time_zero,
c, err, alloc_key_cached_but_read_time_zero,
"cached bucket with read_time == 0");
break;
case BCH_DATA_stripe:
Expand Down Expand Up @@ -790,8 +787,7 @@ int bch2_trans_mark_alloc(struct btree_trans *trans,

new_a->data_type = alloc_data_type(*new_a, new_a->data_type);

if (new_a->dirty_sectors > old_a->dirty_sectors ||
new_a->cached_sectors > old_a->cached_sectors) {
if (bch2_bucket_sectors(*new_a) > bch2_bucket_sectors(*old_a)) {
new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now));
new_a->io_time[WRITE]= max_t(u64, 1, atomic64_read(&c->io_clock[WRITE].now));
SET_BCH_ALLOC_V4_NEED_INC_GEN(new_a, true);
Expand Down Expand Up @@ -1509,6 +1505,27 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
if (a->data_type != BCH_DATA_cached)
return 0;

if (fsck_err_on(!a->io_time[READ], c,
alloc_key_cached_but_read_time_zero,
"cached bucket with read_time 0\n"
" %s",
(printbuf_reset(&buf),
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
struct bkey_i_alloc_v4 *a_mut =
bch2_alloc_to_v4_mut(trans, alloc_k);
ret = PTR_ERR_OR_ZERO(a_mut);
if (ret)
goto err;

a_mut->v.io_time[READ] = atomic64_read(&c->io_clock[READ].now);
ret = bch2_trans_update(trans, alloc_iter,
&a_mut->k_i, BTREE_TRIGGER_NORUN);
if (ret)
goto err;

a = &a_mut->v;
}

lru_k = bch2_bkey_get_iter(trans, &lru_iter, BTREE_ID_lru,
lru_pos(alloc_k.k->p.inode,
bucket_to_u64(alloc_k.k->p),
Expand All @@ -1517,41 +1534,18 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
if (ret)
return ret;

if (fsck_err_on(!a->io_time[READ], c,
alloc_key_cached_but_read_time_zero,
"cached bucket with read_time 0\n"
" %s",
(printbuf_reset(&buf),
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf)) ||
fsck_err_on(lru_k.k->type != KEY_TYPE_set, c,
if (fsck_err_on(lru_k.k->type != KEY_TYPE_set, c,
alloc_key_to_missing_lru_entry,
"missing lru entry\n"
" %s",
(printbuf_reset(&buf),
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
u64 read_time = a->io_time[READ] ?:
atomic64_read(&c->io_clock[READ].now);

ret = bch2_lru_set(trans,
alloc_k.k->p.inode,
bucket_to_u64(alloc_k.k->p),
read_time);
a->io_time[READ]);
if (ret)
goto err;

if (a->io_time[READ] != read_time) {
struct bkey_i_alloc_v4 *a_mut =
bch2_alloc_to_v4_mut(trans, alloc_k);
ret = PTR_ERR_OR_ZERO(a_mut);
if (ret)
goto err;

a_mut->v.io_time[READ] = read_time;
ret = bch2_trans_update(trans, alloc_iter,
&a_mut->k_i, BTREE_TRIGGER_NORUN);
if (ret)
goto err;
}
}
err:
fsck_err:
Expand All @@ -1564,15 +1558,13 @@ int bch2_check_alloc_to_lru_refs(struct bch_fs *c)
{
struct btree_iter iter;
struct bkey_s_c k;
int ret = 0;

ret = bch2_trans_run(c,
int ret = bch2_trans_run(c,
for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
POS_MIN, BTREE_ITER_PREFETCH, k,
NULL, NULL, BCH_TRANS_COMMIT_no_enospc|BCH_TRANS_COMMIT_lazy_rw,
bch2_check_alloc_to_lru_ref(trans, &iter)));
if (ret)
bch_err_fn(c, ret);
bch_err_fn(c, ret);
return ret;
}

Expand Down Expand Up @@ -1734,28 +1726,25 @@ void bch2_do_discards(struct bch_fs *c)
static int invalidate_one_bucket(struct btree_trans *trans,
struct btree_iter *lru_iter,
struct bkey_s_c lru_k,
struct bpos *last_flushed_pos,
s64 *nr_to_invalidate)
{
struct bch_fs *c = trans->c;
struct btree_iter alloc_iter = { NULL };
struct bkey_i_alloc_v4 *a = NULL;
struct printbuf buf = PRINTBUF;
struct bpos bucket = u64_to_bucket(lru_k.k->p.offset);
unsigned cached_sectors;
int ret = 0;

if (*nr_to_invalidate <= 0)
return 1;

if (!bch2_dev_bucket_exists(c, bucket)) {
prt_str(&buf, "lru entry points to invalid bucket");
goto err;
}
ret = bch2_check_lru_key(trans, lru_iter, lru_k, last_flushed_pos);
if (ret)
return ret < 0 ? ret : 0;

struct bpos bucket = u64_to_bucket(lru_k.k->p.offset);
if (bch2_bucket_is_open_safe(c, bucket.inode, bucket.offset))
return 0;

a = bch2_trans_start_alloc_update(trans, &alloc_iter, bucket);
struct btree_iter alloc_iter;
struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, &alloc_iter, bucket);
ret = PTR_ERR_OR_ZERO(a);
if (ret)
goto out;
Expand All @@ -1769,7 +1758,7 @@ static int invalidate_one_bucket(struct btree_trans *trans,
if (!a->v.cached_sectors)
bch_err(c, "invalidating empty bucket, confused");

cached_sectors = a->v.cached_sectors;
unsigned cached_sectors = a->v.cached_sectors;

SET_BCH_ALLOC_V4_NEED_INC_GEN(&a->v, false);
a->v.gen++;
Expand All @@ -1791,28 +1780,7 @@ static int invalidate_one_bucket(struct btree_trans *trans,
--*nr_to_invalidate;
out:
bch2_trans_iter_exit(trans, &alloc_iter);
printbuf_exit(&buf);
return ret;
err:
prt_str(&buf, "\n lru key: ");
bch2_bkey_val_to_text(&buf, c, lru_k);

prt_str(&buf, "\n lru entry: ");
bch2_lru_pos_to_text(&buf, lru_iter->pos);

prt_str(&buf, "\n alloc key: ");
if (!a)
bch2_bpos_to_text(&buf, bucket);
else
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&a->k_i));

bch_err(c, "%s", buf.buf);
if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_lrus) {
bch2_inconsistent_error(c);
ret = -EINVAL;
}

goto out;
}

static void bch2_do_invalidates_work(struct work_struct *work)
Expand All @@ -1822,6 +1790,7 @@ static void bch2_do_invalidates_work(struct work_struct *work)
struct btree_trans *trans = bch2_trans_get(c);
struct btree_iter iter;
struct bkey_s_c k;
struct bpos last_flushed_pos = POS_MIN;
unsigned i;
int ret = 0;

Expand All @@ -1837,7 +1806,8 @@ static void bch2_do_invalidates_work(struct work_struct *work)
lru_pos(ca->dev_idx, 0, 0),
lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX),
BTREE_ITER_INTENT, k,
invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate));
invalidate_one_bucket(trans, &iter, k, &last_flushed_pos,
&nr_to_invalidate));

if (ret < 0) {
percpu_ref_put(&ca->ref);
Expand Down
23 changes: 21 additions & 2 deletions libbcachefs/alloc_background.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ static inline enum bch_data_type bucket_data_type(enum bch_data_type data_type)
return data_type == BCH_DATA_stripe ? BCH_DATA_user : data_type;
}

static inline unsigned bch2_bucket_sectors(struct bch_alloc_v4 a)
{
return a.dirty_sectors + a.cached_sectors;
}

static inline unsigned bch2_bucket_sectors_dirty(struct bch_alloc_v4 a)
{
return a.dirty_sectors;
}

static inline unsigned bch2_bucket_sectors_fragmented(struct bch_dev *ca,
struct bch_alloc_v4 a)
{
unsigned d = bch2_bucket_sectors_dirty(a);

return d ? max(0U, ca->mi.bucket_size - d) : 0;
}

static inline u64 alloc_lru_idx_read(struct bch_alloc_v4 a)
{
return a.data_type == BCH_DATA_cached ? a.io_time[READ] : 0;
Expand All @@ -90,10 +108,11 @@ static inline u64 alloc_lru_idx_fragmentation(struct bch_alloc_v4 a,
struct bch_dev *ca)
{
if (!data_type_movable(a.data_type) ||
a.dirty_sectors >= ca->mi.bucket_size)
!bch2_bucket_sectors_fragmented(ca, a))
return 0;

return div_u64((u64) a.dirty_sectors * (1ULL << 31), ca->mi.bucket_size);
u64 d = bch2_bucket_sectors_dirty(a);
return div_u64(d * (1ULL << 31), ca->mi.bucket_size);
}

static inline u64 alloc_freespace_genbits(struct bch_alloc_v4 a)
Expand Down
3 changes: 3 additions & 0 deletions libbcachefs/alloc_foreground.c
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,9 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
int ret;
int i;

if (!IS_ENABLED(CONFIG_BCACHEFS_ERASURE_CODING))
erasure_code = false;

BUG_ON(flags & BCH_WRITE_ONLY_SPECIFIED_DEVS);

BUG_ON(!nr_replicas || !nr_replicas_required);
Expand Down
2 changes: 1 addition & 1 deletion libbcachefs/bcachefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ struct bch_fs {
mempool_t compression_bounce[2];
mempool_t compress_workspace[BCH_COMPRESSION_TYPE_NR];
mempool_t decompress_workspace;
ZSTD_parameters zstd_params;
size_t zstd_workspace_size;

struct crypto_shash *sha256;
struct crypto_sync_skcipher *chacha20;
Expand Down
10 changes: 7 additions & 3 deletions libbcachefs/bcachefs_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ struct bpos {
#else
#error edit for your odd byteorder.
#endif
} __packed __aligned(4);
} __packed
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
__aligned(4)
#endif
;

#define KEY_INODE_MAX ((__u64)~0ULL)
#define KEY_OFFSET_MAX ((__u64)~0ULL)
Expand Down Expand Up @@ -2203,8 +2207,8 @@ struct jset_entry_dev_usage {
__le32 dev;
__u32 pad;

__le64 buckets_ec;
__le64 _buckets_unavailable; /* No longer used */
__le64 _buckets_ec; /* No longer used */
__le64 _buckets_unavailable; /* No longer used */

struct jset_entry_dev_usage_type d[];
};
Expand Down
17 changes: 16 additions & 1 deletion libbcachefs/bcachefs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ struct bch_ioctl_incremental {
#define BCH_IOCTL_SUBVOLUME_CREATE _IOW(0xbc, 16, struct bch_ioctl_subvolume)
#define BCH_IOCTL_SUBVOLUME_DESTROY _IOW(0xbc, 17, struct bch_ioctl_subvolume)

#define BCH_IOCTL_DEV_USAGE_V2 _IOWR(0xbc, 18, struct bch_ioctl_dev_usage_v2)

/* ioctl below act on a particular file, not the filesystem as a whole: */

#define BCHFS_IOC_REINHERIT_ATTRS _IOR(0xbc, 64, const char __user *)
Expand Down Expand Up @@ -298,7 +300,20 @@ struct bch_ioctl_dev_usage {
__u64 buckets;
__u64 sectors;
__u64 fragmented;
} d[BCH_DATA_NR];
} d[10];
};

struct bch_ioctl_dev_usage_v2 {
__u64 dev;
__u32 flags;
__u8 state;
__u8 nr_data_types;
__u8 pad[6];

__u32 bucket_size;
__u64 nr_buckets;

struct bch_ioctl_dev_usage_type d[0];
};

/*
Expand Down
3 changes: 0 additions & 3 deletions libbcachefs/btree_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,9 +1254,6 @@ static int bch2_gc_done(struct bch_fs *c,
copy_dev_field(dev_usage_fragmented_wrong,
d[i].fragmented, "%s fragmented", bch2_data_types[i]);
}

copy_dev_field(dev_usage_buckets_ec_wrong,
buckets_ec, "buckets_ec");
}

{
Expand Down
3 changes: 1 addition & 2 deletions libbcachefs/btree_trans_commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,6 @@ noinline static int
btree_key_can_insert_cached_slowpath(struct btree_trans *trans, unsigned flags,
struct btree_path *path, unsigned new_u64s)
{
struct bch_fs *c = trans->c;
struct btree_insert_entry *i;
struct bkey_cached *ck = (void *) path->l[0].b;
struct bkey_i *new_k;
Expand All @@ -372,7 +371,7 @@ btree_key_can_insert_cached_slowpath(struct btree_trans *trans, unsigned flags,

new_k = kmalloc(new_u64s * sizeof(u64), GFP_KERNEL);
if (!new_k) {
bch_err(c, "error allocating memory for key cache key, btree %s u64s %u",
bch_err(trans->c, "error allocating memory for key cache key, btree %s u64s %u",
bch2_btree_id_str(path->btree_id), new_u64s);
return -BCH_ERR_ENOMEM_btree_key_cache_insert;
}
Expand Down
Loading

0 comments on commit 3a0cc86

Please sign in to comment.