David Woodhouse
2009-Jul-13 14:11 UTC
[PATCH 3/4] Btrfs: Fix another partial discard bug in on RAID
Each call to btrfs_map_block() will only return a single stripe length,
so we need to loop until we''ve freed as much as we need.
(We should actually move this whole function into volumes.c and let it
do cunning things so that it frees a single contiguous range on each
backing device. I''ll do that when I have to unbreak it for RAID5
anyway.)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
fs/btrfs/extent-tree.c | 25 +++++++++++++++----------
1 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1496925..d829ef3 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1421,23 +1421,28 @@ static int btrfs_discard_extent(struct btrfs_root *root,
u64 bytenr,
struct btrfs_multi_bio *multi = NULL;
/* Tell the block device(s) that the sectors can be discarded */
- ret = btrfs_map_block(&root->fs_info->mapping_tree, WRITE,
- bytenr, &map_length, &multi, 0);
- if (!ret) {
- struct btrfs_bio_stripe *stripe = multi->stripes;
+ while (num_bytes) {
int i;
+ ret = btrfs_map_block(&root->fs_info->mapping_tree, WRITE,
+ bytenr, &map_length, &multi, 0);
+ if (ret)
+ break;
+
+
if (map_length > num_bytes)
map_length = num_bytes;
-
- for (i = 0; i < multi->num_stripes; i++, stripe++) {
- btrfs_issue_discard(stripe->dev->bdev,
- stripe->physical,
+
+ for (i = 0; i < multi->num_stripes; i++)
+ btrfs_issue_discard(multi->stripes[i].dev->bdev,
+ multi->stripes[i].physical,
map_length);
- }
+
kfree(multi);
- }
+ num_bytes -= map_length;
+ bytenr += map_length;
+ }
return ret;
#else
return 0;
--
1.6.2.5
--
David Woodhouse Open Source Technology Centre
David.Woodhouse@intel.com Intel Corporation
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html