aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/disk-io.c15
-rw-r--r--fs/btrfs/extent-tree.c36
3 files changed, 43 insertions, 13 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b29b911dd825..9bc1b0a8615f 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -135,6 +135,7 @@ struct btrfs_super_block {
135 __le32 sectorsize; 135 __le32 sectorsize;
136 __le32 nodesize; 136 __le32 nodesize;
137 __le32 leafsize; 137 __le32 leafsize;
138 __le32 stripesize;
138 u8 root_level; 139 u8 root_level;
139} __attribute__ ((__packed__)); 140} __attribute__ ((__packed__));
140 141
@@ -353,6 +354,8 @@ struct btrfs_root {
353 /* leaf allocations are done in leafsize units */ 354 /* leaf allocations are done in leafsize units */
354 u32 leafsize; 355 u32 leafsize;
355 356
357 u32 stripesize;
358
356 u32 type; 359 u32 type;
357 u64 highest_inode; 360 u64 highest_inode;
358 u64 last_inode_alloc; 361 u64 last_inode_alloc;
@@ -776,6 +779,8 @@ BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block,
776 nodesize, 32); 779 nodesize, 32);
777BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block, 780BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block,
778 leafsize, 32); 781 leafsize, 32);
782BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block,
783 stripesize, 32);
779BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block, 784BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block,
780 root_dir_objectid, 64); 785 root_dir_objectid, 64);
781 786
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index eef4ab56b9ca..60a30da6af00 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -355,7 +355,7 @@ int wait_on_tree_block_writeback(struct btrfs_root *root,
355} 355}
356 356
357static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, 357static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
358 struct btrfs_root *root, 358 u32 stripesize, struct btrfs_root *root,
359 struct btrfs_fs_info *fs_info, 359 struct btrfs_fs_info *fs_info,
360 u64 objectid) 360 u64 objectid)
361{ 361{
@@ -365,6 +365,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
365 root->sectorsize = sectorsize; 365 root->sectorsize = sectorsize;
366 root->nodesize = nodesize; 366 root->nodesize = nodesize;
367 root->leafsize = leafsize; 367 root->leafsize = leafsize;
368 root->stripesize = stripesize;
368 root->ref_cows = 0; 369 root->ref_cows = 0;
369 root->fs_info = fs_info; 370 root->fs_info = fs_info;
370 root->objectid = objectid; 371 root->objectid = objectid;
@@ -393,7 +394,8 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
393 u32 blocksize; 394 u32 blocksize;
394 395
395 __setup_root(tree_root->nodesize, tree_root->leafsize, 396 __setup_root(tree_root->nodesize, tree_root->leafsize,
396 tree_root->sectorsize, root, fs_info, objectid); 397 tree_root->sectorsize, tree_root->stripesize,
398 root, fs_info, objectid);
397 ret = btrfs_find_last_root(tree_root, objectid, 399 ret = btrfs_find_last_root(tree_root, objectid,
398 &root->root_item, &root->root_key); 400 &root->root_item, &root->root_key);
399 BUG_ON(ret); 401 BUG_ON(ret);
@@ -430,8 +432,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
430 } 432 }
431 433
432 __setup_root(tree_root->nodesize, tree_root->leafsize, 434 __setup_root(tree_root->nodesize, tree_root->leafsize,
433 tree_root->sectorsize, root, fs_info, 435 tree_root->sectorsize, tree_root->stripesize,
434 location->objectid); 436 root, fs_info, location->objectid);
435 437
436 path = btrfs_alloc_path(); 438 path = btrfs_alloc_path();
437 BUG_ON(!path); 439 BUG_ON(!path);
@@ -537,6 +539,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
537 u32 nodesize; 539 u32 nodesize;
538 u32 leafsize; 540 u32 leafsize;
539 u32 blocksize; 541 u32 blocksize;
542 u32 stripesize;
540 struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root), 543 struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root),
541 GFP_NOFS); 544 GFP_NOFS);
542 struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root), 545 struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root),
@@ -607,7 +610,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
607 goto fail_iput; 610 goto fail_iput;
608 } 611 }
609#endif 612#endif
610 __setup_root(512, 512, 512, tree_root, 613 __setup_root(512, 512, 512, 512, tree_root,
611 fs_info, BTRFS_ROOT_TREE_OBJECTID); 614 fs_info, BTRFS_ROOT_TREE_OBJECTID);
612 615
613 fs_info->sb_buffer = read_tree_block(tree_root, 616 fs_info->sb_buffer = read_tree_block(tree_root,
@@ -630,9 +633,11 @@ struct btrfs_root *open_ctree(struct super_block *sb)
630 nodesize = btrfs_super_nodesize(disk_super); 633 nodesize = btrfs_super_nodesize(disk_super);
631 leafsize = btrfs_super_leafsize(disk_super); 634 leafsize = btrfs_super_leafsize(disk_super);
632 sectorsize = btrfs_super_sectorsize(disk_super); 635 sectorsize = btrfs_super_sectorsize(disk_super);
636 stripesize = btrfs_super_stripesize(disk_super);
633 tree_root->nodesize = nodesize; 637 tree_root->nodesize = nodesize;
634 tree_root->leafsize = leafsize; 638 tree_root->leafsize = leafsize;
635 tree_root->sectorsize = sectorsize; 639 tree_root->sectorsize = sectorsize;
640 tree_root->stripesize = stripesize;
636 sb_set_blocksize(sb, sectorsize); 641 sb_set_blocksize(sb, sectorsize);
637 642
638 i_size_write(fs_info->btree_inode, 643 i_size_write(fs_info->btree_inode,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 55abdf997ca5..91397e989393 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -932,6 +932,13 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
932 return ret ? ret : pending_ret; 932 return ret ? ret : pending_ret;
933} 933}
934 934
935static u64 stripe_align(struct btrfs_root *root, u64 val)
936{
937 u64 mask = ((u64)root->stripesize - 1);
938 u64 ret = (val + mask) & ~mask;
939 return ret;
940}
941
935/* 942/*
936 * walks the btree of allocated extents and find a hole of a given size. 943 * walks the btree of allocated extents and find a hole of a given size.
937 * The key ins is changed to record the hole: 944 * The key ins is changed to record the hole:
@@ -948,8 +955,9 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
948{ 955{
949 struct btrfs_path *path; 956 struct btrfs_path *path;
950 struct btrfs_key key; 957 struct btrfs_key key;
951 int ret;
952 u64 hole_size = 0; 958 u64 hole_size = 0;
959 u64 aligned;
960 int ret;
953 int slot = 0; 961 int slot = 0;
954 u64 last_byte = 0; 962 u64 last_byte = 0;
955 u64 orig_search_start = search_start; 963 u64 orig_search_start = search_start;
@@ -990,6 +998,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
990check_failed: 998check_failed:
991 search_start = find_search_start(root, &block_group, search_start, 999 search_start = find_search_start(root, &block_group, search_start,
992 total_needed, data, full_scan); 1000 total_needed, data, full_scan);
1001 search_start = stripe_align(root, search_start);
993 cached_start = search_start; 1002 cached_start = search_start;
994 btrfs_init_path(path); 1003 btrfs_init_path(path);
995 ins->objectid = search_start; 1004 ins->objectid = search_start;
@@ -1039,13 +1048,23 @@ check_failed:
1039 search_start = max(search_start, 1048 search_start = max(search_start,
1040 block_group->key.objectid); 1049 block_group->key.objectid);
1041 if (!start_found) { 1050 if (!start_found) {
1042 ins->objectid = search_start; 1051 aligned = stripe_align(root, search_start);
1043 ins->offset = search_end - search_start; 1052 ins->objectid = aligned;
1053 if (aligned >= search_end) {
1054 ret = -ENOSPC;
1055 goto error;
1056 }
1057 ins->offset = search_end - aligned;
1044 start_found = 1; 1058 start_found = 1;
1045 goto check_pending; 1059 goto check_pending;
1046 } 1060 }
1047 ins->objectid = last_byte > search_start ? 1061 ins->objectid = stripe_align(root,
1048 last_byte : search_start; 1062 last_byte > search_start ?
1063 last_byte : search_start);
1064 if (search_end <= ins->objectid) {
1065 ret = -ENOSPC;
1066 goto error;
1067 }
1049 ins->offset = search_end - ins->objectid; 1068 ins->offset = search_end - ins->objectid;
1050 BUG_ON(ins->objectid >= search_end); 1069 BUG_ON(ins->objectid >= search_end);
1051 goto check_pending; 1070 goto check_pending;
@@ -1056,9 +1075,10 @@ check_failed:
1056 start_found) { 1075 start_found) {
1057 if (last_byte < search_start) 1076 if (last_byte < search_start)
1058 last_byte = search_start; 1077 last_byte = search_start;
1059 hole_size = key.objectid - last_byte; 1078 aligned = stripe_align(root, last_byte);
1060 if (hole_size >= num_bytes) { 1079 hole_size = key.objectid - aligned;
1061 ins->objectid = last_byte; 1080 if (key.objectid > aligned && hole_size >= num_bytes) {
1081 ins->objectid = aligned;
1062 ins->offset = hole_size; 1082 ins->offset = hole_size;
1063 goto check_pending; 1083 goto check_pending;
1064 } 1084 }