}
static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
- struct btrfs_root *root,
+ u32 stripesize, struct btrfs_root *root,
struct btrfs_fs_info *fs_info,
u64 objectid)
{
root->sectorsize = sectorsize;
root->nodesize = nodesize;
root->leafsize = leafsize;
+ root->stripesize = stripesize;
root->ref_cows = 0;
root->fs_info = fs_info;
root->objectid = objectid;
u32 blocksize;
__setup_root(tree_root->nodesize, tree_root->leafsize,
- tree_root->sectorsize, root, fs_info, objectid);
+ tree_root->sectorsize, tree_root->stripesize,
+ root, fs_info, objectid);
ret = btrfs_find_last_root(tree_root, objectid,
&root->root_item, &root->root_key);
BUG_ON(ret);
}
__setup_root(tree_root->nodesize, tree_root->leafsize,
- tree_root->sectorsize, root, fs_info,
- location->objectid);
+ tree_root->sectorsize, tree_root->stripesize,
+ root, fs_info, location->objectid);
path = btrfs_alloc_path();
BUG_ON(!path);
u32 nodesize;
u32 leafsize;
u32 blocksize;
+ u32 stripesize;
struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root),
GFP_NOFS);
struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root),
goto fail_iput;
}
#endif
- __setup_root(512, 512, 512, tree_root,
+ __setup_root(512, 512, 512, 512, tree_root,
fs_info, BTRFS_ROOT_TREE_OBJECTID);
fs_info->sb_buffer = read_tree_block(tree_root,
nodesize = btrfs_super_nodesize(disk_super);
leafsize = btrfs_super_leafsize(disk_super);
sectorsize = btrfs_super_sectorsize(disk_super);
+ stripesize = btrfs_super_stripesize(disk_super);
tree_root->nodesize = nodesize;
tree_root->leafsize = leafsize;
tree_root->sectorsize = sectorsize;
+ tree_root->stripesize = stripesize;
sb_set_blocksize(sb, sectorsize);
i_size_write(fs_info->btree_inode,
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:
{
struct btrfs_path *path;
struct btrfs_key key;
- int ret;
u64 hole_size = 0;
+ u64 aligned;
+ int ret;
int slot = 0;
u64 last_byte = 0;
u64 orig_search_start = search_start;
check_failed:
search_start = find_search_start(root, &block_group, search_start,
total_needed, data, full_scan);
+ search_start = stripe_align(root, search_start);
cached_start = search_start;
btrfs_init_path(path);
ins->objectid = search_start;
search_start = max(search_start,
block_group->key.objectid);
if (!start_found) {
- ins->objectid = search_start;
- ins->offset = search_end - search_start;
+ aligned = stripe_align(root, search_start);
+ ins->objectid = aligned;
+ if (aligned >= search_end) {
+ ret = -ENOSPC;
+ goto error;
+ }
+ ins->offset = search_end - 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);
+ if (search_end <= ins->objectid) {
+ ret = -ENOSPC;
+ goto error;
+ }
ins->offset = search_end - ins->objectid;
BUG_ON(ins->objectid >= search_end);
goto check_pending;
start_found) {
if (last_byte < search_start)
last_byte = search_start;
- hole_size = key.objectid - last_byte;
- if (hole_size >= num_bytes) {
- ins->objectid = last_byte;
+ aligned = stripe_align(root, last_byte);
+ hole_size = key.objectid - aligned;
+ if (key.objectid > aligned && hole_size >= num_bytes) {
+ ins->objectid = aligned;
ins->offset = hole_size;
goto check_pending;
}