aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-20 20:35:03 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-20 20:35:03 -0400
commit1261ec42b3d3a3ad878bd172144940e3ac710749 (patch)
tree4b317d8fa13e56a5dd02f37605b9fed5952d723a
parent293ffd5fd340428276fbbd24ce7b98bf6728466b (diff)
Btrfs: Better block record keeping, real mkfs
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/Makefile7
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/debug-tree.c13
-rw-r--r--fs/btrfs/dir-test.c2
-rw-r--r--fs/btrfs/disk-io.c11
-rw-r--r--fs/btrfs/extent-tree.c24
-rw-r--r--fs/btrfs/mkfs.c95
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
2CFLAGS = -g -Wall -Werror 2CFLAGS = -g -Wall -Werror
3headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h \ 3headers = radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h \
4 transaction.h 4 transaction.h
5objects = ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o \ 5objects = 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
19all: tester debug-tree quick-test dir-test tags 19all: tester debug-tree quick-test dir-test tags mkfs.btrfs
20
21mkfs.btrfs: $(objects) mkfs.o
22 gcc $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o
20 23
21debug-tree: $(objects) debug-tree.o 24debug-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 @@
10int main(int ac, char **av) { 10int 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
19static 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
13int mkfs(int fd, u64 num_blocks, u32 blocksize) 28int 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
179u64 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
194int 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