1 #define _XOPEN_SOURCE 500
8 #include "kerncompat.h"
9 #include "radix-tree.h"
13 static int allocated_blocks
= 0;
15 static int check_tree_block(struct ctree_root
*root
, struct tree_buffer
*buf
)
17 if (buf
->blocknr
!= buf
->node
.header
.blocknr
)
19 if (root
->node
&& buf
->node
.header
.parentid
!= root
->node
->node
.header
.parentid
)
24 struct tree_buffer
*alloc_tree_block(struct ctree_root
*root
, u64 blocknr
)
26 struct tree_buffer
*buf
;
28 buf
= malloc(sizeof(struct tree_buffer
));
32 buf
->blocknr
= blocknr
;
34 radix_tree_preload(GFP_KERNEL
);
35 ret
= radix_tree_insert(&root
->cache_radix
, blocknr
, buf
);
36 radix_tree_preload_end();
44 struct tree_buffer
*find_tree_block(struct ctree_root
*root
, u64 blocknr
)
46 struct tree_buffer
*buf
;
47 buf
= radix_tree_lookup(&root
->cache_radix
, blocknr
);
51 buf
= alloc_tree_block(root
, blocknr
);
61 struct tree_buffer
*read_tree_block(struct ctree_root
*root
, u64 blocknr
)
63 loff_t offset
= blocknr
* CTREE_BLOCKSIZE
;
64 struct tree_buffer
*buf
;
67 buf
= radix_tree_lookup(&root
->cache_radix
, blocknr
);
71 buf
= alloc_tree_block(root
, blocknr
);
74 ret
= pread(root
->fp
, &buf
->node
, CTREE_BLOCKSIZE
, offset
);
75 if (ret
!= CTREE_BLOCKSIZE
) {
80 if (check_tree_block(root
, buf
))
85 int write_tree_block(struct ctree_root
*root
, struct tree_buffer
*buf
)
87 u64 blocknr
= buf
->blocknr
;
88 loff_t offset
= blocknr
* CTREE_BLOCKSIZE
;
91 if (buf
->blocknr
!= buf
->node
.header
.blocknr
)
93 ret
= pwrite(root
->fp
, &buf
->node
, CTREE_BLOCKSIZE
, offset
);
94 if (ret
!= CTREE_BLOCKSIZE
)
99 static int __setup_root(struct ctree_root
*root
, struct ctree_root
*extent_root
,
100 struct ctree_root_info
*info
, int fp
)
104 root
->node
= read_tree_block(root
, info
->tree_root
);
105 root
->extent_root
= extent_root
;
109 struct ctree_root
*open_ctree(char *filename
, struct ctree_super_block
*super
)
111 struct ctree_root
*root
= malloc(sizeof(struct ctree_root
));
112 struct ctree_root
*extent_root
= malloc(sizeof(struct ctree_root
));
116 fp
= open(filename
, O_CREAT
| O_RDWR
);
121 INIT_RADIX_TREE(&root
->cache_radix
, GFP_KERNEL
);
122 INIT_RADIX_TREE(&extent_root
->cache_radix
, GFP_KERNEL
);
123 ret
= pread(fp
, super
, sizeof(struct ctree_super_block
),
124 CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE
));
125 if (ret
== 0 || super
->root_info
.tree_root
== 0) {
126 printf("making new FS!\n");
130 ret
= pread(fp
, super
, sizeof(struct ctree_super_block
),
131 CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE
));
132 if (ret
!= sizeof(struct ctree_super_block
))
136 __setup_root(root
, extent_root
, &super
->root_info
, fp
);
137 __setup_root(extent_root
, extent_root
, &super
->extent_info
, fp
);
141 static int __update_root(struct ctree_root
*root
, struct ctree_root_info
*info
)
143 info
->tree_root
= root
->node
->blocknr
;
147 int write_ctree_super(struct ctree_root
*root
, struct ctree_super_block
*s
)
150 __update_root(root
, &s
->root_info
);
151 __update_root(root
->extent_root
, &s
->extent_info
);
152 ret
= pwrite(root
->fp
, s
, sizeof(*s
), CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE
));
153 if (ret
!= sizeof(*s
)) {
154 fprintf(stderr
, "failed to write new super block err %d\n", ret
);
160 int close_ctree(struct ctree_root
*root
)
164 tree_block_release(root
, root
->node
);
165 if (root
->extent_root
->node
)
166 tree_block_release(root
->extent_root
, root
->extent_root
->node
);
168 printf("on close %d blocks are allocated\n", allocated_blocks
);
172 void tree_block_release(struct ctree_root
*root
, struct tree_buffer
*buf
)
177 if (buf
->count
== 0) {
178 if (!radix_tree_lookup(&root
->cache_radix
, buf
->blocknr
))
180 radix_tree_delete(&root
->cache_radix
, buf
->blocknr
);
181 memset(buf
, 0, sizeof(*buf
));
183 BUG_ON(allocated_blocks
== 0);
This page took 0.057726 seconds and 6 git commands to generate.