From patchwork Thu Jul 20 22:57:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 324FFEB64DD for ; Thu, 20 Jul 2023 22:59:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229560AbjGTW67 (ORCPT ); Thu, 20 Jul 2023 18:58:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229450AbjGTW65 (ORCPT ); Thu, 20 Jul 2023 18:58:57 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1849892 for ; Thu, 20 Jul 2023 15:58:56 -0700 (PDT) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id 870055C0166; Thu, 20 Jul 2023 18:58:55 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Thu, 20 Jul 2023 18:58:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893935; x= 1689980335; bh=y7dfXB80FTaXuGegrxi9/8KcyxEkaVrI6XucL83bZWs=; b=Y OZdu0o+5oUz/W9+LSD28sWoJ1Fp6CrqrUL3KvArAJkAG9+PvILLKMloOQrcneb5H PRZ56H11QB7Z287FVKQcVnZwgXj1WlLELeP/URR0IbhDuZvnxq0Qo0XM7I4nLKG8 u8LJp9SoO6kjPfgx5/AdhMVb7XZ2Oh5w9MOhua80LuI8RCj4uVPsxVcOassGuI5Y nwuzx44H3bWAI01N5BHJVJOdIcG+AMzNx8siNTDjVm180Sq7W5WvV4GRPMuZEq7l LSWE6eBtRoXVLWKEBHZa71aNcIxyxclvL6W9lJgoA2SUGQfGplegKrH9g1/tXEdN 8wPe3fEBPfPIKORTGnXkA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893935; x=1689980335; bh=y 7dfXB80FTaXuGegrxi9/8KcyxEkaVrI6XucL83bZWs=; b=L02eFYxyHZsGXv8gq fbRq/eYed0d2xQHiFkPcX9rqWb/kVcbRPB8g0jLdtHudhgMhN98ASGfnOj3WeSMN APxBjWDKIR+q60kkgBPX/JLVBxTId2eEmD/1iAvozFnwhqHNi0gac6h6xChNLcsx IBENO/lSeot3UdUT0T0Q9TLhkj5ipHowRAfrmZpCvlBy9RH2DnRb0n249j/fXxZX M/M+FtQqT7v+e9r9v8GI1GCk7WSPJddTbFJrlAa6eKGUvWHHP+Sg8oaWkiWP6pVs ibMCZISQq7XTzDtefwu4d/XeA3Uxil9Auu6z8lRepIIMcjXrD52HEVvYzUMZ0kVG Wi/nw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:58:55 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 1/8] btrfs-progs: document squotas Date: Thu, 20 Jul 2023 15:57:17 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Document the new options in btrfs quota and mkfs.btrfs. Also, add a section to the long form qgroups document about squotas. Signed-off-by: Boris Burkov --- Documentation/btrfs-quota.rst | 7 +++- Documentation/ch-quota-intro.rst | 59 ++++++++++++++++++++++++++++++++ Documentation/mkfs.btrfs.rst | 6 ++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/Documentation/btrfs-quota.rst b/Documentation/btrfs-quota.rst index 830e9059a..d5e08330e 100644 --- a/Documentation/btrfs-quota.rst +++ b/Documentation/btrfs-quota.rst @@ -47,9 +47,14 @@ SUBCOMMAND disable Disable subvolume quota support for a filesystem. -enable +enable [options] Enable subvolume quota support for a filesystem. + ``Options`` + + -s|--simple + use simple quotas (squotas) instead of qgroups + rescan [options] Trash all qgroup numbers and scan the metadata again with the current config. diff --git a/Documentation/ch-quota-intro.rst b/Documentation/ch-quota-intro.rst index 351772d10..fee5c28ce 100644 --- a/Documentation/ch-quota-intro.rst +++ b/Documentation/ch-quota-intro.rst @@ -194,3 +194,62 @@ but some snapshots for backup purposes are being created by the system. The user's snapshots should be accounted to the user, not the system. The solution is similar to the one from section 'Accounting snapshots to the user', but do not assign system snapshots to user's qgroup. + +Simple Quotas (squotas) +^^^^^^^^^^^^^^^^^^^^^^^ + +As detailed in this document, qgroups can handle many complex extent sharing +and unsharing scenarios while maintaining an accurate count of exclusive and +shared usage. However, this flexibility comes at a cost: many of the +computations are global, in the sense that we must count up the number of trees +referring to an extent after its references change. This can slow down +transaction commits and lead to unacceptable latencies, especially in cases +where snapshots scale up. + +To work around this limitation of qgroups, btrfs also supports a second set of +quota semantics: simple quotas or squotas. Squotas fully share the qgroups API +and hierarchical model, but do not track shared vs. exclusive usage. Instead, +they account all extents to the subvolume that first allocated it. With a bit +of new bookkeeping, this allows all accounting decisions to be local to the +allocation or freeing operation that deals with the extents themselves, and +fully avoids the complex and costly back-reference resolutions. + +``Example`` + +To illustrate the difference between squotas and qgroups, consider the following +basic example assuming a nodesize of 16KiB. + +1. create subvolume 256 +2. rack up 1GiB of data and metadata usage in 256 +3. snapshot 256, creating subvolume 257 +4. CoW 512MiB of the data and metadata in 257 +5. delete everything in 256 + +At each step, qgroups would have the following accounting: +1. 0/256: 16KiB excl 0 shared +2. 0/256: 1GiB excl 0 shared +3. 0/256: 0 excl 1GiB shared; 0/257: 0 excl 1GiB shared +4. 0/256: 512MiB excl 512MiB shared; 0/257: 512MiB excl 512MiB shared +5. 0/256: 16KiB excl 0 shared; 0/257: 1GiB excl 0 shared + +Whereas under squotas, the accounting would look like: +1. 0/256: 16KiB excl 16KiB shared +2. 0/256: 1GiB excl 1GiB shared +3. 0/256: 1GiB excl 1GiB shared; 0/257: 16KiB excl 16KiB shared +4. 0/256: 1GiB excl 1GiB shared; 0/257: 512MiB excl 512MiB shared +5. 0/256: 512MiB excl 512MiB shared; 0/257: 512MiB excl 512MiB shared + +Note that since the original snapshotted 512MiB are still referenced by 257, +they cannot be freed from 256, even after 256 is emptied, or even deleted. + +``Summary`` + +If you want some of power and flexibility of quotas for tracking and limiting +subvolume usage, but want to avoid the performance penalty of accurately +tracking extent ownership lifecycles, then squotas can be a useful option. + +Furthermore, squotas is targeted at use cases where the original extent is +immutable, like image snapshotting for container startup, in which case we avoid +these awkward scenarios where a subvolume is empty or deleted but still has +significant extents accounted to it. However, as long as you are aware of the +accounting semantics, they can handle mutable original extents. diff --git a/Documentation/mkfs.btrfs.rst b/Documentation/mkfs.btrfs.rst index d1626f736..051e8fb1c 100644 --- a/Documentation/mkfs.btrfs.rst +++ b/Documentation/mkfs.btrfs.rst @@ -307,6 +307,12 @@ block-group-tree Enable the block group tree to greatly reduce mount time for large filesystems. +squota + (kernel support since X.X) + + Enable simple quota support (squotas). This is an alternative to qgroups with + a smaller performance impact but no notion of shared vs. exclusive usage. + .. _mkfs-section-profiles: BLOCK GROUPS, CHUNKS, RAID From patchwork Thu Jul 20 22:57:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EDA7DC001DF for ; Thu, 20 Jul 2023 22:59:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229567AbjGTW67 (ORCPT ); Thu, 20 Jul 2023 18:58:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229517AbjGTW66 (ORCPT ); Thu, 20 Jul 2023 18:58:58 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA81B92 for ; Thu, 20 Jul 2023 15:58:57 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 421C65C0166; Thu, 20 Jul 2023 18:58:57 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 20 Jul 2023 18:58:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893937; x= 1689980337; bh=pC5O/GjSwg5IDlqKUIXN0rC3/iUf5tu71uiY9Z5dckQ=; b=R Hg0952+GADOHfcmYd9oAxAtCo9Ed9BxqTwLP49skqSl2dIYJNgf4JEtz/Ign+36V IWyCr0IVXDkuXjsNuuxXnYhN8uN700uGByZ2puPTqtV/e6co6FkTsueNiraGLCSk p262EWGxAlHDNOcsND290k1Wk3FF7laYO6ugjLz8q6vqiq/AzSAIdnjUWvpLpDd+ ApW4/ZrHQvQRx88vWyzlhC9dR8/CrNmiY5L3YzvIj4S9TRqnYy6QaVSqXXQECmcQ Uw7ankGqAjPt6mPXCM3a3CpFcf2U/6YPhY3++7GIaF4PydR0Ku0f7pV8PDfzHz02 lrjuicCpD/n+cWp//l2tg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893937; x=1689980337; bh=p C5O/GjSwg5IDlqKUIXN0rC3/iUf5tu71uiY9Z5dckQ=; b=fzT+N+MTdpQ9zW92v JibTVKBYkzAVUMfBTN2GgmHDBexXzLRPPx9DX+tnFpJlWSzuaRXuOGTS5m776wLi OADh6MBUFmxWtd2Sj2dVfnMxT5MvnbRkUUBmrPeG6ug4Chfcamx+wVT+gxMslWSa 67UyY2zaDaInPpmZB+7Q2bSNiob+M92WwtT4u0YkrMuON87CAqTAJjfhxujtAqW8 /JnvEJg+bZWRVvAsoiUMLwLaeoXtGB2uDgdiW0tm2uwbm3asly3+rA6iuAYti47n Ea2JJxKmRLit6O6dJ9vGpH/PahLE/qJEKPhJo9nnFkwJbMV7EESx2xYGzDqFORLl 0tSeg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgepleenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:58:56 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 2/8] btrfs-progs: simple quotas kernel definitions Date: Thu, 20 Jul 2023 15:57:18 -0700 Message-ID: <6344f891404f2493a2b196489cbcb1920d4cb81b.1689893698.git.boris@bur.io> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Copy over structs, accessors, and constants for simple quotas Signed-off-by: Boris Burkov Reviewed-by: Josef Bacik --- kernel-shared/accessors.h | 9 +++++++++ kernel-shared/ctree.h | 6 ++++-- kernel-shared/uapi/btrfs.h | 1 + kernel-shared/uapi/btrfs_tree.h | 17 ++++++++++++++++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/kernel-shared/accessors.h b/kernel-shared/accessors.h index 539c20d09..ab8c2d337 100644 --- a/kernel-shared/accessors.h +++ b/kernel-shared/accessors.h @@ -379,9 +379,13 @@ static inline u32 btrfs_extent_inline_ref_size(int type) if (type == BTRFS_EXTENT_DATA_REF_KEY) return sizeof(struct btrfs_extent_data_ref) + offsetof(struct btrfs_extent_inline_ref, offset); + if (type == BTRFS_EXTENT_OWNER_REF_KEY) + return sizeof(struct btrfs_extent_inline_ref); return 0; } +BTRFS_SETGET_FUNCS(extent_owner_ref_root_id, struct btrfs_extent_owner_ref, root_id, 64); + /* struct btrfs_node */ BTRFS_SETGET_FUNCS(key_blockptr, struct btrfs_key_ptr, blockptr, 64); BTRFS_SETGET_FUNCS(key_generation, struct btrfs_key_ptr, generation, 64); @@ -979,6 +983,9 @@ BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64); BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, rescan, 64); +BTRFS_SETGET_FUNCS(qgroup_status_enable_gen, struct btrfs_qgroup_status_item, + enable_gen, 64); + BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_generation, struct btrfs_qgroup_status_item, generation, 64); BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_version, @@ -987,6 +994,8 @@ BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64); BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_rescan, struct btrfs_qgroup_status_item, rescan, 64); +BTRFS_SETGET_STACK_FUNCS(stack_qgroup_status_enable_gen, + struct btrfs_qgroup_status_item, enable_gen, 64); /* btrfs_qgroup_info_item */ BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 5d3392ae8..3b283b21e 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -102,7 +102,8 @@ static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize) BTRFS_FEATURE_INCOMPAT_RAID1C34 | \ BTRFS_FEATURE_INCOMPAT_METADATA_UUID | \ BTRFS_FEATURE_INCOMPAT_ZONED | \ - BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2) + BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 | \ + BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA) #else #define BTRFS_FEATURE_INCOMPAT_SUPP \ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ @@ -117,7 +118,8 @@ static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize) BTRFS_FEATURE_INCOMPAT_NO_HOLES | \ BTRFS_FEATURE_INCOMPAT_RAID1C34 | \ BTRFS_FEATURE_INCOMPAT_METADATA_UUID | \ - BTRFS_FEATURE_INCOMPAT_ZONED) + BTRFS_FEATURE_INCOMPAT_ZONED | \ + BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA) #endif /* diff --git a/kernel-shared/uapi/btrfs.h b/kernel-shared/uapi/btrfs.h index 85b04f89a..d312b9f4f 100644 --- a/kernel-shared/uapi/btrfs.h +++ b/kernel-shared/uapi/btrfs.h @@ -356,6 +356,7 @@ _static_assert(sizeof(struct btrfs_ioctl_fs_info_args) == 1024); #define BTRFS_FEATURE_INCOMPAT_RAID1C34 (1ULL << 11) #define BTRFS_FEATURE_INCOMPAT_ZONED (1ULL << 12) #define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 (1ULL << 13) +#define BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA (1ULL << 14) struct btrfs_ioctl_feature_flags { __u64 compat_flags; diff --git a/kernel-shared/uapi/btrfs_tree.h b/kernel-shared/uapi/btrfs_tree.h index ad555e705..56b6c92f5 100644 --- a/kernel-shared/uapi/btrfs_tree.h +++ b/kernel-shared/uapi/btrfs_tree.h @@ -227,6 +227,8 @@ #define BTRFS_SHARED_DATA_REF_KEY 184 +#define BTRFS_EXTENT_OWNER_REF_KEY 190 + /* * block groups give us hints into the extent allocation trees. Which * blocks are free etc etc @@ -783,6 +785,10 @@ struct btrfs_shared_data_ref { __le32 count; } __attribute__ ((__packed__)); +struct btrfs_extent_owner_ref { + __le64 root_id; +} __attribute__ ((__packed__)); + struct btrfs_extent_inline_ref { __u8 type; __le64 offset; @@ -1199,10 +1205,13 @@ static inline __u16 btrfs_qgroup_level(__u64 qgroupid) * Turning qouta off and on again makes it inconsistent, too. */ #define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT (1ULL << 2) +/* bits 3 and 4 taken by runtime qgroup flags */ +#define BTRFS_QGROUP_STATUS_FLAG_SIMPLE (1ULL << 5) #define BTRFS_QGROUP_STATUS_FLAGS_MASK (BTRFS_QGROUP_STATUS_FLAG_ON | \ BTRFS_QGROUP_STATUS_FLAG_RESCAN | \ - BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) + BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT | \ + BTRFS_QGROUP_STATUS_FLAG_SIMPLE) #define BTRFS_QGROUP_STATUS_VERSION 1 @@ -1224,6 +1233,12 @@ struct btrfs_qgroup_status_item { * of the scan. It contains a logical address */ __le64 rescan; + + /* + * Used by simple quotas to ignore old extent deletions + * Present iff incompat flag SIMPLE_QUOTA is set + */ + __le64 enable_gen; } __attribute__ ((__packed__)); struct btrfs_qgroup_info_item { From patchwork Thu Jul 20 22:57:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DBEB6C001DC for ; Thu, 20 Jul 2023 22:59:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229592AbjGTW7B (ORCPT ); Thu, 20 Jul 2023 18:59:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229517AbjGTW7A (ORCPT ); Thu, 20 Jul 2023 18:59:00 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7019092 for ; Thu, 20 Jul 2023 15:58:59 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id DDCB55C0166; Thu, 20 Jul 2023 18:58:58 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 20 Jul 2023 18:58:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893938; x= 1689980338; bh=trt/YrbFZw6OCOYfDoE31H8ek+KPH08PsZNOggaQD2w=; b=S pnosM0VFZE6tJOUEQgPhV+CEFyF/iICm/O/QudS/0WLStbrYrKARSsQ8PjSS14i3 hU5899b45l7cczSvZSK8qzMv3xNmxAmdqD8FrH9R/wiEX3nFX7Z3y/eiVoTUGV9t NGUrmhSLUa00YItyJABZjiPkRtZqptQfVM50qne1qoTOVdGxGRlc22UsLnUOUrxI EMq3vENIVNJb2hvI6/8zoYM3RFUkho/iIa5AegxYrXxtLEzAZtsw32s83fq4ZRQo f4OhAJd38Wap5J9QteVW0DxOnK7K45pKR5n0S6ucsvAYB9ONE7B4lUJdcIxbxw/7 QttQ460QqxQijPv0U0y8g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893938; x=1689980338; bh=t rt/YrbFZw6OCOYfDoE31H8ek+KPH08PsZNOggaQD2w=; b=tK6WOPVBvT4m/QeCg 3V9icY+JHf+E4o9kz5RVRk+KrTUO5u7FfjCj/aTToYrSSOkYyqyICoCW604je7ac Lik0/4IDaRhYeNOD8+tCFpV8ZK2+2W28JV1PdswZJdxF3olOdEy12qVbu5Bb48Ty sViFXuobFybpjSFVKeCXaYaMh+z8Dmrns74nNCWDE2gmjYR5BPI/ajYd6trr7xJb TjW3ZOTHby5OvonfJZQASw3eM0a/DpQVcIVh9+jWb48JsU86wWPf5FNXHJZFUBFR E/NOZp0g8GXGtSxrYfI66E20G48U1X024lsugoMiVB6MMP4R6FcydtfTX9TBwB4j 3GtJQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgepleenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:58:58 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 3/8] btrfs-progs: simple quotas dump commands Date: Thu, 20 Jul 2023 15:57:19 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add support to btrfs inspect-internal dump-super and dump-tree for the new structures and feature flags introduced by simple quotas Signed-off-by: Boris Burkov Reviewed-by: Josef Bacik --- kernel-shared/print-tree.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c index 0f7f7b72f..7d4e77579 100644 --- a/kernel-shared/print-tree.c +++ b/kernel-shared/print-tree.c @@ -509,6 +509,10 @@ void print_extent_item(struct extent_buffer *eb, int slot, int metadata) (unsigned long long)offset, btrfs_shared_data_ref_count(eb, sref)); break; + case BTRFS_EXTENT_OWNER_REF_KEY: + printf("\t\textent owner root %llu\n", + (unsigned long long)offset); + break; default: return; } @@ -661,6 +665,7 @@ void print_key_type(FILE *stream, u64 objectid, u8 type) [BTRFS_EXTENT_DATA_REF_KEY] = "EXTENT_DATA_REF", [BTRFS_SHARED_DATA_REF_KEY] = "SHARED_DATA_REF", [BTRFS_EXTENT_REF_V0_KEY] = "EXTENT_REF_V0", + [BTRFS_EXTENT_OWNER_REF_KEY] = "EXTENT_OWNER_REF", [BTRFS_CSUM_ITEM_KEY] = "CSUM_ITEM", [BTRFS_EXTENT_CSUM_KEY] = "EXTENT_CSUM", [BTRFS_EXTENT_DATA_KEY] = "EXTENT_DATA", @@ -1042,6 +1047,17 @@ static void print_shared_data_ref(struct extent_buffer *eb, int slot) btrfs_shared_data_ref_count(eb, sref)); } +static void print_extent_owner_ref(struct extent_buffer *eb, int slot) +{ + struct btrfs_extent_owner_ref *oref; + u64 root_id; + + oref = btrfs_item_ptr(eb, slot, struct btrfs_extent_owner_ref); + root_id = btrfs_extent_owner_ref_root_id(eb, oref); + + printf("\t\textent owner root %llu\n", root_id); +} + static void print_free_space_info(struct extent_buffer *eb, int slot) { struct btrfs_free_space_info *free_info; @@ -1083,11 +1099,16 @@ static void print_qgroup_status(struct extent_buffer *eb, int slot) memset(flags_str, 0, sizeof(flags_str)); qgroup_flags_to_str(btrfs_qgroup_status_flags(eb, qg_status), flags_str); - printf("\t\tversion %llu generation %llu flags %s scan %llu\n", + printf("\t\tversion %llu generation %llu flags %s scan %llu", (unsigned long long)btrfs_qgroup_status_version(eb, qg_status), (unsigned long long)btrfs_qgroup_status_generation(eb, qg_status), flags_str, (unsigned long long)btrfs_qgroup_status_rescan(eb, qg_status)); + if (btrfs_fs_incompat(eb->fs_info, SIMPLE_QUOTA)) + printf(" enable_gen %llu\n", + (unsigned long long)btrfs_qgroup_status_enable_gen(eb, qg_status)); + else + printf("\n"); } static void print_qgroup_info(struct extent_buffer *eb, int slot) @@ -1407,6 +1428,9 @@ void btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode) case BTRFS_SHARED_DATA_REF_KEY: print_shared_data_ref(eb, i); break; + case BTRFS_EXTENT_OWNER_REF_KEY: + print_extent_owner_ref(eb, i); + break; case BTRFS_EXTENT_REF_V0_KEY: printf("\t\textent ref v0 (deprecated)\n"); break; @@ -1708,6 +1732,7 @@ static struct readable_flag_entry incompat_flags_array[] = { DEF_INCOMPAT_FLAG_ENTRY(RAID1C34), DEF_INCOMPAT_FLAG_ENTRY(ZONED), DEF_INCOMPAT_FLAG_ENTRY(EXTENT_TREE_V2), + DEF_INCOMPAT_FLAG_ENTRY(SIMPLE_QUOTA), }; static const int incompat_flags_num = sizeof(incompat_flags_array) / sizeof(struct readable_flag_entry); From patchwork Thu Jul 20 22:57:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3FF0EB64DA for ; Thu, 20 Jul 2023 22:59:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229610AbjGTW7C (ORCPT ); Thu, 20 Jul 2023 18:59:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229517AbjGTW7C (ORCPT ); Thu, 20 Jul 2023 18:59:02 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E88F92 for ; Thu, 20 Jul 2023 15:59:01 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 7B9EB5C0166; Thu, 20 Jul 2023 18:59:00 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 20 Jul 2023 18:59:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893940; x= 1689980340; bh=GFV+uKPRk4Am+jixPfXNfontdo+7MbTMnFGc/XraWBI=; b=g 2k1tAU+OO9zTU1WBbt+Q+KsUk3pCzz3XnwL46dWUTHwfN06J9PJqlQkWZIy42MQo MyYYb7+Svm5dYXqGETl+14bvWNfcwPJVMREVIQK/IyTZ0d+CRrx7JDWv9PbqptgB WCY76eWM+UauXvxf4r886nueV4saEBl0XSYjq5hie590NUPnsDkWLkqXWiZWD+/u B4ovx9bTtXZ38mDYI7RARUI4OPSHzyem74f2nWnjI1PCtB9OiPAyv7lg8z3kbdxA k1BfX5cSdQIFfBF2+5LMe/Mbp5pJ1PVGIRZ+wCKxe1snTIgk7MzwBrkblZJ0FQGU mG3cZXRc7YNTlOiJrC4nA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893940; x=1689980340; bh=G FV+uKPRk4Am+jixPfXNfontdo+7MbTMnFGc/XraWBI=; b=xNhlfByLp+BWMxZGu RJKq9Sa4fiZS+zYYEdZ2YLzFWHgYNPe6kaSsaKFGqvAgyTDTEnCcrFaU4OJ/Ax8H pQMItWxQsVNxzQCqgWdkmRJD+O9n0tfeg7DWHQN/Hg4Z2SVBKSfaT3iurH0lIJ3W gP/owo6IBfbOEY0COS8fra1thW1dNDVl5PwQqVj47nH3mDl4ijE05OzgQBxXLroh FRf2Wlxird8D3pPYsCmWn++f5hsMelRFUMtXRbQftyR9vn3XOUYnFC/6+s5lD1Pd iG+650kIm//a/vH6fw6+S7xmixA9EGUPPgHuFn0gAH08rv6H+Hs7JrPvhjN9egce 9bVFQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:59:00 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 4/8] btrfs-progs: simple quotas fsck Date: Thu, 20 Jul 2023 15:57:20 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add simple quotas checks to btrfs check. Like the kernel feature, these checks bypass most of the backref walking in the qgroups check. Instead, they enforce the invariant behind the design of simple quotas by scanning the extent tree and determining the owner of each extent: Data: reading the owner ref inline item Metadata: reading the tree block and reading its btrfs_header's owner This gives us the expected count from squotas which we check against the on-disk state of the qgroup items. Signed-off-by: Boris Burkov --- check/main.c | 2 ++ check/qgroup-verify.c | 79 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/check/main.c b/check/main.c index 77bb50a0e..07f31fbe0 100644 --- a/check/main.c +++ b/check/main.c @@ -5667,6 +5667,8 @@ static int process_extent_item(struct btrfs_root *root, btrfs_shared_data_ref_count(eb, sref), gen, 0, num_bytes); break; + case BTRFS_EXTENT_OWNER_REF_KEY: + break; default: fprintf(stderr, "corrupt extent record: key [%llu,%u,%llu]\n", diff --git a/check/qgroup-verify.c b/check/qgroup-verify.c index 1a62009b8..c95e6f806 100644 --- a/check/qgroup-verify.c +++ b/check/qgroup-verify.c @@ -85,6 +85,8 @@ static struct counts_tree { unsigned int num_groups; unsigned int rescan_running:1; unsigned int qgroup_inconsist:1; + unsigned int simple:1; + u64 enable_gen; u64 scan_progress; } counts = { .root = RB_ROOT }; @@ -915,14 +917,18 @@ static int add_qgroup_relation(u64 memberid, u64 parentid) return 0; } -static void read_qgroup_status(struct extent_buffer *eb, int slot, - struct counts_tree *counts) +static void read_qgroup_status(struct btrfs_fs_info *info, + struct extent_buffer *eb, + int slot, struct counts_tree *counts) { struct btrfs_qgroup_status_item *status_item; u64 flags; status_item = btrfs_item_ptr(eb, slot, struct btrfs_qgroup_status_item); flags = btrfs_qgroup_status_flags(eb, status_item); + + if (counts->simple == 1) + counts->enable_gen = btrfs_qgroup_status_enable_gen(eb, status_item); /* * Since qgroup_inconsist/rescan_running is just one bit, * assign value directly won't work. @@ -948,6 +954,8 @@ static int load_quota_info(struct btrfs_fs_info *info) int i, nr; int search_relations = 0; + if (btrfs_fs_incompat(info, SIMPLE_QUOTA)) + counts.simple = 1; loop: /* * Do 2 passes, the first allocates group counts and reads status @@ -990,7 +998,7 @@ loop: } if (key.type == BTRFS_QGROUP_STATUS_KEY) { - read_qgroup_status(leaf, i, &counts); + read_qgroup_status(info, leaf, i, &counts); continue; } @@ -1038,6 +1046,51 @@ out: return ret; } +static int simple_quota_account_extent(struct btrfs_fs_info *info, + struct extent_buffer *leaf, + struct btrfs_key *key, + struct btrfs_extent_item *ei, + struct btrfs_extent_inline_ref *iref, + u64 bytenr, u64 num_bytes, int meta_item) +{ + u64 generation; + int type; + u64 root; + struct ulist *roots = ulist_alloc(0); + int ret; + struct extent_buffer *node_eb; + u64 extent_root; + + generation = btrfs_extent_generation(leaf, ei); + if (generation < counts.enable_gen) + return 0; + + type = btrfs_extent_inline_ref_type(leaf, iref); + if (!meta_item) { + if (type == BTRFS_EXTENT_OWNER_REF_KEY) { + struct btrfs_extent_owner_ref *oref = (struct btrfs_extent_owner_ref *)(&iref->offset); + root = btrfs_extent_owner_ref_root_id(leaf, oref); + } else { + return 0; + } + } else { + extent_root = btrfs_root_id(btrfs_extent_root(info, key->objectid)); + node_eb = read_tree_block(info, key->objectid, extent_root, 0, 0, NULL); + if (!extent_buffer_uptodate(node_eb)) + return -EIO; + root = btrfs_header_owner(node_eb); + free_extent_buffer(node_eb); + } + + if (!is_fstree(root)) + return 0; + + ulist_add(roots, root, 0, 0); + ret = account_one_extent(roots, bytenr, num_bytes); + ulist_free(roots); + return ret; +} + static int add_inline_refs(struct btrfs_fs_info *info, struct extent_buffer *ei_leaf, int slot, u64 bytenr, u64 num_bytes, int meta_item) @@ -1045,6 +1098,7 @@ static int add_inline_refs(struct btrfs_fs_info *info, struct btrfs_extent_item *ei; struct btrfs_extent_inline_ref *iref; struct btrfs_extent_data_ref *dref; + struct btrfs_key key; u64 flags, root_obj, offset, parent; u32 item_size = btrfs_item_size(ei_leaf, slot); int type; @@ -1052,6 +1106,7 @@ static int add_inline_refs(struct btrfs_fs_info *info, unsigned long ptr; ei = btrfs_item_ptr(ei_leaf, slot, struct btrfs_extent_item); + btrfs_item_key_to_cpu(ei_leaf, &key, slot); flags = btrfs_extent_flags(ei_leaf, ei); if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK && !meta_item) { @@ -1062,6 +1117,15 @@ static int add_inline_refs(struct btrfs_fs_info *info, iref = (struct btrfs_extent_inline_ref *)(ei + 1); } + if (counts.simple) { + int ret = simple_quota_account_extent(info, ei_leaf, &key, ei, iref, + bytenr, num_bytes, meta_item); + + if (ret) + error("simple quota account extent error: %d", ret); + return ret; + } + ptr = (unsigned long)iref; end = (unsigned long)ei + item_size; while (ptr < end) { @@ -1083,6 +1147,7 @@ static int add_inline_refs(struct btrfs_fs_info *info, parent = offset; break; default: + error("unexpected iref type %d", type); return 1; } @@ -1445,6 +1510,13 @@ int qgroup_verify_all(struct btrfs_fs_info *info) goto out; } } + /* + * As in the kernel, simple qgroup accounting is done locally per extent, + * so we don't need to resolve backrefs to find which subvol an extent + * is accounted to. + */ + if (counts.simple) + goto check; ret = map_implied_refs(info); if (ret) { @@ -1454,6 +1526,7 @@ int qgroup_verify_all(struct btrfs_fs_info *info) ret = account_all_refs(1, 0); +check: /* * Do the correctness check here, so for callers who don't want * verbose report can skip calling report_qgroups() From patchwork Thu Jul 20 22:57:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321174 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D0ACC001DC for ; Thu, 20 Jul 2023 22:59:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229638AbjGTW7E (ORCPT ); Thu, 20 Jul 2023 18:59:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229517AbjGTW7D (ORCPT ); Thu, 20 Jul 2023 18:59:03 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACAB392 for ; Thu, 20 Jul 2023 15:59:02 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 269F95C0113; Thu, 20 Jul 2023 18:59:02 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Thu, 20 Jul 2023 18:59:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893942; x= 1689980342; bh=cXqNOKAQXfe4bIkJWQHqHnC4KJxLx0QSfwrJwUUEU4Y=; b=m hseqQDAfwRUv5PLE+jU13Vv9GGoNhpwSb0nnISJCh31FnzBLSw/YowtCkgEd4E9T psYG1YchuDBZkNkWHo3AVrPXE5DF1m27RetJOyDMZjxGvV+GvNjo1xT7Q60lxNff lDir6N6NQbC/wS3Ki5CQfhDDATJ5SEQlig4S9loD9CeXF5EO1gHG01C2JsYC6dAc kmHctlIrYZYV+bHMPucVRYElXkD1zNfARbC0rx1qhYH/nh5Ha67Y+Vax5cSdI3qU h+zFPdAjuZu3XqcGNHs0C8MHJs0GXOmXUcTuFsie/WDBw03A2PkCAv5T6RQc+qKp leANrEKakssCr29uMJ9Nw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893942; x=1689980342; bh=c XqNOKAQXfe4bIkJWQHqHnC4KJxLx0QSfwrJwUUEU4Y=; b=QQX7NNi6mmKNTM4As yJrvlDHZcZcWiPlGDp+b3QKv+w5vtAXrGX9cvuiv1VoI1Jk5t86+nSjvO3RAhwlj 27nZg/wWL6W+k5ucYPnjZLZUjgjlDun2X/5OrNNSGU+gOwoMUCsSwI4AdlCjIrJN 4UQo8Z5ikJO+3vftGhInZlrDOYZ7yW8lg1HNDNpyWCzRN/SDbTPUJUln5RBqqg3s 24Q/aPzql2hdWWFZ9Yqx2fSp/Yt5NLylOGoGd7VY05egDmNu6oaN7KgGmhA7sZrz W+rHtuuySoBHMnmaaeGphS4F4MWSoskqzlia21yXkt6/Gn9+YFufQqd/NmV0FciN jQUlg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:59:01 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 5/8] btrfs-progs: simple quotas mkfs Date: Thu, 20 Jul 2023 15:57:21 -0700 Message-ID: <5c1ec94a8bf33e3f145ddb53f2fefafffd9b8f6a.1689893698.git.boris@bur.io> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org 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 Reviewed-by: Josef Bacik --- 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..7b32d7b5c 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; + 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 00658fa51..584ecb5fc 100644 --- a/common/fsfeatures.c +++ b/common/fsfeatures.c @@ -108,6 +108,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 7acd39ec6..e0b20063d 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; + } + 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); From patchwork Thu Jul 20 22:57:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D090BEB64DA for ; Thu, 20 Jul 2023 22:59:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229683AbjGTW7G (ORCPT ); Thu, 20 Jul 2023 18:59:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33120 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229517AbjGTW7F (ORCPT ); Thu, 20 Jul 2023 18:59:05 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E4C6199D for ; Thu, 20 Jul 2023 15:59:04 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id CC0DE5C0170; Thu, 20 Jul 2023 18:59:03 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 20 Jul 2023 18:59:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893943; x= 1689980343; bh=Ul+w1Okja8Akf8fsW7Lei4WyV0Vm9lNnIYsWUueVnl8=; b=q UsbUa2OZpYKSKwfGVr2v5l2A+6ASNbFOLtroQ7AEU79MQp8cCg7R833qIdq5f+he CJrn/LF7wQ6NvnpW54hb3WD/9HLAxoEDK1WwwPGpksYo2mJmeSqyO0HnGhVTJ4Cq zZVEyDdQXZRTskp3XpQrOPdlFtaXHgF/kdnwCJsgoOG69x5NLn0ppjnZk6wY6QUH nnzeMuHis14qtdVdIy3wqyJy6j13ZrRkHXBj82kNDsfkFmQ70EWy7SM4Wh+VJ2Sn Jf1fSBr/8sIKJjgM4Sc+eia+qNpuATZan9SDmxJJZvrabGuqq66/0+DvVSpu1cAo /XbSlGbKhl5v8mrCILSJA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893943; x=1689980343; bh=U l+w1Okja8Akf8fsW7Lei4WyV0Vm9lNnIYsWUueVnl8=; b=esBP2m1St/qZE3/4d vd+pdO5hJVVqDgkP/vhzdhmNuD6sGAvDnrTME3pOXPuWo3OQ3y5SDmLBmQU52vsm TZEiIfshIarKo2JtzCTJpZNoMnIDnQeRKdjUXe1MaHJx12TZS4dR0QL0KtadgPty OzjStzzgiF5lwHZA5sBTaP83V4/i/oB26Ky7b8t3Y2g8cxuFSBVmPWeBVcC9ht9l x+9WrdvHYT5KpVL8hapilV5muQVFcBbRUokTpkS/TbwQIJAZ8D+1+n5+o2GfCfBN K7zk118JDvQrYJtSrD3OuX/A1FQwcVaQFiqcUUf+qRNR+PYMmyBJqxhqXoUdNB83 Ba5cA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgepvdenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:59:03 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 6/8] btrfs-progs: simple quotas btrfstune Date: Thu, 20 Jul 2023 15:57:22 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add the ability to enable simple quotas on an existing file system at rest with btrfstune. This is similar to the functionality in mkfs, except it must also find all the roots for which it must create qgroups. Note that this *does not* retroactively compute usage for existing extents as that is impossible for data. This is consistent with the behavior of the live enable ioctl. Signed-off-by: Boris Burkov Reviewed-by: Josef Bacik --- Makefile | 2 +- tune/main.c | 13 +++- tune/quota.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++ tune/tune.h | 3 + 4 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 tune/quota.c diff --git a/Makefile b/Makefile index 86c73590d..74862ff32 100644 --- a/Makefile +++ b/Makefile @@ -257,7 +257,7 @@ convert_objects = convert/main.o convert/common.o convert/source-fs.o \ mkfs_objects = mkfs/main.o mkfs/common.o mkfs/rootdir.o image_objects = image/main.o image/sanitize.o tune_objects = tune/main.o tune/seeding.o tune/change-uuid.o tune/change-metadata-uuid.o \ - tune/convert-bgt.o tune/change-csum.o check/clear-cache.o + tune/convert-bgt.o tune/change-csum.o tune/quota.o check/clear-cache.o all_objects = $(objects) $(cmds_objects) $(libbtrfs_objects) $(convert_objects) \ $(mkfs_objects) $(image_objects) $(tune_objects) $(libbtrfsutil_objects) diff --git a/tune/main.c b/tune/main.c index e38c1f6d3..b694d0da0 100644 --- a/tune/main.c +++ b/tune/main.c @@ -103,6 +103,7 @@ static const char * const tune_usage[] = { OPTLINE("-x", "enable skinny metadata extent refs (mkfs: skinny-metadata)"), OPTLINE("-n", "enable no-holes feature (mkfs: no-holes, more efficient sparse file representation)"), OPTLINE("-S <0|1>", "set/unset seeding status of a device"), + OPTLINE("-q", "enable simple quotas on the file system. (mkfs: squota)"), OPTLINE("--convert-to-block-group-tree", "convert filesystem to track block groups in " "the separate block-group-tree instead of extent tree (sets the incompat bit)"), OPTLINE("--convert-from-block-group-tree", @@ -147,6 +148,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[]) char *new_fsid_str = NULL; int ret; u64 super_flags = 0; + int quota = 0; int fd = -1; btrfs_config_init(); @@ -169,7 +171,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[]) #endif { NULL, 0, NULL, 0 } }; - int c = getopt_long(argc, argv, "S:rxfuU:nmM:", long_options, NULL); + int c = getopt_long(argc, argv, "S:rxqfuU:nmM:", long_options, NULL); if (c < 0) break; @@ -184,6 +186,9 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[]) case 'x': super_flags |= BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA; break; + case 'q': + quota = 1; + break; case 'n': super_flags |= BTRFS_FEATURE_INCOMPAT_NO_HOLES; break; @@ -241,7 +246,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[]) } if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str) && !change_metadata_uuid && csum_type == -1 && !to_bg_tree && - !to_extent_tree && !to_fst) { + !to_extent_tree && !to_fst && !quota) { error("at least one option should be specified"); usage(&tune_cmd, 1); return 1; @@ -420,6 +425,10 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[]) total++; } + if (quota) { + ret = enable_quota(root->fs_info, true); + } + if (success == total) { ret = 0; } else { diff --git a/tune/quota.c b/tune/quota.c new file mode 100644 index 000000000..b7086c59e --- /dev/null +++ b/tune/quota.c @@ -0,0 +1,172 @@ +#include + +#include "common/messages.h" +#include "kernel-shared/ctree.h" +#include "kernel-shared/disk-io.h" +#include "kernel-shared/transaction.h" +#include "kernel-shared/uapi/btrfs_tree.h" +#include "tune/tune.h" + +static int create_qgroup(struct btrfs_fs_info *fs_info, + struct btrfs_trans_handle *trans, + u64 qgroupid) +{ + struct btrfs_path path; + struct btrfs_root *quota_root = fs_info->quota_root; + struct btrfs_key key; + int ret; + + if (qgroupid >> BTRFS_QGROUP_LEVEL_SHIFT) { + error("qgroup level other than 0 is not supported yet"); + return -ENOTTY; + } + + key.objectid = 0; + key.type = BTRFS_QGROUP_INFO_KEY; + key.offset = qgroupid; + + btrfs_init_path(&path); + ret = btrfs_insert_empty_item(trans, quota_root, &path, &key, + sizeof(struct btrfs_qgroup_info_item)); + btrfs_release_path(&path); + if (ret < 0) + return ret; + + key.objectid = 0; + key.type = BTRFS_QGROUP_LIMIT_KEY; + key.offset = qgroupid; + ret = btrfs_insert_empty_item(trans, quota_root, &path, &key, + sizeof(struct btrfs_qgroup_limit_item)); + btrfs_release_path(&path); + + printf("created qgroup for %llu\n", qgroupid); + return ret; +} + +static int create_qgroups(struct btrfs_fs_info *fs_info, + struct btrfs_trans_handle *trans) +{ + struct btrfs_key key = { + .objectid = 0, + .type = BTRFS_ROOT_REF_KEY, + .offset = 0, + }; + struct btrfs_path path; + struct extent_buffer *leaf; + int slot; + struct btrfs_root *tree_root = fs_info->tree_root; + int ret; + + + ret = create_qgroup(fs_info, trans, BTRFS_FS_TREE_OBJECTID); + if (ret) + goto out; + + btrfs_init_path(&path); + ret = btrfs_search_slot_for_read(tree_root, &key, &path, 1, 0); + if (ret) + goto out; + + while (1) { + slot = path.slots[0]; + leaf = path.nodes[0]; + btrfs_item_key_to_cpu(leaf, &key, slot); + if (key.type == BTRFS_ROOT_REF_KEY) { + ret = create_qgroup(fs_info, trans, key.offset); + if (ret) + goto out; + } + ret = btrfs_next_item(tree_root, &path); + if (ret < 0) { + error("failed to advance to next item"); + goto out; + } + if (ret) + break; + } + +out: + btrfs_release_path(&path); + return ret; +} + +int enable_quota(struct btrfs_fs_info *fs_info, bool simple) +{ + struct btrfs_super_block *sb = fs_info->super_copy; + struct btrfs_trans_handle *trans; + int super_flags = btrfs_super_incompat_flags(sb); + struct btrfs_qgroup_status_item *qsi; + struct btrfs_root *quota_root; + struct btrfs_path path; + struct btrfs_key key; + int flags; + int ret; + + trans = btrfs_start_transaction(fs_info->tree_root, 2); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + errno = -ret; + error_msg(ERROR_MSG_START_TRANS, "%m"); + return ret; + } + + ret = btrfs_create_root(trans, fs_info, BTRFS_QUOTA_TREE_OBJECTID); + if (ret < 0) { + error("failed to create quota root: %d (%m)", ret); + goto fail; + } + quota_root = fs_info->quota_root; + + /* Create the qgroup status item */ + key.objectid = 0; + key.type = BTRFS_QGROUP_STATUS_KEY; + key.offset = 0; + + btrfs_init_path(&path); + ret = btrfs_insert_empty_item(trans, quota_root, &path, &key, + sizeof(*qsi)); + if (ret < 0) { + error("failed to insert qgroup status item: %d (%m)", ret); + goto fail; + } + + qsi = btrfs_item_ptr(path.nodes[0], path.slots[0], + struct btrfs_qgroup_status_item); + 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; + } else { + flags |= 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); + + /* Create the qgroup items */ + ret = create_qgroups(fs_info, trans); + if (ret < 0) { + error("failed to create qgroup items for subvols %d (%m)", ret); + goto fail; + } + + /* Set squota incompat flag */ + if (simple) { + super_flags |= BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA; + btrfs_set_super_incompat_flags(sb, super_flags); + } + + ret = btrfs_commit_transaction(trans, fs_info->tree_root); + if (ret < 0) { + errno = -ret; + error_msg(ERROR_MSG_COMMIT_TRANS, "%m"); + return ret; + } + return ret; +fail: + btrfs_abort_transaction(trans, ret); + return ret; +} diff --git a/tune/tune.h b/tune/tune.h index 0ef249d89..cbf33b2e7 100644 --- a/tune/tune.h +++ b/tune/tune.h @@ -33,4 +33,7 @@ int convert_to_bg_tree(struct btrfs_fs_info *fs_info); int convert_to_extent_tree(struct btrfs_fs_info *fs_info); int btrfs_change_csum_type(struct btrfs_fs_info *fs_info, u16 new_csum_type); + +int enable_quota(struct btrfs_fs_info *fs_info, bool simple); + #endif From patchwork Thu Jul 20 22:57:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321176 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B407C001DC for ; Thu, 20 Jul 2023 22:59:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229707AbjGTW7I (ORCPT ); Thu, 20 Jul 2023 18:59:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229517AbjGTW7H (ORCPT ); Thu, 20 Jul 2023 18:59:07 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1612619A6 for ; Thu, 20 Jul 2023 15:59:06 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 83D2D5C0113; Thu, 20 Jul 2023 18:59:05 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Thu, 20 Jul 2023 18:59:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893945; x= 1689980345; bh=ef9wLWbt0+nPzMM17UYWtWZShfGXjlwNtXYeC80vZQg=; b=a 2w6cUlOM3nP6zM8bPXYFExJJyBVgD4JK9cQ7kRmS3QLVfOEGydF0Rv5H5rnrXQRd IhMt1diTgXO1Y2Qu5DniZeEdMwpYIFcU9Sc4KBWi0ZiMUXiuHCRxZ0g0KmKfnXXB AJ9G/M9Mv/Z18CZYOSROm073xn7YPHp2703BiyjVtIkuADts1oG/GrkJFBcYBshp L1qFYQONqRUZVZGTevtFpDkBOySTCEoH8Wny+YHlA6C3+MBZ6CBGFz9tJIE7xuUK o0AHvUIWFy4sLwlPWq5s4ua3UcaU7z0ZTh//HBYpf4aa9RiAsZ+X99ikA3P4HCWQ +/Zx/vzN2YW2dqGZw8Kgw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893945; x=1689980345; bh=e f9wLWbt0+nPzMM17UYWtWZShfGXjlwNtXYeC80vZQg=; b=rERbL6T5JjiIsMBN2 xOvRSm8aCJfWahtwj9sSJjYX8MZx+/QOFp437iB7twYinEwYd94hGrtw/T7726mc C8aWabzK5sGldoAC/viSM2I78tQteq6WBjLB47AKp9utQ4CU126ucNI+Fml0ZC9o bSzDKHlMCWp/Pz1Hzi9S33csBVpE6/nOaxBxoOgdyUjwLpuDmk2tybcwJS7u+iiP 6r4qLy31JgptJ9vAq2dVVwvt06U3awrWswvEuc410mg2GIMy6ovDtAaJLiU2VdFT Ej8O0JGIFo3JgpEyL3G7dF1/mlu/0YUpCokXyjVkEyf3FxeJb5qLAnlF8YdGf4jW h6TQg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:59:04 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 7/8] btrfs-progs: simple quotas enable cmd Date: Thu, 20 Jul 2023 15:57:23 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add a --simple flag to btrfs quota enable. If set, this enables simple quotas instead of full qgroups by using the new ioctl command value. Signed-off-by: Boris Burkov --- cmds/quota.c | 39 ++++++++++++++++++++++++++++++-------- kernel-shared/uapi/btrfs.h | 2 ++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/cmds/quota.c b/cmds/quota.c index cd874f9ed..a7d032a03 100644 --- a/cmds/quota.c +++ b/cmds/quota.c @@ -34,17 +34,13 @@ static const char * const quota_cmd_group_usage[] = { NULL }; -static int quota_ctl(int cmd, int argc, char **argv) +static int quota_ctl(int cmd, char *path) { int ret = 0; int fd; - char *path = argv[1]; struct btrfs_ioctl_quota_ctl_args args; DIR *dirstream = NULL; - if (check_argc_exact(argc, 2)) - return -1; - memset(&args, 0, sizeof(args)); args.cmd = cmd; @@ -67,16 +63,40 @@ static const char * const cmd_quota_enable_usage[] = { "Any data already present on the filesystem will not count towards", "the space usage numbers. It is recommended to enable quota for a", "filesystem before writing any data to it.", + "", + "-s|--simple simple qgroups account ownership by extent lifetime rather than backref walks", NULL }; static int cmd_quota_enable(const struct cmd_struct *cmd, int argc, char **argv) { int ret; + int ctl_cmd = BTRFS_QUOTA_CTL_ENABLE; - clean_args_no_options(cmd, argc, argv); + optind = 0; + while (1) { + static const struct option long_options[] = { + {"simple", no_argument, NULL, 's'}, + {NULL, 0, NULL, 0} + }; + int c; - ret = quota_ctl(BTRFS_QUOTA_CTL_ENABLE, argc, argv); + c = getopt_long(argc, argv, "s", long_options, NULL); + if (c < 0) + break; + + switch (c) { + case 's': + ctl_cmd = BTRFS_QUOTA_CTL_ENABLE_SIMPLE_QUOTA; + break; + default: + usage_unknown_option(cmd, argv); + } + } + if (check_argc_exact(argc - optind, 1)) + return -1; + + ret = quota_ctl(ctl_cmd, argv[optind]); if (ret < 0) usage(cmd, 1); @@ -97,7 +117,10 @@ static int cmd_quota_disable(const struct cmd_struct *cmd, clean_args_no_options(cmd, argc, argv); - ret = quota_ctl(BTRFS_QUOTA_CTL_DISABLE, argc, argv); + if (check_argc_exact(argc, 2)) + return -1; + + ret = quota_ctl(BTRFS_QUOTA_CTL_DISABLE, argv[1]); if (ret < 0) usage(cmd, 1); diff --git a/kernel-shared/uapi/btrfs.h b/kernel-shared/uapi/btrfs.h index d312b9f4f..09152f8bf 100644 --- a/kernel-shared/uapi/btrfs.h +++ b/kernel-shared/uapi/btrfs.h @@ -786,9 +786,11 @@ struct btrfs_ioctl_get_dev_stats { }; _static_assert(sizeof(struct btrfs_ioctl_get_dev_stats) == 1032); +/* cmd values */ #define BTRFS_QUOTA_CTL_ENABLE 1 #define BTRFS_QUOTA_CTL_DISABLE 2 #define BTRFS_QUOTA_CTL_RESCAN__NOTUSED 3 +#define BTRFS_QUOTA_CTL_ENABLE_SIMPLE_QUOTA 4 struct btrfs_ioctl_quota_ctl_args { __u64 cmd; __u64 status; From patchwork Thu Jul 20 22:57:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Burkov X-Patchwork-Id: 13321177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C3A39EB64DD for ; Thu, 20 Jul 2023 22:59:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229640AbjGTW7J (ORCPT ); Thu, 20 Jul 2023 18:59:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229709AbjGTW7I (ORCPT ); Thu, 20 Jul 2023 18:59:08 -0400 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE12492 for ; Thu, 20 Jul 2023 15:59:07 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 2BE835C00E6; Thu, 20 Jul 2023 18:59:07 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 20 Jul 2023 18:59:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bur.io; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1689893947; x= 1689980347; bh=FPfZW8KTO1u0eOV7SXtgI+mcaKyJGD+tGIo2ZSVwOCs=; b=X IzxUc4dkCLVgD6EJ1U4VeUxlV6fo6Qy4nfHkHx1zVWxz3+osMk+zr18gAHzx9JSO Pa4JBYAuTzw+nWigXVbaVjrMAgeMsoFYI7dh2BvXRb5OZVBayO19v6RRY6/y4NsN /8Op4gKd7yEQ9y1yhhDf2vJbHtVDG6iMNIrGRKxccLbIQOuYD1eMmBxAy3V3rJuf V6MhOgumPtbqI5RdyNUUV4gTDe5cvYLNJsDLyMsbPKMfzxNXHirlMptxO4y0NX9l fvDSraizL3Ua9ot5dMmxg8R0oJkC1q9DdFQobDjzLkICsTZTbKAItKC7KeKuw6MQ iKJ3FUFgE+NNyh9YpZWLg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1689893947; x=1689980347; bh=F PfZW8KTO1u0eOV7SXtgI+mcaKyJGD+tGIo2ZSVwOCs=; b=sXtyjHvws9lFXGvr5 S68E6xpVT4nLBsRD+d/i1C0GzAUzMvzTlaRRhpMynIF4aRl2Dyr3mM18D5+XHibQ VzAR6LzQCzLPQgIMk2PVaTvbJQ/eBwDUuSI625eItq1RHkoHUTH1532K5Kycljln xCx98H7AmO4BhTX2kF15UVkc6DVwdHKt1OCGEYxRLAmnAA0gQogc9anV3+IdnOoE RZXJZ7RUTdHQ7/qKIHo9+RhqU4dpEDrypVI0BldK6q2/t/r6OARFd1jGJrMVWdiD nBlSFfBeR4Mpq/hBLwbT89CbcRhDzOJxVMQ5uxvTjDcPQWfUb0bartStKEEyazrZ +tJwA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrhedugdduhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeeuohhrihhsuceuuhhrkhhovhcuoegsohhrihhssegsuhhrrdhi oheqnecuggftrfgrthhtvghrnhepieeuffeuvdeiueejhfehiefgkeevudejjeejffevvd ehtddufeeihfekgeeuheelnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehm rghilhhfrhhomhepsghorhhishessghurhdrihho X-ME-Proxy: Feedback-ID: i083147f8:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 20 Jul 2023 18:59:06 -0400 (EDT) From: Boris Burkov To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v2 8/8] btrfs-progs: tree-checker: handle owner ref items Date: Thu, 20 Jul 2023 15:57:24 -0700 Message-ID: <207564817d028dd21505936c8f7f25a037d89f59.1689893698.git.boris@bur.io> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Add the new OWNER_REF inline items to the tree-checker extent item checking code. We could somehow validate the root id for being a valid fstree id, but just skipping it seems fine as well. Signed-off-by: Boris Burkov Reviewed-by: Josef Bacik --- kernel-shared/tree-checker.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel-shared/tree-checker.c b/kernel-shared/tree-checker.c index 107975891..2f834cf33 100644 --- a/kernel-shared/tree-checker.c +++ b/kernel-shared/tree-checker.c @@ -1477,6 +1477,8 @@ static int check_extent_item(struct extent_buffer *leaf, } inline_refs += btrfs_shared_data_ref_count(leaf, sref); break; + case BTRFS_EXTENT_OWNER_REF_KEY: + break; default: extent_err(leaf, slot, "unknown inline ref type: %u", inline_type);