4 * Copyright (C) 1995-1997 Paul H. Hargrove
5 * This file may be distributed under the terms of the GNU Public License.
7 * "XXX" in a comment is a note to myself to consider changing something.
13 #include <linux/hfs_sysdep.h>
15 #define HFS_NEW(X) ((X) = hfs_malloc(sizeof(*(X))))
16 #define HFS_DELETE(X) do { hfs_free((X), sizeof(*(X))); (X) = NULL; } \
19 /* offsets to various blocks */
20 #define HFS_DD_BLK 0 /* Driver Descriptor block */
21 #define HFS_PMAP_BLK 1 /* First block of partition map */
22 #define HFS_MDB_BLK 2 /* Block (w/i partition) of MDB */
24 /* magic numbers for various disk blocks */
25 #define HFS_DRVR_DESC_MAGIC 0x4552 /* "ER": driver descriptor map */
26 #define HFS_OLD_PMAP_MAGIC 0x5453 /* "TS": old-type partition map */
27 #define HFS_NEW_PMAP_MAGIC 0x504D /* "PM": new-type partition map */
28 #define HFS_SUPER_MAGIC 0x4244 /* "BD": HFS MDB (super block) */
29 #define HFS_MFS_SUPER_MAGIC 0xD2D7 /* MFS MDB (super block) */
31 /* magic numbers for various internal structures */
32 #define HFS_FILE_MAGIC 0x4801
33 #define HFS_DIR_MAGIC 0x4802
34 #define HFS_MDB_MAGIC 0x4803
35 #define HFS_EXT_MAGIC 0x4804 /* XXX currently unused */
36 #define HFS_BREC_MAGIC 0x4811 /* XXX currently unused */
37 #define HFS_BTREE_MAGIC 0x4812
38 #define HFS_BNODE_MAGIC 0x4813
40 /* various FIXED size parameters */
41 #define HFS_SECTOR_SIZE 512 /* size of an HFS sector */
42 #define HFS_SECTOR_SIZE_BITS 9 /* log_2(HFS_SECTOR_SIZE) */
43 #define HFS_NAMELEN 31 /* maximum length of an HFS filename */
44 #define HFS_NAMEMAX (3*31) /* max size of ENCODED filename */
45 #define HFS_BM_MAXBLOCKS (16) /* max number of bitmap blocks */
46 #define HFS_BM_BPB (8*HFS_SECTOR_SIZE) /* number of bits per bitmap block */
47 #define HFS_MAX_VALENCE 32767U
48 #define HFS_FORK_MAX (0x7FFFFFFF)
50 /* Meanings of the drAtrb field of the MDB,
51 * Reference: _Inside Macintosh: Files_ p. 2-61
53 #define HFS_SB_ATTRIB_HLOCK 0x0080
54 #define HFS_SB_ATTRIB_CLEAN 0x0100
55 #define HFS_SB_ATTRIB_SPARED 0x0200
56 #define HFS_SB_ATTRIB_SLOCK 0x8000
59 #define HFS_USHRT_MAX 65535
61 /* Some special File ID numbers */
62 #define HFS_POR_CNID 1 /* Parent Of the Root */
63 #define HFS_ROOT_CNID 2 /* ROOT directory */
64 #define HFS_EXT_CNID 3 /* EXTents B-tree */
65 #define HFS_CAT_CNID 4 /* CATalog B-tree */
66 #define HFS_BAD_CNID 5 /* BAD blocks file */
67 #define HFS_ALLOC_CNID 6 /* ALLOCation file (HFS+) */
68 #define HFS_START_CNID 7 /* STARTup file (HFS+) */
69 #define HFS_ATTR_CNID 8 /* ATTRibutes file (HFS+) */
70 #define HFS_EXCH_CNID 15 /* ExchangeFiles temp id */
72 /* values for hfs_cat_rec.cdrType */
73 #define HFS_CDR_DIR 0x01 /* folder (directory) */
74 #define HFS_CDR_FIL 0x02 /* file */
75 #define HFS_CDR_THD 0x03 /* folder (directory) thread */
76 #define HFS_CDR_FTH 0x04 /* file thread */
78 /* legal values for hfs_ext_key.FkType and hfs_file.fork */
79 #define HFS_FK_DATA 0x00
80 #define HFS_FK_RSRC 0xFF
82 /* bits in hfs_fil_entry.Flags */
83 #define HFS_FIL_LOCK 0x01 /* locked */
84 #define HFS_FIL_THD 0x02 /* file thread */
85 #define HFS_FIL_DOPEN 0x04 /* data fork open */
86 #define HFS_FIL_ROPEN 0x08 /* resource fork open */
87 #define HFS_FIL_DIR 0x10 /* directory (always clear) */
88 #define HFS_FIL_RSRV1 0x20 /* reserved */
89 #define HFS_FIL_NOCOPY 0x40 /* copy-protected file */
90 #define HFS_FIL_USED 0x80 /* open */
92 /* bits in hfs_dir_entry.Flags. dirflags is 16 bits. */
93 #define HFS_DIR_LOCK 0x01 /* locked */
94 #define HFS_DIR_THD 0x02 /* directory thread */
95 #define HFS_DIR_INEXPFOLDER 0x04 /* in a shared area */
96 #define HFS_DIR_MOUNTED 0x08 /* mounted */
97 #define HFS_DIR_DIR 0x10 /* directory (always set) */
98 #define HFS_DIR_EXPFOLDER 0x20 /* share point */
99 #define HFS_DIR_RSRV1 0x40 /* reserved */
100 #define HFS_DIR_RSRV2 0x80 /* reserved */
102 /* Access types used when requesting access to a B-node */
103 #define HFS_LOCK_NONE 0x0000 /* Illegal */
104 #define HFS_LOCK_READ 0x0001 /* read-only access */
105 #define HFS_LOCK_RESRV 0x0002 /* might potentially modify */
106 #define HFS_LOCK_WRITE 0x0003 /* will modify now (exclusive access) */
107 #define HFS_LOCK_MASK 0x000f
109 /* Flags field of the hfs_path_elem */
110 #define HFS_BPATH_FIRST 0x0100
111 #define HFS_BPATH_OVERFLOW 0x0200
112 #define HFS_BPATH_UNDERFLOW 0x0400
113 #define HFS_BPATH_MASK 0x0f00
115 /* Flags for hfs_bfind() */
116 #define HFS_BFIND_EXACT 0x0010
117 #define HFS_BFIND_LOCK 0x0020
119 /* Modes for hfs_bfind() */
120 #define HFS_BFIND_WRITE (HFS_LOCK_RESRV|HFS_BFIND_EXACT|HFS_BFIND_LOCK)
121 #define HFS_BFIND_READ_EQ (HFS_LOCK_READ|HFS_BFIND_EXACT)
122 #define HFS_BFIND_READ_LE (HFS_LOCK_READ)
123 #define HFS_BFIND_INSERT (HFS_LOCK_RESRV|HFS_BPATH_FIRST|HFS_BPATH_OVERFLOW)
124 #define HFS_BFIND_DELETE \
125 (HFS_LOCK_RESRV|HFS_BFIND_EXACT|HFS_BPATH_FIRST|HFS_BPATH_UNDERFLOW)
127 /*======== HFS structures as they appear on the disk ========*/
129 /* Pascal-style string of up to 31 characters */
133 } __attribute__((packed
));
149 hfs_lword_t fdCreator
;
151 hfs_point_t fdLocation
;
153 } __attribute__((packed
)) hfs_finfo_t
;
157 hfs_byte_t fdUnused
[8];
158 hfs_word_t fdComment
;
159 hfs_lword_t fdPutAway
;
160 } __attribute__((packed
)) hfs_fxinfo_t
;
165 hfs_point_t frLocation
;
167 } __attribute__((packed
)) hfs_dinfo_t
;
170 hfs_point_t frScroll
;
171 hfs_lword_t frOpenChain
;
173 hfs_word_t frComment
;
174 hfs_lword_t frPutAway
;
175 } __attribute__((packed
)) hfs_dxinfo_t
;
177 union hfs_finder_info
{
188 /* A btree record key on disk */
190 hfs_byte_t KeyLen
; /* number of bytes in the key */
191 hfs_byte_t value
[1]; /* (KeyLen) bytes of key */
192 } __attribute__((packed
));
194 /* Cast to a pointer to a generic bkey */
195 #define HFS_BKEY(X) (((void)((X)->KeyLen)), ((struct hfs_bkey *)(X)))
197 /* The key used in the catalog b-tree: */
199 hfs_byte_t KeyLen
; /* number of bytes in the key */
200 hfs_byte_t Resrv1
; /* padding */
201 hfs_lword_t ParID
; /* CNID of the parent dir */
202 struct hfs_name CName
; /* The filename of the entry */
203 } __attribute__((packed
));
205 /* The key used in the extents b-tree: */
207 hfs_byte_t KeyLen
; /* number of bytes in the key */
208 hfs_byte_t FkType
; /* HFS_FK_{DATA,RSRC} */
209 hfs_lword_t FNum
; /* The File ID of the file */
210 hfs_word_t FABN
; /* allocation blocks number*/
211 } __attribute__((packed
));
213 /*======== Data structures kept in memory ========*/
218 * The fields from the MDB of an HFS filesystem
221 int magic
; /* A magic number */
222 unsigned char vname
[28]; /* The volume name */
223 hfs_sysmdb sys_mdb
; /* superblock */
224 hfs_buffer buf
; /* The hfs_buffer
228 hfs_buffer alt_buf
; /* The hfs_buffer holding
229 the alternate superblock */
230 hfs_buffer bitmap
[16]; /* The hfs_buffer holding the
232 struct hfs_btree
* ext_tree
; /* Information about
233 the extents b-tree */
234 struct hfs_btree
* cat_tree
; /* Information about
235 the catalog b-tree */
236 hfs_u32 file_count
; /* The number of
239 hfs_u32 dir_count
; /* The number of
242 hfs_u32 next_id
; /* The next available
244 hfs_u32 clumpablks
; /* The number of allocation
245 blocks to try to add when
247 hfs_u32 write_count
; /* The number of MDB
250 hfs_u32 fs_start
; /* The first 512-byte
253 hfs_u32 create_date
; /* In network byte-order */
254 hfs_u32 modify_date
; /* In network byte-order */
255 hfs_u32 backup_date
; /* In network byte-order */
256 hfs_u16 root_files
; /* The number of
261 hfs_u16 root_dirs
; /* The number of
264 hfs_u16 fs_ablocks
; /* The number of
267 hfs_u16 free_ablocks
; /* The number of unused
270 hfs_u32 alloc_blksz
; /* The number of
272 "allocation block" */
273 hfs_u16 attrib
; /* Attribute word */
274 hfs_wait_queue rename_wait
;
276 hfs_wait_queue bitmap_wait
;
278 struct list_head entry_dirty
;
284 * The offset to allocation block mapping for a given file is
285 * contained in a series of these structures. Each (struct
286 * hfs_extent) records up to three runs of contiguous allocation
287 * blocks. An allocation block is a contiguous group of physical
291 int magic
; /* A magic number */
292 unsigned short start
; /* Where in the file this record
293 begins (in allocation blocks) */
294 unsigned short end
; /* Where in the file this record
295 ends (in allocation blocks) */
296 unsigned short block
[3]; /* The allocation block on disk which
297 begins this extent */
298 unsigned short length
[3]; /* The number of allocation blocks
300 struct hfs_extent
*next
; /* Next extent record for this file */
301 struct hfs_extent
*prev
; /* Previous extent record for this file */
302 int count
; /* Number of times it is used */
308 * This structure holds information specific
309 * to a directory in an HFS filesystem.
312 int magic
; /* A magic number */
314 hfs_u16 dirs
; /* Number of directories in this one */
315 hfs_u16 files
; /* Number of files in this directory */
317 hfs_wait_queue read_wait
;
319 hfs_wait_queue write_wait
;
325 * This structure holds the information
326 * specific to a single fork of a file.
329 struct hfs_cat_entry
*entry
; /* The file this fork is part of */
330 struct hfs_extent first
; /* The first extent record for
332 struct hfs_extent
*cache
; /* The most-recently accessed
333 extent record for this fork */
334 hfs_u32 lsize
; /* The logical size in bytes */
335 hfs_u32 psize
; /* The phys size (512-byte blocks) */
336 hfs_u8 fork
; /* Which fork is this? */
342 * This structure holds information specific
343 * to a file in an HFS filesystem.
347 struct hfs_fork data_fork
;
348 struct hfs_fork rsrc_fork
;
356 * This structure holds information about a
357 * file or directory in an HFS filesystem.
359 * 'wait' must remain 1st and 'hash' 2nd since we do some pointer arithmetic.
361 struct hfs_cat_entry
{
363 struct list_head hash
;
364 struct list_head list
;
366 hfs_sysentry sys_entry
;
367 struct hfs_cat_key key
;
368 union hfs_finder_info info
;
369 hfs_u32 cnid
; /* In network byte-order */
370 hfs_u32 create_date
; /* In network byte-order */
371 hfs_u32 modify_date
; /* In network byte-order */
372 hfs_u32 backup_date
; /* In network byte-order */
373 unsigned short count
;
378 struct hfs_file file
;
382 /* hfs entry state bits */
384 #define HFS_KEYDIRTY 2
386 #define HFS_DELETED 8
389 * struct hfs_bnode_ref
391 * A pointer to a (struct hfs_bnode) and the type of lock held on it.
393 struct hfs_bnode_ref
{
394 struct hfs_bnode
*bn
;
401 * An element of the path from the root of a B-tree to a leaf.
402 * Includes the reference to a (struct hfs_bnode), the index of
403 * the appropriate record in that node, and some flags.
406 struct hfs_bnode_ref bnr
;
414 * The structure returned by hfs_bfind() to describe the requested record.
418 struct hfs_btree
*tree
;
419 struct hfs_belem
*top
;
420 struct hfs_belem
*bottom
;
421 struct hfs_belem elem
[9];
422 struct hfs_bkey
*key
;
423 void *data
; /* The actual data */
426 /*================ Function prototypes ================*/
429 extern int hfs_bdelete(struct hfs_btree
*, const struct hfs_bkey
*);
432 extern void hfs_brec_relse(struct hfs_brec
*, struct hfs_belem
*);
433 extern int hfs_bsucc(struct hfs_brec
*, int);
434 extern int hfs_bfind(struct hfs_brec
*, struct hfs_btree
*,
435 const struct hfs_bkey
*, int);
438 extern int hfs_binsert(struct hfs_btree
*, const struct hfs_bkey
*,
439 const void *, hfs_u16
);
442 extern hfs_u16
hfs_vbm_count_free(const struct hfs_mdb
*, hfs_u16
);
443 extern hfs_u16
hfs_vbm_search_free(const struct hfs_mdb
*, hfs_u16
*);
444 extern int hfs_set_vbm_bits(struct hfs_mdb
*, hfs_u16
, hfs_u16
);
445 extern int hfs_clear_vbm_bits(struct hfs_mdb
*, hfs_u16
, hfs_u16
);
448 extern hfs_u32
hfs_find_zero_bit(const hfs_u32
*, hfs_u32
, hfs_u32
);
449 extern hfs_u32
hfs_count_zero_bits(const hfs_u32
*, hfs_u32
, hfs_u32
);
452 extern struct hfs_btree
*hfs_btree_init(struct hfs_mdb
*, ino_t
,
453 hfs_byte_t
*, hfs_u32
, hfs_u32
);
454 extern void hfs_btree_free(struct hfs_btree
*);
455 extern void hfs_btree_commit(struct hfs_btree
*, hfs_byte_t
*, hfs_lword_t
);
458 extern void hfs_cat_init(void);
459 extern void hfs_cat_put(struct hfs_cat_entry
*);
460 extern void hfs_cat_mark_dirty(struct hfs_cat_entry
*);
461 extern struct hfs_cat_entry
*hfs_cat_get(struct hfs_mdb
*,
462 const struct hfs_cat_key
*);
464 extern void hfs_cat_invalidate(struct hfs_mdb
*);
465 extern void hfs_cat_commit(struct hfs_mdb
*);
466 extern void hfs_cat_free(void);
468 extern int hfs_cat_compare(const struct hfs_cat_key
*,
469 const struct hfs_cat_key
*);
470 extern void hfs_cat_build_key(hfs_u32
, const struct hfs_name
*,
471 struct hfs_cat_key
*);
472 extern struct hfs_cat_entry
*hfs_cat_parent(struct hfs_cat_entry
*);
474 extern int hfs_cat_open(struct hfs_cat_entry
*, struct hfs_brec
*);
475 extern int hfs_cat_next(struct hfs_cat_entry
*, struct hfs_brec
*,
476 hfs_u16
, hfs_u32
*, hfs_u8
*);
477 extern void hfs_cat_close(struct hfs_cat_entry
*, struct hfs_brec
*);
479 extern int hfs_cat_create(struct hfs_cat_entry
*, struct hfs_cat_key
*,
480 hfs_u8
, hfs_u32
, hfs_u32
, struct hfs_cat_entry
**);
481 extern int hfs_cat_mkdir(struct hfs_cat_entry
*, struct hfs_cat_key
*,
482 struct hfs_cat_entry
**);
483 extern int hfs_cat_delete(struct hfs_cat_entry
*, struct hfs_cat_entry
*, int);
484 extern int hfs_cat_move(struct hfs_cat_entry
*, struct hfs_cat_entry
*,
485 struct hfs_cat_entry
*, struct hfs_cat_key
*,
486 struct hfs_cat_entry
**);
489 extern int hfs_ext_compare(const struct hfs_ext_key
*,
490 const struct hfs_ext_key
*);
491 extern void hfs_extent_in(struct hfs_fork
*, const hfs_byte_t
*);
492 extern void hfs_extent_out(const struct hfs_fork
*, hfs_byte_t
*);
493 extern int hfs_extent_map(struct hfs_fork
*, int, int);
494 extern void hfs_extent_adj(struct hfs_fork
*);
495 extern void hfs_extent_free(struct hfs_fork
*);
498 extern int hfs_get_block(struct inode
*, long, struct buffer_head
*, int);
501 extern struct hfs_mdb
*hfs_mdb_get(hfs_sysmdb
, int, hfs_s32
);
502 extern void hfs_mdb_commit(struct hfs_mdb
*, int);
503 extern void hfs_mdb_put(struct hfs_mdb
*, int);
506 extern int hfs_part_find(hfs_sysmdb
, int, int, hfs_s32
*, hfs_s32
*);
509 extern unsigned int hfs_strhash(const unsigned char *, unsigned int);
510 extern int hfs_strcmp(const unsigned char *, unsigned int,
511 const unsigned char *, unsigned int);
512 extern int hfs_streq(const unsigned char *, unsigned int,
513 const unsigned char *, unsigned int);
514 extern void hfs_tolower(unsigned char *, int);
516 static __inline__
struct dentry
517 *hfs_lookup_dentry(struct dentry
*base
, const char *name
, const int len
)
523 this.hash
= hfs_strhash(name
, len
);
525 return d_lookup(base
, &this);
528 /* drop a dentry for one of the special directories.
529 * it's in the form of base/name/dentry. */
530 static __inline__
void hfs_drop_special(struct dentry
*base
,
531 const struct hfs_name
*name
,
532 struct dentry
*dentry
)
534 struct dentry
*dparent
, *de
;
536 dparent
= hfs_lookup_dentry(base
, name
->Name
, name
->Len
);
538 de
= hfs_lookup_dentry(dparent
, dentry
->d_name
.name
,
549 extern struct dentry_operations hfs_dentry_operations
;