LCOV - code coverage report
Current view: top level - fs/btrfs - qgroup.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 809 0.0 %
Date: 2014-02-18 Functions: 0 39 0.0 %
Branches: 0 645 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2011 STRATO.  All rights reserved.
       3                 :            :  *
       4                 :            :  * This program is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU General Public
       6                 :            :  * License v2 as published by the Free Software Foundation.
       7                 :            :  *
       8                 :            :  * This program is distributed in the hope that it will be useful,
       9                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      11                 :            :  * General Public License for more details.
      12                 :            :  *
      13                 :            :  * You should have received a copy of the GNU General Public
      14                 :            :  * License along with this program; if not, write to the
      15                 :            :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      16                 :            :  * Boston, MA 021110-1307, USA.
      17                 :            :  */
      18                 :            : 
      19                 :            : #include <linux/sched.h>
      20                 :            : #include <linux/pagemap.h>
      21                 :            : #include <linux/writeback.h>
      22                 :            : #include <linux/blkdev.h>
      23                 :            : #include <linux/rbtree.h>
      24                 :            : #include <linux/slab.h>
      25                 :            : #include <linux/workqueue.h>
      26                 :            : #include <linux/btrfs.h>
      27                 :            : 
      28                 :            : #include "ctree.h"
      29                 :            : #include "transaction.h"
      30                 :            : #include "disk-io.h"
      31                 :            : #include "locking.h"
      32                 :            : #include "ulist.h"
      33                 :            : #include "backref.h"
      34                 :            : #include "extent_io.h"
      35                 :            : 
      36                 :            : /* TODO XXX FIXME
      37                 :            :  *  - subvol delete -> delete when ref goes to 0? delete limits also?
      38                 :            :  *  - reorganize keys
      39                 :            :  *  - compressed
      40                 :            :  *  - sync
      41                 :            :  *  - copy also limits on subvol creation
      42                 :            :  *  - limit
      43                 :            :  *  - caches fuer ulists
      44                 :            :  *  - performance benchmarks
      45                 :            :  *  - check all ioctl parameters
      46                 :            :  */
      47                 :            : 
      48                 :            : /*
      49                 :            :  * one struct for each qgroup, organized in fs_info->qgroup_tree.
      50                 :            :  */
      51                 :            : struct btrfs_qgroup {
      52                 :            :         u64 qgroupid;
      53                 :            : 
      54                 :            :         /*
      55                 :            :          * state
      56                 :            :          */
      57                 :            :         u64 rfer;       /* referenced */
      58                 :            :         u64 rfer_cmpr;  /* referenced compressed */
      59                 :            :         u64 excl;       /* exclusive */
      60                 :            :         u64 excl_cmpr;  /* exclusive compressed */
      61                 :            : 
      62                 :            :         /*
      63                 :            :          * limits
      64                 :            :          */
      65                 :            :         u64 lim_flags;  /* which limits are set */
      66                 :            :         u64 max_rfer;
      67                 :            :         u64 max_excl;
      68                 :            :         u64 rsv_rfer;
      69                 :            :         u64 rsv_excl;
      70                 :            : 
      71                 :            :         /*
      72                 :            :          * reservation tracking
      73                 :            :          */
      74                 :            :         u64 reserved;
      75                 :            : 
      76                 :            :         /*
      77                 :            :          * lists
      78                 :            :          */
      79                 :            :         struct list_head groups;  /* groups this group is member of */
      80                 :            :         struct list_head members; /* groups that are members of this group */
      81                 :            :         struct list_head dirty;   /* dirty groups */
      82                 :            :         struct rb_node node;      /* tree of qgroups */
      83                 :            : 
      84                 :            :         /*
      85                 :            :          * temp variables for accounting operations
      86                 :            :          */
      87                 :            :         u64 tag;
      88                 :            :         u64 refcnt;
      89                 :            : };
      90                 :            : 
      91                 :            : /*
      92                 :            :  * glue structure to represent the relations between qgroups.
      93                 :            :  */
      94                 :            : struct btrfs_qgroup_list {
      95                 :            :         struct list_head next_group;
      96                 :            :         struct list_head next_member;
      97                 :            :         struct btrfs_qgroup *group;
      98                 :            :         struct btrfs_qgroup *member;
      99                 :            : };
     100                 :            : 
     101                 :            : static int
     102                 :            : qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
     103                 :            :                    int init_flags);
     104                 :            : static void qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info);
     105                 :            : 
     106                 :            : /* must be called with qgroup_ioctl_lock held */
     107                 :            : static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info,
     108                 :            :                                            u64 qgroupid)
     109                 :            : {
     110                 :            :         struct rb_node *n = fs_info->qgroup_tree.rb_node;
     111                 :            :         struct btrfs_qgroup *qgroup;
     112                 :            : 
     113 [ #  # ][ #  # ]:          0 :         while (n) {
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     114                 :          0 :                 qgroup = rb_entry(n, struct btrfs_qgroup, node);
     115 [ #  # ][ #  # ]:          0 :                 if (qgroup->qgroupid < qgroupid)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     116                 :          0 :                         n = n->rb_left;
     117 [ #  # ][ #  # ]:          0 :                 else if (qgroup->qgroupid > qgroupid)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     118                 :          0 :                         n = n->rb_right;
     119                 :            :                 else
     120                 :            :                         return qgroup;
     121                 :            :         }
     122                 :            :         return NULL;
     123                 :            : }
     124                 :            : 
     125                 :            : /* must be called with qgroup_lock held */
     126                 :          0 : static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
     127                 :            :                                           u64 qgroupid)
     128                 :            : {
     129                 :          0 :         struct rb_node **p = &fs_info->qgroup_tree.rb_node;
     130                 :            :         struct rb_node *parent = NULL;
     131                 :            :         struct btrfs_qgroup *qgroup;
     132                 :            : 
     133         [ #  # ]:          0 :         while (*p) {
     134                 :            :                 parent = *p;
     135                 :          0 :                 qgroup = rb_entry(parent, struct btrfs_qgroup, node);
     136                 :            : 
     137         [ #  # ]:          0 :                 if (qgroup->qgroupid < qgroupid)
     138                 :          0 :                         p = &(*p)->rb_left;
     139         [ #  # ]:          0 :                 else if (qgroup->qgroupid > qgroupid)
     140                 :          0 :                         p = &(*p)->rb_right;
     141                 :            :                 else
     142                 :            :                         return qgroup;
     143                 :            :         }
     144                 :            : 
     145                 :            :         qgroup = kzalloc(sizeof(*qgroup), GFP_ATOMIC);
     146         [ #  # ]:          0 :         if (!qgroup)
     147                 :            :                 return ERR_PTR(-ENOMEM);
     148                 :            : 
     149                 :          0 :         qgroup->qgroupid = qgroupid;
     150                 :          0 :         INIT_LIST_HEAD(&qgroup->groups);
     151                 :          0 :         INIT_LIST_HEAD(&qgroup->members);
     152                 :          0 :         INIT_LIST_HEAD(&qgroup->dirty);
     153                 :            : 
     154                 :          0 :         rb_link_node(&qgroup->node, parent, p);
     155                 :          0 :         rb_insert_color(&qgroup->node, &fs_info->qgroup_tree);
     156                 :            : 
     157                 :          0 :         return qgroup;
     158                 :            : }
     159                 :            : 
     160                 :          0 : static void __del_qgroup_rb(struct btrfs_qgroup *qgroup)
     161                 :            : {
     162                 :            :         struct btrfs_qgroup_list *list;
     163                 :            : 
     164                 :            :         list_del(&qgroup->dirty);
     165         [ #  # ]:          0 :         while (!list_empty(&qgroup->groups)) {
     166                 :            :                 list = list_first_entry(&qgroup->groups,
     167                 :            :                                         struct btrfs_qgroup_list, next_group);
     168                 :            :                 list_del(&list->next_group);
     169                 :            :                 list_del(&list->next_member);
     170                 :          0 :                 kfree(list);
     171                 :            :         }
     172                 :            : 
     173         [ #  # ]:          0 :         while (!list_empty(&qgroup->members)) {
     174                 :          0 :                 list = list_first_entry(&qgroup->members,
     175                 :            :                                         struct btrfs_qgroup_list, next_member);
     176                 :            :                 list_del(&list->next_group);
     177                 :            :                 list_del(&list->next_member);
     178                 :          0 :                 kfree(list);
     179                 :            :         }
     180                 :          0 :         kfree(qgroup);
     181                 :          0 : }
     182                 :            : 
     183                 :            : /* must be called with qgroup_lock held */
     184                 :          0 : static int del_qgroup_rb(struct btrfs_fs_info *fs_info, u64 qgroupid)
     185                 :            : {
     186                 :            :         struct btrfs_qgroup *qgroup = find_qgroup_rb(fs_info, qgroupid);
     187                 :            : 
     188         [ #  # ]:          0 :         if (!qgroup)
     189                 :            :                 return -ENOENT;
     190                 :            : 
     191                 :          0 :         rb_erase(&qgroup->node, &fs_info->qgroup_tree);
     192                 :          0 :         __del_qgroup_rb(qgroup);
     193                 :          0 :         return 0;
     194                 :            : }
     195                 :            : 
     196                 :            : /* must be called with qgroup_lock held */
     197                 :          0 : static int add_relation_rb(struct btrfs_fs_info *fs_info,
     198                 :            :                            u64 memberid, u64 parentid)
     199                 :            : {
     200                 :            :         struct btrfs_qgroup *member;
     201                 :            :         struct btrfs_qgroup *parent;
     202                 :            :         struct btrfs_qgroup_list *list;
     203                 :            : 
     204                 :            :         member = find_qgroup_rb(fs_info, memberid);
     205                 :            :         parent = find_qgroup_rb(fs_info, parentid);
     206         [ #  # ]:          0 :         if (!member || !parent)
     207                 :            :                 return -ENOENT;
     208                 :            : 
     209                 :            :         list = kzalloc(sizeof(*list), GFP_ATOMIC);
     210         [ #  # ]:          0 :         if (!list)
     211                 :            :                 return -ENOMEM;
     212                 :            : 
     213                 :          0 :         list->group = parent;
     214                 :          0 :         list->member = member;
     215                 :          0 :         list_add_tail(&list->next_group, &member->groups);
     216                 :          0 :         list_add_tail(&list->next_member, &parent->members);
     217                 :            : 
     218                 :          0 :         return 0;
     219                 :            : }
     220                 :            : 
     221                 :            : /* must be called with qgroup_lock held */
     222                 :          0 : static int del_relation_rb(struct btrfs_fs_info *fs_info,
     223                 :            :                            u64 memberid, u64 parentid)
     224                 :            : {
     225                 :            :         struct btrfs_qgroup *member;
     226                 :            :         struct btrfs_qgroup *parent;
     227                 :            :         struct btrfs_qgroup_list *list;
     228                 :            : 
     229                 :            :         member = find_qgroup_rb(fs_info, memberid);
     230                 :            :         parent = find_qgroup_rb(fs_info, parentid);
     231         [ #  # ]:          0 :         if (!member || !parent)
     232                 :            :                 return -ENOENT;
     233                 :            : 
     234         [ #  # ]:          0 :         list_for_each_entry(list, &member->groups, next_group) {
     235         [ #  # ]:          0 :                 if (list->group == parent) {
     236                 :            :                         list_del(&list->next_group);
     237                 :            :                         list_del(&list->next_member);
     238                 :          0 :                         kfree(list);
     239                 :          0 :                         return 0;
     240                 :            :                 }
     241                 :            :         }
     242                 :            :         return -ENOENT;
     243                 :            : }
     244                 :            : 
     245                 :            : /*
     246                 :            :  * The full config is read in one go, only called from open_ctree()
     247                 :            :  * It doesn't use any locking, as at this point we're still single-threaded
     248                 :            :  */
     249                 :          0 : int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
     250                 :            : {
     251                 :            :         struct btrfs_key key;
     252                 :            :         struct btrfs_key found_key;
     253                 :          0 :         struct btrfs_root *quota_root = fs_info->quota_root;
     254                 :            :         struct btrfs_path *path = NULL;
     255                 :            :         struct extent_buffer *l;
     256                 :            :         int slot;
     257                 :            :         int ret = 0;
     258                 :            :         u64 flags = 0;
     259                 :            :         u64 rescan_progress = 0;
     260                 :            : 
     261         [ #  # ]:          0 :         if (!fs_info->quota_enabled)
     262                 :            :                 return 0;
     263                 :            : 
     264                 :          0 :         fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
     265         [ #  # ]:          0 :         if (!fs_info->qgroup_ulist) {
     266                 :            :                 ret = -ENOMEM;
     267                 :            :                 goto out;
     268                 :            :         }
     269                 :            : 
     270                 :          0 :         path = btrfs_alloc_path();
     271         [ #  # ]:          0 :         if (!path) {
     272                 :            :                 ret = -ENOMEM;
     273                 :            :                 goto out;
     274                 :            :         }
     275                 :            : 
     276                 :            :         /* default this to quota off, in case no status key is found */
     277                 :          0 :         fs_info->qgroup_flags = 0;
     278                 :            : 
     279                 :            :         /*
     280                 :            :          * pass 1: read status, all qgroup infos and limits
     281                 :            :          */
     282                 :          0 :         key.objectid = 0;
     283                 :          0 :         key.type = 0;
     284                 :          0 :         key.offset = 0;
     285                 :          0 :         ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 1);
     286         [ #  # ]:          0 :         if (ret)
     287                 :            :                 goto out;
     288                 :            : 
     289                 :            :         while (1) {
     290                 :            :                 struct btrfs_qgroup *qgroup;
     291                 :            : 
     292                 :          0 :                 slot = path->slots[0];
     293                 :          0 :                 l = path->nodes[0];
     294                 :            :                 btrfs_item_key_to_cpu(l, &found_key, slot);
     295                 :            : 
     296         [ #  # ]:          0 :                 if (found_key.type == BTRFS_QGROUP_STATUS_KEY) {
     297                 :            :                         struct btrfs_qgroup_status_item *ptr;
     298                 :            : 
     299                 :          0 :                         ptr = btrfs_item_ptr(l, slot,
     300                 :            :                                              struct btrfs_qgroup_status_item);
     301                 :            : 
     302         [ #  # ]:          0 :                         if (btrfs_qgroup_status_version(l, ptr) !=
     303                 :            :                             BTRFS_QGROUP_STATUS_VERSION) {
     304                 :          0 :                                 printk(KERN_ERR
     305                 :            :                                  "btrfs: old qgroup version, quota disabled\n");
     306                 :          0 :                                 goto out;
     307                 :            :                         }
     308         [ #  # ]:          0 :                         if (btrfs_qgroup_status_generation(l, ptr) !=
     309                 :          0 :                             fs_info->generation) {
     310                 :            :                                 flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
     311                 :          0 :                                 printk(KERN_ERR
     312                 :            :                                         "btrfs: qgroup generation mismatch, "
     313                 :            :                                         "marked as inconsistent\n");
     314                 :            :                         }
     315                 :          0 :                         fs_info->qgroup_flags = btrfs_qgroup_status_flags(l,
     316                 :            :                                                                           ptr);
     317                 :            :                         rescan_progress = btrfs_qgroup_status_rescan(l, ptr);
     318                 :          0 :                         goto next1;
     319                 :            :                 }
     320                 :            : 
     321         [ #  # ]:          0 :                 if (found_key.type != BTRFS_QGROUP_INFO_KEY &&
     322                 :            :                     found_key.type != BTRFS_QGROUP_LIMIT_KEY)
     323                 :            :                         goto next1;
     324                 :            : 
     325                 :            :                 qgroup = find_qgroup_rb(fs_info, found_key.offset);
     326 [ #  # ][ #  # ]:          0 :                 if ((qgroup && found_key.type == BTRFS_QGROUP_INFO_KEY) ||
                 [ #  # ]
     327         [ #  # ]:          0 :                     (!qgroup && found_key.type == BTRFS_QGROUP_LIMIT_KEY)) {
     328                 :          0 :                         printk(KERN_ERR "btrfs: inconsitent qgroup config\n");
     329                 :            :                         flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
     330                 :            :                 }
     331         [ #  # ]:          0 :                 if (!qgroup) {
     332                 :          0 :                         qgroup = add_qgroup_rb(fs_info, found_key.offset);
     333         [ #  # ]:          0 :                         if (IS_ERR(qgroup)) {
     334                 :            :                                 ret = PTR_ERR(qgroup);
     335                 :          0 :                                 goto out;
     336                 :            :                         }
     337                 :            :                 }
     338      [ #  #  # ]:          0 :                 switch (found_key.type) {
     339                 :            :                 case BTRFS_QGROUP_INFO_KEY: {
     340                 :            :                         struct btrfs_qgroup_info_item *ptr;
     341                 :            : 
     342                 :          0 :                         ptr = btrfs_item_ptr(l, slot,
     343                 :            :                                              struct btrfs_qgroup_info_item);
     344                 :          0 :                         qgroup->rfer = btrfs_qgroup_info_rfer(l, ptr);
     345                 :          0 :                         qgroup->rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
     346                 :          0 :                         qgroup->excl = btrfs_qgroup_info_excl(l, ptr);
     347                 :          0 :                         qgroup->excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
     348                 :            :                         /* generation currently unused */
     349                 :          0 :                         break;
     350                 :            :                 }
     351                 :            :                 case BTRFS_QGROUP_LIMIT_KEY: {
     352                 :            :                         struct btrfs_qgroup_limit_item *ptr;
     353                 :            : 
     354                 :          0 :                         ptr = btrfs_item_ptr(l, slot,
     355                 :            :                                              struct btrfs_qgroup_limit_item);
     356                 :          0 :                         qgroup->lim_flags = btrfs_qgroup_limit_flags(l, ptr);
     357                 :          0 :                         qgroup->max_rfer = btrfs_qgroup_limit_max_rfer(l, ptr);
     358                 :          0 :                         qgroup->max_excl = btrfs_qgroup_limit_max_excl(l, ptr);
     359                 :          0 :                         qgroup->rsv_rfer = btrfs_qgroup_limit_rsv_rfer(l, ptr);
     360                 :          0 :                         qgroup->rsv_excl = btrfs_qgroup_limit_rsv_excl(l, ptr);
     361                 :          0 :                         break;
     362                 :            :                 }
     363                 :            :                 }
     364                 :            : next1:
     365                 :            :                 ret = btrfs_next_item(quota_root, path);
     366         [ #  # ]:          0 :                 if (ret < 0)
     367                 :            :                         goto out;
     368         [ #  # ]:          0 :                 if (ret)
     369                 :            :                         break;
     370                 :            :         }
     371                 :          0 :         btrfs_release_path(path);
     372                 :            : 
     373                 :            :         /*
     374                 :            :          * pass 2: read all qgroup relations
     375                 :            :          */
     376                 :          0 :         key.objectid = 0;
     377                 :          0 :         key.type = BTRFS_QGROUP_RELATION_KEY;
     378                 :          0 :         key.offset = 0;
     379                 :          0 :         ret = btrfs_search_slot_for_read(quota_root, &key, path, 1, 0);
     380         [ #  # ]:          0 :         if (ret)
     381                 :            :                 goto out;
     382                 :            :         while (1) {
     383                 :          0 :                 slot = path->slots[0];
     384                 :          0 :                 l = path->nodes[0];
     385                 :            :                 btrfs_item_key_to_cpu(l, &found_key, slot);
     386                 :            : 
     387         [ #  # ]:          0 :                 if (found_key.type != BTRFS_QGROUP_RELATION_KEY)
     388                 :            :                         goto next2;
     389                 :            : 
     390         [ #  # ]:          0 :                 if (found_key.objectid > found_key.offset) {
     391                 :            :                         /* parent <- member, not needed to build config */
     392                 :            :                         /* FIXME should we omit the key completely? */
     393                 :            :                         goto next2;
     394                 :            :                 }
     395                 :            : 
     396                 :          0 :                 ret = add_relation_rb(fs_info, found_key.objectid,
     397                 :            :                                       found_key.offset);
     398         [ #  # ]:          0 :                 if (ret == -ENOENT) {
     399                 :          0 :                         printk(KERN_WARNING
     400                 :            :                                 "btrfs: orphan qgroup relation 0x%llx->0x%llx\n",
     401                 :            :                                 found_key.objectid, found_key.offset);
     402                 :            :                         ret = 0;        /* ignore the error */
     403                 :            :                 }
     404         [ #  # ]:          0 :                 if (ret)
     405                 :            :                         goto out;
     406                 :            : next2:
     407                 :            :                 ret = btrfs_next_item(quota_root, path);
     408         [ #  # ]:          0 :                 if (ret < 0)
     409                 :            :                         goto out;
     410         [ #  # ]:          0 :                 if (ret)
     411                 :            :                         break;
     412                 :            :         }
     413                 :            : out:
     414                 :          0 :         fs_info->qgroup_flags |= flags;
     415         [ #  # ]:          0 :         if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON)) {
     416                 :          0 :                 fs_info->quota_enabled = 0;
     417                 :          0 :                 fs_info->pending_quota_state = 0;
     418 [ #  # ][ #  # ]:          0 :         } else if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN &&
     419                 :            :                    ret >= 0) {
     420                 :          0 :                 ret = qgroup_rescan_init(fs_info, rescan_progress, 0);
     421                 :            :         }
     422                 :          0 :         btrfs_free_path(path);
     423                 :            : 
     424         [ #  # ]:          0 :         if (ret < 0) {
     425                 :          0 :                 ulist_free(fs_info->qgroup_ulist);
     426                 :          0 :                 fs_info->qgroup_ulist = NULL;
     427                 :          0 :                 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
     428                 :            :         }
     429                 :            : 
     430                 :          0 :         return ret < 0 ? ret : 0;
     431                 :            : }
     432                 :            : 
     433                 :            : /*
     434                 :            :  * This is called from close_ctree() or open_ctree() or btrfs_quota_disable(),
     435                 :            :  * first two are in single-threaded paths.And for the third one, we have set
     436                 :            :  * quota_root to be null with qgroup_lock held before, so it is safe to clean
     437                 :            :  * up the in-memory structures without qgroup_lock held.
     438                 :            :  */
     439                 :          0 : void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info)
     440                 :            : {
     441                 :            :         struct rb_node *n;
     442                 :            :         struct btrfs_qgroup *qgroup;
     443                 :            : 
     444         [ #  # ]:          0 :         while ((n = rb_first(&fs_info->qgroup_tree))) {
     445                 :          0 :                 qgroup = rb_entry(n, struct btrfs_qgroup, node);
     446                 :          0 :                 rb_erase(n, &fs_info->qgroup_tree);
     447                 :          0 :                 __del_qgroup_rb(qgroup);
     448                 :            :         }
     449                 :            :         /*
     450                 :            :          * we call btrfs_free_qgroup_config() when umounting
     451                 :            :          * filesystem and disabling quota, so we set qgroup_ulit
     452                 :            :          * to be null here to avoid double free.
     453                 :            :          */
     454                 :          0 :         ulist_free(fs_info->qgroup_ulist);
     455                 :          0 :         fs_info->qgroup_ulist = NULL;
     456                 :          0 : }
     457                 :            : 
     458                 :          0 : static int add_qgroup_relation_item(struct btrfs_trans_handle *trans,
     459                 :            :                                     struct btrfs_root *quota_root,
     460                 :            :                                     u64 src, u64 dst)
     461                 :            : {
     462                 :            :         int ret;
     463                 :            :         struct btrfs_path *path;
     464                 :            :         struct btrfs_key key;
     465                 :            : 
     466                 :          0 :         path = btrfs_alloc_path();
     467         [ #  # ]:          0 :         if (!path)
     468                 :            :                 return -ENOMEM;
     469                 :            : 
     470                 :          0 :         key.objectid = src;
     471                 :          0 :         key.type = BTRFS_QGROUP_RELATION_KEY;
     472                 :          0 :         key.offset = dst;
     473                 :            : 
     474                 :            :         ret = btrfs_insert_empty_item(trans, quota_root, path, &key, 0);
     475                 :            : 
     476                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     477                 :            : 
     478                 :          0 :         btrfs_free_path(path);
     479                 :          0 :         return ret;
     480                 :            : }
     481                 :            : 
     482                 :          0 : static int del_qgroup_relation_item(struct btrfs_trans_handle *trans,
     483                 :            :                                     struct btrfs_root *quota_root,
     484                 :            :                                     u64 src, u64 dst)
     485                 :            : {
     486                 :            :         int ret;
     487                 :            :         struct btrfs_path *path;
     488                 :            :         struct btrfs_key key;
     489                 :            : 
     490                 :          0 :         path = btrfs_alloc_path();
     491         [ #  # ]:          0 :         if (!path)
     492                 :            :                 return -ENOMEM;
     493                 :            : 
     494                 :          0 :         key.objectid = src;
     495                 :          0 :         key.type = BTRFS_QGROUP_RELATION_KEY;
     496                 :          0 :         key.offset = dst;
     497                 :            : 
     498                 :          0 :         ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
     499         [ #  # ]:          0 :         if (ret < 0)
     500                 :            :                 goto out;
     501                 :            : 
     502         [ #  # ]:          0 :         if (ret > 0) {
     503                 :            :                 ret = -ENOENT;
     504                 :            :                 goto out;
     505                 :            :         }
     506                 :            : 
     507                 :            :         ret = btrfs_del_item(trans, quota_root, path);
     508                 :            : out:
     509                 :          0 :         btrfs_free_path(path);
     510                 :          0 :         return ret;
     511                 :            : }
     512                 :            : 
     513                 :          0 : static int add_qgroup_item(struct btrfs_trans_handle *trans,
     514                 :            :                            struct btrfs_root *quota_root, u64 qgroupid)
     515                 :            : {
     516                 :            :         int ret;
     517                 :            :         struct btrfs_path *path;
     518                 :            :         struct btrfs_qgroup_info_item *qgroup_info;
     519                 :            :         struct btrfs_qgroup_limit_item *qgroup_limit;
     520                 :            :         struct extent_buffer *leaf;
     521                 :            :         struct btrfs_key key;
     522                 :            : 
     523                 :          0 :         path = btrfs_alloc_path();
     524         [ #  # ]:          0 :         if (!path)
     525                 :            :                 return -ENOMEM;
     526                 :            : 
     527                 :          0 :         key.objectid = 0;
     528                 :          0 :         key.type = BTRFS_QGROUP_INFO_KEY;
     529                 :          0 :         key.offset = qgroupid;
     530                 :            : 
     531                 :            :         ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
     532                 :            :                                       sizeof(*qgroup_info));
     533         [ #  # ]:          0 :         if (ret)
     534                 :            :                 goto out;
     535                 :            : 
     536                 :          0 :         leaf = path->nodes[0];
     537                 :          0 :         qgroup_info = btrfs_item_ptr(leaf, path->slots[0],
     538                 :            :                                  struct btrfs_qgroup_info_item);
     539                 :          0 :         btrfs_set_qgroup_info_generation(leaf, qgroup_info, trans->transid);
     540                 :            :         btrfs_set_qgroup_info_rfer(leaf, qgroup_info, 0);
     541                 :            :         btrfs_set_qgroup_info_rfer_cmpr(leaf, qgroup_info, 0);
     542                 :            :         btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
     543                 :            :         btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0);
     544                 :            : 
     545                 :          0 :         btrfs_mark_buffer_dirty(leaf);
     546                 :            : 
     547                 :          0 :         btrfs_release_path(path);
     548                 :            : 
     549                 :          0 :         key.type = BTRFS_QGROUP_LIMIT_KEY;
     550                 :            :         ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
     551                 :            :                                       sizeof(*qgroup_limit));
     552         [ #  # ]:          0 :         if (ret)
     553                 :            :                 goto out;
     554                 :            : 
     555                 :          0 :         leaf = path->nodes[0];
     556                 :          0 :         qgroup_limit = btrfs_item_ptr(leaf, path->slots[0],
     557                 :            :                                   struct btrfs_qgroup_limit_item);
     558                 :            :         btrfs_set_qgroup_limit_flags(leaf, qgroup_limit, 0);
     559                 :            :         btrfs_set_qgroup_limit_max_rfer(leaf, qgroup_limit, 0);
     560                 :            :         btrfs_set_qgroup_limit_max_excl(leaf, qgroup_limit, 0);
     561                 :            :         btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0);
     562                 :            :         btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0);
     563                 :            : 
     564                 :          0 :         btrfs_mark_buffer_dirty(leaf);
     565                 :            : 
     566                 :            :         ret = 0;
     567                 :            : out:
     568                 :          0 :         btrfs_free_path(path);
     569                 :          0 :         return ret;
     570                 :            : }
     571                 :            : 
     572                 :          0 : static int del_qgroup_item(struct btrfs_trans_handle *trans,
     573                 :            :                            struct btrfs_root *quota_root, u64 qgroupid)
     574                 :            : {
     575                 :            :         int ret;
     576                 :            :         struct btrfs_path *path;
     577                 :            :         struct btrfs_key key;
     578                 :            : 
     579                 :          0 :         path = btrfs_alloc_path();
     580         [ #  # ]:          0 :         if (!path)
     581                 :            :                 return -ENOMEM;
     582                 :            : 
     583                 :          0 :         key.objectid = 0;
     584                 :          0 :         key.type = BTRFS_QGROUP_INFO_KEY;
     585                 :          0 :         key.offset = qgroupid;
     586                 :          0 :         ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
     587         [ #  # ]:          0 :         if (ret < 0)
     588                 :            :                 goto out;
     589                 :            : 
     590         [ #  # ]:          0 :         if (ret > 0) {
     591                 :            :                 ret = -ENOENT;
     592                 :            :                 goto out;
     593                 :            :         }
     594                 :            : 
     595                 :            :         ret = btrfs_del_item(trans, quota_root, path);
     596         [ #  # ]:          0 :         if (ret)
     597                 :            :                 goto out;
     598                 :            : 
     599                 :          0 :         btrfs_release_path(path);
     600                 :            : 
     601                 :          0 :         key.type = BTRFS_QGROUP_LIMIT_KEY;
     602                 :          0 :         ret = btrfs_search_slot(trans, quota_root, &key, path, -1, 1);
     603         [ #  # ]:          0 :         if (ret < 0)
     604                 :            :                 goto out;
     605                 :            : 
     606         [ #  # ]:          0 :         if (ret > 0) {
     607                 :            :                 ret = -ENOENT;
     608                 :            :                 goto out;
     609                 :            :         }
     610                 :            : 
     611                 :            :         ret = btrfs_del_item(trans, quota_root, path);
     612                 :            : 
     613                 :            : out:
     614                 :          0 :         btrfs_free_path(path);
     615                 :          0 :         return ret;
     616                 :            : }
     617                 :            : 
     618                 :          0 : static int update_qgroup_limit_item(struct btrfs_trans_handle *trans,
     619                 :            :                                     struct btrfs_root *root, u64 qgroupid,
     620                 :            :                                     u64 flags, u64 max_rfer, u64 max_excl,
     621                 :            :                                     u64 rsv_rfer, u64 rsv_excl)
     622                 :            : {
     623                 :            :         struct btrfs_path *path;
     624                 :            :         struct btrfs_key key;
     625                 :            :         struct extent_buffer *l;
     626                 :            :         struct btrfs_qgroup_limit_item *qgroup_limit;
     627                 :            :         int ret;
     628                 :            :         int slot;
     629                 :            : 
     630                 :          0 :         key.objectid = 0;
     631                 :          0 :         key.type = BTRFS_QGROUP_LIMIT_KEY;
     632                 :          0 :         key.offset = qgroupid;
     633                 :            : 
     634                 :          0 :         path = btrfs_alloc_path();
     635         [ #  # ]:          0 :         if (!path)
     636                 :            :                 return -ENOMEM;
     637                 :            : 
     638                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
     639         [ #  # ]:          0 :         if (ret > 0)
     640                 :            :                 ret = -ENOENT;
     641                 :            : 
     642         [ #  # ]:          0 :         if (ret)
     643                 :            :                 goto out;
     644                 :            : 
     645                 :          0 :         l = path->nodes[0];
     646                 :            :         slot = path->slots[0];
     647                 :          0 :         qgroup_limit = btrfs_item_ptr(l, path->slots[0],
     648                 :            :                                       struct btrfs_qgroup_limit_item);
     649                 :            :         btrfs_set_qgroup_limit_flags(l, qgroup_limit, flags);
     650                 :            :         btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, max_rfer);
     651                 :            :         btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, max_excl);
     652                 :            :         btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, rsv_rfer);
     653                 :            :         btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, rsv_excl);
     654                 :            : 
     655                 :          0 :         btrfs_mark_buffer_dirty(l);
     656                 :            : 
     657                 :            : out:
     658                 :          0 :         btrfs_free_path(path);
     659                 :          0 :         return ret;
     660                 :            : }
     661                 :            : 
     662                 :          0 : static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
     663                 :            :                                    struct btrfs_root *root,
     664                 :            :                                    struct btrfs_qgroup *qgroup)
     665                 :            : {
     666                 :            :         struct btrfs_path *path;
     667                 :            :         struct btrfs_key key;
     668                 :            :         struct extent_buffer *l;
     669                 :            :         struct btrfs_qgroup_info_item *qgroup_info;
     670                 :            :         int ret;
     671                 :            :         int slot;
     672                 :            : 
     673                 :          0 :         key.objectid = 0;
     674                 :          0 :         key.type = BTRFS_QGROUP_INFO_KEY;
     675                 :          0 :         key.offset = qgroup->qgroupid;
     676                 :            : 
     677                 :          0 :         path = btrfs_alloc_path();
     678         [ #  # ]:          0 :         if (!path)
     679                 :            :                 return -ENOMEM;
     680                 :            : 
     681                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
     682         [ #  # ]:          0 :         if (ret > 0)
     683                 :            :                 ret = -ENOENT;
     684                 :            : 
     685         [ #  # ]:          0 :         if (ret)
     686                 :            :                 goto out;
     687                 :            : 
     688                 :          0 :         l = path->nodes[0];
     689                 :            :         slot = path->slots[0];
     690                 :          0 :         qgroup_info = btrfs_item_ptr(l, path->slots[0],
     691                 :            :                                  struct btrfs_qgroup_info_item);
     692                 :          0 :         btrfs_set_qgroup_info_generation(l, qgroup_info, trans->transid);
     693                 :          0 :         btrfs_set_qgroup_info_rfer(l, qgroup_info, qgroup->rfer);
     694                 :          0 :         btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, qgroup->rfer_cmpr);
     695                 :          0 :         btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl);
     696                 :          0 :         btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr);
     697                 :            : 
     698                 :          0 :         btrfs_mark_buffer_dirty(l);
     699                 :            : 
     700                 :            : out:
     701                 :          0 :         btrfs_free_path(path);
     702                 :          0 :         return ret;
     703                 :            : }
     704                 :            : 
     705                 :          0 : static int update_qgroup_status_item(struct btrfs_trans_handle *trans,
     706                 :            :                                      struct btrfs_fs_info *fs_info,
     707                 :            :                                     struct btrfs_root *root)
     708                 :            : {
     709                 :            :         struct btrfs_path *path;
     710                 :            :         struct btrfs_key key;
     711                 :            :         struct extent_buffer *l;
     712                 :            :         struct btrfs_qgroup_status_item *ptr;
     713                 :            :         int ret;
     714                 :            :         int slot;
     715                 :            : 
     716                 :          0 :         key.objectid = 0;
     717                 :          0 :         key.type = BTRFS_QGROUP_STATUS_KEY;
     718                 :          0 :         key.offset = 0;
     719                 :            : 
     720                 :          0 :         path = btrfs_alloc_path();
     721         [ #  # ]:          0 :         if (!path)
     722                 :            :                 return -ENOMEM;
     723                 :            : 
     724                 :          0 :         ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
     725         [ #  # ]:          0 :         if (ret > 0)
     726                 :            :                 ret = -ENOENT;
     727                 :            : 
     728         [ #  # ]:          0 :         if (ret)
     729                 :            :                 goto out;
     730                 :            : 
     731                 :          0 :         l = path->nodes[0];
     732                 :          0 :         slot = path->slots[0];
     733                 :          0 :         ptr = btrfs_item_ptr(l, slot, struct btrfs_qgroup_status_item);
     734                 :          0 :         btrfs_set_qgroup_status_flags(l, ptr, fs_info->qgroup_flags);
     735                 :          0 :         btrfs_set_qgroup_status_generation(l, ptr, trans->transid);
     736                 :          0 :         btrfs_set_qgroup_status_rescan(l, ptr,
     737                 :            :                                 fs_info->qgroup_rescan_progress.objectid);
     738                 :            : 
     739                 :          0 :         btrfs_mark_buffer_dirty(l);
     740                 :            : 
     741                 :            : out:
     742                 :          0 :         btrfs_free_path(path);
     743                 :            :         return ret;
     744                 :            : }
     745                 :            : 
     746                 :            : /*
     747                 :            :  * called with qgroup_lock held
     748                 :            :  */
     749                 :          0 : static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans,
     750                 :            :                                   struct btrfs_root *root)
     751                 :            : {
     752                 :            :         struct btrfs_path *path;
     753                 :            :         struct btrfs_key key;
     754                 :          0 :         struct extent_buffer *leaf = NULL;
     755                 :            :         int ret;
     756                 :            :         int nr = 0;
     757                 :            : 
     758                 :          0 :         path = btrfs_alloc_path();
     759         [ #  # ]:          0 :         if (!path)
     760                 :            :                 return -ENOMEM;
     761                 :            : 
     762                 :          0 :         path->leave_spinning = 1;
     763                 :            : 
     764                 :          0 :         key.objectid = 0;
     765                 :          0 :         key.offset = 0;
     766                 :          0 :         key.type = 0;
     767                 :            : 
     768                 :            :         while (1) {
     769                 :          0 :                 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
     770         [ #  # ]:          0 :                 if (ret < 0)
     771                 :            :                         goto out;
     772                 :          0 :                 leaf = path->nodes[0];
     773                 :          0 :                 nr = btrfs_header_nritems(leaf);
     774         [ #  # ]:          0 :                 if (!nr)
     775                 :            :                         break;
     776                 :            :                 /*
     777                 :            :                  * delete the leaf one by one
     778                 :            :                  * since the whole tree is going
     779                 :            :                  * to be deleted.
     780                 :            :                  */
     781                 :          0 :                 path->slots[0] = 0;
     782                 :          0 :                 ret = btrfs_del_items(trans, root, path, 0, nr);
     783         [ #  # ]:          0 :                 if (ret)
     784                 :            :                         goto out;
     785                 :            : 
     786                 :          0 :                 btrfs_release_path(path);
     787                 :          0 :         }
     788                 :            :         ret = 0;
     789                 :            : out:
     790                 :          0 :         root->fs_info->pending_quota_state = 0;
     791                 :          0 :         btrfs_free_path(path);
     792                 :          0 :         return ret;
     793                 :            : }
     794                 :            : 
     795                 :          0 : int btrfs_quota_enable(struct btrfs_trans_handle *trans,
     796                 :            :                        struct btrfs_fs_info *fs_info)
     797                 :            : {
     798                 :            :         struct btrfs_root *quota_root;
     799                 :          0 :         struct btrfs_root *tree_root = fs_info->tree_root;
     800                 :            :         struct btrfs_path *path = NULL;
     801                 :            :         struct btrfs_qgroup_status_item *ptr;
     802                 :            :         struct extent_buffer *leaf;
     803                 :            :         struct btrfs_key key;
     804                 :            :         struct btrfs_key found_key;
     805                 :            :         struct btrfs_qgroup *qgroup = NULL;
     806                 :            :         int ret = 0;
     807                 :            :         int slot;
     808                 :            : 
     809                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
     810         [ #  # ]:          0 :         if (fs_info->quota_root) {
     811                 :          0 :                 fs_info->pending_quota_state = 1;
     812                 :          0 :                 goto out;
     813                 :            :         }
     814                 :            : 
     815                 :          0 :         fs_info->qgroup_ulist = ulist_alloc(GFP_NOFS);
     816         [ #  # ]:          0 :         if (!fs_info->qgroup_ulist) {
     817                 :            :                 ret = -ENOMEM;
     818                 :            :                 goto out;
     819                 :            :         }
     820                 :            : 
     821                 :            :         /*
     822                 :            :          * initially create the quota tree
     823                 :            :          */
     824                 :          0 :         quota_root = btrfs_create_tree(trans, fs_info,
     825                 :            :                                        BTRFS_QUOTA_TREE_OBJECTID);
     826         [ #  # ]:          0 :         if (IS_ERR(quota_root)) {
     827                 :            :                 ret =  PTR_ERR(quota_root);
     828                 :          0 :                 goto out;
     829                 :            :         }
     830                 :            : 
     831                 :          0 :         path = btrfs_alloc_path();
     832         [ #  # ]:          0 :         if (!path) {
     833                 :            :                 ret = -ENOMEM;
     834                 :            :                 goto out_free_root;
     835                 :            :         }
     836                 :            : 
     837                 :          0 :         key.objectid = 0;
     838                 :          0 :         key.type = BTRFS_QGROUP_STATUS_KEY;
     839                 :          0 :         key.offset = 0;
     840                 :            : 
     841                 :            :         ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
     842                 :            :                                       sizeof(*ptr));
     843         [ #  # ]:          0 :         if (ret)
     844                 :            :                 goto out_free_path;
     845                 :            : 
     846                 :          0 :         leaf = path->nodes[0];
     847                 :          0 :         ptr = btrfs_item_ptr(leaf, path->slots[0],
     848                 :            :                                  struct btrfs_qgroup_status_item);
     849                 :          0 :         btrfs_set_qgroup_status_generation(leaf, ptr, trans->transid);
     850                 :            :         btrfs_set_qgroup_status_version(leaf, ptr, BTRFS_QGROUP_STATUS_VERSION);
     851                 :          0 :         fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON |
     852                 :            :                                 BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
     853                 :            :         btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags);
     854                 :            :         btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
     855                 :            : 
     856                 :          0 :         btrfs_mark_buffer_dirty(leaf);
     857                 :            : 
     858                 :          0 :         key.objectid = 0;
     859                 :          0 :         key.type = BTRFS_ROOT_REF_KEY;
     860                 :          0 :         key.offset = 0;
     861                 :            : 
     862                 :          0 :         btrfs_release_path(path);
     863                 :          0 :         ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0);
     864         [ #  # ]:          0 :         if (ret > 0)
     865                 :            :                 goto out_add_root;
     866         [ #  # ]:          0 :         if (ret < 0)
     867                 :            :                 goto out_free_path;
     868                 :            : 
     869                 :            : 
     870                 :            :         while (1) {
     871                 :          0 :                 slot = path->slots[0];
     872                 :          0 :                 leaf = path->nodes[0];
     873                 :            :                 btrfs_item_key_to_cpu(leaf, &found_key, slot);
     874                 :            : 
     875         [ #  # ]:          0 :                 if (found_key.type == BTRFS_ROOT_REF_KEY) {
     876                 :          0 :                         ret = add_qgroup_item(trans, quota_root,
     877                 :            :                                               found_key.offset);
     878         [ #  # ]:          0 :                         if (ret)
     879                 :            :                                 goto out_free_path;
     880                 :            : 
     881                 :          0 :                         qgroup = add_qgroup_rb(fs_info, found_key.offset);
     882         [ #  # ]:          0 :                         if (IS_ERR(qgroup)) {
     883                 :            :                                 ret = PTR_ERR(qgroup);
     884                 :          0 :                                 goto out_free_path;
     885                 :            :                         }
     886                 :            :                 }
     887                 :            :                 ret = btrfs_next_item(tree_root, path);
     888         [ #  # ]:          0 :                 if (ret < 0)
     889                 :            :                         goto out_free_path;
     890         [ #  # ]:          0 :                 if (ret)
     891                 :            :                         break;
     892                 :            :         }
     893                 :            : 
     894                 :            : out_add_root:
     895                 :          0 :         btrfs_release_path(path);
     896                 :          0 :         ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID);
     897         [ #  # ]:          0 :         if (ret)
     898                 :            :                 goto out_free_path;
     899                 :            : 
     900                 :          0 :         qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID);
     901         [ #  # ]:          0 :         if (IS_ERR(qgroup)) {
     902                 :            :                 ret = PTR_ERR(qgroup);
     903                 :          0 :                 goto out_free_path;
     904                 :            :         }
     905                 :            :         spin_lock(&fs_info->qgroup_lock);
     906                 :          0 :         fs_info->quota_root = quota_root;
     907                 :          0 :         fs_info->pending_quota_state = 1;
     908                 :            :         spin_unlock(&fs_info->qgroup_lock);
     909                 :            : out_free_path:
     910                 :          0 :         btrfs_free_path(path);
     911                 :            : out_free_root:
     912         [ #  # ]:          0 :         if (ret) {
     913                 :          0 :                 free_extent_buffer(quota_root->node);
     914                 :          0 :                 free_extent_buffer(quota_root->commit_root);
     915                 :          0 :                 kfree(quota_root);
     916                 :            :         }
     917                 :            : out:
     918         [ #  # ]:          0 :         if (ret) {
     919                 :          0 :                 ulist_free(fs_info->qgroup_ulist);
     920                 :          0 :                 fs_info->qgroup_ulist = NULL;
     921                 :            :         }
     922                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
     923                 :          0 :         return ret;
     924                 :            : }
     925                 :            : 
     926                 :          0 : int btrfs_quota_disable(struct btrfs_trans_handle *trans,
     927                 :            :                         struct btrfs_fs_info *fs_info)
     928                 :            : {
     929                 :          0 :         struct btrfs_root *tree_root = fs_info->tree_root;
     930                 :            :         struct btrfs_root *quota_root;
     931                 :            :         int ret = 0;
     932                 :            : 
     933                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
     934         [ #  # ]:          0 :         if (!fs_info->quota_root)
     935                 :            :                 goto out;
     936                 :            :         spin_lock(&fs_info->qgroup_lock);
     937                 :          0 :         fs_info->quota_enabled = 0;
     938                 :          0 :         fs_info->pending_quota_state = 0;
     939                 :          0 :         quota_root = fs_info->quota_root;
     940                 :          0 :         fs_info->quota_root = NULL;
     941                 :            :         spin_unlock(&fs_info->qgroup_lock);
     942                 :            : 
     943                 :          0 :         btrfs_free_qgroup_config(fs_info);
     944                 :            : 
     945                 :          0 :         ret = btrfs_clean_quota_tree(trans, quota_root);
     946         [ #  # ]:          0 :         if (ret)
     947                 :            :                 goto out;
     948                 :            : 
     949                 :          0 :         ret = btrfs_del_root(trans, tree_root, &quota_root->root_key);
     950         [ #  # ]:          0 :         if (ret)
     951                 :            :                 goto out;
     952                 :            : 
     953                 :            :         list_del(&quota_root->dirty_list);
     954                 :            : 
     955                 :          0 :         btrfs_tree_lock(quota_root->node);
     956                 :          0 :         clean_tree_block(trans, tree_root, quota_root->node);
     957                 :          0 :         btrfs_tree_unlock(quota_root->node);
     958                 :          0 :         btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1);
     959                 :            : 
     960                 :          0 :         free_extent_buffer(quota_root->node);
     961                 :          0 :         free_extent_buffer(quota_root->commit_root);
     962                 :          0 :         kfree(quota_root);
     963                 :            : out:
     964                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
     965                 :          0 :         return ret;
     966                 :            : }
     967                 :            : 
     968                 :            : static void qgroup_dirty(struct btrfs_fs_info *fs_info,
     969                 :            :                          struct btrfs_qgroup *qgroup)
     970                 :            : {
     971 [ #  # ][ #  # ]:          0 :         if (list_empty(&qgroup->dirty))
         [ #  # ][ #  # ]
                 [ #  # ]
     972                 :          0 :                 list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
     973                 :            : }
     974                 :            : 
     975                 :          0 : int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
     976                 :          0 :                               struct btrfs_fs_info *fs_info, u64 src, u64 dst)
     977                 :            : {
     978                 :            :         struct btrfs_root *quota_root;
     979                 :            :         struct btrfs_qgroup *parent;
     980                 :            :         struct btrfs_qgroup *member;
     981                 :            :         struct btrfs_qgroup_list *list;
     982                 :            :         int ret = 0;
     983                 :            : 
     984                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
     985                 :          0 :         quota_root = fs_info->quota_root;
     986         [ #  # ]:          0 :         if (!quota_root) {
     987                 :            :                 ret = -EINVAL;
     988                 :            :                 goto out;
     989                 :            :         }
     990                 :            :         member = find_qgroup_rb(fs_info, src);
     991                 :            :         parent = find_qgroup_rb(fs_info, dst);
     992         [ #  # ]:          0 :         if (!member || !parent) {
     993                 :            :                 ret = -EINVAL;
     994                 :            :                 goto out;
     995                 :            :         }
     996                 :            : 
     997                 :            :         /* check if such qgroup relation exist firstly */
     998         [ #  # ]:          0 :         list_for_each_entry(list, &member->groups, next_group) {
     999         [ #  # ]:          0 :                 if (list->group == parent) {
    1000                 :            :                         ret = -EEXIST;
    1001                 :            :                         goto out;
    1002                 :            :                 }
    1003                 :            :         }
    1004                 :            : 
    1005                 :          0 :         ret = add_qgroup_relation_item(trans, quota_root, src, dst);
    1006         [ #  # ]:          0 :         if (ret)
    1007                 :            :                 goto out;
    1008                 :            : 
    1009                 :          0 :         ret = add_qgroup_relation_item(trans, quota_root, dst, src);
    1010         [ #  # ]:          0 :         if (ret) {
    1011                 :          0 :                 del_qgroup_relation_item(trans, quota_root, src, dst);
    1012                 :          0 :                 goto out;
    1013                 :            :         }
    1014                 :            : 
    1015                 :            :         spin_lock(&fs_info->qgroup_lock);
    1016                 :          0 :         ret = add_relation_rb(quota_root->fs_info, src, dst);
    1017                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1018                 :            : out:
    1019                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
    1020                 :          0 :         return ret;
    1021                 :            : }
    1022                 :            : 
    1023                 :          0 : int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
    1024                 :          0 :                               struct btrfs_fs_info *fs_info, u64 src, u64 dst)
    1025                 :            : {
    1026                 :            :         struct btrfs_root *quota_root;
    1027                 :            :         struct btrfs_qgroup *parent;
    1028                 :            :         struct btrfs_qgroup *member;
    1029                 :            :         struct btrfs_qgroup_list *list;
    1030                 :            :         int ret = 0;
    1031                 :            :         int err;
    1032                 :            : 
    1033                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
    1034                 :          0 :         quota_root = fs_info->quota_root;
    1035         [ #  # ]:          0 :         if (!quota_root) {
    1036                 :            :                 ret = -EINVAL;
    1037                 :            :                 goto out;
    1038                 :            :         }
    1039                 :            : 
    1040                 :            :         member = find_qgroup_rb(fs_info, src);
    1041                 :            :         parent = find_qgroup_rb(fs_info, dst);
    1042         [ #  # ]:          0 :         if (!member || !parent) {
    1043                 :            :                 ret = -EINVAL;
    1044                 :            :                 goto out;
    1045                 :            :         }
    1046                 :            : 
    1047                 :            :         /* check if such qgroup relation exist firstly */
    1048         [ #  # ]:          0 :         list_for_each_entry(list, &member->groups, next_group) {
    1049         [ #  # ]:          0 :                 if (list->group == parent)
    1050                 :            :                         goto exist;
    1051                 :            :         }
    1052                 :            :         ret = -ENOENT;
    1053                 :            :         goto out;
    1054                 :            : exist:
    1055                 :          0 :         ret = del_qgroup_relation_item(trans, quota_root, src, dst);
    1056                 :          0 :         err = del_qgroup_relation_item(trans, quota_root, dst, src);
    1057         [ #  # ]:          0 :         if (err && !ret)
    1058                 :            :                 ret = err;
    1059                 :            : 
    1060                 :            :         spin_lock(&fs_info->qgroup_lock);
    1061                 :          0 :         del_relation_rb(fs_info, src, dst);
    1062                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1063                 :            : out:
    1064                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
    1065                 :          0 :         return ret;
    1066                 :            : }
    1067                 :            : 
    1068                 :          0 : int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
    1069                 :          0 :                         struct btrfs_fs_info *fs_info, u64 qgroupid, char *name)
    1070                 :            : {
    1071                 :            :         struct btrfs_root *quota_root;
    1072                 :            :         struct btrfs_qgroup *qgroup;
    1073                 :            :         int ret = 0;
    1074                 :            : 
    1075                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
    1076                 :          0 :         quota_root = fs_info->quota_root;
    1077         [ #  # ]:          0 :         if (!quota_root) {
    1078                 :            :                 ret = -EINVAL;
    1079                 :            :                 goto out;
    1080                 :            :         }
    1081                 :            :         qgroup = find_qgroup_rb(fs_info, qgroupid);
    1082         [ #  # ]:          0 :         if (qgroup) {
    1083                 :            :                 ret = -EEXIST;
    1084                 :            :                 goto out;
    1085                 :            :         }
    1086                 :            : 
    1087                 :          0 :         ret = add_qgroup_item(trans, quota_root, qgroupid);
    1088         [ #  # ]:          0 :         if (ret)
    1089                 :            :                 goto out;
    1090                 :            : 
    1091                 :            :         spin_lock(&fs_info->qgroup_lock);
    1092                 :          0 :         qgroup = add_qgroup_rb(fs_info, qgroupid);
    1093                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1094                 :            : 
    1095         [ #  # ]:          0 :         if (IS_ERR(qgroup))
    1096                 :            :                 ret = PTR_ERR(qgroup);
    1097                 :            : out:
    1098                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
    1099                 :          0 :         return ret;
    1100                 :            : }
    1101                 :            : 
    1102                 :          0 : int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
    1103                 :          0 :                         struct btrfs_fs_info *fs_info, u64 qgroupid)
    1104                 :            : {
    1105                 :            :         struct btrfs_root *quota_root;
    1106                 :            :         struct btrfs_qgroup *qgroup;
    1107                 :            :         int ret = 0;
    1108                 :            : 
    1109                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
    1110                 :          0 :         quota_root = fs_info->quota_root;
    1111         [ #  # ]:          0 :         if (!quota_root) {
    1112                 :            :                 ret = -EINVAL;
    1113                 :            :                 goto out;
    1114                 :            :         }
    1115                 :            : 
    1116                 :            :         qgroup = find_qgroup_rb(fs_info, qgroupid);
    1117         [ #  # ]:          0 :         if (!qgroup) {
    1118                 :            :                 ret = -ENOENT;
    1119                 :            :                 goto out;
    1120                 :            :         } else {
    1121                 :            :                 /* check if there are no relations to this qgroup */
    1122 [ #  # ][ #  # ]:          0 :                 if (!list_empty(&qgroup->groups) ||
    1123                 :          0 :                     !list_empty(&qgroup->members)) {
    1124                 :            :                         ret = -EBUSY;
    1125                 :            :                         goto out;
    1126                 :            :                 }
    1127                 :            :         }
    1128                 :          0 :         ret = del_qgroup_item(trans, quota_root, qgroupid);
    1129                 :            : 
    1130                 :            :         spin_lock(&fs_info->qgroup_lock);
    1131                 :          0 :         del_qgroup_rb(quota_root->fs_info, qgroupid);
    1132                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1133                 :            : out:
    1134                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
    1135                 :          0 :         return ret;
    1136                 :            : }
    1137                 :            : 
    1138                 :          0 : int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
    1139                 :          0 :                        struct btrfs_fs_info *fs_info, u64 qgroupid,
    1140                 :            :                        struct btrfs_qgroup_limit *limit)
    1141                 :            : {
    1142                 :            :         struct btrfs_root *quota_root;
    1143                 :            :         struct btrfs_qgroup *qgroup;
    1144                 :            :         int ret = 0;
    1145                 :            : 
    1146                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
    1147                 :          0 :         quota_root = fs_info->quota_root;
    1148         [ #  # ]:          0 :         if (!quota_root) {
    1149                 :            :                 ret = -EINVAL;
    1150                 :            :                 goto out;
    1151                 :            :         }
    1152                 :            : 
    1153                 :            :         qgroup = find_qgroup_rb(fs_info, qgroupid);
    1154         [ #  # ]:          0 :         if (!qgroup) {
    1155                 :            :                 ret = -ENOENT;
    1156                 :            :                 goto out;
    1157                 :            :         }
    1158                 :          0 :         ret = update_qgroup_limit_item(trans, quota_root, qgroupid,
    1159                 :            :                                        limit->flags, limit->max_rfer,
    1160                 :            :                                        limit->max_excl, limit->rsv_rfer,
    1161                 :            :                                        limit->rsv_excl);
    1162         [ #  # ]:          0 :         if (ret) {
    1163                 :          0 :                 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
    1164                 :          0 :                 printk(KERN_INFO "unable to update quota limit for %llu\n",
    1165                 :            :                        qgroupid);
    1166                 :            :         }
    1167                 :            : 
    1168                 :            :         spin_lock(&fs_info->qgroup_lock);
    1169                 :          0 :         qgroup->lim_flags = limit->flags;
    1170                 :          0 :         qgroup->max_rfer = limit->max_rfer;
    1171                 :          0 :         qgroup->max_excl = limit->max_excl;
    1172                 :          0 :         qgroup->rsv_rfer = limit->rsv_rfer;
    1173                 :          0 :         qgroup->rsv_excl = limit->rsv_excl;
    1174                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1175                 :            : out:
    1176                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
    1177                 :          0 :         return ret;
    1178                 :            : }
    1179                 :            : 
    1180                 :            : /*
    1181                 :            :  * btrfs_qgroup_record_ref is called when the ref is added or deleted. it puts
    1182                 :            :  * the modification into a list that's later used by btrfs_end_transaction to
    1183                 :            :  * pass the recorded modifications on to btrfs_qgroup_account_ref.
    1184                 :            :  */
    1185                 :          0 : int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans,
    1186                 :            :                             struct btrfs_delayed_ref_node *node,
    1187                 :            :                             struct btrfs_delayed_extent_op *extent_op)
    1188                 :            : {
    1189                 :            :         struct qgroup_update *u;
    1190                 :            : 
    1191         [ #  # ]:          0 :         BUG_ON(!trans->delayed_ref_elem.seq);
    1192                 :            :         u = kmalloc(sizeof(*u), GFP_NOFS);
    1193         [ #  # ]:          0 :         if (!u)
    1194                 :            :                 return -ENOMEM;
    1195                 :            : 
    1196                 :          0 :         u->node = node;
    1197                 :          0 :         u->extent_op = extent_op;
    1198                 :          0 :         list_add_tail(&u->list, &trans->qgroup_ref_list);
    1199                 :            : 
    1200                 :          0 :         return 0;
    1201                 :            : }
    1202                 :            : 
    1203                 :          0 : static int qgroup_account_ref_step1(struct btrfs_fs_info *fs_info,
    1204                 :            :                                     struct ulist *roots, struct ulist *tmp,
    1205                 :            :                                     u64 seq)
    1206                 :            : {
    1207                 :            :         struct ulist_node *unode;
    1208                 :            :         struct ulist_iterator uiter;
    1209                 :            :         struct ulist_node *tmp_unode;
    1210                 :            :         struct ulist_iterator tmp_uiter;
    1211                 :            :         struct btrfs_qgroup *qg;
    1212                 :            :         int ret;
    1213                 :            : 
    1214                 :          0 :         ULIST_ITER_INIT(&uiter);
    1215         [ #  # ]:          0 :         while ((unode = ulist_next(roots, &uiter))) {
    1216                 :          0 :                 qg = find_qgroup_rb(fs_info, unode->val);
    1217         [ #  # ]:          0 :                 if (!qg)
    1218                 :          0 :                         continue;
    1219                 :            : 
    1220                 :          0 :                 ulist_reinit(tmp);
    1221                 :            :                                                 /* XXX id not needed */
    1222                 :          0 :                 ret = ulist_add(tmp, qg->qgroupid,
    1223                 :          0 :                                 (u64)(uintptr_t)qg, GFP_ATOMIC);
    1224         [ #  # ]:          0 :                 if (ret < 0)
    1225                 :            :                         return ret;
    1226                 :          0 :                 ULIST_ITER_INIT(&tmp_uiter);
    1227         [ #  # ]:          0 :                 while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
    1228                 :            :                         struct btrfs_qgroup_list *glist;
    1229                 :            : 
    1230                 :          0 :                         qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
    1231         [ #  # ]:          0 :                         if (qg->refcnt < seq)
    1232                 :          0 :                                 qg->refcnt = seq + 1;
    1233                 :            :                         else
    1234                 :          0 :                                 ++qg->refcnt;
    1235                 :            : 
    1236         [ #  # ]:          0 :                         list_for_each_entry(glist, &qg->groups, next_group) {
    1237                 :          0 :                                 ret = ulist_add(tmp, glist->group->qgroupid,
    1238                 :          0 :                                                 (u64)(uintptr_t)glist->group,
    1239                 :            :                                                 GFP_ATOMIC);
    1240         [ #  # ]:          0 :                                 if (ret < 0)
    1241                 :            :                                         return ret;
    1242                 :            :                         }
    1243                 :            :                 }
    1244                 :            :         }
    1245                 :            : 
    1246                 :            :         return 0;
    1247                 :            : }
    1248                 :            : 
    1249                 :          0 : static int qgroup_account_ref_step2(struct btrfs_fs_info *fs_info,
    1250                 :            :                                     struct ulist *roots, struct ulist *tmp,
    1251                 :            :                                     u64 seq, int sgn, u64 num_bytes,
    1252                 :            :                                     struct btrfs_qgroup *qgroup)
    1253                 :            : {
    1254                 :            :         struct ulist_node *unode;
    1255                 :            :         struct ulist_iterator uiter;
    1256                 :            :         struct btrfs_qgroup *qg;
    1257                 :            :         struct btrfs_qgroup_list *glist;
    1258                 :            :         int ret;
    1259                 :            : 
    1260                 :          0 :         ulist_reinit(tmp);
    1261                 :          0 :         ret = ulist_add(tmp, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
    1262         [ #  # ]:          0 :         if (ret < 0)
    1263                 :            :                 return ret;
    1264                 :            : 
    1265                 :          0 :         ULIST_ITER_INIT(&uiter);
    1266         [ #  # ]:          0 :         while ((unode = ulist_next(tmp, &uiter))) {
    1267                 :          0 :                 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
    1268         [ #  # ]:          0 :                 if (qg->refcnt < seq) {
    1269                 :            :                         /* not visited by step 1 */
    1270                 :          0 :                         qg->rfer += sgn * num_bytes;
    1271                 :          0 :                         qg->rfer_cmpr += sgn * num_bytes;
    1272         [ #  # ]:          0 :                         if (roots->nnodes == 0) {
    1273                 :          0 :                                 qg->excl += sgn * num_bytes;
    1274                 :          0 :                                 qg->excl_cmpr += sgn * num_bytes;
    1275                 :            :                         }
    1276                 :            :                         qgroup_dirty(fs_info, qg);
    1277                 :            :                 }
    1278         [ #  # ]:          0 :                 WARN_ON(qg->tag >= seq);
    1279                 :          0 :                 qg->tag = seq;
    1280                 :            : 
    1281         [ #  # ]:          0 :                 list_for_each_entry(glist, &qg->groups, next_group) {
    1282                 :          0 :                         ret = ulist_add(tmp, glist->group->qgroupid,
    1283                 :          0 :                                         (uintptr_t)glist->group, GFP_ATOMIC);
    1284         [ #  # ]:          0 :                         if (ret < 0)
    1285                 :            :                                 return ret;
    1286                 :            :                 }
    1287                 :            :         }
    1288                 :            : 
    1289                 :            :         return 0;
    1290                 :            : }
    1291                 :            : 
    1292                 :          0 : static int qgroup_account_ref_step3(struct btrfs_fs_info *fs_info,
    1293                 :            :                                     struct ulist *roots, struct ulist *tmp,
    1294                 :            :                                     u64 seq, int sgn, u64 num_bytes)
    1295                 :            : {
    1296                 :            :         struct ulist_node *unode;
    1297                 :            :         struct ulist_iterator uiter;
    1298                 :            :         struct btrfs_qgroup *qg;
    1299                 :            :         struct ulist_node *tmp_unode;
    1300                 :            :         struct ulist_iterator tmp_uiter;
    1301                 :            :         int ret;
    1302                 :            : 
    1303                 :          0 :         ULIST_ITER_INIT(&uiter);
    1304         [ #  # ]:          0 :         while ((unode = ulist_next(roots, &uiter))) {
    1305                 :          0 :                 qg = find_qgroup_rb(fs_info, unode->val);
    1306         [ #  # ]:          0 :                 if (!qg)
    1307                 :          0 :                         continue;
    1308                 :            : 
    1309                 :          0 :                 ulist_reinit(tmp);
    1310                 :          0 :                 ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg, GFP_ATOMIC);
    1311         [ #  # ]:          0 :                 if (ret < 0)
    1312                 :            :                         return ret;
    1313                 :            : 
    1314                 :          0 :                 ULIST_ITER_INIT(&tmp_uiter);
    1315         [ #  # ]:          0 :                 while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
    1316                 :            :                         struct btrfs_qgroup_list *glist;
    1317                 :            : 
    1318                 :          0 :                         qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
    1319         [ #  # ]:          0 :                         if (qg->tag == seq)
    1320                 :          0 :                                 continue;
    1321                 :            : 
    1322         [ #  # ]:          0 :                         if (qg->refcnt - seq == roots->nnodes) {
    1323                 :          0 :                                 qg->excl -= sgn * num_bytes;
    1324                 :          0 :                                 qg->excl_cmpr -= sgn * num_bytes;
    1325                 :            :                                 qgroup_dirty(fs_info, qg);
    1326                 :            :                         }
    1327                 :            : 
    1328         [ #  # ]:          0 :                         list_for_each_entry(glist, &qg->groups, next_group) {
    1329                 :          0 :                                 ret = ulist_add(tmp, glist->group->qgroupid,
    1330                 :          0 :                                                 (uintptr_t)glist->group,
    1331                 :            :                                                 GFP_ATOMIC);
    1332         [ #  # ]:          0 :                                 if (ret < 0)
    1333                 :            :                                         return ret;
    1334                 :            :                         }
    1335                 :            :                 }
    1336                 :            :         }
    1337                 :            : 
    1338                 :            :         return 0;
    1339                 :            : }
    1340                 :            : 
    1341                 :            : /*
    1342                 :            :  * btrfs_qgroup_account_ref is called for every ref that is added to or deleted
    1343                 :            :  * from the fs. First, all roots referencing the extent are searched, and
    1344                 :            :  * then the space is accounted accordingly to the different roots. The
    1345                 :            :  * accounting algorithm works in 3 steps documented inline.
    1346                 :            :  */
    1347                 :          0 : int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
    1348                 :          0 :                              struct btrfs_fs_info *fs_info,
    1349                 :            :                              struct btrfs_delayed_ref_node *node,
    1350                 :            :                              struct btrfs_delayed_extent_op *extent_op)
    1351                 :            : {
    1352                 :            :         struct btrfs_key ins;
    1353                 :            :         struct btrfs_root *quota_root;
    1354                 :            :         u64 ref_root;
    1355                 :            :         struct btrfs_qgroup *qgroup;
    1356                 :          0 :         struct ulist *roots = NULL;
    1357                 :            :         u64 seq;
    1358                 :            :         int ret = 0;
    1359                 :            :         int sgn;
    1360                 :            : 
    1361         [ #  # ]:          0 :         if (!fs_info->quota_enabled)
    1362                 :            :                 return 0;
    1363                 :            : 
    1364         [ #  # ]:          0 :         BUG_ON(!fs_info->quota_root);
    1365                 :            : 
    1366                 :            :         ins.objectid = node->bytenr;
    1367                 :            :         ins.offset = node->num_bytes;
    1368                 :            :         ins.type = BTRFS_EXTENT_ITEM_KEY;
    1369                 :            : 
    1370         [ #  # ]:          0 :         if (node->type == BTRFS_TREE_BLOCK_REF_KEY ||
    1371                 :            :             node->type == BTRFS_SHARED_BLOCK_REF_KEY) {
    1372                 :            :                 struct btrfs_delayed_tree_ref *ref;
    1373                 :            :                 ref = btrfs_delayed_node_to_tree_ref(node);
    1374                 :          0 :                 ref_root = ref->root;
    1375         [ #  # ]:          0 :         } else if (node->type == BTRFS_EXTENT_DATA_REF_KEY ||
    1376                 :            :                    node->type == BTRFS_SHARED_DATA_REF_KEY) {
    1377                 :            :                 struct btrfs_delayed_data_ref *ref;
    1378                 :            :                 ref = btrfs_delayed_node_to_data_ref(node);
    1379                 :          0 :                 ref_root = ref->root;
    1380                 :            :         } else {
    1381                 :          0 :                 BUG();
    1382                 :            :         }
    1383                 :            : 
    1384         [ #  # ]:          0 :         if (!is_fstree(ref_root)) {
    1385                 :            :                 /*
    1386                 :            :                  * non-fs-trees are not being accounted
    1387                 :            :                  */
    1388                 :            :                 return 0;
    1389                 :            :         }
    1390                 :            : 
    1391   [ #  #  #  # ]:          0 :         switch (node->action) {
    1392                 :            :         case BTRFS_ADD_DELAYED_REF:
    1393                 :            :         case BTRFS_ADD_DELAYED_EXTENT:
    1394                 :            :                 sgn = 1;
    1395                 :          0 :                 seq = btrfs_tree_mod_seq_prev(node->seq);
    1396                 :          0 :                 break;
    1397                 :            :         case BTRFS_DROP_DELAYED_REF:
    1398                 :            :                 sgn = -1;
    1399                 :          0 :                 seq = node->seq;
    1400                 :          0 :                 break;
    1401                 :            :         case BTRFS_UPDATE_DELAYED_HEAD:
    1402                 :            :                 return 0;
    1403                 :            :         default:
    1404                 :          0 :                 BUG();
    1405                 :            :         }
    1406                 :            : 
    1407                 :          0 :         mutex_lock(&fs_info->qgroup_rescan_lock);
    1408         [ #  # ]:          0 :         if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
    1409         [ #  # ]:          0 :                 if (fs_info->qgroup_rescan_progress.objectid <= node->bytenr) {
    1410                 :          0 :                         mutex_unlock(&fs_info->qgroup_rescan_lock);
    1411                 :          0 :                         return 0;
    1412                 :            :                 }
    1413                 :            :         }
    1414                 :          0 :         mutex_unlock(&fs_info->qgroup_rescan_lock);
    1415                 :            : 
    1416                 :            :         /*
    1417                 :            :          * the delayed ref sequence number we pass depends on the direction of
    1418                 :            :          * the operation. for add operations, we pass
    1419                 :            :          * tree_mod_log_prev_seq(node->seq) to skip
    1420                 :            :          * the delayed ref's current sequence number, because we need the state
    1421                 :            :          * of the tree before the add operation. for delete operations, we pass
    1422                 :            :          * (node->seq) to include the delayed ref's current sequence number,
    1423                 :            :          * because we need the state of the tree after the delete operation.
    1424                 :            :          */
    1425                 :          0 :         ret = btrfs_find_all_roots(trans, fs_info, node->bytenr, seq, &roots);
    1426         [ #  # ]:          0 :         if (ret < 0)
    1427                 :            :                 return ret;
    1428                 :            : 
    1429                 :            :         spin_lock(&fs_info->qgroup_lock);
    1430                 :            : 
    1431                 :          0 :         quota_root = fs_info->quota_root;
    1432         [ #  # ]:          0 :         if (!quota_root)
    1433                 :            :                 goto unlock;
    1434                 :            : 
    1435                 :            :         qgroup = find_qgroup_rb(fs_info, ref_root);
    1436         [ #  # ]:          0 :         if (!qgroup)
    1437                 :            :                 goto unlock;
    1438                 :            : 
    1439                 :            :         /*
    1440                 :            :          * step 1: for each old ref, visit all nodes once and inc refcnt
    1441                 :            :          */
    1442                 :          0 :         ulist_reinit(fs_info->qgroup_ulist);
    1443                 :          0 :         seq = fs_info->qgroup_seq;
    1444                 :          0 :         fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
    1445                 :            : 
    1446                 :          0 :         ret = qgroup_account_ref_step1(fs_info, roots, fs_info->qgroup_ulist,
    1447                 :            :                                        seq);
    1448         [ #  # ]:          0 :         if (ret)
    1449                 :            :                 goto unlock;
    1450                 :            : 
    1451                 :            :         /*
    1452                 :            :          * step 2: walk from the new root
    1453                 :            :          */
    1454                 :          0 :         ret = qgroup_account_ref_step2(fs_info, roots, fs_info->qgroup_ulist,
    1455                 :            :                                        seq, sgn, node->num_bytes, qgroup);
    1456         [ #  # ]:          0 :         if (ret)
    1457                 :            :                 goto unlock;
    1458                 :            : 
    1459                 :            :         /*
    1460                 :            :          * step 3: walk again from old refs
    1461                 :            :          */
    1462                 :          0 :         ret = qgroup_account_ref_step3(fs_info, roots, fs_info->qgroup_ulist,
    1463                 :            :                                        seq, sgn, node->num_bytes);
    1464                 :            :         if (ret)
    1465                 :            :                 goto unlock;
    1466                 :            : 
    1467                 :            : unlock:
    1468                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1469                 :          0 :         ulist_free(roots);
    1470                 :            : 
    1471                 :          0 :         return ret;
    1472                 :            : }
    1473                 :            : 
    1474                 :            : /*
    1475                 :            :  * called from commit_transaction. Writes all changed qgroups to disk.
    1476                 :            :  */
    1477                 :          0 : int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
    1478                 :            :                       struct btrfs_fs_info *fs_info)
    1479                 :            : {
    1480                 :          0 :         struct btrfs_root *quota_root = fs_info->quota_root;
    1481                 :            :         int ret = 0;
    1482                 :            :         int start_rescan_worker = 0;
    1483                 :            : 
    1484         [ #  # ]:          0 :         if (!quota_root)
    1485                 :            :                 goto out;
    1486                 :            : 
    1487         [ #  # ]:          0 :         if (!fs_info->quota_enabled && fs_info->pending_quota_state)
    1488                 :            :                 start_rescan_worker = 1;
    1489                 :            : 
    1490                 :          0 :         fs_info->quota_enabled = fs_info->pending_quota_state;
    1491                 :            : 
    1492                 :            :         spin_lock(&fs_info->qgroup_lock);
    1493         [ #  # ]:          0 :         while (!list_empty(&fs_info->dirty_qgroups)) {
    1494                 :            :                 struct btrfs_qgroup *qgroup;
    1495                 :          0 :                 qgroup = list_first_entry(&fs_info->dirty_qgroups,
    1496                 :            :                                           struct btrfs_qgroup, dirty);
    1497                 :          0 :                 list_del_init(&qgroup->dirty);
    1498                 :            :                 spin_unlock(&fs_info->qgroup_lock);
    1499                 :          0 :                 ret = update_qgroup_info_item(trans, quota_root, qgroup);
    1500         [ #  # ]:          0 :                 if (ret)
    1501                 :          0 :                         fs_info->qgroup_flags |=
    1502                 :            :                                         BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
    1503                 :            :                 spin_lock(&fs_info->qgroup_lock);
    1504                 :            :         }
    1505         [ #  # ]:          0 :         if (fs_info->quota_enabled)
    1506                 :          0 :                 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_ON;
    1507                 :            :         else
    1508                 :          0 :                 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
    1509                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1510                 :            : 
    1511                 :          0 :         ret = update_qgroup_status_item(trans, fs_info, quota_root);
    1512         [ #  # ]:          0 :         if (ret)
    1513                 :          0 :                 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
    1514                 :            : 
    1515         [ #  # ]:          0 :         if (!ret && start_rescan_worker) {
    1516                 :          0 :                 ret = qgroup_rescan_init(fs_info, 0, 1);
    1517         [ #  # ]:          0 :                 if (!ret) {
    1518                 :          0 :                         qgroup_rescan_zero_tracking(fs_info);
    1519                 :          0 :                         btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
    1520                 :            :                                            &fs_info->qgroup_rescan_work);
    1521                 :            :                 }
    1522                 :            :                 ret = 0;
    1523                 :            :         }
    1524                 :            : 
    1525                 :            : out:
    1526                 :            : 
    1527                 :          0 :         return ret;
    1528                 :            : }
    1529                 :            : 
    1530                 :            : /*
    1531                 :            :  * copy the acounting information between qgroups. This is necessary when a
    1532                 :            :  * snapshot or a subvolume is created
    1533                 :            :  */
    1534                 :          0 : int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
    1535                 :          0 :                          struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
    1536                 :            :                          struct btrfs_qgroup_inherit *inherit)
    1537                 :            : {
    1538                 :            :         int ret = 0;
    1539                 :            :         int i;
    1540                 :            :         u64 *i_qgroups;
    1541                 :          0 :         struct btrfs_root *quota_root = fs_info->quota_root;
    1542                 :            :         struct btrfs_qgroup *srcgroup;
    1543                 :            :         struct btrfs_qgroup *dstgroup;
    1544                 :            :         u32 level_size = 0;
    1545                 :            :         u64 nums;
    1546                 :            : 
    1547                 :          0 :         mutex_lock(&fs_info->qgroup_ioctl_lock);
    1548         [ #  # ]:          0 :         if (!fs_info->quota_enabled)
    1549                 :            :                 goto out;
    1550                 :            : 
    1551         [ #  # ]:          0 :         if (!quota_root) {
    1552                 :            :                 ret = -EINVAL;
    1553                 :            :                 goto out;
    1554                 :            :         }
    1555                 :            : 
    1556         [ #  # ]:          0 :         if (inherit) {
    1557                 :          0 :                 i_qgroups = (u64 *)(inherit + 1);
    1558                 :          0 :                 nums = inherit->num_qgroups + 2 * inherit->num_ref_copies +
    1559                 :          0 :                        2 * inherit->num_excl_copies;
    1560         [ #  # ]:          0 :                 for (i = 0; i < nums; ++i) {
    1561                 :          0 :                         srcgroup = find_qgroup_rb(fs_info, *i_qgroups);
    1562         [ #  # ]:          0 :                         if (!srcgroup) {
    1563                 :            :                                 ret = -EINVAL;
    1564                 :            :                                 goto out;
    1565                 :            :                         }
    1566                 :          0 :                         ++i_qgroups;
    1567                 :            :                 }
    1568                 :            :         }
    1569                 :            : 
    1570                 :            :         /*
    1571                 :            :          * create a tracking group for the subvol itself
    1572                 :            :          */
    1573                 :          0 :         ret = add_qgroup_item(trans, quota_root, objectid);
    1574         [ #  # ]:          0 :         if (ret)
    1575                 :            :                 goto out;
    1576                 :            : 
    1577 [ #  # ][ #  # ]:          0 :         if (inherit && inherit->flags & BTRFS_QGROUP_INHERIT_SET_LIMITS) {
    1578                 :          0 :                 ret = update_qgroup_limit_item(trans, quota_root, objectid,
    1579                 :            :                                                inherit->lim.flags,
    1580                 :            :                                                inherit->lim.max_rfer,
    1581                 :            :                                                inherit->lim.max_excl,
    1582                 :            :                                                inherit->lim.rsv_rfer,
    1583                 :            :                                                inherit->lim.rsv_excl);
    1584         [ #  # ]:          0 :                 if (ret)
    1585                 :            :                         goto out;
    1586                 :            :         }
    1587                 :            : 
    1588         [ #  # ]:          0 :         if (srcid) {
    1589                 :          0 :                 struct btrfs_root *srcroot;
    1590                 :            :                 struct btrfs_key srckey;
    1591                 :            :                 int srcroot_level;
    1592                 :            : 
    1593                 :          0 :                 srckey.objectid = srcid;
    1594                 :          0 :                 srckey.type = BTRFS_ROOT_ITEM_KEY;
    1595                 :          0 :                 srckey.offset = (u64)-1;
    1596                 :            :                 srcroot = btrfs_read_fs_root_no_name(fs_info, &srckey);
    1597         [ #  # ]:          0 :                 if (IS_ERR(srcroot)) {
    1598                 :            :                         ret = PTR_ERR(srcroot);
    1599                 :          0 :                         goto out;
    1600                 :            :                 }
    1601                 :            : 
    1602                 :            :                 rcu_read_lock();
    1603                 :          0 :                 srcroot_level = btrfs_header_level(srcroot->node);
    1604                 :            :                 level_size = btrfs_level_size(srcroot, srcroot_level);
    1605                 :            :                 rcu_read_unlock();
    1606                 :            :         }
    1607                 :            : 
    1608                 :            :         /*
    1609                 :            :          * add qgroup to all inherited groups
    1610                 :            :          */
    1611         [ #  # ]:          0 :         if (inherit) {
    1612                 :          0 :                 i_qgroups = (u64 *)(inherit + 1);
    1613         [ #  # ]:          0 :                 for (i = 0; i < inherit->num_qgroups; ++i) {
    1614                 :          0 :                         ret = add_qgroup_relation_item(trans, quota_root,
    1615                 :            :                                                        objectid, *i_qgroups);
    1616         [ #  # ]:          0 :                         if (ret)
    1617                 :            :                                 goto out;
    1618                 :          0 :                         ret = add_qgroup_relation_item(trans, quota_root,
    1619                 :            :                                                        *i_qgroups, objectid);
    1620         [ #  # ]:          0 :                         if (ret)
    1621                 :            :                                 goto out;
    1622                 :          0 :                         ++i_qgroups;
    1623                 :            :                 }
    1624                 :            :         }
    1625                 :            : 
    1626                 :            : 
    1627                 :            :         spin_lock(&fs_info->qgroup_lock);
    1628                 :            : 
    1629                 :          0 :         dstgroup = add_qgroup_rb(fs_info, objectid);
    1630         [ #  # ]:          0 :         if (IS_ERR(dstgroup)) {
    1631                 :            :                 ret = PTR_ERR(dstgroup);
    1632                 :          0 :                 goto unlock;
    1633                 :            :         }
    1634                 :            : 
    1635         [ #  # ]:          0 :         if (srcid) {
    1636                 :            :                 srcgroup = find_qgroup_rb(fs_info, srcid);
    1637         [ #  # ]:          0 :                 if (!srcgroup)
    1638                 :            :                         goto unlock;
    1639                 :          0 :                 dstgroup->rfer = srcgroup->rfer - level_size;
    1640                 :          0 :                 dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size;
    1641                 :          0 :                 srcgroup->excl = level_size;
    1642                 :          0 :                 srcgroup->excl_cmpr = level_size;
    1643                 :            :                 qgroup_dirty(fs_info, dstgroup);
    1644                 :            :                 qgroup_dirty(fs_info, srcgroup);
    1645                 :            :         }
    1646                 :            : 
    1647         [ #  # ]:          0 :         if (!inherit)
    1648                 :            :                 goto unlock;
    1649                 :            : 
    1650                 :          0 :         i_qgroups = (u64 *)(inherit + 1);
    1651         [ #  # ]:          0 :         for (i = 0; i < inherit->num_qgroups; ++i) {
    1652                 :          0 :                 ret = add_relation_rb(quota_root->fs_info, objectid,
    1653                 :            :                                       *i_qgroups);
    1654         [ #  # ]:          0 :                 if (ret)
    1655                 :            :                         goto unlock;
    1656                 :          0 :                 ++i_qgroups;
    1657                 :            :         }
    1658                 :            : 
    1659         [ #  # ]:          0 :         for (i = 0; i <  inherit->num_ref_copies; ++i) {
    1660                 :            :                 struct btrfs_qgroup *src;
    1661                 :            :                 struct btrfs_qgroup *dst;
    1662                 :            : 
    1663                 :          0 :                 src = find_qgroup_rb(fs_info, i_qgroups[0]);
    1664                 :          0 :                 dst = find_qgroup_rb(fs_info, i_qgroups[1]);
    1665                 :            : 
    1666         [ #  # ]:          0 :                 if (!src || !dst) {
    1667                 :            :                         ret = -EINVAL;
    1668                 :            :                         goto unlock;
    1669                 :            :                 }
    1670                 :            : 
    1671                 :          0 :                 dst->rfer = src->rfer - level_size;
    1672                 :          0 :                 dst->rfer_cmpr = src->rfer_cmpr - level_size;
    1673                 :          0 :                 i_qgroups += 2;
    1674                 :            :         }
    1675         [ #  # ]:          0 :         for (i = 0; i <  inherit->num_excl_copies; ++i) {
    1676                 :            :                 struct btrfs_qgroup *src;
    1677                 :            :                 struct btrfs_qgroup *dst;
    1678                 :            : 
    1679                 :          0 :                 src = find_qgroup_rb(fs_info, i_qgroups[0]);
    1680                 :          0 :                 dst = find_qgroup_rb(fs_info, i_qgroups[1]);
    1681                 :            : 
    1682         [ #  # ]:          0 :                 if (!src || !dst) {
    1683                 :            :                         ret = -EINVAL;
    1684                 :            :                         goto unlock;
    1685                 :            :                 }
    1686                 :            : 
    1687                 :          0 :                 dst->excl = src->excl + level_size;
    1688                 :          0 :                 dst->excl_cmpr = src->excl_cmpr + level_size;
    1689                 :          0 :                 i_qgroups += 2;
    1690                 :            :         }
    1691                 :            : 
    1692                 :            : unlock:
    1693                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1694                 :            : out:
    1695                 :          0 :         mutex_unlock(&fs_info->qgroup_ioctl_lock);
    1696                 :          0 :         return ret;
    1697                 :            : }
    1698                 :            : 
    1699                 :            : /*
    1700                 :            :  * reserve some space for a qgroup and all its parents. The reservation takes
    1701                 :            :  * place with start_transaction or dealloc_reserve, similar to ENOSPC
    1702                 :            :  * accounting. If not enough space is available, EDQUOT is returned.
    1703                 :            :  * We assume that the requested space is new for all qgroups.
    1704                 :            :  */
    1705                 :          0 : int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
    1706                 :            : {
    1707                 :            :         struct btrfs_root *quota_root;
    1708                 :            :         struct btrfs_qgroup *qgroup;
    1709                 :          0 :         struct btrfs_fs_info *fs_info = root->fs_info;
    1710                 :          0 :         u64 ref_root = root->root_key.objectid;
    1711                 :            :         int ret = 0;
    1712                 :            :         struct ulist_node *unode;
    1713                 :            :         struct ulist_iterator uiter;
    1714                 :            : 
    1715         [ #  # ]:          0 :         if (!is_fstree(ref_root))
    1716                 :            :                 return 0;
    1717                 :            : 
    1718         [ #  # ]:          0 :         if (num_bytes == 0)
    1719                 :            :                 return 0;
    1720                 :            : 
    1721                 :            :         spin_lock(&fs_info->qgroup_lock);
    1722                 :          0 :         quota_root = fs_info->quota_root;
    1723         [ #  # ]:          0 :         if (!quota_root)
    1724                 :            :                 goto out;
    1725                 :            : 
    1726                 :            :         qgroup = find_qgroup_rb(fs_info, ref_root);
    1727         [ #  # ]:          0 :         if (!qgroup)
    1728                 :            :                 goto out;
    1729                 :            : 
    1730                 :            :         /*
    1731                 :            :          * in a first step, we check all affected qgroups if any limits would
    1732                 :            :          * be exceeded
    1733                 :            :          */
    1734                 :          0 :         ulist_reinit(fs_info->qgroup_ulist);
    1735                 :          0 :         ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
    1736                 :          0 :                         (uintptr_t)qgroup, GFP_ATOMIC);
    1737         [ #  # ]:          0 :         if (ret < 0)
    1738                 :            :                 goto out;
    1739                 :          0 :         ULIST_ITER_INIT(&uiter);
    1740         [ #  # ]:          0 :         while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
    1741                 :            :                 struct btrfs_qgroup *qg;
    1742                 :            :                 struct btrfs_qgroup_list *glist;
    1743                 :            : 
    1744                 :          0 :                 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
    1745                 :            : 
    1746 [ #  # ][ #  # ]:          0 :                 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
    1747                 :          0 :                     qg->reserved + (s64)qg->rfer + num_bytes >
    1748                 :          0 :                     qg->max_rfer) {
    1749                 :            :                         ret = -EDQUOT;
    1750                 :            :                         goto out;
    1751                 :            :                 }
    1752                 :            : 
    1753 [ #  # ][ #  # ]:          0 :                 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
    1754                 :          0 :                     qg->reserved + (s64)qg->excl + num_bytes >
    1755                 :          0 :                     qg->max_excl) {
    1756                 :            :                         ret = -EDQUOT;
    1757                 :            :                         goto out;
    1758                 :            :                 }
    1759                 :            : 
    1760         [ #  # ]:          0 :                 list_for_each_entry(glist, &qg->groups, next_group) {
    1761                 :          0 :                         ret = ulist_add(fs_info->qgroup_ulist,
    1762                 :          0 :                                         glist->group->qgroupid,
    1763                 :          0 :                                         (uintptr_t)glist->group, GFP_ATOMIC);
    1764         [ #  # ]:          0 :                         if (ret < 0)
    1765                 :            :                                 goto out;
    1766                 :            :                 }
    1767                 :            :         }
    1768                 :            :         ret = 0;
    1769                 :            :         /*
    1770                 :            :          * no limits exceeded, now record the reservation into all qgroups
    1771                 :            :          */
    1772                 :          0 :         ULIST_ITER_INIT(&uiter);
    1773         [ #  # ]:          0 :         while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
    1774                 :            :                 struct btrfs_qgroup *qg;
    1775                 :            : 
    1776                 :          0 :                 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
    1777                 :            : 
    1778                 :          0 :                 qg->reserved += num_bytes;
    1779                 :            :         }
    1780                 :            : 
    1781                 :            : out:
    1782                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1783                 :          0 :         return ret;
    1784                 :            : }
    1785                 :            : 
    1786                 :          0 : void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
    1787                 :            : {
    1788                 :            :         struct btrfs_root *quota_root;
    1789                 :            :         struct btrfs_qgroup *qgroup;
    1790                 :          0 :         struct btrfs_fs_info *fs_info = root->fs_info;
    1791                 :            :         struct ulist_node *unode;
    1792                 :            :         struct ulist_iterator uiter;
    1793                 :          0 :         u64 ref_root = root->root_key.objectid;
    1794                 :            :         int ret = 0;
    1795                 :            : 
    1796         [ #  # ]:          0 :         if (!is_fstree(ref_root))
    1797                 :          0 :                 return;
    1798                 :            : 
    1799         [ #  # ]:          0 :         if (num_bytes == 0)
    1800                 :            :                 return;
    1801                 :            : 
    1802                 :            :         spin_lock(&fs_info->qgroup_lock);
    1803                 :            : 
    1804                 :          0 :         quota_root = fs_info->quota_root;
    1805         [ #  # ]:          0 :         if (!quota_root)
    1806                 :            :                 goto out;
    1807                 :            : 
    1808                 :            :         qgroup = find_qgroup_rb(fs_info, ref_root);
    1809         [ #  # ]:          0 :         if (!qgroup)
    1810                 :            :                 goto out;
    1811                 :            : 
    1812                 :          0 :         ulist_reinit(fs_info->qgroup_ulist);
    1813                 :          0 :         ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
    1814                 :          0 :                         (uintptr_t)qgroup, GFP_ATOMIC);
    1815         [ #  # ]:          0 :         if (ret < 0)
    1816                 :            :                 goto out;
    1817                 :          0 :         ULIST_ITER_INIT(&uiter);
    1818         [ #  # ]:          0 :         while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
    1819                 :            :                 struct btrfs_qgroup *qg;
    1820                 :            :                 struct btrfs_qgroup_list *glist;
    1821                 :            : 
    1822                 :          0 :                 qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
    1823                 :            : 
    1824                 :          0 :                 qg->reserved -= num_bytes;
    1825                 :            : 
    1826         [ #  # ]:          0 :                 list_for_each_entry(glist, &qg->groups, next_group) {
    1827                 :          0 :                         ret = ulist_add(fs_info->qgroup_ulist,
    1828                 :          0 :                                         glist->group->qgroupid,
    1829                 :          0 :                                         (uintptr_t)glist->group, GFP_ATOMIC);
    1830         [ #  # ]:          0 :                         if (ret < 0)
    1831                 :            :                                 goto out;
    1832                 :            :                 }
    1833                 :            :         }
    1834                 :            : 
    1835                 :            : out:
    1836                 :            :         spin_unlock(&fs_info->qgroup_lock);
    1837                 :            : }
    1838                 :            : 
    1839                 :          0 : void assert_qgroups_uptodate(struct btrfs_trans_handle *trans)
    1840                 :            : {
    1841 [ #  # ][ #  # ]:          0 :         if (list_empty(&trans->qgroup_ref_list) && !trans->delayed_ref_elem.seq)
    1842                 :          0 :                 return;
    1843         [ #  # ]:          0 :         pr_err("btrfs: qgroups not uptodate in trans handle %p: list is%s empty, seq is %#x.%x\n",
    1844                 :            :                 trans, list_empty(&trans->qgroup_ref_list) ? "" : " not",
    1845                 :            :                 (u32)(trans->delayed_ref_elem.seq >> 32),
    1846                 :            :                 (u32)trans->delayed_ref_elem.seq);
    1847                 :          0 :         BUG();
    1848                 :            : }
    1849                 :            : 
    1850                 :            : /*
    1851                 :            :  * returns < 0 on error, 0 when more leafs are to be scanned.
    1852                 :            :  * returns 1 when done, 2 when done and FLAG_INCONSISTENT was cleared.
    1853                 :            :  */
    1854                 :            : static int
    1855                 :          0 : qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
    1856                 :            :                    struct btrfs_trans_handle *trans, struct ulist *tmp,
    1857                 :          0 :                    struct extent_buffer *scratch_leaf)
    1858                 :            : {
    1859                 :            :         struct btrfs_key found;
    1860                 :          0 :         struct ulist *roots = NULL;
    1861                 :            :         struct ulist_node *unode;
    1862                 :            :         struct ulist_iterator uiter;
    1863                 :          0 :         struct seq_list tree_mod_seq_elem = {};
    1864                 :            :         u64 seq;
    1865                 :            :         int slot;
    1866                 :            :         int ret;
    1867                 :            : 
    1868                 :          0 :         path->leave_spinning = 1;
    1869                 :          0 :         mutex_lock(&fs_info->qgroup_rescan_lock);
    1870                 :          0 :         ret = btrfs_search_slot_for_read(fs_info->extent_root,
    1871                 :            :                                          &fs_info->qgroup_rescan_progress,
    1872                 :            :                                          path, 1, 0);
    1873                 :            : 
    1874                 :            :         pr_debug("current progress key (%llu %u %llu), search_slot ret %d\n",
    1875                 :            :                  fs_info->qgroup_rescan_progress.objectid,
    1876                 :            :                  fs_info->qgroup_rescan_progress.type,
    1877                 :            :                  fs_info->qgroup_rescan_progress.offset, ret);
    1878                 :            : 
    1879         [ #  # ]:          0 :         if (ret) {
    1880                 :            :                 /*
    1881                 :            :                  * The rescan is about to end, we will not be scanning any
    1882                 :            :                  * further blocks. We cannot unset the RESCAN flag here, because
    1883                 :            :                  * we want to commit the transaction if everything went well.
    1884                 :            :                  * To make the live accounting work in this phase, we set our
    1885                 :            :                  * scan progress pointer such that every real extent objectid
    1886                 :            :                  * will be smaller.
    1887                 :            :                  */
    1888                 :          0 :                 fs_info->qgroup_rescan_progress.objectid = (u64)-1;
    1889                 :          0 :                 btrfs_release_path(path);
    1890                 :          0 :                 mutex_unlock(&fs_info->qgroup_rescan_lock);
    1891                 :          0 :                 return ret;
    1892                 :            :         }
    1893                 :            : 
    1894                 :          0 :         btrfs_item_key_to_cpu(path->nodes[0], &found,
    1895                 :          0 :                               btrfs_header_nritems(path->nodes[0]) - 1);
    1896                 :          0 :         fs_info->qgroup_rescan_progress.objectid = found.objectid + 1;
    1897                 :            : 
    1898                 :          0 :         btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
    1899                 :          0 :         memcpy(scratch_leaf, path->nodes[0], sizeof(*scratch_leaf));
    1900                 :          0 :         slot = path->slots[0];
    1901                 :          0 :         btrfs_release_path(path);
    1902                 :          0 :         mutex_unlock(&fs_info->qgroup_rescan_lock);
    1903                 :            : 
    1904         [ #  # ]:          0 :         for (; slot < btrfs_header_nritems(scratch_leaf); ++slot) {
    1905                 :            :                 btrfs_item_key_to_cpu(scratch_leaf, &found, slot);
    1906         [ #  # ]:          0 :                 if (found.type != BTRFS_EXTENT_ITEM_KEY)
    1907                 :          0 :                         continue;
    1908                 :          0 :                 ret = btrfs_find_all_roots(trans, fs_info, found.objectid,
    1909                 :            :                                            tree_mod_seq_elem.seq, &roots);
    1910         [ #  # ]:          0 :                 if (ret < 0)
    1911                 :            :                         goto out;
    1912                 :            :                 spin_lock(&fs_info->qgroup_lock);
    1913                 :          0 :                 seq = fs_info->qgroup_seq;
    1914                 :          0 :                 fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
    1915                 :            : 
    1916                 :          0 :                 ret = qgroup_account_ref_step1(fs_info, roots, tmp, seq);
    1917         [ #  # ]:          0 :                 if (ret) {
    1918                 :            :                         spin_unlock(&fs_info->qgroup_lock);
    1919                 :          0 :                         ulist_free(roots);
    1920                 :          0 :                         goto out;
    1921                 :            :                 }
    1922                 :            : 
    1923                 :            :                 /*
    1924                 :            :                  * step2 of btrfs_qgroup_account_ref works from a single root,
    1925                 :            :                  * we're doing all at once here.
    1926                 :            :                  */
    1927                 :          0 :                 ulist_reinit(tmp);
    1928                 :          0 :                 ULIST_ITER_INIT(&uiter);
    1929         [ #  # ]:          0 :                 while ((unode = ulist_next(roots, &uiter))) {
    1930                 :            :                         struct btrfs_qgroup *qg;
    1931                 :            : 
    1932                 :          0 :                         qg = find_qgroup_rb(fs_info, unode->val);
    1933         [ #  # ]:          0 :                         if (!qg)
    1934                 :          0 :                                 continue;
    1935                 :            : 
    1936                 :          0 :                         ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg,
    1937                 :            :                                         GFP_ATOMIC);
    1938         [ #  # ]:          0 :                         if (ret < 0) {
    1939                 :            :                                 spin_unlock(&fs_info->qgroup_lock);
    1940                 :          0 :                                 ulist_free(roots);
    1941                 :          0 :                                 goto out;
    1942                 :            :                         }
    1943                 :            :                 }
    1944                 :            : 
    1945                 :            :                 /* this loop is similar to step 2 of btrfs_qgroup_account_ref */
    1946                 :          0 :                 ULIST_ITER_INIT(&uiter);
    1947         [ #  # ]:          0 :                 while ((unode = ulist_next(tmp, &uiter))) {
    1948                 :            :                         struct btrfs_qgroup *qg;
    1949                 :            :                         struct btrfs_qgroup_list *glist;
    1950                 :            : 
    1951                 :          0 :                         qg = (struct btrfs_qgroup *)(uintptr_t) unode->aux;
    1952                 :          0 :                         qg->rfer += found.offset;
    1953                 :          0 :                         qg->rfer_cmpr += found.offset;
    1954         [ #  # ]:          0 :                         WARN_ON(qg->tag >= seq);
    1955         [ #  # ]:          0 :                         if (qg->refcnt - seq == roots->nnodes) {
    1956                 :          0 :                                 qg->excl += found.offset;
    1957                 :          0 :                                 qg->excl_cmpr += found.offset;
    1958                 :            :                         }
    1959                 :            :                         qgroup_dirty(fs_info, qg);
    1960                 :            : 
    1961         [ #  # ]:          0 :                         list_for_each_entry(glist, &qg->groups, next_group) {
    1962                 :          0 :                                 ret = ulist_add(tmp, glist->group->qgroupid,
    1963                 :          0 :                                                 (uintptr_t)glist->group,
    1964                 :            :                                                 GFP_ATOMIC);
    1965         [ #  # ]:          0 :                                 if (ret < 0) {
    1966                 :            :                                         spin_unlock(&fs_info->qgroup_lock);
    1967                 :          0 :                                         ulist_free(roots);
    1968                 :          0 :                                         goto out;
    1969                 :            :                                 }
    1970                 :            :                         }
    1971                 :            :                 }
    1972                 :            : 
    1973                 :            :                 spin_unlock(&fs_info->qgroup_lock);
    1974                 :          0 :                 ulist_free(roots);
    1975                 :            :                 ret = 0;
    1976                 :            :         }
    1977                 :            : 
    1978                 :            : out:
    1979                 :          0 :         btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
    1980                 :            : 
    1981                 :          0 :         return ret;
    1982                 :            : }
    1983                 :            : 
    1984                 :          0 : static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
    1985                 :            : {
    1986                 :          0 :         struct btrfs_fs_info *fs_info = container_of(work, struct btrfs_fs_info,
    1987                 :            :                                                      qgroup_rescan_work);
    1988                 :            :         struct btrfs_path *path;
    1989                 :            :         struct btrfs_trans_handle *trans = NULL;
    1990                 :            :         struct ulist *tmp = NULL;
    1991                 :            :         struct extent_buffer *scratch_leaf = NULL;
    1992                 :            :         int err = -ENOMEM;
    1993                 :            : 
    1994                 :          0 :         path = btrfs_alloc_path();
    1995         [ #  # ]:          0 :         if (!path)
    1996                 :            :                 goto out;
    1997                 :          0 :         tmp = ulist_alloc(GFP_NOFS);
    1998         [ #  # ]:          0 :         if (!tmp)
    1999                 :            :                 goto out;
    2000                 :            :         scratch_leaf = kmalloc(sizeof(*scratch_leaf), GFP_NOFS);
    2001         [ #  # ]:          0 :         if (!scratch_leaf)
    2002                 :            :                 goto out;
    2003                 :            : 
    2004                 :            :         err = 0;
    2005         [ #  # ]:          0 :         while (!err) {
    2006                 :          0 :                 trans = btrfs_start_transaction(fs_info->fs_root, 0);
    2007         [ #  # ]:          0 :                 if (IS_ERR(trans)) {
    2008                 :            :                         err = PTR_ERR(trans);
    2009                 :          0 :                         break;
    2010                 :            :                 }
    2011         [ #  # ]:          0 :                 if (!fs_info->quota_enabled) {
    2012                 :            :                         err = -EINTR;
    2013                 :            :                 } else {
    2014                 :          0 :                         err = qgroup_rescan_leaf(fs_info, path, trans,
    2015                 :            :                                                  tmp, scratch_leaf);
    2016                 :            :                 }
    2017         [ #  # ]:          0 :                 if (err > 0)
    2018                 :          0 :                         btrfs_commit_transaction(trans, fs_info->fs_root);
    2019                 :            :                 else
    2020                 :          0 :                         btrfs_end_transaction(trans, fs_info->fs_root);
    2021                 :            :         }
    2022                 :            : 
    2023                 :            : out:
    2024                 :          0 :         kfree(scratch_leaf);
    2025                 :          0 :         ulist_free(tmp);
    2026                 :          0 :         btrfs_free_path(path);
    2027                 :            : 
    2028                 :          0 :         mutex_lock(&fs_info->qgroup_rescan_lock);
    2029                 :          0 :         fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
    2030                 :            : 
    2031 [ #  # ][ #  # ]:          0 :         if (err == 2 &&
    2032                 :          0 :             fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
    2033                 :          0 :                 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
    2034         [ #  # ]:          0 :         } else if (err < 0) {
    2035                 :          0 :                 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
    2036                 :            :         }
    2037                 :          0 :         mutex_unlock(&fs_info->qgroup_rescan_lock);
    2038                 :            : 
    2039         [ #  # ]:          0 :         if (err >= 0) {
    2040         [ #  # ]:          0 :                 pr_info("btrfs: qgroup scan completed%s\n",
    2041                 :            :                         err == 2 ? " (inconsistency flag cleared)" : "");
    2042                 :            :         } else {
    2043                 :          0 :                 pr_err("btrfs: qgroup scan failed with %d\n", err);
    2044                 :            :         }
    2045                 :            : 
    2046                 :          0 :         complete_all(&fs_info->qgroup_rescan_completion);
    2047                 :          0 : }
    2048                 :            : 
    2049                 :            : /*
    2050                 :            :  * Checks that (a) no rescan is running and (b) quota is enabled. Allocates all
    2051                 :            :  * memory required for the rescan context.
    2052                 :            :  */
    2053                 :            : static int
    2054                 :          0 : qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
    2055                 :            :                    int init_flags)
    2056                 :            : {
    2057                 :            :         int ret = 0;
    2058                 :            : 
    2059 [ #  # ][ #  # ]:          0 :         if (!init_flags &&
    2060         [ #  # ]:          0 :             (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) ||
    2061                 :          0 :              !(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))) {
    2062                 :            :                 ret = -EINVAL;
    2063                 :            :                 goto err;
    2064                 :            :         }
    2065                 :            : 
    2066                 :          0 :         mutex_lock(&fs_info->qgroup_rescan_lock);
    2067                 :            :         spin_lock(&fs_info->qgroup_lock);
    2068                 :            : 
    2069         [ #  # ]:          0 :         if (init_flags) {
    2070         [ #  # ]:          0 :                 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
    2071                 :            :                         ret = -EINPROGRESS;
    2072         [ #  # ]:          0 :                 else if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))
    2073                 :            :                         ret = -EINVAL;
    2074                 :            : 
    2075         [ #  # ]:          0 :                 if (ret) {
    2076                 :            :                         spin_unlock(&fs_info->qgroup_lock);
    2077                 :          0 :                         mutex_unlock(&fs_info->qgroup_rescan_lock);
    2078                 :          0 :                         goto err;
    2079                 :            :                 }
    2080                 :            : 
    2081                 :          0 :                 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN;
    2082                 :            :         }
    2083                 :            : 
    2084                 :          0 :         memset(&fs_info->qgroup_rescan_progress, 0,
    2085                 :            :                 sizeof(fs_info->qgroup_rescan_progress));
    2086                 :          0 :         fs_info->qgroup_rescan_progress.objectid = progress_objectid;
    2087                 :            : 
    2088                 :            :         spin_unlock(&fs_info->qgroup_lock);
    2089                 :          0 :         mutex_unlock(&fs_info->qgroup_rescan_lock);
    2090                 :            : 
    2091                 :            :         init_completion(&fs_info->qgroup_rescan_completion);
    2092                 :            : 
    2093                 :          0 :         memset(&fs_info->qgroup_rescan_work, 0,
    2094                 :            :                sizeof(fs_info->qgroup_rescan_work));
    2095                 :          0 :         fs_info->qgroup_rescan_work.func = btrfs_qgroup_rescan_worker;
    2096                 :            : 
    2097         [ #  # ]:          0 :         if (ret) {
    2098                 :            : err:
    2099                 :          0 :                 pr_info("btrfs: qgroup_rescan_init failed with %d\n", ret);
    2100                 :          0 :                 return ret;
    2101                 :            :         }
    2102                 :            : 
    2103                 :            :         return 0;
    2104                 :            : }
    2105                 :            : 
    2106                 :            : static void
    2107                 :          0 : qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info)
    2108                 :            : {
    2109                 :            :         struct rb_node *n;
    2110                 :            :         struct btrfs_qgroup *qgroup;
    2111                 :            : 
    2112                 :            :         spin_lock(&fs_info->qgroup_lock);
    2113                 :            :         /* clear all current qgroup tracking information */
    2114         [ #  # ]:          0 :         for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) {
    2115                 :            :                 qgroup = rb_entry(n, struct btrfs_qgroup, node);
    2116                 :          0 :                 qgroup->rfer = 0;
    2117                 :          0 :                 qgroup->rfer_cmpr = 0;
    2118                 :          0 :                 qgroup->excl = 0;
    2119                 :          0 :                 qgroup->excl_cmpr = 0;
    2120                 :            :         }
    2121                 :            :         spin_unlock(&fs_info->qgroup_lock);
    2122                 :          0 : }
    2123                 :            : 
    2124                 :            : int
    2125                 :          0 : btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
    2126                 :            : {
    2127                 :            :         int ret = 0;
    2128                 :            :         struct btrfs_trans_handle *trans;
    2129                 :            : 
    2130                 :          0 :         ret = qgroup_rescan_init(fs_info, 0, 1);
    2131         [ #  # ]:          0 :         if (ret)
    2132                 :            :                 return ret;
    2133                 :            : 
    2134                 :            :         /*
    2135                 :            :          * We have set the rescan_progress to 0, which means no more
    2136                 :            :          * delayed refs will be accounted by btrfs_qgroup_account_ref.
    2137                 :            :          * However, btrfs_qgroup_account_ref may be right after its call
    2138                 :            :          * to btrfs_find_all_roots, in which case it would still do the
    2139                 :            :          * accounting.
    2140                 :            :          * To solve this, we're committing the transaction, which will
    2141                 :            :          * ensure we run all delayed refs and only after that, we are
    2142                 :            :          * going to clear all tracking information for a clean start.
    2143                 :            :          */
    2144                 :            : 
    2145                 :          0 :         trans = btrfs_join_transaction(fs_info->fs_root);
    2146         [ #  # ]:          0 :         if (IS_ERR(trans)) {
    2147                 :          0 :                 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
    2148                 :          0 :                 return PTR_ERR(trans);
    2149                 :            :         }
    2150                 :          0 :         ret = btrfs_commit_transaction(trans, fs_info->fs_root);
    2151         [ #  # ]:          0 :         if (ret) {
    2152                 :          0 :                 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
    2153                 :          0 :                 return ret;
    2154                 :            :         }
    2155                 :            : 
    2156                 :          0 :         qgroup_rescan_zero_tracking(fs_info);
    2157                 :            : 
    2158                 :          0 :         btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
    2159                 :            :                            &fs_info->qgroup_rescan_work);
    2160                 :            : 
    2161                 :          0 :         return 0;
    2162                 :            : }
    2163                 :            : 
    2164                 :          0 : int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info)
    2165                 :            : {
    2166                 :            :         int running;
    2167                 :            :         int ret = 0;
    2168                 :            : 
    2169                 :          0 :         mutex_lock(&fs_info->qgroup_rescan_lock);
    2170                 :            :         spin_lock(&fs_info->qgroup_lock);
    2171                 :          0 :         running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN;
    2172                 :            :         spin_unlock(&fs_info->qgroup_lock);
    2173                 :          0 :         mutex_unlock(&fs_info->qgroup_rescan_lock);
    2174                 :            : 
    2175         [ #  # ]:          0 :         if (running)
    2176                 :          0 :                 ret = wait_for_completion_interruptible(
    2177                 :            :                                         &fs_info->qgroup_rescan_completion);
    2178                 :            : 
    2179                 :          0 :         return ret;
    2180                 :            : }
    2181                 :            : 
    2182                 :            : /*
    2183                 :            :  * this is only called from open_ctree where we're still single threaded, thus
    2184                 :            :  * locking is omitted here.
    2185                 :            :  */
    2186                 :            : void
    2187                 :          0 : btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info)
    2188                 :            : {
    2189         [ #  # ]:          0 :         if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
    2190                 :          0 :                 btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
    2191                 :            :                                    &fs_info->qgroup_rescan_work);
    2192                 :          0 : }

Generated by: LCOV version 1.9