summaryrefslogtreecommitdiff
path: root/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'extent-tree.c')
-rw-r--r--extent-tree.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/extent-tree.c b/extent-tree.c
index 8f7dc068..8615a432 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -372,6 +372,13 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
return ret ? ret : pending_ret;
}
+static u64 stripe_align(struct btrfs_root *root, u64 val)
+{
+ u64 mask = ((u64)root->stripesize - 1);
+ u64 ret = (val + mask) & ~mask;
+ return ret;
+}
+
/*
* walks the btree of allocated extents and find a hole of a given size.
* The key ins is changed to record the hole:
@@ -390,6 +397,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
u64 hole_size = 0;
int slot = 0;
u64 last_byte = 0;
+ u64 aligned;
int start_found;
struct btrfs_leaf *l;
struct btrfs_root * root = orig_root->fs_info->extent_root;
@@ -397,6 +405,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
if (root->fs_info->last_insert.objectid > search_start)
search_start = root->fs_info->last_insert.objectid;
+ search_start = stripe_align(root, search_start);
btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
check_failed:
@@ -421,13 +430,15 @@ check_failed:
if (ret < 0)
goto error;
if (!start_found) {
- ins->objectid = search_start;
- ins->offset = (u64)-1 - search_start;
+ aligned = stripe_align(root, search_start);
+ ins->objectid = aligned;
+ ins->offset = (u64)-1 - aligned;
start_found = 1;
goto check_pending;
}
- ins->objectid = last_byte > search_start ?
- last_byte : search_start;
+ ins->objectid = stripe_align(root,
+ last_byte > search_start ?
+ last_byte : search_start);
ins->offset = (u64)-1 - ins->objectid;
goto check_pending;
}
@@ -438,9 +449,11 @@ check_failed:
if (start_found) {
if (last_byte < search_start)
last_byte = search_start;
- hole_size = key.objectid - last_byte;
- if (hole_size > total_needed) {
- ins->objectid = last_byte;
+ aligned = stripe_align(root, last_byte);
+ hole_size = key.objectid - aligned;
+ if (key.objectid > aligned &&
+ hole_size > total_needed) {
+ ins->objectid = aligned;
ins->offset = hole_size;
goto check_pending;
}