mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +03:00
Update bcachefs sources to 2f11bb05b0 bcachefs: for_each_btree_key2()
This commit is contained in:
parent
0e69c66198
commit
2cea78f5cc
@ -1 +1 @@
|
|||||||
17a344f26599e37e7023a6daff813e4d1a96cdd2
|
2f11bb05b0df04b7e0e190fd27b111e9f20cd749
|
||||||
|
@ -356,6 +356,37 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
|
|||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define for_each_btree_key2(_trans, _iter, _btree_id, \
|
||||||
|
_start, _flags, _k, _do) \
|
||||||
|
({ \
|
||||||
|
int _ret = 0; \
|
||||||
|
\
|
||||||
|
bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
|
||||||
|
(_start), (_flags)); \
|
||||||
|
\
|
||||||
|
do { \
|
||||||
|
bch2_trans_begin(_trans); \
|
||||||
|
(_k) = bch2_btree_iter_peek_type(&(_iter), (_flags)); \
|
||||||
|
if (!(_k).k) \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
_ret = bkey_err(_k) ?: (_do); \
|
||||||
|
if (!_ret) \
|
||||||
|
bch2_btree_iter_advance(&(_iter)); \
|
||||||
|
} while (_ret == 0 || _ret == -EINTR); \
|
||||||
|
\
|
||||||
|
bch2_trans_iter_exit((_trans), &(_iter)); \
|
||||||
|
_ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define for_each_btree_key_commit(_trans, _iter, _btree_id, \
|
||||||
|
_start, _iter_flags, _k, \
|
||||||
|
_disk_res, _journal_seq, _commit_flags,\
|
||||||
|
_do) \
|
||||||
|
for_each_btree_key2(_trans, _iter, _btree_id, _start, _iter_flags, _k,\
|
||||||
|
(_do) ?: bch2_trans_commit(_trans, (_disk_res),\
|
||||||
|
(_journal_seq), (_commit_flags)))
|
||||||
|
|
||||||
#define for_each_btree_key(_trans, _iter, _btree_id, \
|
#define for_each_btree_key(_trans, _iter, _btree_id, \
|
||||||
_start, _flags, _k, _ret) \
|
_start, _flags, _k, _ret) \
|
||||||
for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
|
for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
|
||||||
|
@ -830,24 +830,16 @@ fsck_err:
|
|||||||
|
|
||||||
static int check_inode(struct btree_trans *trans,
|
static int check_inode(struct btree_trans *trans,
|
||||||
struct btree_iter *iter,
|
struct btree_iter *iter,
|
||||||
|
struct bkey_s_c k,
|
||||||
struct bch_inode_unpacked *prev,
|
struct bch_inode_unpacked *prev,
|
||||||
struct snapshots_seen *s,
|
struct snapshots_seen *s,
|
||||||
bool full)
|
bool full)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct bkey_s_c k;
|
|
||||||
struct bch_inode_unpacked u;
|
struct bch_inode_unpacked u;
|
||||||
bool do_update = false;
|
bool do_update = false;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
k = bch2_btree_iter_peek(iter);
|
|
||||||
if (!k.k)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = bkey_err(k);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = check_key_has_snapshot(trans, iter, k);
|
ret = check_key_has_snapshot(trans, iter, k);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
@ -981,25 +973,19 @@ static int check_inodes(struct bch_fs *c, bool full)
|
|||||||
struct btree_iter iter;
|
struct btree_iter iter;
|
||||||
struct bch_inode_unpacked prev = { 0 };
|
struct bch_inode_unpacked prev = { 0 };
|
||||||
struct snapshots_seen s;
|
struct snapshots_seen s;
|
||||||
|
struct bkey_s_c k;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
snapshots_seen_init(&s);
|
snapshots_seen_init(&s);
|
||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_inodes, POS_MIN,
|
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_inodes,
|
||||||
BTREE_ITER_INTENT|
|
POS_MIN,
|
||||||
BTREE_ITER_PREFETCH|
|
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
|
||||||
BTREE_ITER_ALL_SNAPSHOTS);
|
k,
|
||||||
|
NULL, NULL,
|
||||||
do {
|
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||||
ret = commit_do(&trans, NULL, NULL,
|
check_inode(&trans, &iter, k, &prev, &s, full));
|
||||||
BTREE_INSERT_LAZY_RW|
|
|
||||||
BTREE_INSERT_NOFAIL,
|
|
||||||
check_inode(&trans, &iter, &prev, &s, full));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
} while (bch2_btree_iter_advance(&iter));
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
|
|
||||||
bch2_trans_exit(&trans);
|
bch2_trans_exit(&trans);
|
||||||
snapshots_seen_exit(&s);
|
snapshots_seen_exit(&s);
|
||||||
@ -1144,23 +1130,15 @@ fsck_err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
|
static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
|
||||||
|
struct bkey_s_c k,
|
||||||
struct inode_walker *inode,
|
struct inode_walker *inode,
|
||||||
struct snapshots_seen *s)
|
struct snapshots_seen *s)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct bkey_s_c k;
|
|
||||||
struct inode_walker_entry *i;
|
struct inode_walker_entry *i;
|
||||||
struct printbuf buf = PRINTBUF;
|
struct printbuf buf = PRINTBUF;
|
||||||
struct bpos equiv;
|
struct bpos equiv;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
peek:
|
|
||||||
k = bch2_btree_iter_peek(iter);
|
|
||||||
if (!k.k)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = bkey_err(k);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
ret = check_key_has_snapshot(trans, iter, k);
|
ret = check_key_has_snapshot(trans, iter, k);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -1190,7 +1168,7 @@ peek:
|
|||||||
* it shouldn't be but we need to fix the new i_sectors check
|
* it shouldn't be but we need to fix the new i_sectors check
|
||||||
* code and delete the old bch2_count_inode_sectors() first
|
* code and delete the old bch2_count_inode_sectors() first
|
||||||
*/
|
*/
|
||||||
goto peek;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
if (bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) {
|
if (bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) {
|
||||||
@ -1284,6 +1262,7 @@ static int check_extents(struct bch_fs *c)
|
|||||||
struct snapshots_seen s;
|
struct snapshots_seen s;
|
||||||
struct btree_trans trans;
|
struct btree_trans trans;
|
||||||
struct btree_iter iter;
|
struct btree_iter iter;
|
||||||
|
struct bkey_s_c k;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -1296,21 +1275,12 @@ static int check_extents(struct bch_fs *c)
|
|||||||
|
|
||||||
bch_verbose(c, "checking extents");
|
bch_verbose(c, "checking extents");
|
||||||
|
|
||||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
|
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_extents,
|
||||||
POS(BCACHEFS_ROOT_INO, 0),
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
BTREE_ITER_INTENT|
|
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
|
||||||
BTREE_ITER_PREFETCH|
|
NULL, NULL,
|
||||||
BTREE_ITER_ALL_SNAPSHOTS);
|
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||||
|
check_extent(&trans, &iter, k, &w, &s));
|
||||||
do {
|
|
||||||
ret = commit_do(&trans, NULL, NULL,
|
|
||||||
BTREE_INSERT_LAZY_RW|
|
|
||||||
BTREE_INSERT_NOFAIL,
|
|
||||||
check_extent(&trans, &iter, &w, &s));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
} while (bch2_btree_iter_advance(&iter));
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
#if 0
|
#if 0
|
||||||
bch2_bkey_buf_exit(&prev, c);
|
bch2_bkey_buf_exit(&prev, c);
|
||||||
#endif
|
#endif
|
||||||
@ -1482,26 +1452,18 @@ fsck_err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
|
static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
|
||||||
|
struct bkey_s_c k,
|
||||||
struct bch_hash_info *hash_info,
|
struct bch_hash_info *hash_info,
|
||||||
struct inode_walker *dir,
|
struct inode_walker *dir,
|
||||||
struct inode_walker *target,
|
struct inode_walker *target,
|
||||||
struct snapshots_seen *s)
|
struct snapshots_seen *s)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct bkey_s_c k;
|
|
||||||
struct bkey_s_c_dirent d;
|
struct bkey_s_c_dirent d;
|
||||||
struct inode_walker_entry *i;
|
struct inode_walker_entry *i;
|
||||||
struct printbuf buf = PRINTBUF;
|
struct printbuf buf = PRINTBUF;
|
||||||
struct bpos equiv;
|
struct bpos equiv;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
peek:
|
|
||||||
k = bch2_btree_iter_peek(iter);
|
|
||||||
if (!k.k)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = bkey_err(k);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
ret = check_key_has_snapshot(trans, iter, k);
|
ret = check_key_has_snapshot(trans, iter, k);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -1527,7 +1489,7 @@ peek:
|
|||||||
|
|
||||||
if (!iter->path->should_be_locked) {
|
if (!iter->path->should_be_locked) {
|
||||||
/* hack: see check_extent() */
|
/* hack: see check_extent() */
|
||||||
goto peek;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = __walk_inode(trans, dir, equiv);
|
ret = __walk_inode(trans, dir, equiv);
|
||||||
@ -1675,6 +1637,7 @@ static int check_dirents(struct bch_fs *c)
|
|||||||
struct bch_hash_info hash_info;
|
struct bch_hash_info hash_info;
|
||||||
struct btree_trans trans;
|
struct btree_trans trans;
|
||||||
struct btree_iter iter;
|
struct btree_iter iter;
|
||||||
|
struct bkey_s_c k;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
bch_verbose(c, "checking dirents");
|
bch_verbose(c, "checking dirents");
|
||||||
@ -1682,22 +1645,13 @@ static int check_dirents(struct bch_fs *c)
|
|||||||
snapshots_seen_init(&s);
|
snapshots_seen_init(&s);
|
||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_dirents,
|
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_dirents,
|
||||||
POS(BCACHEFS_ROOT_INO, 0),
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
BTREE_ITER_INTENT|
|
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
|
||||||
BTREE_ITER_PREFETCH|
|
k,
|
||||||
BTREE_ITER_ALL_SNAPSHOTS);
|
NULL, NULL,
|
||||||
|
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||||
do {
|
check_dirent(&trans, &iter, k, &hash_info, &dir, &target, &s));
|
||||||
ret = commit_do(&trans, NULL, NULL,
|
|
||||||
BTREE_INSERT_LAZY_RW|
|
|
||||||
BTREE_INSERT_NOFAIL,
|
|
||||||
check_dirent(&trans, &iter, &hash_info,
|
|
||||||
&dir, &target, &s));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
} while (bch2_btree_iter_advance(&iter));
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
|
|
||||||
bch2_trans_exit(&trans);
|
bch2_trans_exit(&trans);
|
||||||
snapshots_seen_exit(&s);
|
snapshots_seen_exit(&s);
|
||||||
@ -1710,21 +1664,13 @@ static int check_dirents(struct bch_fs *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
|
static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
|
||||||
|
struct bkey_s_c k,
|
||||||
struct bch_hash_info *hash_info,
|
struct bch_hash_info *hash_info,
|
||||||
struct inode_walker *inode)
|
struct inode_walker *inode)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct bkey_s_c k;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
k = bch2_btree_iter_peek(iter);
|
|
||||||
if (!k.k)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = bkey_err(k);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = check_key_has_snapshot(trans, iter, k);
|
ret = check_key_has_snapshot(trans, iter, k);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1763,28 +1709,20 @@ static int check_xattrs(struct bch_fs *c)
|
|||||||
struct bch_hash_info hash_info;
|
struct bch_hash_info hash_info;
|
||||||
struct btree_trans trans;
|
struct btree_trans trans;
|
||||||
struct btree_iter iter;
|
struct btree_iter iter;
|
||||||
|
struct bkey_s_c k;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
bch_verbose(c, "checking xattrs");
|
bch_verbose(c, "checking xattrs");
|
||||||
|
|
||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
|
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
|
||||||
POS(BCACHEFS_ROOT_INO, 0),
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
BTREE_ITER_INTENT|
|
BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
|
||||||
BTREE_ITER_PREFETCH|
|
k,
|
||||||
BTREE_ITER_ALL_SNAPSHOTS);
|
NULL, NULL,
|
||||||
|
BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||||
do {
|
check_xattr(&trans, &iter, k, &hash_info, &inode));
|
||||||
ret = commit_do(&trans, NULL, NULL,
|
|
||||||
BTREE_INSERT_LAZY_RW|
|
|
||||||
BTREE_INSERT_NOFAIL,
|
|
||||||
check_xattr(&trans, &iter, &hash_info,
|
|
||||||
&inode));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
} while (bch2_btree_iter_advance(&iter));
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
|
|
||||||
bch2_trans_exit(&trans);
|
bch2_trans_exit(&trans);
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ static int snapshot_live(struct btree_trans *trans, u32 id)
|
|||||||
if (!id)
|
if (!id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = lockrestart_do(trans, snapshot_lookup(trans, id, &v));
|
ret = snapshot_lookup(trans, id, &v);
|
||||||
if (ret == -ENOENT)
|
if (ret == -ENOENT)
|
||||||
bch_err(trans->c, "snapshot node %u not found", id);
|
bch_err(trans->c, "snapshot node %u not found", id);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -140,15 +140,20 @@ static int snapshot_live(struct btree_trans *trans, u32 id)
|
|||||||
return !BCH_SNAPSHOT_DELETED(&v);
|
return !BCH_SNAPSHOT_DELETED(&v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_snapshot_set_equiv(struct btree_trans *trans,
|
static int bch2_snapshot_set_equiv(struct btree_trans *trans, struct bkey_s_c k)
|
||||||
struct bkey_s_c_snapshot snap)
|
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
unsigned i, nr_live = 0, live_idx = 0;
|
unsigned i, nr_live = 0, live_idx = 0;
|
||||||
u32 id = snap.k->p.offset, child[2] = {
|
struct bkey_s_c_snapshot snap;
|
||||||
[0] = le32_to_cpu(snap.v->children[0]),
|
u32 id = k.k->p.offset, child[2];
|
||||||
[1] = le32_to_cpu(snap.v->children[1])
|
|
||||||
};
|
if (k.k->type != KEY_TYPE_snapshot)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snap = bkey_s_c_to_snapshot(k);
|
||||||
|
|
||||||
|
child[0] = le32_to_cpu(snap.v->children[0]);
|
||||||
|
child[1] = le32_to_cpu(snap.v->children[1]);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
int ret = snapshot_live(trans, child[i]);
|
int ret = snapshot_live(trans, child[i]);
|
||||||
@ -166,58 +171,27 @@ static int bch2_snapshot_set_equiv(struct btree_trans *trans,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_snapshots_set_equiv(struct btree_trans *trans)
|
|
||||||
{
|
|
||||||
struct btree_iter iter;
|
|
||||||
struct bkey_s_c k;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
for_each_btree_key(trans, iter, BTREE_ID_snapshots,
|
|
||||||
POS_MIN, 0, k, ret) {
|
|
||||||
if (k.k->type != KEY_TYPE_snapshot)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = bch2_snapshot_set_equiv(trans, bkey_s_c_to_snapshot(k));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bch2_trans_iter_exit(trans, &iter);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
bch_err(trans->c, "error in bch2_snapshots_set_equiv: %i", ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fsck: */
|
/* fsck: */
|
||||||
static int check_snapshot(struct btree_trans *trans,
|
static int check_snapshot(struct btree_trans *trans,
|
||||||
struct btree_iter *iter)
|
struct btree_iter *iter,
|
||||||
|
struct bkey_s_c k)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct bkey_s_c_snapshot s;
|
struct bkey_s_c_snapshot s;
|
||||||
struct bch_subvolume subvol;
|
struct bch_subvolume subvol;
|
||||||
struct bch_snapshot v;
|
struct bch_snapshot v;
|
||||||
struct bkey_s_c k;
|
|
||||||
struct printbuf buf = PRINTBUF;
|
struct printbuf buf = PRINTBUF;
|
||||||
bool should_have_subvol;
|
bool should_have_subvol;
|
||||||
u32 i, id;
|
u32 i, id;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
k = bch2_btree_iter_peek(iter);
|
|
||||||
if (!k.k)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = bkey_err(k);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (k.k->type != KEY_TYPE_snapshot)
|
if (k.k->type != KEY_TYPE_snapshot)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = bkey_s_c_to_snapshot(k);
|
s = bkey_s_c_to_snapshot(k);
|
||||||
id = le32_to_cpu(s.v->parent);
|
id = le32_to_cpu(s.v->parent);
|
||||||
if (id) {
|
if (id) {
|
||||||
ret = lockrestart_do(trans, snapshot_lookup(trans, id, &v));
|
ret = snapshot_lookup(trans, id, &v);
|
||||||
if (ret == -ENOENT)
|
if (ret == -ENOENT)
|
||||||
bch_err(c, "snapshot with nonexistent parent:\n %s",
|
bch_err(c, "snapshot with nonexistent parent:\n %s",
|
||||||
(bch2_bkey_val_to_text(&buf, c, s.s_c), buf.buf));
|
(bch2_bkey_val_to_text(&buf, c, s.s_c), buf.buf));
|
||||||
@ -236,7 +210,7 @@ static int check_snapshot(struct btree_trans *trans,
|
|||||||
for (i = 0; i < 2 && s.v->children[i]; i++) {
|
for (i = 0; i < 2 && s.v->children[i]; i++) {
|
||||||
id = le32_to_cpu(s.v->children[i]);
|
id = le32_to_cpu(s.v->children[i]);
|
||||||
|
|
||||||
ret = lockrestart_do(trans, snapshot_lookup(trans, id, &v));
|
ret = snapshot_lookup(trans, id, &v);
|
||||||
if (ret == -ENOENT)
|
if (ret == -ENOENT)
|
||||||
bch_err(c, "snapshot node %llu has nonexistent child %u",
|
bch_err(c, "snapshot node %llu has nonexistent child %u",
|
||||||
s.k->p.offset, id);
|
s.k->p.offset, id);
|
||||||
@ -256,7 +230,7 @@ static int check_snapshot(struct btree_trans *trans,
|
|||||||
|
|
||||||
if (should_have_subvol) {
|
if (should_have_subvol) {
|
||||||
id = le32_to_cpu(s.v->subvol);
|
id = le32_to_cpu(s.v->subvol);
|
||||||
ret = lockrestart_do(trans, bch2_subvolume_get(trans, id, 0, false, &subvol));
|
ret = bch2_subvolume_get(trans, id, 0, false, &subvol);
|
||||||
if (ret == -ENOENT)
|
if (ret == -ENOENT)
|
||||||
bch_err(c, "snapshot points to nonexistent subvolume:\n %s",
|
bch_err(c, "snapshot points to nonexistent subvolume:\n %s",
|
||||||
(bch2_bkey_val_to_text(&buf, c, s.s_c), buf.buf));
|
(bch2_bkey_val_to_text(&buf, c, s.s_c), buf.buf));
|
||||||
@ -298,22 +272,16 @@ int bch2_fs_check_snapshots(struct bch_fs *c)
|
|||||||
{
|
{
|
||||||
struct btree_trans trans;
|
struct btree_trans trans;
|
||||||
struct btree_iter iter;
|
struct btree_iter iter;
|
||||||
|
struct bkey_s_c k;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bch2_trans_init(&trans, c, 0, 0);
|
bch2_trans_init(&trans, c, 0, 0);
|
||||||
|
|
||||||
bch2_trans_iter_init(&trans, &iter, BTREE_ID_snapshots,
|
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_snapshots,
|
||||||
POS_MIN, BTREE_ITER_PREFETCH);
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
|
BTREE_ITER_PREFETCH, k,
|
||||||
do {
|
NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
|
||||||
ret = commit_do(&trans, NULL, NULL,
|
check_snapshot(&trans, &iter, k));
|
||||||
BTREE_INSERT_LAZY_RW|
|
|
||||||
BTREE_INSERT_NOFAIL,
|
|
||||||
check_snapshot(&trans, &iter));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
} while (bch2_btree_iter_advance(&iter));
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
bch_err(c, "error %i checking snapshots", ret);
|
bch_err(c, "error %i checking snapshots", ret);
|
||||||
@ -404,20 +372,10 @@ int bch2_fs_snapshots_start(struct bch_fs *c)
|
|||||||
|
|
||||||
bch2_trans_init(&trans, c, 0, 0);
|
bch2_trans_init(&trans, c, 0, 0);
|
||||||
|
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
|
for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
|
||||||
POS_MIN, 0, k, ret) {
|
POS_MIN, 0, k,
|
||||||
if (bkey_cmp(k.k->p, POS(0, U32_MAX)) > 0)
|
bch2_mark_snapshot(&trans, bkey_s_c_null, k, 0) ?:
|
||||||
break;
|
bch2_snapshot_set_equiv(&trans, k));
|
||||||
|
|
||||||
if (k.k->type != KEY_TYPE_snapshot)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = bch2_mark_snapshot(&trans, bkey_s_c_null, k, 0) ?:
|
|
||||||
bch2_snapshot_set_equiv(&trans, bkey_s_c_to_snapshot(k));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
|
|
||||||
bch2_trans_exit(&trans);
|
bch2_trans_exit(&trans);
|
||||||
|
|
||||||
@ -692,6 +650,34 @@ static int bch2_snapshot_delete_keys_btree(struct btree_trans *trans,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bch2_delete_redundant_snapshot(struct btree_trans *trans, struct btree_iter *iter,
|
||||||
|
struct bkey_s_c k)
|
||||||
|
{
|
||||||
|
struct bkey_s_c_snapshot snap;
|
||||||
|
u32 children[2];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (k.k->type != KEY_TYPE_snapshot)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snap = bkey_s_c_to_snapshot(k);
|
||||||
|
if (BCH_SNAPSHOT_DELETED(snap.v) ||
|
||||||
|
BCH_SNAPSHOT_SUBVOL(snap.v))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
children[0] = le32_to_cpu(snap.v->children[0]);
|
||||||
|
children[1] = le32_to_cpu(snap.v->children[1]);
|
||||||
|
|
||||||
|
ret = snapshot_live(trans, children[0]) ?:
|
||||||
|
snapshot_live(trans, children[1]);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return bch2_snapshot_node_set_deleted(trans, k.k->p.offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int bch2_delete_dead_snapshots(struct bch_fs *c)
|
int bch2_delete_dead_snapshots(struct bch_fs *c)
|
||||||
{
|
{
|
||||||
struct btree_trans trans;
|
struct btree_trans trans;
|
||||||
@ -699,7 +685,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
|||||||
struct bkey_s_c k;
|
struct bkey_s_c k;
|
||||||
struct bkey_s_c_snapshot snap;
|
struct bkey_s_c_snapshot snap;
|
||||||
snapshot_id_list deleted = { 0 };
|
snapshot_id_list deleted = { 0 };
|
||||||
u32 i, id, children[2];
|
u32 i, id;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!test_bit(BCH_FS_HAVE_DELETED_SNAPSHOTS, &c->flags))
|
if (!test_bit(BCH_FS_HAVE_DELETED_SNAPSHOTS, &c->flags))
|
||||||
@ -719,43 +705,22 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
|
|||||||
* For every snapshot node: If we have no live children and it's not
|
* For every snapshot node: If we have no live children and it's not
|
||||||
* pointed to by a subvolume, delete it:
|
* pointed to by a subvolume, delete it:
|
||||||
*/
|
*/
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
|
ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_snapshots,
|
||||||
POS_MIN, 0, k, ret) {
|
POS_MIN, 0, k,
|
||||||
if (k.k->type != KEY_TYPE_snapshot)
|
NULL, NULL, 0,
|
||||||
continue;
|
bch2_delete_redundant_snapshot(&trans, &iter, k));
|
||||||
|
|
||||||
snap = bkey_s_c_to_snapshot(k);
|
|
||||||
if (BCH_SNAPSHOT_DELETED(snap.v) ||
|
|
||||||
BCH_SNAPSHOT_SUBVOL(snap.v))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
children[0] = le32_to_cpu(snap.v->children[0]);
|
|
||||||
children[1] = le32_to_cpu(snap.v->children[1]);
|
|
||||||
|
|
||||||
ret = snapshot_live(&trans, children[0]) ?:
|
|
||||||
snapshot_live(&trans, children[1]);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
if (ret)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = commit_do(&trans, NULL, NULL, 0,
|
|
||||||
bch2_snapshot_node_set_deleted(&trans, iter.pos.offset));
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
bch_err(c, "error deleting snapshot %llu: %i", iter.pos.offset, ret);
|
bch_err(c, "error deleting redundant snapshots: %i", ret);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
bch_err(c, "error walking snapshots: %i", ret);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bch2_snapshots_set_equiv(&trans);
|
for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
|
||||||
if (ret)
|
POS_MIN, 0, k,
|
||||||
|
bch2_snapshot_set_equiv(&trans, k));
|
||||||
|
if (ret) {
|
||||||
|
bch_err(c, "error in bch2_snapshots_set_equiv: %i", ret);
|
||||||
goto err;
|
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) {
|
POS_MIN, 0, k, ret) {
|
||||||
|
Loading…
Reference in New Issue
Block a user