From: Alexander Block <ablock84@googlemail.com>
To: chris.mason@oracle.com
Cc: linux-btrfs@vger.kernel.org, Alexander Block <ablock84@googlemail.com>
Subject: [PATCH 2/3] btrfs: Fix ulist related problems in backref walking code
Date: Fri, 4 May 2012 20:54:24 +0200 [thread overview]
Message-ID: <1336157665-17328-2-git-send-email-ablock84@googlemail.com> (raw)
In-Reply-To: <1336157665-17328-1-git-send-email-ablock84@googlemail.com>
1. in btrfs_find_all_roots
This method uses a ulist to solve the recursion. The local variable
node is used in combination with ulist_next to iterate through the
list. Calls to find_parent_nodes fill up this list. The problem is,
adding new nodes to the ulist may cause the ulist->nodes pointer to
change in case the ulist needs to realloc the buffer. The call to
ulist_next may use a wrong prev pointer in that case, resulting in
undefined behaviour. It is changed now to not use ulist_next.
2. in __iterate_extent_inodes
the first while loop calls btrfs_find_all_roots, which then allocates
a new ulist for the roots. In case the first while loops loops more
then once, we leak the previous ulist as it is not freed.
Point 1 was also causing missed backrefs because the iteration stopped
too early.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
---
fs/btrfs/backref.c | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index f28ecba..b08cf93 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -791,6 +791,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
struct ulist *tmp;
struct ulist_node *node = NULL;
int ret;
+ int cur;
tmp = ulist_alloc(GFP_NOFS);
if (!tmp)
@@ -801,7 +802,14 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
return -ENOMEM;
}
- while (1) {
+ cur = 0;
+ ulist_add(tmp, bytenr, 0, GFP_NOFS);
+
+ while (cur < tmp->nnodes) {
+ node = &tmp->nodes[cur++];
+ bytenr = node->val;
+
+ /* this will add new nodes to the tmp ulist */
ret = find_parent_nodes(trans, fs_info, bytenr, seq,
tmp, *roots);
if (ret < 0 && ret != -ENOENT) {
@@ -809,10 +817,6 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
ulist_free(*roots);
return ret;
}
- node = ulist_next(tmp, node);
- if (!node)
- break;
- bytenr = node->val;
}
ulist_free(tmp);
@@ -1231,10 +1235,14 @@ static int __iterate_extent_inodes(struct btrfs_fs_info *fs_info,
match_with_offset,
iterate, ctx);
}
+ if (roots)
+ ulist_free(roots);
+ roots = NULL;
}
ulist_free(refs);
- ulist_free(roots);
+ if (roots)
+ ulist_free(roots);
out:
if (!search_commit_root) {
btrfs_put_delayed_seq(delayed_refs, &seq_elem);
--
1.7.3.4
next prev parent reply other threads:[~2012-05-04 18:54 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-04 18:54 [PATCH 1/3] btrfs: Fix missed backrefs in backref walking code Alexander Block
2012-05-04 18:54 ` Alexander Block [this message]
2012-05-04 18:54 ` [PATCH 3/3] btrfs: Update comment above ulist_next Alexander Block
2012-05-04 19:10 ` Arne Jansen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1336157665-17328-2-git-send-email-ablock84@googlemail.com \
--to=ablock84@googlemail.com \
--cc=chris.mason@oracle.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).