* [PATCH][RESEND] btrfs: clear 'ret' in btrfs_check_shared() loop
@ 2015-05-19 19:49 Mark Fasheh
2015-05-19 20:35 ` Josef Bacik
0 siblings, 1 reply; 2+ messages in thread
From: Mark Fasheh @ 2015-05-19 19:49 UTC (permalink / raw)
To: linux-btrfs; +Cc: Josef Bacik, Chris Mason
btrfs_check_shared() is leaking a return value of '1' from
find_parent_nodes(). As a result, callers (in this case, extent_fiemap())
are told extents are shared when they are not. This in turn broke fiemap on
btrfs for kernels v3.18 and up.
The fix is simple - we just have to clear 'ret' after we are done processing
the results of find_parent_nodes().
It wasn't clear to me at first what was happening with return values in
btrfs_check_shared() and find_parent_nodes() - thanks to Josef for the help
on irc. I added documentation to both functions to make things more clear
for the next hacker who might come across them.
If we could queue this up for -stable too that would be great.
Signed-off-by: Mark Fasheh <mfasheh@suse.de>
---
fs/btrfs/backref.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index f55721f..8d47380 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -880,6 +880,8 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
* indirect refs to their parent bytenr.
* When roots are found, they're added to the roots list
*
+ * NOTE: This can return values > 0
+ *
* FIXME some caching might speed things up
*/
static int find_parent_nodes(struct btrfs_trans_handle *trans,
@@ -1198,6 +1200,19 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
return ret;
}
+/**
+ * btrfs_check_shared - tell us whether an extent is shared
+ *
+ * @trans: optional trans handle
+ *
+ * btrfs_check_shared uses the backref walking code but will short
+ * circuit as soon as it finds a root or inode that doesn't match the
+ * one passed in. This provides a significant performance benefit for
+ * callers (such as fiemap) which want to know whether the extent is
+ * shared but do not need a ref count.
+ *
+ * Return: 0 if extent is not shared, 1 if it is shared, < 0 on error.
+ */
int btrfs_check_shared(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 root_objectid,
u64 inum, u64 bytenr)
@@ -1226,11 +1241,13 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans,
ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp,
roots, NULL, root_objectid, inum);
if (ret == BACKREF_FOUND_SHARED) {
+ /* this is the only condition under which we return 1 */
ret = 1;
break;
}
if (ret < 0 && ret != -ENOENT)
break;
+ ret = 0;
node = ulist_next(tmp, &uiter);
if (!node)
break;
--
2.1.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH][RESEND] btrfs: clear 'ret' in btrfs_check_shared() loop
2015-05-19 19:49 [PATCH][RESEND] btrfs: clear 'ret' in btrfs_check_shared() loop Mark Fasheh
@ 2015-05-19 20:35 ` Josef Bacik
0 siblings, 0 replies; 2+ messages in thread
From: Josef Bacik @ 2015-05-19 20:35 UTC (permalink / raw)
To: Mark Fasheh, linux-btrfs; +Cc: Chris Mason
On 05/19/2015 03:49 PM, Mark Fasheh wrote:
> btrfs_check_shared() is leaking a return value of '1' from
> find_parent_nodes(). As a result, callers (in this case, extent_fiemap())
> are told extents are shared when they are not. This in turn broke fiemap on
> btrfs for kernels v3.18 and up.
>
> The fix is simple - we just have to clear 'ret' after we are done processing
> the results of find_parent_nodes().
>
> It wasn't clear to me at first what was happening with return values in
> btrfs_check_shared() and find_parent_nodes() - thanks to Josef for the help
> on irc. I added documentation to both functions to make things more clear
> for the next hacker who might come across them.
>
> If we could queue this up for -stable too that would be great.
>
> Signed-off-by: Mark Fasheh <mfasheh@suse.de>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Thanks,
Josef
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-05-19 20:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-19 19:49 [PATCH][RESEND] btrfs: clear 'ret' in btrfs_check_shared() loop Mark Fasheh
2015-05-19 20:35 ` Josef Bacik
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).