diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-11-30 11:30:34 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 87ee04eb0f2f0c63314cef4a76bd1adac748425e (patch) | |
tree | 2be6218d1d94ec92230be8df8e215691ecd5065d /fs | |
parent | 00f5c795fca47d038fedd3f0c9311da3be710c9f (diff) |
Btrfs: Add simple stripe size parameter
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 5 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 15 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 36 |
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); |
777 | BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block, | 780 | BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block, |
778 | leafsize, 32); | 781 | leafsize, 32); |
782 | BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block, | ||
783 | stripesize, 32); | ||
779 | BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block, | 784 | BTRFS_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 | ||
357 | static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | 357 | static 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 | ||
935 | static 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 | |||
990 | check_failed: | 998 | check_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 | } |