/* Stripes btree keys: */
int bch2_stripe_invalid(const struct bch_fs *c, struct bkey_s_c k,
- unsigned flags, struct printbuf *err)
+ enum bkey_invalid_flags flags,
+ struct printbuf *err)
{
const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
return -BCH_ERR_invalid_bkey;
}
- if (bkey_val_bytes(k.k) < sizeof(*s)) {
- prt_printf(err, "incorrect value size (%zu < %zu)",
- bkey_val_bytes(k.k), sizeof(*s));
- return -BCH_ERR_invalid_bkey;
- }
-
if (bkey_val_u64s(k.k) < stripe_val_u64s(s)) {
prt_printf(err, "incorrect value size (%zu < %u)",
bkey_val_u64s(k.k), stripe_val_u64s(s));
}
static void ec_block_io(struct bch_fs *c, struct ec_stripe_buf *buf,
- unsigned rw, unsigned idx, struct closure *cl)
+ blk_opf_t opf, unsigned idx, struct closure *cl)
{
struct bch_stripe *v = &buf->key.v;
unsigned offset = 0, bytes = buf->size << 9;
enum bch_data_type data_type = idx < buf->key.v.nr_blocks - buf->key.v.nr_redundant
? BCH_DATA_user
: BCH_DATA_parity;
+ int rw = op_is_write(opf);
if (ptr_stale(ca, ptr)) {
bch_err_ratelimited(c,
ec_bio = container_of(bio_alloc_bioset(ca->disk_sb.bdev,
nr_iovecs,
- rw,
+ opf,
GFP_KERNEL,
&c->ec_bioset),
struct ec_bio, bio);
struct bkey_s_c k;
int ret;
- bch2_trans_iter_init(trans, &iter, BTREE_ID_stripes,
- POS(0, idx), BTREE_ITER_SLOTS);
- k = bch2_btree_iter_peek_slot(&iter);
+ k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes,
+ POS(0, idx), BTREE_ITER_SLOTS);
ret = bkey_err(k);
if (ret)
goto err;
BUG_ON(!rbio->pick.has_ec);
- buf = kzalloc(sizeof(*buf), GFP_NOIO);
+ buf = kzalloc(sizeof(*buf), GFP_NOFS);
if (!buf)
return -BCH_ERR_ENOMEM_ec_read_extent;
static int ec_stripe_mem_alloc(struct btree_trans *trans,
struct btree_iter *iter)
{
- size_t idx = iter->pos.offset;
-
- if (!__ec_stripe_mem_alloc(trans->c, idx, GFP_NOWAIT|__GFP_NOWARN))
- return 0;
-
- bch2_trans_unlock(trans);
-
- return __ec_stripe_mem_alloc(trans->c, idx, GFP_KERNEL) ?:
- bch2_trans_relock(trans);
+ return allocate_dropping_locks_errcode(trans,
+ __ec_stripe_mem_alloc(trans->c, iter->pos.offset, _gfp));
}
/*
struct bkey_s_c_stripe s;
int ret;
- bch2_trans_iter_init(trans, &iter, BTREE_ID_stripes, POS(0, idx),
- BTREE_ITER_INTENT);
- k = bch2_btree_iter_peek_slot(&iter);
+ k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes, POS(0, idx),
+ BTREE_ITER_INTENT);
ret = bkey_err(k);
if (ret)
goto err;
ret = commit_do(&trans, NULL, NULL, BTREE_INSERT_NOFAIL,
ec_stripe_delete(&trans, idx));
if (ret) {
- bch_err(c, "%s: err %s", __func__, bch2_err_str(ret));
+ bch_err_fn(c, ret);
break;
}
}
void bch2_do_stripe_deletes(struct bch_fs *c)
{
if (bch2_write_ref_tryget(c, BCH_WRITE_REF_stripe_delete) &&
- !schedule_work(&c->ec_stripe_delete_work))
+ !queue_work(c->write_ref_wq, &c->ec_stripe_delete_work))
bch2_write_ref_put(c, BCH_WRITE_REF_stripe_delete);
}
struct bkey_s_c k;
int ret;
- bch2_trans_iter_init(trans, &iter, BTREE_ID_stripes,
- new->k.p, BTREE_ITER_INTENT);
- k = bch2_btree_iter_peek_slot(&iter);
+ k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes,
+ new->k.p, BTREE_ITER_INTENT);
ret = bkey_err(k);
if (ret)
goto err;
static int ec_stripe_update_extent(struct btree_trans *trans,
struct bpos bucket, u8 gen,
struct ec_stripe_buf *s,
- u64 *bp_offset)
+ struct bpos *bp_pos)
{
struct bch_fs *c = trans->c;
struct bch_backpointer bp;
int ret, dev, block;
ret = bch2_get_next_backpointer(trans, bucket, gen,
- bp_offset, &bp, BTREE_ITER_CACHED);
+ bp_pos, &bp, BTREE_ITER_CACHED);
if (ret)
return ret;
- if (*bp_offset == U64_MAX)
+ if (bpos_eq(*bp_pos, SPOS_MAX))
return 0;
if (bp.level) {
struct btree_iter node_iter;
struct btree *b;
- b = bch2_backpointer_get_node(trans, &node_iter, bucket, *bp_offset, bp);
+ b = bch2_backpointer_get_node(trans, &node_iter, *bp_pos, bp);
bch2_trans_iter_exit(trans, &node_iter);
if (!b)
return -EIO;
}
- k = bch2_backpointer_get_key(trans, &iter, bucket, *bp_offset, bp);
+ k = bch2_backpointer_get_key(trans, &iter, *bp_pos, bp, BTREE_ITER_INTENT);
ret = bkey_err(k);
if (ret)
return ret;
struct bch_fs *c = trans->c;
struct bch_extent_ptr bucket = s->key.v.ptrs[block];
struct bpos bucket_pos = PTR_BUCKET_POS(c, &bucket);
- u64 bp_offset = 0;
+ struct bpos bp_pos = POS_MIN;
int ret = 0;
while (1) {
BTREE_INSERT_NOCHECK_RW|
BTREE_INSERT_NOFAIL,
ec_stripe_update_extent(trans, bucket_pos, bucket.gen,
- s, &bp_offset));
+ s, &bp_pos));
if (ret)
break;
- if (bp_offset == U64_MAX)
+ if (bkey_eq(bp_pos, POS_MAX))
break;
- bp_offset++;
+ bp_pos = bpos_nosnap_successor(bp_pos);
}
return ret;
int ret;
if (!bch2_dev_get_ioref(ca, WRITE)) {
- s->err = -EROFS;
+ s->err = -BCH_ERR_erofs_no_writes;
return;
}
mutex_lock(&c->ec_stripe_new_lock);
list_del(&s->list);
mutex_unlock(&c->ec_stripe_new_lock);
+ wake_up(&c->ec_stripe_new_wait);
ec_stripe_buf_exit(&s->existing_stripe);
ec_stripe_buf_exit(&s->new_stripe);
static struct ec_stripe_head *
ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
unsigned algo, unsigned redundancy,
- enum alloc_reserve reserve)
+ enum bch_watermark watermark)
{
struct ec_stripe_head *h;
struct bch_dev *ca;
h->target = target;
h->algo = algo;
h->redundancy = redundancy;
- h->reserve = reserve;
+ h->watermark = watermark;
rcu_read_lock();
h->devs = target_rw_devs(c, BCH_DATA_user, target);
mutex_unlock(&h->lock);
}
-struct ec_stripe_head *__bch2_ec_stripe_head_get(struct btree_trans *trans,
- unsigned target,
- unsigned algo,
- unsigned redundancy,
- enum alloc_reserve reserve)
+static struct ec_stripe_head *
+__bch2_ec_stripe_head_get(struct btree_trans *trans,
+ unsigned target,
+ unsigned algo,
+ unsigned redundancy,
+ enum bch_watermark watermark)
{
struct bch_fs *c = trans->c;
struct ec_stripe_head *h;
return ERR_PTR(ret);
if (test_bit(BCH_FS_GOING_RO, &c->flags)) {
- h = ERR_PTR(-EROFS);
+ h = ERR_PTR(-BCH_ERR_erofs_no_writes);
goto found;
}
if (h->target == target &&
h->algo == algo &&
h->redundancy == redundancy &&
- h->reserve == reserve) {
+ h->watermark == watermark) {
ret = bch2_trans_mutex_lock(trans, &h->lock);
if (ret)
h = ERR_PTR(ret);
goto found;
}
- h = ec_new_stripe_head_alloc(c, target, algo, redundancy, reserve);
+ h = ec_new_stripe_head_alloc(c, target, algo, redundancy, watermark);
found:
mutex_unlock(&c->ec_stripe_head_lock);
return h;
}
static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_head *h,
- enum alloc_reserve reserve, struct closure *cl)
+ enum bch_watermark watermark, struct closure *cl)
{
struct bch_fs *c = trans->c;
struct bch_devs_mask devs = h->devs;
&nr_have_parity,
&have_cache, 0,
BCH_DATA_parity,
- reserve,
+ watermark,
cl);
open_bucket_for_each(c, &buckets, ob, i) {
&nr_have_data,
&have_cache, 0,
BCH_DATA_user,
- reserve,
+ watermark,
cl);
open_bucket_for_each(c, &buckets, ob, i) {
}
BUG_ON(h->s->existing_stripe.size != h->blocksize);
- BUG_ON(h->s->existing_stripe.size != h->s->existing_stripe.key.v.sectors);
+ BUG_ON(h->s->existing_stripe.size != le16_to_cpu(h->s->existing_stripe.key.v.sectors));
/*
* Free buckets we initially allocated - they might conflict with
unsigned target,
unsigned algo,
unsigned redundancy,
- enum alloc_reserve reserve,
+ enum bch_watermark watermark,
struct closure *cl)
{
struct bch_fs *c = trans->c;
bool waiting = false;
int ret;
- h = __bch2_ec_stripe_head_get(trans, target, algo, redundancy, reserve);
+ h = __bch2_ec_stripe_head_get(trans, target, algo, redundancy, watermark);
if (!h)
bch_err(c, "no stripe head");
if (IS_ERR_OR_NULL(h))
goto alloc_existing;
/* First, try to allocate a full stripe: */
- ret = new_stripe_alloc_buckets(trans, h, RESERVE_stripe, NULL) ?:
+ ret = new_stripe_alloc_buckets(trans, h, BCH_WATERMARK_stripe, NULL) ?:
__bch2_ec_stripe_head_reserve(trans, h);
if (!ret)
goto allocate_buf;
if (waiting || !cl || ret != -BCH_ERR_stripe_alloc_blocked)
goto err;
- if (reserve == RESERVE_movinggc) {
- ret = new_stripe_alloc_buckets(trans, h, reserve, NULL) ?:
+ if (watermark == BCH_WATERMARK_copygc) {
+ ret = new_stripe_alloc_buckets(trans, h, watermark, NULL) ?:
__bch2_ec_stripe_head_reserve(trans, h);
if (ret)
goto err;
closure_wake_up(&c->freelist_wait);
alloc_existing:
/*
- * Retry allocating buckets, with the reserve watermark for this
+ * Retry allocating buckets, with the watermark for this
* particular write:
*/
- ret = new_stripe_alloc_buckets(trans, h, reserve, cl);
+ ret = new_stripe_alloc_buckets(trans, h, watermark, cl);
if (ret)
goto err;
}
goto unlock;
found:
- h->s->err = -EROFS;
+ h->s->err = -BCH_ERR_erofs_no_writes;
ec_stripe_set_pending(c, h);
unlock:
mutex_unlock(&h->lock);
bch2_trans_exit(&trans);
if (ret)
- bch_err(c, "error reading stripes: %i", ret);
+ bch_err_fn(c, ret);
return ret;
}
list_for_each_entry(h, &c->ec_stripe_head_list, list) {
prt_printf(out, "target %u algo %u redundancy %u %s:\n",
h->target, h->algo, h->redundancy,
- bch2_alloc_reserves[h->reserve]);
+ bch2_watermarks[h->watermark]);
if (h->s)
prt_printf(out, "\tidx %llu blocks %u+%u allocated %u\n",
s->idx, s->nr_data, s->nr_parity,
atomic_read(&s->ref[STRIPE_REF_io]),
atomic_read(&s->ref[STRIPE_REF_stripe]),
- bch2_alloc_reserves[s->h->reserve]);
+ bch2_watermarks[s->h->watermark]);
}
mutex_unlock(&c->ec_stripe_new_lock);
}