Btrfs: Add simple stripe size parameter
authorChris Mason <chris.mason@oracle.com>
Fri, 30 Nov 2007 16:30:34 +0000 (11:30 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:58 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c

index b29b911..9bc1b0a 100644 (file)
@@ -135,6 +135,7 @@ struct btrfs_super_block {
        __le32 sectorsize;
        __le32 nodesize;
        __le32 leafsize;
+       __le32 stripesize;
        u8 root_level;
 } __attribute__ ((__packed__));
 
@@ -353,6 +354,8 @@ struct btrfs_root {
        /* leaf allocations are done in leafsize units */
        u32 leafsize;
 
+       u32 stripesize;
+
        u32 type;
        u64 highest_inode;
        u64 last_inode_alloc;
@@ -776,6 +779,8 @@ BTRFS_SETGET_STACK_FUNCS(super_nodesize, struct btrfs_super_block,
                         nodesize, 32);
 BTRFS_SETGET_STACK_FUNCS(super_leafsize, struct btrfs_super_block,
                         leafsize, 32);
+BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block,
+                        stripesize, 32);
 BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block,
                         root_dir_objectid, 64);
 
index eef4ab5..60a30da 100644 (file)
@@ -355,7 +355,7 @@ int wait_on_tree_block_writeback(struct btrfs_root *root,
 }
 
 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)
 {
@@ -365,6 +365,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
        root->sectorsize = sectorsize;
        root->nodesize = nodesize;
        root->leafsize = leafsize;
+       root->stripesize = stripesize;
        root->ref_cows = 0;
        root->fs_info = fs_info;
        root->objectid = objectid;
@@ -393,7 +394,8 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
        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);
@@ -430,8 +432,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
        }
 
        __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);
@@ -537,6 +539,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
        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),
@@ -607,7 +610,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
                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,
@@ -630,9 +633,11 @@ struct btrfs_root *open_ctree(struct super_block *sb)
        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,
index 55abdf9..91397e9 100644 (file)
@@ -932,6 +932,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:
@@ -948,8 +955,9 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
 {
        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;
@@ -990,6 +998,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
 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;
@@ -1039,13 +1048,23 @@ check_failed:
                        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;
@@ -1056,9 +1075,10 @@ check_failed:
                    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;
                        }