linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* re: btrfs: qgroup: account shared subtrees during snapshot delete
@ 2015-02-01 20:51 Dan Carpenter
  2015-02-06 22:16 ` Mark Fasheh
  0 siblings, 1 reply; 12+ messages in thread
From: Dan Carpenter @ 2015-02-01 20:51 UTC (permalink / raw)
  To: mfasheh; +Cc: linux-btrfs

Hello Mark Fasheh,

The patch 1152651a0817: "btrfs: qgroup: account shared subtrees
during snapshot delete" from Jul 17, 2014, leads to the following
static checker warning:

	fs/btrfs/extent-tree.c:7642 account_shared_subtree()
	error: off-by-one overflow 'path->nodes' size 8.  index range = '1-8'

fs/btrfs/extent-tree.c
  7611          BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL);

At first I thought that I could just change this > to >= to fix this
warning.

  7612          BUG_ON(root_eb == NULL);
  7613  
  7614          if (!root->fs_info->quota_enabled)
  7615                  return 0;
  7616  
  7617          if (!extent_buffer_uptodate(root_eb)) {
  7618                  ret = btrfs_read_buffer(root_eb, root_gen);
  7619                  if (ret)
  7620                          goto out;
  7621          }
  7622  
  7623          if (root_level == 0) {
  7624                  ret = account_leaf_items(trans, root, root_eb);
  7625                  goto out;
  7626          }
  7627  
  7628          path = btrfs_alloc_path();
  7629          if (!path)
  7630                  return -ENOMEM;
  7631  
  7632          /*
  7633           * Walk down the tree.  Missing extent blocks are filled in as
  7634           * we go. Metadata is accounted every time we read a new
  7635           * extent block.
  7636           *
  7637           * When we reach a leaf, we account for file extent items in it,
  7638           * walk back up the tree (adjusting slot pointers as we go)
  7639           * and restart the search process.
  7640           */
  7641          extent_buffer_get(root_eb); /* For path */
  7642          path->nodes[root_level] = root_eb;

->nodes[] has BTRFS_MAX_LEVEL elements.

  7643          path->slots[root_level] = 0;
  7644          path->locks[root_level] = 0; /* so release_path doesn't try to unlock */
  7645  walk_down:
  7646          level = root_level;
  7647          while (level >= 0) {
  7648                  if (path->nodes[level] == NULL) {
  7649                          int parent_slot;
  7650                          u64 child_gen;
  7651                          u64 child_bytenr;
  7652  
  7653                          /* We need to get child blockptr/gen from
  7654                           * parent before we can read it. */
  7655                          eb = path->nodes[level + 1];
                                         ^^^^^^^^^^^^^^^^^^
But when I changed that, then it introduced a warning here because we
add one.  I'm not sure what to do.

  7656                          parent_slot = path->slots[level + 1];
  7657                          child_bytenr = btrfs_node_blockptr(eb, parent_slot);
  7658                          child_gen = btrfs_node_ptr_generation(eb, parent_slot);
  7659  
  7660                          eb = read_tree_block(root, child_bytenr, child_gen);
  7661                          if (!eb || !extent_buffer_uptodate(eb)) {
  7662                                  ret = -EIO;
  7663                                  goto out;
  7664                          }
  7665  
  7666                          path->nodes[level] = eb;
  7667                          path->slots[level] = 0;
  7668  

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 12+ messages in thread
* [PATCH 0/3] btrfs: qgroup fixes for btrfs_drop_snapshot V3
@ 2014-07-07 22:09 Mark Fasheh
  2014-07-07 22:09 ` btrfs: qgroup: account shared subtrees during snapshot delete Mark Fasheh
  0 siblings, 1 reply; 12+ messages in thread
From: Mark Fasheh @ 2014-07-07 22:09 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Chris Mason, Josef Bacik, Mark Fasheh

Hi, the following patches try to fix a long outstanding issue with qgroups
and snapshot deletion. The core problem is that btrfs_drop_snapshot will
skip shared extents during it's tree walk. This results in an inconsistent
qgroup state once the drop is processed.

The first patch adds some tracing which I found very useful in debugging
qgroup operations. The second patch is an actual fix to the problem. A third
patch, from Josef is also added. We need this because it fixes at least one
set of inconsistencies qgroups can get to via drop_snapshot.

With this version of the patch series, I can no longer reproduce
qgroup inconsistencies via drop_snapshot on my test disks.

Changes from last patch set:

- search on bytenr and root, but not seq in btrfs_record_ref when
  we're looking for existing qgroup operations.

Changes before that (V1-V2):

- remove extra extent_buffer_uptodate call from account_shared_subtree()

- catch return values for the accounting calls now and do the right thing
  (log an error and tell the user to rescan)

- remove the loop on roots in qgroup_subtree_accounting and just use the
  nnodes member to make our first decision.

