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