From: Boris Burkov <boris@bur.io>
To: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: [PATCH v3 5/8] btrfs-progs: simple quotas mkfs
Date: Wed, 27 Sep 2023 10:46:46 -0700 [thread overview]
Message-ID: <3b69a29059b051962e556f4ce3aa53e4d00466a2.1695836680.git.boris@bur.io> (raw)
In-Reply-To: <cover.1695836680.git.boris@bur.io>
Add the ability to enable simple quotas from mkfs with '-O squota'
There is some complication around handling enable gen while still
counting the root node of an fs. To handle this, employ a hack of doing
a no-op write on the root node to bump its generation up above that of
the qgroup enable generation, which results in counting it properly.
Signed-off-by: Boris Burkov <boris@bur.io>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
---
check/qgroup-verify.c | 7 +++--
common/fsfeatures.c | 9 ++++++
mkfs/main.c | 64 +++++++++++++++++++++++++++++++++++++++----
3 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/check/qgroup-verify.c b/check/qgroup-verify.c
index c95e6f806..1cf01d2d0 100644
--- a/check/qgroup-verify.c
+++ b/check/qgroup-verify.c
@@ -1695,6 +1695,8 @@ static int repair_qgroup_status(struct btrfs_fs_info *info, bool silent)
struct btrfs_path path;
struct btrfs_key key;
struct btrfs_qgroup_status_item *status_item;
+ bool simple = btrfs_fs_incompat(info, SIMPLE_QUOTA);
+ int flags = BTRFS_QGROUP_STATUS_FLAG_ON;
if (!silent)
printf("Repair qgroup status item\n");
@@ -1717,8 +1719,9 @@ static int repair_qgroup_status(struct btrfs_fs_info *info, bool silent)
status_item = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_qgroup_status_item);
- btrfs_set_qgroup_status_flags(path.nodes[0], status_item,
- BTRFS_QGROUP_STATUS_FLAG_ON);
+ if (simple)
+ flags |= BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
+ btrfs_set_qgroup_status_flags(path.nodes[0], status_item, flags);
btrfs_set_qgroup_status_rescan(path.nodes[0], status_item, 0);
btrfs_set_qgroup_status_generation(path.nodes[0], status_item,
trans->transid);
diff --git a/common/fsfeatures.c b/common/fsfeatures.c
index 1c993b594..6bf87937b 100644
--- a/common/fsfeatures.c
+++ b/common/fsfeatures.c
@@ -109,6 +109,15 @@ static const struct btrfs_feature mkfs_features[] = {
VERSION_NULL(default),
.desc = "quota support (qgroups)"
},
+ {
+ .name = "squota",
+ .incompat_flag = BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA,
+ .sysfs_name = "squota",
+ VERSION_TO_STRING2(compat, 6,5),
+ VERSION_NULL(safe),
+ VERSION_NULL(default),
+ .desc = "squota support (simple qgroups)"
+ },
{
.name = "extref",
.incompat_flag = BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF,
diff --git a/mkfs/main.c b/mkfs/main.c
index 1c5d668e1..5bb4d1a21 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -59,6 +59,8 @@
#include "mkfs/common.h"
#include "mkfs/rootdir.h"
+#include "libbtrfs/ctree.h"
+
struct mkfs_allocation {
u64 data;
u64 metadata;
@@ -882,6 +884,37 @@ static int insert_qgroup_items(struct btrfs_trans_handle *trans,
return ret;
}
+static int touch_root_subvol(struct btrfs_fs_info *fs_info)
+{
+ struct btrfs_trans_handle *trans;
+ struct btrfs_key key = {
+ .objectid = BTRFS_FIRST_FREE_OBJECTID,
+ .type = BTRFS_INODE_ITEM_KEY,
+ .offset = 0,
+ };
+ struct extent_buffer *leaf;
+ int slot;
+ struct btrfs_path path;
+ int ret;
+
+ trans = btrfs_start_transaction(fs_info->fs_root, 1);
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(trans, fs_info->fs_root, &key, &path, 0, 1);
+ if (ret)
+ goto fail;
+ leaf = path.nodes[0];
+ slot = path.slots[0];
+ btrfs_item_key_to_cpu(leaf, &key, slot);
+ btrfs_mark_buffer_dirty(leaf);
+ btrfs_commit_transaction(trans, fs_info->fs_root);
+ btrfs_release_path(&path);
+ return 0;
+fail:
+ btrfs_abort_transaction(trans, ret);
+ btrfs_release_path(&path);
+ return ret;
+}
+
static int setup_quota_root(struct btrfs_fs_info *fs_info)
{
struct btrfs_trans_handle *trans;
@@ -890,8 +923,11 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
struct btrfs_path path;
struct btrfs_key key;
int qgroup_repaired = 0;
+ bool simple = btrfs_fs_incompat(fs_info, SIMPLE_QUOTA);
+ int flags;
int ret;
+
/* One to modify tree root, one for quota root */
trans = btrfs_start_transaction(fs_info->tree_root, 2);
if (IS_ERR(trans)) {
@@ -921,13 +957,19 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
qsi = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_qgroup_status_item);
- btrfs_set_qgroup_status_generation(path.nodes[0], qsi, 0);
+ btrfs_set_qgroup_status_generation(path.nodes[0], qsi, trans->transid);
btrfs_set_qgroup_status_rescan(path.nodes[0], qsi, 0);
+ flags = BTRFS_QGROUP_STATUS_FLAG_ON;
+ if (simple) {
+ btrfs_set_qgroup_status_enable_gen(path.nodes[0], qsi, trans->transid);
+ flags |= BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
+ }
+ else {
+ flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+ }
- /* Mark current status info inconsistent, and fix it later */
- btrfs_set_qgroup_status_flags(path.nodes[0], qsi,
- BTRFS_QGROUP_STATUS_FLAG_ON |
- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT);
+ btrfs_set_qgroup_status_version(path.nodes[0], qsi, 1);
+ btrfs_set_qgroup_status_flags(path.nodes[0], qsi, flags);
btrfs_release_path(&path);
/* Currently mkfs will only create one subvolume */
@@ -944,6 +986,15 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
return ret;
}
+ /* Hack to count the default subvol metadata by dirtying it */
+ if (simple) {
+ ret = touch_root_subvol(fs_info);
+ if (ret) {
+ error("failed to touch root dir for simple quota accounting %d (%m)", ret);
+ goto fail;
+ }
+ }
+
/*
* Qgroup is setup but with wrong info, use qgroup-verify
* infrastructure to repair them. (Just acts as offline rescan)
@@ -1743,7 +1794,8 @@ raid_groups:
}
}
- if (features.runtime_flags & BTRFS_FEATURE_RUNTIME_QUOTA) {
+ if (features.runtime_flags & BTRFS_FEATURE_RUNTIME_QUOTA ||
+ features.incompat_flags & BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA) {
ret = setup_quota_root(fs_info);
if (ret < 0) {
error("failed to initialize quota: %d (%m)", ret);
--
2.42.0
next prev parent reply other threads:[~2023-09-27 17:46 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-27 17:46 [PATCH v3 0/8] btrfs-progs: simple quotas Boris Burkov
2023-09-27 17:46 ` [PATCH v3 1/8] btrfs-progs: document squotas Boris Burkov
2023-09-27 17:46 ` [PATCH v3 2/8] btrfs-progs: simple quotas kernel definitions Boris Burkov
2023-09-27 17:46 ` [PATCH v3 3/8] btrfs-progs: simple quotas dump commands Boris Burkov
2023-09-27 17:46 ` [PATCH v3 4/8] btrfs-progs: simple quotas fsck Boris Burkov
2023-09-27 17:46 ` Boris Burkov [this message]
2023-10-02 16:11 ` [PATCH v3 5/8] btrfs-progs: simple quotas mkfs David Sterba
2023-09-27 17:46 ` [PATCH v3 6/8] btrfs-progs: simple quotas btrfstune Boris Burkov
2023-09-27 17:46 ` [PATCH v3 7/8] btrfs-progs: simple quotas enable cmd Boris Burkov
2023-09-27 17:46 ` [PATCH v3 8/8] btrfs-progs: tree-checker: handle owner ref items Boris Burkov
2023-10-02 16:20 ` [PATCH v3 0/8] btrfs-progs: simple quotas David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3b69a29059b051962e556f4ce3aa53e4d00466a2.1695836680.git.boris@bur.io \
--to=boris@bur.io \
--cc=kernel-team@fb.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).