bcachefs: Heap allocate btree_trans
We're using more stack than we'd like in a number of functions, and btree_trans is the biggest object that we stack allocate. But we have to do a heap allocatation to initialize it anyways, so there's no real downside to heap allocating the entire thing. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
96dea3d599
commit
6bd68ec266
@ -279,18 +279,16 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct bch_hash_info hash = bch2_hash_info_init(c, &inode->ei_inode);
|
||||
struct xattr_search_key search = X_SEARCH(acl_to_xattr_type(type), "", 0);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bkey_s_c_xattr xattr;
|
||||
struct posix_acl *acl = NULL;
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_hash_lookup(&trans, &iter, bch2_xattr_hash_desc,
|
||||
ret = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
|
||||
&hash, inode_inum(inode), &search, 0);
|
||||
if (ret) {
|
||||
if (!bch2_err_matches(ret, ENOENT))
|
||||
@ -306,7 +304,7 @@ retry:
|
||||
}
|
||||
|
||||
xattr = bkey_s_c_to_xattr(k);
|
||||
acl = bch2_acl_from_disk(&trans, xattr_val(xattr.v),
|
||||
acl = bch2_acl_from_disk(trans, xattr_val(xattr.v),
|
||||
le16_to_cpu(xattr.v->x_val_len));
|
||||
|
||||
if (!IS_ERR(acl))
|
||||
@ -315,8 +313,8 @@ out:
|
||||
if (bch2_err_matches(PTR_ERR_OR_ZERO(acl), BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return acl;
|
||||
}
|
||||
|
||||
@ -356,7 +354,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
|
||||
{
|
||||
struct bch_inode_info *inode = to_bch_ei(dentry->d_inode);
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter inode_iter = { NULL };
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct posix_acl *acl;
|
||||
@ -364,12 +362,11 @@ int bch2_set_acl(struct mnt_idmap *idmap,
|
||||
int ret;
|
||||
|
||||
mutex_lock(&inode->ei_update_lock);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
acl = _acl;
|
||||
|
||||
ret = bch2_inode_peek(&trans, &inode_iter, &inode_u, inode_inum(inode),
|
||||
ret = bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode),
|
||||
BTREE_ITER_INTENT);
|
||||
if (ret)
|
||||
goto btree_err;
|
||||
@ -382,30 +379,30 @@ retry:
|
||||
goto btree_err;
|
||||
}
|
||||
|
||||
ret = bch2_set_acl_trans(&trans, inode_inum(inode), &inode_u, acl, type);
|
||||
ret = bch2_set_acl_trans(trans, inode_inum(inode), &inode_u, acl, type);
|
||||
if (ret)
|
||||
goto btree_err;
|
||||
|
||||
inode_u.bi_ctime = bch2_current_time(c);
|
||||
inode_u.bi_mode = mode;
|
||||
|
||||
ret = bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL, 0);
|
||||
ret = bch2_inode_write(trans, &inode_iter, &inode_u) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL, 0);
|
||||
btree_err:
|
||||
bch2_trans_iter_exit(&trans, &inode_iter);
|
||||
bch2_trans_iter_exit(trans, &inode_iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
if (unlikely(ret))
|
||||
goto err;
|
||||
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u,
|
||||
bch2_inode_update_after_write(trans, inode, &inode_u,
|
||||
ATTR_CTIME|ATTR_MODE);
|
||||
|
||||
set_cached_acl(&inode->v, type, acl);
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
mutex_unlock(&inode->ei_update_lock);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ void bch2_bucket_gens_to_text(struct printbuf *out, struct bch_fs *c, struct bke
|
||||
|
||||
int bch2_bucket_gens_init(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_alloc_v4 a;
|
||||
@ -559,9 +559,7 @@ int bch2_bucket_gens_init(struct bch_fs *c)
|
||||
u8 gen;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
/*
|
||||
* Not a fsck error because this is checked/repaired by
|
||||
@ -574,10 +572,10 @@ int bch2_bucket_gens_init(struct bch_fs *c)
|
||||
pos = alloc_gens_pos(iter.pos, &offset);
|
||||
|
||||
if (have_bucket_gens_key && bkey_cmp(iter.pos, pos)) {
|
||||
ret = commit_do(&trans, NULL, NULL,
|
||||
ret = commit_do(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL|
|
||||
BTREE_INSERT_LAZY_RW,
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_bucket_gens, &g.k_i, 0));
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_bucket_gens, &g.k_i, 0));
|
||||
if (ret)
|
||||
break;
|
||||
have_bucket_gens_key = false;
|
||||
@ -591,15 +589,15 @@ int bch2_bucket_gens_init(struct bch_fs *c)
|
||||
|
||||
g.v.gens[offset] = gen;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (have_bucket_gens_key && !ret)
|
||||
ret = commit_do(&trans, NULL, NULL,
|
||||
ret = commit_do(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL|
|
||||
BTREE_INSERT_LAZY_RW,
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_bucket_gens, &g.k_i, 0));
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_bucket_gens, &g.k_i, 0));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
@ -608,20 +606,19 @@ int bch2_bucket_gens_init(struct bch_fs *c)
|
||||
|
||||
int bch2_alloc_read(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_dev *ca;
|
||||
int ret;
|
||||
|
||||
down_read(&c->gc_lock);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_bucket_gens) {
|
||||
const struct bch_bucket_gens *g;
|
||||
u64 b;
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_bucket_gens, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_bucket_gens, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
u64 start = bucket_gens_pos_to_alloc(k.k->p, 0).offset;
|
||||
u64 end = bucket_gens_pos_to_alloc(bpos_nosnap_successor(k.k->p), 0).offset;
|
||||
@ -645,11 +642,11 @@ int bch2_alloc_read(struct bch_fs *c)
|
||||
b++)
|
||||
*bucket_gen(ca, b) = g->gens[b & KEY_TYPE_BUCKET_GENS_MASK];
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
} else {
|
||||
struct bch_alloc_v4 a;
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
/*
|
||||
* Not a fsck error because this is checked/repaired by
|
||||
@ -662,10 +659,10 @@ int bch2_alloc_read(struct bch_fs *c)
|
||||
|
||||
*bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
up_read(&c->gc_lock);
|
||||
|
||||
if (ret)
|
||||
@ -1371,27 +1368,25 @@ fsck_err:
|
||||
|
||||
int bch2_check_alloc_info(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter, discard_iter, freespace_iter, bucket_gens_iter;
|
||||
struct bkey hole;
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_alloc, POS_MIN,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc, POS_MIN,
|
||||
BTREE_ITER_PREFETCH);
|
||||
bch2_trans_iter_init(&trans, &discard_iter, BTREE_ID_need_discard, POS_MIN,
|
||||
bch2_trans_iter_init(trans, &discard_iter, BTREE_ID_need_discard, POS_MIN,
|
||||
BTREE_ITER_PREFETCH);
|
||||
bch2_trans_iter_init(&trans, &freespace_iter, BTREE_ID_freespace, POS_MIN,
|
||||
bch2_trans_iter_init(trans, &freespace_iter, BTREE_ID_freespace, POS_MIN,
|
||||
BTREE_ITER_PREFETCH);
|
||||
bch2_trans_iter_init(&trans, &bucket_gens_iter, BTREE_ID_bucket_gens, POS_MIN,
|
||||
bch2_trans_iter_init(trans, &bucket_gens_iter, BTREE_ID_bucket_gens, POS_MIN,
|
||||
BTREE_ITER_PREFETCH);
|
||||
|
||||
while (1) {
|
||||
struct bpos next;
|
||||
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
k = bch2_get_key_or_real_bucket_hole(&iter, &hole);
|
||||
ret = bkey_err(k);
|
||||
@ -1404,7 +1399,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
|
||||
if (k.k->type) {
|
||||
next = bpos_nosnap_successor(k.k->p);
|
||||
|
||||
ret = bch2_check_alloc_key(&trans,
|
||||
ret = bch2_check_alloc_key(trans,
|
||||
k, &iter,
|
||||
&discard_iter,
|
||||
&freespace_iter,
|
||||
@ -1414,11 +1409,11 @@ int bch2_check_alloc_info(struct bch_fs *c)
|
||||
} else {
|
||||
next = k.k->p;
|
||||
|
||||
ret = bch2_check_alloc_hole_freespace(&trans,
|
||||
ret = bch2_check_alloc_hole_freespace(trans,
|
||||
bkey_start_pos(k.k),
|
||||
&next,
|
||||
&freespace_iter) ?:
|
||||
bch2_check_alloc_hole_bucket_gens(&trans,
|
||||
bch2_check_alloc_hole_bucket_gens(trans,
|
||||
bkey_start_pos(k.k),
|
||||
&next,
|
||||
&bucket_gens_iter);
|
||||
@ -1426,7 +1421,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
|
||||
goto bkey_err;
|
||||
}
|
||||
|
||||
ret = bch2_trans_commit(&trans, NULL, NULL,
|
||||
ret = bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL|
|
||||
BTREE_INSERT_LAZY_RW);
|
||||
if (ret)
|
||||
@ -1439,29 +1434,29 @@ bkey_err:
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &bucket_gens_iter);
|
||||
bch2_trans_iter_exit(&trans, &freespace_iter);
|
||||
bch2_trans_iter_exit(&trans, &discard_iter);
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &bucket_gens_iter);
|
||||
bch2_trans_iter_exit(trans, &freespace_iter);
|
||||
bch2_trans_iter_exit(trans, &discard_iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = for_each_btree_key2(&trans, iter,
|
||||
ret = for_each_btree_key2(trans, iter,
|
||||
BTREE_ID_need_discard, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
bch2_check_discard_freespace_key(&trans, &iter, k.k->p)) ?:
|
||||
for_each_btree_key2(&trans, iter,
|
||||
bch2_check_discard_freespace_key(trans, &iter, k.k->p)) ?:
|
||||
for_each_btree_key2(trans, iter,
|
||||
BTREE_ID_freespace, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
bch2_check_discard_freespace_key(&trans, &iter, k.k->p)) ?:
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
bch2_check_discard_freespace_key(trans, &iter, k.k->p)) ?:
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_bucket_gens, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
|
||||
bch2_check_bucket_gens_key(&trans, &iter, k));
|
||||
bch2_check_bucket_gens_key(trans, &iter, k));
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1547,10 +1542,10 @@ int bch2_check_alloc_to_lru_refs(struct bch_fs *c)
|
||||
int ret = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
|
||||
for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
|
||||
POS_MIN, BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
|
||||
bch2_check_alloc_to_lru_ref(&trans, &iter)));
|
||||
bch2_check_alloc_to_lru_ref(trans, &iter)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1675,29 +1670,25 @@ out:
|
||||
static void bch2_do_discards_work(struct work_struct *work)
|
||||
{
|
||||
struct bch_fs *c = container_of(work, struct bch_fs, discard_work);
|
||||
struct btree_trans trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
u64 seen = 0, open = 0, need_journal_commit = 0, discarded = 0;
|
||||
struct bpos discard_pos_done = POS_MAX;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
/*
|
||||
* We're doing the commit in bch2_discard_one_bucket instead of using
|
||||
* for_each_btree_key_commit() so that we can increment counters after
|
||||
* successful commit:
|
||||
*/
|
||||
ret = for_each_btree_key2(&trans, iter,
|
||||
BTREE_ID_need_discard, POS_MIN, 0, k,
|
||||
bch2_discard_one_bucket(&trans, &iter, &discard_pos_done,
|
||||
&seen,
|
||||
&open,
|
||||
&need_journal_commit,
|
||||
&discarded));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key2(trans, iter,
|
||||
BTREE_ID_need_discard, POS_MIN, 0, k,
|
||||
bch2_discard_one_bucket(trans, &iter, &discard_pos_done,
|
||||
&seen,
|
||||
&open,
|
||||
&need_journal_commit,
|
||||
&discarded)));
|
||||
|
||||
if (need_journal_commit * 2 > seen)
|
||||
bch2_journal_flush_async(&c->journal, NULL);
|
||||
@ -1803,15 +1794,13 @@ static void bch2_do_invalidates_work(struct work_struct *work)
|
||||
{
|
||||
struct bch_fs *c = container_of(work, struct bch_fs, invalidate_work);
|
||||
struct bch_dev *ca;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
ret = bch2_btree_write_buffer_flush(&trans);
|
||||
ret = bch2_btree_write_buffer_flush(trans);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -1819,11 +1808,11 @@ static void bch2_do_invalidates_work(struct work_struct *work)
|
||||
s64 nr_to_invalidate =
|
||||
should_invalidate_buckets(ca, bch2_dev_usage_read(ca));
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_lru,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_lru,
|
||||
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, &nr_to_invalidate));
|
||||
|
||||
if (ret < 0) {
|
||||
percpu_ref_put(&ca->ref);
|
||||
@ -1831,7 +1820,7 @@ static void bch2_do_invalidates_work(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
|
||||
}
|
||||
|
||||
@ -1845,7 +1834,7 @@ void bch2_do_invalidates(struct bch_fs *c)
|
||||
static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
unsigned long *last_updated)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey hole;
|
||||
@ -1853,9 +1842,7 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
struct bch_member *m;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_alloc,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
|
||||
POS(ca->dev_idx, ca->mi.first_bucket),
|
||||
BTREE_ITER_PREFETCH);
|
||||
/*
|
||||
@ -1869,7 +1856,7 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
*last_updated = jiffies;
|
||||
}
|
||||
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
if (bkey_ge(iter.pos, end)) {
|
||||
ret = 0;
|
||||
@ -1889,8 +1876,8 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
struct bch_alloc_v4 a_convert;
|
||||
const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &a_convert);
|
||||
|
||||
ret = bch2_bucket_do_index(&trans, k, a, true) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL,
|
||||
ret = bch2_bucket_do_index(trans, k, a, true) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_LAZY_RW|
|
||||
BTREE_INSERT_NOFAIL);
|
||||
if (ret)
|
||||
@ -1900,7 +1887,7 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
} else {
|
||||
struct bkey_i *freespace;
|
||||
|
||||
freespace = bch2_trans_kmalloc(&trans, sizeof(*freespace));
|
||||
freespace = bch2_trans_kmalloc(trans, sizeof(*freespace));
|
||||
ret = PTR_ERR_OR_ZERO(freespace);
|
||||
if (ret)
|
||||
goto bkey_err;
|
||||
@ -1910,8 +1897,8 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
freespace->k.p = k.k->p;
|
||||
freespace->k.size = k.k->size;
|
||||
|
||||
ret = bch2_btree_insert_trans(&trans, BTREE_ID_freespace, freespace, 0) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL,
|
||||
ret = bch2_btree_insert_trans(trans, BTREE_ID_freespace, freespace, 0) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_LAZY_RW|
|
||||
BTREE_INSERT_NOFAIL);
|
||||
if (ret)
|
||||
@ -1926,8 +1913,8 @@ bkey_err:
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret < 0) {
|
||||
bch_err_msg(ca, ret, "initializing free space");
|
||||
|
@ -602,7 +602,7 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca,
|
||||
struct open_bucket *ob;
|
||||
|
||||
bch2_trans_do(c, NULL, NULL, 0,
|
||||
PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(&trans, ca, watermark,
|
||||
PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark,
|
||||
cl, &usage)));
|
||||
return ob;
|
||||
}
|
||||
|
@ -390,10 +390,10 @@ int bch2_check_btree_backpointers(struct bch_fs *c)
|
||||
int ret;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_backpointers, POS_MIN, 0, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
bch2_check_btree_backpointer(&trans, &iter, k)));
|
||||
bch2_check_btree_backpointer(trans, &iter, k)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -723,13 +723,12 @@ static int bch2_get_alloc_in_memory_pos(struct btree_trans *trans,
|
||||
|
||||
int bch2_check_extents_to_backpointers(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bpos start = POS_MIN, end;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
while (1) {
|
||||
ret = bch2_get_alloc_in_memory_pos(&trans, start, &end);
|
||||
ret = bch2_get_alloc_in_memory_pos(trans, start, &end);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
@ -749,13 +748,13 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c)
|
||||
printbuf_exit(&buf);
|
||||
}
|
||||
|
||||
ret = bch2_check_extents_to_backpointers_pass(&trans, start, end);
|
||||
ret = bch2_check_extents_to_backpointers_pass(trans, start, end);
|
||||
if (ret || bpos_eq(end, SPOS_MAX))
|
||||
break;
|
||||
|
||||
start = bpos_successor(end);
|
||||
}
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
@ -824,13 +823,12 @@ static int bch2_check_backpointers_to_extents_pass(struct btree_trans *trans,
|
||||
|
||||
int bch2_check_backpointers_to_extents(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bbpos start = (struct bbpos) { .btree = 0, .pos = POS_MIN, }, end;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
while (1) {
|
||||
ret = bch2_get_btree_in_memory_pos(&trans,
|
||||
ret = bch2_get_btree_in_memory_pos(trans,
|
||||
(1U << BTREE_ID_extents)|
|
||||
(1U << BTREE_ID_reflink),
|
||||
~0,
|
||||
@ -856,13 +854,13 @@ int bch2_check_backpointers_to_extents(struct bch_fs *c)
|
||||
printbuf_exit(&buf);
|
||||
}
|
||||
|
||||
ret = bch2_check_backpointers_to_extents_pass(&trans, start, end);
|
||||
ret = bch2_check_backpointers_to_extents_pass(trans, start, end);
|
||||
if (ret || !bbpos_cmp(end, BBPOS_MAX))
|
||||
break;
|
||||
|
||||
start = bbpos_successor(end);
|
||||
}
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
|
@ -627,8 +627,8 @@ struct journal_keys {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct btree_path_buf {
|
||||
struct btree_path *path;
|
||||
struct btree_trans_buf {
|
||||
struct btree_trans *trans;
|
||||
};
|
||||
|
||||
#define REPLICAS_DELTA_LIST_MAX (1U << 16)
|
||||
@ -787,9 +787,9 @@ struct bch_fs {
|
||||
/* btree_iter.c: */
|
||||
struct seqmutex btree_trans_lock;
|
||||
struct list_head btree_trans_list;
|
||||
mempool_t btree_paths_pool;
|
||||
mempool_t btree_trans_pool;
|
||||
mempool_t btree_trans_mem_pool;
|
||||
struct btree_path_buf __percpu *btree_paths_bufs;
|
||||
struct btree_trans_buf __percpu *btree_trans_bufs;
|
||||
|
||||
struct srcu_struct btree_trans_barrier;
|
||||
bool btree_trans_barrier_initialized;
|
||||
|
@ -529,13 +529,11 @@ fsck_err:
|
||||
|
||||
int bch2_check_topology(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree *b;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < btree_id_nr_alive(c) && !ret; i++) {
|
||||
struct btree_root *r = bch2_btree_id_root(c, i);
|
||||
|
||||
@ -546,8 +544,8 @@ int bch2_check_topology(struct bch_fs *c)
|
||||
if (btree_node_fake(b))
|
||||
continue;
|
||||
|
||||
btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
|
||||
ret = bch2_btree_repair_topology_recurse(&trans, b);
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
|
||||
ret = bch2_btree_repair_topology_recurse(trans, b);
|
||||
six_unlock_read(&b->c.lock);
|
||||
|
||||
if (ret == DROP_THIS_NODE) {
|
||||
@ -556,7 +554,7 @@ int bch2_check_topology(struct bch_fs *c)
|
||||
}
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1068,35 +1066,33 @@ static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r)
|
||||
|
||||
static int bch2_gc_btrees(struct bch_fs *c, bool initial, bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
enum btree_id ids[BTREE_ID_NR];
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < BTREE_ID_NR; i++)
|
||||
ids[i] = i;
|
||||
bubble_sort(ids, BTREE_ID_NR, btree_id_gc_phase_cmp);
|
||||
|
||||
for (i = 0; i < BTREE_ID_NR && !ret; i++)
|
||||
ret = initial
|
||||
? bch2_gc_btree_init(&trans, ids[i], metadata_only)
|
||||
: bch2_gc_btree(&trans, ids[i], initial, metadata_only);
|
||||
? bch2_gc_btree_init(trans, ids[i], metadata_only)
|
||||
: bch2_gc_btree(trans, ids[i], initial, metadata_only);
|
||||
|
||||
for (i = BTREE_ID_NR; i < btree_id_nr_alive(c) && !ret; i++) {
|
||||
if (!bch2_btree_id_root(c, i)->alive)
|
||||
continue;
|
||||
|
||||
ret = initial
|
||||
? bch2_gc_btree_init(&trans, i, metadata_only)
|
||||
: bch2_gc_btree(&trans, i, initial, metadata_only);
|
||||
? bch2_gc_btree_init(trans, i, metadata_only)
|
||||
: bch2_gc_btree(trans, i, initial, metadata_only);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
bch_err_fn(c, ret);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1458,21 +1454,19 @@ fsck_err:
|
||||
|
||||
static int bch2_gc_alloc_done(struct bch_fs *c, bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_dev *ca;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for_each_member_device(ca, c, i) {
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
|
||||
POS(ca->dev_idx, ca->mi.first_bucket),
|
||||
BTREE_ITER_SLOTS|BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW,
|
||||
bch2_alloc_write_key(&trans, &iter, k, metadata_only));
|
||||
bch2_alloc_write_key(trans, &iter, k, metadata_only));
|
||||
|
||||
if (ret < 0) {
|
||||
bch_err_fn(c, ret);
|
||||
@ -1481,14 +1475,14 @@ static int bch2_gc_alloc_done(struct bch_fs *c, bool metadata_only)
|
||||
}
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
|
||||
{
|
||||
struct bch_dev *ca;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bucket *g;
|
||||
@ -1504,7 +1498,8 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
|
||||
if (!buckets) {
|
||||
percpu_ref_put(&ca->ref);
|
||||
bch_err(c, "error allocating ca->buckets[gc]");
|
||||
return -BCH_ERR_ENOMEM_gc_alloc_start;
|
||||
ret = -BCH_ERR_ENOMEM_gc_alloc_start;
|
||||
goto err;
|
||||
}
|
||||
|
||||
buckets->first_bucket = ca->mi.first_bucket;
|
||||
@ -1512,9 +1507,7 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
|
||||
rcu_assign_pointer(ca->buckets_gc, buckets);
|
||||
}
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
ca = bch_dev_bkey_exists(c, k.k->p.inode);
|
||||
g = gc_bucket(ca, k.k->p.offset);
|
||||
@ -1535,13 +1528,11 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
|
||||
g->stripe_redundancy = a->stripe_redundancy;
|
||||
}
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1616,7 +1607,7 @@ fsck_err:
|
||||
|
||||
static int bch2_gc_reflink_done(struct bch_fs *c, bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
size_t idx = 0;
|
||||
@ -1625,23 +1616,23 @@ static int bch2_gc_reflink_done(struct bch_fs *c, bool metadata_only)
|
||||
if (metadata_only)
|
||||
return 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter,
|
||||
ret = for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_reflink, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
bch2_gc_write_reflink_key(&trans, &iter, k, &idx));
|
||||
bch2_gc_write_reflink_key(trans, &iter, k, &idx));
|
||||
|
||||
c->reflink_gc_nr = 0;
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_gc_reflink_start(struct bch_fs *c,
|
||||
bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct reflink_gc *r;
|
||||
@ -1650,10 +1641,10 @@ static int bch2_gc_reflink_start(struct bch_fs *c,
|
||||
if (metadata_only)
|
||||
return 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
c->reflink_gc_nr = 0;
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_reflink, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_reflink, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
const __le64 *refcount = bkey_refcount_c(k);
|
||||
|
||||
@ -1671,9 +1662,9 @@ static int bch2_gc_reflink_start(struct bch_fs *c,
|
||||
r->size = k.k->size;
|
||||
r->refcount = 0;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1740,7 +1731,7 @@ fsck_err:
|
||||
|
||||
static int bch2_gc_stripes_done(struct bch_fs *c, bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
@ -1748,15 +1739,15 @@ static int bch2_gc_stripes_done(struct bch_fs *c, bool metadata_only)
|
||||
if (metadata_only)
|
||||
return 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter,
|
||||
ret = for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_stripes, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
bch2_gc_write_stripes_key(&trans, &iter, k));
|
||||
bch2_gc_write_stripes_key(trans, &iter, k));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1942,7 +1933,7 @@ static int bch2_alloc_write_oldest_gen(struct btree_trans *trans, struct btree_i
|
||||
|
||||
int bch2_gc_gens(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_dev *ca;
|
||||
@ -1960,7 +1951,7 @@ int bch2_gc_gens(struct bch_fs *c)
|
||||
|
||||
trace_and_count(c, gc_gens_start, c);
|
||||
down_read(&c->gc_lock);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
for_each_member_device(ca, c, i) {
|
||||
struct bucket_gens *gens;
|
||||
@ -1986,26 +1977,26 @@ int bch2_gc_gens(struct bch_fs *c)
|
||||
c->gc_gens_btree = i;
|
||||
c->gc_gens_pos = POS_MIN;
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, i,
|
||||
ret = for_each_btree_key_commit(trans, iter, i,
|
||||
POS_MIN,
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
|
||||
k,
|
||||
NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL,
|
||||
gc_btree_gens_key(&trans, &iter, k));
|
||||
gc_btree_gens_key(trans, &iter, k));
|
||||
if (ret && !bch2_err_matches(ret, EROFS))
|
||||
bch_err_fn(c, ret);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
|
||||
POS_MIN,
|
||||
BTREE_ITER_PREFETCH,
|
||||
k,
|
||||
NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL,
|
||||
bch2_alloc_write_oldest_gen(&trans, &iter, k));
|
||||
bch2_alloc_write_oldest_gen(trans, &iter, k));
|
||||
if (ret && !bch2_err_matches(ret, EROFS))
|
||||
bch_err_fn(c, ret);
|
||||
if (ret)
|
||||
@ -2024,7 +2015,7 @@ err:
|
||||
ca->oldest_gen = NULL;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
up_read(&c->gc_lock);
|
||||
mutex_unlock(&c->gc_gens_lock);
|
||||
return ret;
|
||||
|
@ -1628,8 +1628,7 @@ err:
|
||||
int bch2_btree_root_read(struct bch_fs *c, enum btree_id id,
|
||||
const struct bkey_i *k, unsigned level)
|
||||
{
|
||||
return bch2_trans_run(c, __bch2_btree_root_read(&trans, id, k, level));
|
||||
|
||||
return bch2_trans_run(c, __bch2_btree_root_read(trans, id, k, level));
|
||||
}
|
||||
|
||||
void bch2_btree_complete_write(struct bch_fs *c, struct btree *b,
|
||||
@ -1691,15 +1690,13 @@ static void __btree_node_write_done(struct bch_fs *c, struct btree *b)
|
||||
|
||||
static void btree_node_write_done(struct bch_fs *c, struct btree *b)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
|
||||
__btree_node_write_done(c, b);
|
||||
six_unlock_read(&b->c.lock);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
}
|
||||
|
||||
static void btree_node_write_work(struct work_struct *work)
|
||||
@ -1728,7 +1725,7 @@ static void btree_node_write_work(struct work_struct *work)
|
||||
}
|
||||
} else {
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_btree_node_update_key_get_iter(&trans, b, &wbio->key,
|
||||
bch2_btree_node_update_key_get_iter(trans, b, &wbio->key,
|
||||
BCH_WATERMARK_reclaim|
|
||||
BTREE_INSERT_JOURNAL_RECLAIM|
|
||||
BTREE_INSERT_NOFAIL|
|
||||
|
@ -2906,28 +2906,23 @@ u32 bch2_trans_begin(struct btree_trans *trans)
|
||||
return trans->restart_count;
|
||||
}
|
||||
|
||||
static void bch2_trans_alloc_paths(struct btree_trans *trans, struct bch_fs *c)
|
||||
static struct btree_trans *bch2_trans_alloc(struct bch_fs *c)
|
||||
{
|
||||
size_t paths_bytes = sizeof(struct btree_path) * BTREE_ITER_MAX;
|
||||
size_t updates_bytes = sizeof(struct btree_insert_entry) * BTREE_ITER_MAX;
|
||||
void *p = NULL;
|
||||
struct btree_trans *trans;
|
||||
|
||||
BUG_ON(trans->used_mempool);
|
||||
|
||||
#ifdef __KERNEL__
|
||||
p = this_cpu_xchg(c->btree_paths_bufs->path, NULL);
|
||||
#endif
|
||||
if (!p) {
|
||||
p = mempool_alloc(&trans->c->btree_paths_pool, GFP_NOFS);
|
||||
/*
|
||||
* paths need to be zeroed, bch2_check_for_deadlock looks at
|
||||
* paths in other threads
|
||||
*/
|
||||
memset(p, 0, paths_bytes);
|
||||
if (IS_ENABLED(__KERNEL__)) {
|
||||
trans = this_cpu_xchg(c->btree_trans_bufs->trans, NULL);
|
||||
if (trans)
|
||||
return trans;
|
||||
}
|
||||
|
||||
trans->paths = p; p += paths_bytes;
|
||||
trans->updates = p; p += updates_bytes;
|
||||
trans = mempool_alloc(&c->btree_trans_pool, GFP_NOFS);
|
||||
/*
|
||||
* paths need to be zeroed, bch2_check_for_deadlock looks at
|
||||
* paths in other threads
|
||||
*/
|
||||
memset(&trans->paths, 0, sizeof(trans->paths));
|
||||
return trans;
|
||||
}
|
||||
|
||||
const char *bch2_btree_transaction_fns[BCH_TRANSACTIONS_NR];
|
||||
@ -2947,11 +2942,14 @@ unsigned bch2_trans_get_fn_idx(const char *fn)
|
||||
return i;
|
||||
}
|
||||
|
||||
void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, unsigned fn_idx)
|
||||
struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx)
|
||||
__acquires(&c->btree_trans_barrier)
|
||||
{
|
||||
struct btree_trans *trans;
|
||||
struct btree_transaction_stats *s;
|
||||
|
||||
trans = bch2_trans_alloc(c);
|
||||
|
||||
memset(trans, 0, sizeof(*trans));
|
||||
trans->c = c;
|
||||
trans->fn = fn_idx < ARRAY_SIZE(bch2_btree_transaction_fns)
|
||||
@ -2963,8 +2961,6 @@ void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, unsigned fn_
|
||||
!test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags);
|
||||
closure_init_stack(&trans->ref);
|
||||
|
||||
bch2_trans_alloc_paths(trans, c);
|
||||
|
||||
s = btree_trans_stats(trans);
|
||||
if (s && s->max_mem) {
|
||||
unsigned expected_mem_bytes = roundup_pow_of_two(s->max_mem);
|
||||
@ -3010,6 +3006,8 @@ void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, unsigned fn_
|
||||
list_add_done:
|
||||
seqmutex_unlock(&c->btree_trans_lock);
|
||||
}
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
static void check_btree_paths_leaked(struct btree_trans *trans)
|
||||
@ -3034,7 +3032,7 @@ leaked:
|
||||
#endif
|
||||
}
|
||||
|
||||
void bch2_trans_exit(struct btree_trans *trans)
|
||||
void bch2_trans_put(struct btree_trans *trans)
|
||||
__releases(&c->btree_trans_barrier)
|
||||
{
|
||||
struct btree_insert_entry *i;
|
||||
@ -3080,18 +3078,11 @@ void bch2_trans_exit(struct btree_trans *trans)
|
||||
else
|
||||
kfree(trans->mem);
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/*
|
||||
* Userspace doesn't have a real percpu implementation:
|
||||
*/
|
||||
trans->paths = this_cpu_xchg(c->btree_paths_bufs->path, trans->paths);
|
||||
#endif
|
||||
|
||||
if (trans->paths)
|
||||
mempool_free(trans->paths, &c->btree_paths_pool);
|
||||
|
||||
trans->mem = (void *) 0x1;
|
||||
trans->paths = (void *) 0x1;
|
||||
/* Userspace doesn't have a real percpu implementation: */
|
||||
if (IS_ENABLED(__KERNEL__))
|
||||
trans = this_cpu_xchg(c->btree_trans_bufs->trans, trans);
|
||||
if (trans)
|
||||
mempool_free(trans, &c->btree_trans_pool);
|
||||
}
|
||||
|
||||
static void __maybe_unused
|
||||
@ -3169,6 +3160,17 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
|
||||
void bch2_fs_btree_iter_exit(struct bch_fs *c)
|
||||
{
|
||||
struct btree_transaction_stats *s;
|
||||
struct btree_trans *trans;
|
||||
int cpu;
|
||||
|
||||
trans = list_first_entry_or_null(&c->btree_trans_list, struct btree_trans, list);
|
||||
if (trans)
|
||||
panic("%s leaked btree_trans\n", trans->fn);
|
||||
|
||||
if (c->btree_trans_bufs)
|
||||
for_each_possible_cpu(cpu)
|
||||
kfree(per_cpu_ptr(c->btree_trans_bufs, cpu)->trans);
|
||||
free_percpu(c->btree_trans_bufs);
|
||||
|
||||
for (s = c->btree_transaction_stats;
|
||||
s < c->btree_transaction_stats + ARRAY_SIZE(c->btree_transaction_stats);
|
||||
@ -3180,13 +3182,12 @@ void bch2_fs_btree_iter_exit(struct bch_fs *c)
|
||||
if (c->btree_trans_barrier_initialized)
|
||||
cleanup_srcu_struct(&c->btree_trans_barrier);
|
||||
mempool_exit(&c->btree_trans_mem_pool);
|
||||
mempool_exit(&c->btree_paths_pool);
|
||||
mempool_exit(&c->btree_trans_pool);
|
||||
}
|
||||
|
||||
int bch2_fs_btree_iter_init(struct bch_fs *c)
|
||||
{
|
||||
struct btree_transaction_stats *s;
|
||||
unsigned nr = BTREE_ITER_MAX;
|
||||
int ret;
|
||||
|
||||
for (s = c->btree_transaction_stats;
|
||||
@ -3199,9 +3200,12 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
|
||||
INIT_LIST_HEAD(&c->btree_trans_list);
|
||||
seqmutex_init(&c->btree_trans_lock);
|
||||
|
||||
ret = mempool_init_kmalloc_pool(&c->btree_paths_pool, 1,
|
||||
sizeof(struct btree_path) * nr +
|
||||
sizeof(struct btree_insert_entry) * nr) ?:
|
||||
c->btree_trans_bufs = alloc_percpu(struct btree_trans_buf);
|
||||
if (!c->btree_trans_bufs)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mempool_init_kmalloc_pool(&c->btree_trans_pool, 1,
|
||||
sizeof(struct btree_trans)) ?:
|
||||
mempool_init_kmalloc_pool(&c->btree_trans_mem_pool, 1,
|
||||
BTREE_TRANS_MEM_MAX) ?:
|
||||
init_srcu_struct(&c->btree_trans_barrier);
|
||||
|
@ -915,21 +915,21 @@ void bch2_btree_path_to_text(struct printbuf *, struct btree_path *);
|
||||
void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *);
|
||||
void bch2_dump_trans_updates(struct btree_trans *);
|
||||
void bch2_dump_trans_paths_updates(struct btree_trans *);
|
||||
void __bch2_trans_init(struct btree_trans *, struct bch_fs *, unsigned);
|
||||
void bch2_trans_exit(struct btree_trans *);
|
||||
|
||||
struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned);
|
||||
void bch2_trans_put(struct btree_trans *);
|
||||
|
||||
extern const char *bch2_btree_transaction_fns[BCH_TRANSACTIONS_NR];
|
||||
unsigned bch2_trans_get_fn_idx(const char *);
|
||||
|
||||
#define bch2_trans_init(_trans, _c, _nr_iters, _mem) \
|
||||
do { \
|
||||
#define bch2_trans_get(_c) \
|
||||
({ \
|
||||
static unsigned trans_fn_idx; \
|
||||
\
|
||||
if (unlikely(!trans_fn_idx)) \
|
||||
trans_fn_idx = bch2_trans_get_fn_idx(__func__); \
|
||||
\
|
||||
__bch2_trans_init(_trans, _c, trans_fn_idx); \
|
||||
} while (0)
|
||||
__bch2_trans_get(_c, trans_fn_idx); \
|
||||
})
|
||||
|
||||
void bch2_btree_trans_to_text(struct printbuf *, struct btree_trans *);
|
||||
|
||||
|
@ -704,13 +704,11 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
|
||||
struct bkey_cached *ck =
|
||||
container_of(pin, struct bkey_cached, journal);
|
||||
struct bkey_cached_key key;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
int srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
btree_node_lock_nopath_nofail(&trans, &ck->c, SIX_LOCK_read);
|
||||
btree_node_lock_nopath_nofail(trans, &ck->c, SIX_LOCK_read);
|
||||
key = ck->key;
|
||||
|
||||
if (ck->journal.seq != seq ||
|
||||
@ -727,13 +725,13 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
|
||||
}
|
||||
six_unlock_read(&ck->c.lock);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
btree_key_cache_flush_pos(&trans, key, seq,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
btree_key_cache_flush_pos(trans, key, seq,
|
||||
BTREE_INSERT_JOURNAL_RECLAIM, false));
|
||||
unlock:
|
||||
srcu_read_unlock(&c->btree_trans_barrier, srcu_idx);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -163,13 +163,11 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
|
||||
struct bch_fs *c = container_of(j, struct bch_fs, journal);
|
||||
struct btree_write *w = container_of(pin, struct btree_write, journal);
|
||||
struct btree *b = container_of(w, struct btree, writes[i]);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
unsigned long old, new, v;
|
||||
unsigned idx = w - b->writes;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
|
||||
v = READ_ONCE(b->flags);
|
||||
|
||||
do {
|
||||
@ -188,7 +186,7 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
|
||||
btree_node_write_if_need(c, b, SIX_LOCK_read);
|
||||
six_unlock_read(&b->c.lock);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -452,8 +452,8 @@ struct btree_trans {
|
||||
void *mem;
|
||||
|
||||
u8 sorted[BTREE_ITER_MAX + 8];
|
||||
struct btree_path *paths;
|
||||
struct btree_insert_entry *updates;
|
||||
struct btree_path paths[BTREE_ITER_MAX];
|
||||
struct btree_insert_entry updates[BTREE_ITER_MAX];
|
||||
struct btree_write_buffered_key *wb_updates;
|
||||
|
||||
/* update path: */
|
||||
|
@ -692,7 +692,7 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k,
|
||||
struct disk_reservation *disk_res, int flags)
|
||||
{
|
||||
return bch2_trans_do(c, disk_res, NULL, flags,
|
||||
bch2_btree_insert_trans(&trans, id, k, 0));
|
||||
bch2_btree_insert_trans(trans, id, k, 0));
|
||||
}
|
||||
|
||||
int bch2_btree_delete_extent_at(struct btree_trans *trans, struct btree_iter *iter,
|
||||
@ -824,7 +824,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
|
||||
u64 *journal_seq)
|
||||
{
|
||||
int ret = bch2_trans_run(c,
|
||||
bch2_btree_delete_range_trans(&trans, id, start, end,
|
||||
bch2_btree_delete_range_trans(trans, id, start, end,
|
||||
update_flags, journal_seq));
|
||||
if (ret == -BCH_ERR_transaction_restart_nested)
|
||||
ret = 0;
|
||||
@ -898,7 +898,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
|
||||
} else {
|
||||
ret = bch2_trans_do(c, NULL, NULL,
|
||||
BTREE_INSERT_LAZY_RW|commit_flags,
|
||||
__bch2_trans_log_msg(&trans.extra_journal_entries, fmt, args));
|
||||
__bch2_trans_log_msg(&trans->extra_journal_entries, fmt, args));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -146,29 +146,16 @@ static inline int bch2_trans_commit(struct btree_trans *trans,
|
||||
nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\
|
||||
(_journal_seq), (_flags)))
|
||||
|
||||
#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do) \
|
||||
#define bch2_trans_run(_c, _do) \
|
||||
({ \
|
||||
struct btree_trans trans; \
|
||||
int _ret; \
|
||||
\
|
||||
bch2_trans_init(&trans, (_c), 0, 0); \
|
||||
_ret = commit_do(&trans, _disk_res, _journal_seq, _flags, _do); \
|
||||
bch2_trans_exit(&trans); \
|
||||
\
|
||||
struct btree_trans *trans = bch2_trans_get(_c); \
|
||||
int _ret = (_do); \
|
||||
bch2_trans_put(trans); \
|
||||
_ret; \
|
||||
})
|
||||
|
||||
#define bch2_trans_run(_c, _do) \
|
||||
({ \
|
||||
struct btree_trans trans; \
|
||||
int _ret; \
|
||||
\
|
||||
bch2_trans_init(&trans, (_c), 0, 0); \
|
||||
_ret = (_do); \
|
||||
bch2_trans_exit(&trans); \
|
||||
\
|
||||
_ret; \
|
||||
})
|
||||
#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do) \
|
||||
bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do))
|
||||
|
||||
#define trans_for_each_update(_trans, _i) \
|
||||
for ((_i) = (_trans)->updates; \
|
||||
|
@ -597,12 +597,11 @@ static void btree_update_nodes_written(struct btree_update *as)
|
||||
{
|
||||
struct bch_fs *c = as->c;
|
||||
struct btree *b;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
u64 journal_seq = 0;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 512);
|
||||
/*
|
||||
* If we're already in an error state, it might be because a btree node
|
||||
* was never written, and we might be trying to free that same btree
|
||||
@ -623,7 +622,7 @@ static void btree_update_nodes_written(struct btree_update *as)
|
||||
|
||||
b = as->old_nodes[i];
|
||||
|
||||
btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
|
||||
seq = b->data ? b->data->keys.seq : 0;
|
||||
six_unlock_read(&b->c.lock);
|
||||
|
||||
@ -645,13 +644,13 @@ static void btree_update_nodes_written(struct btree_update *as)
|
||||
* journal reclaim does btree updates when flushing bkey_cached entries,
|
||||
* which may require allocations as well.
|
||||
*/
|
||||
ret = commit_do(&trans, &as->disk_res, &journal_seq,
|
||||
ret = commit_do(trans, &as->disk_res, &journal_seq,
|
||||
BCH_WATERMARK_reclaim|
|
||||
BTREE_INSERT_NOFAIL|
|
||||
BTREE_INSERT_NOCHECK_RW|
|
||||
BTREE_INSERT_JOURNAL_RECLAIM,
|
||||
btree_update_nodes_written_trans(&trans, as));
|
||||
bch2_trans_unlock(&trans);
|
||||
btree_update_nodes_written_trans(trans, as));
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
bch2_fs_fatal_err_on(ret && !bch2_journal_error(&c->journal), c,
|
||||
"%s(): error %s", __func__, bch2_err_str(ret));
|
||||
@ -660,7 +659,7 @@ err:
|
||||
struct btree_path *path;
|
||||
|
||||
b = as->b;
|
||||
path = get_unlocked_mut_path(&trans, as->btree_id, b->c.level, b->key.k.p);
|
||||
path = get_unlocked_mut_path(trans, as->btree_id, b->c.level, b->key.k.p);
|
||||
/*
|
||||
* @b is the node we did the final insert into:
|
||||
*
|
||||
@ -683,13 +682,13 @@ err:
|
||||
* we may rarely end up with a locked path besides the one we
|
||||
* have here:
|
||||
*/
|
||||
bch2_trans_unlock(&trans);
|
||||
btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_intent);
|
||||
mark_btree_node_locked(&trans, path, b->c.level, BTREE_NODE_INTENT_LOCKED);
|
||||
bch2_trans_unlock(trans);
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_intent);
|
||||
mark_btree_node_locked(trans, path, b->c.level, BTREE_NODE_INTENT_LOCKED);
|
||||
path->l[b->c.level].lock_seq = six_lock_seq(&b->c.lock);
|
||||
path->l[b->c.level].b = b;
|
||||
|
||||
bch2_btree_node_lock_write_nofail(&trans, path, &b->c);
|
||||
bch2_btree_node_lock_write_nofail(trans, path, &b->c);
|
||||
|
||||
mutex_lock(&c->btree_interior_update_lock);
|
||||
|
||||
@ -729,8 +728,8 @@ err:
|
||||
six_unlock_write(&b->c.lock);
|
||||
|
||||
btree_node_write_if_need(c, b, SIX_LOCK_intent);
|
||||
btree_node_unlock(&trans, path, b->c.level);
|
||||
bch2_path_put(&trans, path, true);
|
||||
btree_node_unlock(trans, path, b->c.level);
|
||||
bch2_path_put(trans, path, true);
|
||||
}
|
||||
|
||||
bch2_journal_pin_drop(&c->journal, &as->journal);
|
||||
@ -750,7 +749,7 @@ err:
|
||||
for (i = 0; i < as->nr_new_nodes; i++) {
|
||||
b = as->new_nodes[i];
|
||||
|
||||
btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
|
||||
btree_node_write_if_need(c, b, SIX_LOCK_read);
|
||||
six_unlock_read(&b->c.lock);
|
||||
}
|
||||
@ -758,8 +757,8 @@ err:
|
||||
for (i = 0; i < as->nr_open_buckets; i++)
|
||||
bch2_open_bucket_put(c, c->open_buckets + as->open_buckets[i]);
|
||||
|
||||
bch2_btree_update_free(as, &trans);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_btree_update_free(as, trans);
|
||||
bch2_trans_put(trans);
|
||||
}
|
||||
|
||||
static void btree_interior_update_work(struct work_struct *work)
|
||||
@ -2049,7 +2048,7 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
|
||||
int ret;
|
||||
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
async_btree_node_rewrite_trans(&trans, a));
|
||||
async_btree_node_rewrite_trans(trans, a));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite);
|
||||
@ -2365,7 +2364,7 @@ static int __bch2_btree_root_alloc(struct btree_trans *trans, enum btree_id id)
|
||||
|
||||
void bch2_btree_root_alloc(struct bch_fs *c, enum btree_id id)
|
||||
{
|
||||
bch2_trans_run(c, __bch2_btree_root_alloc(&trans, id));
|
||||
bch2_trans_run(c, __bch2_btree_root_alloc(trans, id));
|
||||
}
|
||||
|
||||
void bch2_btree_updates_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
|
@ -296,7 +296,7 @@ static int bch2_btree_write_buffer_journal_flush(struct journal *j,
|
||||
mutex_lock(&wb->flush_lock);
|
||||
|
||||
return bch2_trans_run(c,
|
||||
__bch2_btree_write_buffer_flush(&trans, BTREE_INSERT_NOCHECK_RW, true));
|
||||
__bch2_btree_write_buffer_flush(trans, BTREE_INSERT_NOCHECK_RW, true));
|
||||
}
|
||||
|
||||
static inline u64 btree_write_buffer_ref(int idx)
|
||||
|
@ -1923,7 +1923,7 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
|
||||
|
||||
int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca)
|
||||
{
|
||||
int ret = bch2_trans_run(c, __bch2_trans_mark_dev_sb(&trans, ca));
|
||||
int ret = bch2_trans_run(c, __bch2_trans_mark_dev_sb(trans, ca));
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
|
@ -303,7 +303,7 @@ out:
|
||||
|
||||
int bch2_data_update_index_update(struct bch_write_op *op)
|
||||
{
|
||||
return bch2_trans_run(op->c, __bch2_data_update_index_update(&trans, op));
|
||||
return bch2_trans_run(op->c, __bch2_data_update_index_update(trans, op));
|
||||
}
|
||||
|
||||
void bch2_data_update_read_done(struct data_update *m,
|
||||
|
@ -366,7 +366,7 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
|
||||
size_t size, loff_t *ppos)
|
||||
{
|
||||
struct dump_iter *i = file->private_data;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
ssize_t ret;
|
||||
@ -379,17 +379,17 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bch2_trans_init(&trans, i->c, 0, 0);
|
||||
ret = for_each_btree_key2(&trans, iter, i->id, i->from,
|
||||
trans = bch2_trans_get(i->c);
|
||||
ret = for_each_btree_key2(trans, iter, i->id, i->from,
|
||||
BTREE_ITER_PREFETCH|
|
||||
BTREE_ITER_ALL_SNAPSHOTS, k, ({
|
||||
bch2_bkey_val_to_text(&i->buf, i->c, k);
|
||||
prt_newline(&i->buf);
|
||||
drop_locks_do(&trans, flush_buf(i));
|
||||
drop_locks_do(trans, flush_buf(i));
|
||||
}));
|
||||
i->from = iter.pos;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (!ret)
|
||||
ret = flush_buf(i);
|
||||
@ -408,7 +408,7 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
|
||||
size_t size, loff_t *ppos)
|
||||
{
|
||||
struct dump_iter *i = file->private_data;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct btree *b;
|
||||
ssize_t ret;
|
||||
@ -424,26 +424,26 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
|
||||
if (bpos_eq(SPOS_MAX, i->from))
|
||||
return i->ret;
|
||||
|
||||
bch2_trans_init(&trans, i->c, 0, 0);
|
||||
trans = bch2_trans_get(i->c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
for_each_btree_node(&trans, iter, i->id, i->from, 0, b, ret) {
|
||||
for_each_btree_node(trans, iter, i->id, i->from, 0, b, ret) {
|
||||
bch2_btree_node_to_text(&i->buf, i->c, b);
|
||||
i->from = !bpos_eq(SPOS_MAX, b->key.k.p)
|
||||
? bpos_successor(b->key.k.p)
|
||||
: b->key.k.p;
|
||||
|
||||
ret = drop_locks_do(&trans, flush_buf(i));
|
||||
ret = drop_locks_do(trans, flush_buf(i));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (!ret)
|
||||
ret = flush_buf(i);
|
||||
@ -462,7 +462,7 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
|
||||
size_t size, loff_t *ppos)
|
||||
{
|
||||
struct dump_iter *i = file->private_data;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
ssize_t ret;
|
||||
@ -475,9 +475,9 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bch2_trans_init(&trans, i->c, 0, 0);
|
||||
trans = bch2_trans_get(i->c);
|
||||
|
||||
ret = for_each_btree_key2(&trans, iter, i->id, i->from,
|
||||
ret = for_each_btree_key2(trans, iter, i->id, i->from,
|
||||
BTREE_ITER_PREFETCH|
|
||||
BTREE_ITER_ALL_SNAPSHOTS, k, ({
|
||||
struct btree_path_level *l = &iter.path->l[0];
|
||||
@ -490,11 +490,11 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
|
||||
}
|
||||
|
||||
bch2_bfloat_to_text(&i->buf, l->b, _k);
|
||||
drop_locks_do(&trans, flush_buf(i));
|
||||
drop_locks_do(trans, flush_buf(i));
|
||||
}));
|
||||
i->from = iter.pos;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (!ret)
|
||||
ret = flush_buf(i);
|
||||
|
@ -479,21 +479,19 @@ u64 bch2_dirent_lookup(struct bch_fs *c, subvol_inum dir,
|
||||
const struct bch_hash_info *hash_info,
|
||||
const struct qstr *name, subvol_inum *inum)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = __bch2_dirent_lookup_trans(&trans, &iter, dir, hash_info,
|
||||
ret = __bch2_dirent_lookup_trans(trans, &iter, dir, hash_info,
|
||||
name, inum, 0);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
if (!ret)
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -522,7 +520,7 @@ int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
|
||||
|
||||
int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_s_c_dirent dirent;
|
||||
@ -533,15 +531,14 @@ int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
|
||||
int ret;
|
||||
|
||||
bch2_bkey_buf_init(&sk);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_dirents,
|
||||
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_dirents,
|
||||
SPOS(inum.inum, ctx->pos, snapshot),
|
||||
POS(inum.inum, U64_MAX), 0, k, ret) {
|
||||
if (k.k->type != KEY_TYPE_dirent)
|
||||
@ -549,7 +546,7 @@ retry:
|
||||
|
||||
dirent = bkey_s_c_to_dirent(k);
|
||||
|
||||
ret = bch2_dirent_read_target(&trans, inum, dirent, &target);
|
||||
ret = bch2_dirent_read_target(trans, inum, dirent, &target);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret)
|
||||
@ -558,7 +555,7 @@ retry:
|
||||
/* dir_emit() can fault and block: */
|
||||
bch2_bkey_buf_reassemble(&sk, c, k);
|
||||
dirent = bkey_i_to_s_c_dirent(sk.k);
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
name = bch2_dirent_get_name(dirent);
|
||||
|
||||
@ -574,16 +571,16 @@ retry:
|
||||
* read_target looks up subvolumes, we can overflow paths if the
|
||||
* directory has many subvolumes in it
|
||||
*/
|
||||
ret = btree_trans_too_many_iters(&trans);
|
||||
ret = btree_trans_too_many_iters(trans);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&sk, c);
|
||||
|
||||
return ret;
|
||||
|
@ -476,7 +476,7 @@ err:
|
||||
|
||||
static int get_stripe_key(struct bch_fs *c, u64 idx, struct ec_stripe_buf *stripe)
|
||||
{
|
||||
return bch2_trans_run(c, get_stripe_key_trans(&trans, idx, stripe));
|
||||
return bch2_trans_run(c, get_stripe_key_trans(trans, idx, stripe));
|
||||
}
|
||||
|
||||
/* recovery read path: */
|
||||
@ -788,12 +788,10 @@ static void ec_stripe_delete_work(struct work_struct *work)
|
||||
{
|
||||
struct bch_fs *c =
|
||||
container_of(work, struct bch_fs, ec_stripe_delete_work);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
int ret;
|
||||
u64 idx;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
while (1) {
|
||||
mutex_lock(&c->ec_stripes_heap_lock);
|
||||
idx = stripe_idx_to_delete(c);
|
||||
@ -802,15 +800,15 @@ static void ec_stripe_delete_work(struct work_struct *work)
|
||||
if (!idx)
|
||||
break;
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
ec_stripe_delete(&trans, idx));
|
||||
ret = commit_do(trans, NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
ec_stripe_delete(trans, idx));
|
||||
if (ret) {
|
||||
bch_err_fn(c, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_stripe_delete);
|
||||
}
|
||||
@ -999,24 +997,22 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
|
||||
|
||||
static int ec_stripe_update_extents(struct bch_fs *c, struct ec_stripe_buf *s)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
|
||||
unsigned i, nr_data = v->nr_blocks - v->nr_redundant;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
ret = bch2_btree_write_buffer_flush(&trans);
|
||||
ret = bch2_btree_write_buffer_flush(trans);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < nr_data; i++) {
|
||||
ret = ec_stripe_update_bucket(&trans, s, i);
|
||||
ret = ec_stripe_update_bucket(trans, s, i);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1124,7 +1120,7 @@ static void ec_stripe_create(struct ec_stripe_new *s)
|
||||
ret = bch2_trans_do(c, &s->res, NULL,
|
||||
BTREE_INSERT_NOCHECK_RW|
|
||||
BTREE_INSERT_NOFAIL,
|
||||
ec_stripe_key_update(&trans,
|
||||
ec_stripe_key_update(trans,
|
||||
bkey_i_to_stripe(&s->new_stripe.key),
|
||||
!s->have_existing_stripe));
|
||||
if (ret) {
|
||||
@ -1822,7 +1818,7 @@ void bch2_fs_ec_flush(struct bch_fs *c)
|
||||
|
||||
int bch2_stripes_read(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
const struct bch_stripe *s;
|
||||
@ -1830,9 +1826,7 @@ int bch2_stripes_read(struct bch_fs *c)
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_stripes, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_stripes, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
if (k.k->type != KEY_TYPE_stripe)
|
||||
continue;
|
||||
@ -1855,9 +1849,9 @@ int bch2_stripes_read(struct bch_fs *c)
|
||||
|
||||
bch2_stripes_heap_insert(c, m, k.k->p.offset);
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
|
@ -270,7 +270,7 @@ void bch2_readahead(struct readahead_control *ractl)
|
||||
struct bch_inode_info *inode = to_bch_ei(ractl->mapping->host);
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct bch_io_opts opts;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct folio *folio;
|
||||
struct readpages_iter readpages_iter;
|
||||
int ret;
|
||||
@ -280,8 +280,6 @@ void bch2_readahead(struct readahead_control *ractl)
|
||||
ret = readpages_iter_init(&readpages_iter, ractl);
|
||||
BUG_ON(ret);
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
bch2_pagecache_add_get(inode);
|
||||
|
||||
while ((folio = readpage_iter_peek(&readpages_iter))) {
|
||||
@ -300,31 +298,27 @@ void bch2_readahead(struct readahead_control *ractl)
|
||||
rbio->bio.bi_end_io = bch2_readpages_end_io;
|
||||
BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
|
||||
|
||||
bchfs_read(&trans, rbio, inode_inum(inode),
|
||||
bchfs_read(trans, rbio, inode_inum(inode),
|
||||
&readpages_iter);
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
}
|
||||
|
||||
bch2_pagecache_add_put(inode);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
darray_exit(&readpages_iter.folios);
|
||||
}
|
||||
|
||||
static void __bchfs_readfolio(struct bch_fs *c, struct bch_read_bio *rbio,
|
||||
subvol_inum inum, struct folio *folio)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
|
||||
bch2_folio_create(folio, __GFP_NOFAIL);
|
||||
|
||||
rbio->bio.bi_opf = REQ_OP_READ|REQ_SYNC;
|
||||
rbio->bio.bi_iter.bi_sector = folio_sector(folio);
|
||||
BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bchfs_read(&trans, rbio, inum, NULL);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_run(c, (bchfs_read(trans, rbio, inum, NULL), 0));
|
||||
}
|
||||
|
||||
static void bch2_read_single_folio_end_io(struct bio *bio)
|
||||
|
@ -234,23 +234,21 @@ static bool bch2_check_range_allocated(struct bch_fs *c, subvol_inum inum,
|
||||
u64 offset, u64 size,
|
||||
unsigned nr_replicas, bool compressed)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
u64 end = offset + size;
|
||||
u32 snapshot;
|
||||
bool ret = true;
|
||||
int err;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
err = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
err = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
|
||||
for_each_btree_key_norestart(trans, iter, BTREE_ID_extents,
|
||||
SPOS(inum.inum, offset, snapshot),
|
||||
BTREE_ITER_SLOTS, k, err) {
|
||||
if (bkey_ge(bkey_start_pos(k.k), POS(inum.inum, end)))
|
||||
@ -265,11 +263,11 @@ retry:
|
||||
}
|
||||
|
||||
offset = iter.pos.offset;
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(err, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return err ? false : ret;
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ static void __bch2_folio_set(struct folio *folio,
|
||||
int bch2_folio_set(struct bch_fs *c, subvol_inum inum,
|
||||
struct folio **fs, unsigned nr_folios)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_folio *s;
|
||||
@ -204,15 +204,15 @@ int bch2_folio_set(struct bch_fs *c, subvol_inum inum,
|
||||
return 0;
|
||||
|
||||
folio_idx = 0;
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
|
||||
for_each_btree_key_norestart(trans, iter, BTREE_ID_extents,
|
||||
SPOS(inum.inum, offset, snapshot),
|
||||
BTREE_ITER_SLOTS, k, ret) {
|
||||
unsigned nr_ptrs = bch2_bkey_nr_ptrs_fully_allocated(k);
|
||||
@ -243,11 +243,11 @@ retry:
|
||||
}
|
||||
|
||||
offset = iter.pos.offset;
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -207,31 +207,29 @@ static inline int range_has_data(struct bch_fs *c, u32 subvol,
|
||||
struct bpos start,
|
||||
struct bpos end)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, subvol, &start.snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, subvol, &start.snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_extents, start, end, 0, k, ret)
|
||||
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_extents, start, end, 0, k, ret)
|
||||
if (bkey_extent_is_data(k.k) && !bkey_extent_is_unwritten(k)) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
start = iter.pos;
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -582,16 +580,15 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
|
||||
u64 start_sector, u64 end_sector)
|
||||
{
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bpos end_pos = POS(inode->v.i_ino, end_sector);
|
||||
struct bch_io_opts opts;
|
||||
int ret = 0;
|
||||
|
||||
bch2_inode_opts_get(&opts, c, &inode->ei_inode);
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 512);
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
POS(inode->v.i_ino, start_sector),
|
||||
BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
|
||||
|
||||
@ -604,9 +601,9 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
|
||||
u64 hole_start, hole_end;
|
||||
u32 snapshot;
|
||||
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans,
|
||||
ret = bch2_subvolume_get_snapshot(trans,
|
||||
inode->ei_subvol, &snapshot);
|
||||
if (ret)
|
||||
goto bkey_err;
|
||||
@ -643,7 +640,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
|
||||
&hole_start,
|
||||
&hole_end,
|
||||
opts.data_replicas, true))
|
||||
ret = drop_locks_do(&trans,
|
||||
ret = drop_locks_do(trans,
|
||||
(bch2_clamp_data_hole(&inode->v,
|
||||
&hole_start,
|
||||
&hole_end,
|
||||
@ -666,7 +663,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
|
||||
goto bkey_err;
|
||||
}
|
||||
|
||||
ret = bch2_extent_fallocate(&trans, inode_inum(inode), &iter,
|
||||
ret = bch2_extent_fallocate(trans, inode_inum(inode), &iter,
|
||||
sectors, opts, &i_sectors_delta,
|
||||
writepoint_hashed((unsigned long) current));
|
||||
if (ret)
|
||||
@ -674,7 +671,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
|
||||
|
||||
bch2_i_sectors_acct(c, inode, "a_res, i_sectors_delta);
|
||||
|
||||
drop_locks_do(&trans,
|
||||
drop_locks_do(trans,
|
||||
(bch2_mark_pagecache_reserved(inode, hole_start, iter.pos.offset), 0));
|
||||
bkey_err:
|
||||
bch2_quota_reservation_put(c, inode, "a_res);
|
||||
@ -686,14 +683,14 @@ bkey_err:
|
||||
struct quota_res quota_res = { 0 };
|
||||
s64 i_sectors_delta = 0;
|
||||
|
||||
bch2_fpunch_at(&trans, &iter, inode_inum(inode),
|
||||
bch2_fpunch_at(trans, &iter, inode_inum(inode),
|
||||
end_sector, &i_sectors_delta);
|
||||
bch2_i_sectors_acct(c, inode, "a_res, i_sectors_delta);
|
||||
bch2_quota_reservation_put(c, inode, "a_res);
|
||||
}
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -799,26 +796,24 @@ static int quota_reserve_range(struct bch_inode_info *inode,
|
||||
u64 start, u64 end)
|
||||
{
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
u32 snapshot;
|
||||
u64 sectors = end - start;
|
||||
u64 pos = start;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inode->ei_subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inode->ei_subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
SPOS(inode->v.i_ino, pos, snapshot), 0);
|
||||
|
||||
while (!(ret = btree_trans_too_many_iters(&trans)) &&
|
||||
while (!(ret = btree_trans_too_many_iters(trans)) &&
|
||||
(k = bch2_btree_iter_peek_upto(&iter, POS(inode->v.i_ino, end - 1))).k &&
|
||||
!(ret = bkey_err(k))) {
|
||||
if (bkey_extent_is_allocation(k.k)) {
|
||||
@ -830,17 +825,14 @@ retry:
|
||||
bch2_btree_iter_advance(&iter);
|
||||
}
|
||||
pos = iter.pos.offset;
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return bch2_quota_reservation_add(c, inode, res, sectors, true);
|
||||
return ret ?: bch2_quota_reservation_add(c, inode, res, sectors, true);
|
||||
}
|
||||
|
||||
loff_t bch2_remap_file_range(struct file *file_src, loff_t pos_src,
|
||||
@ -933,7 +925,7 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
|
||||
{
|
||||
struct bch_inode_info *inode = file_bch_inode(file);
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
subvol_inum inum = inode_inum(inode);
|
||||
@ -945,15 +937,15 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
|
||||
if (offset >= isize)
|
||||
return -ENXIO;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_extents,
|
||||
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_extents,
|
||||
SPOS(inode->v.i_ino, offset >> 9, snapshot),
|
||||
POS(inode->v.i_ino, U64_MAX),
|
||||
0, k, ret) {
|
||||
@ -963,12 +955,12 @@ retry:
|
||||
} else if (k.k->p.offset >> 9 > isize)
|
||||
break;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -986,7 +978,7 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
|
||||
{
|
||||
struct bch_inode_info *inode = file_bch_inode(file);
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
subvol_inum inum = inode_inum(inode);
|
||||
@ -998,15 +990,15 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
|
||||
if (offset >= isize)
|
||||
return -ENXIO;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
|
||||
for_each_btree_key_norestart(trans, iter, BTREE_ID_extents,
|
||||
SPOS(inode->v.i_ino, offset >> 9, snapshot),
|
||||
BTREE_ITER_SLOTS, k, ret) {
|
||||
if (k.k->p.inode != inode->v.i_ino) {
|
||||
@ -1024,12 +1016,12 @@ retry:
|
||||
offset = max(offset, bkey_start_offset(k.k) << 9);
|
||||
}
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
166
fs/bcachefs/fs.c
166
fs/bcachefs/fs.c
@ -82,29 +82,27 @@ int __must_check bch2_write_inode(struct bch_fs *c,
|
||||
inode_set_fn set,
|
||||
void *p, unsigned fields)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bch_inode_unpacked inode_u;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 512);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_inode_peek(&trans, &iter, &inode_u, inode_inum(inode),
|
||||
ret = bch2_inode_peek(trans, &iter, &inode_u, inode_inum(inode),
|
||||
BTREE_ITER_INTENT) ?:
|
||||
(set ? set(&trans, inode, &inode_u, p) : 0) ?:
|
||||
bch2_inode_write(&trans, &iter, &inode_u) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL, BTREE_INSERT_NOFAIL);
|
||||
(set ? set(trans, inode, &inode_u, p) : 0) ?:
|
||||
bch2_inode_write(trans, &iter, &inode_u) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL, BTREE_INSERT_NOFAIL);
|
||||
|
||||
/*
|
||||
* the btree node lock protects inode->ei_inode, not ei_update_lock;
|
||||
* this is important for inode updates via bchfs_write_index_update
|
||||
*/
|
||||
if (!ret)
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, fields);
|
||||
bch2_inode_update_after_write(trans, inode, &inode_u, fields);
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
@ -114,7 +112,7 @@ retry:
|
||||
inode_inum(inode).subvol,
|
||||
inode_inum(inode).inum);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
@ -182,7 +180,7 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
{
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct bch_inode_info *inode;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct bch_subvolume subvol;
|
||||
int ret;
|
||||
|
||||
@ -196,14 +194,14 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
if (!(inode->v.i_state & I_NEW))
|
||||
return &inode->v;
|
||||
|
||||
bch2_trans_init(&trans, c, 8, 0);
|
||||
ret = lockrestart_do(&trans,
|
||||
bch2_subvolume_get(&trans, inum.subvol, true, 0, &subvol) ?:
|
||||
bch2_inode_find_by_inum_trans(&trans, inum, &inode_u));
|
||||
trans = bch2_trans_get(c);
|
||||
ret = lockrestart_do(trans,
|
||||
bch2_subvolume_get(trans, inum.subvol, true, 0, &subvol) ?:
|
||||
bch2_inode_find_by_inum_trans(trans, inum, &inode_u));
|
||||
|
||||
if (!ret)
|
||||
bch2_vfs_inode_init(&trans, inum, inode, &inode_u, &subvol);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_vfs_inode_init(trans, inum, inode, &inode_u, &subvol);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret) {
|
||||
iget_failed(&inode->v);
|
||||
@ -226,7 +224,7 @@ __bch2_create(struct mnt_idmap *idmap,
|
||||
unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = dir->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct bch_inode_unpacked dir_u;
|
||||
struct bch_inode_info *inode, *old;
|
||||
struct bch_inode_unpacked inode_u;
|
||||
@ -256,13 +254,11 @@ __bch2_create(struct mnt_idmap *idmap,
|
||||
if (!(flags & BCH_CREATE_TMPFILE))
|
||||
mutex_lock(&dir->ei_update_lock);
|
||||
|
||||
bch2_trans_init(&trans, c, 8,
|
||||
2048 + (!(flags & BCH_CREATE_TMPFILE)
|
||||
? dentry->d_name.len : 0));
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_create_trans(&trans,
|
||||
ret = bch2_create_trans(trans,
|
||||
inode_inum(dir), &dir_u, &inode_u,
|
||||
!(flags & BCH_CREATE_TMPFILE)
|
||||
? &dentry->d_name : NULL,
|
||||
@ -278,9 +274,9 @@ retry:
|
||||
inum.subvol = inode_u.bi_subvol ?: dir->ei_subvol;
|
||||
inum.inum = inode_u.bi_inum;
|
||||
|
||||
ret = bch2_subvolume_get(&trans, inum.subvol, true,
|
||||
ret = bch2_subvolume_get(trans, inum.subvol, true,
|
||||
BTREE_ITER_WITH_UPDATES, &subvol) ?:
|
||||
bch2_trans_commit(&trans, NULL, &journal_seq, 0);
|
||||
bch2_trans_commit(trans, NULL, &journal_seq, 0);
|
||||
if (unlikely(ret)) {
|
||||
bch2_quota_acct(c, bch_qid(&inode_u), Q_INO, -1,
|
||||
KEY_TYPE_QUOTA_WARN);
|
||||
@ -291,13 +287,13 @@ err_before_quota:
|
||||
}
|
||||
|
||||
if (!(flags & BCH_CREATE_TMPFILE)) {
|
||||
bch2_inode_update_after_write(&trans, dir, &dir_u,
|
||||
bch2_inode_update_after_write(trans, dir, &dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
mutex_unlock(&dir->ei_update_lock);
|
||||
}
|
||||
|
||||
bch2_iget5_set(&inode->v, &inum);
|
||||
bch2_vfs_inode_init(&trans, inum, inode, &inode_u, &subvol);
|
||||
bch2_vfs_inode_init(trans, inum, inode, &inode_u, &subvol);
|
||||
|
||||
set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
|
||||
set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl);
|
||||
@ -337,7 +333,7 @@ err_before_quota:
|
||||
unlock_new_inode(&inode->v);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
err:
|
||||
posix_acl_release(default_acl);
|
||||
posix_acl_release(acl);
|
||||
@ -346,7 +342,7 @@ err_trans:
|
||||
if (!(flags & BCH_CREATE_TMPFILE))
|
||||
mutex_unlock(&dir->ei_update_lock);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
make_bad_inode(&inode->v);
|
||||
iput(&inode->v);
|
||||
inode = ERR_PTR(ret);
|
||||
@ -401,26 +397,25 @@ static int __bch2_link(struct bch_fs *c,
|
||||
struct bch_inode_info *dir,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bch_inode_unpacked dir_u, inode_u;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&inode->ei_update_lock);
|
||||
bch2_trans_init(&trans, c, 4, 1024);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_link_trans(&trans,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_link_trans(trans,
|
||||
inode_inum(dir), &dir_u,
|
||||
inode_inum(inode), &inode_u,
|
||||
&dentry->d_name));
|
||||
|
||||
if (likely(!ret)) {
|
||||
bch2_inode_update_after_write(&trans, dir, &dir_u,
|
||||
bch2_inode_update_after_write(trans, dir, &dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, ATTR_CTIME);
|
||||
bch2_inode_update_after_write(trans, inode, &inode_u, ATTR_CTIME);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
mutex_unlock(&inode->ei_update_lock);
|
||||
return ret;
|
||||
}
|
||||
@ -451,24 +446,23 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
|
||||
struct bch_inode_info *dir = to_bch_ei(vdir);
|
||||
struct bch_inode_info *inode = to_bch_ei(dentry->d_inode);
|
||||
struct bch_inode_unpacked dir_u, inode_u;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
int ret;
|
||||
|
||||
bch2_lock_inodes(INODE_UPDATE_LOCK, dir, inode);
|
||||
bch2_trans_init(&trans, c, 4, 1024);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL,
|
||||
ret = commit_do(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL,
|
||||
bch2_unlink_trans(&trans,
|
||||
bch2_unlink_trans(trans,
|
||||
inode_inum(dir), &dir_u,
|
||||
&inode_u, &dentry->d_name,
|
||||
deleting_snapshot));
|
||||
if (unlikely(ret))
|
||||
goto err;
|
||||
|
||||
bch2_inode_update_after_write(&trans, dir, &dir_u,
|
||||
bch2_inode_update_after_write(trans, dir, &dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u,
|
||||
bch2_inode_update_after_write(trans, inode, &inode_u,
|
||||
ATTR_MTIME);
|
||||
|
||||
if (inode_u.bi_subvol) {
|
||||
@ -479,8 +473,8 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
|
||||
set_nlink(&inode->v, 0);
|
||||
}
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -543,7 +537,7 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
struct bch_inode_info *dst_inode = to_bch_ei(dst_dentry->d_inode);
|
||||
struct bch_inode_unpacked dst_dir_u, src_dir_u;
|
||||
struct bch_inode_unpacked src_inode_u, dst_inode_u;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
enum bch_rename_mode mode = flags & RENAME_EXCHANGE
|
||||
? BCH_RENAME_EXCHANGE
|
||||
: dst_dentry->d_inode
|
||||
@ -560,7 +554,7 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bch2_trans_init(&trans, c, 8, 2048);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
bch2_lock_inodes(INODE_UPDATE_LOCK,
|
||||
src_dir,
|
||||
@ -587,8 +581,8 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_rename_trans(&trans,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_rename_trans(trans,
|
||||
inode_inum(src_dir), &src_dir_u,
|
||||
inode_inum(dst_dir), &dst_dir_u,
|
||||
&src_inode_u,
|
||||
@ -603,21 +597,21 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
BUG_ON(dst_inode &&
|
||||
dst_inode->v.i_ino != dst_inode_u.bi_inum);
|
||||
|
||||
bch2_inode_update_after_write(&trans, src_dir, &src_dir_u,
|
||||
bch2_inode_update_after_write(trans, src_dir, &src_dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
|
||||
if (src_dir != dst_dir)
|
||||
bch2_inode_update_after_write(&trans, dst_dir, &dst_dir_u,
|
||||
bch2_inode_update_after_write(trans, dst_dir, &dst_dir_u,
|
||||
ATTR_MTIME|ATTR_CTIME);
|
||||
|
||||
bch2_inode_update_after_write(&trans, src_inode, &src_inode_u,
|
||||
bch2_inode_update_after_write(trans, src_inode, &src_inode_u,
|
||||
ATTR_CTIME);
|
||||
|
||||
if (dst_inode)
|
||||
bch2_inode_update_after_write(&trans, dst_inode, &dst_inode_u,
|
||||
bch2_inode_update_after_write(trans, dst_inode, &dst_inode_u,
|
||||
ATTR_CTIME);
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
bch2_fs_quota_transfer(c, src_inode,
|
||||
bch_qid(&src_inode->ei_inode),
|
||||
@ -680,7 +674,7 @@ int bch2_setattr_nonsize(struct mnt_idmap *idmap,
|
||||
{
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct bch_qid qid;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter inode_iter = { NULL };
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct posix_acl *acl = NULL;
|
||||
@ -701,13 +695,13 @@ int bch2_setattr_nonsize(struct mnt_idmap *idmap,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
kfree(acl);
|
||||
acl = NULL;
|
||||
|
||||
ret = bch2_inode_peek(&trans, &inode_iter, &inode_u, inode_inum(inode),
|
||||
ret = bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode),
|
||||
BTREE_ITER_INTENT);
|
||||
if (ret)
|
||||
goto btree_err;
|
||||
@ -715,29 +709,29 @@ retry:
|
||||
bch2_setattr_copy(idmap, inode, &inode_u, attr);
|
||||
|
||||
if (attr->ia_valid & ATTR_MODE) {
|
||||
ret = bch2_acl_chmod(&trans, inode_inum(inode), &inode_u,
|
||||
ret = bch2_acl_chmod(trans, inode_inum(inode), &inode_u,
|
||||
inode_u.bi_mode, &acl);
|
||||
if (ret)
|
||||
goto btree_err;
|
||||
}
|
||||
|
||||
ret = bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL,
|
||||
ret = bch2_inode_write(trans, &inode_iter, &inode_u) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL);
|
||||
btree_err:
|
||||
bch2_trans_iter_exit(&trans, &inode_iter);
|
||||
bch2_trans_iter_exit(trans, &inode_iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
if (unlikely(ret))
|
||||
goto err_trans;
|
||||
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, attr->ia_valid);
|
||||
bch2_inode_update_after_write(trans, inode, &inode_u, attr->ia_valid);
|
||||
|
||||
if (acl)
|
||||
set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
|
||||
err_trans:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
err:
|
||||
mutex_unlock(&inode->ei_update_lock);
|
||||
|
||||
@ -879,7 +873,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
|
||||
{
|
||||
struct bch_fs *c = vinode->i_sb->s_fs_info;
|
||||
struct bch_inode_info *ei = to_bch_ei(vinode);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_buf cur, prev;
|
||||
@ -900,18 +894,18 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
|
||||
|
||||
bch2_bkey_buf_init(&cur);
|
||||
bch2_bkey_buf_init(&prev);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, ei->ei_subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, ei->ei_subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
SPOS(ei->v.i_ino, start, snapshot), 0);
|
||||
|
||||
while (!(ret = btree_trans_too_many_iters(&trans)) &&
|
||||
while (!(ret = btree_trans_too_many_iters(trans)) &&
|
||||
(k = bch2_btree_iter_peek_upto(&iter, end)).k &&
|
||||
!(ret = bkey_err(k))) {
|
||||
enum btree_id data_btree = BTREE_ID_extents;
|
||||
@ -928,7 +922,7 @@ retry:
|
||||
|
||||
bch2_bkey_buf_reassemble(&cur, c, k);
|
||||
|
||||
ret = bch2_read_indirect_extent(&trans, &data_btree,
|
||||
ret = bch2_read_indirect_extent(trans, &data_btree,
|
||||
&offset_into_extent, &cur);
|
||||
if (ret)
|
||||
break;
|
||||
@ -947,7 +941,7 @@ retry:
|
||||
cur.k->k.p.offset += cur.k->k.size;
|
||||
|
||||
if (have_extent) {
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
ret = bch2_fill_extent(c, info,
|
||||
bkey_i_to_s_c(prev.k), 0);
|
||||
if (ret)
|
||||
@ -961,18 +955,18 @@ retry:
|
||||
POS(iter.pos.inode, iter.pos.offset + sectors));
|
||||
}
|
||||
start = iter.pos.offset;
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
if (!ret && have_extent) {
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k),
|
||||
FIEMAP_EXTENT_LAST);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&cur, c);
|
||||
bch2_bkey_buf_exit(&prev, c);
|
||||
return ret < 0 ? ret : 0;
|
||||
@ -1230,7 +1224,7 @@ static int bch2_get_name(struct dentry *parent, char *name, struct dentry *child
|
||||
struct bch_inode_info *inode = to_bch_ei(child->d_inode);
|
||||
struct bch_inode_info *dir = to_bch_ei(parent->d_inode);
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter1;
|
||||
struct btree_iter iter2;
|
||||
struct bkey_s_c k;
|
||||
@ -1245,23 +1239,23 @@ static int bch2_get_name(struct dentry *parent, char *name, struct dentry *child
|
||||
if (!S_ISDIR(dir->v.i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter1, BTREE_ID_dirents,
|
||||
bch2_trans_iter_init(trans, &iter1, BTREE_ID_dirents,
|
||||
POS(dir->ei_inode.bi_inum, 0), 0);
|
||||
bch2_trans_iter_init(&trans, &iter2, BTREE_ID_dirents,
|
||||
bch2_trans_iter_init(trans, &iter2, BTREE_ID_dirents,
|
||||
POS(dir->ei_inode.bi_inum, 0), 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, dir->ei_subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, dir->ei_subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
bch2_btree_iter_set_snapshot(&iter1, snapshot);
|
||||
bch2_btree_iter_set_snapshot(&iter2, snapshot);
|
||||
|
||||
ret = bch2_inode_find_by_inum_trans(&trans, inode_inum(inode), &inode_u);
|
||||
ret = bch2_inode_find_by_inum_trans(trans, inode_inum(inode), &inode_u);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -1279,7 +1273,7 @@ retry:
|
||||
}
|
||||
|
||||
d = bkey_s_c_to_dirent(k);
|
||||
ret = bch2_dirent_read_target(&trans, inode_inum(dir), d, &target);
|
||||
ret = bch2_dirent_read_target(trans, inode_inum(dir), d, &target);
|
||||
if (ret > 0)
|
||||
ret = -BCH_ERR_ENOENT_dirent_doesnt_match_inode;
|
||||
if (ret)
|
||||
@ -1301,7 +1295,7 @@ retry:
|
||||
continue;
|
||||
|
||||
d = bkey_s_c_to_dirent(k);
|
||||
ret = bch2_dirent_read_target(&trans, inode_inum(dir), d, &target);
|
||||
ret = bch2_dirent_read_target(trans, inode_inum(dir), d, &target);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret)
|
||||
@ -1325,9 +1319,9 @@ err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter1);
|
||||
bch2_trans_iter_exit(&trans, &iter2);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter1);
|
||||
bch2_trans_iter_exit(trans, &iter2);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -987,7 +987,7 @@ noinline_for_stack
|
||||
int bch2_check_inodes(struct bch_fs *c)
|
||||
{
|
||||
bool full = c->opts.fsck;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bch_inode_unpacked prev = { 0 };
|
||||
struct snapshots_seen s;
|
||||
@ -995,16 +995,15 @@ int bch2_check_inodes(struct bch_fs *c)
|
||||
int ret;
|
||||
|
||||
snapshots_seen_init(&s);
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_inodes,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_inodes,
|
||||
POS_MIN,
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_inode(&trans, &iter, k, &prev, &s, full));
|
||||
check_inode(trans, &iter, k, &prev, &s, full));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
snapshots_seen_exit(&s);
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1437,7 +1436,7 @@ int bch2_check_extents(struct bch_fs *c)
|
||||
{
|
||||
struct inode_walker w = inode_walker_init();
|
||||
struct snapshots_seen s;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct extent_ends extent_ends;
|
||||
@ -1446,23 +1445,22 @@ int bch2_check_extents(struct bch_fs *c)
|
||||
|
||||
snapshots_seen_init(&s);
|
||||
extent_ends_init(&extent_ends);
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 4096);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_extents,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_extents,
|
||||
POS(BCACHEFS_ROOT_INO, 0),
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
&res, NULL,
|
||||
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL, ({
|
||||
bch2_disk_reservation_put(c, &res);
|
||||
check_extent(&trans, &iter, k, &w, &s, &extent_ends);
|
||||
check_extent(trans, &iter, k, &w, &s, &extent_ends);
|
||||
})) ?:
|
||||
check_i_sectors(&trans, &w);
|
||||
check_i_sectors(trans, &w);
|
||||
|
||||
bch2_disk_reservation_put(c, &res);
|
||||
extent_ends_exit(&extent_ends);
|
||||
inode_walker_exit(&w);
|
||||
bch2_trans_exit(&trans);
|
||||
snapshots_seen_exit(&s);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
@ -1803,23 +1801,22 @@ int bch2_check_dirents(struct bch_fs *c)
|
||||
struct inode_walker target = inode_walker_init();
|
||||
struct snapshots_seen s;
|
||||
struct bch_hash_info hash_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
|
||||
snapshots_seen_init(&s);
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_dirents,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_dirents,
|
||||
POS(BCACHEFS_ROOT_INO, 0),
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
|
||||
k,
|
||||
NULL, NULL,
|
||||
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_dirent(&trans, &iter, k, &hash_info, &dir, &target, &s));
|
||||
check_dirent(trans, &iter, k, &hash_info, &dir, &target, &s));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
snapshots_seen_exit(&s);
|
||||
inode_walker_exit(&dir);
|
||||
inode_walker_exit(&target);
|
||||
@ -1873,23 +1870,18 @@ int bch2_check_xattrs(struct bch_fs *c)
|
||||
{
|
||||
struct inode_walker inode = inode_walker_init();
|
||||
struct bch_hash_info hash_info;
|
||||
struct btree_trans trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(trans, iter, BTREE_ID_xattrs,
|
||||
POS(BCACHEFS_ROOT_INO, 0),
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
|
||||
k,
|
||||
NULL, NULL,
|
||||
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_xattr(&trans, &iter, k, &hash_info, &inode));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
|
||||
check_xattr(trans, &iter, k, &hash_info, &inode)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1958,7 +1950,7 @@ int bch2_check_root(struct bch_fs *c)
|
||||
ret = bch2_trans_do(c, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL|
|
||||
BTREE_INSERT_LAZY_RW,
|
||||
check_root_trans(&trans));
|
||||
check_root_trans(trans));
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
@ -2110,16 +2102,14 @@ fsck_err:
|
||||
*/
|
||||
int bch2_check_directory_structure(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_inode_unpacked u;
|
||||
pathbuf path = { 0, };
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_inodes, POS_MIN,
|
||||
BTREE_ITER_INTENT|
|
||||
BTREE_ITER_PREFETCH|
|
||||
BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
|
||||
@ -2136,12 +2126,12 @@ int bch2_check_directory_structure(struct bch_fs *c)
|
||||
if (u.bi_flags & BCH_INODE_UNLINKED)
|
||||
continue;
|
||||
|
||||
ret = check_path(&trans, &path, &u, iter.pos.snapshot);
|
||||
ret = check_path(trans, &path, &u, iter.pos.snapshot);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
darray_exit(&path);
|
||||
|
||||
if (ret)
|
||||
@ -2230,15 +2220,13 @@ static int check_nlinks_find_hardlinks(struct bch_fs *c,
|
||||
struct nlink_table *t,
|
||||
u64 start, u64 *end)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_inode_unpacked u;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_inodes,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_inodes,
|
||||
POS(0, start),
|
||||
BTREE_ITER_INTENT|
|
||||
BTREE_ITER_PREFETCH|
|
||||
@ -2267,8 +2255,8 @@ static int check_nlinks_find_hardlinks(struct bch_fs *c,
|
||||
}
|
||||
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err(c, "error in fsck: btree error %i while walking inodes", ret);
|
||||
@ -2280,7 +2268,7 @@ noinline_for_stack
|
||||
static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links,
|
||||
u64 range_start, u64 range_end)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct snapshots_seen s;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
@ -2289,9 +2277,7 @@ static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links
|
||||
|
||||
snapshots_seen_init(&s);
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_dirents, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_dirents, POS_MIN,
|
||||
BTREE_ITER_INTENT|
|
||||
BTREE_ITER_PREFETCH|
|
||||
BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
|
||||
@ -2311,12 +2297,12 @@ static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links
|
||||
break;
|
||||
}
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (ret)
|
||||
bch_err(c, "error in fsck: btree error %i while walking dirents", ret);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
snapshots_seen_exit(&s);
|
||||
return ret;
|
||||
}
|
||||
@ -2367,22 +2353,17 @@ static int check_nlinks_update_hardlinks(struct bch_fs *c,
|
||||
struct nlink_table *links,
|
||||
u64 range_start, u64 range_end)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
size_t idx = 0;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_inodes,
|
||||
POS(0, range_start),
|
||||
BTREE_ITER_INTENT|BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_nlinks_update_inode(&trans, &iter, k, links, &idx, range_end));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(trans, iter, BTREE_ID_inodes,
|
||||
POS(0, range_start),
|
||||
BTREE_ITER_INTENT|BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_nlinks_update_inode(trans, &iter, k, links, &idx, range_end)));
|
||||
if (ret < 0) {
|
||||
bch_err(c, "error in fsck: btree error %i while walking inodes", ret);
|
||||
return ret;
|
||||
@ -2464,13 +2445,12 @@ int bch2_fix_reflink_p(struct bch_fs *c)
|
||||
return 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_extents, POS_MIN,
|
||||
BTREE_ITER_INTENT|BTREE_ITER_PREFETCH|
|
||||
BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
|
||||
fix_reflink_p_key(&trans, &iter, k)));
|
||||
|
||||
fix_reflink_p_key(trans, &iter, k)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
|
@ -826,7 +826,7 @@ err:
|
||||
|
||||
int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bkey_i_inode_generation delete;
|
||||
struct bch_inode_unpacked inode_u;
|
||||
@ -834,8 +834,6 @@ int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
|
||||
u32 snapshot;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 1024);
|
||||
|
||||
/*
|
||||
* If this was a directory, there shouldn't be any real dirents left -
|
||||
* but there could be whiteouts (from hash collisions) that we should
|
||||
@ -844,19 +842,19 @@ int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
|
||||
* XXX: the dirent could ideally would delete whiteouts when they're no
|
||||
* longer needed
|
||||
*/
|
||||
ret = bch2_inode_delete_keys(&trans, inum, BTREE_ID_extents) ?:
|
||||
bch2_inode_delete_keys(&trans, inum, BTREE_ID_xattrs) ?:
|
||||
bch2_inode_delete_keys(&trans, inum, BTREE_ID_dirents);
|
||||
ret = bch2_inode_delete_keys(trans, inum, BTREE_ID_extents) ?:
|
||||
bch2_inode_delete_keys(trans, inum, BTREE_ID_xattrs) ?:
|
||||
bch2_inode_delete_keys(trans, inum, BTREE_ID_dirents);
|
||||
if (ret)
|
||||
goto err;
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
k = bch2_bkey_get_iter(&trans, &iter, BTREE_ID_inodes,
|
||||
k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
|
||||
SPOS(0, inum.inum, snapshot),
|
||||
BTREE_ITER_INTENT|BTREE_ITER_CACHED);
|
||||
ret = bkey_err(k);
|
||||
@ -864,7 +862,7 @@ retry:
|
||||
goto err;
|
||||
|
||||
if (!bkey_is_inode(k.k)) {
|
||||
bch2_fs_inconsistent(trans.c,
|
||||
bch2_fs_inconsistent(c,
|
||||
"inode %llu:%u not found when deleting",
|
||||
inum.inum, snapshot);
|
||||
ret = -EIO;
|
||||
@ -877,15 +875,15 @@ retry:
|
||||
delete.k.p = iter.pos;
|
||||
delete.v.bi_generation = cpu_to_le32(inode_u.bi_generation + 1);
|
||||
|
||||
ret = bch2_trans_update(&trans, &iter, &delete.k_i, 0) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL,
|
||||
ret = bch2_trans_update(trans, &iter, &delete.k_i, 0) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL);
|
||||
err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -919,7 +917,7 @@ int bch2_inode_find_by_inum(struct bch_fs *c, subvol_inum inum,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
return bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_inode_find_by_inum_trans(&trans, inum, inode));
|
||||
bch2_inode_find_by_inum_trans(trans, inum, inode));
|
||||
}
|
||||
|
||||
int bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
|
||||
@ -1091,14 +1089,12 @@ delete:
|
||||
|
||||
int bch2_delete_dead_inodes(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
ret = bch2_btree_write_buffer_flush_sync(&trans);
|
||||
ret = bch2_btree_write_buffer_flush_sync(trans);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -1108,26 +1104,26 @@ int bch2_delete_dead_inodes(struct bch_fs *c)
|
||||
* but we can't retry because the btree write buffer won't have been
|
||||
* flushed and we'd spin:
|
||||
*/
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_deleted_inodes, POS_MIN,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_deleted_inodes, POS_MIN,
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
|
||||
ret = lockrestart_do(&trans, may_delete_deleted_inode(&trans, k.k->p));
|
||||
ret = lockrestart_do(trans, may_delete_deleted_inode(trans, k.k->p));
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (ret) {
|
||||
if (!test_bit(BCH_FS_RW, &c->flags)) {
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
bch2_fs_lazy_rw(c);
|
||||
}
|
||||
|
||||
ret = bch2_inode_rm_snapshot(&trans, k.k->p.offset, k.k->p.snapshot);
|
||||
ret = bch2_inode_rm_snapshot(trans, k.k->p.offset, k.k->p.snapshot);
|
||||
if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
break;
|
||||
}
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -198,19 +198,18 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
|
||||
int bch2_fpunch(struct bch_fs *c, subvol_inum inum, u64 start, u64 end,
|
||||
s64 *i_sectors_delta)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
POS(inum.inum, start),
|
||||
BTREE_ITER_INTENT);
|
||||
|
||||
ret = bch2_fpunch_at(&trans, &iter, inum, end, i_sectors_delta);
|
||||
ret = bch2_fpunch_at(trans, &iter, inum, end, i_sectors_delta);
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
ret = 0;
|
||||
@ -289,8 +288,8 @@ int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sec
|
||||
op.v.new_i_size = cpu_to_le64(new_i_size);
|
||||
|
||||
return bch2_trans_run(c,
|
||||
bch2_logged_op_start(&trans, &op.k_i) ?:
|
||||
__bch2_resume_logged_op_truncate(&trans, &op.k_i, i_sectors_delta));
|
||||
bch2_logged_op_start(trans, &op.k_i) ?:
|
||||
__bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta));
|
||||
}
|
||||
|
||||
/* finsert/fcollapse: */
|
||||
@ -493,6 +492,6 @@ int bch2_fcollapse_finsert(struct bch_fs *c, subvol_inum inum,
|
||||
op.v.pos = cpu_to_le64(insert ? U64_MAX : offset);
|
||||
|
||||
return bch2_trans_run(c,
|
||||
bch2_logged_op_start(&trans, &op.k_i) ?:
|
||||
__bch2_resume_logged_op_finsert(&trans, &op.k_i, i_sectors_delta));
|
||||
bch2_logged_op_start(trans, &op.k_i) ?:
|
||||
__bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta));
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio
|
||||
struct bch_io_failures *failed,
|
||||
unsigned flags)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_buf sk;
|
||||
struct bkey_s_c k;
|
||||
@ -369,9 +369,8 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio
|
||||
flags |= BCH_READ_MUST_CLONE;
|
||||
|
||||
bch2_bkey_buf_init(&sk);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, rbio->data_btree,
|
||||
bch2_trans_iter_init(trans, &iter, rbio->data_btree,
|
||||
rbio->read_pos, BTREE_ITER_SLOTS);
|
||||
retry:
|
||||
rbio->bio.bi_status = 0;
|
||||
@ -382,7 +381,7 @@ retry:
|
||||
|
||||
bch2_bkey_buf_reassemble(&sk, c, k);
|
||||
k = bkey_i_to_s_c(sk.k);
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
if (!bch2_bkey_matches_ptr(c, k,
|
||||
rbio->pick.ptr,
|
||||
@ -393,7 +392,7 @@ retry:
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = __bch2_read_extent(&trans, rbio, bvec_iter,
|
||||
ret = __bch2_read_extent(trans, rbio, bvec_iter,
|
||||
rbio->read_pos,
|
||||
rbio->data_btree,
|
||||
k, 0, failed, flags);
|
||||
@ -403,8 +402,8 @@ retry:
|
||||
goto err;
|
||||
out:
|
||||
bch2_rbio_done(rbio);
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&sk, c);
|
||||
return;
|
||||
err:
|
||||
@ -526,7 +525,7 @@ out:
|
||||
static noinline void bch2_rbio_narrow_crcs(struct bch_read_bio *rbio)
|
||||
{
|
||||
bch2_trans_do(rbio->c, NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
__bch2_rbio_narrow_crcs(&trans, rbio));
|
||||
__bch2_rbio_narrow_crcs(trans, rbio));
|
||||
}
|
||||
|
||||
/* Inner part that may run in process context */
|
||||
@ -1082,7 +1081,7 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
|
||||
struct bvec_iter bvec_iter, subvol_inum inum,
|
||||
struct bch_io_failures *failed, unsigned flags)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_buf sk;
|
||||
struct bkey_s_c k;
|
||||
@ -1092,16 +1091,15 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
|
||||
BUG_ON(flags & BCH_READ_NODECODE);
|
||||
|
||||
bch2_bkey_buf_init(&sk);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
iter = (struct btree_iter) { NULL };
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
SPOS(inum.inum, bvec_iter.bi_sector, snapshot),
|
||||
BTREE_ITER_SLOTS);
|
||||
while (1) {
|
||||
@ -1112,7 +1110,7 @@ retry:
|
||||
* read_extent -> io_time_reset may cause a transaction restart
|
||||
* without returning an error, we need to check for that here:
|
||||
*/
|
||||
ret = bch2_trans_relock(&trans);
|
||||
ret = bch2_trans_relock(trans);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
@ -1130,7 +1128,7 @@ retry:
|
||||
|
||||
bch2_bkey_buf_reassemble(&sk, c, k);
|
||||
|
||||
ret = bch2_read_indirect_extent(&trans, &data_btree,
|
||||
ret = bch2_read_indirect_extent(trans, &data_btree,
|
||||
&offset_into_extent, &sk);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1149,7 +1147,7 @@ retry:
|
||||
if (bvec_iter.bi_size == bytes)
|
||||
flags |= BCH_READ_LAST_FRAGMENT;
|
||||
|
||||
ret = __bch2_read_extent(&trans, rbio, bvec_iter, iter.pos,
|
||||
ret = __bch2_read_extent(trans, rbio, bvec_iter, iter.pos,
|
||||
data_btree, k,
|
||||
offset_into_extent, failed, flags);
|
||||
if (ret)
|
||||
@ -1161,19 +1159,19 @@ retry:
|
||||
swap(bvec_iter.bi_size, bytes);
|
||||
bio_advance_iter(&rbio->bio, &bvec_iter, bytes);
|
||||
|
||||
ret = btree_trans_too_many_iters(&trans);
|
||||
ret = btree_trans_too_many_iters(trans);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart) ||
|
||||
ret == READ_RETRY ||
|
||||
ret == READ_RETRY_AVOID)
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&sk, c);
|
||||
|
||||
if (ret) {
|
||||
|
@ -322,7 +322,7 @@ static int bch2_write_index_default(struct bch_write_op *op)
|
||||
struct bkey_buf sk;
|
||||
struct keylist *keys = &op->insert_keys;
|
||||
struct bkey_i *k = bch2_keylist_front(keys);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
subvol_inum inum = {
|
||||
.subvol = op->subvol,
|
||||
@ -333,30 +333,29 @@ static int bch2_write_index_default(struct bch_write_op *op)
|
||||
BUG_ON(!inum.subvol);
|
||||
|
||||
bch2_bkey_buf_init(&sk);
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
|
||||
|
||||
do {
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
k = bch2_keylist_front(keys);
|
||||
bch2_bkey_buf_copy(&sk, c, k);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol,
|
||||
ret = bch2_subvolume_get_snapshot(trans, inum.subvol,
|
||||
&sk.k->k.p.snapshot);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
continue;
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
bkey_start_pos(&sk.k->k),
|
||||
BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
|
||||
|
||||
ret = bch2_extent_update(&trans, inum, &iter, sk.k,
|
||||
ret = bch2_extent_update(trans, inum, &iter, sk.k,
|
||||
&op->res,
|
||||
op->new_i_size, &op->i_sectors_delta,
|
||||
op->flags & BCH_WRITE_CHECK_ENOSPC);
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
continue;
|
||||
@ -369,7 +368,7 @@ static int bch2_write_index_default(struct bch_write_op *op)
|
||||
bch2_cut_front(iter.pos, k);
|
||||
} while (!bch2_keylist_empty(keys));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&sk, c);
|
||||
|
||||
return ret;
|
||||
@ -1163,20 +1162,18 @@ static int bch2_nocow_write_convert_one_unwritten(struct btree_trans *trans,
|
||||
static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
|
||||
{
|
||||
struct bch_fs *c = op->c;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_i *orig;
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for_each_keylist_key(&op->insert_keys, orig) {
|
||||
ret = for_each_btree_key_upto_commit(&trans, iter, BTREE_ID_extents,
|
||||
ret = for_each_btree_key_upto_commit(trans, iter, BTREE_ID_extents,
|
||||
bkey_start_pos(&orig->k), orig->k.p,
|
||||
BTREE_ITER_INTENT, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL, ({
|
||||
bch2_nocow_write_convert_one_unwritten(&trans, &iter, orig, k, op->new_i_size);
|
||||
bch2_nocow_write_convert_one_unwritten(trans, &iter, orig, k, op->new_i_size);
|
||||
}));
|
||||
|
||||
if (ret && !bch2_err_matches(ret, EROFS)) {
|
||||
@ -1194,7 +1191,7 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
|
||||
}
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
}
|
||||
|
||||
static void __bch2_nocow_write_done(struct bch_write_op *op)
|
||||
@ -1218,7 +1215,7 @@ static void bch2_nocow_write_done(struct closure *cl)
|
||||
static void bch2_nocow_write(struct bch_write_op *op)
|
||||
{
|
||||
struct bch_fs *c = op->c;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_ptrs_c ptrs;
|
||||
@ -1235,15 +1232,15 @@ static void bch2_nocow_write(struct bch_write_op *op)
|
||||
if (op->flags & BCH_WRITE_MOVE)
|
||||
return;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, op->subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, op->subvol, &snapshot);
|
||||
if (unlikely(ret))
|
||||
goto err;
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
SPOS(op->pos.inode, op->pos.offset, snapshot),
|
||||
BTREE_ITER_SLOTS);
|
||||
while (1) {
|
||||
@ -1289,7 +1286,7 @@ retry:
|
||||
|
||||
/* Unlock before taking nocow locks, doing IO: */
|
||||
bkey_reassemble(op->insert_keys.top, k);
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
bch2_cut_front(op->pos, op->insert_keys.top);
|
||||
if (op->flags & BCH_WRITE_CONVERT_UNWRITTEN)
|
||||
@ -1338,7 +1335,7 @@ retry:
|
||||
bch2_btree_iter_advance(&iter);
|
||||
}
|
||||
out:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
@ -1353,7 +1350,7 @@ err:
|
||||
op->flags |= BCH_WRITE_DONE;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
/* fallback to cow write path? */
|
||||
if (!(op->flags & BCH_WRITE_DONE)) {
|
||||
@ -1431,7 +1428,7 @@ again:
|
||||
* allocations for specific disks may hang arbitrarily long:
|
||||
*/
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_alloc_sectors_start_trans(&trans,
|
||||
bch2_alloc_sectors_start_trans(trans,
|
||||
op->target,
|
||||
op->opts.erasure_code && !(op->flags & BCH_WRITE_CACHED),
|
||||
op->write_point,
|
||||
|
@ -834,7 +834,7 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
|
||||
break;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
bch2_trans_mark_metadata_bucket(&trans, ca,
|
||||
bch2_trans_mark_metadata_bucket(trans, ca,
|
||||
ob[nr_got]->bucket, BCH_DATA_journal,
|
||||
ca->mi.bucket_size));
|
||||
if (ret) {
|
||||
@ -915,7 +915,7 @@ err_unblock:
|
||||
if (ret && !new_fs)
|
||||
for (i = 0; i < nr_got; i++)
|
||||
bch2_trans_run(c,
|
||||
bch2_trans_mark_metadata_bucket(&trans, ca,
|
||||
bch2_trans_mark_metadata_bucket(trans, ca,
|
||||
bu[i], BCH_DATA_free, 0));
|
||||
err_free:
|
||||
if (!new_fs)
|
||||
|
@ -250,20 +250,18 @@ void bch2_blacklist_entries_gc(struct work_struct *work)
|
||||
struct journal_seq_blacklist_table *t;
|
||||
struct bch_sb_field_journal_seq_blacklist *bl;
|
||||
struct journal_seq_blacklist_entry *src, *dst;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
unsigned i, nr, new_nr;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < BTREE_ID_NR; i++) {
|
||||
struct btree_iter iter;
|
||||
struct btree *b;
|
||||
|
||||
bch2_trans_node_iter_init(&trans, &iter, i, POS_MIN,
|
||||
bch2_trans_node_iter_init(trans, &iter, i, POS_MIN,
|
||||
0, 0, BTREE_ITER_PREFETCH);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
b = bch2_btree_iter_peek_node(&iter);
|
||||
|
||||
@ -275,10 +273,10 @@ retry:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
|
@ -59,9 +59,9 @@ int bch2_resume_logged_ops(struct bch_fs *c)
|
||||
int ret;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key2(&trans, iter,
|
||||
for_each_btree_key2(trans, iter,
|
||||
BTREE_ID_logged_ops, POS_MIN, BTREE_ITER_PREFETCH, k,
|
||||
resume_logged_op(&trans, &iter, k)));
|
||||
resume_logged_op(trans, &iter, k)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
|
@ -151,10 +151,10 @@ int bch2_check_lrus(struct bch_fs *c)
|
||||
int ret = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_lru, POS_MIN, BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
|
||||
bch2_check_lru_key(&trans, &iter, k, &last_flushed_pos)));
|
||||
bch2_check_lru_key(trans, &iter, k, &last_flushed_pos)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
|
@ -78,34 +78,32 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans,
|
||||
|
||||
static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
enum btree_id id;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||
|
||||
for (id = 0; id < BTREE_ID_NR; id++) {
|
||||
if (!btree_type_has_ptrs(id))
|
||||
continue;
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter, id, POS_MIN,
|
||||
ret = for_each_btree_key_commit(trans, iter, id, POS_MIN,
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
bch2_dev_usrdata_drop_key(&trans, &iter, k, dev_idx, flags));
|
||||
bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct closure cl;
|
||||
struct btree *b;
|
||||
@ -117,16 +115,16 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
|
||||
if (flags & BCH_FORCE_IF_METADATA_LOST)
|
||||
return -EINVAL;
|
||||
|
||||
trans = bch2_trans_get(c);
|
||||
bch2_bkey_buf_init(&k);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
closure_init_stack(&cl);
|
||||
|
||||
for (id = 0; id < BTREE_ID_NR; id++) {
|
||||
bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
|
||||
bch2_trans_node_iter_init(trans, &iter, id, POS_MIN, 0, 0,
|
||||
BTREE_ITER_PREFETCH);
|
||||
retry:
|
||||
ret = 0;
|
||||
while (bch2_trans_begin(&trans),
|
||||
while (bch2_trans_begin(trans),
|
||||
(b = bch2_btree_iter_peek_node(&iter)) &&
|
||||
!(ret = PTR_ERR_OR_ZERO(b))) {
|
||||
if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx))
|
||||
@ -141,7 +139,7 @@ retry:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bch2_btree_node_update_key(&trans, &iter, b, k.k, 0, false);
|
||||
ret = bch2_btree_node_update_key(trans, &iter, b, k.k, 0, false);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
|
||||
ret = 0;
|
||||
continue;
|
||||
@ -157,7 +155,7 @@ next:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
@ -166,8 +164,8 @@ next:
|
||||
bch2_btree_interior_updates_flush(c);
|
||||
ret = 0;
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_bkey_buf_exit(&k, c);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
BUG_ON(bch2_err_matches(ret, BCH_ERR_transaction_restart));
|
||||
|
||||
|
@ -525,7 +525,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
|
||||
struct bch_fs *c = ctxt->c;
|
||||
struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
|
||||
struct bkey_buf sk;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct data_update_opts data_opts;
|
||||
@ -533,7 +533,6 @@ static int __bch2_move_data(struct moving_context *ctxt,
|
||||
int ret = 0, ret2;
|
||||
|
||||
bch2_bkey_buf_init(&sk);
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
if (ctxt->stats) {
|
||||
ctxt->stats->data_type = BCH_DATA_user;
|
||||
@ -541,15 +540,15 @@ static int __bch2_move_data(struct moving_context *ctxt,
|
||||
ctxt->stats->pos = start;
|
||||
}
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, btree_id, start,
|
||||
bch2_trans_iter_init(trans, &iter, btree_id, start,
|
||||
BTREE_ITER_PREFETCH|
|
||||
BTREE_ITER_ALL_SNAPSHOTS);
|
||||
|
||||
if (ctxt->rate)
|
||||
bch2_ratelimit_reset(ctxt->rate);
|
||||
|
||||
while (!move_ratelimit(&trans, ctxt)) {
|
||||
bch2_trans_begin(&trans);
|
||||
while (!move_ratelimit(trans, ctxt)) {
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
k = bch2_btree_iter_peek(&iter);
|
||||
if (!k.k)
|
||||
@ -570,7 +569,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
|
||||
if (!bkey_extent_is_direct_data(k.k))
|
||||
goto next_nondata;
|
||||
|
||||
ret = move_get_io_opts(&trans, &io_opts, k, &cur_inum);
|
||||
ret = move_get_io_opts(trans, &io_opts, k, &cur_inum);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
@ -585,7 +584,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
|
||||
bch2_bkey_buf_reassemble(&sk, c, k);
|
||||
k = bkey_i_to_s_c(sk.k);
|
||||
|
||||
ret2 = bch2_move_extent(&trans, &iter, ctxt, NULL,
|
||||
ret2 = bch2_move_extent(trans, &iter, ctxt, NULL,
|
||||
io_opts, btree_id, k, data_opts);
|
||||
if (ret2) {
|
||||
if (bch2_err_matches(ret2, BCH_ERR_transaction_restart))
|
||||
@ -593,7 +592,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
|
||||
|
||||
if (ret2 == -ENOMEM) {
|
||||
/* memory allocation failure, wait for some IO to finish */
|
||||
bch2_move_ctxt_wait_for_io(ctxt, &trans);
|
||||
bch2_move_ctxt_wait_for_io(ctxt, trans);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -610,8 +609,8 @@ next_nondata:
|
||||
bch2_btree_iter_advance(&iter);
|
||||
}
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&sk, c);
|
||||
|
||||
return ret;
|
||||
@ -826,15 +825,14 @@ int bch2_evacuate_bucket(struct bch_fs *c,
|
||||
struct write_point_specifier wp,
|
||||
bool wait_on_copygc)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct moving_context ctxt;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_moving_ctxt_init(&ctxt, c, rate, stats, wp, wait_on_copygc);
|
||||
ret = __bch2_evacuate_bucket(&trans, &ctxt, NULL, bucket, gen, data_opts);
|
||||
ret = __bch2_evacuate_bucket(trans, &ctxt, NULL, bucket, gen, data_opts);
|
||||
bch2_moving_ctxt_exit(&ctxt);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -851,14 +849,13 @@ static int bch2_move_btree(struct bch_fs *c,
|
||||
{
|
||||
bool kthread = (current->flags & PF_KTHREAD) != 0;
|
||||
struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct btree *b;
|
||||
enum btree_id id;
|
||||
struct data_update_opts data_opts;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
progress_list_add(c, stats);
|
||||
|
||||
stats->data_type = BCH_DATA_btree;
|
||||
@ -871,11 +868,11 @@ static int bch2_move_btree(struct bch_fs *c,
|
||||
if (!bch2_btree_id_root(c, id)->b)
|
||||
continue;
|
||||
|
||||
bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
|
||||
bch2_trans_node_iter_init(trans, &iter, id, POS_MIN, 0, 0,
|
||||
BTREE_ITER_PREFETCH);
|
||||
retry:
|
||||
ret = 0;
|
||||
while (bch2_trans_begin(&trans),
|
||||
while (bch2_trans_begin(trans),
|
||||
(b = bch2_btree_iter_peek_node(&iter)) &&
|
||||
!(ret = PTR_ERR_OR_ZERO(b))) {
|
||||
if (kthread && kthread_should_stop())
|
||||
@ -890,7 +887,7 @@ retry:
|
||||
if (!pred(c, arg, b, &io_opts, &data_opts))
|
||||
goto next;
|
||||
|
||||
ret = bch2_btree_node_rewrite(&trans, &iter, b, 0) ?: ret;
|
||||
ret = bch2_btree_node_rewrite(trans, &iter, b, 0) ?: ret;
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
continue;
|
||||
if (ret)
|
||||
@ -901,13 +898,13 @@ next:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (kthread && kthread_should_stop())
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
|
@ -300,7 +300,7 @@ void bch2_copygc_wait_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
static int bch2_copygc_thread(void *arg)
|
||||
{
|
||||
struct bch_fs *c = arg;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct moving_context ctxt;
|
||||
struct bch_move_stats move_stats;
|
||||
struct io_clock *clock = &c->io_clock[WRITE];
|
||||
@ -317,7 +317,7 @@ static int bch2_copygc_thread(void *arg)
|
||||
}
|
||||
|
||||
set_freezable();
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
bch2_move_stats_init(&move_stats, "copygc");
|
||||
bch2_moving_ctxt_init(&ctxt, c, NULL, &move_stats,
|
||||
@ -325,16 +325,16 @@ static int bch2_copygc_thread(void *arg)
|
||||
false);
|
||||
|
||||
while (!ret && !kthread_should_stop()) {
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
cond_resched();
|
||||
|
||||
if (!c->copy_gc_enabled) {
|
||||
move_buckets_wait(&trans, &ctxt, &buckets, true);
|
||||
move_buckets_wait(trans, &ctxt, &buckets, true);
|
||||
kthread_wait_freezable(c->copy_gc_enabled);
|
||||
}
|
||||
|
||||
if (unlikely(freezing(current))) {
|
||||
move_buckets_wait(&trans, &ctxt, &buckets, true);
|
||||
move_buckets_wait(trans, &ctxt, &buckets, true);
|
||||
__refrigerator(false);
|
||||
continue;
|
||||
}
|
||||
@ -345,7 +345,7 @@ static int bch2_copygc_thread(void *arg)
|
||||
if (wait > clock->max_slop) {
|
||||
c->copygc_wait_at = last;
|
||||
c->copygc_wait = last + wait;
|
||||
move_buckets_wait(&trans, &ctxt, &buckets, true);
|
||||
move_buckets_wait(trans, &ctxt, &buckets, true);
|
||||
trace_and_count(c, copygc_wait, c, wait, last + wait);
|
||||
bch2_kthread_io_clock_wait(clock, last + wait,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
@ -355,15 +355,15 @@ static int bch2_copygc_thread(void *arg)
|
||||
c->copygc_wait = 0;
|
||||
|
||||
c->copygc_running = true;
|
||||
ret = bch2_copygc(&trans, &ctxt, &buckets);
|
||||
ret = bch2_copygc(trans, &ctxt, &buckets);
|
||||
c->copygc_running = false;
|
||||
|
||||
wake_up(&c->copygc_running_wq);
|
||||
}
|
||||
|
||||
move_buckets_wait(&trans, &ctxt, &buckets, true);
|
||||
move_buckets_wait(trans, &ctxt, &buckets, true);
|
||||
rhashtable_destroy(&buckets.table);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_moving_ctxt_exit(&ctxt);
|
||||
|
||||
return 0;
|
||||
|
@ -599,7 +599,7 @@ advance:
|
||||
int bch2_fs_quota_read(struct bch_fs *c)
|
||||
{
|
||||
struct bch_sb_field_quota *sb_quota;
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
@ -614,16 +614,16 @@ int bch2_fs_quota_read(struct bch_fs *c)
|
||||
bch2_sb_quota_read(c);
|
||||
mutex_unlock(&c->sb_lock);
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
ret = for_each_btree_key2(&trans, iter, BTREE_ID_quotas,
|
||||
ret = for_each_btree_key2(trans, iter, BTREE_ID_quotas,
|
||||
POS_MIN, BTREE_ITER_PREFETCH, k,
|
||||
__bch2_quota_set(c, k, NULL)) ?:
|
||||
for_each_btree_key2(&trans, iter, BTREE_ID_inodes,
|
||||
for_each_btree_key2(trans, iter, BTREE_ID_inodes,
|
||||
POS_MIN, BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
bch2_fs_quota_read_inode(&trans, &iter, k));
|
||||
bch2_fs_quota_read_inode(trans, &iter, k));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
@ -956,7 +956,7 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid,
|
||||
new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));
|
||||
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_set_quota_trans(&trans, &new_quota, qdq)) ?:
|
||||
bch2_set_quota_trans(trans, &new_quota, qdq)) ?:
|
||||
__bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i), qdq);
|
||||
|
||||
return bch2_err_class(ret);
|
||||
|
@ -165,7 +165,7 @@ static int bch2_journal_replay(struct bch_fs *c)
|
||||
(!k->allocated
|
||||
? BTREE_INSERT_JOURNAL_REPLAY|BCH_WATERMARK_reclaim
|
||||
: 0),
|
||||
bch2_journal_replay_key(&trans, k));
|
||||
bch2_journal_replay_key(trans, k));
|
||||
if (ret) {
|
||||
bch_err(c, "journal replay: error while replaying key at btree %s level %u: %s",
|
||||
bch2_btree_ids[k->btree_id], k->level, bch2_err_str(ret));
|
||||
@ -466,7 +466,7 @@ noinline_for_stack
|
||||
static int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
|
||||
{
|
||||
int ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW,
|
||||
__bch2_fs_upgrade_for_subvolumes(&trans));
|
||||
__bch2_fs_upgrade_for_subvolumes(trans));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1013,7 +1013,7 @@ int bch2_fs_initialize(struct bch_fs *c)
|
||||
bch2_inode_init_early(c, &lostfound_inode);
|
||||
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_create_trans(&trans,
|
||||
bch2_create_trans(trans,
|
||||
BCACHEFS_ROOT_SUBVOL_INUM,
|
||||
&root_inode, &lostfound_inode,
|
||||
&lostfound,
|
||||
|
@ -253,7 +253,7 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
u64 remap_sectors,
|
||||
u64 new_i_size, s64 *i_sectors_delta)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter dst_iter, src_iter;
|
||||
struct bkey_s_c src_k;
|
||||
struct bkey_buf new_dst, new_src;
|
||||
@ -275,11 +275,11 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
|
||||
bch2_bkey_buf_init(&new_dst);
|
||||
bch2_bkey_buf_init(&new_src);
|
||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 4096);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
bch2_trans_iter_init(&trans, &src_iter, BTREE_ID_extents, src_start,
|
||||
bch2_trans_iter_init(trans, &src_iter, BTREE_ID_extents, src_start,
|
||||
BTREE_ITER_INTENT);
|
||||
bch2_trans_iter_init(&trans, &dst_iter, BTREE_ID_extents, dst_start,
|
||||
bch2_trans_iter_init(trans, &dst_iter, BTREE_ID_extents, dst_start,
|
||||
BTREE_ITER_INTENT);
|
||||
|
||||
while ((ret == 0 ||
|
||||
@ -287,21 +287,21 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
bkey_lt(dst_iter.pos, dst_end)) {
|
||||
struct disk_reservation disk_res = { 0 };
|
||||
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
if (fatal_signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, src_inum.subvol,
|
||||
ret = bch2_subvolume_get_snapshot(trans, src_inum.subvol,
|
||||
&src_snapshot);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
bch2_btree_iter_set_snapshot(&src_iter, src_snapshot);
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, dst_inum.subvol,
|
||||
ret = bch2_subvolume_get_snapshot(trans, dst_inum.subvol,
|
||||
&dst_snapshot);
|
||||
if (ret)
|
||||
continue;
|
||||
@ -318,7 +318,7 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
continue;
|
||||
|
||||
if (bkey_lt(src_want, src_iter.pos)) {
|
||||
ret = bch2_fpunch_at(&trans, &dst_iter, dst_inum,
|
||||
ret = bch2_fpunch_at(trans, &dst_iter, dst_inum,
|
||||
min(dst_end.offset,
|
||||
dst_iter.pos.offset +
|
||||
src_iter.pos.offset - src_want.offset),
|
||||
@ -332,7 +332,7 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
bch2_bkey_buf_reassemble(&new_src, c, src_k);
|
||||
src_k = bkey_i_to_s_c(new_src.k);
|
||||
|
||||
ret = bch2_make_extent_indirect(&trans, &src_iter,
|
||||
ret = bch2_make_extent_indirect(trans, &src_iter,
|
||||
new_src.k);
|
||||
if (ret)
|
||||
continue;
|
||||
@ -360,14 +360,14 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
min(src_k.k->p.offset - src_want.offset,
|
||||
dst_end.offset - dst_iter.pos.offset));
|
||||
|
||||
ret = bch2_extent_update(&trans, dst_inum, &dst_iter,
|
||||
ret = bch2_extent_update(trans, dst_inum, &dst_iter,
|
||||
new_dst.k, &disk_res,
|
||||
new_i_size, i_sectors_delta,
|
||||
true);
|
||||
bch2_disk_reservation_put(c, &disk_res);
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &dst_iter);
|
||||
bch2_trans_iter_exit(&trans, &src_iter);
|
||||
bch2_trans_iter_exit(trans, &dst_iter);
|
||||
bch2_trans_iter_exit(trans, &src_iter);
|
||||
|
||||
BUG_ON(!ret && !bkey_eq(dst_iter.pos, dst_end));
|
||||
BUG_ON(bkey_gt(dst_iter.pos, dst_end));
|
||||
@ -379,23 +379,23 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct btree_iter inode_iter = { NULL };
|
||||
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret2 = bch2_inode_peek(&trans, &inode_iter, &inode_u,
|
||||
ret2 = bch2_inode_peek(trans, &inode_iter, &inode_u,
|
||||
dst_inum, BTREE_ITER_INTENT);
|
||||
|
||||
if (!ret2 &&
|
||||
inode_u.bi_size < new_i_size) {
|
||||
inode_u.bi_size = new_i_size;
|
||||
ret2 = bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
|
||||
bch2_trans_commit(&trans, NULL, NULL,
|
||||
ret2 = bch2_inode_write(trans, &inode_iter, &inode_u) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL);
|
||||
}
|
||||
|
||||
bch2_trans_iter_exit(&trans, &inode_iter);
|
||||
bch2_trans_iter_exit(trans, &inode_iter);
|
||||
} while (bch2_err_matches(ret2, BCH_ERR_transaction_restart));
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
bch2_bkey_buf_exit(&new_src, c);
|
||||
bch2_bkey_buf_exit(&new_dst, c);
|
||||
|
||||
|
@ -610,11 +610,11 @@ int bch2_check_snapshot_trees(struct bch_fs *c)
|
||||
int ret;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_snapshot_trees, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_snapshot_tree(&trans, &iter, k)));
|
||||
check_snapshot_tree(trans, &iter, k)));
|
||||
|
||||
if (ret)
|
||||
bch_err(c, "error %i checking snapshot trees", ret);
|
||||
@ -883,11 +883,11 @@ int bch2_check_snapshots(struct bch_fs *c)
|
||||
* the parent's depth already be correct:
|
||||
*/
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_reverse_commit(&trans, iter,
|
||||
for_each_btree_key_reverse_commit(trans, iter,
|
||||
BTREE_ID_snapshots, POS_MAX,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_snapshot(&trans, &iter, k)));
|
||||
check_snapshot(trans, &iter, k)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1373,7 +1373,7 @@ static int bch2_fix_child_of_deleted_snapshot(struct btree_trans *trans,
|
||||
|
||||
int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_s_c_snapshot snap;
|
||||
@ -1390,30 +1390,30 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
}
|
||||
}
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
/*
|
||||
* For every snapshot node: If we have no live children and it's not
|
||||
* pointed to by a subvolume, delete it:
|
||||
*/
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_snapshots,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_snapshots,
|
||||
POS_MIN, 0, k,
|
||||
NULL, NULL, 0,
|
||||
bch2_delete_redundant_snapshot(&trans, &iter, k));
|
||||
bch2_delete_redundant_snapshot(trans, &iter, k));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "deleting redundant snapshots");
|
||||
goto err;
|
||||
}
|
||||
|
||||
for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
|
||||
for_each_btree_key2(trans, iter, BTREE_ID_snapshots,
|
||||
POS_MIN, 0, k,
|
||||
bch2_snapshot_set_equiv(&trans, k));
|
||||
bch2_snapshot_set_equiv(trans, k));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "in bch2_snapshots_set_equiv");
|
||||
goto err;
|
||||
}
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_snapshots,
|
||||
POS_MIN, 0, k, ret) {
|
||||
if (k.k->type != KEY_TYPE_snapshot)
|
||||
continue;
|
||||
@ -1425,7 +1425,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
break;
|
||||
}
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "walking snapshots");
|
||||
@ -1440,16 +1440,16 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
if (!btree_type_has_snapshots(id))
|
||||
continue;
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter,
|
||||
ret = for_each_btree_key_commit(trans, iter,
|
||||
id, POS_MIN,
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
&res, NULL, BTREE_INSERT_NOFAIL,
|
||||
snapshot_delete_key(&trans, &iter, k, &deleted, &equiv_seen, &last_pos)) ?:
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
snapshot_delete_key(trans, &iter, k, &deleted, &equiv_seen, &last_pos)) ?:
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
id, POS_MIN,
|
||||
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||
&res, NULL, BTREE_INSERT_NOFAIL,
|
||||
move_key_to_correct_snapshot(&trans, &iter, k));
|
||||
move_key_to_correct_snapshot(trans, &iter, k));
|
||||
|
||||
bch2_disk_reservation_put(c, &res);
|
||||
darray_exit(&equiv_seen);
|
||||
@ -1460,7 +1460,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
}
|
||||
}
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
|
||||
for_each_btree_key(trans, iter, BTREE_ID_snapshots,
|
||||
POS_MIN, 0, k, ret) {
|
||||
u32 snapshot = k.k->p.offset;
|
||||
u32 equiv = bch2_snapshot_equiv(c, snapshot);
|
||||
@ -1468,23 +1468,23 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
if (equiv != snapshot)
|
||||
snapshot_list_add(c, &deleted_interior, snapshot);
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
/*
|
||||
* Fixing children of deleted snapshots can't be done completely
|
||||
* atomically, if we crash between here and when we delete the interior
|
||||
* nodes some depth fields will be off:
|
||||
*/
|
||||
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_snapshots, POS_MIN,
|
||||
ret = for_each_btree_key_commit(trans, iter, BTREE_ID_snapshots, POS_MIN,
|
||||
BTREE_ITER_INTENT, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL,
|
||||
bch2_fix_child_of_deleted_snapshot(&trans, &iter, k, &deleted_interior));
|
||||
bch2_fix_child_of_deleted_snapshot(trans, &iter, k, &deleted_interior));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
darray_for_each(deleted, i) {
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_snapshot_node_delete(&trans, *i));
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_snapshot_node_delete(trans, *i));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "deleting snapshot %u", *i);
|
||||
goto err;
|
||||
@ -1492,8 +1492,8 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
}
|
||||
|
||||
darray_for_each(deleted_interior, i) {
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_snapshot_node_delete(&trans, *i));
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_snapshot_node_delete(trans, *i));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "deleting snapshot %u", *i);
|
||||
goto err;
|
||||
@ -1504,7 +1504,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||
err:
|
||||
darray_exit(&deleted_interior);
|
||||
darray_exit(&deleted);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -1671,11 +1671,11 @@ int bch2_snapshots_read(struct bch_fs *c)
|
||||
int ret = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
|
||||
for_each_btree_key2(trans, iter, BTREE_ID_snapshots,
|
||||
POS_MIN, 0, k,
|
||||
bch2_mark_snapshot(&trans, BTREE_ID_snapshots, 0, bkey_s_c_null, k, 0) ?:
|
||||
bch2_snapshot_set_equiv(&trans, k)) ?:
|
||||
for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
|
||||
bch2_mark_snapshot(trans, BTREE_ID_snapshots, 0, bkey_s_c_null, k, 0) ?:
|
||||
bch2_snapshot_set_equiv(trans, k)) ?:
|
||||
for_each_btree_key2(trans, iter, BTREE_ID_snapshots,
|
||||
POS_MIN, 0, k,
|
||||
(set_is_ancestor_bitmap(c, k.k->p.offset), 0)));
|
||||
if (ret)
|
||||
|
@ -86,10 +86,10 @@ int bch2_check_subvols(struct bch_fs *c)
|
||||
int ret;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_subvolumes, POS_MIN, BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||
check_subvol(&trans, &iter, k)));
|
||||
check_subvol(trans, &iter, k)));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
@ -293,7 +293,7 @@ static void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *wor
|
||||
bch2_evict_subvolume_inodes(c, &s);
|
||||
|
||||
for (id = s.data; id < s.data + s.nr; id++) {
|
||||
ret = bch2_trans_run(c, bch2_subvolume_delete(&trans, *id));
|
||||
ret = bch2_trans_run(c, bch2_subvolume_delete(trans, *id));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "deleting subvolume %u", *id);
|
||||
break;
|
||||
|
@ -470,7 +470,6 @@ int bch2_fs_read_write_early(struct bch_fs *c)
|
||||
static void __bch2_fs_free(struct bch_fs *c)
|
||||
{
|
||||
unsigned i;
|
||||
int cpu;
|
||||
|
||||
for (i = 0; i < BCH_TIME_STAT_NR; i++)
|
||||
bch2_time_stats_exit(&c->times[i]);
|
||||
@ -502,12 +501,7 @@ static void __bch2_fs_free(struct bch_fs *c)
|
||||
percpu_free_rwsem(&c->mark_lock);
|
||||
free_percpu(c->online_reserved);
|
||||
|
||||
if (c->btree_paths_bufs)
|
||||
for_each_possible_cpu(cpu)
|
||||
kfree(per_cpu_ptr(c->btree_paths_bufs, cpu)->path);
|
||||
|
||||
darray_exit(&c->btree_roots_extra);
|
||||
free_percpu(c->btree_paths_bufs);
|
||||
free_percpu(c->pcpu);
|
||||
mempool_exit(&c->large_bkey_pool);
|
||||
mempool_exit(&c->btree_bounce_pool);
|
||||
@ -829,7 +823,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
|
||||
BIOSET_NEED_BVECS) ||
|
||||
!(c->pcpu = alloc_percpu(struct bch_fs_pcpu)) ||
|
||||
!(c->online_reserved = alloc_percpu(u64)) ||
|
||||
!(c->btree_paths_bufs = alloc_percpu(struct btree_path_buf)) ||
|
||||
mempool_init_kvpmalloc_pool(&c->btree_bounce_pool, 1,
|
||||
btree_bytes(c)) ||
|
||||
mempool_init_kmalloc_pool(&c->large_bkey_pool, 1, 2048) ||
|
||||
|
@ -252,7 +252,7 @@ static size_t bch2_btree_cache_size(struct bch_fs *c)
|
||||
|
||||
static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
enum btree_id id;
|
||||
@ -268,13 +268,13 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c
|
||||
if (!test_bit(BCH_FS_STARTED, &c->flags))
|
||||
return -EPERM;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
trans = bch2_trans_get(c);
|
||||
|
||||
for (id = 0; id < BTREE_ID_NR; id++) {
|
||||
if (!btree_type_has_ptrs(id))
|
||||
continue;
|
||||
|
||||
for_each_btree_key(&trans, iter, id, POS_MIN,
|
||||
for_each_btree_key(trans, iter, id, POS_MIN,
|
||||
BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
const union bch_extent_entry *entry;
|
||||
@ -308,10 +308,10 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c
|
||||
else if (compressed)
|
||||
nr_compressed_extents++;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -31,7 +31,7 @@ static void delete_test_keys(struct bch_fs *c)
|
||||
|
||||
static int test_delete(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_i_cookie k;
|
||||
int ret;
|
||||
@ -39,44 +39,43 @@ static int test_delete(struct bch_fs *c, u64 nr)
|
||||
bkey_cookie_init(&k.k_i);
|
||||
k.k.p.snapshot = U32_MAX;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs, k.k.p,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs, k.k.p,
|
||||
BTREE_ITER_INTENT);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_iter_traverse(&iter) ?:
|
||||
bch2_trans_update(&trans, &iter, &k.k_i, 0));
|
||||
bch2_trans_update(trans, &iter, &k.k_i, 0));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "update error");
|
||||
goto err;
|
||||
}
|
||||
|
||||
pr_info("deleting once");
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_iter_traverse(&iter) ?:
|
||||
bch2_btree_delete_at(&trans, &iter, 0));
|
||||
bch2_btree_delete_at(trans, &iter, 0));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "delete error (first)");
|
||||
goto err;
|
||||
}
|
||||
|
||||
pr_info("deleting twice");
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_iter_traverse(&iter) ?:
|
||||
bch2_btree_delete_at(&trans, &iter, 0));
|
||||
bch2_btree_delete_at(trans, &iter, 0));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "delete error (second)");
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_delete_written(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_i_cookie k;
|
||||
int ret;
|
||||
@ -84,45 +83,41 @@ static int test_delete_written(struct bch_fs *c, u64 nr)
|
||||
bkey_cookie_init(&k.k_i);
|
||||
k.k.p.snapshot = U32_MAX;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs, k.k.p,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs, k.k.p,
|
||||
BTREE_ITER_INTENT);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_iter_traverse(&iter) ?:
|
||||
bch2_trans_update(&trans, &iter, &k.k_i, 0));
|
||||
bch2_trans_update(trans, &iter, &k.k_i, 0));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "update error");
|
||||
goto err;
|
||||
}
|
||||
|
||||
bch2_trans_unlock(&trans);
|
||||
bch2_trans_unlock(trans);
|
||||
bch2_journal_flush_all_pins(&c->journal);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_iter_traverse(&iter) ?:
|
||||
bch2_btree_delete_at(&trans, &iter, 0));
|
||||
bch2_btree_delete_at(trans, &iter, 0));
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "delete error");
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_iterate(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bkey_s_c k;
|
||||
u64 i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
delete_test_keys(c);
|
||||
|
||||
pr_info("inserting test keys");
|
||||
@ -145,7 +140,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
|
||||
|
||||
i = 0;
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(k.k->p.offset != i++);
|
||||
@ -160,7 +155,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
|
||||
|
||||
pr_info("iterating backwards");
|
||||
|
||||
ret = for_each_btree_key_reverse(&trans, iter, BTREE_ID_xattrs,
|
||||
ret = for_each_btree_key_reverse(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, U64_MAX, U32_MAX), 0, k,
|
||||
({
|
||||
BUG_ON(k.k->p.offset != --i);
|
||||
@ -173,21 +168,19 @@ static int test_iterate(struct bch_fs *c, u64 nr)
|
||||
|
||||
BUG_ON(i);
|
||||
err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_iterate_extents(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bkey_s_c k;
|
||||
u64 i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
delete_test_keys(c);
|
||||
|
||||
pr_info("inserting test extents");
|
||||
@ -211,7 +204,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
|
||||
|
||||
i = 0;
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(bkey_start_offset(k.k) != i);
|
||||
@ -227,7 +220,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
|
||||
|
||||
pr_info("iterating backwards");
|
||||
|
||||
ret = for_each_btree_key_reverse(&trans, iter, BTREE_ID_extents,
|
||||
ret = for_each_btree_key_reverse(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, U64_MAX, U32_MAX), 0, k,
|
||||
({
|
||||
BUG_ON(k.k->p.offset != i);
|
||||
@ -241,21 +234,19 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
|
||||
|
||||
BUG_ON(i);
|
||||
err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_iterate_slots(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bkey_s_c k;
|
||||
u64 i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
delete_test_keys(c);
|
||||
|
||||
pr_info("inserting test keys");
|
||||
@ -278,7 +269,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
|
||||
|
||||
i = 0;
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(k.k->p.offset != i);
|
||||
@ -296,7 +287,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
|
||||
|
||||
i = 0;
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
BTREE_ITER_SLOTS, k, ({
|
||||
if (i >= nr * 2)
|
||||
@ -314,20 +305,18 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
|
||||
}
|
||||
ret = 0;
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter = { NULL };
|
||||
struct bkey_s_c k;
|
||||
u64 i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
delete_test_keys(c);
|
||||
|
||||
pr_info("inserting test keys");
|
||||
@ -351,7 +340,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
|
||||
|
||||
i = 0;
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(bkey_start_offset(k.k) != i + 8);
|
||||
@ -370,7 +359,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
|
||||
|
||||
i = 0;
|
||||
|
||||
ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
|
||||
ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
BTREE_ITER_SLOTS, k, ({
|
||||
if (i == nr)
|
||||
@ -388,7 +377,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
|
||||
}
|
||||
ret = 0;
|
||||
err:
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -398,43 +387,41 @@ err:
|
||||
*/
|
||||
static int test_peek_end(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), 0);
|
||||
|
||||
lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_peek_end_extents(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), 0);
|
||||
|
||||
lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -510,7 +497,7 @@ static int insert_test_overlapping_extent(struct bch_fs *c, u64 inum, u64 start,
|
||||
k.k_i.k.size = len;
|
||||
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_btree_insert_nonextent(&trans, BTREE_ID_extents, &k.k_i,
|
||||
bch2_btree_insert_nonextent(trans, BTREE_ID_extents, &k.k_i,
|
||||
BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE));
|
||||
if (ret)
|
||||
bch_err_fn(c, ret);
|
||||
@ -533,7 +520,7 @@ static int test_extent_create_overlapping(struct bch_fs *c, u64 inum)
|
||||
/* Test skipping over keys in unrelated snapshots: */
|
||||
static int test_snapshot_filter(struct bch_fs *c, u32 snapid_lo, u32 snapid_hi)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_i_cookie cookie;
|
||||
@ -545,15 +532,15 @@ static int test_snapshot_filter(struct bch_fs *c, u32 snapid_lo, u32 snapid_hi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
|
||||
trans = bch2_trans_get(c);
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, snapid_lo), 0);
|
||||
lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
|
||||
BUG_ON(k.k->p.snapshot != U32_MAX);
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -571,7 +558,7 @@ static int test_snapshots(struct bch_fs *c, u64 nr)
|
||||
return ret;
|
||||
|
||||
ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_snapshot_node_create(&trans, U32_MAX,
|
||||
bch2_snapshot_node_create(trans, U32_MAX,
|
||||
snapids,
|
||||
snapid_subvols,
|
||||
2));
|
||||
@ -602,38 +589,34 @@ static u64 test_rand(void)
|
||||
|
||||
static int rand_insert(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bkey_i_cookie k;
|
||||
int ret = 0;
|
||||
u64 i;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
bkey_cookie_init(&k.k_i);
|
||||
k.k.p.offset = test_rand();
|
||||
k.k.p.snapshot = U32_MAX;
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k.k_i, 0));
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k.k_i, 0));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rand_insert_multi(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bkey_i_cookie k[8];
|
||||
int ret = 0;
|
||||
unsigned j;
|
||||
u64 i;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < nr; i += ARRAY_SIZE(k)) {
|
||||
for (j = 0; j < ARRAY_SIZE(k); j++) {
|
||||
bkey_cookie_init(&k[j].k_i);
|
||||
@ -641,46 +624,45 @@ static int rand_insert_multi(struct bch_fs *c, u64 nr)
|
||||
k[j].k.p.snapshot = U32_MAX;
|
||||
}
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[0].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[1].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[2].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[3].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[4].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[5].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[6].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[7].k_i, 0));
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[0].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[1].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[2].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[3].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[4].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[5].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[6].k_i, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[7].k_i, 0));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rand_lookup(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
u64 i;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), 0);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
bch2_btree_iter_set_pos(&iter, SPOS(0, test_rand(), U32_MAX));
|
||||
|
||||
lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
|
||||
lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -712,26 +694,25 @@ static int rand_mixed_trans(struct btree_trans *trans,
|
||||
|
||||
static int rand_mixed(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_i_cookie cookie;
|
||||
int ret = 0;
|
||||
u64 i, rand;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), 0);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
rand = test_rand();
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
rand_mixed_trans(&trans, &iter, &cookie, i, rand));
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
rand_mixed_trans(trans, &iter, &cookie, i, rand));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -759,22 +740,20 @@ err:
|
||||
|
||||
static int rand_delete(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
int ret = 0;
|
||||
u64 i;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
struct bpos pos = SPOS(0, test_rand(), U32_MAX);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
__do_delete(&trans, pos));
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
__do_delete(trans, pos));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -787,14 +766,14 @@ static int seq_insert(struct bch_fs *c, u64 nr)
|
||||
bkey_cookie_init(&insert.k_i);
|
||||
|
||||
return bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
|
||||
for_each_btree_key_commit(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX),
|
||||
BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k,
|
||||
NULL, NULL, 0, ({
|
||||
if (iter.pos.offset >= nr)
|
||||
break;
|
||||
insert.k.p = iter.pos;
|
||||
bch2_trans_update(&trans, &iter, &insert.k_i, 0);
|
||||
bch2_trans_update(trans, &iter, &insert.k_i, 0);
|
||||
})));
|
||||
}
|
||||
|
||||
@ -804,7 +783,7 @@ static int seq_lookup(struct bch_fs *c, u64 nr)
|
||||
struct bkey_s_c k;
|
||||
|
||||
return bch2_trans_run(c,
|
||||
for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
|
||||
for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k,
|
||||
0));
|
||||
@ -816,14 +795,14 @@ static int seq_overwrite(struct bch_fs *c, u64 nr)
|
||||
struct bkey_s_c k;
|
||||
|
||||
return bch2_trans_run(c,
|
||||
for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
|
||||
for_each_btree_key_commit(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX),
|
||||
BTREE_ITER_INTENT, k,
|
||||
NULL, NULL, 0, ({
|
||||
struct bkey_i_cookie u;
|
||||
|
||||
bkey_reassemble(&u.k_i, k);
|
||||
bch2_trans_update(&trans, &iter, &u.k_i, 0);
|
||||
bch2_trans_update(trans, &iter, &u.k_i, 0);
|
||||
})));
|
||||
}
|
||||
|
||||
|
@ -307,24 +307,22 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
|
||||
{
|
||||
struct bch_fs *c = dentry->d_sb->s_fs_info;
|
||||
struct bch_inode_info *inode = to_bch_ei(dentry->d_inode);
|
||||
struct btree_trans trans;
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct xattr_buf buf = { .buf = buffer, .len = buffer_size };
|
||||
u64 offset = 0, inum = inode->ei_inode.bi_inum;
|
||||
u32 snapshot;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
retry:
|
||||
bch2_trans_begin(&trans);
|
||||
bch2_trans_begin(trans);
|
||||
iter = (struct btree_iter) { NULL };
|
||||
|
||||
ret = bch2_subvolume_get_snapshot(&trans, inode->ei_subvol, &snapshot);
|
||||
ret = bch2_subvolume_get_snapshot(trans, inode->ei_subvol, &snapshot);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_xattrs,
|
||||
for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(inum, offset, snapshot),
|
||||
POS(inum, U64_MAX), 0, k, ret) {
|
||||
if (k.k->type != KEY_TYPE_xattr)
|
||||
@ -336,12 +334,12 @@ retry:
|
||||
}
|
||||
|
||||
offset = iter.pos.offset;
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
err:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
bch2_trans_put(trans);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
@ -366,7 +364,7 @@ static int bch2_xattr_get_handler(const struct xattr_handler *handler,
|
||||
struct bch_inode_info *inode = to_bch_ei(vinode);
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
int ret = bch2_trans_do(c, NULL, NULL, 0,
|
||||
bch2_xattr_get_trans(&trans, inode, name, buffer, size, handler->flags));
|
||||
bch2_xattr_get_trans(trans, inode, name, buffer, size, handler->flags));
|
||||
|
||||
return bch2_err_class(ret);
|
||||
}
|
||||
@ -381,18 +379,14 @@ static int bch2_xattr_set_handler(const struct xattr_handler *handler,
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct bch_hash_info hash = bch2_hash_info_init(c, &inode->ei_inode);
|
||||
struct bch_inode_unpacked inode_u;
|
||||
struct btree_trans trans;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
ret = commit_do(&trans, NULL, NULL, 0,
|
||||
bch2_xattr_set(&trans, inode_inum(inode), &inode_u,
|
||||
ret = bch2_trans_run(c,
|
||||
commit_do(trans, NULL, NULL, 0,
|
||||
bch2_xattr_set(trans, inode_inum(inode), &inode_u,
|
||||
&hash, name, value, size,
|
||||
handler->flags, flags));
|
||||
if (!ret)
|
||||
bch2_inode_update_after_write(&trans, inode, &inode_u, ATTR_CTIME);
|
||||
bch2_trans_exit(&trans);
|
||||
handler->flags, flags)) ?:
|
||||
(bch2_inode_update_after_write(trans, inode, &inode_u, ATTR_CTIME), 0));
|
||||
|
||||
return bch2_err_class(ret);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user