{
    "content": [
        {
            "type": "text",
            "text": "# btrfs-quota (man)\n\n## NAME\n\nbtrfs-quota - control the global quota status of a btrfs filesystem\n\n## SYNOPSIS\n\nbtrfs quota <subcommand> <args>\n\n## DESCRIPTION\n\nThe  commands  under  btrfs  quota  are used to affect the global status of quotas of a btrfs\nfilesystem. The quota groups (qgroups) are managed by the subcommand btrfs-qgroup(8).\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION** (1 subsections)\n- **HIERARCHICAL QUOTA GROUP CONCEPTS** (10 subsections)\n- **SUBCOMMAND** (3 subsections)\n- **EXIT STATUS**\n- **AVAILABILITY**\n- **SEE ALSO**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "btrfs-quota",
        "section": "",
        "mode": "man",
        "summary": "btrfs-quota - control the global quota status of a btrfs filesystem",
        "synopsis": "btrfs quota <subcommand> <args>",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [
            {
                "name": "btrfs-qgroup",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/btrfs-qgroup/8/json"
            },
            {
                "name": "btrfs-subvolume",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/btrfs-subvolume/8/json"
            },
            {
                "name": "mkfs.btrfs",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/mkfs.btrfs/8/json"
            },
            {
                "name": "BTRFS-QUOTA",
                "section": "8",
                "url": "https://www.chedong.com/phpMan.php/man/BTRFS-QUOTA/8/json"
            }
        ],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 3,
                "subsections": [
                    {
                        "name": "NOTE:",
                        "lines": 14
                    }
                ]
            },
            {
                "name": "HIERARCHICAL QUOTA GROUP CONCEPTS",
                "lines": 33,
                "subsections": [
                    {
                        "name": "referenced",
                        "lines": 3
                    },
                    {
                        "name": "exclusive",
                        "lines": 3
                    },
                    {
                        "name": "Subvolume quota groups",
                        "lines": 49
                    },
                    {
                        "name": "Inheritance",
                        "lines": 24
                    },
                    {
                        "name": "Use cases",
                        "lines": 3
                    },
                    {
                        "name": "Single-user machine",
                        "lines": 10
                    },
                    {
                        "name": "Multi-user machine",
                        "lines": 26
                    },
                    {
                        "name": "Simple quotas (squota)",
                        "lines": 14
                    },
                    {
                        "name": "Example",
                        "lines": 40
                    },
                    {
                        "name": "Summary",
                        "lines": 10
                    }
                ]
            },
            {
                "name": "SUBCOMMAND",
                "lines": 1,
                "subsections": [
                    {
                        "name": "disable <path>",
                        "lines": 2
                    },
                    {
                        "name": "enable [options] <path>",
                        "lines": 10
                    },
                    {
                        "name": "rescan [options] <path>",
                        "lines": 13
                    }
                ]
            },
            {
                "name": "EXIT STATUS",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "AVAILABILITY",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 4,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "btrfs-quota - control the global quota status of a btrfs filesystem\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "btrfs quota <subcommand> <args>\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "The  commands  under  btrfs  quota  are used to affect the global status of quotas of a btrfs\nfilesystem. The quota groups (qgroups) are managed by the subcommand btrfs-qgroup(8).\n",
                "subsections": [
                    {
                        "name": "NOTE:",
                        "content": "Qgroups are different than the traditional user quotas and designed to  track  shared  and\nexclusive  data  per-subvolume.  Please refer to the section HIERARCHICAL QUOTA GROUP CON‐\nCEPTS for a detailed description.\n\nPERFORMANCE IMPLICATIONS\nWhen quotas are activated, they affect all extent processing, which takes a performance  hit.\nActivation of qgroups is not recommended unless the user intends to actually use them.\n\nSTABILITY STATUS\nThe  qgroup implementation has turned out to be quite difficult as it affects the core of the\nfilesystem operation. Qgroup users have hit various corner cases over time, such as incorrect\naccounting or system instability. The situation is gradually improving and issues  found  and\nfixed.\n"
                    }
                ]
            },
            "HIERARCHICAL QUOTA GROUP CONCEPTS": {
                "content": "The  concept  of quota has a long-standing tradition in the Unix world.  Ever since computers\nallow multiple users to work simultaneously in one filesystem, there is the need  to  prevent\none  user from using up the entire space.  Every user should get his fair share of the avail‐\nable resources.\n\nIn case of files, the solution is quite straightforward.  Each file  has  an  owner  recorded\nalong  with  it,  and  it has a size.  Traditional quota just restricts the total size of all\nfiles that are owned by a user.  The concept is quite flexible: if  a  user  hits  his  quota\nlimit, the administrator can raise it on the fly.\n\nOn the other hand, the traditional approach has only a poor solution to restrict directories.\nAt  installation  time,  the  harddisk can be partitioned so that every directory (e.g. /usr,\n/var, ...) that needs a limit gets its own partition.  The obvious problem is that those lim‐\nits cannot be changed without a reinstallation.  The btrfs subvolume feature builds a bridge.\nSubvolumes correspond in many ways to partitions, as  every  subvolume  looks  like  its  own\nfilesystem.   With subvolume quota, it is now possible to restrict each subvolume like a par‐\ntition, but keep the flexibility of quota.  The space for each subvolume can be  expanded  or\nrestricted on the fly.\n\nAs  subvolumes  are the basis for snapshots, interesting questions arise as to how to account\nused space in the presence of snapshots.  If you have a file shared between a subvolume and a\nsnapshot, whom to account the file to? The creator? Both? What if the file gets  modified  in\nthe  snapshot,  should only these changes be accounted to it? But wait, both the snapshot and\nthe subvolume belong to the same user home.  I just want to limit the  total  space  used  by\nboth! But somebody else might not want to charge the snapshots to the users.\n\nBtrfs  subvolume  quota solves these problems by introducing groups of subvolumes and let the\nuser put limits on them.  It is even possible to have groups of groups.  In the following, we\nrefer to them as qgroups.\n\nEach qgroup primarily tracks two numbers, the amount of total referenced space and the amount\nof exclusively referenced space.\n",
                "subsections": [
                    {
                        "name": "referenced",
                        "content": "space is the amount of data that can be reached from any of the  subvolumes  contained\nin the qgroup, while\n"
                    },
                    {
                        "name": "exclusive",
                        "content": "is  the  amount  of  data where all references to this data can be reached from within\nthis qgroup.\n"
                    },
                    {
                        "name": "Subvolume quota groups",
                        "content": "The basic notion of the Subvolume Quota feature is the quota group,  short  qgroup.   Qgroups\nare  notated as level/id, e.g.  the qgroup 3/2 is a qgroup of level 3. For level 0, the lead‐\ning 0/ can be omitted.  Qgroups of level 0 get created automatically when  a  subvolume/snap‐\nshot  gets  created.   The ID of the qgroup corresponds to the ID of the subvolume, so 0/5 is\nthe qgroup for the root subvolume.  For the btrfs qgroup command, the path to  the  subvolume\ncan also be used instead of 0/ID.  For all higher levels, the ID can be chosen freely.\n\nEach  qgroup  can contain a set of lower level qgroups, thus creating a hierarchy of qgroups.\nFigure 1 shows an example qgroup tree.\n\n+---+\n|2/1|\n+---+\n/     \\\n+---+/       \\+---+\n|1/1|         |1/2|\n+---+         +---+\n/     \\       /     \\\n+---+/       \\+---+/       \\+---+\nqgroups     |0/1|         |0/2|         |0/3|\n+-+-+         +---+         +---+\n|          /     \\       /     \\\n|         /       \\     /       \\\n|        /         \\   /         \\\nextents       1       2            3            4\n\nFigure 1: Sample qgroup hierarchy\n\nAt the bottom, some extents are depicted showing which qgroups reference which  extents.   It\nis important to understand the notion of referenced vs exclusive.  In the example, qgroup 0/2\nreferences extents 2 and 3, while 1/2 references extents 2-4, 2/1 references all extents.\n\nOn the other hand, extent 1 is exclusive to 0/1, extent 2 is exclusive to 0/2, while extent 3\nis neither exclusive to 0/2 nor to 0/3.  But because both references can be reached from 1/2,\nextent 3 is exclusive to 1/2.  All extents are exclusive to 2/1.\n\nSo  exclusive  does not mean there is no other way to reach the extent, but it does mean that\nif you delete all subvolumes contained in a qgroup, the extent will get deleted.\n\nExclusive of a qgroup conveys the useful information how much space will be freed in case all\nsubvolumes of the qgroup get deleted.\n\nAll data extents are accounted this way.  Metadata that belongs to a specific subvolume (i.e.\nits filesystem tree) is also accounted.  Checksums and extent allocation information are  not\naccounted.\n\nIn  turn, the referenced count of a qgroup can be limited.  All writes beyond this limit will\nlead to a 'Quota Exceeded' error.\n"
                    },
                    {
                        "name": "Inheritance",
                        "content": "Things get a bit more complicated when new subvolumes or snapshots are created.  The case  of\n(empty) subvolumes is still quite easy.  If a subvolume should be part of a qgroup, it has to\nbe added to the qgroup at creation time.  To add it at a later time, it would be necessary to\nat least rescan the full subvolume for a proper accounting.\n\nCreation  of  a  snapshot is the hard case.  Obviously, the snapshot will reference the exact\namount of space as its source, and both source and destination now have an exclusive count of\n0 (the filesystem nodesize to be precise, as the roots of the trees  are  not  shared).   But\nwhat  about qgroups of higher levels? If the qgroup contains both the source and the destina‐\ntion, nothing changes.  If the qgroup contains only the source, it might lose some exclusive.\n\nBut how much? The tempting answer is, subtract all exclusive of the source from  the  qgroup,\nbut  that  is  wrong, or at least not enough.  There could have been an extent that is refer‐\nenced from the source and another subvolume from that qgroup.  This extent  would  have  been\nexclusive to the qgroup, but not to the source subvolume.  With the creation of the snapshot,\nthe qgroup would also lose this extent from its exclusive set.\n\nSo  how can this problem be solved? In the instant the snapshot gets created, we already have\nto know the correct exclusive count.  We need to have a second qgroup that contains  all  the\nsubvolumes as the first qgroup, except the subvolume we want to snapshot.  The moment we cre‐\nate  the snapshot, the exclusive count from the second qgroup needs to be copied to the first\nqgroup, as it represents the correct value.  The second qgroup is called a  tracking  qgroup.\nIt is only there in case a snapshot is needed.\n"
                    },
                    {
                        "name": "Use cases",
                        "content": "Below  are  some use cases that do not mean to be extensive. You can find your own way how to\nintegrate qgroups.\n"
                    },
                    {
                        "name": "Single-user machine",
                        "content": "Replacement for partitions.  The simplest use case is to use qgroups  as  simple  replacement\nfor partitions.  Btrfs takes the disk as a whole, and /, /usr, /var, etc. are created as sub‐\nvolumes.   As each subvolume gets it own qgroup automatically, they can simply be restricted.\nNo hierarchy is needed for that.\n\nTrack usage of snapshots.  When a snapshot is taken, a qgroup for it  will  automatically  be\ncreated  with  the  correct  values.  Referenced will show how much is in it, possibly shared\nwith other subvolumes.  Exclusive will be the amount of space that gets freed when  the  sub‐\nvolume is deleted.\n"
                    },
                    {
                        "name": "Multi-user machine",
                        "content": "Restricting  homes.  When you have several users on a machine, with home directories probably\nunder /home, you might want to restrict /home as a whole, while restricting every user to  an\nindividual  limit as well.  This is easily accomplished by creating a qgroup for /home , e.g.\n1/1, and assigning all user subvolumes to it.  Restricting  this  qgroup  will  limit  /home,\nwhile every user subvolume can get its own (lower) limit.\n\nAccounting snapshots to the user.  Let's say the user is allowed to create snapshots via some\nmechanism.   It  would only be fair to account space used by the snapshots to the user.  This\ndoes not mean the user doubles his usage as soon as he takes a snapshot.   Of  course,  files\nthat are present in his home and the snapshot should only be accounted once.  This can be ac‐\ncomplished  by  creating  a qgroup for each user, say 1/UID.  The user home and all snapshots\nare assigned to this qgroup.  Limiting it will extend the limit to  all  snapshots,  counting\nfiles  only once.  To limit /home as a whole, a higher level group 2/1 replacing 1/1 from the\nprevious example is needed, with all user qgroups assigned to it.\n\nDo not account snapshots.  On the other hand, when the snapshots get  created  automatically,\nthe  user has no chance to control them, so the space used by them should not be accounted to\nhim.  This is already the case when creating snapshots in the example from the previous  sec‐\ntion.\n\nSnapshots for backup purposes.  This scenario is a mixture of the previous two.  The user can\ncreate  snapshots,  but  some  snapshots for backup purposes are being created by the system.\nThe user's snapshots should be accounted to the user, not the system.  The solution is  simi‐\nlar  to the one from section Accounting snapshots to the user, but do not assign system snap‐\nshots to user's qgroup.\n"
                    },
                    {
                        "name": "Simple quotas (squota)",
                        "content": "As detailed in this document, qgroups can handle many complex extent  sharing  and  unsharing\nscenarios  while  maintaining  an accurate count of exclusive and shared usage. However, this\nflexibility comes at a cost: many of the computations are global, in the sense that  we  must\ncount  up  the  number  of trees referring to an extent after its references change. This can\nslow down transaction commits and lead to unacceptable latencies, especially in  cases  where\nsnapshots scale up.\n\nTo  work  around this limitation of qgroups, btrfs also supports a second set of quota seman‐\ntics: simple quotas or squotas. Squotas fully share the qgroups API and  hierarchical  model,\nbut do not track shared vs. exclusive usage. Instead, they account all extents to the subvol‐\nume  that first allocated it. With a bit of new bookkeeping, this allows all accounting deci‐\nsions to be local to the allocation or freeing operation that deals with  the  extents  them‐\nselves, and fully avoids the complex and costly back-reference resolutions.\n"
                    },
                    {
                        "name": "Example",
                        "content": "To  illustrate the difference between squotas and qgroups, consider the following basic exam‐\nple assuming a nodesize of 16KiB.\n\n1. create subvolume 256\n\n2. rack up 1GiB of data and metadata usage in 256\n\n3. snapshot 256, creating subvolume 257\n\n4. COW 512MiB of the data and metadata in 257\n\n5. delete everything in 256\n\nAt each step, qgroups would have the following accounting:\n\n1. 0/256: 16KiB excl 0 shared\n\n2. 0/256: 1GiB excl 0 shared\n\n3. 0/256: 0 excl 1GiB shared; 0/257: 0 excl 1GiB shared\n\n4. 0/256: 512MiB excl 512MiB shared; 0/257: 512MiB excl 512MiB shared\n\n5. 0/256: 16KiB excl 0 shared; 0/257: 1GiB excl 0 shared\n\nWhereas under squotas, the accounting would look like:\n\n1. 0/256: 16KiB excl 16KiB shared\n\n2. 0/256: 1GiB excl 1GiB shared\n\n3. 0/256: 1GiB excl 1GiB shared; 0/257: 16KiB excl 16KiB shared\n\n4. 0/256: 1GiB excl 1GiB shared; 0/257: 512MiB excl 512MiB shared\n\n5. 0/256: 512MiB excl 512MiB shared; 0/257: 512MiB excl 512MiB shared\n\nNote that since the original snapshotted 512MiB are still referenced by 257, they  cannot  be\nfreed from 256, even after 256 is emptied, or even deleted.\n"
                    },
                    {
                        "name": "Summary",
                        "content": "If  you  want some of power and flexibility of quotas for tracking and limiting subvolume us‐\nage, but want to avoid the performance penalty of accurately tracking extent  ownership  life\ncycles, then squotas can be a useful option.\n\nFurthermore,  squotas  is  targeted at use cases where the original extent is immutable, like\nimage snapshotting for container startup, in which case  we  avoid  these  awkward  scenarios\nwhere a subvolume is empty or deleted but still has significant extents accounted to it. How‐\never,  as long as you are aware of the accounting semantics, they can handle mutable original\nextents.\n"
                    }
                ]
            },
            "SUBCOMMAND": {
                "content": "",
                "subsections": [
                    {
                        "name": "disable <path>",
                        "content": "Disable subvolume quota support for a filesystem.\n"
                    },
                    {
                        "name": "enable [options] <path>",
                        "content": "Enable subvolume quota support for a filesystem. At this point it's possible  the  two\nmodes  of  accounting.  The  full  means  that  extent ownership by subvolumes will be\ntracked all the time, simple will account everything to the first owner. See the  sec‐\ntion for more details.\n\nOptions\n\n-s|--simple\nuse simple quotas (squotas) instead of full qgroup accounting\n"
                    },
                    {
                        "name": "rescan [options] <path>",
                        "content": "Trash all qgroup numbers and scan the metadata again with the current config.\n\nOptions\n\n-s|--status\nshow status of a running rescan operation.\n\n-w|--wait\nstart rescan and wait for it to finish (can be already in progress)\n\n-W|--wait-norescan\nwait for rescan to finish without starting it\n"
                    }
                ]
            },
            "EXIT STATUS": {
                "content": "btrfs  quota returns a zero exit status if it succeeds. Non zero is returned in case of fail‐\nure.\n",
                "subsections": []
            },
            "AVAILABILITY": {
                "content": "btrfs   is   part   of   btrfs-progs.     Please    refer    to    the    documentation    at\nhttps://btrfs.readthedocs.io.\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "btrfs-qgroup(8), btrfs-subvolume(8), mkfs.btrfs(8)\n\n\n6.6.3                                       Mar 31, 2024                              BTRFS-QUOTA(8)",
                "subsections": []
            }
        }
    }
}