- Don't queue up the subtree root for a change (the code in drop_snapshot
  handkles qgroup updates for this block).

- only walk subtrees if we're actually in DROP_REFERENCE stage and we're
  going to call free_extent

- account leaf items for level zero blocks that we are dropping in
  walk_up_proc


General qgroups TODO:

- We need an xfstest for the drop_snapshot case, otherwise I'm
  concerned that we can easily regress from bugs introduced via
  seemingly unrelated patches. This stuff can be fragile.
   - I already have a script that creates and removes a level 1 tree to
     introduce an inconsistency. I think adapting that is probably a good
     first step. The script can be found at:

     http://zeniv.linux.org.uk/~mfasheh/create-btrfs-trees.sh

     Please don't make fun of my poor shell scripting skills  :)

- qgroup items are not deleted after drop_snapshot. They stay orphaned, on
  disk, often with nonzero values in their count fields. This is something
  for another patch. Josef and I have some ideas for how to deal with this:
   - Just zero them out at the end of drop_snapshot (maybe in the future we
     could actually then delete them from disk?)
   - update btrfs_subtree_accounting() to remove bytes from the
     being-deleted qgroups so they wind up as zero on disk (this is
     preferable but might not be practical)

- we need at least a rescan to be kicked off when adding parent qgroups.
  otherwise, the newly added groups start with the wrong information. Quite
  possible the rescan itself might need to be updated (I haven't tested this
  enough).

- qgroup heirarchies in general don't seem quite implemented yet. Once we
  fix the previous items the code to update their counts for them will
  probably need some love.

Please review, thanks. Diffstat follows,
	--Mark

 fs/btrfs/ctree.c             |   20 +--
 fs/btrfs/ctree.h             |    4 
 fs/btrfs/extent-tree.c       |  285 +++++++++++++++++++++++++++++++++++++++++--
 fs/btrfs/qgroup.c            |  168 +++++++++++++++++++++++++
 fs/btrfs/qgroup.h            |    1 
 fs/btrfs/super.c             |    1 
 include/trace/events/btrfs.h |   57 ++++++++
 7 files changed, 511 insertions(+), 25 deletions(-)

^ permalink raw reply	[flat|nested] 12+ messages in thread
* [PATCH 0/2] btrfs: qgroup fixes for btrfs_drop_snapshot
@ 2014-06-19 21:49 Mark Fasheh
  2014-06-19 21:49 ` btrfs: qgroup: account shared subtrees during snapshot delete Mark Fasheh
  0 siblings, 1 reply; 12+ messages in thread
From: Mark Fasheh @ 2014-06-19 21:49 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Chris Mason, Josef Bacik, Mark Fasheh

Hi, the following patches try to fix a long outstanding issue with qgroups
and snapshot deletion. The core problem is that btrfs_drop_snapshot will
skip shared extents during it's tree walk. This results in an inconsistent
qgroup state once the drop is processed.

The first patch adds some tracing which I found very useful in debugging
qgroup operations. The second patch is an actual fix to the problem.

Even with this patch series, we still have some inconsistency in qgroups
when a snapshot is deleted.  As far as I can tell this is because shared
subtree roots are not completely skipped and may get passed to the qgroup
subsystem via a number of ref operations that happen during drop snapshot. 
I am working on a fix for that issue, but feel that what I have here gets us
90% of the way to a full fix.

Please review, thanks. Diffstat follows,
	--Mark

 fs/btrfs/extent-tree.c       |  234 +++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/qgroup.c            |  169 +++++++++++++++++++++++++++++--
 fs/btrfs/qgroup.h            |    1 
 fs/btrfs/super.c             |    1 
 include/trace/events/btrfs.h |   57 ++++++++++
 5 files changed, 456 insertions(+), 6 deletions(-)

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-02-06 22:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-01 20:51 btrfs: qgroup: account shared subtrees during snapshot delete Dan Carpenter
2015-02-06 22:16 ` Mark Fasheh
  -- strict thread matches above, loose matches on Subject: below --
2014-07-07 22:09 [PATCH 0/3] btrfs: qgroup fixes for btrfs_drop_snapshot V3 Mark Fasheh
2014-07-07 22:09 ` btrfs: qgroup: account shared subtrees during snapshot delete Mark Fasheh
2014-06-19 21:49 [PATCH 0/2] btrfs: qgroup fixes for btrfs_drop_snapshot Mark Fasheh
2014-06-19 21:49 ` btrfs: qgroup: account shared subtrees during snapshot delete Mark Fasheh
2014-06-19 22:25   ` Josef Bacik
2014-06-19 23:16     ` Mark Fasheh
2014-06-19 23:17       ` Josef Bacik
2014-06-20 11:25         ` David Sterba
2014-06-20 15:29           ` Mark Fasheh
2014-06-20 15:44             ` Josef Bacik
2014-06-20 17:18               ` Mark Fasheh
2014-06-23 14:49             ` David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).