Blame


1 d63163af 2007-05-28 devnull /*
2 d63163af 2007-05-28 devnull Supports HFS Plus and HFSX file systems with or without an HFS
3 d63163af 2007-05-28 devnull wrapper.
4 d63163af 2007-05-28 devnull
5 d63163af 2007-05-28 devnull Apple technical note 1150 documents the file system:
6 fa325e9b 2020-01-10 cross
7 d63163af 2007-05-28 devnull http://developer.apple.com/technotes/tn/tn1150.html
8 fa325e9b 2020-01-10 cross
9 d63163af 2007-05-28 devnull Briefly an hfs file system comprises a volume header, an
10 d63163af 2007-05-28 devnull optional journal, and a set of forks.
11 fa325e9b 2020-01-10 cross
12 d63163af 2007-05-28 devnull Most fs metadata resides in forks including a block allocation
13 d63163af 2007-05-28 devnull bitmap, a tree storing extents (q.v.) for forks and bad disk
14 d63163af 2007-05-28 devnull blocks, and a tree storing catalog (file and directory)
15 d63163af 2007-05-28 devnull information.
16 d63163af 2007-05-28 devnull
17 d63163af 2007-05-28 devnull An extent comprises a starting block number and block count.
18 d63163af 2007-05-28 devnull The fs maintains a list of k*NEXTENTS extents for each fork.
19 d63163af 2007-05-28 devnull These are used to map fork block numbers to disk block
20 d63163af 2007-05-28 devnull numbers. A fork's initial extents are in its catalog record
21 d63163af 2007-05-28 devnull or (for fs forks) the volume header. The rest are in the
22 d63163af 2007-05-28 devnull extents tree.
23 d63163af 2007-05-28 devnull
24 d63163af 2007-05-28 devnull Fs trees are layed out (in a fork) as an array of fixed-size
25 d63163af 2007-05-28 devnull nodes. A node comprises a header, a sorted list of
26 d63163af 2007-05-28 devnull variable-size records, and trailing record offsets. The
27 d63163af 2007-05-28 devnull records in interior nodes map keys to (child) node numbers.
28 d63163af 2007-05-28 devnull The records in leaf nodes map keys to data. The nodes at each
29 d63163af 2007-05-28 devnull level in a tree are also sorted via (sibling) node numbers
30 d63163af 2007-05-28 devnull stored in each node header.
31 d63163af 2007-05-28 devnull */
32 d63163af 2007-05-28 devnull
33 d63163af 2007-05-28 devnull typedef struct Extent Extent;
34 d63163af 2007-05-28 devnull typedef struct Fork Fork;
35 d63163af 2007-05-28 devnull typedef struct Inode Inode;
36 d63163af 2007-05-28 devnull typedef struct Tree Tree;
37 d63163af 2007-05-28 devnull typedef struct Node Node;
38 d63163af 2007-05-28 devnull typedef struct Treeref Treeref;
39 d63163af 2007-05-28 devnull typedef struct Key Key;
40 d63163af 2007-05-28 devnull typedef struct Extentkey Extentkey;
41 d63163af 2007-05-28 devnull typedef struct Name Name;
42 d63163af 2007-05-28 devnull typedef struct Catalogkey Catalogkey;
43 d63163af 2007-05-28 devnull typedef struct Hfs Hfs;
44 d63163af 2007-05-28 devnull
45 d63163af 2007-05-28 devnull enum
46 d63163af 2007-05-28 devnull {
47 d63163af 2007-05-28 devnull Hfssig = 0x4244,
48 d63163af 2007-05-28 devnull Hfsplussig = 0x482B,
49 d63163af 2007-05-28 devnull Hfsxsig = 0x4858,
50 d63163af 2007-05-28 devnull Hfsplusmagic = (Hfsplussig<<16)|4,
51 d63163af 2007-05-28 devnull Hfsxmagic = (Hfsxsig<<16)|5,
52 d63163af 2007-05-28 devnull
53 d63163af 2007-05-28 devnull NAMELEN = 255,
54 d63163af 2007-05-28 devnull UTFNAMELEN = NAMELEN*UTFmax,
55 fa325e9b 2020-01-10 cross
56 d63163af 2007-05-28 devnull NEXTENTS = 8,
57 fa325e9b 2020-01-10 cross
58 d63163af 2007-05-28 devnull Dfork = 0, Rfork = 255,
59 fa325e9b 2020-01-10 cross
60 d63163af 2007-05-28 devnull /* fixed cnids */
61 d63163af 2007-05-28 devnull RootpId = 1, RootId, ExtentsId, CatalogId,
62 d63163af 2007-05-28 devnull BadblockId, AllocId, MinuserId = 16,
63 d63163af 2007-05-28 devnull
64 d63163af 2007-05-28 devnull /* size of a few structures on disk */
65 d63163af 2007-05-28 devnull Extentlen = 8, /* Extent */
66 d63163af 2007-05-28 devnull Ndlen = 14, /* Node */
67 d63163af 2007-05-28 devnull Folderlen = 88, Filelen = 248, /* Inode */
68 63408c39 2007-06-08 devnull Adlen = 82, /* Apple double header */
69 63408c39 2007-06-08 devnull Fioff = 50,
70 63408c39 2007-06-08 devnull Filen = 32, /* Finder info */
71 d63163af 2007-05-28 devnull
72 d63163af 2007-05-28 devnull /* values in Node.type */
73 d63163af 2007-05-28 devnull LeafNode = -1, IndexNode, HeaderNode, MapNode,
74 fa325e9b 2020-01-10 cross
75 d63163af 2007-05-28 devnull /* catalog record types */
76 d63163af 2007-05-28 devnull Folder = 1, File, FolderThread, FileThread,
77 d63163af 2007-05-28 devnull
78 1f098efb 2020-08-16 rsc /* some systems have these defined */
79 1f098efb 2020-08-16 rsc #undef IEXEC
80 1f098efb 2020-08-16 rsc #undef IWRITE
81 1f098efb 2020-08-16 rsc #undef IREAD
82 1f098efb 2020-08-16 rsc #undef ISVTX
83 1f098efb 2020-08-16 rsc #undef ISGID
84 1f098efb 2020-08-16 rsc #undef ISUID
85 1f098efb 2020-08-16 rsc #undef IFMT
86 1f098efb 2020-08-16 rsc #undef IFIFO
87 1f098efb 2020-08-16 rsc #undef IFCHR
88 1f098efb 2020-08-16 rsc #undef IFDIR
89 1f098efb 2020-08-16 rsc #undef IFBLK
90 1f098efb 2020-08-16 rsc #undef IFREG
91 1f098efb 2020-08-16 rsc #undef IFLNK
92 1f098efb 2020-08-16 rsc #undef IFSOCK
93 1f098efb 2020-08-16 rsc #undef IFWHT
94 1f098efb 2020-08-16 rsc
95 1f098efb 2020-08-16 rsc #define IEXEC HFS_IEXEC
96 1f098efb 2020-08-16 rsc #define IWRITE HFS_IWRITE
97 1f098efb 2020-08-16 rsc #define IREAD HFS_IREAD
98 1f098efb 2020-08-16 rsc #define ISVTX HFS_ISVTX
99 1f098efb 2020-08-16 rsc #define ISGID HFS_ISGID
100 1f098efb 2020-08-16 rsc #define ISUID HFS_ISUID
101 1f098efb 2020-08-16 rsc #define IFMT HFS_IFMT
102 1f098efb 2020-08-16 rsc #define IFIFO HFS_IFIFO
103 1f098efb 2020-08-16 rsc #define IFCHR HFS_IFCHR
104 1f098efb 2020-08-16 rsc #define IFDIR HFS_IFDIR
105 1f098efb 2020-08-16 rsc #define IFBLK HFS_IFBLK
106 1f098efb 2020-08-16 rsc #define IFREG HFS_IFREG
107 1f098efb 2020-08-16 rsc #define IFLNK HFS_IFLNK
108 1f098efb 2020-08-16 rsc #define IFSOCK HFS_IFSOCK
109 1f098efb 2020-08-16 rsc #define IFWHT HFS_IFWHT
110 1f098efb 2020-08-16 rsc
111 d63163af 2007-05-28 devnull /* permissions in Inode.mode */
112 d63163af 2007-05-28 devnull IEXEC = 00100,
113 d63163af 2007-05-28 devnull IWRITE = 0200,
114 d63163af 2007-05-28 devnull IREAD = 0400,
115 d63163af 2007-05-28 devnull ISTXT = 01000,
116 d63163af 2007-05-28 devnull ISGID = 02000,
117 d63163af 2007-05-28 devnull ISUID = 04000,
118 d63163af 2007-05-28 devnull
119 d63163af 2007-05-28 devnull /* type in Inode.mode */
120 d63163af 2007-05-28 devnull IFMT = 0170000,
121 d63163af 2007-05-28 devnull IFIFO = 0010000,
122 d63163af 2007-05-28 devnull IFCHR = 0020000,
123 d63163af 2007-05-28 devnull IFDIR = 0040000,
124 d63163af 2007-05-28 devnull IFBLK = 0060000,
125 d63163af 2007-05-28 devnull IFREG = 0100000,
126 d63163af 2007-05-28 devnull IFLNK = 0120000,
127 d63163af 2007-05-28 devnull IFSOCK = 0140000,
128 d63163af 2007-05-28 devnull IFWHT = 0160000,
129 d63163af 2007-05-28 devnull };
130 d63163af 2007-05-28 devnull
131 d63163af 2007-05-28 devnull struct Extent
132 d63163af 2007-05-28 devnull {
133 d63163af 2007-05-28 devnull u32int start; /* first block in extent */
134 d63163af 2007-05-28 devnull u32int count; /* number of blocks in extent */
135 d63163af 2007-05-28 devnull };
136 d63163af 2007-05-28 devnull
137 d63163af 2007-05-28 devnull struct Fork
138 d63163af 2007-05-28 devnull {
139 d63163af 2007-05-28 devnull u32int cnid; /* catalog node id (in memory only) */
140 d63163af 2007-05-28 devnull int type; /* Dfork or Rfork (in memory only) */
141 d63163af 2007-05-28 devnull u64int size; /* size in bytes */
142 d63163af 2007-05-28 devnull u32int nblocks;
143 d63163af 2007-05-28 devnull Extent extent[NEXTENTS]; /* initial extents */
144 d63163af 2007-05-28 devnull };
145 d63163af 2007-05-28 devnull
146 d63163af 2007-05-28 devnull /*
147 d63163af 2007-05-28 devnull * In-core catalog record for a file or folder.
148 d63163af 2007-05-28 devnull */
149 d63163af 2007-05-28 devnull struct Inode
150 d63163af 2007-05-28 devnull {
151 d63163af 2007-05-28 devnull u32int cnid;
152 63408c39 2007-06-08 devnull u64int fileid; /* in memory only */
153 d63163af 2007-05-28 devnull u32int mtime; /* modification */
154 d63163af 2007-05-28 devnull u32int ctime; /* attribute modification */
155 d63163af 2007-05-28 devnull u32int atime; /* access */
156 d28cfee1 2007-06-18 devnull u32int nlink; /* in memory only */
157 d63163af 2007-05-28 devnull u32int uid;
158 d63163af 2007-05-28 devnull u32int gid;
159 d63163af 2007-05-28 devnull int mode;
160 d63163af 2007-05-28 devnull u32int special;
161 d63163af 2007-05-28 devnull union{
162 d63163af 2007-05-28 devnull u32int nentries; /* directories */
163 d63163af 2007-05-28 devnull struct{ /* files */
164 d63163af 2007-05-28 devnull Fork dfork;
165 63408c39 2007-06-08 devnull Fork rfork;
166 63408c39 2007-06-08 devnull uchar info[Filen];
167 63408c39 2007-06-08 devnull
168 63408c39 2007-06-08 devnull /* in memory only */
169 63408c39 2007-06-08 devnull int nhdr; /* 0 or Adlen */
170 63408c39 2007-06-08 devnull Fork *fork; /* dfork or rfork */
171 5f6612ba 2008-05-31 rsc } f;
172 5f6612ba 2008-05-31 rsc } u;
173 d63163af 2007-05-28 devnull };
174 d63163af 2007-05-28 devnull
175 d63163af 2007-05-28 devnull struct Tree
176 d63163af 2007-05-28 devnull {
177 d63163af 2007-05-28 devnull int nodesize; /* node size in bytes */
178 d63163af 2007-05-28 devnull u32int nnodes; /* number of nodes in tree */
179 d63163af 2007-05-28 devnull u32int root; /* node number of the tree's root */
180 d63163af 2007-05-28 devnull int height;
181 d63163af 2007-05-28 devnull int maxkeylen; /* maximum key size in bytes */
182 d63163af 2007-05-28 devnull int indexkeylen; /* 0 or length of index node keys */
183 d63163af 2007-05-28 devnull int sensitive; /* are key strings case sensitive */
184 d63163af 2007-05-28 devnull Hfs *fs;
185 d63163af 2007-05-28 devnull Fork *fork;
186 d63163af 2007-05-28 devnull };
187 d63163af 2007-05-28 devnull
188 d63163af 2007-05-28 devnull struct Node
189 d63163af 2007-05-28 devnull {
190 d63163af 2007-05-28 devnull int type; /* type of this node */
191 d63163af 2007-05-28 devnull u32int next; /* next related node or 0 */
192 d63163af 2007-05-28 devnull int nrec; /* number of records in this node */
193 d63163af 2007-05-28 devnull };
194 d63163af 2007-05-28 devnull
195 d63163af 2007-05-28 devnull struct Treeref
196 d63163af 2007-05-28 devnull {
197 d63163af 2007-05-28 devnull Tree *tree;
198 d63163af 2007-05-28 devnull u32int cnid; /* tree->fork->cnid, for debugging prints */
199 fa325e9b 2020-01-10 cross
200 d63163af 2007-05-28 devnull Block *block; /* a node in the tree */
201 d63163af 2007-05-28 devnull u32int nno;
202 d63163af 2007-05-28 devnull Node node;
203 fa325e9b 2020-01-10 cross
204 d63163af 2007-05-28 devnull int rno; /* a record in the node */
205 d63163af 2007-05-28 devnull int klen;
206 fa325e9b 2020-01-10 cross uchar *key;
207 d63163af 2007-05-28 devnull int dlen;
208 d63163af 2007-05-28 devnull uchar *data;
209 d63163af 2007-05-28 devnull };
210 d63163af 2007-05-28 devnull
211 d63163af 2007-05-28 devnull struct Key
212 d63163af 2007-05-28 devnull {
213 d63163af 2007-05-28 devnull int (*_cmp)(uchar *k, int len, int *order, Key *key);
214 d63163af 2007-05-28 devnull void *priv;
215 d63163af 2007-05-28 devnull };
216 d63163af 2007-05-28 devnull
217 d63163af 2007-05-28 devnull struct Extentkey
218 d63163af 2007-05-28 devnull {
219 d63163af 2007-05-28 devnull u32int cnid;
220 d63163af 2007-05-28 devnull int type;
221 d63163af 2007-05-28 devnull u32int bno;
222 d63163af 2007-05-28 devnull };
223 d63163af 2007-05-28 devnull
224 d63163af 2007-05-28 devnull struct Name
225 d63163af 2007-05-28 devnull {
226 d63163af 2007-05-28 devnull int len;
227 d63163af 2007-05-28 devnull Rune name[NAMELEN]; /* only len runes on disk */
228 d63163af 2007-05-28 devnull };
229 d63163af 2007-05-28 devnull
230 d63163af 2007-05-28 devnull struct Catalogkey
231 d63163af 2007-05-28 devnull {
232 d63163af 2007-05-28 devnull u32int parent;
233 d63163af 2007-05-28 devnull union{
234 d63163af 2007-05-28 devnull Name name;
235 d63163af 2007-05-28 devnull uchar *b; /* not yet decoded */
236 5f6612ba 2008-05-31 rsc } u;
237 d63163af 2007-05-28 devnull };
238 d63163af 2007-05-28 devnull
239 d63163af 2007-05-28 devnull struct Hfs
240 d63163af 2007-05-28 devnull {
241 d63163af 2007-05-28 devnull u32int blocksize;
242 d63163af 2007-05-28 devnull u32int nblock;
243 d63163af 2007-05-28 devnull u32int nfree; /* for debugging */
244 d63163af 2007-05-28 devnull int hasbadblocks;
245 d63163af 2007-05-28 devnull Fork alloc; /* block allocation bitmap */
246 d63163af 2007-05-28 devnull Fork extentsfork;
247 d63163af 2007-05-28 devnull Fork catalogfork;
248 d63163af 2007-05-28 devnull Tree extents; /* Extentkey -> Extent[NEXTENT] */
249 d63163af 2007-05-28 devnull Tree catalog; /* Catalogkey -> Catalogkey + Inode */
250 d28cfee1 2007-06-18 devnull u32int hlinkparent; /* 0 or cnid */
251 d63163af 2007-05-28 devnull Disk *disk;
252 d63163af 2007-05-28 devnull Fsys *fsys;
253 d63163af 2007-05-28 devnull };