diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-03-20 20:35:03 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-03-20 20:35:03 -0400 |
commit | 1261ec42b3d3a3ad878bd172144940e3ac710749 (patch) | |
tree | 4b317d8fa13e56a5dd02f37605b9fed5952d723a /fs/btrfs | |
parent | 293ffd5fd340428276fbbd24ce7b98bf6728466b (diff) |
Btrfs: Better block record keeping, real mkfs
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/Makefile | 7 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/debug-tree.c | 13 | ||||
-rw-r--r-- | fs/btrfs/dir-test.c | 2 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 11 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 24 | ||||
-rw-r--r-- | fs/btrfs/mkfs.c | 95 |
7 files changed, 134 insertions, 19 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 636c63efde6f..0720169b6d66 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -2,7 +2,7 @@ CC=gcc | |||
2 | CFLAGS = -g -Wall -Werror | 2 | CFLAGS = -g -Wall -Werror |
3 | headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h \ | 3 | headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h \ |
4 | transaction.h | 4 | transaction.h |
5 | objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o \ | 5 | objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \ |
6 | root-tree.o dir-item.o hash.o file-item.o inode-item.o \ | 6 | root-tree.o dir-item.o hash.o file-item.o inode-item.o \ |
7 | inode-map.o \ | 7 | inode-map.o \ |
8 | 8 | ||
@@ -16,7 +16,10 @@ check=sparse $(CHECKFLAGS) | |||
16 | $(check) $< | 16 | $(check) $< |
17 | $(CC) $(CFLAGS) -c $< | 17 | $(CC) $(CFLAGS) -c $< |
18 | 18 | ||
19 | all: tester debug-tree quick-test dir-test tags | 19 | all: tester debug-tree quick-test dir-test tags mkfs.btrfs |
20 | |||
21 | mkfs.btrfs: $(objects) mkfs.o | ||
22 | gcc $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o | ||
20 | 23 | ||
21 | debug-tree: $(objects) debug-tree.o | 24 | debug-tree: $(objects) debug-tree.o |
22 | gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o | 25 | gcc $(CFLAGS) -o debug-tree $(objects) debug-tree.o |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b30b2ce72455..1a4d1d6fa401 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -223,6 +223,7 @@ struct btrfs_fs_info { | |||
223 | int cache_size; | 223 | int cache_size; |
224 | int fp; | 224 | int fp; |
225 | struct btrfs_trans_handle *running_transaction; | 225 | struct btrfs_trans_handle *running_transaction; |
226 | struct btrfs_super_block *disk_super; | ||
226 | }; | 227 | }; |
227 | 228 | ||
228 | /* | 229 | /* |
diff --git a/fs/btrfs/debug-tree.c b/fs/btrfs/debug-tree.c index d9f36efc3dd1..fd07969600c6 100644 --- a/fs/btrfs/debug-tree.c +++ b/fs/btrfs/debug-tree.c | |||
@@ -10,8 +10,17 @@ | |||
10 | int main(int ac, char **av) { | 10 | int main(int ac, char **av) { |
11 | struct btrfs_super_block super; | 11 | struct btrfs_super_block super; |
12 | struct btrfs_root *root; | 12 | struct btrfs_root *root; |
13 | |||
14 | if (ac != 2) { | ||
15 | fprintf(stderr, "usage: %s device\n", av[0]); | ||
16 | exit(1); | ||
17 | } | ||
13 | radix_tree_init(); | 18 | radix_tree_init(); |
14 | root = open_ctree("dbfile", &super); | 19 | root = open_ctree(av[1], &super); |
20 | if (!root) { | ||
21 | fprintf(stderr, "unable to open %s\n", av[1]); | ||
22 | exit(1); | ||
23 | } | ||
15 | printf("fs tree\n"); | 24 | printf("fs tree\n"); |
16 | btrfs_print_tree(root, root->node); | 25 | btrfs_print_tree(root, root->node); |
17 | printf("map tree\n"); | 26 | printf("map tree\n"); |
@@ -23,5 +32,7 @@ int main(int ac, char **av) { | |||
23 | printf("root tree\n"); | 32 | printf("root tree\n"); |
24 | btrfs_print_tree(root->fs_info->tree_root, | 33 | btrfs_print_tree(root->fs_info->tree_root, |
25 | root->fs_info->tree_root->node); | 34 | root->fs_info->tree_root->node); |
35 | printf("total blocks %Lu\n", btrfs_super_total_blocks(&super)); | ||
36 | printf("blocks used %Lu\n", btrfs_super_blocks_used(&super)); | ||
26 | return 0; | 37 | return 0; |
27 | } | 38 | } |
diff --git a/fs/btrfs/dir-test.c b/fs/btrfs/dir-test.c index 8fc77c83a351..b673982a1f3c 100644 --- a/fs/btrfs/dir-test.c +++ b/fs/btrfs/dir-test.c | |||
@@ -425,8 +425,6 @@ int main(int ac, char **av) | |||
425 | struct btrfs_trans_handle *trans; | 425 | struct btrfs_trans_handle *trans; |
426 | radix_tree_init(); | 426 | radix_tree_init(); |
427 | 427 | ||
428 | printf("removing old tree\n"); | ||
429 | unlink("dbfile"); | ||
430 | root = open_ctree("dbfile", &super); | 428 | root = open_ctree("dbfile", &super); |
431 | trans = btrfs_start_transaction(root, 1); | 429 | trans = btrfs_start_transaction(root, 1); |
432 | 430 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index bacaa38ea82e..0322c55162cb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -293,20 +293,15 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) | |||
293 | fs_info->inode_root = inode_root; | 293 | fs_info->inode_root = inode_root; |
294 | fs_info->last_inode_alloc = 0; | 294 | fs_info->last_inode_alloc = 0; |
295 | fs_info->last_inode_alloc_dirid = 0; | 295 | fs_info->last_inode_alloc_dirid = 0; |
296 | fs_info->disk_super = super; | ||
296 | memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); | 297 | memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); |
297 | memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); | 298 | memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); |
298 | 299 | ||
299 | ret = pread(fp, super, sizeof(struct btrfs_super_block), | 300 | ret = pread(fp, super, sizeof(struct btrfs_super_block), |
300 | BTRFS_SUPER_INFO_OFFSET); | 301 | BTRFS_SUPER_INFO_OFFSET); |
301 | if (ret == 0 || btrfs_super_root(super) == 0) { | 302 | if (ret == 0 || btrfs_super_root(super) == 0) { |
302 | printf("making new FS!\n"); | 303 | BUG(); |
303 | ret = mkfs(fp, 0, 1024); | 304 | return NULL; |
304 | if (ret) | ||
305 | return NULL; | ||
306 | ret = pread(fp, super, sizeof(struct btrfs_super_block), | ||
307 | BTRFS_SUPER_INFO_OFFSET); | ||
308 | if (ret != sizeof(struct btrfs_super_block)) | ||
309 | return NULL; | ||
310 | } | 305 | } |
311 | BUG_ON(ret < 0); | 306 | BUG_ON(ret < 0); |
312 | 307 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 09eeeb4d9d28..9bc4ad38876d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -134,6 +134,8 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
134 | struct btrfs_extent_item extent_item; | 134 | struct btrfs_extent_item extent_item; |
135 | int i; | 135 | int i; |
136 | int ret; | 136 | int ret; |
137 | u64 super_blocks_used; | ||
138 | struct btrfs_fs_info *info = extent_root->fs_info; | ||
137 | 139 | ||
138 | btrfs_set_extent_refs(&extent_item, 1); | 140 | btrfs_set_extent_refs(&extent_item, 1); |
139 | btrfs_set_extent_owner(&extent_item, | 141 | btrfs_set_extent_owner(&extent_item, |
@@ -145,6 +147,9 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
145 | for (i = 0; i < extent_root->fs_info->current_insert.flags; i++) { | 147 | for (i = 0; i < extent_root->fs_info->current_insert.flags; i++) { |
146 | ins.objectid = extent_root->fs_info->current_insert.objectid + | 148 | ins.objectid = extent_root->fs_info->current_insert.objectid + |
147 | i; | 149 | i; |
150 | super_blocks_used = btrfs_super_blocks_used(info->disk_super); | ||
151 | btrfs_set_super_blocks_used(info->disk_super, | ||
152 | super_blocks_used + 1); | ||
148 | ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item, | 153 | ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item, |
149 | sizeof(extent_item)); | 154 | sizeof(extent_item)); |
150 | BUG_ON(ret); | 155 | BUG_ON(ret); |
@@ -161,7 +166,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
161 | { | 166 | { |
162 | struct btrfs_path path; | 167 | struct btrfs_path path; |
163 | struct btrfs_key key; | 168 | struct btrfs_key key; |
164 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 169 | struct btrfs_fs_info *info = root->fs_info; |
170 | struct btrfs_root *extent_root = info->extent_root; | ||
165 | int ret; | 171 | int ret; |
166 | struct btrfs_extent_item *ei; | 172 | struct btrfs_extent_item *ei; |
167 | struct btrfs_key ins; | 173 | struct btrfs_key ins; |
@@ -188,15 +194,18 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
188 | refs = btrfs_extent_refs(ei) - 1; | 194 | refs = btrfs_extent_refs(ei) - 1; |
189 | btrfs_set_extent_refs(ei, refs); | 195 | btrfs_set_extent_refs(ei, refs); |
190 | if (refs == 0) { | 196 | if (refs == 0) { |
197 | u64 super_blocks_used; | ||
191 | if (pin) { | 198 | if (pin) { |
192 | int err; | 199 | int err; |
193 | radix_tree_preload(GFP_KERNEL); | 200 | radix_tree_preload(GFP_KERNEL); |
194 | err = radix_tree_insert( | 201 | err = radix_tree_insert(&info->pinned_radix, |
195 | &extent_root->fs_info->pinned_radix, | 202 | blocknr, (void *)blocknr); |
196 | blocknr, (void *)blocknr); | ||
197 | BUG_ON(err); | 203 | BUG_ON(err); |
198 | radix_tree_preload_end(); | 204 | radix_tree_preload_end(); |
199 | } | 205 | } |
206 | super_blocks_used = btrfs_super_blocks_used(info->disk_super); | ||
207 | btrfs_set_super_blocks_used(info->disk_super, | ||
208 | super_blocks_used - num_blocks); | ||
200 | ret = btrfs_del_item(trans, extent_root, &path); | 209 | ret = btrfs_del_item(trans, extent_root, &path); |
201 | if (!pin && extent_root->fs_info->last_insert.objectid > | 210 | if (!pin && extent_root->fs_info->last_insert.objectid > |
202 | blocknr) | 211 | blocknr) |
@@ -392,7 +401,9 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
392 | { | 401 | { |
393 | int ret; | 402 | int ret; |
394 | int pending_ret; | 403 | int pending_ret; |
395 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 404 | u64 super_blocks_used; |
405 | struct btrfs_fs_info *info = root->fs_info; | ||
406 | struct btrfs_root *extent_root = info->extent_root; | ||
396 | struct btrfs_extent_item extent_item; | 407 | struct btrfs_extent_item extent_item; |
397 | 408 | ||
398 | btrfs_set_extent_refs(&extent_item, 1); | 409 | btrfs_set_extent_refs(&extent_item, 1); |
@@ -413,6 +424,9 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
413 | if (ret) | 424 | if (ret) |
414 | return ret; | 425 | return ret; |
415 | 426 | ||
427 | super_blocks_used = btrfs_super_blocks_used(info->disk_super); | ||
428 | btrfs_set_super_blocks_used(info->disk_super, super_blocks_used + | ||
429 | num_blocks); | ||
416 | ret = btrfs_insert_item(trans, extent_root, ins, &extent_item, | 430 | ret = btrfs_insert_item(trans, extent_root, ins, &extent_item, |
417 | sizeof(extent_item)); | 431 | sizeof(extent_item)); |
418 | 432 | ||
diff --git a/fs/btrfs/mkfs.c b/fs/btrfs/mkfs.c index 1cac5ab114dd..f7efc8a5fb1a 100644 --- a/fs/btrfs/mkfs.c +++ b/fs/btrfs/mkfs.c | |||
@@ -1,4 +1,8 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #ifndef __CHECKER__ | ||
3 | #include <sys/ioctl.h> | ||
4 | #include <sys/mount.h> | ||
5 | #endif | ||
2 | #include <stdio.h> | 6 | #include <stdio.h> |
3 | #include <stdlib.h> | 7 | #include <stdlib.h> |
4 | #include <sys/types.h> | 8 | #include <sys/types.h> |
@@ -10,6 +14,17 @@ | |||
10 | #include "ctree.h" | 14 | #include "ctree.h" |
11 | #include "disk-io.h" | 15 | #include "disk-io.h" |
12 | 16 | ||
17 | #ifdef __CHECKER__ | ||
18 | #define BLKGETSIZE64 0 | ||
19 | static inline int ioctl(int fd, int define, u64 *size) { return 0; } | ||
20 | #endif | ||
21 | |||
22 | #if 0 | ||
23 | #if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64) | ||
24 | # define BLKGETSIZE64 _IOR(0x12, 114, __u64) | ||
25 | #endif | ||
26 | #endif | ||
27 | |||
13 | int mkfs(int fd, u64 num_blocks, u32 blocksize) | 28 | int mkfs(int fd, u64 num_blocks, u32 blocksize) |
14 | { | 29 | { |
15 | struct btrfs_super_block super; | 30 | struct btrfs_super_block super; |
@@ -27,7 +42,7 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize) | |||
27 | strcpy((char *)(&super.magic), BTRFS_MAGIC); | 42 | strcpy((char *)(&super.magic), BTRFS_MAGIC); |
28 | btrfs_set_super_blocksize(&super, blocksize); | 43 | btrfs_set_super_blocksize(&super, blocksize); |
29 | btrfs_set_super_total_blocks(&super, num_blocks); | 44 | btrfs_set_super_total_blocks(&super, num_blocks); |
30 | btrfs_set_super_blocks_used(&super, 0); | 45 | btrfs_set_super_blocks_used(&super, start_block + 5); |
31 | 46 | ||
32 | block = malloc(blocksize); | 47 | block = malloc(blocksize); |
33 | memset(block, 0, blocksize); | 48 | memset(block, 0, blocksize); |
@@ -160,3 +175,81 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize) | |||
160 | return -1; | 175 | return -1; |
161 | return 0; | 176 | return 0; |
162 | } | 177 | } |
178 | |||
179 | u64 device_size(int fd, struct stat *st) | ||
180 | { | ||
181 | u64 size; | ||
182 | if (S_ISREG(st->st_mode)) { | ||
183 | return st->st_size; | ||
184 | } | ||
185 | if (!S_ISBLK(st->st_mode)) { | ||
186 | return 0; | ||
187 | } | ||
188 | if (ioctl(fd, BLKGETSIZE64, &size) >= 0) { | ||
189 | return size; | ||
190 | } | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | int main(int ac, char **av) | ||
195 | { | ||
196 | char *file; | ||
197 | u64 block_count = 0; | ||
198 | int fd; | ||
199 | struct stat st; | ||
200 | int ret; | ||
201 | int i; | ||
202 | char *buf = malloc(4096); | ||
203 | if (ac >= 2) { | ||
204 | file = av[1]; | ||
205 | if (ac == 3) { | ||
206 | block_count = atoi(av[2]); | ||
207 | if (!block_count) { | ||
208 | fprintf(stderr, "error finding block count\n"); | ||
209 | exit(1); | ||
210 | } | ||
211 | } | ||
212 | } else { | ||
213 | fprintf(stderr, "usage: mkfs.btrfs file [block count]\n"); | ||
214 | exit(1); | ||
215 | } | ||
216 | fd = open(file, O_RDWR); | ||
217 | if (fd < 0) { | ||
218 | fprintf(stderr, "unable to open %s\n", file); | ||
219 | exit(1); | ||
220 | } | ||
221 | ret = fstat(fd, &st); | ||
222 | if (ret < 0) { | ||
223 | fprintf(stderr, "unable to stat %s\n", file); | ||
224 | exit(1); | ||
225 | } | ||
226 | if (block_count == 0) { | ||
227 | block_count = device_size(fd, &st); | ||
228 | if (block_count == 0) { | ||
229 | fprintf(stderr, "unable to find %s size\n", file); | ||
230 | exit(1); | ||
231 | } | ||
232 | } | ||
233 | block_count /= 4096; | ||
234 | if (block_count < 256) { | ||
235 | fprintf(stderr, "device %s is too small\n", file); | ||
236 | exit(1); | ||
237 | } | ||
238 | memset(buf, 0, 4096); | ||
239 | for(i = 0; i < 6; i++) { | ||
240 | ret = write(fd, buf, 4096); | ||
241 | if (ret != 4096) { | ||
242 | fprintf(stderr, "unable to zero fill device\n"); | ||
243 | exit(1); | ||
244 | } | ||
245 | } | ||
246 | ret = mkfs(fd, block_count, 4096); | ||
247 | if (ret) { | ||
248 | fprintf(stderr, "error during mkfs %d\n", ret); | ||
249 | exit(1); | ||
250 | } | ||
251 | printf("fs created on %s blocksize %d blocks %Lu\n", | ||
252 | file, 4096, block_count); | ||
253 | return 0; | ||
254 | } | ||
255 | |||