diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-02-20 16:40:44 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-02-20 16:40:44 -0500 |
commit | d97e63b69ef21c02b67e20e41d9968b0e503572e (patch) | |
tree | 400db046be21c09f2d96f74ff98677464c45507f /fs | |
parent | 74123bd72a4e34c66e5ad95ce233dd352bebc572 (diff) |
Btrfs: early extent mapping support
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/Makefile | 4 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 152 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 34 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 76 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 3 |
5 files changed, 236 insertions, 33 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 63360212a075..df065dd2dce7 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -4,8 +4,8 @@ CFLAGS= -g -Wall | |||
4 | .c.o: | 4 | .c.o: |
5 | $(CC) $(CFLAGS) -c $< | 5 | $(CC) $(CFLAGS) -c $< |
6 | 6 | ||
7 | ctree: ctree.o disk-io.h ctree.h disk-io.o radix-tree.o radix-tree.h | 7 | ctree: ctree.o disk-io.h ctree.h disk-io.o radix-tree.o radix-tree.h mkfs.o |
8 | gcc $(CFLAGS) -o ctree ctree.o disk-io.o radix-tree.o | 8 | gcc $(CFLAGS) -o ctree ctree.o disk-io.o radix-tree.o mkfs.o |
9 | 9 | ||
10 | clean: | 10 | clean: |
11 | rm ctree *.o | 11 | rm ctree *.o |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 6b64f49a0279..2177744dedd3 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -5,6 +5,8 @@ | |||
5 | #include "ctree.h" | 5 | #include "ctree.h" |
6 | #include "disk-io.h" | 6 | #include "disk-io.h" |
7 | 7 | ||
8 | static int refill_alloc_extent(struct ctree_root *root); | ||
9 | |||
8 | static inline void init_path(struct ctree_path *p) | 10 | static inline void init_path(struct ctree_path *p) |
9 | { | 11 | { |
10 | memset(p, 0, sizeof(*p)); | 12 | memset(p, 0, sizeof(*p)); |
@@ -29,7 +31,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf) | |||
29 | { | 31 | { |
30 | unsigned int nr = leaf->header.nritems; | 32 | unsigned int nr = leaf->header.nritems; |
31 | if (nr == 0) | 33 | if (nr == 0) |
32 | return ARRAY_SIZE(leaf->data); | 34 | return sizeof(leaf->data); |
33 | return leaf->items[nr-1].offset; | 35 | return leaf->items[nr-1].offset; |
34 | } | 36 | } |
35 | 37 | ||
@@ -421,7 +423,7 @@ int insert_ptr(struct ctree_root *root, | |||
421 | * due to splitting. Once we've done all the splitting required | 423 | * due to splitting. Once we've done all the splitting required |
422 | * do the inserts based on the data in the bal array. | 424 | * do the inserts based on the data in the bal array. |
423 | */ | 425 | */ |
424 | memset(bal, 0, ARRAY_SIZE(bal)); | 426 | memset(bal, 0, sizeof(bal)); |
425 | while(t && t->node.header.nritems == NODEPTRS_PER_BLOCK) { | 427 | while(t && t->node.header.nritems == NODEPTRS_PER_BLOCK) { |
426 | c = &t->node; | 428 | c = &t->node; |
427 | if (push_node_left(root, path, | 429 | if (push_node_left(root, path, |
@@ -756,6 +758,7 @@ int insert_item(struct ctree_root *root, struct key *key, | |||
756 | if (leaf_free_space(leaf) < 0) | 758 | if (leaf_free_space(leaf) < 0) |
757 | BUG(); | 759 | BUG(); |
758 | release_path(root, &path); | 760 | release_path(root, &path); |
761 | refill_alloc_extent(root); | ||
759 | return 0; | 762 | return 0; |
760 | } | 763 | } |
761 | 764 | ||
@@ -884,6 +887,135 @@ int del_item(struct ctree_root *root, struct ctree_path *path) | |||
884 | return 0; | 887 | return 0; |
885 | } | 888 | } |
886 | 889 | ||
890 | int next_leaf(struct ctree_root *root, struct ctree_path *path) | ||
891 | { | ||
892 | int slot; | ||
893 | int level = 1; | ||
894 | u64 blocknr; | ||
895 | struct tree_buffer *c; | ||
896 | struct tree_buffer *next; | ||
897 | |||
898 | while(level < MAX_LEVEL) { | ||
899 | if (!path->nodes[level]) | ||
900 | return -1; | ||
901 | slot = path->slots[level] + 1; | ||
902 | c = path->nodes[level]; | ||
903 | if (slot >= c->node.header.nritems) { | ||
904 | level++; | ||
905 | continue; | ||
906 | } | ||
907 | blocknr = c->node.blockptrs[slot]; | ||
908 | next = read_tree_block(root, blocknr); | ||
909 | break; | ||
910 | } | ||
911 | path->slots[level] = slot; | ||
912 | while(1) { | ||
913 | level--; | ||
914 | c = path->nodes[level]; | ||
915 | tree_block_release(root, c); | ||
916 | path->nodes[level] = next; | ||
917 | path->slots[level] = 0; | ||
918 | if (!level) | ||
919 | break; | ||
920 | next = read_tree_block(root, next->node.blockptrs[0]); | ||
921 | } | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start, | ||
926 | u64 search_end, u64 owner, struct key *ins) | ||
927 | { | ||
928 | struct ctree_path path; | ||
929 | struct key *key; | ||
930 | int ret; | ||
931 | u64 hole_size = 0; | ||
932 | int slot = 0; | ||
933 | u64 last_block; | ||
934 | int start_found = 0; | ||
935 | struct leaf *l; | ||
936 | struct extent_item extent_item; | ||
937 | |||
938 | init_path(&path); | ||
939 | ins->objectid = search_start; | ||
940 | ins->offset = 0; | ||
941 | ins->flags = 0; | ||
942 | |||
943 | ret = search_slot(root, ins, &path); | ||
944 | while (1) { | ||
945 | l = &path.nodes[0]->leaf; | ||
946 | slot = path.slots[0]; | ||
947 | if (!l) { | ||
948 | // FIXME allocate root | ||
949 | } | ||
950 | if (slot >= l->header.nritems) { | ||
951 | ret = next_leaf(root, &path); | ||
952 | if (ret == 0) | ||
953 | continue; | ||
954 | if (!start_found) { | ||
955 | ins->objectid = search_start; | ||
956 | ins->offset = num_blocks; | ||
957 | hole_size = search_end - search_start; | ||
958 | goto insert; | ||
959 | } | ||
960 | ins->objectid = last_block; | ||
961 | ins->offset = num_blocks; | ||
962 | hole_size = search_end - last_block; | ||
963 | goto insert; | ||
964 | } | ||
965 | key = &l->items[slot].key; | ||
966 | if (start_found) { | ||
967 | hole_size = key->objectid - last_block; | ||
968 | if (hole_size > num_blocks) { | ||
969 | ins->objectid = last_block; | ||
970 | ins->offset = num_blocks; | ||
971 | goto insert; | ||
972 | } | ||
973 | } else | ||
974 | start_found = 1; | ||
975 | last_block = key->objectid + key->offset; | ||
976 | path.slots[0]++; | ||
977 | printf("last block is not %lu\n", last_block); | ||
978 | } | ||
979 | // FIXME -ENOSPC | ||
980 | insert: | ||
981 | extent_item.refs = 1; | ||
982 | extent_item.owner = owner; | ||
983 | ret = insert_item(root, ins, &extent_item, sizeof(extent_item)); | ||
984 | return ret; | ||
985 | } | ||
986 | |||
987 | static int refill_alloc_extent(struct ctree_root *root) | ||
988 | { | ||
989 | struct alloc_extent *ae = root->alloc_extent; | ||
990 | struct key key; | ||
991 | int ret; | ||
992 | int min_blocks = MAX_LEVEL * 2; | ||
993 | |||
994 | printf("refill alloc root %p, numused %lu total %lu\n", root, ae->num_used, ae->num_blocks); | ||
995 | if (ae->num_blocks > ae->num_used && ae->num_blocks - ae->num_used > | ||
996 | min_blocks) | ||
997 | return 0; | ||
998 | ae = root->reserve_extent; | ||
999 | if (ae->num_blocks > ae->num_used) { | ||
1000 | if (root->alloc_extent->num_blocks == 0) { | ||
1001 | /* we should swap reserve/alloc_extent when alloc | ||
1002 | * fills up | ||
1003 | */ | ||
1004 | BUG(); | ||
1005 | } | ||
1006 | if (ae->num_blocks - ae->num_used < min_blocks) | ||
1007 | BUG(); | ||
1008 | return 0; | ||
1009 | } | ||
1010 | // FIXME, this recurses | ||
1011 | ret = alloc_extent(root->extent_root, | ||
1012 | min_blocks * 2, 0, (unsigned long)-1, 0, &key); | ||
1013 | ae->blocknr = key.objectid; | ||
1014 | ae->num_blocks = key.offset; | ||
1015 | ae->num_used = 0; | ||
1016 | return ret; | ||
1017 | } | ||
1018 | |||
887 | void print_leaf(struct leaf *l) | 1019 | void print_leaf(struct leaf *l) |
888 | { | 1020 | { |
889 | int i; | 1021 | int i; |
@@ -948,8 +1080,8 @@ void print_tree(struct ctree_root *root, struct tree_buffer *t) | |||
948 | 1080 | ||
949 | /* for testing only */ | 1081 | /* for testing only */ |
950 | int next_key(int i, int max_key) { | 1082 | int next_key(int i, int max_key) { |
951 | return rand() % max_key; | 1083 | // return rand() % max_key; |
952 | // return i; | 1084 | return i; |
953 | } | 1085 | } |
954 | 1086 | ||
955 | int main() { | 1087 | int main() { |
@@ -960,7 +1092,7 @@ int main() { | |||
960 | int i; | 1092 | int i; |
961 | int num; | 1093 | int num; |
962 | int ret; | 1094 | int ret; |
963 | int run_size = 25000; | 1095 | int run_size = 256; |
964 | int max_key = 100000000; | 1096 | int max_key = 100000000; |
965 | int tree_size = 0; | 1097 | int tree_size = 0; |
966 | struct ctree_path path; | 1098 | struct ctree_path path; |
@@ -980,10 +1112,20 @@ int main() { | |||
980 | ins.objectid = num; | 1112 | ins.objectid = num; |
981 | ins.offset = 0; | 1113 | ins.offset = 0; |
982 | ins.flags = 0; | 1114 | ins.flags = 0; |
1115 | printf("insert %d\n", i); | ||
983 | ret = insert_item(root, &ins, buf, strlen(buf)); | 1116 | ret = insert_item(root, &ins, buf, strlen(buf)); |
984 | if (!ret) | 1117 | if (!ret) |
985 | tree_size++; | 1118 | tree_size++; |
1119 | printf("done insert %d\n", i); | ||
986 | } | 1120 | } |
1121 | printf("root used: %lu\n", root->alloc_extent->num_used); | ||
1122 | printf("root tree\n"); | ||
1123 | print_tree(root, root->node); | ||
1124 | printf("map tree\n"); | ||
1125 | printf("map used: %lu\n", root->extent_root->alloc_extent->num_used); | ||
1126 | print_tree(root->extent_root, root->extent_root->node); | ||
1127 | exit(1); | ||
1128 | |||
987 | close_ctree(root); | 1129 | close_ctree(root); |
988 | root = open_ctree("dbfile"); | 1130 | root = open_ctree("dbfile"); |
989 | printf("starting search\n"); | 1131 | printf("starting search\n"); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 586bf1866042..b737925be314 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __CTREE__ | 1 | #ifndef __CTREE__ |
2 | #define __CTREE__ | 2 | #define __CTREE__ |
3 | 3 | ||
4 | #define CTREE_BLOCKSIZE 4096 | 4 | #define CTREE_BLOCKSIZE 256 |
5 | 5 | ||
6 | struct key { | 6 | struct key { |
7 | u64 objectid; | 7 | u64 objectid; |
@@ -22,18 +22,41 @@ struct header { | |||
22 | #define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \ | 22 | #define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \ |
23 | (sizeof(struct key) + sizeof(u64))) | 23 | (sizeof(struct key) + sizeof(u64))) |
24 | 24 | ||
25 | #define LEVEL_BITS 3 | 25 | #define MAX_LEVEL 8 |
26 | #define MAX_LEVEL (1 << LEVEL_BITS) | ||
27 | #define node_level(f) ((f) & (MAX_LEVEL-1)) | 26 | #define node_level(f) ((f) & (MAX_LEVEL-1)) |
28 | #define is_leaf(f) (node_level(f) == 0) | 27 | #define is_leaf(f) (node_level(f) == 0) |
29 | 28 | ||
30 | struct tree_buffer; | 29 | struct tree_buffer; |
30 | |||
31 | struct alloc_extent { | ||
32 | u64 blocknr; | ||
33 | u64 num_blocks; | ||
34 | u64 num_used; | ||
35 | } __attribute__ ((__packed__)); | ||
36 | |||
31 | struct ctree_root { | 37 | struct ctree_root { |
32 | struct tree_buffer *node; | 38 | struct tree_buffer *node; |
39 | struct ctree_root *extent_root; | ||
40 | struct alloc_extent *alloc_extent; | ||
41 | struct alloc_extent *reserve_extent; | ||
33 | int fp; | 42 | int fp; |
34 | struct radix_tree_root cache_radix; | 43 | struct radix_tree_root cache_radix; |
44 | struct alloc_extent ai1; | ||
45 | struct alloc_extent ai2; | ||
35 | }; | 46 | }; |
36 | 47 | ||
48 | struct ctree_root_info { | ||
49 | u64 fsid[2]; /* FS specific uuid */ | ||
50 | u64 blocknr; /* blocknr of this block */ | ||
51 | u64 objectid; /* inode number of this root */ | ||
52 | u64 tree_root; /* the tree root */ | ||
53 | u32 csum; | ||
54 | u32 ham; | ||
55 | struct alloc_extent alloc_extent; | ||
56 | struct alloc_extent reserve_extent; | ||
57 | u64 snapuuid[2]; /* root specific uuid */ | ||
58 | } __attribute__ ((__packed__)); | ||
59 | |||
37 | struct item { | 60 | struct item { |
38 | struct key key; | 61 | struct key key; |
39 | u16 offset; | 62 | u16 offset; |
@@ -55,6 +78,11 @@ struct node { | |||
55 | u64 blockptrs[NODEPTRS_PER_BLOCK]; | 78 | u64 blockptrs[NODEPTRS_PER_BLOCK]; |
56 | } __attribute__ ((__packed__)); | 79 | } __attribute__ ((__packed__)); |
57 | 80 | ||
81 | struct extent_item { | ||
82 | u32 refs; | ||
83 | u64 owner; | ||
84 | } __attribute__ ((__packed__)); | ||
85 | |||
58 | struct ctree_path { | 86 | struct ctree_path { |
59 | struct tree_buffer *nodes[MAX_LEVEL]; | 87 | struct tree_buffer *nodes[MAX_LEVEL]; |
60 | int slots[MAX_LEVEL]; | 88 | int slots[MAX_LEVEL]; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8d51a07051d9..653f18aab330 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -12,25 +12,27 @@ | |||
12 | 12 | ||
13 | static int allocated_blocks = 0; | 13 | static int allocated_blocks = 0; |
14 | 14 | ||
15 | struct ctree_header { | ||
16 | u64 root_block; | ||
17 | } __attribute__ ((__packed__)); | ||
18 | |||
19 | static int get_free_block(struct ctree_root *root, u64 *block) | 15 | static int get_free_block(struct ctree_root *root, u64 *block) |
20 | { | 16 | { |
21 | struct stat st; | 17 | struct stat st; |
22 | int ret; | 18 | int ret; |
23 | 19 | ||
20 | if (root->alloc_extent->num_used >= root->alloc_extent->num_blocks) | ||
21 | return -1; | ||
22 | |||
23 | *block = root->alloc_extent->blocknr + root->alloc_extent->num_used; | ||
24 | root->alloc_extent->num_used += 1; | ||
25 | if (root->alloc_extent->num_used >= root->alloc_extent->num_blocks) { | ||
26 | struct alloc_extent *ae = root->alloc_extent; | ||
27 | root->alloc_extent = root->reserve_extent; | ||
28 | root->reserve_extent = ae; | ||
29 | ae->num_blocks = 0; | ||
30 | } | ||
24 | st.st_size = 0; | 31 | st.st_size = 0; |
25 | ret = fstat(root->fp, &st); | 32 | ret = fstat(root->fp, &st); |
26 | if (st.st_size > sizeof(struct ctree_header)) { | 33 | if (st.st_size < (*block + 1) * CTREE_BLOCKSIZE) |
27 | *block = (st.st_size - | 34 | ret = ftruncate(root->fp, |
28 | sizeof(struct ctree_header)) / CTREE_BLOCKSIZE; | 35 | (*block + 1) * CTREE_BLOCKSIZE); |
29 | } else { | ||
30 | *block = 0; | ||
31 | } | ||
32 | ret = ftruncate(root->fp, sizeof(struct ctree_header) + (*block + 1) * | ||
33 | CTREE_BLOCKSIZE); | ||
34 | return ret; | 36 | return ret; |
35 | } | 37 | } |
36 | 38 | ||
@@ -72,7 +74,7 @@ struct tree_buffer *alloc_free_block(struct ctree_root *root) | |||
72 | 74 | ||
73 | struct tree_buffer *read_tree_block(struct ctree_root *root, u64 blocknr) | 75 | struct tree_buffer *read_tree_block(struct ctree_root *root, u64 blocknr) |
74 | { | 76 | { |
75 | loff_t offset = blocknr * CTREE_BLOCKSIZE + sizeof(struct ctree_header); | 77 | loff_t offset = blocknr * CTREE_BLOCKSIZE; |
76 | struct tree_buffer *buf; | 78 | struct tree_buffer *buf; |
77 | int ret; | 79 | int ret; |
78 | 80 | ||
@@ -101,7 +103,7 @@ struct tree_buffer *read_tree_block(struct ctree_root *root, u64 blocknr) | |||
101 | int write_tree_block(struct ctree_root *root, struct tree_buffer *buf) | 103 | int write_tree_block(struct ctree_root *root, struct tree_buffer *buf) |
102 | { | 104 | { |
103 | u64 blocknr = buf->blocknr; | 105 | u64 blocknr = buf->blocknr; |
104 | loff_t offset = blocknr * CTREE_BLOCKSIZE + sizeof(struct ctree_header); | 106 | loff_t offset = blocknr * CTREE_BLOCKSIZE; |
105 | int ret; | 107 | int ret; |
106 | 108 | ||
107 | if (buf->blocknr != buf->node.header.blocknr) | 109 | if (buf->blocknr != buf->node.header.blocknr) |
@@ -114,11 +116,32 @@ int write_tree_block(struct ctree_root *root, struct tree_buffer *buf) | |||
114 | return 0; | 116 | return 0; |
115 | } | 117 | } |
116 | 118 | ||
119 | struct ctree_super_block { | ||
120 | struct ctree_root_info root_info; | ||
121 | struct ctree_root_info extent_info; | ||
122 | } __attribute__ ((__packed__)); | ||
123 | |||
124 | static int __setup_root(struct ctree_root *root, struct ctree_root *extent_root, | ||
125 | struct ctree_root_info *info, int fp) | ||
126 | { | ||
127 | root->fp = fp; | ||
128 | root->node = read_tree_block(root, info->tree_root); | ||
129 | root->extent_root = extent_root; | ||
130 | memcpy(&root->ai1, &info->alloc_extent, sizeof(info->alloc_extent)); | ||
131 | memcpy(&root->ai2, &info->reserve_extent, sizeof(info->reserve_extent)); | ||
132 | root->alloc_extent = &root->ai1; | ||
133 | root->reserve_extent = &root->ai2; | ||
134 | INIT_RADIX_TREE(&root->cache_radix, GFP_KERNEL); | ||
135 | printf("setup done reading root %p, used %lu\n", root, root->alloc_extent->num_used); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
117 | struct ctree_root *open_ctree(char *filename) | 139 | struct ctree_root *open_ctree(char *filename) |
118 | { | 140 | { |
119 | struct ctree_root *root = malloc(sizeof(struct ctree_root)); | 141 | struct ctree_root *root = malloc(sizeof(struct ctree_root)); |
142 | struct ctree_root *extent_root = malloc(sizeof(struct ctree_root)); | ||
143 | struct ctree_super_block super; | ||
120 | int fp; | 144 | int fp; |
121 | u64 root_block; | ||
122 | int ret; | 145 | int ret; |
123 | 146 | ||
124 | fp = open(filename, O_CREAT | O_RDWR); | 147 | fp = open(filename, O_CREAT | O_RDWR); |
@@ -126,14 +149,20 @@ struct ctree_root *open_ctree(char *filename) | |||
126 | free(root); | 149 | free(root); |
127 | return NULL; | 150 | return NULL; |
128 | } | 151 | } |
129 | root->fp = fp; | 152 | ret = pread(fp, &super, sizeof(struct ctree_super_block), |
130 | INIT_RADIX_TREE(&root->cache_radix, GFP_KERNEL); | 153 | CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE)); |
131 | ret = pread(fp, &root_block, sizeof(u64), 0); | 154 | if (ret == 0) { |
132 | if (ret == sizeof(u64)) { | 155 | ret = mkfs(fp); |
133 | printf("reading root node at block %lu\n", root_block); | 156 | if (ret) |
134 | root->node = read_tree_block(root, root_block); | 157 | return NULL; |
135 | } else | 158 | ret = pread(fp, &super, sizeof(struct ctree_super_block), |
136 | root->node = NULL; | 159 | CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE)); |
160 | if (ret != sizeof(struct ctree_super_block)) | ||
161 | return NULL; | ||
162 | } | ||
163 | BUG_ON(ret < 0); | ||
164 | __setup_root(root, extent_root, &super.root_info, fp); | ||
165 | __setup_root(extent_root, extent_root, &super.extent_info, fp); | ||
137 | return root; | 166 | return root; |
138 | } | 167 | } |
139 | 168 | ||
@@ -160,6 +189,7 @@ int update_root_block(struct ctree_root *root) | |||
160 | 189 | ||
161 | void tree_block_release(struct ctree_root *root, struct tree_buffer *buf) | 190 | void tree_block_release(struct ctree_root *root, struct tree_buffer *buf) |
162 | { | 191 | { |
192 | return; | ||
163 | buf->count--; | 193 | buf->count--; |
164 | if (buf->count == 0) { | 194 | if (buf->count == 0) { |
165 | if (!radix_tree_lookup(&root->cache_radix, buf->blocknr)) | 195 | if (!radix_tree_lookup(&root->cache_radix, buf->blocknr)) |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index ee95fa05c4a3..41acb65eee19 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -17,5 +17,8 @@ int close_ctree(struct ctree_root *root); | |||
17 | void tree_block_release(struct ctree_root *root, struct tree_buffer *buf); | 17 | void tree_block_release(struct ctree_root *root, struct tree_buffer *buf); |
18 | struct tree_buffer *alloc_free_block(struct ctree_root *root); | 18 | struct tree_buffer *alloc_free_block(struct ctree_root *root); |
19 | int update_root_block(struct ctree_root *root); | 19 | int update_root_block(struct ctree_root *root); |
20 | int mkfs(int fd); | ||
21 | |||
22 | #define CTREE_SUPER_INFO_OFFSET(bs) (16 * (bs)) | ||
20 | 23 | ||
21 | #endif | 24 | #endif |