]> git.pld-linux.org Git - packages/kernel.git/blob - hfsplus-20011213.patch
- obsolete
[packages/kernel.git] / hfsplus-20011213.patch
1 diff -urN -x CVS linux-bk/Documentation/Configure.help linux-hfsplus/Documentation/Configure.help
2 --- linux-bk/Documentation/Configure.help       Sun Mar  4 16:18:35 2001
3 +++ linux-hfsplus/Documentation/Configure.help  Sat Sep 15 17:03:12 2001
4 @@ -11383,6 +11383,24 @@
5    compile it as a module, say M here and read
6    Documentation/modules.txt.
7  
8 +Apple Extended file system support (read-only) (EXPERIMENTAL)
9 +CONFIG_HFSPLUS_FS
10 +  If you say Y here, you will be able to mount extended format
11 +  Macintosh-formatted hard drive partitions with read-only access.
12 +  Most of the UNIX related filesystem data saved by Mac OSX should
13 +  be readable.
14 +
15 +  This file system is often called HFS+ and was introduced with
16 +  MacOS 8. It includes all Mac specific filesystem data such as
17 +  data forks and creator codes, but it also has several UNIX
18 +  style features such as file ownership and permissions. No Mac
19 +  specific data can currently be accessed with this driver.
20 +
21 +  This file system is also available as a module ( = code which can
22 +  be inserted in and removed from the running kernel whenever you
23 +  want). The module is called hfsplus.o. If you want to compile it
24 +  as a module, say M here and read Documentation/modules.txt.
25 +
26  ROM file system support
27  CONFIG_ROMFS_FS
28    This is a very small read-only file system mainly intended for
29 diff -urN -x CVS linux-bk/MAINTAINERS linux-hfsplus/MAINTAINERS
30 --- linux-bk/MAINTAINERS        Sun Mar  4 16:18:16 2001
31 +++ linux-hfsplus/MAINTAINERS   Sat Sep 15 17:03:52 2001
32 @@ -503,6 +503,12 @@
33  L:      linux-kernel@vger.kernel.org
34  S:      Maintained
35  
36 +HFSPLUS FILESYSTEM
37 +P:     Brad Boyer
38 +M:     flar@allandria.com
39 +W:     http://sourceforge.net/projects/linux-hfsplus/
40 +S:     Maintained
41 +
42  HGA FRAMEBUFFER DRIVER
43  P:     Ferenc Bakonyi
44  M:     fero@drama.obuda.kando.hu
45 diff -urN -x CVS linux-bk/fs/Config.in linux-hfsplus/fs/Config.in
46 --- linux-bk/fs/Config.in       Sun Mar  4 16:26:05 2001
47 +++ linux-hfsplus/fs/Config.in  Tue Apr 10 22:48:28 2001
48 @@ -18,6 +18,8 @@
49  
50  dep_tristate 'Apple Macintosh file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
51  
52 +dep_tristate 'Apple Extended HFS file system support (EXPERIMENTAL)' CONFIG_HFSPLUS_FS $CONFIG_EXPERIMENTAL
53 +
54  dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
55  
56  # msdos file systems
57 diff -urN -x CVS linux-bk/fs/Makefile linux-hfsplus/fs/Makefile
58 --- linux-bk/fs/Makefile        Sun Mar  4 16:26:05 2001
59 +++ linux-hfsplus/fs/Makefile   Tue Apr 10 22:48:28 2001
60 @@ -38,6 +38,7 @@
61  subdir-$(CONFIG_ISO9660_FS)    += isofs
62  subdir-$(CONFIG_DEVFS_FS)      += devfs
63  subdir-$(CONFIG_HFS_FS)                += hfs
64 +subdir-$(CONFIG_HFSPLUS_FS)    += hfsplus
65  subdir-$(CONFIG_VXFS_FS)       += freevxfs
66  subdir-$(CONFIG_NFS_FS)                += nfs
67  subdir-$(CONFIG_NFSD)          += nfsd
68 diff -urN -x CVS linux-bk/fs/hfsplus/Makefile linux-hfsplus/fs/hfsplus/Makefile
69 --- linux-bk/fs/hfsplus/Makefile        Wed Dec 31 16:00:00 1969
70 +++ linux-hfsplus/fs/hfsplus/Makefile   Fri Sep 21 00:42:03 2001
71 @@ -0,0 +1,17 @@
72 +#
73 +# Makefile for the Linux hfsplus filesystem routines.
74 +#
75 +# Note! Dependencies are done automagically by 'make dep', which also
76 +# removes any old dependencies. DON'T put your own dependencies here
77 +# unless it's something special (not a .c file).
78 +#
79 +# Note 2! The CFLAGS definitions are now in the main makefile.
80 +
81 +O_TARGET := hfsplus.o
82 +
83 +obj-y    := super.o options.o inode.o extents.o catalog.o dir.o btree.o \
84 +               bnode.o brec.o bfind.o btiter.o tables.o unicode.o wrapper.o
85 +
86 +obj-m    := $(O_TARGET)
87 +
88 +include $(TOPDIR)/Rules.make
89 diff -urN -x CVS linux-bk/fs/hfsplus/bfind.c linux-hfsplus/fs/hfsplus/bfind.c
90 --- linux-bk/fs/hfsplus/bfind.c Wed Dec 31 16:00:00 1969
91 +++ linux-hfsplus/fs/hfsplus/bfind.c    Mon Nov  5 00:09:43 2001
92 @@ -0,0 +1,236 @@
93 +/*
94 + *  linux/fs/hfsplus/bfind.c
95 + *
96 + * Copyright (C) 2001
97 + * Brad Boyer (flar@allandria.com)
98 + *
99 + * Search routines for btrees
100 + */
101 +
102 +#include <linux/hfsplus_fs.h>
103 +
104 +/* Find the record in bnode that best matches key (not greater than...)*/
105 +static hfsp_u16 hfsplus_find_rec(hfsplus_bnode *bnode, hfsplus_btree_key *key,
106 +                                int *error)
107 +{
108 +       hfsplus_btree_key tmpkey;
109 +       int cmpval;
110 +       hfsp_u16 b, m, e, keylen;
111 +
112 +       b = 0;
113 +       e = bnode->num_recs - 1;
114 +       *error = 0;
115 +       while(b <= e) {
116 +               m = (e + b) / 2;
117 +               keylen = hfsplus_brec_key(bnode, m, &tmpkey, sizeof(tmpkey));
118 +               if(!keylen) {
119 +                       printk("HFS+-fs: missing key in B*Tree\n");
120 +                       *error = -EIO;
121 +                       return 0xFFFF;
122 +               }
123 +               cmpval = bnode->tree->keycmp(&tmpkey, key);
124 +               if(!cmpval)
125 +                       return m;
126 +               if(cmpval < 0) {
127 +                       b = m + 1;
128 +               } else {
129 +                       e = m - 1;
130 +               }
131 +       }
132 +       if(e == 0xFFFF) {
133 +               *error = -ENOENT;
134 +               return 0xFFFF;
135 +       }
136 +       return e;
137 +}
138 +
139 +/* Traverse a B*Tree from the root to a leaf finding best fit to key */
140 +/* Return allocated copy of node found, set recnum to best record */
141 +static hfsplus_bnode *hfsplus_find_leaf(hfsplus_btree *tree,
142 +                                       hfsplus_btree_key *key,
143 +                                       hfsp_u16 *recnum, int *error)
144 +{
145 +       hfsplus_bnode *curr, *last, *retval;
146 +       int localerr;
147 +       hfsp_u32 next;
148 +       hfsp_u16 rec, off, klen;
149 +       hfsp_lword data;
150 +
151 +       *error = -EIO;
152 +       last = retval = NULL;
153 +       curr = hfsplus_get_bnode(tree, tree->root);
154 +       if(!curr || !curr->height || (curr->height > tree->depth)) {
155 +               printk("HFS+-fs: Found bad root node in B*Tree\n");
156 +               return NULL;
157 +       }
158 +
159 +       for(;;) {
160 +               rec = hfsplus_find_rec(curr, key, &localerr);
161 +               if(rec >= curr->num_recs) {
162 +                       if(localerr)
163 +                               *error = localerr;
164 +                       goto cleanup;
165 +               }
166 +               if(curr->kind == HFSPLUS_NODE_LEAF) {
167 +                       /* Found it */
168 +                       retval = curr;
169 +                       *recnum = rec;
170 +                       *error = 0;
171 +                       goto cleanup;
172 +               }
173 +               if(curr->kind != HFSPLUS_NODE_NDX) {
174 +                       printk("HFS+-fs: non-keyed B*Tree node in index\n");
175 +                       goto cleanup;
176 +               }
177 +               if(last) {
178 +                       hfsplus_put_bnode(last);
179 +                       last = NULL;
180 +               }
181 +
182 +               klen = hfsplus_brec_keylen(curr, rec);
183 +               if(!klen) {
184 +                       printk("HFS+-fs: bad index key in B*Tree\n");
185 +                       goto cleanup;
186 +               }
187 +               if(hfsplus_brec_lenoff(curr, rec, &off) < klen + 4) {
188 +                       printk("HFS+-fs: invalid index record in B*Tree\n");
189 +                       goto cleanup;
190 +               }
191 +               if(hfsplus_bnode_copybytes(curr, data, off + klen, 4) != 4) {
192 +                       printk("HFS+-fs: unable to follow index in B*Tree\n");
193 +                       goto cleanup;
194 +               }
195 +               next = hfsp_get_hl(data);
196 +
197 +               last = curr;
198 +               curr = hfsplus_get_bnode(tree, next);
199 +               if(!curr) {
200 +                       printk("HFS+-fs: failed to get next node in B*Tree\n");
201 +                       goto cleanup;
202 +               }
203 +               if(!curr->height || (curr->height != (last->height - 1))) {
204 +                       printk("HFS+-fs: inconsistency in B*Tree height\n");
205 +                       goto cleanup;
206 +               }
207 +       } /* end of for(;;) */
208 + cleanup:
209 +       if(last && (last != retval))
210 +               hfsplus_put_bnode(last);
211 +       if(curr && (curr != retval))
212 +               hfsplus_put_bnode(curr);
213 +       return retval;
214 +}
215 +
216 +/* take in tree, key to find, buffer, sizeof buffer */
217 +/* return error code, set entry_len to actual value on success */
218 +/* will only return an exact match */
219 +int hfsplus_btfind_exact(hfsplus_btree *tree, hfsplus_btree_key *key,
220 +                        void *entry, int *entry_len)
221 +{
222 +       hfsplus_bnode *node;
223 +       hfsplus_btree_key tmpkey;
224 +       int err;
225 +       hfsp_u16 rec, off, keylen, datalen;
226 +
227 +       if(!tree || !key || !entry || !entry_len)
228 +               return -EIO;
229 +
230 +       node = hfsplus_find_leaf(tree, key, &rec, &err);
231 +       if(!node)
232 +               return err;
233 +       err = -EIO;
234 +       if(!(keylen = hfsplus_brec_key(node, rec, &tmpkey, sizeof(tmpkey)))) {
235 +               printk("HFS+-fs: unable to read key from B*Tree record\n");
236 +               goto out;
237 +       }
238 +       if(tree->keycmp(key, &tmpkey)) {
239 +               err = -ENOENT;
240 +               goto out;
241 +       }
242 +
243 +       datalen = hfsplus_brec_lenoff(node, rec, &off) - keylen;
244 +       if((datalen <= 0) || (datalen > *entry_len)) {
245 +               printk("HFS+-fs: bad entry length in B*Tree\n");
246 +               goto out;
247 +       }
248 +       if(!hfsplus_bnode_copybytes(node, entry, off + keylen, datalen)) {
249 +               printk("HFS+-fs: unable to read record in B*Tree\n");
250 +               goto out;
251 +       }
252 +       *entry_len = datalen;
253 +       err = 0;
254 + out:
255 +       hfsplus_put_bnode(node);
256 +       return err;
257 +}
258 +
259 +/* take in tree, key to find, buffer, sizeof buffer; return error code */
260 +/* updates key to actual record found, updates length of actual entry */
261 +/* will return largest key not greater than search key */
262 +int hfsplus_btfind(hfsplus_btree *tree, hfsplus_btree_key *key, void *entry,
263 +                  int *entry_len)
264 +{
265 +       hfsplus_bnode *node;
266 +       int err;
267 +       hfsp_u16 rec, off, keylen, datalen;
268 +
269 +       if(!tree || !key || !entry || !entry_len)
270 +               return -EIO;
271 +
272 +       node = hfsplus_find_leaf(tree, key, &rec, &err);
273 +       if(!node)
274 +               return err;
275 +       err = -EIO;
276 +       if(!(keylen = hfsplus_brec_keylen(node, rec))) {
277 +               printk("HFS+-fs: unable to read key from B*Tree record\n");
278 +               goto out;
279 +       }
280 +
281 +       datalen = hfsplus_brec_lenoff(node, rec, &off) - keylen;
282 +       if((datalen <= 0) || (datalen > *entry_len)) {
283 +               printk("HFS+-fs: bad entry length in B*Tree\n");
284 +               goto out;
285 +       }
286 +       if(!hfsplus_bnode_copybytes(node, key, off, keylen)) {
287 +               printk("HFS+-fs: unable to copy key from B*Tree\n");
288 +               goto out;
289 +       }
290 +       if(!hfsplus_bnode_copybytes(node, entry, off + keylen, datalen)) {
291 +               printk("HFS+-fs: unable to read record in B*Tree\n");
292 +               goto out;
293 +       }
294 +       *entry_len = datalen;
295 +       err = 0;
296 + out:
297 +       hfsplus_put_bnode(node);
298 +       return err;
299 +}
300 +
301 +int hfsplus_btiter_find(hfsplus_btiter *iter, hfsplus_btree_key *key)
302 +{
303 +       hfsplus_bnode *node;
304 +       int err;
305 +       hfsplus_btree_key tmpkey;
306 +       hfsp_u16 rec, keylen;
307 +
308 +       if(!iter || !key || !iter->tree)
309 +               return -EIO;
310 +
311 +       if((node = hfsplus_find_leaf(iter->tree, key, &rec, &err)) == NULL)
312 +               return err;
313 +       if(!(keylen = hfsplus_brec_key(node, rec, &tmpkey, sizeof(tmpkey)))) {
314 +               printk("HFS+-fs: unable to read key from B*Tree record\n");
315 +               err = -EIO;
316 +               goto out;
317 +       }
318 +       if(node->tree->keycmp(key, &tmpkey)) {
319 +               err = -ENOENT;
320 +               goto out;
321 +       }
322 +       iter->node = node->this;
323 +       iter->rec = rec;
324 +       err = 0;
325 + out:
326 +       hfsplus_put_bnode(node);
327 +       return err;
328 +}
329 diff -urN -x CVS linux-bk/fs/hfsplus/bnode.c linux-hfsplus/fs/hfsplus/bnode.c
330 --- linux-bk/fs/hfsplus/bnode.c Wed Dec 31 16:00:00 1969
331 +++ linux-hfsplus/fs/hfsplus/bnode.c    Mon Nov  5 00:07:58 2001
332 @@ -0,0 +1,195 @@
333 +/*
334 + *  linux/fs/hfsplus/bnode.c
335 + *
336 + * Copyright (C) 2001
337 + * Brad Boyer (flar@allandria.com)
338 + *
339 + * Handle basic btree node operations
340 + */
341 +
342 +#include <linux/string.h>
343 +#include <linux/slab.h>
344 +#include <linux/pagemap.h>
345 +#include <linux/fs.h>
346 +#include <linux/hfsplus_fs.h>
347 +#include <linux/hfsplus_raw.h>
348 +
349 +/* Convert a node, offset to page number in tree */
350 +static inline unsigned long hfsplus_pagenum(hfsplus_bnode *node, hfsp_u16 off)
351 +{
352 +       return ((node->this * node->tree->node_size) + off) >> PAGE_SHIFT;
353 +}
354 +
355 +/* Convert a node, offset to page offset */
356 +static inline unsigned long hfsplus_pageoff(hfsplus_bnode *node, hfsp_u16 off)
357 +{
358 +       return ((node->this * node->tree->node_size) + off) & (PAGE_SIZE - 1);
359 +}
360 +
361 +/* Dump a page we loaded with hfsplus_get_page */
362 +static inline void hfsplus_put_page(hfsplus_bnode *node)
363 +{
364 +       if(node->page) {
365 +               UnlockPage(node->page);
366 +               kunmap(node->page);
367 +               page_cache_release(node->page);
368 +               node->page = NULL;
369 +       }
370 +}
371 +
372 +/* Get the give page associated with the inode */
373 +static struct page *hfsplus_get_page(hfsplus_bnode *node, unsigned long n)
374 +{
375 +       struct address_space *mapping;
376 +       struct page *page;
377 +
378 +       if(!node || !node->tree)
379 +               return NULL;
380 +
381 +       if(!node->inode) {
382 +               node->inode = iget(node->tree->sb, node->tree->cnid);
383 +               if(!node->inode) {
384 +                       printk("HFS+-fs: Failed load of B*Tree data\n");
385 +                       return NULL;
386 +               }
387 +       }
388 +       mapping = node->inode->i_mapping;
389 +       if(node->page) {
390 +               if(node->page->index == n) {
391 +                       page = node->page;
392 +                       goto check_page;
393 +               }
394 +               hfsplus_put_page(node);
395 +       }
396 +       page = read_cache_page(mapping, n, mapping->a_ops->readpage, NULL);
397 +       if(!IS_ERR(page)) {
398 +               lock_page(page);
399 +               kmap(page);
400 +       check_page:
401 +               if(!Page_Uptodate(page))
402 +                       goto put_page;
403 +               if(PageError(page))
404 +                       goto put_page;
405 +       }
406 +       node->page = page;
407 +       return page;
408 + put_page:
409 +       hfsplus_put_page(node);
410 +       return NULL;
411 +}
412 +
413 +/* Fill the node->page element for the given offset */
414 +static inline struct page *hfsplus_fill_page(hfsplus_bnode *node, hfsp_u16 off)
415 +{
416 +       return hfsplus_get_page(node, hfsplus_pagenum(node, off));
417 +}
418 +
419 +/* Copy a specified range of bytes from the raw data of a node */
420 +hfsp_u16 hfsplus_bnode_copybytes(hfsplus_bnode *node, void *buf,
421 +                                hfsp_u16 off, hfsp_u16 len)
422 +{
423 +       char *kaddr;
424 +
425 +       if(hfsplus_pagenum(node, off) == hfsplus_pagenum(node, off+len-1)) {
426 +               /* All on one page */
427 +               if(!hfsplus_fill_page(node, off)) {
428 +                       return 0;
429 +               }
430 +               kaddr = (char *)page_address(node->page);
431 +               memcpy(buf, kaddr + hfsplus_pageoff(node, off), len);
432 +       } else {
433 +               /* Multiple pages (should be rare) */
434 +               unsigned long poff;
435 +               size_t tocopy;
436 +               hfsp_u16 curr = 0;
437 +
438 +               while(curr < len) {
439 +                       if(!hfsplus_fill_page(node, off + curr)) {
440 +                               return curr;
441 +                       }
442 +                       poff = hfsplus_pageoff(node, off + curr);
443 +                       tocopy = PAGE_SIZE - poff;
444 +                       if(curr + tocopy > len)
445 +                               tocopy = len - curr;
446 +                       kaddr = (char *)page_address(node->page);
447 +                       memcpy(buf + curr, kaddr + poff, tocopy);
448 +                       curr += tocopy;
449 +               }
450 +       }
451 +
452 +       return len;
453 +}
454 +
455 +/* Check for valid kind/height pairs , return 0 for bad pairings */
456 +static int hfsplus_check_kh(hfsplus_btree *tree, hfsp_u8 kind, hfsp_u8 height)
457 +{
458 +       if((kind == HFSPLUS_NODE_HEAD) || (kind == HFSPLUS_NODE_MAP)) {
459 +               if(height != 0)
460 +                       goto hk_error;
461 +       } else if(kind == HFSPLUS_NODE_LEAF) {
462 +               if(height != 1)
463 +                       goto hk_error;
464 +       } else if(kind == HFSPLUS_NODE_NDX) {
465 +               if((height <= 1) || (height > tree->depth)) 
466 +                       goto hk_error;
467 +       } else {
468 +               printk("HFS+-fs: unknown node type in B*Tree\n");
469 +               return 0;
470 +       }
471 +       return 1;
472 + hk_error:
473 +       printk("HFS+-fs: corrupt node height in B*Tree\n");
474 +       return 0;
475 +}
476 +
477 +/* Load a particular node out of a tree */
478 +hfsplus_bnode *hfsplus_get_bnode(hfsplus_btree *tree, hfsp_u32 num)
479 +{
480 +       hfsplus_bnode *node;
481 +       hfsplus_btree_node_desc desc;
482 +       hfsp_u16 bytes;
483 +
484 +       if(num >= tree->node_count) {
485 +               printk("HFS+-fs: request for non-existent node in B*Tree\n");
486 +               return NULL;
487 +       }
488 +
489 +       node = kmalloc(sizeof(hfsplus_bnode), GFP_KERNEL);
490 +       if(!node)
491 +               return NULL;
492 +       node->tree = tree;
493 +       node->page = NULL;
494 +       node->inode = NULL;
495 +       node->this = num;
496 +       bytes = hfsplus_bnode_copybytes(node, &desc, 0,
497 +                                       sizeof(hfsplus_btree_node_desc));
498 +       if(bytes != sizeof(hfsplus_btree_node_desc)) {
499 +               printk("HFS+-fs: failed to read node descriptor in B*Tree\n");
500 +               goto free_node;
501 +       }
502 +       node->prev = hfsp_get_hl(desc.prev);
503 +       node->next = hfsp_get_hl(desc.next);
504 +       node->num_recs = hfsp_get_hs(desc.num_rec);
505 +       node->kind = desc.kind;
506 +       node->height = desc.height;
507 +       if(!hfsplus_check_kh(tree, desc.kind, desc.height))
508 +               goto free_node;
509 +       return node;
510 + free_node:
511 +       kfree(node);
512 +       return NULL;
513 +}
514 +
515 +/* Dispose of resources used by a node */
516 +void hfsplus_put_bnode(hfsplus_bnode *node)
517 +{
518 +       if(node) {
519 +               if(node->page)
520 +                       hfsplus_put_page(node);
521 +               if(node->inode) {
522 +                       iput(node->inode);
523 +                       node->inode = NULL;
524 +               }
525 +               kfree(node);
526 +       }
527 +}
528 diff -urN -x CVS linux-bk/fs/hfsplus/brec.c linux-hfsplus/fs/hfsplus/brec.c
529 --- linux-bk/fs/hfsplus/brec.c  Wed Dec 31 16:00:00 1969
530 +++ linux-hfsplus/fs/hfsplus/brec.c     Mon Nov  5 00:09:43 2001
531 @@ -0,0 +1,111 @@
532 +/*
533 + *  linux/fs/hfsplus/brec.c
534 + *
535 + * Copyright (C) 2001
536 + * Brad Boyer (flar@allandria.com)
537 + *
538 + * Handle individual btree records
539 + */
540 +
541 +#include <linux/hfsplus_fs.h>
542 +#include <linux/hfsplus_raw.h>
543 +
544 +/* Get the offset of the given record in the given node */
545 +hfsp_u16 hfsplus_brec_off(hfsplus_bnode *node, hfsp_u16 rec)
546 +{
547 +       hfsp_word retval;
548 +       hfsp_u16 dataoff;
549 +
550 +       dataoff = node->tree->node_size - (rec + 1) * 2;
551 +       if(hfsplus_bnode_copybytes(node, retval, dataoff, 2) != 2)
552 +               return 0;
553 +       return hfsp_get_hs(retval);
554 +}
555 +
556 +/* Get the length of the given record in the given node */
557 +hfsp_u16 hfsplus_brec_len(hfsplus_bnode *node, hfsp_u16 rec)
558 +{
559 +       unsigned char retval[4];
560 +       hfsp_u16 dataoff;
561 +
562 +       dataoff = node->tree->node_size - (rec + 2) * 2;
563 +       if(hfsplus_bnode_copybytes(node, retval, dataoff, 4) != 4)
564 +               return 0;
565 +       return hfsp_get_hs(retval) - hfsp_get_hs(retval + 2);
566 +}
567 +
568 +/* Get the length and offset of the given record in the given node */
569 +hfsp_u16 hfsplus_brec_lenoff(hfsplus_bnode *node, hfsp_u16 rec, hfsp_u16 *off)
570 +{
571 +       unsigned char retval[4];
572 +       hfsp_u16 dataoff;
573 +
574 +       dataoff = node->tree->node_size - (rec + 2) * 2;
575 +       if(hfsplus_bnode_copybytes(node, retval, dataoff, 4) != 4) {
576 +               return 0;
577 +       }
578 +       *off = hfsp_get_hs(retval + 2);
579 +       return hfsp_get_hs(retval) - *off;
580 +}
581 +
582 +/* Copy a record from a node into a buffer, return the actual length */
583 +hfsp_u16 hfsplus_brec_data(hfsplus_bnode *node, hfsp_u16 rec, char *buf,
584 +                          hfsp_u16 len)
585 +{
586 +       hfsp_u16 recoff, reclen, cplen;
587 +
588 +       reclen = hfsplus_brec_lenoff(node, rec, &recoff);
589 +       if(!reclen)
590 +               return 0;
591 +       cplen = (reclen>len) ? len : reclen;
592 +       if(hfsplus_bnode_copybytes(node, buf, recoff, cplen) != cplen)
593 +               return 0;
594 +       return reclen;
595 +}
596 +
597 +/* Get the length of the key from a keyed record */
598 +hfsp_u16 hfsplus_brec_keylen(hfsplus_bnode *node, hfsp_u16 rec)
599 +{
600 +       hfsp_u16 klsz, retval, recoff;
601 +       unsigned char buf[2];
602 +
603 +       if((node->kind != HFSPLUS_NODE_NDX)&&(node->kind != HFSPLUS_NODE_LEAF))
604 +               return 0;
605 +
606 +       klsz = (node->tree->attributes & HFSPLUS_TREE_BIGKEYS) ? 2 : 1;
607 +       if((node->kind == HFSPLUS_NODE_NDX) &&
608 +          !(node->tree->attributes & HFSPLUS_TREE_VAR_NDXKEY_SIZE)) {
609 +               retval = node->tree->max_key_len;
610 +       } else {
611 +               recoff = hfsplus_brec_off(node, rec);
612 +               if(!recoff)
613 +                       return 0;
614 +               if(hfsplus_bnode_copybytes(node, buf, recoff, klsz) != klsz)
615 +                       return 0;
616 +               if(klsz == 1)
617 +                       retval = buf[0];
618 +               else
619 +                       retval = hfsp_get_hs(buf);
620 +       }
621 +       return (retval + klsz + 1) & 0xFFFE;
622 +}
623 +
624 +/* Get a copy of the key of the given record, returns real key length */
625 +hfsp_u16 hfsplus_brec_key(hfsplus_bnode *node, hfsp_u16 rec, void *buf,
626 +                         hfsp_u16 len)
627 +{
628 +       hfsp_u16 recoff, reclen, keylen, tocopy;
629 +
630 +       reclen = hfsplus_brec_lenoff(node, rec, &recoff);
631 +       keylen = hfsplus_brec_keylen(node, rec);
632 +       if(!reclen || !keylen)
633 +               return 0;
634 +       if(keylen > reclen) {
635 +               printk("HFS+-fs: corrupt key length in B*Tree\n");
636 +               return 0;
637 +       }
638 +       tocopy = (len > keylen) ? keylen : len;
639 +       if(hfsplus_bnode_copybytes(node, buf, recoff, tocopy) != tocopy)
640 +               return 0;
641 +       return keylen;
642 +}
643 diff -urN -x CVS linux-bk/fs/hfsplus/btiter.c linux-hfsplus/fs/hfsplus/btiter.c
644 --- linux-bk/fs/hfsplus/btiter.c        Wed Dec 31 16:00:00 1969
645 +++ linux-hfsplus/fs/hfsplus/btiter.c   Fri Sep 21 20:56:21 2001
646 @@ -0,0 +1,115 @@
647 +/*
648 + *  linux/fs/hfsplus/btiter.c
649 + *
650 + * Copyright (C) 2001
651 + * Brad Boyer (flar@allandria.com)
652 + *
653 + * Iterators for btrees
654 + */
655 +
656 +#include <linux/hfsplus_fs.h>
657 +
658 +void hfsplus_btiter_setup(hfsplus_btiter *iter, hfsplus_btree *tree)
659 +{
660 +       iter->tree = tree;
661 +       iter->node = 0;
662 +       iter->rec = 0;
663 +}
664 +
665 +int hfsplus_btiter_move(hfsplus_btiter *iter, int cnt)
666 +{
667 +       hfsplus_bnode *node;
668 +       int err = -EIO;
669 +
670 +       if(!iter || !iter->tree)
671 +               return err;
672 +       if((cnt < -0xFFFF) || (cnt > 0xFFFF))
673 +               return err;
674 +       if(!iter->node)
675 +               return -ENOENT;
676 +
677 + get_node:
678 +       if(!(node = hfsplus_get_bnode(iter->tree, iter->node)))
679 +               return err;
680 + start_node:
681 +       if(node->kind != HFSPLUS_NODE_LEAF) {
682 +               printk("HFS+-fs: found entry of bad type\n");
683 +               goto out;
684 +       }
685 +       if(iter->rec >= node->num_recs)
686 +               goto out;
687 +
688 +       if((iter->rec + cnt >= 0) && (iter->rec + cnt < node->num_recs)) {
689 +               iter->rec += cnt;
690 +               err = 0;
691 +               goto out;
692 +       }
693 +       if(cnt < 0) {
694 +               iter->node = node->prev;
695 +               if(!iter->node) {
696 +                       err = -ENOENT;
697 +                       goto out;
698 +               }
699 +               hfsplus_put_bnode(node);
700 +               if(!(node = hfsplus_get_bnode(iter->tree, iter->node)))
701 +                       return err;
702 +               cnt += iter->rec + 1;
703 +               iter->rec = node->num_recs - 1;
704 +               goto start_node;
705 +       }
706 +       iter->node = node->next;
707 +       if(!iter->node) {
708 +               err = -ENOENT;
709 +               goto out;
710 +       }
711 +       cnt -= node->num_recs - iter->rec;
712 +       iter->rec = 0;
713 +       hfsplus_put_bnode(node);
714 +       goto get_node;
715 + out:
716 +       hfsplus_put_bnode(node);
717 +       return err;
718 +}
719 +
720 +int hfsplus_btiter_get(hfsplus_btiter *iter, hfsplus_btree_key *key,
721 +                      void *entry, int *entry_len)
722 +{
723 +       hfsplus_bnode *node;
724 +       int err = -EIO;
725 +       hfsp_u16 rec, off, keylen, datalen;
726 +
727 +       if(!iter || !iter->tree || !key || !entry || !entry_len)
728 +               return err;
729 +
730 +       if((node = hfsplus_get_bnode(iter->tree, iter->node)) == NULL)
731 +               return err;
732 +       if(node->kind != HFSPLUS_NODE_LEAF) {
733 +               printk("HFS+-fs: found entry of bad type\n");
734 +               goto out;
735 +       }
736 +
737 +       rec = iter->rec;
738 +       if(!(keylen = hfsplus_brec_keylen(node, rec))) {
739 +               printk("HFS+-fs: unable to read key from B*Tree record\n");
740 +               goto out;
741 +       }
742 +       datalen = hfsplus_brec_lenoff(node, rec, &off) - keylen;
743 +       if((datalen <= 0) || (datalen > *entry_len)) {
744 +               printk("HFS+-fs: bad entry length in B*Tree\n");
745 +               goto out;
746 +       }
747 +       if(!hfsplus_bnode_copybytes(node, key, off, keylen)) {
748 +               printk("HFS+-fs: unable to copy key from B*Tree\n");
749 +               goto out;
750 +       }
751 +       if(!hfsplus_bnode_copybytes(node, entry, off + keylen, datalen)) {
752 +               printk("HFS+-fs: unable to read record in B*Tree\n");
753 +               goto out;
754 +       }
755 +       *entry_len = datalen;
756 +       err = 0;
757 + out:
758 +       hfsplus_put_bnode(node);
759 +       return err;
760 +}
761 +
762 diff -urN -x CVS linux-bk/fs/hfsplus/btree.c linux-hfsplus/fs/hfsplus/btree.c
763 --- linux-bk/fs/hfsplus/btree.c Wed Dec 31 16:00:00 1969
764 +++ linux-hfsplus/fs/hfsplus/btree.c    Mon Nov  5 00:07:58 2001
765 @@ -0,0 +1,89 @@
766 +/*
767 + *  linux/fs/hfsplus/btree.c
768 + *
769 + * Copyright (C) 2001
770 + * Brad Boyer (flar@allandria.com)
771 + *
772 + * Handle opening/closing btree
773 + */
774 +
775 +#include <linux/slab.h>
776 +#include <linux/pagemap.h>
777 +#include <linux/hfsplus_fs.h>
778 +#include <linux/hfsplus_raw.h>
779 +
780 +/* Release resources used by a btree */
781 +void hfsplus_close_btree(struct hfsplus_btree *tree)
782 +{
783 +       if(tree) {
784 +               kfree(tree);
785 +       }
786 +}
787 +
788 +/* Fill in extra data in tree structure from header node */
789 +static void hfsplus_fill_treeinfo(hfsplus_btree *tree, hfsplus_btree_head *hdr)
790 +{
791 +       if (!tree || !hdr)
792 +               return;
793 +
794 +       tree->root = hfsp_get_hl(hdr->root);
795 +       tree->node_count = hfsp_get_hl(hdr->node_count);
796 +       tree->free_nodes = hfsp_get_hl(hdr->free_nodes);
797 +       tree->attributes = hfsp_get_hl(hdr->attributes);
798 +       tree->node_size = hfsp_get_hs(hdr->node_size);
799 +       tree->max_key_len = hfsp_get_hs(hdr->max_key_len);
800 +       tree->depth = hfsp_get_hs(hdr->depth);
801 +}
802 +
803 +/* Get a reference to a B*Tree and do some initial checks */
804 +hfsplus_btree *hfsplus_open_btree(struct super_block *sb, hfsp_cnid id)
805 +{
806 +       hfsplus_btree *tree;
807 +       hfsplus_bnode *hnode;
808 +       hfsplus_btree_head head;
809 +       hfsp_u16 bytes;
810 +
811 +       tree = kmalloc(sizeof(struct hfsplus_btree), GFP_KERNEL);
812 +       if(!tree)
813 +               return NULL;
814 +
815 +       /* Set the correct compare function */
816 +       tree->sb = sb;
817 +       tree->cnid = id;
818 +       if(id == HFSPLUS_EXT_CNID) {
819 +               tree->keycmp = hfsplus_cmp_ext_key;
820 +       } else if(id == HFSPLUS_CAT_CNID) {
821 +               tree->keycmp = hfsplus_cmp_cat_key;
822 +       } else {
823 +               printk("HFS+-fs: unknown B*Tree requested\n");
824 +               goto free_tree;
825 +       }
826 +
827 +       /* Set up some dummy values */
828 +       tree->node_count = 1;
829 +       if(PAGE_SIZE > HFSPLUS_NODE_MXSZ)
830 +               tree->node_size = HFSPLUS_NODE_MXSZ;
831 +       else
832 +               tree->node_size = PAGE_SIZE;
833 +
834 +       /* Load the header */
835 +       hnode = hfsplus_get_bnode(tree, HFSPLUS_TREE_HEAD);
836 +       if(!hnode)
837 +               goto free_tree;
838 +       bytes = hfsplus_bnode_copybytes(hnode, &head,
839 +                                       sizeof(hfsplus_btree_node_desc),
840 +                                       sizeof(hfsplus_btree_head));
841 +       if(bytes != sizeof(hfsplus_btree_head)) {
842 +               printk("HFS+-fs: unable to read B*Tree header\n");
843 +               goto put_hnode;
844 +       }
845 +       hfsplus_fill_treeinfo(tree, &head);
846 +       hfsplus_put_bnode(hnode);
847 +       return tree;
848 +
849 + put_hnode:
850 +       hfsplus_put_bnode(hnode);
851 + free_tree:
852 +       kfree(tree);
853 +       return NULL;
854 +}
855 diff -urN -x CVS linux-bk/fs/hfsplus/catalog.c linux-hfsplus/fs/hfsplus/catalog.c
856 --- linux-bk/fs/hfsplus/catalog.c       Wed Dec 31 16:00:00 1969
857 +++ linux-hfsplus/fs/hfsplus/catalog.c  Mon Nov  5 00:09:43 2001
858 @@ -0,0 +1,95 @@
859 +/*
860 + *  linux/fs/hfsplus/catalog.c
861 + *
862 + * Copyright (C) 2001
863 + * Brad Boyer (flar@allandria.com)
864 + *
865 + * Handling of catalog records
866 + */
867 +
868 +#include <linux/hfsplus_fs.h>
869 +#include <linux/hfsplus_raw.h>
870 +
871 +int hfsplus_cmp_cat_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
872 +{
873 +        hfsp_cnid k1p, k2p;
874 +
875 +        k1p = hfsp_get_hl(k1->u.cat.parent);
876 +        k2p = hfsp_get_hl(k2->u.cat.parent);
877 +        if(k1p != k2p) {
878 +                return (k1p < k2p) ? -1 : 1;
879 +        }
880 +        return hfsplus_unistrcmp(&(k1->u.cat.name), &(k2->u.cat.name));
881 +}
882 +
883 +int hfsplus_fill_cat_key(hfsplus_btree_key *key, hfsp_cnid parent, char *name,
884 +                        int namelen)
885 +{
886 +       int err;
887 +
888 +       hfsp_put_hl(parent, key->u.cat.parent);
889 +       if(!name || !namelen) {
890 +               hfsp_put_hs(0, key->u.cat.name.length);
891 +       } else {
892 +               err = hfsplus_asc2uni(&(key->u.cat.name), name, namelen);
893 +               if(err)
894 +                       return err;
895 +       }
896 +       hfsp_put_hs(6 + 2 * hfsp_get_hs(key->u.cat.name.length), key->key_len);
897 +       return 0;
898 +}
899 +
900 +static void hfsplus_fill_cat_key_uni(hfsplus_btree_key *key, hfsp_cnid parent,
901 +                                    hfsplus_unistr *name)
902 +{
903 +       hfsp_u16 ustrlen;
904 +
905 +       ustrlen = hfsp_get_hs(name->length);
906 +       hfsp_put_hs(6 + 2 * ustrlen, key->key_len);
907 +       hfsp_put_hl(parent, key->u.cat.parent);
908 +       hfsp_put_hs(ustrlen, key->u.cat.name.length);
909 +       memcpy(key->u.cat.name.unicode, name->unicode,
910 +              2 * ustrlen);
911 +}
912 +
913 +/* Try to get a catalog entry for given catalog id */
914 +int hfsplus_find_cat(struct super_block *sb, unsigned long cnid,
915 +                    hfsplus_cat_entry *entry)
916 +{
917 +       hfsplus_btree_key key;
918 +       hfsplus_cat_entry tmp;
919 +       int err, sz;
920 +       hfsp_u16 type;
921 +
922 +       hfsplus_fill_cat_key(&key, cnid, NULL, 0);
923 +       sz = sizeof(hfsplus_cat_entry);
924 +       err = hfsplus_btfind_exact(HFSPLUS_SB(sb).cat_tree, &key, &tmp, &sz);
925 +       if(err)
926 +               return err;
927 +
928 +       type = hfsp_get_hs(tmp.type);
929 +       if((type != HFSPLUS_FOLDER_THREAD) && (type != HFSPLUS_FILE_THREAD)) {
930 +               printk("HFS+-fs: Found bad thread record in catalog\n");
931 +               return -EIO;
932 +       }
933 +
934 +       hfsplus_fill_cat_key_uni(&key, hfsp_get_hl(tmp.u.thread.parentID),
935 +                                &(tmp.u.thread.nodeName));
936 +       sz = sizeof(hfsplus_cat_entry);
937 +       err = hfsplus_btfind_exact(HFSPLUS_SB(sb).cat_tree, &key, entry, &sz);
938 +       if(err) {
939 +               printk("HFS+-fs: Unable to find record listed in thread\n");
940 +               return err;
941 +       }
942 +       type = hfsp_get_hs(entry->type);
943 +       if((type != HFSPLUS_FOLDER) && (type != HFSPLUS_FILE)) {
944 +               printk("HFS+-fs: Found bad entry in catalog\n");
945 +               return -EIO;
946 +       }
947 +       if(((type == HFSPLUS_FILE) && (sz < 2+sizeof(hfsplus_cat_file))) ||
948 +          ((type == HFSPLUS_FOLDER) && (sz < 2+sizeof(hfsplus_cat_folder)))) {
949 +               printk("HFS+-fs: Found truncated entry in catalog\n");
950 +               return -EIO;
951 +       }
952 +       return 0;
953 +}
954 diff -urN -x CVS linux-bk/fs/hfsplus/dir.c linux-hfsplus/fs/hfsplus/dir.c
955 --- linux-bk/fs/hfsplus/dir.c   Wed Dec 31 16:00:00 1969
956 +++ linux-hfsplus/fs/hfsplus/dir.c      Thu Dec 13 22:11:55 2001
957 @@ -0,0 +1,156 @@
958 +/*
959 + *  linux/fs/hfsplus/dir.c
960 + *
961 + * Copyright (C) 2001
962 + * Brad Boyer (flar@allandria.com)
963 + *
964 + * Handling of directories
965 + */
966 +
967 +#include <linux/errno.h>
968 +#include <linux/fs.h>
969 +#include <linux/hfsplus_fs.h>
970 +#include <linux/hfsplus_raw.h>
971 +
972 +/* Find the entry inside dir named dentry->d_name */
973 +static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry)
974 +{
975 +       struct inode *inode = NULL;
976 +       hfsplus_btree_key key;
977 +       hfsplus_cat_entry entry;
978 +       int err, sz;
979 +       hfsp_u32 cnid;
980 +       hfsp_u16 type;
981 +
982 +       if((err = hfsplus_fill_cat_key(&key, dir->i_ino, dentry->d_name.name,
983 +                                      dentry->d_name.len)) != 0)
984 +               return ERR_PTR(err);
985 +       sz = sizeof(entry);
986 +       if((err = hfsplus_btfind_exact(HFSPLUS_SB(dir->i_sb).cat_tree, &key,
987 +                                      &entry, &sz)) != 0) {
988 +               if(err == -ENOENT) {
989 +                       /* No such entry */
990 +                       inode = NULL;
991 +                       goto out;
992 +               }
993 +               return ERR_PTR(err);
994 +       }
995 +       type = hfsp_get_hs(entry.type);
996 +       if(type == HFSPLUS_FOLDER) {
997 +               if(sz < 2 + sizeof(hfsplus_cat_folder))
998 +                       return ERR_PTR(-EIO);
999 +               cnid = hfsp_get_hl(entry.u.folder.id);
1000 +       } else if(type == HFSPLUS_FILE) {
1001 +               if(sz < 2 + sizeof(hfsplus_cat_file))
1002 +                       return ERR_PTR(-EIO);
1003 +               cnid = hfsp_get_hl(entry.u.file.id);
1004 +       } else {
1005 +               printk("HFS+-fs: Illegal catalog entry type in lookup\n");
1006 +               return ERR_PTR(-EIO);
1007 +       }
1008 +       inode = iget(dir->i_sb, cnid);
1009 +       if(!inode)
1010 +               return ERR_PTR(-EACCES);
1011 + out:
1012 +       d_add(dentry, inode);
1013 +       return NULL;
1014 +}
1015 +
1016 +static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
1017 +{
1018 +       struct inode *inode = filp->f_dentry->d_inode;
1019 +       int len, sz, err, done = 0;
1020 +       char strbuf[HFSPLUS_MAX_STRLEN + 1];
1021 +       hfsplus_cat_entry entry;
1022 +       hfsplus_btree_key key;
1023 +       hfsplus_btiter iter;
1024 +       hfsp_u16 type;
1025 +
1026 +       if(filp->f_pos >= inode->i_size)
1027 +               return 0;
1028 +
1029 +       hfsplus_fill_cat_key(&key, inode->i_ino, NULL, 0);
1030 +       hfsplus_btiter_setup(&iter, HFSPLUS_SB(inode->i_sb).cat_tree);
1031 +       if((err = hfsplus_btiter_find(&iter, &key)) != 0) {
1032 +               return err;
1033 +       }
1034 +       if(filp->f_pos > 1)
1035 +               if((err = hfsplus_btiter_move(&iter, filp->f_pos - 1)))
1036 +                       return err;
1037 +
1038 +       while(!done) {
1039 +               if(!filp->f_pos) {
1040 +                       /* This is completely artificial... */
1041 +                       if(filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))
1042 +                               done = 1;
1043 +                       filp->f_pos++;
1044 +                       continue;
1045 +               }
1046 +               sz = sizeof(entry);
1047 +               if((err = hfsplus_btiter_get(&iter, &key, &entry, &sz)))
1048 +                       return err;
1049 +               if(hfsp_get_hl(key.u.cat.parent) != inode->i_ino) {
1050 +                       printk("HFS+-fs: walked past end of dir\n");
1051 +                       return 0;
1052 +               }
1053 +               if(sz < 2)
1054 +                       return -EIO;
1055 +               type = hfsp_get_hs(entry.type);
1056 +               if(filp->f_pos == 1) {
1057 +                       if(type != HFSPLUS_FOLDER_THREAD) {
1058 +                               printk("HFS+-fs: bad catalog folder thread\n");
1059 +                               return -EIO;
1060 +                       }
1061 +                       if(sz < HFSPLUS_MIN_THREAD_SZ) {
1062 +                               printk("HFS+-fs: truncated catalog thread\n");
1063 +                               return -EIO;
1064 +                       }
1065 +                       if(filldir(dirent, "..", 2, 1,
1066 +                                  hfsp_get_hl(entry.u.thread.parentID),
1067 +                                  DT_DIR))
1068 +                               done = 1;
1069 +               } else {
1070 +                       len = HFSPLUS_MAX_STRLEN;
1071 +                       err = hfsplus_uni2asc(&(key.u.cat.name), strbuf, &len);
1072 +                       if(err)
1073 +                               return err;
1074 +                       if(type == HFSPLUS_FOLDER) {
1075 +                               if(sz < 2 + sizeof(hfsplus_cat_folder)) {
1076 +                                       printk("HFS+-fs: small dir entry\n");
1077 +                                       return -EIO;
1078 +                               }
1079 +                               if(filldir(dirent, strbuf, len, filp->f_pos,
1080 +                                          hfsp_get_hl(entry.u.folder.id),
1081 +                                          DT_DIR))
1082 +                                       done = 1;
1083 +                       } else if(type == HFSPLUS_FILE) {
1084 +                               if(sz < 2 + sizeof(hfsplus_cat_file)) {
1085 +                                       printk("HFS+-fs: small file entry\n");
1086 +                                       return -EIO;
1087 +                               }
1088 +                               if(filldir(dirent, strbuf, len, filp->f_pos,
1089 +                                          hfsp_get_hl(entry.u.file.id),
1090 +                                          DT_REG))
1091 +                                       done = 1;
1092 +                       } else {
1093 +                               printk("HFS+-fs: bad catalog entry type\n");
1094 +                               return -EIO;
1095 +                       }
1096 +               } /* if(filp->f_pos == 1) */
1097 +               filp->f_pos++;
1098 +               if(filp->f_pos >= inode->i_size)
1099 +                       break;
1100 +               if((err = hfsplus_btiter_move(&iter, 1)))
1101 +                       return err;
1102 +       } /* while(!done) */
1103 +       return 0;
1104 +}
1105 +
1106 +struct inode_operations hfsplus_dir_inode_operations = {
1107 +       lookup:         hfsplus_lookup,
1108 +};
1109 +
1110 +struct file_operations hfsplus_dir_operations = {
1111 +       read:          generic_read_dir,
1112 +       readdir:       hfsplus_readdir,
1113 +};
1114 diff -urN -x CVS linux-bk/fs/hfsplus/extents.c linux-hfsplus/fs/hfsplus/extents.c
1115 --- linux-bk/fs/hfsplus/extents.c       Wed Dec 31 16:00:00 1969
1116 +++ linux-hfsplus/fs/hfsplus/extents.c  Mon Nov  5 00:03:59 2001
1117 @@ -0,0 +1,162 @@
1118 +/*
1119 + *  linux/fs/hfsplus/extents.c
1120 + *
1121 + * Copyright (C) 2001
1122 + * Brad Boyer (flar@allandria.com)
1123 + *
1124 + * Handling of Extents both in catalog and extents overflow trees
1125 + */
1126 +
1127 +#include <linux/errno.h>
1128 +#include <linux/fs.h>
1129 +#include <linux/hfsplus_fs.h>
1130 +#include <linux/hfsplus_raw.h>
1131 +
1132 +/* Compare two extents keys, returns 0 on same, pos/neg for difference */
1133 +int hfsplus_cmp_ext_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
1134 +{
1135 +        hfsp_cnid k1id, k2id;
1136 +        hfsp_u32 k1s, k2s;
1137 +
1138 +        k1id = hfsp_get_hl(k1->u.ext.cnid);
1139 +        k2id = hfsp_get_hl(k2->u.ext.cnid);
1140 +        if(k1id != k2id) {
1141 +                return (k1id < k2id) ? -1 : 1;
1142 +        }
1143 +        if(k1->u.ext.fork_type != k2->u.ext.fork_type) {
1144 +                return (k1->u.ext.fork_type < k2->u.ext.fork_type) ? -1 : 1;
1145 +        }
1146 +        k1s = hfsp_get_hl(k1->u.ext.start_block);
1147 +        k2s = hfsp_get_hl(k2->u.ext.start_block);
1148 +        if(k1s == k2s)
1149 +                return 0;
1150 +        return (k1s < k2s) ? -1 : 1;
1151 +}
1152 +
1153 +void hfsplus_fill_ext_key(hfsplus_btree_key *key, hfsp_u32 cnid,
1154 +                         hfsp_u32 block, hfsp_u8 type)
1155 +{
1156 +       hfsp_put_hl(HFSPLUS_EXT_KEYLEN, key->key_len);
1157 +       hfsp_put_hl(cnid, key->u.ext.cnid);
1158 +       hfsp_put_hl(block, key->u.ext.start_block);
1159 +       key->u.ext.fork_type = type;
1160 +       key->u.ext.pad = 0;
1161 +}
1162 +
1163 +/* Get a block at iblock for inode, possibly allocating if create */
1164 +int hfsplus_get_block(struct inode *inode, long iblock,
1165 +                     struct buffer_head *bh_result, int create)
1166 +{
1167 +       struct super_block *s;
1168 +       hfsplus_extent *extents, ext_entry[8];
1169 +       hfsplus_btree_key key;
1170 +       hfsplus_cat_entry cat_entry;
1171 +       unsigned long ino;
1172 +       long remain;
1173 +       int i, sz, localerr, search_tree = 1, err = -EIO;
1174 +       hfsp_u32 curr, tmp, ablock, dblock, dbpab, dbo;
1175 +       hfsp_u8 forktype;
1176 +
1177 +       if(!inode || !bh_result)
1178 +               goto out;
1179 +
1180 +       ino = inode->i_ino;
1181 +       s = inode->i_sb;
1182 +
1183 +       /* Convert inode block to disk allocation block */
1184 +       dbo = HFSPLUS_SB(s).dboff;
1185 +       dbpab = HFSPLUS_SB(s).dbpab;
1186 +       ablock = iblock / dbpab;
1187 +       remain = iblock % dbpab;
1188 +
1189 +       /* Some files have extents in volume header */
1190 +       if(ino <= HFSPLUS_ATTR_CNID) {
1191 +               switch(ino) {
1192 +               case HFSPLUS_EXT_CNID:
1193 +                       extents = HFSPLUS_SB(s).s_vhdr->ext_file.extents;
1194 +                       search_tree = 0;
1195 +                       break;
1196 +               case HFSPLUS_CAT_CNID:
1197 +                       extents = HFSPLUS_SB(s).s_vhdr->cat_file.extents;
1198 +                       break;
1199 +               case HFSPLUS_ALLOC_CNID:
1200 +                       extents = HFSPLUS_SB(s).s_vhdr->alloc_file.extents;
1201 +                       break;
1202 +               case HFSPLUS_START_CNID:
1203 +                       extents = HFSPLUS_SB(s).s_vhdr->start_file.extents;
1204 +                       break;
1205 +               case HFSPLUS_ATTR_CNID:
1206 +                       extents = HFSPLUS_SB(s).s_vhdr->attr_file.extents;
1207 +                       break;
1208 +               default:
1209 +                       /* Nothing else in this block is valid */
1210 +                       goto out;
1211 +                       break;
1212 +               }
1213 +       } else {
1214 +               if((localerr = hfsplus_find_cat(s, ino, &cat_entry)) != 0) {
1215 +                       err = localerr;
1216 +                       goto out;
1217 +               }
1218 +               if(hfsp_get_hs(cat_entry.type) != HFSPLUS_FILE)
1219 +                       goto out;
1220 +               if(HFSPLUS_IS_DATA(inode)) {
1221 +                       extents = cat_entry.u.file.data_fork.extents;
1222 +               } else if(HFSPLUS_IS_RSRC(inode)) {
1223 +                       extents = cat_entry.u.file.res_fork.extents;
1224 +               } else {
1225 +                       goto out;
1226 +               }
1227 +       }
1228 +
1229 +       /* Look in extent record for block */
1230 +       curr = 0;
1231 + search_extent:
1232 +       for(i = 0; i < 8; i++) {
1233 +               tmp = hfsp_get_hl(extents[i].block_count);
1234 +               if(tmp && (ablock < curr + tmp)) {
1235 +                       /* Found it */
1236 +                       dblock = hfsp_get_hl(extents[i].start_block);
1237 +                       dblock += ablock - curr;
1238 +                       bh_result->b_dev = inode->i_dev;
1239 +                       bh_result->b_blocknr = dblock * dbpab + remain + dbo;
1240 +                       bh_result->b_state |= (1UL << BH_Mapped);
1241 +                       err = 0;
1242 +                       goto out;
1243 +               }
1244 +               curr += tmp;
1245 +       }
1246 +
1247 +       /* Look for extents in tree */
1248 +       if(!search_tree)
1249 +               goto not_found;
1250 +       forktype = HFSPLUS_IS_RSRC(inode) ? HFSPLUS_TYPE_RSRC :
1251 +               HFSPLUS_TYPE_DATA;
1252 +       hfsplus_fill_ext_key(&key, ino, ablock, forktype);
1253 +       sz = sizeof(ext_entry);
1254 +       if((localerr = hfsplus_btfind(HFSPLUS_SB(s).ext_tree, &key, ext_entry,
1255 +                                     &sz))) {
1256 +               if(localerr == -ENOENT)
1257 +                       goto not_found;
1258 +               printk("HFS+-fs: Unknown problem searching extents B*Tree\n");
1259 +               err = localerr;
1260 +               goto out;
1261 +       }
1262 +       if((hfsp_get_hl(key.u.ext.cnid) != ino) ||
1263 +          (key.u.ext.fork_type != forktype)) {
1264 +               goto not_found;
1265 +       }
1266 +       search_tree = 0;
1267 +       curr = hfsp_get_hl(key.u.ext.start_block);
1268 +       extents = ext_entry;
1269 +       goto search_extent;
1270 + not_found:
1271 +       if(!create) {
1272 +               err = 0;
1273 +               goto out;
1274 +       }
1275 +       /* FIXME: Should allocate blocks here... */
1276 +       printk("HFS+-fs: no file writes, but block allocation attempted\n");
1277 + out:
1278 +       return err;
1279 +}
1280 diff -urN -x CVS linux-bk/fs/hfsplus/inode.c linux-hfsplus/fs/hfsplus/inode.c
1281 --- linux-bk/fs/hfsplus/inode.c Wed Dec 31 16:00:00 1969
1282 +++ linux-hfsplus/fs/hfsplus/inode.c    Thu Dec 13 22:32:32 2001
1283 @@ -0,0 +1,126 @@
1284 +/*
1285 + *  linux/fs/hfsplus/inode.c
1286 + *
1287 + * Copyright (C) 2001
1288 + * Brad Boyer (flar@allandria.com)
1289 + *
1290 + * Inode handling routines
1291 + */
1292 +
1293 +#include <linux/fs.h>
1294 +#include <linux/hfsplus_fs.h>
1295 +#include <linux/hfsplus_raw.h>
1296 +
1297 +static int hfsplus_readpage(struct file *file, struct page *page)
1298 +{
1299 +       return block_read_full_page(page, hfsplus_get_block);
1300 +}
1301 +
1302 +static int hfsplus_bmap(struct address_space *mapping, long block)
1303 +{
1304 +       return generic_block_bmap(mapping, block, hfsplus_get_block);
1305 +}
1306 +
1307 +struct address_space_operations hfsplus_aops = {
1308 +       readpage: hfsplus_readpage,
1309 +       bmap: hfsplus_bmap,
1310 +};
1311 +
1312 +static void hfsplus_fill_perms(struct inode *inode, hfsplus_perm *perms)
1313 +{
1314 +       struct super_block *s = inode->i_sb;
1315 +
1316 +       inode->i_mode = hfsp_get_hl(perms->mode);
1317 +       if(inode->i_mode) {
1318 +               inode->i_mode &= ~(S_IFMT);
1319 +       } else {
1320 +               inode->i_mode = S_IRWXUGO & ~(HFSPLUS_SB(s).umask);
1321 +       }
1322 +       inode->i_uid = hfsp_get_hl(perms->owner);
1323 +       if(!(inode->i_uid))
1324 +               inode->i_uid = HFSPLUS_SB(s).uid;
1325 +       inode->i_gid = hfsp_get_hl(perms->group);
1326 +       if(!(inode->i_gid))
1327 +               inode->i_gid = HFSPLUS_SB(s).gid;
1328 +       HFSPLUS_I(inode).dev = hfsp_get_hl(perms->dev);
1329 +}
1330 +
1331 +extern struct inode_operations hfsplus_dir_inode_operations;
1332 +extern struct file_operations hfsplus_dir_operations;
1333 +
1334 +struct inode_operations hfsplus_file_inode_operations = {
1335 +};
1336 +struct file_operations hfsplus_file_operations = {
1337 +       read:          generic_file_read,
1338 +       mmap:          generic_file_mmap,
1339 +};
1340 +
1341 +static void hfsplus_count_subdirs(struct inode *inode)
1342 +{
1343 +       hfsplus_btree_key key;
1344 +       hfsplus_cat_entry entry;
1345 +       hfsplus_btiter iter;
1346 +       int sz;
1347 +
1348 +       hfsplus_fill_cat_key(&key, inode->i_ino, NULL, 0);
1349 +       hfsplus_btiter_setup(&iter, HFSPLUS_SB(inode->i_sb).cat_tree);
1350 +       if(hfsplus_btiter_find(&iter, &key))
1351 +               return;
1352 +       while(1) {
1353 +               sz = sizeof(hfsplus_cat_entry);
1354 +               if(hfsplus_btiter_get(&iter, &key, &entry, &sz) || (sz < 2))
1355 +                       return;
1356 +
1357 +               if(hfsp_get_hl(key.u.cat.parent) != inode->i_ino)
1358 +                       return;
1359 +               if(hfsp_get_hs(entry.type) == HFSPLUS_FOLDER)
1360 +                       HFSPLUS_I(inode).ndirs++;
1361 +
1362 +               if(hfsplus_btiter_move(&iter, 1))
1363 +                       return;
1364 +       }
1365 +}
1366 +
1367 +int hfsplus_cat_fill_inode(struct inode *inode, hfsplus_cat_entry *entry)
1368 +{
1369 +       hfsplus_cat_folder *folder;
1370 +       hfsplus_cat_file *file;
1371 +       hfsp_u16 type;
1372 +
1373 +       type = hfsp_get_hs(entry->type);
1374 +       HFSPLUS_I(inode).ndirs = 0;
1375 +       HFSPLUS_I(inode).dev = 0;
1376 +       inode->i_blksize = PAGE_SIZE; /* Doesn't seem to be useful... */
1377 +       if(type == HFSPLUS_FOLDER) {
1378 +               folder = &(entry->u.folder);
1379 +               hfsplus_fill_perms(inode, &(folder->permissions));
1380 +               inode->i_mode |= S_IFDIR;
1381 +               hfsplus_count_subdirs(inode);
1382 +               inode->i_nlink = 2 + HFSPLUS_I(inode).ndirs;
1383 +               inode->i_size = 2 + hfsp_get_hl(folder->valence);
1384 +               inode->i_atime = hfsp_mt2ut(folder->access_date);
1385 +               inode->i_mtime = hfsp_mt2ut(folder->content_mod_date);
1386 +               inode->i_ctime = inode->i_mtime;
1387 +               inode->i_blocks = 0;
1388 +               inode->i_op = &hfsplus_dir_inode_operations;
1389 +               inode->i_fop = &hfsplus_dir_operations;
1390 +       } else if(type == HFSPLUS_FILE) {
1391 +               file = &(entry->u.file);
1392 +               hfsplus_fill_perms(inode, &(file->permissions));
1393 +               inode->i_mode |= S_IFREG;
1394 +               inode->i_nlink = 1;
1395 +               inode->i_size = hfsp_get_hll(file->data_fork.total_size);
1396 +               inode->i_atime = hfsp_mt2ut(file->access_date);
1397 +               inode->i_mtime = hfsp_mt2ut(file->content_mod_date);
1398 +               inode->i_ctime = inode->i_mtime;
1399 +               inode->i_blocks = hfsp_get_hl(file->data_fork.total_blocks);
1400 +               inode->i_op = &hfsplus_file_inode_operations;
1401 +               inode->i_fop = &hfsplus_file_operations;
1402 +               inode->i_mapping->a_ops = &hfsplus_aops;
1403 +       } else {
1404 +               printk("HFS+-fs: bad catalog entry used to create inode\n");
1405 +               return -EIO;
1406 +       }
1407 +       return 0;
1408 +}
1409 +
1410 diff -urN -x CVS linux-bk/fs/hfsplus/options.c linux-hfsplus/fs/hfsplus/options.c
1411 --- linux-bk/fs/hfsplus/options.c       Wed Dec 31 16:00:00 1969
1412 +++ linux-hfsplus/fs/hfsplus/options.c  Fri Sep 21 00:42:03 2001
1413 @@ -0,0 +1,147 @@
1414 +/*
1415 + *  linux/fs/hfsplus/options.c
1416 + *
1417 + * Copyright (C) 2001
1418 + * Brad Boyer (flar@allandria.com)
1419 + *
1420 + * Option parsing
1421 + */
1422 +
1423 +#include <linux/string.h>
1424 +#include <linux/kernel.h>
1425 +#include <linux/sched.h>
1426 +#include <linux/hfsplus_fs.h>
1427 +
1428 +/* Initialize an options object to reasonable defaults */
1429 +void fill_defaults(struct hfsplus_sb_info *opts)
1430 +{
1431 +       if(!opts)
1432 +               return;
1433 +
1434 +       opts->creator = HFSPLUS_DEF_CR_TYPE;
1435 +       opts->type = HFSPLUS_DEF_CR_TYPE;
1436 +       opts->charcase = HFSPLUS_CASE_ASIS;
1437 +       opts->fork = HFSPLUS_FORK_RAW;
1438 +       opts->namemap = HFSPLUS_NAMES_TRIVIAL;
1439 +       opts->umask = current->fs->umask;
1440 +       opts->uid = current->uid;
1441 +       opts->gid = current->gid;
1442 +}
1443 +
1444 +/* Copy settings from one hfsplus_sb_info object to another */
1445 +void fill_current(struct hfsplus_sb_info *curopts,
1446 +                 struct hfsplus_sb_info *opts)
1447 +{
1448 +       if(!curopts || !opts)
1449 +               return;
1450 +
1451 +       opts->creator = curopts->creator;
1452 +       opts->type = curopts->type;
1453 +       opts->charcase = curopts->charcase;
1454 +       opts->fork = curopts->fork;
1455 +       opts->namemap = curopts->namemap;
1456 +       opts->umask = curopts->umask;
1457 +       opts->uid = curopts->uid;
1458 +       opts->gid = curopts->gid;
1459 +}
1460 +
1461 +/* My own little ultra-paranoid version of strtok (yes, there is strtok...) */
1462 +static char *my_strtok(char *input, char **next, char delim)
1463 +{
1464 +       char *d;
1465 +
1466 +       if(!input || !*input || !next)
1467 +               return NULL;
1468 +
1469 +       *next = NULL;
1470 +       d = strchr(input, delim);
1471 +       if(d) {
1472 +               *d = '\0';
1473 +               *next = d+1;
1474 +       }
1475 +       return input;
1476 +}
1477 +
1478 +/* convert a "four byte character" to a 32 bit int with error checks */
1479 +static int fill_fourchar(hfsp_u32 *result, char *input)
1480 +{
1481 +       hfsp_u32 out;
1482 +       int i;
1483 +
1484 +       if(!result || !input || !*input || (strlen(input) != 4))
1485 +               return 0;
1486 +
1487 +       for(out = 0, i = 0; i < 4; i++) {
1488 +               out <<= 8;
1489 +               out |= ((int)(input[i])) & 0xFF;
1490 +       }
1491 +       *result = out;
1492 +       return 1;
1493 +}
1494 +
1495 +/* convert a string to int with error checks */
1496 +static int fill_int(int *result, char *input, int base)
1497 +{
1498 +       char *tmp = input;
1499 +       int intval;
1500 +
1501 +       if(!result || !input || !*input)
1502 +               return 0;
1503 +
1504 +       intval = simple_strtoul(tmp, &tmp, base);
1505 +       if(*tmp)
1506 +               return 0;
1507 +
1508 +       *result = intval;
1509 +       return 1;
1510 +}
1511 +
1512 +/* Parse options from mount. Returns 0 on failure */
1513 +/* input is the options passed to mount() as a string */
1514 +int parse_options(char *input, struct hfsplus_sb_info *results)
1515 +{
1516 +       char *next, *curropt, *value;
1517 +
1518 +       if(!input)
1519 +               return 1;
1520 +
1521 +       for(curropt = my_strtok(input, &next, ','); curropt != NULL;
1522 +           curropt = my_strtok(next, &next, ',')) {
1523 +               if((value = strchr(curropt, '=')) != NULL)
1524 +                       *value++ = '\0';
1525 +
1526 +               if(!strcmp(curropt, "creator")) {
1527 +                       if(!fill_fourchar(&(results->creator), value)) {
1528 +                               printk("HFS+-fs: creator requires a value\n");
1529 +                               return 0;
1530 +                       }
1531 +               } else if(!strcmp(curropt, "type")) {
1532 +                       if(!fill_fourchar(&(results->type), value)) {
1533 +                               printk("HFS+-fs: type requires a value\n");
1534 +                               return 0;
1535 +                       }
1536 +               } else if(!strcmp(curropt, "case")) {
1537 +               } else if(!strcmp(curropt, "fork")) {
1538 +               } else if(!strcmp(curropt, "names")) {
1539 +               } else if(!strcmp(curropt, "umask")) {
1540 +                       if(!fill_int(&(results->umask), value, 8))
1541 +                               printk("HFS+-fs: umask requires a value\n");
1542 +                               return 0;
1543 +               } else if(!strcmp(curropt, "uid")) {
1544 +                       if(!fill_int(&(results->uid), value, 0)) {
1545 +                               printk("HFS+-fs: uid requires an argument\n");
1546 +                               return 0;
1547 +                       }
1548 +               } else if(!strcmp(curropt, "gid")) {
1549 +                       if(!fill_int(&(results->gid), value, 0)) {
1550 +                               printk("HFS+-fs: gid requires an argument\n");
1551 +                               return 0;
1552 +                       }
1553 +               } else {
1554 +                       printk("HFS+-fs: unknown option %s\n", curropt);
1555 +                       return 0;
1556 +               }
1557 +       }
1558 +
1559 +       return 1;
1560 +}
1561 diff -urN -x CVS linux-bk/fs/hfsplus/super.c linux-hfsplus/fs/hfsplus/super.c
1562 --- linux-bk/fs/hfsplus/super.c Wed Dec 31 16:00:00 1969
1563 +++ linux-hfsplus/fs/hfsplus/super.c    Mon Nov  5 00:11:34 2001
1564 @@ -0,0 +1,164 @@
1565 +/*
1566 + *  linux/fs/hfsplus/super.c
1567 + *
1568 + * Copyright (C) 2001
1569 + * Brad Boyer (flar@allandria.com)
1570 + *
1571 + */
1572 +
1573 +#include <linux/config.h>
1574 +#include <linux/init.h>
1575 +#include <linux/module.h>
1576 +#include <linux/fs.h>
1577 +#include <linux/hfsplus_fs.h>
1578 +
1579 +static void hfsplus_read_inode(struct inode *inode)
1580 +{
1581 +       hfsplus_cat_entry entry;
1582 +
1583 +       memset(&entry, 0, sizeof(entry));
1584 +       hfsp_put_hs(HFSPLUS_FILE, entry.type);
1585 +       switch(inode->i_ino) {
1586 +       case HFSPLUS_EXT_CNID:
1587 +               memcpy(&(entry.u.file.data_fork),
1588 +                      &(HFSPLUS_SB(inode->i_sb).s_vhdr->ext_file.extents),
1589 +                      sizeof(hfsplus_fork_raw));
1590 +               break;
1591 +       case HFSPLUS_CAT_CNID:
1592 +               memcpy(&(entry.u.file.data_fork),
1593 +                      &(HFSPLUS_SB(inode->i_sb).s_vhdr->cat_file.extents),
1594 +                      sizeof(hfsplus_fork_raw));
1595 +               break;
1596 +       default:
1597 +               if(hfsplus_find_cat(inode->i_sb, inode->i_ino, &entry))
1598 +                       goto bad_inode;
1599 +               break;
1600 +       }
1601 +       if(hfsplus_cat_fill_inode(inode, &entry))
1602 +               goto bad_inode;
1603 +       return;
1604 +
1605 + bad_inode:
1606 +       make_bad_inode(inode);
1607 +}
1608 +
1609 +static void hfsplus_put_super(struct super_block *sb)
1610 +{
1611 +       hfsplus_close_btree(HFSPLUS_SB(sb).cat_tree);
1612 +       HFSPLUS_SB(sb).cat_tree = NULL;
1613 +       hfsplus_close_btree(HFSPLUS_SB(sb).ext_tree);
1614 +       HFSPLUS_SB(sb).ext_tree = NULL;
1615 +
1616 +       if(HFSPLUS_SB(sb).s_vhbh)
1617 +               brelse(HFSPLUS_SB(sb).s_vhbh);
1618 +       HFSPLUS_SB(sb).s_vhbh = NULL;
1619 +       HFSPLUS_SB(sb).s_vhdr = NULL;
1620 +}
1621 +
1622 +static int hfsplus_statfs(struct super_block *sb, struct statfs *buf)
1623 +{
1624 +       buf->f_type = HFSPLUS_SUPER_MAGIC;
1625 +       buf->f_bsize = sb->s_blocksize;
1626 +       buf->f_blocks = hfsp_get_ahl(HFSPLUS_SB(sb).s_vhdr->total_blocks);
1627 +       buf->f_bfree = HFSPLUS_SB(sb).free_blocks;
1628 +       buf->f_bavail = buf->f_bfree;
1629 +       buf->f_files = HFSPLUS_SB(sb).file_count + HFSPLUS_SB(sb).folder_count;
1630 +       buf->f_ffree = 0xFFFFFFFF - HFSPLUS_SB(sb).next_cnid;
1631 +       buf->f_namelen = HFSPLUS_MAX_STRLEN;
1632 +
1633 +       return 0;
1634 +}
1635 +
1636 +static struct super_operations hfsplus_sops = {
1637 +       read_inode: hfsplus_read_inode,
1638 +       put_super:  hfsplus_put_super,
1639 +       statfs:     hfsplus_statfs,
1640 +};
1641 +
1642 +struct super_block *hfsplus_read_super(struct super_block *sb, void *data,
1643 +                                      int silent)
1644 +{
1645 +       struct hfsplus_vh *vhdr;
1646 +       struct hfsplus_sb_info opts;
1647 +
1648 +       fill_defaults(&opts);
1649 +       if(!parse_options(data, &opts)) {
1650 +               if(!silent)
1651 +                       printk("HFS+-fs: unable to parse mount options\n");
1652 +               return NULL;
1653 +       }
1654 +       fill_current(&opts, &(HFSPLUS_SB(sb)));
1655 +
1656 +       HFSPLUS_SB(sb).s_vhdr = NULL;
1657 +       HFSPLUS_SB(sb).s_vhbh = NULL;
1658 +       HFSPLUS_SB(sb).ext_tree = NULL;
1659 +       HFSPLUS_SB(sb).cat_tree = NULL;
1660 +
1661 +       /* Grab the volume header */
1662 +       if(!hfsplus_read_wrapper(sb)) {
1663 +               if(!silent)
1664 +                       printk("HFS+-fs: unable to find HFS+ superblock\n");
1665 +               return NULL;
1666 +       }
1667 +       vhdr = HFSPLUS_SB(sb).s_vhdr;
1668 +
1669 +       /* Copy parts of the volume header into the superblock */
1670 +       sb->s_magic = hfsp_get_hs(vhdr->signature);
1671 +       if(hfsp_get_hs(vhdr->version) != HFSPLUS_CURRENT_VERSION) {
1672 +               if(!silent)
1673 +                       printk("HFS+-fs: wrong filesystem version\n");
1674 +               goto cleanup;
1675 +       }
1676 +       HFSPLUS_SB(sb).free_blocks = hfsp_get_ahl(vhdr->free_blocks);
1677 +       HFSPLUS_SB(sb).next_cnid = hfsp_get_ahl(vhdr->next_cnid);
1678 +       HFSPLUS_SB(sb).file_count = hfsp_get_ahl(vhdr->file_count);
1679 +       HFSPLUS_SB(sb).folder_count = hfsp_get_ahl(vhdr->folder_count);
1680 +
1681 +       /* Set up operations so we can load metadata */
1682 +       sb->s_op = &hfsplus_sops;
1683 +
1684 +       /* Load metadata objects (B*Trees) */
1685 +       HFSPLUS_SB(sb).ext_tree = hfsplus_open_btree(sb, HFSPLUS_EXT_CNID);
1686 +       if(!HFSPLUS_SB(sb).ext_tree) {
1687 +               if(!silent)
1688 +                       printk("HFS+-fs: failed to load extents file\n");
1689 +               goto cleanup;
1690 +       }
1691 +       HFSPLUS_SB(sb).cat_tree = hfsplus_open_btree(sb, HFSPLUS_CAT_CNID);
1692 +       if(!HFSPLUS_SB(sb).cat_tree) {
1693 +               if(!silent)
1694 +                       printk("HFS+-fs: failed to load catalog file\n");
1695 +               goto cleanup;
1696 +       }
1697 +
1698 +       /* Load the root directory */
1699 +       sb->s_root = d_alloc_root(iget(sb, HFSPLUS_ROOT_CNID));
1700 +       if(!sb->s_root) {
1701 +               if(!silent)
1702 +                       printk("HFS+-fs: failed to load root directory\n");
1703 +               goto cleanup;
1704 +       }
1705 +
1706 +       return sb;
1707 +
1708 + cleanup:
1709 +       hfsplus_put_super(sb);
1710 +       return NULL;
1711 +}
1712 +
1713 +static DECLARE_FSTYPE_DEV(hfsplus_fs_type, "hfsplus", hfsplus_read_super);
1714 +
1715 +static int __init init_hfsplus_fs(void)
1716 +{
1717 +       return register_filesystem(&hfsplus_fs_type);
1718 +}
1719 +
1720 +static void __exit exit_hfsplus_fs(void)
1721 +{
1722 +       unregister_filesystem(&hfsplus_fs_type);
1723 +}
1724 +
1725 +EXPORT_NO_SYMBOLS;
1726 +
1727 +module_init(init_hfsplus_fs)
1728 +module_exit(exit_hfsplus_fs)
1729 diff -urN -x CVS linux-bk/fs/hfsplus/tables.c linux-hfsplus/fs/hfsplus/tables.c
1730 --- linux-bk/fs/hfsplus/tables.c        Wed Dec 31 16:00:00 1969
1731 +++ linux-hfsplus/fs/hfsplus/tables.c   Fri Sep 21 00:42:03 2001
1732 @@ -0,0 +1,408 @@
1733 +/*
1734 + * linux/fs/hfsplus/tables.c
1735 + *
1736 + * Various data tables
1737 + */
1738 +
1739 +#include <linux/hfsplus_fs.h>
1740 +
1741 +/*
1742 + *  Unicode case folding table taken from Apple Technote #1150
1743 + *  (HFS Plus Volume Format)
1744 + */
1745 +
1746 +hfsp_u16 case_fold_table[] = {
1747 +/*
1748 + *  The lower case table consists of a 256-entry high-byte table followed by
1749 + *  some number of 256-entry subtables. The high-byte table contains either an
1750 + *  offset to the subtable for characters with that high byte or zero, which
1751 + *  means that there are no case mappings or ignored characters in that block.
1752 + *  Ignored characters are mapped to zero.
1753 + */
1754 +
1755 +    // High-byte indices ( == 0 iff no case mapping and no ignorables )
1756 +
1757 +
1758 +    /* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
1759 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1760 +    /* 1 */ 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1761 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1762 +    /* 2 */ 0x0700, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1763 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1764 +    /* 3 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1765 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1766 +    /* 4 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1767 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1768 +    /* 5 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1769 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1770 +    /* 6 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1771 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1772 +    /* 7 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1773 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1774 +    /* 8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1775 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1776 +    /* 9 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1777 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1778 +    /* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1779 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1780 +    /* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1781 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1782 +    /* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1783 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1784 +    /* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1785 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1786 +    /* E */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1787 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1788 +    /* F */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1789 +            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0900, 0x0A00,
1790 +
1791 +    // Table 1 (for high byte 0x00)
1792 +
1793 +    /* 0 */ 0xFFFF, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
1794 +            0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
1795 +    /* 1 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
1796 +            0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
1797 +    /* 2 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
1798 +            0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
1799 +    /* 3 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
1800 +            0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
1801 +    /* 4 */ 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
1802 +            0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
1803 +    /* 5 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
1804 +            0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
1805 +    /* 6 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
1806 +            0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
1807 +    /* 7 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
1808 +            0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
1809 +    /* 8 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
1810 +            0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
1811 +    /* 9 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
1812 +            0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
1813 +    /* A */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
1814 +            0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
1815 +    /* B */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
1816 +            0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
1817 +    /* C */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00E6, 0x00C7,
1818 +            0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
1819 +    /* D */ 0x00F0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
1820 +            0x00F8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00FE, 0x00DF,
1821 +    /* E */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
1822 +            0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
1823 +    /* F */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
1824 +            0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
1825 +
1826 +    // Table 2 (for high byte 0x01)
1827 +
1828 +    /* 0 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
1829 +            0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
1830 +    /* 1 */ 0x0111, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
1831 +            0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
1832 +    /* 2 */ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0127, 0x0127,
1833 +            0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
1834 +    /* 3 */ 0x0130, 0x0131, 0x0133, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
1835 +            0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x0140,
1836 +    /* 4 */ 0x0140, 0x0142, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
1837 +            0x0148, 0x0149, 0x014B, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
1838 +    /* 5 */ 0x0150, 0x0151, 0x0153, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157,
1839 +            0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
1840 +    /* 6 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0167, 0x0167,
1841 +            0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
1842 +    /* 7 */ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
1843 +            0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
1844 +    /* 8 */ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
1845 +            0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
1846 +    /* 9 */ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
1847 +            0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
1848 +    /* A */ 0x01A0, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x01A6, 0x01A8,
1849 +            0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01AF,
1850 +    /* B */ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
1851 +            0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
1852 +    /* C */ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
1853 +            0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
1854 +    /* D */ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7,
1855 +            0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
1856 +    /* E */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E5, 0x01E5, 0x01E6, 0x01E7,
1857 +            0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
1858 +    /* F */ 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
1859 +            0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
1860 +
1861 +    // Table 3 (for high byte 0x03)
1862 +
1863 +    /* 0 */ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
1864 +            0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
1865 +    /* 1 */ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
1866 +            0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
1867 +    /* 2 */ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
1868 +            0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
1869 +    /* 3 */ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
1870 +            0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
1871 +    /* 4 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347,
1872 +            0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
1873 +    /* 5 */ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
1874 +            0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
1875 +    /* 6 */ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
1876 +            0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
1877 +    /* 7 */ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
1878 +            0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
1879 +    /* 8 */ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387,
1880 +            0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
1881 +    /* 9 */ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
1882 +            0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
1883 +    /* A */ 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
1884 +            0x03C8, 0x03C9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
1885 +    /* B */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
1886 +            0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
1887 +    /* C */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
1888 +            0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
1889 +    /* D */ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
1890 +            0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
1891 +    /* E */ 0x03E0, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
1892 +            0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
1893 +    /* F */ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7,
1894 +            0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
1895 +
1896 +    // Table 4 (for high byte 0x04)
1897 +
1898 +    /* 0 */ 0x0400, 0x0401, 0x0452, 0x0403, 0x0454, 0x0455, 0x0456, 0x0407,
1899 +            0x0458, 0x0459, 0x045A, 0x045B, 0x040C, 0x040D, 0x040E, 0x045F,
1900 +    /* 1 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
1901 +            0x0438, 0x0419, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
1902 +    /* 2 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
1903 +            0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
1904 +    /* 3 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
1905 +            0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
1906 +    /* 4 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
1907 +            0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
1908 +    /* 5 */ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
1909 +            0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
1910 +    /* 6 */ 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467,
1911 +            0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F,
1912 +    /* 7 */ 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0476, 0x0477,
1913 +            0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F,
1914 +    /* 8 */ 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
1915 +            0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
1916 +    /* 9 */ 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497,
1917 +            0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F,
1918 +    /* A */ 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7,
1919 +            0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF,
1920 +    /* B */ 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7,
1921 +            0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF,
1922 +    /* C */ 0x04C0, 0x04C1, 0x04C2, 0x04C4, 0x04C4, 0x04C5, 0x04C6, 0x04C8,
1923 +            0x04C8, 0x04C9, 0x04CA, 0x04CC, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
1924 +    /* D */ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7,
1925 +            0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
1926 +    /* E */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
1927 +            0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
1928 +    /* F */ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7,
1929 +            0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
1930 +
1931 +    // Table 5 (for high byte 0x05)
1932 +
1933 +    /* 0 */ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507,
1934 +            0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
1935 +    /* 1 */ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
1936 +            0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
1937 +    /* 2 */ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
1938 +            0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
1939 +    /* 3 */ 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
1940 +            0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
1941 +    /* 4 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
1942 +            0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
1943 +    /* 5 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557,
1944 +            0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
1945 +    /* 6 */ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
1946 +            0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
1947 +    /* 7 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
1948 +            0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
1949 +    /* 8 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587,
1950 +            0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
1951 +    /* 9 */ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597,
1952 +            0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
1953 +    /* A */ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7,
1954 +            0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
1955 +    /* B */ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
1956 +            0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
1957 +    /* C */ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7,
1958 +            0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
1959 +    /* D */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
1960 +            0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
1961 +    /* E */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
1962 +            0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
1963 +    /* F */ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7,
1964 +            0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
1965 +
1966 +    // Table 6 (for high byte 0x10)
1967 +
1968 +    /* 0 */ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
1969 +            0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
1970 +    /* 1 */ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
1971 +            0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
1972 +    /* 2 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
1973 +            0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
1974 +    /* 3 */ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
1975 +            0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
1976 +    /* 4 */ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
1977 +            0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
1978 +    /* 5 */ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
1979 +            0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
1980 +    /* 6 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
1981 +            0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
1982 +    /* 7 */ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
1983 +            0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
1984 +    /* 8 */ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
1985 +            0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
1986 +    /* 9 */ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
1987 +            0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
1988 +    /* A */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
1989 +            0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
1990 +    /* B */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
1991 +            0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
1992 +    /* C */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10C6, 0x10C7,
1993 +            0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
1994 +    /* D */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
1995 +            0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
1996 +    /* E */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
1997 +            0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
1998 +    /* F */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7,
1999 +            0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
2000 +
2001 +    // Table 7 (for high byte 0x20)
2002 +
2003 +    /* 0 */ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
2004 +            0x2008, 0x2009, 0x200A, 0x200B, 0x0000, 0x0000, 0x0000, 0x0000,
2005 +    /* 1 */ 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017,
2006 +            0x2018, 0x2019, 0x201A, 0x201B, 0x201C, 0x201D, 0x201E, 0x201F,
2007 +    /* 2 */ 0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027,
2008 +            0x2028, 0x2029, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202F,
2009 +    /* 3 */ 0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037,
2010 +            0x2038, 0x2039, 0x203A, 0x203B, 0x203C, 0x203D, 0x203E, 0x203F,
2011 +    /* 4 */ 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047,
2012 +            0x2048, 0x2049, 0x204A, 0x204B, 0x204C, 0x204D, 0x204E, 0x204F,
2013 +    /* 5 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057,
2014 +            0x2058, 0x2059, 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, 0x205F,
2015 +    /* 6 */ 0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067,
2016 +            0x2068, 0x2069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2017 +    /* 7 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077,
2018 +            0x2078, 0x2079, 0x207A, 0x207B, 0x207C, 0x207D, 0x207E, 0x207F,
2019 +    /* 8 */ 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
2020 +            0x2088, 0x2089, 0x208A, 0x208B, 0x208C, 0x208D, 0x208E, 0x208F,
2021 +    /* 9 */ 0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097,
2022 +            0x2098, 0x2099, 0x209A, 0x209B, 0x209C, 0x209D, 0x209E, 0x209F,
2023 +    /* A */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7,
2024 +            0x20A8, 0x20A9, 0x20AA, 0x20AB, 0x20AC, 0x20AD, 0x20AE, 0x20AF,
2025 +    /* B */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7,
2026 +            0x20B8, 0x20B9, 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, 0x20BF,
2027 +    /* C */ 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7,
2028 +            0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF,
2029 +    /* D */ 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
2030 +            0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x20DF,
2031 +    /* E */ 0x20E0, 0x20E1, 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7,
2032 +            0x20E8, 0x20E9, 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF,
2033 +    /* F */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7,
2034 +            0x20F8, 0x20F9, 0x20FA, 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF,
2035 +
2036 +    // Table 8 (for high byte 0x21)
2037 +
2038 +    /* 0 */ 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107,
2039 +            0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F,
2040 +    /* 1 */ 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117,
2041 +            0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F,
2042 +    /* 2 */ 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127,
2043 +            0x2128, 0x2129, 0x212A, 0x212B, 0x212C, 0x212D, 0x212E, 0x212F,
2044 +    /* 3 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
2045 +            0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F,
2046 +    /* 4 */ 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147,
2047 +            0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F,
2048 +    /* 5 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157,
2049 +            0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F,
2050 +    /* 6 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
2051 +            0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
2052 +    /* 7 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
2053 +            0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
2054 +    /* 8 */ 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187,
2055 +            0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F,
2056 +    /* 9 */ 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197,
2057 +            0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F,
2058 +    /* A */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7,
2059 +            0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF,
2060 +    /* B */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7,
2061 +            0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF,
2062 +    /* C */ 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7,
2063 +            0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF,
2064 +    /* D */ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7,
2065 +            0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF,
2066 +    /* E */ 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7,
2067 +            0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF,
2068 +    /* F */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7,
2069 +            0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF,
2070 +
2071 +    // Table 9 (for high byte 0xFE)
2072 +
2073 +    /* 0 */ 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07,
2074 +            0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F,
2075 +    /* 1 */ 0xFE10, 0xFE11, 0xFE12, 0xFE13, 0xFE14, 0xFE15, 0xFE16, 0xFE17,
2076 +            0xFE18, 0xFE19, 0xFE1A, 0xFE1B, 0xFE1C, 0xFE1D, 0xFE1E, 0xFE1F,
2077 +    /* 2 */ 0xFE20, 0xFE21, 0xFE22, 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27,
2078 +            0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F,
2079 +    /* 3 */ 0xFE30, 0xFE31, 0xFE32, 0xFE33, 0xFE34, 0xFE35, 0xFE36, 0xFE37,
2080 +            0xFE38, 0xFE39, 0xFE3A, 0xFE3B, 0xFE3C, 0xFE3D, 0xFE3E, 0xFE3F,
2081 +    /* 4 */ 0xFE40, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE45, 0xFE46, 0xFE47,
2082 +            0xFE48, 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F,
2083 +    /* 5 */ 0xFE50, 0xFE51, 0xFE52, 0xFE53, 0xFE54, 0xFE55, 0xFE56, 0xFE57,
2084 +            0xFE58, 0xFE59, 0xFE5A, 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F,
2085 +    /* 6 */ 0xFE60, 0xFE61, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE67,
2086 +            0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F,
2087 +    /* 7 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE75, 0xFE76, 0xFE77,
2088 +            0xFE78, 0xFE79, 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F,
2089 +    /* 8 */ 0xFE80, 0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE85, 0xFE86, 0xFE87,
2090 +            0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, 0xFE8E, 0xFE8F,
2091 +    /* 9 */ 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97,
2092 +            0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 0xFE9F,
2093 +    /* A */ 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
2094 +            0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF,
2095 +    /* B */ 0xFEB0, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7,
2096 +            0xFEB8, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF,
2097 +    /* C */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7,
2098 +            0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, 0xFECF,
2099 +    /* D */ 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 0xFED5, 0xFED6, 0xFED7,
2100 +            0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 0xFEDE, 0xFEDF,
2101 +    /* E */ 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7,
2102 +            0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
2103 +    /* F */ 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7,
2104 +            0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0x0000,
2105 +
2106 +    // Table 10 (for high byte 0xFF)
2107 +
2108 +    /* 0 */ 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07,
2109 +            0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
2110 +    /* 1 */ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17,
2111 +            0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
2112 +    /* 2 */ 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
2113 +            0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
2114 +    /* 3 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
2115 +            0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
2116 +    /* 4 */ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
2117 +            0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
2118 +    /* 5 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
2119 +            0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F,
2120 +    /* 6 */ 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
2121 +            0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
2122 +    /* 7 */ 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
2123 +            0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,
2124 +    /* 8 */ 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87,
2125 +            0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,
2126 +    /* 9 */ 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,
2127 +            0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
2128 +    /* A */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7,
2129 +            0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF,
2130 +    /* B */ 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7,
2131 +            0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF,
2132 +    /* C */ 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7,
2133 +            0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
2134 +    /* D */ 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7,
2135 +            0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
2136 +    /* E */ 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7,
2137 +            0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF,
2138 +    /* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
2139 +            0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
2140 +};
2141 diff -urN -x CVS linux-bk/fs/hfsplus/unicode.c linux-hfsplus/fs/hfsplus/unicode.c
2142 --- linux-bk/fs/hfsplus/unicode.c       Wed Dec 31 16:00:00 1969
2143 +++ linux-hfsplus/fs/hfsplus/unicode.c  Thu Dec 13 22:32:32 2001
2144 @@ -0,0 +1,122 @@
2145 +/*
2146 + *  linux/fs/hfsplus/unicode.c
2147 + *
2148 + * Copyright (C) 2001
2149 + * Brad Boyer (flar@allandria.com)
2150 + *
2151 + * Handler routines for unicode strings
2152 + */
2153 +
2154 +#include <linux/types.h>
2155 +#include <linux/nls.h>
2156 +#include <linux/hfsplus_fs.h>
2157 +#include <linux/hfsplus_raw.h>
2158 +
2159 +/* Fold the case of a unicode char, given the 16 bit value */
2160 +/* Returns folded char, or 0 if ignorable */
2161 +static inline hfsp_u16 case_fold(hfsp_u16 c)
2162 +{
2163 +        hfsp_u16 tmp;
2164 +
2165 +        tmp = case_fold_table[(c>>8)];
2166 +        if(tmp)
2167 +                tmp = case_fold_table[tmp + (c & 0xFF)];
2168 +        else
2169 +                tmp = c;
2170 +        return tmp;
2171 +}
2172 +
2173 +/* Compare unicode strings, return values like normal strcmp */
2174 +int hfsplus_unistrcmp(hfsplus_unistr *s1, hfsplus_unistr *s2)
2175 +{
2176 +       hfsp_u16 len1, len2, c1, c2;
2177 +       hfsplus_unichr *p1, *p2;
2178 +
2179 +       len1 = hfsp_get_hs(s1->length);
2180 +       len2 = hfsp_get_hs(s2->length);
2181 +       p1 = s1->unicode;
2182 +       p2 = s2->unicode;
2183 +
2184 +       while(1) {
2185 +               c1 = c2 = 0;
2186 +
2187 +               while(len1 && !c1) {
2188 +                       c1 = case_fold(hfsp_get_hs(p1++));
2189 +                       len1--;
2190 +               }
2191 +               while(len2 && !c2) {
2192 +                       c2 = case_fold(hfsp_get_hs(p2++));
2193 +                       len2--;
2194 +               }
2195 +
2196 +               if(c1 != c2)
2197 +                       return (c1 < c2) ? -1 : 1;
2198 +               if(!c1 && !c2)
2199 +                       return 0;
2200 +       }
2201 +}
2202 +
2203 +int hfsplus_uni2asc(hfsplus_unistr *ustr, char *astr, int *len)
2204 +{
2205 +       const hfsp_u16 *ip;
2206 +       hfsp_u8 *op;
2207 +       hfsp_u16 ustrlen, cc;
2208 +       int size, tmp;
2209 +
2210 +       op = astr;
2211 +       ip = (hfsp_u16 *)(ustr->unicode);
2212 +       ustrlen = hfsp_get_hs(ustr->length);
2213 +       tmp = *len;
2214 +       while((ustrlen > 0) && (tmp > 0)) {
2215 +               cc = hfsp_get_hs(ip);
2216 +               if(cc > 0x7f) {
2217 +                       size = utf8_wctomb(op, cc, tmp);
2218 +                       if(size == -1) {
2219 +                               /* ignore */
2220 +                       } else {
2221 +                               op += size;
2222 +                               tmp -= size;
2223 +                       }
2224 +               } else {
2225 +                       *op++ = (hfsp_u8) cc;
2226 +                       tmp--;
2227 +               }
2228 +               ip++;
2229 +               ustrlen--;
2230 +       }
2231 +       *len = (char *)op - astr;
2232 +       if(ustrlen)
2233 +               return -ENAMETOOLONG;
2234 +       return 0;
2235 +}
2236 +
2237 +int hfsplus_asc2uni(hfsplus_unistr *ustr, char *astr, int len)
2238 +{
2239 +       int tmp;
2240 +       wchar_t c;
2241 +       hfsp_u16 outlen = 0;
2242 +
2243 +       while((outlen <= HFSPLUS_MAX_STRLEN) && (len > 0)) {
2244 +               if(*astr & 0x80) {
2245 +                       if((tmp = utf8_mbtowc(&c, astr, len)) < 0) {
2246 +                               astr++;
2247 +                               len--;
2248 +                               continue;
2249 +                       } else {
2250 +                               astr += tmp;
2251 +                               len -= tmp;
2252 +                       }
2253 +               } else {
2254 +                       c = *astr++;
2255 +                       len--;
2256 +               }
2257 +               hfsp_put_hs(c, ustr->unicode + outlen);
2258 +               outlen++;
2259 +       }
2260 +       hfsp_put_hs(outlen, ustr->length);
2261 +       if(len > 0)
2262 +               return -ENAMETOOLONG;
2263 +       return 0;
2264 +}
2265 +                       
2266 +
2267 diff -urN -x CVS linux-bk/fs/hfsplus/wrapper.c linux-hfsplus/fs/hfsplus/wrapper.c
2268 --- linux-bk/fs/hfsplus/wrapper.c       Wed Dec 31 16:00:00 1969
2269 +++ linux-hfsplus/fs/hfsplus/wrapper.c  Mon Nov  5 00:11:34 2001
2270 @@ -0,0 +1,121 @@
2271 +/*
2272 + *  linux/fs/hfsplus/wrapper.c
2273 + *
2274 + * Copyright (C) 2001
2275 + * Brad Boyer (flar@allandria.com)
2276 + *
2277 + * Handling of HFS wrappers around HFS+ volumes
2278 + */
2279 +
2280 +#include <linux/fs.h>
2281 +#include <linux/hfsplus_fs.h>
2282 +#include <linux/hfsplus_raw.h>
2283 +#include <linux/blkdev.h>
2284 +
2285 +struct hfsplus_wd {
2286 +       hfsp_u32 ablk_size;
2287 +       hfsp_u16 ablk_start;
2288 +       hfsp_u16 embed_start;
2289 +       hfsp_u16 embed_count;
2290 +};
2291 +
2292 +static int hfsplus_read_mdb(unsigned char *bufptr, struct hfsplus_wd *wd)
2293 +{
2294 +       hfsp_u32 extent;
2295 +       hfsp_u16 attrib;
2296 +
2297 +       if(hfsp_get_hs(bufptr + HFSP_WRAPOFF_EMBEDSIG) != HFSPLUS_VOLHEAD_SIG)
2298 +               return 0;
2299 +
2300 +       attrib = hfsp_get_hs(bufptr + HFSP_WRAPOFF_ATTRIB);
2301 +       if(!(attrib & HFSP_WRAP_ATTRIB_SLOCK) ||
2302 +          !(attrib & HFSP_WRAP_ATTRIB_SPARED))
2303 +               return 0;
2304 +
2305 +       wd->ablk_size = hfsp_get_hl(bufptr + HFSP_WRAPOFF_ABLKSIZE);
2306 +       if(wd->ablk_size < HFSPLUS_SECTOR_SIZE)
2307 +               return 0;
2308 +       if(wd->ablk_size % HFSPLUS_SECTOR_SIZE)
2309 +               return 0;
2310 +       wd->ablk_start = hfsp_get_hs(bufptr + HFSP_WRAPOFF_ABLKSTART);
2311 +
2312 +       extent = hfsp_get_hl(bufptr + HFSP_WRAPOFF_EMBEDEXT);
2313 +       wd->embed_start = (extent >> 16) & 0xFFFF;
2314 +       wd->embed_count = extent & 0xFFFF;
2315 +
2316 +       return 1;
2317 +}
2318 +
2319 +/* Find the volume header and fill in some minimum bits in superblock */
2320 +/* Takes in super block, returns true if good data read */
2321 +int hfsplus_read_wrapper(struct super_block *sb)
2322 +{
2323 +       struct buffer_head *bh;
2324 +       struct hfsplus_vh *vhdr;
2325 +       unsigned char *bufptr;
2326 +       unsigned long block, offset, vhsect;
2327 +       kdev_t dev = sb->s_dev;
2328 +       struct hfsplus_wd wd;
2329 +       int blocksize;
2330 +       hfsp_u32 dblksz;
2331 +       hfsp_u16 sig;
2332 +
2333 +       blocksize = get_hardsect_size(dev);
2334 +       if((blocksize == 0) || (blocksize < HFSPLUS_SECTOR_SIZE)) {
2335 +         blocksize = HFSPLUS_SECTOR_SIZE;
2336 +       }
2337 +       set_blocksize(dev, blocksize);
2338 +
2339 +       block = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) / blocksize;
2340 +       offset = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) % blocksize;
2341 +
2342 +       if(!(bh = bread(dev, block, blocksize))) {
2343 +               printk("HFS+-fs: unable to read VHDR or MDB\n");
2344 +               return 0;
2345 +       }
2346 +
2347 +       bufptr = ((unsigned char *)bh->b_data) + offset;
2348 +       sig = hfsp_get_hs(bufptr + HFSP_WRAPOFF_SIG);
2349 +       if(sig == HFSP_WRAP_MAGIC) {
2350 +               if(!hfsplus_read_mdb(bufptr, &wd))
2351 +                       goto error;
2352 +               vhsect = (wd.ablk_start + wd.embed_start * (wd.ablk_size >> 9))
2353 +                       + HFSPLUS_VOLHEAD_SECTOR;
2354 +               block = (vhsect * HFSPLUS_SECTOR_SIZE) / blocksize;
2355 +               offset = (vhsect * HFSPLUS_SECTOR_SIZE) % blocksize;
2356 +               brelse(bh);
2357 +               if(!(bh = bread(dev, block, blocksize))) {
2358 +                       printk("HFS+-fs: unable to read VHDR\n");
2359 +                       return 0;
2360 +               }
2361 +       } else {
2362 +               wd.ablk_start = 0;
2363 +               wd.ablk_size = blocksize;
2364 +               wd.embed_start = 0;
2365 +       }
2366 +       vhdr = (struct hfsplus_vh *)(((char *)bh->b_data) + offset);
2367 +       if(hfsp_get_hs(vhdr->signature) != HFSPLUS_VOLHEAD_SIG)
2368 +               goto error;
2369 +       dblksz = hfsp_get_hl(vhdr->blocksize);
2370 +       if(wd.ablk_size && (wd.ablk_size % dblksz)) {
2371 +               printk("HFS+-fs: embedded blocks not aligned with wrapper\n");
2372 +               goto error;
2373 +       }
2374 +       if((blocksize > dblksz) && (dblksz % blocksize)) {
2375 +               printk("HFS+-fs: volume blocks not aligned on device\n");
2376 +               goto error;
2377 +       }
2378 +       HFSPLUS_SB(sb).dbpab = dblksz / blocksize;
2379 +       HFSPLUS_SB(sb).dboff = (wd.ablk_start + wd.embed_start *
2380 +                               (wd.ablk_size >> 9)) * (blocksize >> 9);
2381 +       sb->s_blocksize = blocksize;
2382 +       sb->s_blocksize_bits = ffz(~(blocksize));
2383 +
2384 +       HFSPLUS_SB(sb).s_vhbh = bh;
2385 +       HFSPLUS_SB(sb).s_vhdr = vhdr;
2386 +       
2387 +       return 1;
2388 + error:
2389 +       brelse(bh);
2390 +       return 0;
2391 +}
2392 diff -urN -x CVS linux-bk/include/linux/fs.h linux-hfsplus/include/linux/fs.h
2393 --- linux-bk/include/linux/fs.h Sun Mar  4 16:50:00 2001
2394 +++ linux-hfsplus/include/linux/fs.h    Tue Apr 10 22:48:28 2001
2395 @@ -294,6 +294,7 @@
2396  #include <linux/shmem_fs.h>
2397  #include <linux/smb_fs_i.h>
2398  #include <linux/hfs_fs_i.h>
2399 +#include <linux/hfsplus_fs_i.h>
2400  #include <linux/adfs_fs_i.h>
2401  #include <linux/qnx4_fs_i.h>
2402  #include <linux/reiserfs_fs_i.h>
2403 @@ -457,6 +458,7 @@
2404                 struct coda_inode_info          coda_i;
2405                 struct smb_inode_info           smbfs_i;
2406                 struct hfs_inode_info           hfs_i;
2407 +               struct hfsplus_inode_info       hfsplus_i;
2408                 struct adfs_inode_info          adfs_i;
2409                 struct qnx4_inode_info          qnx4_i;
2410                 struct reiserfs_inode_info      reiserfs_i;
2411 @@ -635,6 +637,7 @@
2412  #include <linux/romfs_fs_sb.h>
2413  #include <linux/smb_fs_sb.h>
2414  #include <linux/hfs_fs_sb.h>
2415 +#include <linux/hfsplus_fs_sb.h>
2416  #include <linux/adfs_fs_sb.h>
2417  #include <linux/qnx4_fs_sb.h>
2418  #include <linux/reiserfs_fs_sb.h>
2419 @@ -685,6 +688,7 @@
2420                 struct romfs_sb_info    romfs_sb;
2421                 struct smb_sb_info      smbfs_sb;
2422                 struct hfs_sb_info      hfs_sb;
2423 +               struct hfsplus_sb_info  hfsplus_sb;
2424                 struct adfs_sb_info     adfs_sb;
2425                 struct qnx4_sb_info     qnx4_sb;
2426                 struct reiserfs_sb_info reiserfs_sb;
2427 diff -urN -x CVS linux-bk/include/linux/hfsplus_fs.h linux-hfsplus/include/linux/hfsplus_fs.h
2428 --- linux-bk/include/linux/hfsplus_fs.h Wed Dec 31 16:00:00 1969
2429 +++ linux-hfsplus/include/linux/hfsplus_fs.h    Mon Nov  5 00:01:52 2001
2430 @@ -0,0 +1,170 @@
2431 +/*
2432 + *  linux/include/linux/hfsplus_fs.h
2433 + *
2434 + * Copyright (C) 1999
2435 + * Brad Boyer (flar@pants.nu)
2436 + *
2437 + */
2438 +
2439 +#ifndef _LINUX_HFSPLUS_FS_H
2440 +#define _LINUX_HFSPLUS_FS_H
2441 +
2442 +#include <linux/fs.h>
2443 +
2444 +#include <asm/unaligned.h>
2445 +
2446 +#include <linux/hfsplus_raw.h>
2447 +#include <linux/hfsplus_fs_sb.h>
2448 +
2449 +typedef  __u8 hfsp_u8;
2450 +typedef __u16 hfsp_u16;
2451 +typedef __u32 hfsp_u32;
2452 +typedef __u64 hfsp_u64;
2453 +typedef __u32 hfsp_cnid;
2454 +
2455 +/* Runtime config options */
2456 +#define HFSPLUS_CASE_ASIS      0
2457 +#define HFSPLUS_CASE_LOWER     1
2458 +
2459 +#define HFSPLUS_FORK_RAW       0
2460 +#define HFSPLUS_FORK_CAP       1
2461 +#define HFSPLUS_FORK_DOUBLE    2
2462 +#define HFSPLUS_FORK_NETATALK  3
2463 +
2464 +#define HFSPLUS_NAMES_TRIVIAL  0
2465 +#define HFSPLUS_NAMES_CAP      1
2466 +#define HFSPLUS_NAMES_NETATALK 2
2467 +#define HFSPLUS_NAMES_7BIT     3
2468 +
2469 +#define HFSPLUS_DEF_CR_TYPE    0x3F3F3F3F  /* '????' */
2470 +
2471 +#define HFSPLUS_TYPE_DATA 0x00
2472 +#define HFSPLUS_TYPE_RSRC 0xFF
2473 +
2474 +struct hfsplus_btree;
2475 +struct page;
2476 +
2477 +/* An HFS+ BTree node in memory */
2478 +typedef struct {
2479 +       struct hfsplus_btree *tree;
2480 +       struct page          *page;
2481 +       struct inode         *inode;
2482 +
2483 +       hfsp_u32              prev;
2484 +       hfsp_u32              this;
2485 +       hfsp_u32              next;
2486 +
2487 +       hfsp_u16              num_recs;
2488 +       hfsp_u8               kind;
2489 +       hfsp_u8               height;
2490 +} hfsplus_bnode;
2491 +
2492 +typedef int (*btree_keycmp)(hfsplus_btree_key *, hfsplus_btree_key *);
2493 +
2494 +/* An HFS+ BTree held in memory */
2495 +typedef struct hfsplus_btree {
2496 +       struct super_block *sb;
2497 +       btree_keycmp        keycmp;
2498 +
2499 +       hfsp_u32            cnid;
2500 +       hfsp_u32            root;
2501 +       hfsp_u32            node_count;
2502 +       hfsp_u32            free_nodes;
2503 +       hfsp_u32            attributes;
2504 +
2505 +       hfsp_u16            node_size;
2506 +       hfsp_u16            max_key_len;
2507 +       hfsp_u16            depth;
2508 +} hfsplus_btree;
2509 +
2510 +/* An iterator for walking an HFS+ BTree */
2511 +typedef struct {
2512 +       hfsplus_btree *tree;
2513 +       hfsp_u32 node;
2514 +       hfsp_u16 rec;
2515 +} hfsplus_btiter;
2516 +
2517 +/*
2518 + * Functions in any *.c used in other files
2519 + */
2520 +
2521 +/* bfind.c */
2522 +int hfsplus_btfind(hfsplus_btree *, hfsplus_btree_key *, void *, int *);
2523 +int hfsplus_btfind_exact(hfsplus_btree *, hfsplus_btree_key *, void *, int *);
2524 +int hfsplus_btiter_find(hfsplus_btiter *, hfsplus_btree_key *);
2525 +
2526 +/* bnode.c */
2527 +hfsplus_bnode *hfsplus_get_bnode(hfsplus_btree *, hfsp_u32);
2528 +void hfsplus_put_bnode(hfsplus_bnode *);
2529 +hfsp_u16 hfsplus_bnode_copybytes(hfsplus_bnode *, void *, hfsp_u16, hfsp_u16);
2530 +
2531 +/* brec.c */
2532 +hfsp_u16 hfsplus_brec_off(hfsplus_bnode *, hfsp_u16);
2533 +hfsp_u16 hfsplus_brec_len(hfsplus_bnode *, hfsp_u16);
2534 +hfsp_u16 hfsplus_brec_lenoff(hfsplus_bnode *, hfsp_u16, hfsp_u16 *);
2535 +hfsp_u16 hfsplus_brec_data(hfsplus_bnode *, hfsp_u16, char *, hfsp_u16);
2536 +hfsp_u16 hfsplus_brec_keylen(hfsplus_bnode *, hfsp_u16);
2537 +hfsp_u16 hfsplus_brec_key(hfsplus_bnode *, hfsp_u16, void *, hfsp_u16);
2538 +
2539 +/* btiter.c */
2540 +void hfsplus_btiter_setup(hfsplus_btiter *, hfsplus_btree *);
2541 +int hfsplus_btiter_move(hfsplus_btiter *, int);
2542 +int hfsplus_btiter_get(hfsplus_btiter *, hfsplus_btree_key *, void *, int *);
2543 +
2544 +/* btree.c */
2545 +hfsplus_btree *hfsplus_open_btree(struct super_block *, hfsp_cnid);
2546 +void hfsplus_close_btree(struct hfsplus_btree *);
2547 +
2548 +/* catalog.c */
2549 +int hfsplus_cmp_cat_key(hfsplus_btree_key *, hfsplus_btree_key *);
2550 +int hfsplus_fill_cat_key(hfsplus_btree_key *, hfsp_cnid, char *, int);
2551 +int hfsplus_find_cat(struct super_block *, unsigned long, hfsplus_cat_entry *);
2552 +
2553 +/* extents.c */
2554 +int hfsplus_cmp_ext_key(hfsplus_btree_key *, hfsplus_btree_key *);
2555 +void hfsplus_fill_ext_key(hfsplus_btree_key *, hfsp_u32, hfsp_u32, hfsp_u8);
2556 +int hfsplus_get_block(struct inode *, long, struct buffer_head *, int);
2557 +
2558 +/* inode.c */
2559 +int hfsplus_cat_fill_inode(struct inode *, hfsplus_cat_entry *);
2560 +
2561 +/* options.c */
2562 +int parse_options(char *, struct hfsplus_sb_info *);
2563 +void fill_defaults(struct hfsplus_sb_info *);
2564 +void fill_current(struct hfsplus_sb_info *,  struct hfsplus_sb_info *);
2565 +
2566 +/* tables.c */
2567 +extern hfsp_u16 case_fold_table[];
2568 +
2569 +/* unicode.c */
2570 +int hfsplus_unistrcmp(hfsplus_unistr *, hfsplus_unistr *);
2571 +int hfsplus_uni2asc(hfsplus_unistr *, char *, int *);
2572 +int hfsplus_asc2uni(hfsplus_unistr *, char *, int);
2573 +
2574 +/* wrapper.c */
2575 +int hfsplus_read_wrapper(struct super_block *);
2576 +
2577 +/* access macros */
2578 +#define HFSPLUS_SB(super)        ((super)->u.hfsplus_sb)
2579 +#define HFSPLUS_I(inode)         ((inode)->u.hfsplus_i)
2580 +
2581 +#define HFSPLUS_IS_DATA(inode)   (1)
2582 +#define HFSPLUS_IS_RSRC(inode)   (0)
2583 +
2584 +#define hfsp_get_hs(addr)        ntohs(*((hfsp_u16 *)(addr)))
2585 +#define hfsp_get_hl(addr)        ntohl(get_unaligned((hfsp_u32 *)(addr)))
2586 +#define hfsp_get_ahl(addr)       ntohl(*((hfsp_u32 *)(addr)))
2587 +#define hfsp_get_hll(addr)       __be64_to_cpu(get_unaligned((hfsp_u64 *)(addr)))
2588 +#define hfsp_get_ahll(addr)      __be64_to_cpu(*((hfsp_u64 *)(addr)))
2589 +#define hfsp_put_hs(val, addr)   ((void)(*((hfsp_u16 *)(addr)) = ntohs(val)))
2590 +#define hfsp_put_hl(val, addr)   put_unaligned(htonl(val), (hfsp_u32 *)(addr))
2591 +#define hfsp_put_ahl(val, addr)  ((void)(*((hfsp_u32 *)(addr)) = ntohl(val)))
2592 +#define hfsp_put_hll(val, addr)  put_unaligned(__cpu_to_be64(val), \
2593 +                                              (hfsp_u64 *)(addr))
2594 +#define hfsp_put_ahll(val, addr) ((void)(*((hfsp_u64 *)(addr)) = \
2595 +                                 __cpu_to_be64(val)))
2596 +
2597 +/* time macros */
2598 +#define hfsp_mt2ut(t)          (hfsp_get_hl(t) - 2082844800U)
2599 +
2600 +#endif
2601 diff -urN -x CVS linux-bk/include/linux/hfsplus_fs_i.h linux-hfsplus/include/linux/hfsplus_fs_i.h
2602 --- linux-bk/include/linux/hfsplus_fs_i.h       Wed Dec 31 16:00:00 1969
2603 +++ linux-hfsplus/include/linux/hfsplus_fs_i.h  Mon Sep  3 22:57:43 2001
2604 @@ -0,0 +1,23 @@
2605 +/*
2606 + *  linux/include/linux/hfsplus_fs_i.h
2607 + *
2608 + * Copyright (C) 1999
2609 + * Brad Boyer (flar@pants.nu)
2610 + *
2611 + */
2612 +
2613 +#ifndef _LINUX_HFSPLUS_FS_I_H
2614 +#define _LINUX_HFSPLUS_FS_I_H
2615 +
2616 +#include <linux/types.h>
2617 +
2618 +struct hfsplus_fork;
2619 +
2620 +struct hfsplus_inode_info {
2621 +       /* Number of subdirectories in a directory */
2622 +       nlink_t              ndirs;
2623 +       /* Device number in hfsplus_permissions in catalog */
2624 +       __u32                dev;
2625 +};
2626 +
2627 +#endif
2628 diff -urN -x CVS linux-bk/include/linux/hfsplus_fs_sb.h linux-hfsplus/include/linux/hfsplus_fs_sb.h
2629 --- linux-bk/include/linux/hfsplus_fs_sb.h      Wed Dec 31 16:00:00 1969
2630 +++ linux-hfsplus/include/linux/hfsplus_fs_sb.h Sat Oct 20 23:33:18 2001
2631 @@ -0,0 +1,50 @@
2632 +/*
2633 + *  linux/include/linux/hfsplus_fs_sb.h
2634 + *
2635 + * Copyright (C) 1999
2636 + * Brad Boyer (flar@pants.nu)
2637 + *
2638 + */
2639 +
2640 +#ifndef _LINUX_HFSPLUS_FS_SB_H
2641 +#define _LINUX_HFSPLUS_FS_SB_H
2642 +
2643 +#include <asm/types.h>
2644 +
2645 +/*
2646 + * HFS+ superblock info (built from Volume Header on disk)
2647 + */
2648 +
2649 +struct hfsplus_vh;
2650 +struct hfsplus_btree;
2651 +
2652 +struct hfsplus_sb_info {
2653 +       struct buffer_head   *s_vhbh;
2654 +       struct hfsplus_vh    *s_vhdr;
2655 +       struct hfsplus_btree *ext_tree;
2656 +       struct hfsplus_btree *cat_tree;
2657 +
2658 +       /* Runtime variables */
2659 +       __u32                 dbpab; /* Device blocks per allocation block */
2660 +       __u32                 dboff; /* Offset to actual HFS+ blocks */
2661 +
2662 +       /* Stuff in host order from Vol Header */
2663 +       __u32                 free_blocks;
2664 +       __u32                 next_cnid;
2665 +       __u32                 file_count;
2666 +       __u32                 folder_count;
2667 +
2668 +       /* Config options */
2669 +       __u32                 creator;
2670 +       __u32                 type;
2671 +
2672 +       int                   charcase;
2673 +       int                   fork;
2674 +       int                   namemap;
2675 +
2676 +       umode_t               umask;
2677 +       uid_t                 uid;
2678 +       gid_t                 gid;
2679 +};
2680 +
2681 +#endif
2682 diff -urN -x CVS linux-bk/include/linux/hfsplus_raw.h linux-hfsplus/include/linux/hfsplus_raw.h
2683 --- linux-bk/include/linux/hfsplus_raw.h        Wed Dec 31 16:00:00 1969
2684 +++ linux-hfsplus/include/linux/hfsplus_raw.h   Thu Dec 13 22:11:55 2001
2685 @@ -0,0 +1,314 @@
2686 +/*
2687 + *  linux/include/linux/hfsplus_raw.h
2688 + *
2689 + * Copyright (C) 1999
2690 + * Brad Boyer (flar@pants.nu)
2691 + *
2692 + * Format of structures on disk
2693 + * Information taken from Apple Technote #1150 (HFS Plus Volume Format)
2694 + *
2695 + */
2696 +
2697 +#ifndef _LINUX_HFSPLUS_RAW_H
2698 +#define _LINUX_HFSPLUS_RAW_H
2699 +
2700 +#include <asm/types.h>
2701 +
2702 +/* Some constants */
2703 +#define HFSPLUS_SECTOR_SIZE        512
2704 +#define HFSPLUS_VOLHEAD_SECTOR       2
2705 +#define HFSPLUS_VOLHEAD_SIG     0x482b
2706 +#define HFSPLUS_SUPER_MAGIC     0x482b
2707 +#define HFSPLUS_CURRENT_VERSION      4
2708 +
2709 +#define HFSP_WRAP_MAGIC         0x4244
2710 +#define HFSP_WRAP_ATTRIB_SLOCK  0x8000
2711 +#define HFSP_WRAP_ATTRIB_SPARED 0x0200
2712 +
2713 +#define HFSP_WRAPOFF_SIG          0x00
2714 +#define HFSP_WRAPOFF_ATTRIB       0x0A
2715 +#define HFSP_WRAPOFF_ABLKSIZE     0x14
2716 +#define HFSP_WRAPOFF_ABLKSTART    0x1C
2717 +#define HFSP_WRAPOFF_EMBEDSIG     0x7C
2718 +#define HFSP_WRAPOFF_EMBEDEXT     0x7E
2719 +
2720 +/* Structures used on disk */
2721 +
2722 +typedef unsigned char hfsp_byte;
2723 +typedef unsigned char hfsp_word[2];
2724 +typedef unsigned char hfsp_lword[4];
2725 +typedef unsigned char hfsp_llword[8];
2726 +
2727 +typedef hfsp_lword hfsplus_cnid;
2728 +typedef hfsp_word hfsplus_unichr;
2729 +
2730 +/* A "string" as used in filenames, etc. */
2731 +typedef struct {
2732 +       hfsp_word          length;
2733 +       hfsplus_unichr     unicode[255];
2734 +} hfsplus_unistr;
2735 +
2736 +#define HFSPLUS_MAX_STRLEN 255
2737 +
2738 +/* POSIX permissions */
2739 +typedef struct {
2740 +       hfsp_lword         owner;
2741 +       hfsp_lword         group;
2742 +       hfsp_lword         mode;
2743 +       hfsp_lword         dev;
2744 +} hfsplus_perm;
2745 +
2746 +/* A single contiguous area of a file */
2747 +typedef struct {
2748 +       hfsp_lword         start_block;
2749 +       hfsp_lword         block_count;
2750 +} hfsplus_extent;
2751 +typedef hfsplus_extent hfsplus_extent_rec[8];
2752 +
2753 +/* Information for a "Fork" in a file */
2754 +typedef struct {
2755 +       hfsp_llword        total_size;
2756 +       hfsp_lword         clump_size;
2757 +       hfsp_lword         total_blocks;
2758 +       hfsplus_extent_rec extents;
2759 +} hfsplus_fork_raw;
2760 +
2761 +/* HFS+ Volume Header */
2762 +typedef struct hfsplus_vh{
2763 +       hfsp_word          signature;
2764 +       hfsp_word          version;
2765 +       hfsp_lword         attributes;
2766 +       hfsp_lword         last_mount_vers;
2767 +       hfsp_lword         reserved;
2768 +
2769 +       hfsp_lword         create_date;
2770 +       hfsp_lword         modify_date;
2771 +       hfsp_lword         backup_date;
2772 +       hfsp_lword         checked_date;
2773 +
2774 +       hfsp_lword         file_count;
2775 +       hfsp_lword         folder_count;
2776 +
2777 +       hfsp_lword         blocksize;
2778 +       hfsp_lword         total_blocks;
2779 +       hfsp_lword         free_blocks;
2780 +
2781 +       hfsp_lword         next_alloc;
2782 +       hfsp_lword         rsrc_clump_sz;
2783 +       hfsp_lword         data_clump_sz;
2784 +       hfsplus_cnid       next_cnid;
2785 +
2786 +       hfsp_lword         write_count;
2787 +       hfsp_llword        encodings_bmp;
2788 +
2789 +       hfsp_byte          finder_info[32];
2790 +
2791 +       hfsplus_fork_raw   alloc_file;
2792 +       hfsplus_fork_raw   ext_file;
2793 +       hfsplus_fork_raw   cat_file;
2794 +       hfsplus_fork_raw   attr_file;
2795 +       hfsplus_fork_raw   start_file;
2796 +} hfsplus_vh;
2797 +
2798 +/* HFS+ volume attributes */
2799 +#define HFSPLUS_VOL_UNMNT     (1 << 8)
2800 +#define HFSPLUS_VOL_SPARE_BLK (1 << 9)
2801 +#define HFSPLUS_VOL_NOCACHE   (1 << 10)
2802 +#define HFSPLUS_VOL_INCNSTNT  (1 << 11)
2803 +#define HFSPLUS_VOL_SOFTLOCK  (1 << 15)
2804 +
2805 +/* HFS+ BTree node descriptor */
2806 +typedef struct {
2807 +       hfsp_lword         next;
2808 +       hfsp_lword         prev;
2809 +       hfsp_byte          kind;
2810 +       hfsp_byte          height;
2811 +       hfsp_word          num_rec;
2812 +       hfsp_word          reserved;
2813 +} hfsplus_btree_node_desc;
2814 +
2815 +/* HFS+ BTree node types */
2816 +#define HFSPLUS_NODE_NDX  0x00
2817 +#define HFSPLUS_NODE_HEAD 0x01
2818 +#define HFSPLUS_NODE_MAP  0x02
2819 +#define HFSPLUS_NODE_LEAF 0xFF
2820 +
2821 +/* HFS+ BTree header */
2822 +typedef struct {
2823 +       hfsp_word          depth;
2824 +       hfsp_lword         root;
2825 +       hfsp_lword         leaf_count;
2826 +       hfsp_lword         leaf_head;
2827 +       hfsp_lword         leaf_tail;
2828 +       hfsp_word          node_size;
2829 +       hfsp_word          max_key_len;
2830 +       hfsp_lword         node_count;
2831 +       hfsp_lword         free_nodes;
2832 +       hfsp_word          reserved1;
2833 +       hfsp_lword         clump_size;
2834 +       hfsp_byte          btree_type;
2835 +       hfsp_byte          reserved2;
2836 +       hfsp_lword         attributes;
2837 +       hfsp_lword         reserved3[16];
2838 +} hfsplus_btree_head;
2839 +
2840 +/* BTree attributes */
2841 +#define HFSPLUS_TREE_BIGKEYS         2
2842 +#define HFSPLUS_TREE_VAR_NDXKEY_SIZE 4
2843 +
2844 +/* HFS+ BTree misc info */
2845 +#define HFSPLUS_TREE_HEAD 0
2846 +#define HFSPLUS_NODE_MXSZ 32768
2847 +
2848 +/* Some special File ID numbers (stolen from hfs.h) */
2849 +#define HFSPLUS_POR_CNID             1  /* Parent Of the Root */
2850 +#define HFSPLUS_ROOT_CNID            2  /* ROOT directory */
2851 +#define HFSPLUS_EXT_CNID             3  /* EXTents B-tree */
2852 +#define HFSPLUS_CAT_CNID             4  /* CATalog B-tree */
2853 +#define HFSPLUS_BAD_CNID             5  /* BAD blocks file */
2854 +#define HFSPLUS_ALLOC_CNID           6  /* ALLOCation file */
2855 +#define HFSPLUS_START_CNID           7  /* STARTup file */
2856 +#define HFSPLUS_ATTR_CNID            8  /* ATTRibutes file  */
2857 +#define HFSPLUS_EXCH_CNID           15  /* ExchangeFiles temp id */
2858 +
2859 +/* HFS+ catalog entry key */
2860 +typedef struct {
2861 +       hfsplus_cnid       parent;
2862 +       hfsplus_unistr     name;
2863 +} hfsplus_cat_key;
2864 +
2865 +
2866 +/* Structs from hfs.h */
2867 +typedef struct {
2868 +        hfsp_word          v;
2869 +        hfsp_word          h;
2870 +} hfsp_point;
2871 +
2872 +typedef struct {
2873 +        hfsp_word          top;
2874 +        hfsp_word          left;
2875 +        hfsp_word          bottom;
2876 +        hfsp_word          right;
2877 +} hfsp_rect;
2878 +
2879 +
2880 +/* HFS directory info (stolen from hfs.h */
2881 +typedef struct {
2882 +        hfsp_rect          frRect;
2883 +        hfsp_word          frFlags;
2884 +        hfsp_point         frLocation;
2885 +        hfsp_word          frView;
2886 +} DInfo;
2887 +
2888 +typedef struct {
2889 +        hfsp_point         frScroll;
2890 +        hfsp_lword         frOpenChain;
2891 +        hfsp_word          frUnused;
2892 +        hfsp_word          frComment;
2893 +        hfsp_lword         frPutAway;
2894 +} DXInfo;
2895 +
2896 +/* HFS+ folder data (part of an hfsplus_cat_entry) */
2897 +typedef struct {
2898 +       hfsp_word          flags;
2899 +       hfsp_lword         valence;
2900 +       hfsplus_cnid       id;
2901 +       hfsp_lword         create_date;
2902 +       hfsp_lword         content_mod_date;
2903 +       hfsp_lword         attribute_mod_date;
2904 +       hfsp_lword         access_date;
2905 +       hfsp_lword         backup_date;
2906 +       hfsplus_perm       permissions;
2907 +       DInfo              user_info;
2908 +       DXInfo             finder_info;
2909 +       hfsp_lword         text_encoding;
2910 +       hfsp_lword         reserved;
2911 +} hfsplus_cat_folder;
2912 +
2913 +/* HFS file info (stolen from hfs.h) */
2914 +typedef struct {
2915 +        hfsp_lword         fdType;
2916 +        hfsp_lword         fdCreator;
2917 +        hfsp_word          fdFlags;
2918 +        hfsp_point         fdLocation;
2919 +        hfsp_word          fdFldr;
2920 +} FInfo;
2921 +
2922 +typedef struct {
2923 +        hfsp_word          fdIconID;
2924 +        hfsp_byte          fdUnused[8];
2925 +        hfsp_word          fdComment;
2926 +        hfsp_lword         fdPutAway;
2927 +} FXInfo;
2928 +
2929 +/* HFS+ file data (part of a cat_entry) */
2930 +typedef struct {
2931 +       hfsp_word          flags;
2932 +       hfsp_lword         reserved1;
2933 +       hfsplus_cnid       id;
2934 +       hfsp_lword         create_date;
2935 +       hfsp_lword         content_mod_date;
2936 +       hfsp_lword         attribute_mod_date;
2937 +       hfsp_lword         access_date;
2938 +       hfsp_lword         backup_date;
2939 +       hfsplus_perm       permissions;
2940 +       FInfo              user_info;
2941 +       FXInfo             finder_info;
2942 +       hfsp_lword         text_encoding;
2943 +       hfsp_lword         reserved2;
2944 +
2945 +       hfsplus_fork_raw   data_fork;
2946 +       hfsplus_fork_raw   res_fork;
2947 +} hfsplus_cat_file;
2948 +
2949 +/* File attribute bits */
2950 +#define kHFSFileLockedBit       0x0000
2951 +#define kHFSFileLockedMask      0x0001
2952 +#define kHFSThreadExistsBit     0x0001
2953 +#define kHFSThreadExistsMask    0x0002
2954 +
2955 +/* HFS+ catalog thread (part of a cat_entry) */
2956 +typedef struct {
2957 +       hfsp_word          reserved;
2958 +       hfsplus_cnid       parentID;
2959 +       hfsplus_unistr     nodeName;
2960 +} hfsplus_cat_thread;
2961 +
2962 +#define HFSPLUS_MIN_THREAD_SZ 10
2963 +
2964 +/* A data record in the catalog tree */
2965 +typedef struct {
2966 +       hfsp_word          type;
2967 +       union {
2968 +               hfsplus_cat_folder folder;
2969 +               hfsplus_cat_file   file;
2970 +               hfsplus_cat_thread thread;
2971 +       } u;
2972 +} hfsplus_cat_entry;
2973 +
2974 +/* HFS+ catalog entry type */
2975 +#define HFSPLUS_FOLDER         0x0001
2976 +#define HFSPLUS_FILE           0x0002
2977 +#define HFSPLUS_FOLDER_THREAD  0x0003
2978 +#define HFSPLUS_FILE_THREAD    0x0004
2979 +
2980 +/* HFS+ extents tree key */
2981 +typedef struct {
2982 +       hfsp_byte          fork_type;
2983 +       hfsp_byte          pad;
2984 +       hfsplus_cnid       cnid;
2985 +       hfsp_lword         start_block;
2986 +} hfsplus_ext_key;
2987 +
2988 +#define HFSPLUS_EXT_KEYLEN 10
2989 +
2990 +/* HFS+ generic BTree key */
2991 +typedef struct {
2992 +       hfsp_word          key_len;
2993 +       union {
2994 +               hfsplus_cat_key cat;
2995 +               hfsplus_ext_key ext;
2996 +       } u;
2997 +} hfsplus_btree_key;
2998 +
2999 +#endif
This page took 0.325328 seconds and 3 git commands to generate.