1 // SPDX-License-Identifier: GPL-2.0
4 #include "btree_key_cache.h"
5 #include "btree_update.h"
12 static void bch2_delete_dead_snapshots_work(struct work_struct *);
13 static void bch2_delete_dead_snapshots(struct bch_fs *);
15 void bch2_snapshot_to_text(struct printbuf *out, struct bch_fs *c,
18 struct bkey_s_c_snapshot s = bkey_s_c_to_snapshot(k);
20 pr_buf(out, "is_subvol %llu deleted %llu parent %u children %u %u subvol %u",
21 BCH_SNAPSHOT_SUBVOL(s.v),
22 BCH_SNAPSHOT_DELETED(s.v),
23 le32_to_cpu(s.v->parent),
24 le32_to_cpu(s.v->children[0]),
25 le32_to_cpu(s.v->children[1]),
26 le32_to_cpu(s.v->subvol));
29 const char *bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k)
31 struct bkey_s_c_snapshot s;
34 if (bkey_cmp(k.k->p, POS(0, U32_MAX)) > 0 ||
35 bkey_cmp(k.k->p, POS(0, 1)) < 0)
38 if (bkey_val_bytes(k.k) != sizeof(struct bch_snapshot))
39 return "bad val size";
41 s = bkey_s_c_to_snapshot(k);
43 id = le32_to_cpu(s.v->parent);
44 if (id && id <= k.k->p.offset)
45 return "bad parent node";
47 if (le32_to_cpu(s.v->children[0]) < le32_to_cpu(s.v->children[1]))
48 return "children not normalized";
50 if (s.v->children[0] &&
51 s.v->children[0] == s.v->children[1])
52 return "duplicate child nodes";
54 for (i = 0; i < 2; i++) {
55 id = le32_to_cpu(s.v->children[i]);
57 if (id >= k.k->p.offset)
58 return "bad child node";
64 int bch2_mark_snapshot(struct btree_trans *trans,
65 struct bkey_s_c old, struct bkey_s_c new,
68 struct bch_fs *c = trans->c;
71 t = genradix_ptr_alloc(&c->snapshots,
72 U32_MAX - new.k->p.offset,
77 if (new.k->type == KEY_TYPE_snapshot) {
78 struct bkey_s_c_snapshot s = bkey_s_c_to_snapshot(new);
80 t->parent = le32_to_cpu(s.v->parent);
81 t->children[0] = le32_to_cpu(s.v->children[0]);
82 t->children[1] = le32_to_cpu(s.v->children[1]);
83 t->subvol = BCH_SNAPSHOT_SUBVOL(s.v) ? le32_to_cpu(s.v->subvol) : 0;
94 static int snapshot_lookup(struct btree_trans *trans, u32 id,
95 struct bch_snapshot *s)
97 struct btree_iter iter;
101 bch2_trans_iter_init(trans, &iter, BTREE_ID_snapshots, POS(0, id),
102 BTREE_ITER_WITH_UPDATES);
103 k = bch2_btree_iter_peek_slot(&iter);
104 ret = bkey_err(k) ?: k.k->type == KEY_TYPE_snapshot ? 0 : -ENOENT;
107 *s = *bkey_s_c_to_snapshot(k).v;
109 bch2_trans_iter_exit(trans, &iter);
113 static int snapshot_live(struct btree_trans *trans, u32 id)
115 struct bch_snapshot v;
121 ret = lockrestart_do(trans, snapshot_lookup(trans, id, &v));
123 bch_err(trans->c, "snapshot node %u not found", id);
127 return !BCH_SNAPSHOT_DELETED(&v);
130 static int bch2_snapshots_set_equiv(struct btree_trans *trans)
132 struct bch_fs *c = trans->c;
133 struct btree_iter iter;
135 struct bkey_s_c_snapshot snap;
139 for_each_btree_key(trans, iter, BTREE_ID_snapshots,
140 POS_MIN, 0, k, ret) {
141 u32 id = k.k->p.offset, child[2];
142 unsigned nr_live = 0, live_idx = 0;
144 if (k.k->type != KEY_TYPE_snapshot)
147 snap = bkey_s_c_to_snapshot(k);
148 child[0] = le32_to_cpu(snap.v->children[0]);
149 child[1] = le32_to_cpu(snap.v->children[1]);
151 for (i = 0; i < 2; i++) {
152 ret = snapshot_live(trans, child[i]);
161 snapshot_t(c, id)->equiv = nr_live == 1
162 ? snapshot_t(c, child[live_idx])->equiv
166 bch2_trans_iter_exit(trans, &iter);
169 bch_err(c, "error walking snapshots: %i", ret);
175 static int bch2_snapshot_check(struct btree_trans *trans,
176 struct bkey_s_c_snapshot s)
178 struct bch_subvolume subvol;
179 struct bch_snapshot v;
183 id = le32_to_cpu(s.v->subvol);
184 ret = lockrestart_do(trans, bch2_subvolume_get(trans, id, 0, false, &subvol));
186 bch_err(trans->c, "snapshot node %llu has nonexistent subvolume %u",
191 if (BCH_SNAPSHOT_SUBVOL(s.v) != (le32_to_cpu(subvol.snapshot) == s.k->p.offset)) {
192 bch_err(trans->c, "snapshot node %llu has wrong BCH_SNAPSHOT_SUBVOL",
197 id = le32_to_cpu(s.v->parent);
199 ret = lockrestart_do(trans, snapshot_lookup(trans, id, &v));
201 bch_err(trans->c, "snapshot node %llu has nonexistent parent %u",
206 if (le32_to_cpu(v.children[0]) != s.k->p.offset &&
207 le32_to_cpu(v.children[1]) != s.k->p.offset) {
208 bch_err(trans->c, "snapshot parent %u missing pointer to child %llu",
214 for (i = 0; i < 2 && s.v->children[i]; i++) {
215 id = le32_to_cpu(s.v->children[i]);
217 ret = lockrestart_do(trans, snapshot_lookup(trans, id, &v));
219 bch_err(trans->c, "snapshot node %llu has nonexistent child %u",
224 if (le32_to_cpu(v.parent) != s.k->p.offset) {
225 bch_err(trans->c, "snapshot child %u has wrong parent (got %u should be %llu)",
226 id, le32_to_cpu(v.parent), s.k->p.offset);
234 int bch2_fs_snapshots_check(struct bch_fs *c)
236 struct btree_trans trans;
237 struct btree_iter iter;
239 struct bch_snapshot s;
243 bch2_trans_init(&trans, c, 0, 0);
245 for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
246 POS_MIN, 0, k, ret) {
247 if (k.k->type != KEY_TYPE_snapshot)
250 ret = bch2_snapshot_check(&trans, bkey_s_c_to_snapshot(k));
254 bch2_trans_iter_exit(&trans, &iter);
257 bch_err(c, "error %i checking snapshots", ret);
261 for_each_btree_key(&trans, iter, BTREE_ID_subvolumes,
262 POS_MIN, 0, k, ret) {
263 if (k.k->type != KEY_TYPE_subvolume)
266 id = le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot);
267 ret = snapshot_lookup(&trans, id, &s);
270 k = bch2_btree_iter_peek(&iter);
272 } else if (ret == -ENOENT)
273 bch_err(c, "subvolume %llu points to nonexistent snapshot %u",
278 bch2_trans_iter_exit(&trans, &iter);
280 bch2_trans_exit(&trans);
284 void bch2_fs_snapshots_exit(struct bch_fs *c)
286 genradix_free(&c->snapshots);
289 int bch2_fs_snapshots_start(struct bch_fs *c)
291 struct btree_trans trans;
292 struct btree_iter iter;
294 bool have_deleted = false;
297 bch2_trans_init(&trans, c, 0, 0);
299 for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
300 POS_MIN, 0, k, ret) {
301 if (bkey_cmp(k.k->p, POS(0, U32_MAX)) > 0)
304 if (k.k->type != KEY_TYPE_snapshot) {
305 bch_err(c, "found wrong key type %u in snapshot node table",
310 if (BCH_SNAPSHOT_DELETED(bkey_s_c_to_snapshot(k).v))
313 ret = bch2_mark_snapshot(&trans, bkey_s_c_null, k, 0);
317 bch2_trans_iter_exit(&trans, &iter);
322 ret = bch2_snapshots_set_equiv(&trans);
326 bch2_trans_exit(&trans);
328 if (!ret && have_deleted) {
329 bch_info(c, "restarting deletion of dead snapshots");
331 bch2_delete_dead_snapshots_work(&c->snapshot_delete_work);
333 bch2_delete_dead_snapshots(c);
341 * Mark a snapshot as deleted, for future cleanup:
343 static int bch2_snapshot_node_set_deleted(struct btree_trans *trans, u32 id)
345 struct btree_iter iter;
347 struct bkey_i_snapshot *s;
350 bch2_trans_iter_init(trans, &iter, BTREE_ID_snapshots, POS(0, id),
352 k = bch2_btree_iter_peek_slot(&iter);
357 if (k.k->type != KEY_TYPE_snapshot) {
358 bch2_fs_inconsistent(trans->c, "missing snapshot %u", id);
363 /* already deleted? */
364 if (BCH_SNAPSHOT_DELETED(bkey_s_c_to_snapshot(k).v))
367 s = bch2_trans_kmalloc(trans, sizeof(*s));
368 ret = PTR_ERR_OR_ZERO(s);
372 bkey_reassemble(&s->k_i, k);
374 SET_BCH_SNAPSHOT_DELETED(&s->v, true);
375 ret = bch2_trans_update(trans, &iter, &s->k_i, 0);
379 bch2_trans_iter_exit(trans, &iter);
383 static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
385 struct btree_iter iter, p_iter = (struct btree_iter) { NULL };
387 struct bkey_s_c_snapshot s;
388 struct bkey_i_snapshot *parent;
393 bch2_trans_iter_init(trans, &iter, BTREE_ID_snapshots, POS(0, id),
395 k = bch2_btree_iter_peek_slot(&iter);
400 if (k.k->type != KEY_TYPE_snapshot) {
401 bch2_fs_inconsistent(trans->c, "missing snapshot %u", id);
406 s = bkey_s_c_to_snapshot(k);
408 BUG_ON(!BCH_SNAPSHOT_DELETED(s.v));
409 parent_id = le32_to_cpu(s.v->parent);
412 bch2_trans_iter_init(trans, &p_iter, BTREE_ID_snapshots,
415 k = bch2_btree_iter_peek_slot(&p_iter);
420 if (k.k->type != KEY_TYPE_snapshot) {
421 bch2_fs_inconsistent(trans->c, "missing snapshot %u", parent_id);
426 parent = bch2_trans_kmalloc(trans, sizeof(*parent));
427 ret = PTR_ERR_OR_ZERO(parent);
431 bkey_reassemble(&parent->k_i, k);
433 for (i = 0; i < 2; i++)
434 if (le32_to_cpu(parent->v.children[i]) == id)
438 bch_err(trans->c, "snapshot %u missing child pointer to %u",
441 parent->v.children[i] = 0;
443 if (le32_to_cpu(parent->v.children[0]) <
444 le32_to_cpu(parent->v.children[1]))
445 swap(parent->v.children[0],
446 parent->v.children[1]);
448 ret = bch2_trans_update(trans, &p_iter, &parent->k_i, 0);
453 ret = bch2_btree_delete_at(trans, &iter, 0);
455 bch2_trans_iter_exit(trans, &p_iter);
456 bch2_trans_iter_exit(trans, &iter);
460 int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
462 u32 *snapshot_subvols,
465 struct btree_iter iter;
466 struct bkey_i_snapshot *n;
471 bch2_trans_iter_init(trans, &iter, BTREE_ID_snapshots,
472 POS_MIN, BTREE_ITER_INTENT);
473 k = bch2_btree_iter_peek(&iter);
478 for (i = 0; i < nr_snapids; i++) {
479 k = bch2_btree_iter_prev_slot(&iter);
484 if (!k.k || !k.k->p.offset) {
489 n = bch2_trans_kmalloc(trans, sizeof(*n));
490 ret = PTR_ERR_OR_ZERO(n);
494 bkey_snapshot_init(&n->k_i);
497 n->v.parent = cpu_to_le32(parent);
498 n->v.subvol = cpu_to_le32(snapshot_subvols[i]);
500 SET_BCH_SNAPSHOT_SUBVOL(&n->v, true);
502 ret = bch2_trans_update(trans, &iter, &n->k_i, 0) ?:
503 bch2_mark_snapshot(trans, bkey_s_c_null, bkey_i_to_s_c(&n->k_i), 0);
507 new_snapids[i] = iter.pos.offset;
511 bch2_btree_iter_set_pos(&iter, POS(0, parent));
512 k = bch2_btree_iter_peek(&iter);
517 if (k.k->type != KEY_TYPE_snapshot) {
518 bch_err(trans->c, "snapshot %u not found", parent);
523 n = bch2_trans_kmalloc(trans, sizeof(*n));
524 ret = PTR_ERR_OR_ZERO(n);
528 bkey_reassemble(&n->k_i, k);
530 if (n->v.children[0] || n->v.children[1]) {
531 bch_err(trans->c, "Trying to add child snapshot nodes to parent that already has children");
536 n->v.children[0] = cpu_to_le32(new_snapids[0]);
537 n->v.children[1] = cpu_to_le32(new_snapids[1]);
538 SET_BCH_SNAPSHOT_SUBVOL(&n->v, false);
539 ret = bch2_trans_update(trans, &iter, &n->k_i, 0);
544 bch2_trans_iter_exit(trans, &iter);
548 static int snapshot_id_add(struct snapshot_id_list *s, u32 id)
550 BUG_ON(snapshot_list_has_id(s, id));
552 if (s->nr == s->size) {
553 size_t new_size = max(8U, s->size * 2);
554 void *n = krealloc(s->d,
555 new_size * sizeof(s->d[0]),
558 pr_err("error allocating snapshot ID list");
570 static int bch2_snapshot_delete_keys_btree(struct btree_trans *trans,
571 struct snapshot_id_list *deleted,
572 enum btree_id btree_id)
574 struct bch_fs *c = trans->c;
575 struct btree_iter iter;
577 struct snapshot_id_list equiv_seen = { 0 };
578 struct bpos last_pos = POS_MIN;
582 * XXX: We should also delete whiteouts that no longer overwrite
586 bch2_trans_iter_init(trans, &iter, btree_id, POS_MIN,
589 BTREE_ITER_NOT_EXTENTS|
590 BTREE_ITER_ALL_SNAPSHOTS);
592 while ((bch2_trans_begin(trans),
593 (k = bch2_btree_iter_peek(&iter)).k) &&
594 !(ret = bkey_err(k))) {
595 u32 equiv = snapshot_t(c, k.k->p.snapshot)->equiv;
597 if (bkey_cmp(k.k->p, last_pos))
601 if (snapshot_list_has_id(deleted, k.k->p.snapshot) ||
602 snapshot_list_has_id(&equiv_seen, equiv)) {
603 if (btree_id == BTREE_ID_inodes &&
604 bch2_btree_key_cache_flush(trans, btree_id, iter.pos))
607 ret = __bch2_trans_do(trans, NULL, NULL,
609 bch2_btree_iter_traverse(&iter) ?:
610 bch2_btree_delete_at(trans, &iter,
611 BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE));
615 ret = snapshot_id_add(&equiv_seen, equiv);
620 bch2_btree_iter_advance(&iter);
622 bch2_trans_iter_exit(trans, &iter);
629 static void bch2_delete_dead_snapshots_work(struct work_struct *work)
631 struct bch_fs *c = container_of(work, struct bch_fs, snapshot_delete_work);
632 struct btree_trans trans;
633 struct btree_iter iter;
635 struct bkey_s_c_snapshot snap;
636 struct snapshot_id_list deleted = { 0 };
637 u32 i, id, children[2];
640 bch2_trans_init(&trans, c, 0, 0);
643 * For every snapshot node: If we have no live children and it's not
644 * pointed to by a subvolume, delete it:
646 for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
647 POS_MIN, 0, k, ret) {
648 if (k.k->type != KEY_TYPE_snapshot)
651 snap = bkey_s_c_to_snapshot(k);
652 if (BCH_SNAPSHOT_DELETED(snap.v) ||
653 BCH_SNAPSHOT_SUBVOL(snap.v))
656 children[0] = le32_to_cpu(snap.v->children[0]);
657 children[1] = le32_to_cpu(snap.v->children[1]);
659 ret = snapshot_live(&trans, children[0]) ?:
660 snapshot_live(&trans, children[1]);
666 ret = __bch2_trans_do(&trans, NULL, NULL, 0,
667 bch2_snapshot_node_set_deleted(&trans, iter.pos.offset));
669 bch_err(c, "error deleting snapshot %llu: %i", iter.pos.offset, ret);
673 bch2_trans_iter_exit(&trans, &iter);
676 bch_err(c, "error walking snapshots: %i", ret);
680 ret = bch2_snapshots_set_equiv(&trans);
684 for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
685 POS_MIN, 0, k, ret) {
686 if (k.k->type != KEY_TYPE_snapshot)
689 snap = bkey_s_c_to_snapshot(k);
690 if (BCH_SNAPSHOT_DELETED(snap.v)) {
691 ret = snapshot_id_add(&deleted, k.k->p.offset);
696 bch2_trans_iter_exit(&trans, &iter);
699 bch_err(c, "error walking snapshots: %i", ret);
703 for (id = 0; id < BTREE_ID_NR; id++) {
704 if (!btree_type_has_snapshots(id))
707 ret = bch2_snapshot_delete_keys_btree(&trans, &deleted, id);
709 bch_err(c, "error deleting snapshot keys: %i", ret);
714 for (i = 0; i < deleted.nr; i++) {
715 ret = __bch2_trans_do(&trans, NULL, NULL, 0,
716 bch2_snapshot_node_delete(&trans, deleted.d[i]));
718 bch_err(c, "error deleting snapshot %u: %i",
725 bch2_trans_exit(&trans);
726 percpu_ref_put(&c->writes);
729 static void bch2_delete_dead_snapshots(struct bch_fs *c)
731 if (unlikely(!percpu_ref_tryget(&c->writes)))
734 if (!queue_work(system_long_wq, &c->snapshot_delete_work))
735 percpu_ref_put(&c->writes);
738 static int bch2_delete_dead_snapshots_hook(struct btree_trans *trans,
739 struct btree_trans_commit_hook *h)
741 bch2_delete_dead_snapshots(trans->c);
747 const char *bch2_subvolume_invalid(const struct bch_fs *c, struct bkey_s_c k)
749 if (bkey_cmp(k.k->p, SUBVOL_POS_MIN) < 0)
750 return "invalid pos";
752 if (bkey_cmp(k.k->p, SUBVOL_POS_MAX) > 0)
753 return "invalid pos";
755 if (bkey_val_bytes(k.k) != sizeof(struct bch_subvolume))
756 return "bad val size";
761 void bch2_subvolume_to_text(struct printbuf *out, struct bch_fs *c,
764 struct bkey_s_c_subvolume s = bkey_s_c_to_subvolume(k);
766 pr_buf(out, "root %llu snapshot id %u",
767 le64_to_cpu(s.v->inode),
768 le32_to_cpu(s.v->snapshot));
771 int bch2_subvolume_get(struct btree_trans *trans, unsigned subvol,
772 bool inconsistent_if_not_found,
774 struct bch_subvolume *s)
776 struct btree_iter iter;
780 bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes, POS(0, subvol),
782 k = bch2_btree_iter_peek_slot(&iter);
783 ret = bkey_err(k) ?: k.k->type == KEY_TYPE_subvolume ? 0 : -ENOENT;
785 if (ret == -ENOENT && inconsistent_if_not_found)
786 bch2_fs_inconsistent(trans->c, "missing subvolume %u", subvol);
788 *s = *bkey_s_c_to_subvolume(k).v;
790 bch2_trans_iter_exit(trans, &iter);
794 int bch2_snapshot_get_subvol(struct btree_trans *trans, u32 snapshot,
795 struct bch_subvolume *subvol)
797 struct bch_snapshot snap;
799 return snapshot_lookup(trans, snapshot, &snap) ?:
800 bch2_subvolume_get(trans, le32_to_cpu(snap.subvol), true, 0, subvol);
803 int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvol,
806 struct bch_subvolume s;
809 ret = bch2_subvolume_get(trans, subvol, true,
811 BTREE_ITER_WITH_UPDATES,
814 *snapid = le32_to_cpu(s.snapshot);
819 * Delete subvolume, mark snapshot ID as deleted, queue up snapshot
822 int bch2_subvolume_delete(struct btree_trans *trans, u32 subvolid)
824 struct btree_iter iter;
826 struct bkey_s_c_subvolume subvol;
827 struct btree_trans_commit_hook *h;
828 struct bkey_i *delete;
832 bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
836 k = bch2_btree_iter_peek_slot(&iter);
841 if (k.k->type != KEY_TYPE_subvolume) {
842 bch2_fs_inconsistent(trans->c, "missing subvolume %u", subvolid);
847 subvol = bkey_s_c_to_subvolume(k);
848 snapid = le32_to_cpu(subvol.v->snapshot);
850 delete = bch2_trans_kmalloc(trans, sizeof(*delete));
851 ret = PTR_ERR_OR_ZERO(delete);
855 bkey_init(&delete->k);
856 delete->k.p = iter.pos;
857 ret = bch2_trans_update(trans, &iter, delete, 0);
861 ret = bch2_snapshot_node_set_deleted(trans, snapid);
863 h = bch2_trans_kmalloc(trans, sizeof(*h));
864 ret = PTR_ERR_OR_ZERO(h);
868 h->fn = bch2_delete_dead_snapshots_hook;
869 bch2_trans_commit_hook(trans, h);
871 bch2_trans_iter_exit(trans, &iter);
875 void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *work)
877 struct bch_fs *c = container_of(work, struct bch_fs,
878 snapshot_wait_for_pagecache_and_delete_work);
879 struct snapshot_id_list s;
884 mutex_lock(&c->snapshots_unlinked_lock);
885 s = c->snapshots_unlinked;
886 memset(&c->snapshots_unlinked, 0, sizeof(c->snapshots_unlinked));
887 mutex_unlock(&c->snapshots_unlinked_lock);
892 bch2_evict_subvolume_inodes(c, &s);
894 for (id = s.d; id < s.d + s.nr; id++) {
895 ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
896 bch2_subvolume_delete(&trans, *id));
898 bch_err(c, "error %i deleting subvolume %u", ret, *id);
906 percpu_ref_put(&c->writes);
909 struct subvolume_unlink_hook {
910 struct btree_trans_commit_hook h;
914 int bch2_subvolume_wait_for_pagecache_and_delete_hook(struct btree_trans *trans,
915 struct btree_trans_commit_hook *_h)
917 struct subvolume_unlink_hook *h = container_of(_h, struct subvolume_unlink_hook, h);
918 struct bch_fs *c = trans->c;
921 mutex_lock(&c->snapshots_unlinked_lock);
922 if (!snapshot_list_has_id(&c->snapshots_unlinked, h->subvol))
923 ret = snapshot_id_add(&c->snapshots_unlinked, h->subvol);
924 mutex_unlock(&c->snapshots_unlinked_lock);
929 if (unlikely(!percpu_ref_tryget(&c->writes)))
932 if (!queue_work(system_long_wq, &c->snapshot_wait_for_pagecache_and_delete_work))
933 percpu_ref_put(&c->writes);
937 int bch2_subvolume_unlink(struct btree_trans *trans, u32 subvolid)
939 struct btree_iter iter;
941 struct bkey_i_subvolume *n;
942 struct subvolume_unlink_hook *h;
945 bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
949 k = bch2_btree_iter_peek_slot(&iter);
954 if (k.k->type != KEY_TYPE_subvolume) {
955 bch2_fs_inconsistent(trans->c, "missing subvolume %u", subvolid);
960 n = bch2_trans_kmalloc(trans, sizeof(*n));
961 ret = PTR_ERR_OR_ZERO(n);
965 bkey_reassemble(&n->k_i, k);
966 SET_BCH_SUBVOLUME_UNLINKED(&n->v, true);
968 ret = bch2_trans_update(trans, &iter, &n->k_i, 0);
972 h = bch2_trans_kmalloc(trans, sizeof(*h));
973 ret = PTR_ERR_OR_ZERO(h);
977 h->h.fn = bch2_subvolume_wait_for_pagecache_and_delete_hook;
978 h->subvol = subvolid;
979 bch2_trans_commit_hook(trans, &h->h);
981 bch2_trans_iter_exit(trans, &iter);
985 int bch2_subvolume_create(struct btree_trans *trans, u64 inode,
991 struct bch_fs *c = trans->c;
992 struct btree_iter dst_iter, src_iter = (struct btree_iter) { NULL };
993 struct bkey_i_subvolume *new_subvol = NULL;
994 struct bkey_i_subvolume *src_subvol = NULL;
996 u32 parent = 0, new_nodes[2], snapshot_subvols[2];
999 for_each_btree_key(trans, dst_iter, BTREE_ID_subvolumes, SUBVOL_POS_MIN,
1000 BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k, ret) {
1001 if (bkey_cmp(k.k->p, SUBVOL_POS_MAX) > 0)
1005 * bch2_subvolume_delete() doesn't flush the btree key cache -
1006 * ideally it would but that's tricky
1008 if (bkey_deleted(k.k) &&
1009 !bch2_btree_key_cache_find(c, BTREE_ID_subvolumes, dst_iter.pos))
1017 snapshot_subvols[0] = dst_iter.pos.offset;
1018 snapshot_subvols[1] = src_subvolid;
1021 /* Creating a snapshot: */
1022 src_subvol = bch2_trans_kmalloc(trans, sizeof(*src_subvol));
1023 ret = PTR_ERR_OR_ZERO(src_subvol);
1027 bch2_trans_iter_init(trans, &src_iter, BTREE_ID_subvolumes,
1028 POS(0, src_subvolid),
1031 k = bch2_btree_iter_peek_slot(&src_iter);
1036 if (k.k->type != KEY_TYPE_subvolume) {
1037 bch_err(c, "subvolume %u not found", src_subvolid);
1042 bkey_reassemble(&src_subvol->k_i, k);
1043 parent = le32_to_cpu(src_subvol->v.snapshot);
1046 ret = bch2_snapshot_node_create(trans, parent, new_nodes,
1048 src_subvolid ? 2 : 1);
1053 src_subvol->v.snapshot = cpu_to_le32(new_nodes[1]);
1054 ret = bch2_trans_update(trans, &src_iter, &src_subvol->k_i, 0);
1059 new_subvol = bch2_trans_kmalloc(trans, sizeof(*new_subvol));
1060 ret = PTR_ERR_OR_ZERO(new_subvol);
1064 bkey_subvolume_init(&new_subvol->k_i);
1065 new_subvol->v.flags = 0;
1066 new_subvol->v.snapshot = cpu_to_le32(new_nodes[0]);
1067 new_subvol->v.inode = cpu_to_le64(inode);
1068 SET_BCH_SUBVOLUME_RO(&new_subvol->v, ro);
1069 SET_BCH_SUBVOLUME_SNAP(&new_subvol->v, src_subvolid != 0);
1070 new_subvol->k.p = dst_iter.pos;
1071 ret = bch2_trans_update(trans, &dst_iter, &new_subvol->k_i, 0);
1075 *new_subvolid = new_subvol->k.p.offset;
1076 *new_snapshotid = new_nodes[0];
1078 bch2_trans_iter_exit(trans, &src_iter);
1079 bch2_trans_iter_exit(trans, &dst_iter);
1083 int bch2_fs_subvolumes_init(struct bch_fs *c)
1085 INIT_WORK(&c->snapshot_delete_work, bch2_delete_dead_snapshots_work);
1086 INIT_WORK(&c->snapshot_wait_for_pagecache_and_delete_work,
1087 bch2_subvolume_wait_for_pagecache_and_delete);
1088 mutex_init(&c->snapshots_unlinked_lock);