]> code.delx.au - refind/blob - filesystems/fsw_core.h
Added rudimentary debconf support for Debian package.
[refind] / filesystems / fsw_core.h
1 /**
2 * \file fsw_core.h
3 * Core file system wrapper abstraction layer header.
4 */
5
6 /*-
7 * Copyright (c) 2006 Christoph Pfisterer
8 * Portions Copyright (c) The Regents of the University of California.
9 * Portions Copyright (c) UNIX System Laboratories, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are
13 * met:
14 *
15 * * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * * Neither the name of Christoph Pfisterer nor the names of the
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #ifndef _FSW_CORE_H_
41 #define _FSW_CORE_H_
42
43 #include "fsw_base.h"
44 #ifdef __MAKEWITH_GNUEFI
45 #include "fsw_efi_base.h"
46 #endif
47
48 /** Maximum size for a path, specifically symlink target paths. */
49 #define FSW_PATH_MAX (4096)
50
51 /** Helper macro for token concatenation. */
52 #define FSW_CONCAT3(a,b,c) a##b##c
53 /** Expands to the name of a fstype dispatch table (fsw_fstype_table) for a named file system type. */
54 #define FSW_FSTYPE_TABLE_NAME(t) FSW_CONCAT3(fsw_,t,_table)
55
56 /** Indicates that the block cache entry is empty. */
57 #define FSW_INVALID_BNO 0xFFFFFFFFFFFFFFFF
58
59
60 //
61 // Byte-swapping macros
62 //
63
64
65 /**
66 * \name Byte Order Macros
67 * Implements big endian vs. little endian awareness and conversion.
68 */
69 /*@{*/
70
71 typedef fsw_u16 fsw_u16_le;
72 typedef fsw_u16 fsw_u16_be;
73 typedef fsw_u32 fsw_u32_le;
74 typedef fsw_u32 fsw_u32_be;
75 typedef fsw_u64 fsw_u64_le;
76 typedef fsw_u64 fsw_u64_be;
77
78 #define FSW_SWAPVALUE_U16(v) ((((fsw_u16)(v) & 0xff00) >> 8) | \
79 (((fsw_u16)(v) & 0x00ff) << 8))
80 #define FSW_SWAPVALUE_U32(v) ((((fsw_u32)(v) & 0xff000000UL) >> 24) | \
81 (((fsw_u32)(v) & 0x00ff0000UL) >> 8) | \
82 (((fsw_u32)(v) & 0x0000ff00UL) << 8) | \
83 (((fsw_u32)(v) & 0x000000ffUL) << 24))
84 #define FSW_SWAPVALUE_U64(v) ((((fsw_u64)(v) & 0xff00000000000000ULL) >> 56) | \
85 (((fsw_u64)(v) & 0x00ff000000000000ULL) >> 40) | \
86 (((fsw_u64)(v) & 0x0000ff0000000000ULL) >> 24) | \
87 (((fsw_u64)(v) & 0x000000ff00000000ULL) >> 8) | \
88 (((fsw_u64)(v) & 0x00000000ff000000ULL) << 8) | \
89 (((fsw_u64)(v) & 0x0000000000ff0000ULL) << 24) | \
90 (((fsw_u64)(v) & 0x000000000000ff00ULL) << 40) | \
91 (((fsw_u64)(v) & 0x00000000000000ffULL) << 56))
92
93 #ifdef FSW_LITTLE_ENDIAN
94
95 #define fsw_u16_le_swap(v) (v)
96 #define fsw_u16_be_swap(v) FSW_SWAPVALUE_U16(v)
97 #define fsw_u32_le_swap(v) (v)
98 #define fsw_u32_be_swap(v) FSW_SWAPVALUE_U32(v)
99 #define fsw_u64_le_swap(v) (v)
100 #define fsw_u64_be_swap(v) FSW_SWAPVALUE_U64(v)
101
102 #define fsw_u16_le_sip(var)
103 #define fsw_u16_be_sip(var) (var = FSW_SWAPVALUE_U16(var))
104 #define fsw_u32_le_sip(var)
105 #define fsw_u32_be_sip(var) (var = FSW_SWAPVALUE_U32(var))
106 #define fsw_u64_le_sip(var)
107 #define fsw_u64_be_sip(var) (var = FSW_SWAPVALUE_U64(var))
108
109 #else
110 #ifdef FSW_BIG_ENDIAN
111
112 #define fsw_u16_le_swap(v) FSW_SWAPVALUE_U16(v)
113 #define fsw_u16_be_swap(v) (v)
114 #define fsw_u32_le_swap(v) FSW_SWAPVALUE_U32(v)
115 #define fsw_u32_be_swap(v) (v)
116 #define fsw_u64_le_swap(v) FSW_SWAPVALUE_U64(v)
117 #define fsw_u64_be_swap(v) (v)
118
119 #define fsw_u16_le_sip(var) (var = FSW_SWAPVALUE_U16(var))
120 #define fsw_u16_be_sip(var)
121 #define fsw_u32_le_sip(var) (var = FSW_SWAPVALUE_U32(var))
122 #define fsw_u32_be_sip(var)
123 #define fsw_u64_le_sip(var) (var = FSW_SWAPVALUE_U64(var))
124 #define fsw_u64_be_sip(var)
125
126 #else
127 #fail Neither FSW_BIG_ENDIAN nor FSW_LITTLE_ENDIAN are defined
128 #endif
129 #endif
130
131 /*@}*/
132
133
134 //
135 // The following evil hack avoids a lot of casts between generic and fstype-specific
136 // structures.
137 //
138
139 #ifndef VOLSTRUCTNAME
140 #define VOLSTRUCTNAME fsw_volume
141 #else
142 struct VOLSTRUCTNAME;
143 #endif
144 #ifndef DNODESTRUCTNAME
145 #define DNODESTRUCTNAME fsw_dnode
146 #else
147 struct DNODESTRUCTNAME;
148 #endif
149
150
151 /**
152 * Status code type, returned from all functions that can fail.
153 */
154 typedef int fsw_status_t;
155
156 /**
157 * Possible status codes.
158 */
159 enum {
160 FSW_SUCCESS,
161 FSW_OUT_OF_MEMORY,
162 FSW_IO_ERROR,
163 FSW_UNSUPPORTED,
164 FSW_NOT_FOUND,
165 FSW_VOLUME_CORRUPTED,
166 FSW_UNKNOWN_ERROR
167 };
168
169
170 /**
171 * Core: A string with explicit length and encoding information.
172 */
173
174 struct fsw_string {
175 int type; //!< Encoding of the string - empty, ISO-8859-1, UTF8, UTF16
176 int len; //!< Length in characters
177 int size; //!< Total data size in bytes
178 void *data; //!< Data pointer (may be NULL if type is EMPTY or len is zero)
179 };
180
181 /**
182 * Possible string types / encodings. In the case of FSW_STRING_TYPE_EMPTY,
183 * all other members of the fsw_string structure may be invalid.
184 */
185 enum {
186 FSW_STRING_TYPE_EMPTY,
187 FSW_STRING_TYPE_ISO88591,
188 FSW_STRING_TYPE_UTF8,
189 FSW_STRING_TYPE_UTF16,
190 FSW_STRING_TYPE_UTF16_SWAPPED
191 };
192
193 #ifdef FSW_LITTLE_ENDIAN
194 #define FSW_STRING_TYPE_UTF16_LE FSW_STRING_TYPE_UTF16
195 #define FSW_STRING_TYPE_UTF16_BE FSW_STRING_TYPE_UTF16_SWAPPED
196 #else
197 #define FSW_STRING_TYPE_UTF16_LE FSW_STRING_TYPE_UTF16_SWAPPED
198 #define FSW_STRING_TYPE_UTF16_BE FSW_STRING_TYPE_UTF16
199 #endif
200
201 /** Static initializer for an empty string. */
202 #define FSW_STRING_INIT { FSW_STRING_TYPE_EMPTY, 0, 0, NULL }
203
204
205 /* forward declarations */
206
207 struct fsw_dnode;
208 struct fsw_host_table;
209 struct fsw_fstype_table;
210
211 struct fsw_blockcache {
212 fsw_u32 refcount; //!< Reference count
213 fsw_u32 cache_level; //!< Level of importance of this block
214 fsw_u64 phys_bno; //!< Physical block number
215 void *data; //!< Block data buffer
216 };
217
218 /**
219 * Core: Represents a mounted volume.
220 */
221
222 struct fsw_volume {
223 fsw_u32 phys_blocksize; //!< Block size for disk access / file system structures
224 fsw_u32 log_blocksize; //!< Block size for logical file data
225
226 struct DNODESTRUCTNAME *root; //!< Root directory dnode
227 struct fsw_string label; //!< Volume label
228
229 struct fsw_dnode *dnode_head; //!< List of all dnodes allocated for this volume
230
231 struct fsw_blockcache *bcache; //!< Array of block cache entries
232 fsw_u32 bcache_size; //!< Number of entries in the block cache array
233
234 void *host_data; //!< Hook for a host-specific data structure
235 struct fsw_host_table *host_table; //!< Dispatch table for host-specific functions
236 struct fsw_fstype_table *fstype_table; //!< Dispatch table for file system specific functions
237 int host_string_type; //!< String type used by the host environment
238 };
239
240 /**
241 * Core: Represents a "directory node" - a file, directory, symlink, whatever.
242 */
243
244 struct fsw_dnode {
245 fsw_u32 refcount; //!< Reference count
246
247 struct VOLSTRUCTNAME *vol; //!< The volume this dnode belongs to
248 struct DNODESTRUCTNAME *parent; //!< Parent directory dnode
249 struct fsw_string name; //!< Name of this item in the parent directory
250
251 fsw_u64 tree_id; //!< Unique id number (usually the btrfs subvolume)
252 fsw_u64 dnode_id; //!< Unique id number (usually the inode number)
253 int type; //!< Type of the dnode - file, dir, symlink, special
254 fsw_u64 size; //!< Data size in bytes
255
256 struct fsw_dnode *next; //!< Doubly-linked list of all dnodes: previous dnode
257 struct fsw_dnode *prev; //!< Doubly-linked list of all dnodes: next dnode
258 };
259
260 /**
261 * Possible dnode types. FSW_DNODE_TYPE_UNKNOWN may only be used before
262 * fsw_dnode_fill has been called on the dnode.
263 */
264 enum {
265 FSW_DNODE_TYPE_UNKNOWN,
266 FSW_DNODE_TYPE_FILE,
267 FSW_DNODE_TYPE_DIR,
268 FSW_DNODE_TYPE_SYMLINK,
269 FSW_DNODE_TYPE_SPECIAL
270 };
271
272 /**
273 * Core: Stores the mapping of a region of a file to the data on disk.
274 */
275
276 struct fsw_extent {
277 fsw_u32 type; //!< Type of extent specification
278 fsw_u64 log_start; //!< Starting logical block number
279 fsw_u32 log_count; //!< Logical block count
280 fsw_u64 phys_start; //!< Starting physical block number (for FSW_EXTENT_TYPE_PHYSBLOCK only)
281 void *buffer; //!< Allocated buffer pointer (for FSW_EXTENT_TYPE_BUFFER only)
282 };
283
284 /**
285 * Possible extent representation types. FSW_EXTENT_TYPE_INVALID is for shandle's
286 * internal use only, it must not be returned from a get_extent function.
287 */
288 enum {
289 FSW_EXTENT_TYPE_INVALID,
290 FSW_EXTENT_TYPE_SPARSE,
291 FSW_EXTENT_TYPE_PHYSBLOCK,
292 FSW_EXTENT_TYPE_BUFFER
293 };
294
295 /**
296 * Core: An access structure to a dnode's raw data. There can be multiple
297 * shandles per dnode, each of them has its own position pointer.
298 */
299
300 struct fsw_shandle {
301 struct fsw_dnode *dnode; //!< The dnode this handle reads data from
302
303 fsw_u64 pos; //!< Current file pointer in bytes
304 struct fsw_extent extent; //!< Current extent
305 };
306
307 /**
308 * Core: Used in gathering detailed information on a volume.
309 */
310
311 struct fsw_volume_stat {
312 fsw_u64 total_bytes; //!< Total size of data area size in bytes
313 fsw_u64 free_bytes; //!< Bytes still available for storing file data
314 };
315
316 /**
317 * Core: Used in gathering detailed information on a dnode.
318 */
319
320 struct fsw_dnode_stat {
321 fsw_u64 used_bytes; //!< Bytes actually used by the file on disk
322 void *host_data; //!< Hook for a host-specific data structure
323 };
324
325 /**
326 * Type of the timestamp passed into store_time_posix.
327 */
328 enum {
329 FSW_DNODE_STAT_CTIME,
330 FSW_DNODE_STAT_MTIME,
331 FSW_DNODE_STAT_ATIME
332 };
333
334 /**
335 * Core: Function table for a host environment.
336 */
337
338 struct fsw_host_table
339 {
340 int native_string_type; //!< String type used by the host environment
341
342 void EFIAPI (*change_blocksize)(struct fsw_volume *vol,
343 fsw_u32 old_phys_blocksize, fsw_u32 old_log_blocksize,
344 fsw_u32 new_phys_blocksize, fsw_u32 new_log_blocksize);
345 fsw_status_t EFIAPI (*read_block)(struct fsw_volume *vol, fsw_u64 phys_bno, void *buffer);
346 };
347
348 /**
349 * Core: Function table for a file system driver.
350 */
351
352 struct fsw_fstype_table
353 {
354 struct fsw_string name; //!< String giving the name of the file system
355 fsw_u32 volume_struct_size; //!< Size for allocating the fsw_volume structure
356 fsw_u32 dnode_struct_size; //!< Size for allocating the fsw_dnode structure
357
358 fsw_status_t (*volume_mount)(struct VOLSTRUCTNAME *vol);
359 void (*volume_free)(struct VOLSTRUCTNAME *vol);
360 fsw_status_t (*volume_stat)(struct VOLSTRUCTNAME *vol, struct fsw_volume_stat *sb);
361
362 fsw_status_t (*dnode_fill)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno);
363 void (*dnode_free)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno);
364 fsw_status_t (*dnode_stat)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
365 struct fsw_dnode_stat *sb);
366 fsw_status_t (*get_extent)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
367 struct fsw_extent *extent);
368
369 fsw_status_t (*dir_lookup)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
370 struct fsw_string *lookup_name, struct DNODESTRUCTNAME **child_dno);
371 fsw_status_t (*dir_read)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
372 struct fsw_shandle *shand, struct DNODESTRUCTNAME **child_dno);
373 fsw_status_t (*readlink)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
374 struct fsw_string *link_target);
375 };
376
377
378 /**
379 * \name Volume Functions
380 */
381 /*@{*/
382
383 fsw_status_t fsw_mount(void *host_data,
384 struct fsw_host_table *host_table,
385 struct fsw_fstype_table *fstype_table,
386 struct fsw_volume **vol_out);
387 void fsw_unmount(struct fsw_volume *vol);
388 fsw_status_t fsw_volume_stat(struct fsw_volume *vol, struct fsw_volume_stat *sb);
389
390 void fsw_set_blocksize(struct VOLSTRUCTNAME *vol, fsw_u32 phys_blocksize, fsw_u32 log_blocksize);
391 fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u64 phys_bno, fsw_u32 cache_level, void **buffer_out);
392 void fsw_block_release(struct VOLSTRUCTNAME *vol, fsw_u64 phys_bno, void *buffer);
393
394 /*@}*/
395
396
397 /**
398 * \name dnode Functions
399 */
400 /*@{*/
401
402 fsw_status_t fsw_dnode_create_root(struct VOLSTRUCTNAME *vol, fsw_u64 dnode_id, struct DNODESTRUCTNAME **dno_out);
403 fsw_status_t fsw_dnode_create(struct DNODESTRUCTNAME *parent_dno, fsw_u64 dnode_id, int type,
404 struct fsw_string *name, struct DNODESTRUCTNAME **dno_out);
405 fsw_status_t fsw_dnode_create_root_with_tree(struct VOLSTRUCTNAME *vol, fsw_u64 tree_id, fsw_u64 dnode_id, struct DNODESTRUCTNAME **dno_out);
406 fsw_status_t fsw_dnode_create_with_tree(struct DNODESTRUCTNAME *parent_dno, fsw_u64 tree_id, fsw_u64 dnode_id, int type,
407 struct fsw_string *name, struct DNODESTRUCTNAME **dno_out);
408 void fsw_dnode_retain(struct fsw_dnode *dno);
409 void fsw_dnode_release(struct fsw_dnode *dno);
410
411 fsw_status_t fsw_dnode_fill(struct fsw_dnode *dno);
412 fsw_status_t fsw_dnode_stat(struct fsw_dnode *dno, struct fsw_dnode_stat *sb);
413
414 fsw_status_t fsw_dnode_lookup(struct fsw_dnode *dno,
415 struct fsw_string *lookup_name, struct fsw_dnode **child_dno_out);
416 fsw_status_t fsw_dnode_lookup_path(struct fsw_dnode *dno,
417 struct fsw_string *lookup_path, char separator,
418 struct fsw_dnode **child_dno_out);
419 fsw_status_t fsw_dnode_dir_read(struct fsw_shandle *shand, struct fsw_dnode **child_dno_out);
420 fsw_status_t fsw_dnode_readlink(struct fsw_dnode *dno, struct fsw_string *link_target);
421 fsw_status_t fsw_dnode_readlink_data(struct DNODESTRUCTNAME *dno, struct fsw_string *link_target);
422 fsw_status_t fsw_dnode_resolve(struct fsw_dnode *dno, struct fsw_dnode **target_dno_out);
423 void fsw_store_time_posix(struct fsw_dnode_stat *sb, int which, fsw_u32 posix_time);
424 void fsw_store_attr_posix(struct fsw_dnode_stat *sb, fsw_u16 posix_mode);
425 void fsw_store_attr_efi(struct fsw_dnode_stat *sb, fsw_u16 attr);
426
427 /*@}*/
428
429
430 /**
431 * \name shandle Functions
432 */
433 /*@{*/
434
435 fsw_status_t fsw_shandle_open(struct DNODESTRUCTNAME *dno, struct fsw_shandle *shand);
436 void fsw_shandle_close(struct fsw_shandle *shand);
437 fsw_status_t fsw_shandle_read(struct fsw_shandle *shand, fsw_u32 *buffer_size_inout, void *buffer);
438
439 /*@}*/
440
441
442 /**
443 * \name Memory Functions
444 */
445 /*@{*/
446
447 fsw_status_t fsw_alloc_zero(int len, void **ptr_out);
448 fsw_status_t fsw_memdup(void **dest_out, void *src, int len);
449
450 /*@}*/
451
452
453 /**
454 * \name String Functions
455 */
456 /*@{*/
457
458 int fsw_strlen(struct fsw_string *s);
459 int fsw_streq(struct fsw_string *s1, struct fsw_string *s2);
460 int fsw_streq_cstr(struct fsw_string *s1, const char *s2);
461 fsw_status_t fsw_strdup_coerce(struct fsw_string *dest, int type, struct fsw_string *src);
462 void fsw_strsplit(struct fsw_string *lookup_name, struct fsw_string *buffer, char separator);
463
464 void fsw_strfree(struct fsw_string *s);
465
466 /*@}*/
467
468
469 /**
470 * \name Posix Mode Macros
471 * These macros can be used globally to test fields and bits in
472 * Posix-style modes.
473 *
474 * Taken from FreeBSD sys/stat.h.
475 */
476 /*@{*/
477 #ifndef S_IRWXU
478
479 #define S_ISUID 0004000 /* set user id on execution */
480 #define S_ISGID 0002000 /* set group id on execution */
481 #define S_ISTXT 0001000 /* sticky bit */
482
483 #define S_IRWXU 0000700 /* RWX mask for owner */
484 #define S_IRUSR 0000400 /* R for owner */
485 #define S_IWUSR 0000200 /* W for owner */
486 #define S_IXUSR 0000100 /* X for owner */
487
488 #define S_IRWXG 0000070 /* RWX mask for group */
489 #define S_IRGRP 0000040 /* R for group */
490 #define S_IWGRP 0000020 /* W for group */
491 #define S_IXGRP 0000010 /* X for group */
492
493 #define S_IRWXO 0000007 /* RWX mask for other */
494 #define S_IROTH 0000004 /* R for other */
495 #define S_IWOTH 0000002 /* W for other */
496 #define S_IXOTH 0000001 /* X for other */
497
498 #define S_IFMT 0170000 /* type of file mask */
499 #define S_IFIFO 0010000 /* named pipe (fifo) */
500 #define S_IFCHR 0020000 /* character special */
501 #define S_IFDIR 0040000 /* directory */
502 #define S_IFBLK 0060000 /* block special */
503 #define S_IFREG 0100000 /* regular */
504 #define S_IFLNK 0120000 /* symbolic link */
505 #define S_IFSOCK 0140000 /* socket */
506 #define S_ISVTX 0001000 /* save swapped text even after use */
507 #define S_IFWHT 0160000 /* whiteout */
508
509 #define S_ISDIR(m) (((m) & 0170000) == 0040000) /* directory */
510 #define S_ISCHR(m) (((m) & 0170000) == 0020000) /* char special */
511 #define S_ISBLK(m) (((m) & 0170000) == 0060000) /* block special */
512 #define S_ISREG(m) (((m) & 0170000) == 0100000) /* regular file */
513 #define S_ISFIFO(m) (((m) & 0170000) == 0010000) /* fifo or socket */
514 #define S_ISLNK(m) (((m) & 0170000) == 0120000) /* symbolic link */
515 #define S_ISSOCK(m) (((m) & 0170000) == 0140000) /* socket */
516 #define S_ISWHT(m) (((m) & 0170000) == 0160000) /* whiteout */
517
518 #define S_BLKSIZE 512 /* block size used in the stat struct */
519
520 #endif
521 /*@}*/
522
523
524 #endif