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.
8 +Apple Extended file system support (read-only) (EXPERIMENTAL)
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
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.
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.
26 ROM file system support
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
33 L: linux-kernel@vger.kernel.org
38 +M: flar@allandria.com
39 +W: http://sourceforge.net/projects/linux-hfsplus/
42 HGA FRAMEBUFFER DRIVER
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
50 dep_tristate 'Apple Macintosh file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
52 +dep_tristate 'Apple Extended HFS file system support (EXPERIMENTAL)' CONFIG_HFSPLUS_FS $CONFIG_EXPERIMENTAL
54 dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
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
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
73 +# Makefile for the Linux hfsplus filesystem routines.
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).
79 +# Note 2! The CFLAGS definitions are now in the main makefile.
81 +O_TARGET := hfsplus.o
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
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
94 + * linux/fs/hfsplus/bfind.c
96 + * Copyright (C) 2001
97 + * Brad Boyer (flar@allandria.com)
99 + * Search routines for btrees
102 +#include <linux/hfsplus_fs.h>
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,
108 + hfsplus_btree_key tmpkey;
110 + hfsp_u16 b, m, e, keylen;
113 + e = bnode->num_recs - 1;
117 + keylen = hfsplus_brec_key(bnode, m, &tmpkey, sizeof(tmpkey));
119 + printk("HFS+-fs: missing key in B*Tree\n");
123 + cmpval = bnode->tree->keycmp(&tmpkey, key);
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)
145 + hfsplus_bnode *curr, *last, *retval;
148 + hfsp_u16 rec, off, klen;
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");
160 + rec = hfsplus_find_rec(curr, key, &localerr);
161 + if(rec >= curr->num_recs) {
166 + if(curr->kind == HFSPLUS_NODE_LEAF) {
173 + if(curr->kind != HFSPLUS_NODE_NDX) {
174 + printk("HFS+-fs: non-keyed B*Tree node in index\n");
178 + hfsplus_put_bnode(last);
182 + klen = hfsplus_brec_keylen(curr, rec);
184 + printk("HFS+-fs: bad index key in B*Tree\n");
187 + if(hfsplus_brec_lenoff(curr, rec, &off) < klen + 4) {
188 + printk("HFS+-fs: invalid index record in B*Tree\n");
191 + if(hfsplus_bnode_copybytes(curr, data, off + klen, 4) != 4) {
192 + printk("HFS+-fs: unable to follow index in B*Tree\n");
195 + next = hfsp_get_hl(data);
198 + curr = hfsplus_get_bnode(tree, next);
200 + printk("HFS+-fs: failed to get next node in B*Tree\n");
203 + if(!curr->height || (curr->height != (last->height - 1))) {
204 + printk("HFS+-fs: inconsistency in B*Tree height\n");
207 + } /* end of for(;;) */
209 + if(last && (last != retval))
210 + hfsplus_put_bnode(last);
211 + if(curr && (curr != retval))
212 + hfsplus_put_bnode(curr);
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)
222 + hfsplus_bnode *node;
223 + hfsplus_btree_key tmpkey;
225 + hfsp_u16 rec, off, keylen, datalen;
227 + if(!tree || !key || !entry || !entry_len)
230 + node = hfsplus_find_leaf(tree, key, &rec, &err);
234 + if(!(keylen = hfsplus_brec_key(node, rec, &tmpkey, sizeof(tmpkey)))) {
235 + printk("HFS+-fs: unable to read key from B*Tree record\n");
238 + if(tree->keycmp(key, &tmpkey)) {
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");
248 + if(!hfsplus_bnode_copybytes(node, entry, off + keylen, datalen)) {
249 + printk("HFS+-fs: unable to read record in B*Tree\n");
252 + *entry_len = datalen;
255 + hfsplus_put_bnode(node);
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,
265 + hfsplus_bnode *node;
267 + hfsp_u16 rec, off, keylen, datalen;
269 + if(!tree || !key || !entry || !entry_len)
272 + node = hfsplus_find_leaf(tree, key, &rec, &err);
276 + if(!(keylen = hfsplus_brec_keylen(node, rec))) {
277 + printk("HFS+-fs: unable to read key from B*Tree record\n");
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");
286 + if(!hfsplus_bnode_copybytes(node, key, off, keylen)) {
287 + printk("HFS+-fs: unable to copy key from B*Tree\n");
290 + if(!hfsplus_bnode_copybytes(node, entry, off + keylen, datalen)) {
291 + printk("HFS+-fs: unable to read record in B*Tree\n");
294 + *entry_len = datalen;
297 + hfsplus_put_bnode(node);
301 +int hfsplus_btiter_find(hfsplus_btiter *iter, hfsplus_btree_key *key)
303 + hfsplus_bnode *node;
305 + hfsplus_btree_key tmpkey;
306 + hfsp_u16 rec, keylen;
308 + if(!iter || !key || !iter->tree)
311 + if((node = hfsplus_find_leaf(iter->tree, key, &rec, &err)) == NULL)
313 + if(!(keylen = hfsplus_brec_key(node, rec, &tmpkey, sizeof(tmpkey)))) {
314 + printk("HFS+-fs: unable to read key from B*Tree record\n");
318 + if(node->tree->keycmp(key, &tmpkey)) {
322 + iter->node = node->this;
326 + hfsplus_put_bnode(node);
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
334 + * linux/fs/hfsplus/bnode.c
336 + * Copyright (C) 2001
337 + * Brad Boyer (flar@allandria.com)
339 + * Handle basic btree node operations
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>
349 +/* Convert a node, offset to page number in tree */
350 +static inline unsigned long hfsplus_pagenum(hfsplus_bnode *node, hfsp_u16 off)
352 + return ((node->this * node->tree->node_size) + off) >> PAGE_SHIFT;
355 +/* Convert a node, offset to page offset */
356 +static inline unsigned long hfsplus_pageoff(hfsplus_bnode *node, hfsp_u16 off)
358 + return ((node->this * node->tree->node_size) + off) & (PAGE_SIZE - 1);
361 +/* Dump a page we loaded with hfsplus_get_page */
362 +static inline void hfsplus_put_page(hfsplus_bnode *node)
365 + UnlockPage(node->page);
366 + kunmap(node->page);
367 + page_cache_release(node->page);
372 +/* Get the give page associated with the inode */
373 +static struct page *hfsplus_get_page(hfsplus_bnode *node, unsigned long n)
375 + struct address_space *mapping;
378 + if(!node || !node->tree)
382 + node->inode = iget(node->tree->sb, node->tree->cnid);
384 + printk("HFS+-fs: Failed load of B*Tree data\n");
388 + mapping = node->inode->i_mapping;
390 + if(node->page->index == n) {
394 + hfsplus_put_page(node);
396 + page = read_cache_page(mapping, n, mapping->a_ops->readpage, NULL);
397 + if(!IS_ERR(page)) {
401 + if(!Page_Uptodate(page))
403 + if(PageError(page))
409 + hfsplus_put_page(node);
413 +/* Fill the node->page element for the given offset */
414 +static inline struct page *hfsplus_fill_page(hfsplus_bnode *node, hfsp_u16 off)
416 + return hfsplus_get_page(node, hfsplus_pagenum(node, off));
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)
425 + if(hfsplus_pagenum(node, off) == hfsplus_pagenum(node, off+len-1)) {
426 + /* All on one page */
427 + if(!hfsplus_fill_page(node, off)) {
430 + kaddr = (char *)page_address(node->page);
431 + memcpy(buf, kaddr + hfsplus_pageoff(node, off), len);
433 + /* Multiple pages (should be rare) */
434 + unsigned long poff;
438 + while(curr < len) {
439 + if(!hfsplus_fill_page(node, off + curr)) {
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);
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)
458 + if((kind == HFSPLUS_NODE_HEAD) || (kind == HFSPLUS_NODE_MAP)) {
461 + } else if(kind == HFSPLUS_NODE_LEAF) {
464 + } else if(kind == HFSPLUS_NODE_NDX) {
465 + if((height <= 1) || (height > tree->depth))
468 + printk("HFS+-fs: unknown node type in B*Tree\n");
473 + printk("HFS+-fs: corrupt node height in B*Tree\n");
477 +/* Load a particular node out of a tree */
478 +hfsplus_bnode *hfsplus_get_bnode(hfsplus_btree *tree, hfsp_u32 num)
480 + hfsplus_bnode *node;
481 + hfsplus_btree_node_desc desc;
484 + if(num >= tree->node_count) {
485 + printk("HFS+-fs: request for non-existent node in B*Tree\n");
489 + node = kmalloc(sizeof(hfsplus_bnode), GFP_KERNEL);
494 + node->inode = NULL;
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");
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))
515 +/* Dispose of resources used by a node */
516 +void hfsplus_put_bnode(hfsplus_bnode *node)
520 + hfsplus_put_page(node);
523 + node->inode = NULL;
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
533 + * linux/fs/hfsplus/brec.c
535 + * Copyright (C) 2001
536 + * Brad Boyer (flar@allandria.com)
538 + * Handle individual btree records
541 +#include <linux/hfsplus_fs.h>
542 +#include <linux/hfsplus_raw.h>
544 +/* Get the offset of the given record in the given node */
545 +hfsp_u16 hfsplus_brec_off(hfsplus_bnode *node, hfsp_u16 rec)
550 + dataoff = node->tree->node_size - (rec + 1) * 2;
551 + if(hfsplus_bnode_copybytes(node, retval, dataoff, 2) != 2)
553 + return hfsp_get_hs(retval);
556 +/* Get the length of the given record in the given node */
557 +hfsp_u16 hfsplus_brec_len(hfsplus_bnode *node, hfsp_u16 rec)
559 + unsigned char retval[4];
562 + dataoff = node->tree->node_size - (rec + 2) * 2;
563 + if(hfsplus_bnode_copybytes(node, retval, dataoff, 4) != 4)
565 + return hfsp_get_hs(retval) - hfsp_get_hs(retval + 2);
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)
571 + unsigned char retval[4];
574 + dataoff = node->tree->node_size - (rec + 2) * 2;
575 + if(hfsplus_bnode_copybytes(node, retval, dataoff, 4) != 4) {
578 + *off = hfsp_get_hs(retval + 2);
579 + return hfsp_get_hs(retval) - *off;
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,
586 + hfsp_u16 recoff, reclen, cplen;
588 + reclen = hfsplus_brec_lenoff(node, rec, &recoff);
591 + cplen = (reclen>len) ? len : reclen;
592 + if(hfsplus_bnode_copybytes(node, buf, recoff, cplen) != cplen)
597 +/* Get the length of the key from a keyed record */
598 +hfsp_u16 hfsplus_brec_keylen(hfsplus_bnode *node, hfsp_u16 rec)
600 + hfsp_u16 klsz, retval, recoff;
601 + unsigned char buf[2];
603 + if((node->kind != HFSPLUS_NODE_NDX)&&(node->kind != HFSPLUS_NODE_LEAF))
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;
611 + recoff = hfsplus_brec_off(node, rec);
614 + if(hfsplus_bnode_copybytes(node, buf, recoff, klsz) != klsz)
619 + retval = hfsp_get_hs(buf);
621 + return (retval + klsz + 1) & 0xFFFE;
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,
628 + hfsp_u16 recoff, reclen, keylen, tocopy;
630 + reclen = hfsplus_brec_lenoff(node, rec, &recoff);
631 + keylen = hfsplus_brec_keylen(node, rec);
632 + if(!reclen || !keylen)
634 + if(keylen > reclen) {
635 + printk("HFS+-fs: corrupt key length in B*Tree\n");
638 + tocopy = (len > keylen) ? keylen : len;
639 + if(hfsplus_bnode_copybytes(node, buf, recoff, tocopy) != tocopy)
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
648 + * linux/fs/hfsplus/btiter.c
650 + * Copyright (C) 2001
651 + * Brad Boyer (flar@allandria.com)
653 + * Iterators for btrees
656 +#include <linux/hfsplus_fs.h>
658 +void hfsplus_btiter_setup(hfsplus_btiter *iter, hfsplus_btree *tree)
665 +int hfsplus_btiter_move(hfsplus_btiter *iter, int cnt)
667 + hfsplus_bnode *node;
670 + if(!iter || !iter->tree)
672 + if((cnt < -0xFFFF) || (cnt > 0xFFFF))
678 + if(!(node = hfsplus_get_bnode(iter->tree, iter->node)))
681 + if(node->kind != HFSPLUS_NODE_LEAF) {
682 + printk("HFS+-fs: found entry of bad type\n");
685 + if(iter->rec >= node->num_recs)
688 + if((iter->rec + cnt >= 0) && (iter->rec + cnt < node->num_recs)) {
694 + iter->node = node->prev;
699 + hfsplus_put_bnode(node);
700 + if(!(node = hfsplus_get_bnode(iter->tree, iter->node)))
702 + cnt += iter->rec + 1;
703 + iter->rec = node->num_recs - 1;
706 + iter->node = node->next;
711 + cnt -= node->num_recs - iter->rec;
713 + hfsplus_put_bnode(node);
716 + hfsplus_put_bnode(node);
720 +int hfsplus_btiter_get(hfsplus_btiter *iter, hfsplus_btree_key *key,
721 + void *entry, int *entry_len)
723 + hfsplus_bnode *node;
725 + hfsp_u16 rec, off, keylen, datalen;
727 + if(!iter || !iter->tree || !key || !entry || !entry_len)
730 + if((node = hfsplus_get_bnode(iter->tree, iter->node)) == NULL)
732 + if(node->kind != HFSPLUS_NODE_LEAF) {
733 + printk("HFS+-fs: found entry of bad type\n");
738 + if(!(keylen = hfsplus_brec_keylen(node, rec))) {
739 + printk("HFS+-fs: unable to read key from B*Tree record\n");
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");
747 + if(!hfsplus_bnode_copybytes(node, key, off, keylen)) {
748 + printk("HFS+-fs: unable to copy key from B*Tree\n");
751 + if(!hfsplus_bnode_copybytes(node, entry, off + keylen, datalen)) {
752 + printk("HFS+-fs: unable to read record in B*Tree\n");
755 + *entry_len = datalen;
758 + hfsplus_put_bnode(node);
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
767 + * linux/fs/hfsplus/btree.c
769 + * Copyright (C) 2001
770 + * Brad Boyer (flar@allandria.com)
772 + * Handle opening/closing btree
775 +#include <linux/slab.h>
776 +#include <linux/pagemap.h>
777 +#include <linux/hfsplus_fs.h>
778 +#include <linux/hfsplus_raw.h>
780 +/* Release resources used by a btree */
781 +void hfsplus_close_btree(struct hfsplus_btree *tree)
788 +/* Fill in extra data in tree structure from header node */
789 +static void hfsplus_fill_treeinfo(hfsplus_btree *tree, hfsplus_btree_head *hdr)
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);
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)
806 + hfsplus_btree *tree;
807 + hfsplus_bnode *hnode;
808 + hfsplus_btree_head head;
811 + tree = kmalloc(sizeof(struct hfsplus_btree), GFP_KERNEL);
815 + /* Set the correct compare function */
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;
823 + printk("HFS+-fs: unknown B*Tree requested\n");
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;
832 + tree->node_size = PAGE_SIZE;
834 + /* Load the header */
835 + hnode = hfsplus_get_bnode(tree, HFSPLUS_TREE_HEAD);
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");
845 + hfsplus_fill_treeinfo(tree, &head);
846 + hfsplus_put_bnode(hnode);
850 + hfsplus_put_bnode(hnode);
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
860 + * linux/fs/hfsplus/catalog.c
862 + * Copyright (C) 2001
863 + * Brad Boyer (flar@allandria.com)
865 + * Handling of catalog records
868 +#include <linux/hfsplus_fs.h>
869 +#include <linux/hfsplus_raw.h>
871 +int hfsplus_cmp_cat_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
873 + hfsp_cnid k1p, k2p;
875 + k1p = hfsp_get_hl(k1->u.cat.parent);
876 + k2p = hfsp_get_hl(k2->u.cat.parent);
878 + return (k1p < k2p) ? -1 : 1;
880 + return hfsplus_unistrcmp(&(k1->u.cat.name), &(k2->u.cat.name));
883 +int hfsplus_fill_cat_key(hfsplus_btree_key *key, hfsp_cnid parent, char *name,
888 + hfsp_put_hl(parent, key->u.cat.parent);
889 + if(!name || !namelen) {
890 + hfsp_put_hs(0, key->u.cat.name.length);
892 + err = hfsplus_asc2uni(&(key->u.cat.name), name, namelen);
896 + hfsp_put_hs(6 + 2 * hfsp_get_hs(key->u.cat.name.length), key->key_len);
900 +static void hfsplus_fill_cat_key_uni(hfsplus_btree_key *key, hfsp_cnid parent,
901 + hfsplus_unistr *name)
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,
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)
917 + hfsplus_btree_key key;
918 + hfsplus_cat_entry tmp;
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);
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");
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);
939 + printk("HFS+-fs: Unable to find record listed in thread\n");
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");
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");
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
959 + * linux/fs/hfsplus/dir.c
961 + * Copyright (C) 2001
962 + * Brad Boyer (flar@allandria.com)
964 + * Handling of directories
967 +#include <linux/errno.h>
968 +#include <linux/fs.h>
969 +#include <linux/hfsplus_fs.h>
970 +#include <linux/hfsplus_raw.h>
972 +/* Find the entry inside dir named dentry->d_name */
973 +static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry)
975 + struct inode *inode = NULL;
976 + hfsplus_btree_key key;
977 + hfsplus_cat_entry entry;
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 */
993 + return ERR_PTR(err);
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);
1005 + printk("HFS+-fs: Illegal catalog entry type in lookup\n");
1006 + return ERR_PTR(-EIO);
1008 + inode = iget(dir->i_sb, cnid);
1010 + return ERR_PTR(-EACCES);
1012 + d_add(dentry, inode);
1016 +static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
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;
1026 + if(filp->f_pos >= inode->i_size)
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) {
1034 + if(filp->f_pos > 1)
1035 + if((err = hfsplus_btiter_move(&iter, filp->f_pos - 1)))
1039 + if(!filp->f_pos) {
1040 + /* This is completely artificial... */
1041 + if(filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))
1046 + sz = sizeof(entry);
1047 + if((err = hfsplus_btiter_get(&iter, &key, &entry, &sz)))
1049 + if(hfsp_get_hl(key.u.cat.parent) != inode->i_ino) {
1050 + printk("HFS+-fs: walked past end of dir\n");
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");
1061 + if(sz < HFSPLUS_MIN_THREAD_SZ) {
1062 + printk("HFS+-fs: truncated catalog thread\n");
1065 + if(filldir(dirent, "..", 2, 1,
1066 + hfsp_get_hl(entry.u.thread.parentID),
1070 + len = HFSPLUS_MAX_STRLEN;
1071 + err = hfsplus_uni2asc(&(key.u.cat.name), strbuf, &len);
1074 + if(type == HFSPLUS_FOLDER) {
1075 + if(sz < 2 + sizeof(hfsplus_cat_folder)) {
1076 + printk("HFS+-fs: small dir entry\n");
1079 + if(filldir(dirent, strbuf, len, filp->f_pos,
1080 + hfsp_get_hl(entry.u.folder.id),
1083 + } else if(type == HFSPLUS_FILE) {
1084 + if(sz < 2 + sizeof(hfsplus_cat_file)) {
1085 + printk("HFS+-fs: small file entry\n");
1088 + if(filldir(dirent, strbuf, len, filp->f_pos,
1089 + hfsp_get_hl(entry.u.file.id),
1093 + printk("HFS+-fs: bad catalog entry type\n");
1096 + } /* if(filp->f_pos == 1) */
1098 + if(filp->f_pos >= inode->i_size)
1100 + if((err = hfsplus_btiter_move(&iter, 1)))
1102 + } /* while(!done) */
1106 +struct inode_operations hfsplus_dir_inode_operations = {
1107 + lookup: hfsplus_lookup,
1110 +struct file_operations hfsplus_dir_operations = {
1111 + read: generic_read_dir,
1112 + readdir: hfsplus_readdir,
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
1119 + * linux/fs/hfsplus/extents.c
1121 + * Copyright (C) 2001
1122 + * Brad Boyer (flar@allandria.com)
1124 + * Handling of Extents both in catalog and extents overflow trees
1127 +#include <linux/errno.h>
1128 +#include <linux/fs.h>
1129 +#include <linux/hfsplus_fs.h>
1130 +#include <linux/hfsplus_raw.h>
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)
1135 + hfsp_cnid k1id, k2id;
1136 + hfsp_u32 k1s, k2s;
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;
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;
1146 + k1s = hfsp_get_hl(k1->u.ext.start_block);
1147 + k2s = hfsp_get_hl(k2->u.ext.start_block);
1150 + return (k1s < k2s) ? -1 : 1;
1153 +void hfsplus_fill_ext_key(hfsplus_btree_key *key, hfsp_u32 cnid,
1154 + hfsp_u32 block, hfsp_u8 type)
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;
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)
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;
1173 + int i, sz, localerr, search_tree = 1, err = -EIO;
1174 + hfsp_u32 curr, tmp, ablock, dblock, dbpab, dbo;
1177 + if(!inode || !bh_result)
1180 + ino = inode->i_ino;
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;
1189 + /* Some files have extents in volume header */
1190 + if(ino <= HFSPLUS_ATTR_CNID) {
1192 + case HFSPLUS_EXT_CNID:
1193 + extents = HFSPLUS_SB(s).s_vhdr->ext_file.extents;
1196 + case HFSPLUS_CAT_CNID:
1197 + extents = HFSPLUS_SB(s).s_vhdr->cat_file.extents;
1199 + case HFSPLUS_ALLOC_CNID:
1200 + extents = HFSPLUS_SB(s).s_vhdr->alloc_file.extents;
1202 + case HFSPLUS_START_CNID:
1203 + extents = HFSPLUS_SB(s).s_vhdr->start_file.extents;
1205 + case HFSPLUS_ATTR_CNID:
1206 + extents = HFSPLUS_SB(s).s_vhdr->attr_file.extents;
1209 + /* Nothing else in this block is valid */
1214 + if((localerr = hfsplus_find_cat(s, ino, &cat_entry)) != 0) {
1218 + if(hfsp_get_hs(cat_entry.type) != HFSPLUS_FILE)
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;
1229 + /* Look in extent record for block */
1232 + for(i = 0; i < 8; i++) {
1233 + tmp = hfsp_get_hl(extents[i].block_count);
1234 + if(tmp && (ablock < curr + tmp)) {
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);
1247 + /* Look for extents in tree */
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,
1256 + if(localerr == -ENOENT)
1258 + printk("HFS+-fs: Unknown problem searching extents B*Tree\n");
1262 + if((hfsp_get_hl(key.u.ext.cnid) != ino) ||
1263 + (key.u.ext.fork_type != forktype)) {
1267 + curr = hfsp_get_hl(key.u.ext.start_block);
1268 + extents = ext_entry;
1269 + goto search_extent;
1275 + /* FIXME: Should allocate blocks here... */
1276 + printk("HFS+-fs: no file writes, but block allocation attempted\n");
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
1285 + * linux/fs/hfsplus/inode.c
1287 + * Copyright (C) 2001
1288 + * Brad Boyer (flar@allandria.com)
1290 + * Inode handling routines
1293 +#include <linux/fs.h>
1294 +#include <linux/hfsplus_fs.h>
1295 +#include <linux/hfsplus_raw.h>
1297 +static int hfsplus_readpage(struct file *file, struct page *page)
1299 + return block_read_full_page(page, hfsplus_get_block);
1302 +static int hfsplus_bmap(struct address_space *mapping, long block)
1304 + return generic_block_bmap(mapping, block, hfsplus_get_block);
1307 +struct address_space_operations hfsplus_aops = {
1308 + readpage: hfsplus_readpage,
1309 + bmap: hfsplus_bmap,
1312 +static void hfsplus_fill_perms(struct inode *inode, hfsplus_perm *perms)
1314 + struct super_block *s = inode->i_sb;
1316 + inode->i_mode = hfsp_get_hl(perms->mode);
1317 + if(inode->i_mode) {
1318 + inode->i_mode &= ~(S_IFMT);
1320 + inode->i_mode = S_IRWXUGO & ~(HFSPLUS_SB(s).umask);
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);
1331 +extern struct inode_operations hfsplus_dir_inode_operations;
1332 +extern struct file_operations hfsplus_dir_operations;
1334 +struct inode_operations hfsplus_file_inode_operations = {
1336 +struct file_operations hfsplus_file_operations = {
1337 + read: generic_file_read,
1338 + mmap: generic_file_mmap,
1341 +static void hfsplus_count_subdirs(struct inode *inode)
1343 + hfsplus_btree_key key;
1344 + hfsplus_cat_entry entry;
1345 + hfsplus_btiter iter;
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))
1353 + sz = sizeof(hfsplus_cat_entry);
1354 + if(hfsplus_btiter_get(&iter, &key, &entry, &sz) || (sz < 2))
1357 + if(hfsp_get_hl(key.u.cat.parent) != inode->i_ino)
1359 + if(hfsp_get_hs(entry.type) == HFSPLUS_FOLDER)
1360 + HFSPLUS_I(inode).ndirs++;
1362 + if(hfsplus_btiter_move(&iter, 1))
1367 +int hfsplus_cat_fill_inode(struct inode *inode, hfsplus_cat_entry *entry)
1369 + hfsplus_cat_folder *folder;
1370 + hfsplus_cat_file *file;
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;
1404 + printk("HFS+-fs: bad catalog entry used to create inode\n");
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
1415 + * linux/fs/hfsplus/options.c
1417 + * Copyright (C) 2001
1418 + * Brad Boyer (flar@allandria.com)
1423 +#include <linux/string.h>
1424 +#include <linux/kernel.h>
1425 +#include <linux/sched.h>
1426 +#include <linux/hfsplus_fs.h>
1428 +/* Initialize an options object to reasonable defaults */
1429 +void fill_defaults(struct hfsplus_sb_info *opts)
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;
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)
1448 + if(!curopts || !opts)
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;
1461 +/* My own little ultra-paranoid version of strtok (yes, there is strtok...) */
1462 +static char *my_strtok(char *input, char **next, char delim)
1466 + if(!input || !*input || !next)
1470 + d = strchr(input, delim);
1478 +/* convert a "four byte character" to a 32 bit int with error checks */
1479 +static int fill_fourchar(hfsp_u32 *result, char *input)
1484 + if(!result || !input || !*input || (strlen(input) != 4))
1487 + for(out = 0, i = 0; i < 4; i++) {
1489 + out |= ((int)(input[i])) & 0xFF;
1495 +/* convert a string to int with error checks */
1496 +static int fill_int(int *result, char *input, int base)
1498 + char *tmp = input;
1501 + if(!result || !input || !*input)
1504 + intval = simple_strtoul(tmp, &tmp, base);
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)
1516 + char *next, *curropt, *value;
1521 + for(curropt = my_strtok(input, &next, ','); curropt != NULL;
1522 + curropt = my_strtok(next, &next, ',')) {
1523 + if((value = strchr(curropt, '=')) != NULL)
1526 + if(!strcmp(curropt, "creator")) {
1527 + if(!fill_fourchar(&(results->creator), value)) {
1528 + printk("HFS+-fs: creator requires a value\n");
1531 + } else if(!strcmp(curropt, "type")) {
1532 + if(!fill_fourchar(&(results->type), value)) {
1533 + printk("HFS+-fs: type requires a value\n");
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");
1543 + } else if(!strcmp(curropt, "uid")) {
1544 + if(!fill_int(&(results->uid), value, 0)) {
1545 + printk("HFS+-fs: uid requires an argument\n");
1548 + } else if(!strcmp(curropt, "gid")) {
1549 + if(!fill_int(&(results->gid), value, 0)) {
1550 + printk("HFS+-fs: gid requires an argument\n");
1554 + printk("HFS+-fs: unknown option %s\n", curropt);
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
1566 + * linux/fs/hfsplus/super.c
1568 + * Copyright (C) 2001
1569 + * Brad Boyer (flar@allandria.com)
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>
1579 +static void hfsplus_read_inode(struct inode *inode)
1581 + hfsplus_cat_entry entry;
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));
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));
1597 + if(hfsplus_find_cat(inode->i_sb, inode->i_ino, &entry))
1601 + if(hfsplus_cat_fill_inode(inode, &entry))
1606 + make_bad_inode(inode);
1609 +static void hfsplus_put_super(struct super_block *sb)
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;
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;
1622 +static int hfsplus_statfs(struct super_block *sb, struct statfs *buf)
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;
1636 +static struct super_operations hfsplus_sops = {
1637 + read_inode: hfsplus_read_inode,
1638 + put_super: hfsplus_put_super,
1639 + statfs: hfsplus_statfs,
1642 +struct super_block *hfsplus_read_super(struct super_block *sb, void *data,
1645 + struct hfsplus_vh *vhdr;
1646 + struct hfsplus_sb_info opts;
1648 + fill_defaults(&opts);
1649 + if(!parse_options(data, &opts)) {
1651 + printk("HFS+-fs: unable to parse mount options\n");
1654 + fill_current(&opts, &(HFSPLUS_SB(sb)));
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;
1661 + /* Grab the volume header */
1662 + if(!hfsplus_read_wrapper(sb)) {
1664 + printk("HFS+-fs: unable to find HFS+ superblock\n");
1667 + vhdr = HFSPLUS_SB(sb).s_vhdr;
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) {
1673 + printk("HFS+-fs: wrong filesystem version\n");
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);
1681 + /* Set up operations so we can load metadata */
1682 + sb->s_op = &hfsplus_sops;
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) {
1688 + printk("HFS+-fs: failed to load extents file\n");
1691 + HFSPLUS_SB(sb).cat_tree = hfsplus_open_btree(sb, HFSPLUS_CAT_CNID);
1692 + if(!HFSPLUS_SB(sb).cat_tree) {
1694 + printk("HFS+-fs: failed to load catalog file\n");
1698 + /* Load the root directory */
1699 + sb->s_root = d_alloc_root(iget(sb, HFSPLUS_ROOT_CNID));
1702 + printk("HFS+-fs: failed to load root directory\n");
1709 + hfsplus_put_super(sb);
1713 +static DECLARE_FSTYPE_DEV(hfsplus_fs_type, "hfsplus", hfsplus_read_super);
1715 +static int __init init_hfsplus_fs(void)
1717 + return register_filesystem(&hfsplus_fs_type);
1720 +static void __exit exit_hfsplus_fs(void)
1722 + unregister_filesystem(&hfsplus_fs_type);
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
1734 + * linux/fs/hfsplus/tables.c
1736 + * Various data tables
1739 +#include <linux/hfsplus_fs.h>
1742 + * Unicode case folding table taken from Apple Technote #1150
1743 + * (HFS Plus Volume Format)
1746 +hfsp_u16 case_fold_table[] = {
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.
1755 + // High-byte indices ( == 0 iff no case mapping and no ignorables )
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,
1791 + // Table 1 (for high byte 0x00)
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,
1826 + // Table 2 (for high byte 0x01)
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,
1861 + // Table 3 (for high byte 0x03)
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,
1896 + // Table 4 (for high byte 0x04)
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,
1931 + // Table 5 (for high byte 0x05)
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,
1966 + // Table 6 (for high byte 0x10)
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,
2001 + // Table 7 (for high byte 0x20)
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,
2036 + // Table 8 (for high byte 0x21)
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,
2071 + // Table 9 (for high byte 0xFE)
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,
2106 + // Table 10 (for high byte 0xFF)
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,
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
2146 + * linux/fs/hfsplus/unicode.c
2148 + * Copyright (C) 2001
2149 + * Brad Boyer (flar@allandria.com)
2151 + * Handler routines for unicode strings
2154 +#include <linux/types.h>
2155 +#include <linux/nls.h>
2156 +#include <linux/hfsplus_fs.h>
2157 +#include <linux/hfsplus_raw.h>
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)
2165 + tmp = case_fold_table[(c>>8)];
2167 + tmp = case_fold_table[tmp + (c & 0xFF)];
2173 +/* Compare unicode strings, return values like normal strcmp */
2174 +int hfsplus_unistrcmp(hfsplus_unistr *s1, hfsplus_unistr *s2)
2176 + hfsp_u16 len1, len2, c1, c2;
2177 + hfsplus_unichr *p1, *p2;
2179 + len1 = hfsp_get_hs(s1->length);
2180 + len2 = hfsp_get_hs(s2->length);
2187 + while(len1 && !c1) {
2188 + c1 = case_fold(hfsp_get_hs(p1++));
2191 + while(len2 && !c2) {
2192 + c2 = case_fold(hfsp_get_hs(p2++));
2197 + return (c1 < c2) ? -1 : 1;
2203 +int hfsplus_uni2asc(hfsplus_unistr *ustr, char *astr, int *len)
2205 + const hfsp_u16 *ip;
2207 + hfsp_u16 ustrlen, cc;
2211 + ip = (hfsp_u16 *)(ustr->unicode);
2212 + ustrlen = hfsp_get_hs(ustr->length);
2214 + while((ustrlen > 0) && (tmp > 0)) {
2215 + cc = hfsp_get_hs(ip);
2217 + size = utf8_wctomb(op, cc, tmp);
2225 + *op++ = (hfsp_u8) cc;
2231 + *len = (char *)op - astr;
2233 + return -ENAMETOOLONG;
2237 +int hfsplus_asc2uni(hfsplus_unistr *ustr, char *astr, int len)
2241 + hfsp_u16 outlen = 0;
2243 + while((outlen <= HFSPLUS_MAX_STRLEN) && (len > 0)) {
2244 + if(*astr & 0x80) {
2245 + if((tmp = utf8_mbtowc(&c, astr, len)) < 0) {
2257 + hfsp_put_hs(c, ustr->unicode + outlen);
2260 + hfsp_put_hs(outlen, ustr->length);
2262 + return -ENAMETOOLONG;
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
2272 + * linux/fs/hfsplus/wrapper.c
2274 + * Copyright (C) 2001
2275 + * Brad Boyer (flar@allandria.com)
2277 + * Handling of HFS wrappers around HFS+ volumes
2280 +#include <linux/fs.h>
2281 +#include <linux/hfsplus_fs.h>
2282 +#include <linux/hfsplus_raw.h>
2283 +#include <linux/blkdev.h>
2285 +struct hfsplus_wd {
2286 + hfsp_u32 ablk_size;
2287 + hfsp_u16 ablk_start;
2288 + hfsp_u16 embed_start;
2289 + hfsp_u16 embed_count;
2292 +static int hfsplus_read_mdb(unsigned char *bufptr, struct hfsplus_wd *wd)
2297 + if(hfsp_get_hs(bufptr + HFSP_WRAPOFF_EMBEDSIG) != HFSPLUS_VOLHEAD_SIG)
2300 + attrib = hfsp_get_hs(bufptr + HFSP_WRAPOFF_ATTRIB);
2301 + if(!(attrib & HFSP_WRAP_ATTRIB_SLOCK) ||
2302 + !(attrib & HFSP_WRAP_ATTRIB_SPARED))
2305 + wd->ablk_size = hfsp_get_hl(bufptr + HFSP_WRAPOFF_ABLKSIZE);
2306 + if(wd->ablk_size < HFSPLUS_SECTOR_SIZE)
2308 + if(wd->ablk_size % HFSPLUS_SECTOR_SIZE)
2310 + wd->ablk_start = hfsp_get_hs(bufptr + HFSP_WRAPOFF_ABLKSTART);
2312 + extent = hfsp_get_hl(bufptr + HFSP_WRAPOFF_EMBEDEXT);
2313 + wd->embed_start = (extent >> 16) & 0xFFFF;
2314 + wd->embed_count = extent & 0xFFFF;
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)
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;
2333 + blocksize = get_hardsect_size(dev);
2334 + if((blocksize == 0) || (blocksize < HFSPLUS_SECTOR_SIZE)) {
2335 + blocksize = HFSPLUS_SECTOR_SIZE;
2337 + set_blocksize(dev, blocksize);
2339 + block = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) / blocksize;
2340 + offset = (HFSPLUS_VOLHEAD_SECTOR * HFSPLUS_SECTOR_SIZE) % blocksize;
2342 + if(!(bh = bread(dev, block, blocksize))) {
2343 + printk("HFS+-fs: unable to read VHDR or MDB\n");
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))
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;
2357 + if(!(bh = bread(dev, block, blocksize))) {
2358 + printk("HFS+-fs: unable to read VHDR\n");
2362 + wd.ablk_start = 0;
2363 + wd.ablk_size = blocksize;
2364 + wd.embed_start = 0;
2366 + vhdr = (struct hfsplus_vh *)(((char *)bh->b_data) + offset);
2367 + if(hfsp_get_hs(vhdr->signature) != HFSPLUS_VOLHEAD_SIG)
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");
2374 + if((blocksize > dblksz) && (dblksz % blocksize)) {
2375 + printk("HFS+-fs: volume blocks not aligned on device\n");
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));
2384 + HFSPLUS_SB(sb).s_vhbh = bh;
2385 + HFSPLUS_SB(sb).s_vhdr = vhdr;
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
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>
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;
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>
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
2432 + * linux/include/linux/hfsplus_fs.h
2434 + * Copyright (C) 1999
2435 + * Brad Boyer (flar@pants.nu)
2439 +#ifndef _LINUX_HFSPLUS_FS_H
2440 +#define _LINUX_HFSPLUS_FS_H
2442 +#include <linux/fs.h>
2444 +#include <asm/unaligned.h>
2446 +#include <linux/hfsplus_raw.h>
2447 +#include <linux/hfsplus_fs_sb.h>
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;
2455 +/* Runtime config options */
2456 +#define HFSPLUS_CASE_ASIS 0
2457 +#define HFSPLUS_CASE_LOWER 1
2459 +#define HFSPLUS_FORK_RAW 0
2460 +#define HFSPLUS_FORK_CAP 1
2461 +#define HFSPLUS_FORK_DOUBLE 2
2462 +#define HFSPLUS_FORK_NETATALK 3
2464 +#define HFSPLUS_NAMES_TRIVIAL 0
2465 +#define HFSPLUS_NAMES_CAP 1
2466 +#define HFSPLUS_NAMES_NETATALK 2
2467 +#define HFSPLUS_NAMES_7BIT 3
2469 +#define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */
2471 +#define HFSPLUS_TYPE_DATA 0x00
2472 +#define HFSPLUS_TYPE_RSRC 0xFF
2474 +struct hfsplus_btree;
2477 +/* An HFS+ BTree node in memory */
2479 + struct hfsplus_btree *tree;
2480 + struct page *page;
2481 + struct inode *inode;
2487 + hfsp_u16 num_recs;
2492 +typedef int (*btree_keycmp)(hfsplus_btree_key *, hfsplus_btree_key *);
2494 +/* An HFS+ BTree held in memory */
2495 +typedef struct hfsplus_btree {
2496 + struct super_block *sb;
2497 + btree_keycmp keycmp;
2501 + hfsp_u32 node_count;
2502 + hfsp_u32 free_nodes;
2503 + hfsp_u32 attributes;
2505 + hfsp_u16 node_size;
2506 + hfsp_u16 max_key_len;
2510 +/* An iterator for walking an HFS+ BTree */
2512 + hfsplus_btree *tree;
2518 + * Functions in any *.c used in other files
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 *);
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);
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);
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 *);
2545 +hfsplus_btree *hfsplus_open_btree(struct super_block *, hfsp_cnid);
2546 +void hfsplus_close_btree(struct hfsplus_btree *);
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 *);
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);
2559 +int hfsplus_cat_fill_inode(struct inode *, hfsplus_cat_entry *);
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 *);
2567 +extern hfsp_u16 case_fold_table[];
2570 +int hfsplus_unistrcmp(hfsplus_unistr *, hfsplus_unistr *);
2571 +int hfsplus_uni2asc(hfsplus_unistr *, char *, int *);
2572 +int hfsplus_asc2uni(hfsplus_unistr *, char *, int);
2575 +int hfsplus_read_wrapper(struct super_block *);
2577 +/* access macros */
2578 +#define HFSPLUS_SB(super) ((super)->u.hfsplus_sb)
2579 +#define HFSPLUS_I(inode) ((inode)->u.hfsplus_i)
2581 +#define HFSPLUS_IS_DATA(inode) (1)
2582 +#define HFSPLUS_IS_RSRC(inode) (0)
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)))
2598 +#define hfsp_mt2ut(t) (hfsp_get_hl(t) - 2082844800U)
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
2606 + * linux/include/linux/hfsplus_fs_i.h
2608 + * Copyright (C) 1999
2609 + * Brad Boyer (flar@pants.nu)
2613 +#ifndef _LINUX_HFSPLUS_FS_I_H
2614 +#define _LINUX_HFSPLUS_FS_I_H
2616 +#include <linux/types.h>
2618 +struct hfsplus_fork;
2620 +struct hfsplus_inode_info {
2621 + /* Number of subdirectories in a directory */
2623 + /* Device number in hfsplus_permissions in catalog */
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
2633 + * linux/include/linux/hfsplus_fs_sb.h
2635 + * Copyright (C) 1999
2636 + * Brad Boyer (flar@pants.nu)
2640 +#ifndef _LINUX_HFSPLUS_FS_SB_H
2641 +#define _LINUX_HFSPLUS_FS_SB_H
2643 +#include <asm/types.h>
2646 + * HFS+ superblock info (built from Volume Header on disk)
2650 +struct hfsplus_btree;
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;
2658 + /* Runtime variables */
2659 + __u32 dbpab; /* Device blocks per allocation block */
2660 + __u32 dboff; /* Offset to actual HFS+ blocks */
2662 + /* Stuff in host order from Vol Header */
2663 + __u32 free_blocks;
2666 + __u32 folder_count;
2668 + /* Config options */
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
2687 + * linux/include/linux/hfsplus_raw.h
2689 + * Copyright (C) 1999
2690 + * Brad Boyer (flar@pants.nu)
2692 + * Format of structures on disk
2693 + * Information taken from Apple Technote #1150 (HFS Plus Volume Format)
2697 +#ifndef _LINUX_HFSPLUS_RAW_H
2698 +#define _LINUX_HFSPLUS_RAW_H
2700 +#include <asm/types.h>
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
2709 +#define HFSP_WRAP_MAGIC 0x4244
2710 +#define HFSP_WRAP_ATTRIB_SLOCK 0x8000
2711 +#define HFSP_WRAP_ATTRIB_SPARED 0x0200
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
2720 +/* Structures used on disk */
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];
2727 +typedef hfsp_lword hfsplus_cnid;
2728 +typedef hfsp_word hfsplus_unichr;
2730 +/* A "string" as used in filenames, etc. */
2733 + hfsplus_unichr unicode[255];
2736 +#define HFSPLUS_MAX_STRLEN 255
2738 +/* POSIX permissions */
2746 +/* A single contiguous area of a file */
2748 + hfsp_lword start_block;
2749 + hfsp_lword block_count;
2751 +typedef hfsplus_extent hfsplus_extent_rec[8];
2753 +/* Information for a "Fork" in a file */
2755 + hfsp_llword total_size;
2756 + hfsp_lword clump_size;
2757 + hfsp_lword total_blocks;
2758 + hfsplus_extent_rec extents;
2759 +} hfsplus_fork_raw;
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;
2769 + hfsp_lword create_date;
2770 + hfsp_lword modify_date;
2771 + hfsp_lword backup_date;
2772 + hfsp_lword checked_date;
2774 + hfsp_lword file_count;
2775 + hfsp_lword folder_count;
2777 + hfsp_lword blocksize;
2778 + hfsp_lword total_blocks;
2779 + hfsp_lword free_blocks;
2781 + hfsp_lword next_alloc;
2782 + hfsp_lword rsrc_clump_sz;
2783 + hfsp_lword data_clump_sz;
2784 + hfsplus_cnid next_cnid;
2786 + hfsp_lword write_count;
2787 + hfsp_llword encodings_bmp;
2789 + hfsp_byte finder_info[32];
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;
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)
2805 +/* HFS+ BTree node descriptor */
2811 + hfsp_word num_rec;
2812 + hfsp_word reserved;
2813 +} hfsplus_btree_node_desc;
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
2821 +/* HFS+ BTree header */
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;
2840 +/* BTree attributes */
2841 +#define HFSPLUS_TREE_BIGKEYS 2
2842 +#define HFSPLUS_TREE_VAR_NDXKEY_SIZE 4
2844 +/* HFS+ BTree misc info */
2845 +#define HFSPLUS_TREE_HEAD 0
2846 +#define HFSPLUS_NODE_MXSZ 32768
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 */
2859 +/* HFS+ catalog entry key */
2861 + hfsplus_cnid parent;
2862 + hfsplus_unistr name;
2866 +/* Structs from hfs.h */
2880 +/* HFS directory info (stolen from hfs.h */
2883 + hfsp_word frFlags;
2884 + hfsp_point frLocation;
2889 + hfsp_point frScroll;
2890 + hfsp_lword frOpenChain;
2891 + hfsp_word frUnused;
2892 + hfsp_word frComment;
2893 + hfsp_lword frPutAway;
2896 +/* HFS+ folder data (part of an hfsplus_cat_entry) */
2899 + hfsp_lword valence;
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;
2908 + DXInfo finder_info;
2909 + hfsp_lword text_encoding;
2910 + hfsp_lword reserved;
2911 +} hfsplus_cat_folder;
2913 +/* HFS file info (stolen from hfs.h) */
2915 + hfsp_lword fdType;
2916 + hfsp_lword fdCreator;
2917 + hfsp_word fdFlags;
2918 + hfsp_point fdLocation;
2923 + hfsp_word fdIconID;
2924 + hfsp_byte fdUnused[8];
2925 + hfsp_word fdComment;
2926 + hfsp_lword fdPutAway;
2929 +/* HFS+ file data (part of a cat_entry) */
2932 + hfsp_lword reserved1;
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;
2941 + FXInfo finder_info;
2942 + hfsp_lword text_encoding;
2943 + hfsp_lword reserved2;
2945 + hfsplus_fork_raw data_fork;
2946 + hfsplus_fork_raw res_fork;
2947 +} hfsplus_cat_file;
2949 +/* File attribute bits */
2950 +#define kHFSFileLockedBit 0x0000
2951 +#define kHFSFileLockedMask 0x0001
2952 +#define kHFSThreadExistsBit 0x0001
2953 +#define kHFSThreadExistsMask 0x0002
2955 +/* HFS+ catalog thread (part of a cat_entry) */
2957 + hfsp_word reserved;
2958 + hfsplus_cnid parentID;
2959 + hfsplus_unistr nodeName;
2960 +} hfsplus_cat_thread;
2962 +#define HFSPLUS_MIN_THREAD_SZ 10
2964 +/* A data record in the catalog tree */
2968 + hfsplus_cat_folder folder;
2969 + hfsplus_cat_file file;
2970 + hfsplus_cat_thread thread;
2972 +} hfsplus_cat_entry;
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
2980 +/* HFS+ extents tree key */
2982 + hfsp_byte fork_type;
2984 + hfsplus_cnid cnid;
2985 + hfsp_lword start_block;
2988 +#define HFSPLUS_EXT_KEYLEN 10
2990 +/* HFS+ generic BTree key */
2992 + hfsp_word key_len;
2994 + hfsplus_cat_key cat;
2995 + hfsplus_ext_key ext;
2997 +} hfsplus_btree_key;