]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/subvolume.c
Move c_src dirs back to toplevel
[bcachefs-tools-debian] / libbcachefs / subvolume.c
index 0214a98deb4ff2a566eaea9915457182af04bd34..7c67c28d3ef88ff32d1805257faf37ebc79f0d2d 100644 (file)
@@ -37,12 +37,8 @@ static int check_subvol(struct btree_trans *trans,
                return ret;
 
        if (BCH_SUBVOLUME_UNLINKED(subvol.v)) {
-               bch2_fs_lazy_rw(c);
-
                ret = bch2_subvolume_delete(trans, iter->pos.offset);
-               if (ret)
-                       bch_err(c, "error deleting subvolume %llu: %s",
-                               iter->pos.offset, bch2_err_str(ret));
+               bch_err_msg(c, ret, "deleting subvolume %llu", iter->pos.offset);
                return ret ?: -BCH_ERR_transaction_restart_nested;
        }
 
@@ -63,7 +59,8 @@ static int check_subvol(struct btree_trans *trans,
                if (ret)
                        return ret;
 
-               if (fsck_err_on(le32_to_cpu(st.master_subvol) != subvol.k->p.offset, c,
+               if (fsck_err_on(le32_to_cpu(st.master_subvol) != subvol.k->p.offset,
+                               c, subvol_not_master_and_not_snapshot,
                                "subvolume %llu is not set as snapshot but is not master subvolume",
                                k.k->p.offset)) {
                        struct bkey_i_subvolume *s =
@@ -82,32 +79,28 @@ fsck_err:
 
 int bch2_check_subvols(struct bch_fs *c)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
-       int ret;
-
-       ret = bch2_trans_run(c,
-               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)));
-       if (ret)
-               bch_err_fn(c, ret);
+       int ret = bch2_trans_run(c,
+               for_each_btree_key_commit(trans, iter,
+                               BTREE_ID_subvolumes, POS_MIN, BTREE_ITER_PREFETCH, k,
+                               NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+                       check_subvol(trans, &iter, k)));
+       bch_err_fn(c, ret);
        return ret;
 }
 
 /* Subvolumes: */
 
-int bch2_subvolume_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                          unsigned flags, struct printbuf *err)
+int bch2_subvolume_invalid(struct bch_fs *c, struct bkey_s_c k,
+                          enum bkey_invalid_flags flags, struct printbuf *err)
 {
-       if (bkey_lt(k.k->p, SUBVOL_POS_MIN) ||
-           bkey_gt(k.k->p, SUBVOL_POS_MAX)) {
-               prt_printf(err, "invalid pos");
-               return -BCH_ERR_invalid_bkey;
-       }
+       int ret = 0;
 
-       return 0;
+       bkey_fsck_err_on(bkey_lt(k.k->p, SUBVOL_POS_MIN) ||
+                        bkey_gt(k.k->p, SUBVOL_POS_MAX), c, err,
+                        subvol_pos_bad,
+                        "invalid pos");
+fsck_err:
+       return ret;
 }
 
 void bch2_subvolume_to_text(struct printbuf *out, struct bch_fs *c,
@@ -145,6 +138,24 @@ int bch2_subvolume_get(struct btree_trans *trans, unsigned subvol,
        return bch2_subvolume_get_inlined(trans, subvol, inconsistent_if_not_found, iter_flags, s);
 }
 
+int bch2_subvol_is_ro_trans(struct btree_trans *trans, u32 subvol)
+{
+       struct bch_subvolume s;
+       int ret = bch2_subvolume_get_inlined(trans, subvol, true, 0, &s);
+       if (ret)
+               return ret;
+
+       if (BCH_SUBVOLUME_RO(&s))
+               return -EROFS;
+       return 0;
+}
+
+int bch2_subvol_is_ro(struct bch_fs *c, u32 subvol)
+{
+       return bch2_trans_do(c, NULL, NULL, 0,
+               bch2_subvol_is_ro_trans(trans, subvol));
+}
+
 int bch2_snapshot_get_subvol(struct btree_trans *trans, u32 snapshot,
                             struct bch_subvolume *subvol)
 {
@@ -209,8 +220,6 @@ static int bch2_subvolume_reparent(struct btree_trans *trans,
  */
 static int bch2_subvolumes_reparent(struct btree_trans *trans, u32 subvolid_to_delete)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
        struct bch_subvolume s;
 
        return lockrestart_do(trans,
@@ -218,7 +227,7 @@ static int bch2_subvolumes_reparent(struct btree_trans *trans, u32 subvolid_to_d
                                   BTREE_ITER_CACHED, &s)) ?:
                for_each_btree_key_commit(trans, iter,
                                BTREE_ID_subvolumes, POS_MIN, BTREE_ITER_PREFETCH, k,
-                               NULL, NULL, BTREE_INSERT_NOFAIL,
+                               NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                        bch2_subvolume_reparent(trans, &iter, k,
                                        subvolid_to_delete, le32_to_cpu(s.parent)));
 }
@@ -231,7 +240,6 @@ static int __bch2_subvolume_delete(struct btree_trans *trans, u32 subvolid)
 {
        struct btree_iter iter;
        struct bkey_s_c_subvolume subvol;
-       struct btree_trans_commit_hook *h;
        u32 snapid;
        int ret = 0;
 
@@ -247,22 +255,8 @@ static int __bch2_subvolume_delete(struct btree_trans *trans, u32 subvolid)
 
        snapid = le32_to_cpu(subvol.v->snapshot);
 
-       ret = bch2_btree_delete_at(trans, &iter, 0);
-       if (ret)
-               goto err;
-
-       ret = bch2_snapshot_node_set_deleted(trans, snapid);
-       if (ret)
-               goto err;
-
-       h = bch2_trans_kmalloc(trans, sizeof(*h));
-       ret = PTR_ERR_OR_ZERO(h);
-       if (ret)
-               goto err;
-
-       h->fn = bch2_delete_dead_snapshots_hook;
-       bch2_trans_commit_hook(trans, h);
-err:
+       ret =   bch2_btree_delete_at(trans, &iter, 0) ?:
+               bch2_snapshot_node_set_deleted(trans, snapid);
        bch2_trans_iter_exit(trans, &iter);
        return ret;
 }
@@ -270,7 +264,7 @@ err:
 static int bch2_subvolume_delete(struct btree_trans *trans, u32 subvolid)
 {
        return bch2_subvolumes_reparent(trans, subvolid) ?:
-               commit_do(trans, NULL, NULL, BTREE_INSERT_NOFAIL,
+               commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                          __bch2_subvolume_delete(trans, subvolid));
 }
 
@@ -294,11 +288,10 @@ 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));
-                       if (ret) {
-                               bch_err(c, "error deleting subvolume %u: %s", *id, bch2_err_str(ret));
+                       ret = bch2_trans_run(c, bch2_subvolume_delete(trans, *id));
+                       bch_err_msg(c, ret, "deleting subvolume %u", *id);
+                       if (ret)
                                break;
-                       }
                }
 
                darray_exit(&s);