vfs: check userland buffers before reading them.
[haiku.git] / src / bin / bfs_tools / lib / bfs.h
blob0d9dff9511f0d972b7cb8b4255c43ebeb377cfaa
1 /* bfs - BFS definitions and helper functions
3 * Initial version by Axel Dörfler, axeld@pinc-software.de
4 * Parts of this code is based on work previously done by Marcus Overhagen
6 * Copyright 2001-2008 pinc Software. All Rights Reserved.
7 * This file may be used under the terms of the MIT License.
8 */
9 #ifndef BFS_H
10 #define BFS_H
13 #include <SupportDefs.h>
15 #if !defined(BEOS_VERSION_DANO) && !defined(__HAIKU__)
16 # define B_BAD_DATA B_ERROR
17 #endif
20 struct __attribute__((packed)) block_run {
21 int32 allocation_group;
22 uint16 start;
23 uint16 length;
25 inline bool operator==(const block_run &run) const;
26 inline bool operator!=(const block_run &run) const;
27 inline bool IsZero() const;
28 inline void SetTo(int32 group, uint16 start, uint16 length = 1);
30 inline static block_run Run(int32 group, uint16 start, uint16 length = 1);
33 typedef block_run inode_addr;
35 //**************************************
38 #define BFS_DISK_NAME_LENGTH 32
40 struct __attribute__((packed)) disk_super_block
42 char name[BFS_DISK_NAME_LENGTH];
43 int32 magic1;
44 int32 fs_byte_order;
45 uint32 block_size;
46 uint32 block_shift;
47 int64 num_blocks;
48 int64 used_blocks;
49 int32 inode_size;
50 int32 magic2;
51 int32 blocks_per_ag;
52 int32 ag_shift;
53 int32 num_ags;
54 int32 flags;
55 block_run log_blocks;
56 int64 log_start;
57 int64 log_end;
58 int32 magic3;
59 inode_addr root_dir;
60 inode_addr indices;
61 int32 pad[8];
64 #define SUPER_BLOCK_FS_LENDIAN 'BIGE' /* BIGE */
66 #define SUPER_BLOCK_MAGIC1 'BFS1' /* BFS1 */
67 #define SUPER_BLOCK_MAGIC2 0xdd121031
68 #define SUPER_BLOCK_MAGIC3 0x15b6830e
70 #define SUPER_BLOCK_CLEAN 'CLEN' /* CLEN */
71 #define SUPER_BLOCK_DIRTY 'DIRT' /* DIRT */
73 //**************************************
75 #define NUM_DIRECT_BLOCKS 12
77 struct __attribute__((packed)) data_stream
79 block_run direct[NUM_DIRECT_BLOCKS];
80 int64 max_direct_range;
81 block_run indirect;
82 int64 max_indirect_range;
83 block_run double_indirect;
84 int64 max_double_indirect_range;
85 int64 size;
88 // **************************************
90 struct bfs_inode;
92 struct __attribute__((packed)) small_data
94 uint32 type;
95 uint16 name_size;
96 uint16 data_size;
97 char name[0]; // name_size long, followed by data
99 inline char *Name();
100 inline uint8 *Data();
101 inline small_data *Next();
102 inline bool IsLast(bfs_inode *inode);
105 // the file name is part of the small_data structure
106 #define FILE_NAME_TYPE 'CSTR'
107 #define FILE_NAME_NAME 0x13
108 #define FILE_NAME_NAME_LENGTH 1
110 // **************************************
112 #define SHORT_SYMLINK_NAME_LENGTH 144 // length incl. terminating '\0'
114 struct __attribute__((packed)) bfs_inode
116 int32 magic1;
117 inode_addr inode_num;
118 int32 uid;
119 int32 gid;
120 int32 mode; // see sys/stat.h
121 int32 flags;
122 int64 create_time;
123 int64 last_modified_time;
124 inode_addr parent;
125 inode_addr attributes;
126 uint32 type; // attribute type
128 int32 inode_size;
129 uint32 etc; // for in-memory structures (unused in OpenBeOS' fs)
131 union __attribute__((packed)) {
132 data_stream data;
133 char short_symlink[SHORT_SYMLINK_NAME_LENGTH];
135 int32 pad[4];
136 small_data small_data_start[0];
139 #define INODE_MAGIC1 0x3bbe0ad9
140 #define INODE_TIME_SHIFT 16
141 #define INODE_FILE_NAME_LENGTH 256
143 enum inode_flags
145 INODE_IN_USE = 0x00000001, // always set
146 INODE_ATTR_INODE = 0x00000004,
147 INODE_LOGGED = 0x00000008, // log changes to the data stream
148 INODE_DELETED = 0x00000010,
149 INODE_EMPTY = 0x00000020,
150 INODE_LONG_SYMLINK = 0x00000040, // symlink in data stream
152 INODE_PERMANENT_FLAGS = 0x0000ffff,
154 INODE_NO_CACHE = 0x00010000,
155 INODE_WAS_WRITTEN = 0x00020000,
156 INODE_NO_TRANSACTION = 0x00040000
159 //**************************************
162 inline int32
163 divide_roundup(int32 num,int32 divisor)
165 return (num + divisor - 1) / divisor;
168 inline int64
169 divide_roundup(int64 num,int32 divisor)
171 return (num + divisor - 1) / divisor;
174 inline int
175 get_shift(uint64 i)
177 int c;
178 c = 0;
179 while (i > 1) {
180 i >>= 1;
181 c++;
183 return c;
186 inline int32
187 round_up(uint32 data)
189 // rounds up to the next off_t boundary
190 return (data + sizeof(off_t) - 1) & ~(sizeof(off_t) - 1);
193 /************************ block_run inline functions ************************/
194 // #pragma mark -
197 inline bool block_run::operator==(const block_run &run) const
199 return allocation_group == run.allocation_group
200 && start == run.start
201 && length == run.length;
204 inline bool block_run::operator!=(const block_run &run) const
206 return allocation_group != run.allocation_group
207 || start != run.start
208 || length != run.length;
211 inline bool block_run::IsZero() const
213 return allocation_group == 0 && start == 0 && length == 0;
216 inline void block_run::SetTo(int32 _group,uint16 _start,uint16 _length)
218 allocation_group = _group;
219 start = _start;
220 length = _length;
223 inline block_run block_run::Run(int32 group, uint16 start, uint16 length)
225 block_run run;
226 run.allocation_group = group;
227 run.start = start;
228 run.length = length;
229 return run;
233 /************************ small_data inline functions ************************/
234 // #pragma mark -
237 inline char *small_data::Name()
239 return name;
242 inline uint8 *small_data::Data()
244 return (uint8 *)name + name_size + 3;
247 inline small_data *small_data::Next()
249 return (small_data *)((uint8 *)(this + 1) + name_size + 3 + data_size + 1);
252 inline bool small_data::IsLast(bfs_inode *inode)
254 return (addr_t)this > (addr_t)inode + inode->inode_size - sizeof(small_data)
255 || name_size == 0;
258 #endif /* BFS_H */