static noinline int bch2_inode_unpack_slowpath(struct bkey_s_c k,
struct bch_inode_unpacked *unpacked)
{
+ memset(unpacked, 0, sizeof(*unpacked));
+
switch (k.k->type) {
case KEY_TYPE_inode: {
struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
if (ret)
return ret;
- bch2_trans_iter_init(trans, iter, BTREE_ID_inodes,
- SPOS(0, inum.inum, snapshot),
- flags|BTREE_ITER_CACHED);
- k = bch2_btree_iter_peek_slot(iter);
+ k = bch2_bkey_get_iter(trans, iter, BTREE_ID_inodes,
+ SPOS(0, inum.inum, snapshot),
+ flags|BTREE_ITER_CACHED);
ret = bkey_err(k);
if (ret)
- goto err;
+ return ret;
ret = bkey_is_inode(k.k) ? 0 : -ENOENT;
if (ret)
}
int bch2_inode_invalid(const struct bch_fs *c, struct bkey_s_c k,
- int rw, struct printbuf *err)
+ unsigned flags, struct printbuf *err)
{
struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
- if (bkey_val_bytes(k.k) < sizeof(*inode.v)) {
- prt_printf(err, "incorrect value size (%zu < %zu)",
- bkey_val_bytes(k.k), sizeof(*inode.v));
- return -BCH_ERR_invalid_bkey;
- }
-
if (INODE_STR_HASH(inode.v) >= BCH_STR_HASH_NR) {
prt_printf(err, "invalid str hash type (%llu >= %u)",
INODE_STR_HASH(inode.v), BCH_STR_HASH_NR);
}
int bch2_inode_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
- int rw, struct printbuf *err)
+ unsigned flags, struct printbuf *err)
{
struct bkey_s_c_inode_v2 inode = bkey_s_c_to_inode_v2(k);
- if (bkey_val_bytes(k.k) < sizeof(*inode.v)) {
- prt_printf(err, "incorrect value size (%zu < %zu)",
- bkey_val_bytes(k.k), sizeof(*inode.v));
- return -BCH_ERR_invalid_bkey;
- }
-
if (INODEv2_STR_HASH(inode.v) >= BCH_STR_HASH_NR) {
prt_printf(err, "invalid str hash type (%llu >= %u)",
INODEv2_STR_HASH(inode.v), BCH_STR_HASH_NR);
}
int bch2_inode_v3_invalid(const struct bch_fs *c, struct bkey_s_c k,
- int rw, struct printbuf *err)
+ unsigned flags, struct printbuf *err)
{
struct bkey_s_c_inode_v3 inode = bkey_s_c_to_inode_v3(k);
- if (bkey_val_bytes(k.k) < sizeof(*inode.v)) {
- prt_printf(err, "incorrect value size (%zu < %zu)",
- bkey_val_bytes(k.k), sizeof(*inode.v));
- return -BCH_ERR_invalid_bkey;
- }
-
if (INODEv3_FIELDS_START(inode.v) < INODEv3_FIELDS_START_INITIAL ||
INODEv3_FIELDS_START(inode.v) > bkey_val_u64s(inode.k)) {
prt_printf(err, "invalid fields_start (got %llu, min %u max %zu)",
}
int bch2_inode_generation_invalid(const struct bch_fs *c, struct bkey_s_c k,
- int rw, struct printbuf *err)
+ unsigned flags, struct printbuf *err)
{
if (k.k->p.inode) {
prt_printf(err, "nonzero k.p.inode");
return -BCH_ERR_invalid_bkey;
}
- if (bkey_val_bytes(k.k) != sizeof(struct bch_inode_generation)) {
- prt_printf(err, "incorrect value size (%zu != %zu)",
- bkey_val_bytes(k.k), sizeof(struct bch_inode_generation));
- return -BCH_ERR_invalid_bkey;
- }
-
return 0;
}
while ((k = bch2_btree_iter_peek(iter)).k &&
!(ret = bkey_err(k)) &&
bkey_lt(k.k->p, POS(0, max))) {
- while (pos < iter->pos.offset) {
- if (!bch2_btree_key_cache_find(c, BTREE_ID_inodes, POS(0, pos)))
- goto found_slot;
-
- pos++;
- }
-
- if (k.k->p.snapshot == snapshot &&
- !bkey_is_inode(k.k) &&
- !bch2_btree_key_cache_find(c, BTREE_ID_inodes, SPOS(0, pos, snapshot))) {
- bch2_btree_iter_advance(iter);
- continue;
- }
+ if (pos < iter->pos.offset)
+ goto found_slot;
/*
* We don't need to iterate over keys in every snapshot once
bch2_btree_iter_set_pos(iter, POS(0, pos));
}
- while (!ret && pos < max) {
- if (!bch2_btree_key_cache_find(c, BTREE_ID_inodes, POS(0, pos)))
- goto found_slot;
-
- pos++;
- }
+ if (!ret && pos < max)
+ goto found_slot;
if (!ret && start == min)
ret = -BCH_ERR_ENOSPC_inode_create;
return ret;
}
- /* We may have raced while the iterator wasn't pointing at pos: */
- if (bkey_is_inode(k.k) ||
- bch2_btree_key_cache_find(c, BTREE_ID_inodes, k.k->p))
- goto again;
-
*hint = k.k->p.offset;
inode_u->bi_inum = k.k->p.offset;
inode_u->bi_generation = bkey_generation(k);
int ret = 0;
/*
- * We're never going to be deleting extents, no need to use an extent
- * iterator:
+ * We're never going to be deleting partial extents, no need to use an
+ * extent iterator:
*/
bch2_trans_iter_init(trans, &iter, id, POS(inum.inum, 0),
- BTREE_ITER_INTENT);
+ BTREE_ITER_INTENT|BTREE_ITER_NOT_EXTENTS);
while (1) {
bch2_trans_begin(trans);
bkey_init(&delete.k);
delete.k.p = iter.pos;
- if (iter.flags & BTREE_ITER_IS_EXTENTS) {
- bch2_key_resize(&delete.k, k.k->p.offset - iter.pos.offset);
-
- ret = bch2_extent_trim_atomic(trans, &iter, &delete);
- if (ret)
- goto err;
- }
-
ret = bch2_trans_update(trans, &iter, &delete, 0) ?:
bch2_trans_commit(trans, NULL, NULL,
BTREE_INSERT_NOFAIL);
if (ret)
goto err;
- bch2_trans_iter_init(&trans, &iter, BTREE_ID_inodes,
- SPOS(0, inum.inum, snapshot),
- BTREE_ITER_INTENT|BTREE_ITER_CACHED);
- k = bch2_btree_iter_peek_slot(&iter);
-
+ 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);
if (ret)
goto err;
if (!bkey_is_inode(k.k)) {
bch2_fs_inconsistent(trans.c,
- "inode %llu not found when deleting",
- inum.inum);
+ "inode %llu:%u not found when deleting",
+ inum.inum, snapshot);
ret = -EIO;
goto err;
}
bch2_inode_unpack(k, &inode_u);
- /* Subvolume root? */
- BUG_ON(inode_u.bi_subvol);
-
bkey_inode_generation_init(&delete.k_i);
delete.k.p = iter.pos;
delete.v.bi_generation = cpu_to_le32(inode_u.bi_generation + 1);