1
2
3#ifndef _HFS_H
4#define _HFS_H
5
6#include <linux/hfs_sysdep.h>
7
8#define HFS_NEW(X)	((X) = hfs_malloc(sizeof(*(X))))
9#define HFS_DELETE(X)	do { hfs_free((X), sizeof(*(X))); (X) = NULL; } \
10                        while (0)
11
12/* offsets to various blocks */
13#define HFS_DD_BLK		0 /* Driver Descriptor block */
14#define HFS_PMAP_BLK		1 /* First block of partition map */
15#define HFS_MDB_BLK		2 /* Block (w/i partition) of MDB */
16
17/* magic numbers for various disk blocks */
18#define HFS_DRVR_DESC_MAGIC	0x4552 /* "ER": driver descriptor map */
19#define HFS_OLD_PMAP_MAGIC	0x5453 /* "TS": old-type partition map */
20#define HFS_NEW_PMAP_MAGIC	0x504D /* "PM": new-type partition map */
21#define HFS_SUPER_MAGIC		0x4244 /* "BD": HFS MDB (super block) */
22#define HFS_MFS_SUPER_MAGIC	0xD2D7 /* MFS MDB (super block) */
23
24/* magic numbers for various internal structures */
25#define HFS_FILE_MAGIC		0x4801
26#define HFS_DIR_MAGIC		0x4802
27#define HFS_MDB_MAGIC		0x4803
28#define HFS_EXT_MAGIC		0x4804
29#define HFS_BREC_MAGIC		0x4811
30#define HFS_BTREE_MAGIC		0x4812
31#define HFS_BNODE_MAGIC		0x4813
32
33/* various FIXED size parameters */
34#define HFS_SECTOR_SIZE		512    /* size of an HFS sector */
35#define HFS_SECTOR_SIZE_BITS	9      /* log_2(HFS_SECTOR_SIZE) */
36#define HFS_NAMELEN		31     /* maximum length of an HFS filename */
37#define HFS_NAMEMAX		(3*31) /* max size of ENCODED filename */
38#define HFS_BM_MAXBLOCKS	(16)   /* max number of bitmap blocks */
39#define HFS_BM_BPB (8*HFS_SECTOR_SIZE) /* number of bits per bitmap block */
40#define HFS_MAX_VALENCE		32767U
41#define HFS_FORK_MAX		(0x7FFFFFFF)
42
43/* Meanings of the drAtrb field of the MDB,
44 * Reference: _Inside Macintosh: Files_ p. 2-61
45 */
46#define HFS_SB_ATTRIB_HLOCK 0x0080
47#define HFS_SB_ATTRIB_CLEAN 0x0100
48#define HFS_SB_ATTRIB_SPARED 0x0200
49#define HFS_SB_ATTRIB_SLOCK 0x8000
50
51/* 2**16 - 1 */
52#define HFS_USHRT_MAX	65535
53
54/* Some special File ID numbers */
55#define HFS_POR_CNID	1	/* Parent Of the Root */
56#define HFS_ROOT_CNID	2	/* ROOT directory */
57#define HFS_EXT_CNID	3	/* EXTents B-tree */
58#define HFS_CAT_CNID	4	/* CATalog B-tree */
59#define HFS_BAD_CNID	5	/* BAD blocks file */
60#define HFS_ALLOC_CNID  6       /* ALLOCation file (HFS+) */
61#define HFS_START_CNID  7       /* STARTup file (HFS+) */
62#define HFS_ATTR_CNID   8       /* ATTRibutes file (HFS+) */
63#define HFS_EXCH_CNID  15       /* ExchangeFiles temp id */
64
65/* values for hfs_cat_rec.cdrType */
66#define HFS_CDR_DIR    0x01    /* folder (directory) */
67#define HFS_CDR_FIL    0x02    /* file */
68#define HFS_CDR_THD    0x03    /* folder (directory) thread */
69#define HFS_CDR_FTH    0x04    /* file thread */
70
71/* legal values for hfs_ext_key.FkType and hfs_file.fork */
72#define HFS_FK_DATA	0x00
73#define HFS_FK_RSRC	0xFF
74
75/* bits in hfs_fil_entry.Flags */
76#define HFS_FIL_LOCK	0x01  /* locked */
77#define HFS_FIL_THD	0x02  /* file thread */
78#define HFS_FIL_DOPEN   0x04  /* data fork open */
79#define HFS_FIL_ROPEN   0x08  /* resource fork open */
80#define HFS_FIL_DIR     0x10  /* directory (always clear) */
81#define HFS_FIL_RSRV1   0x20  /* reserved */
82#define HFS_FIL_NOCOPY  0x40  /* copy-protected file */
83#define HFS_FIL_USED	0x80  /* open */
84
85/* bits in hfs_dir_entry.Flags. dirflags is 16 bits. */
86#define HFS_DIR_LOCK        0x01  /* locked */
87#define HFS_DIR_THD         0x02  /* directory thread */
88#define HFS_DIR_INEXPFOLDER 0x04  /* in a shared area */
89#define HFS_DIR_MOUNTED     0x08  /* mounted */
90#define HFS_DIR_DIR         0x10  /* directory (always set) */
91#define HFS_DIR_EXPFOLDER   0x20  /* share point */
92#define HFS_DIR_RSRV1       0x40  /* reserved */
93#define HFS_DIR_RSRV2       0x80  /* reserved */
94
95/* Access types used when requesting access to a B-node */
96#define HFS_LOCK_NONE	0x0000	/* Illegal */
97#define HFS_LOCK_READ	0x0001	/* read-only access */
98#define HFS_LOCK_RESRV	0x0002	/* might potentially modify */
99#define HFS_LOCK_WRITE	0x0003	/* will modify now (exclusive access) */
100#define HFS_LOCK_MASK	0x000f
101
102/* Flags field of the hfs_path_elem */
103#define HFS_BPATH_FIRST		0x0100
104#define HFS_BPATH_OVERFLOW	0x0200
105#define HFS_BPATH_UNDERFLOW	0x0400
106#define HFS_BPATH_MASK		0x0f00
107
108/* Flags for hfs_bfind() */
109#define HFS_BFIND_EXACT		0x0010
110#define HFS_BFIND_LOCK		0x0020
111
112/* Modes for hfs_bfind() */
113#define HFS_BFIND_WRITE   (HFS_LOCK_RESRV|HFS_BFIND_EXACT|HFS_BFIND_LOCK)
114#define HFS_BFIND_READ_EQ (HFS_LOCK_READ|HFS_BFIND_EXACT)
115#define HFS_BFIND_READ_LE (HFS_LOCK_READ)
116#define HFS_BFIND_INSERT  (HFS_LOCK_RESRV|HFS_BPATH_FIRST|HFS_BPATH_OVERFLOW)
117#define HFS_BFIND_DELETE \
118	 (HFS_LOCK_RESRV|HFS_BFIND_EXACT|HFS_BPATH_FIRST|HFS_BPATH_UNDERFLOW)
119
120/*======== HFS structures as they appear on the disk ========*/
121
122/* Pascal-style string of up to 31 characters */
123struct hfs_name {
124	hfs_byte_t	Len;
125	hfs_byte_t	Name[31];
126} __attribute__((packed));
127
128typedef struct {
129	hfs_word_t	v;
130	hfs_word_t	h;
131} hfs_point_t;
132
133typedef struct {
134	hfs_word_t	top;
135	hfs_word_t	left;
136	hfs_word_t	bottom;
137	hfs_word_t	right;
138} hfs_rect_t;
139
140typedef struct {
141	hfs_lword_t	 fdType;
142	hfs_lword_t	 fdCreator;
143	hfs_word_t	 fdFlags;
144	hfs_point_t	 fdLocation;
145	hfs_word_t	 fdFldr;
146} __attribute__((packed)) hfs_finfo_t;
147
148typedef struct {
149	hfs_word_t	fdIconID;
150	hfs_byte_t	fdUnused[8];
151	hfs_word_t	fdComment;
152	hfs_lword_t	fdPutAway;
153} __attribute__((packed)) hfs_fxinfo_t;
154
155typedef struct {
156	hfs_rect_t	frRect;
157	hfs_word_t	frFlags;
158	hfs_point_t	frLocation;
159	hfs_word_t	frView;
160} __attribute__((packed)) hfs_dinfo_t;
161
162typedef struct {
163	hfs_point_t	frScroll;
164	hfs_lword_t	frOpenChain;
165	hfs_word_t	frUnused;
166	hfs_word_t	frComment;
167	hfs_lword_t	frPutAway;
168} __attribute__((packed)) hfs_dxinfo_t;
169
170union hfs_finder_info {
171	struct {
172		hfs_finfo_t	finfo;
173		hfs_fxinfo_t	fxinfo;
174	} file;
175	struct {
176		hfs_dinfo_t	dinfo;
177		hfs_dxinfo_t	dxinfo;
178	} dir;
179};
180
181/* A btree record key on disk */
182struct hfs_bkey {
183	hfs_byte_t	KeyLen;		/* number of bytes in the key */
184	hfs_byte_t	value[1];	/* (KeyLen) bytes of key */
185} __attribute__((packed));
186
187/* Cast to a pointer to a generic bkey */
188#define	HFS_BKEY(X)	(((void)((X)->KeyLen)), ((struct hfs_bkey *)(X)))
189
190/* The key used in the catalog b-tree: */
191struct hfs_cat_key {
192	hfs_byte_t	KeyLen;	/* number of bytes in the key */
193	hfs_byte_t	Resrv1;	/* padding */
194	hfs_lword_t	ParID;	/* CNID of the parent dir */
195	struct hfs_name	CName;	/* The filename of the entry */
196} __attribute__((packed));
197
198/* The key used in the extents b-tree: */
199struct hfs_ext_key {
200	hfs_byte_t	KeyLen;	/* number of bytes in the key */
201	hfs_byte_t	FkType;	/* HFS_FK_{DATA,RSRC} */
202	hfs_lword_t	FNum;	/* The File ID of the file */
203	hfs_word_t	FABN;	/* allocation blocks number*/
204} __attribute__((packed));
205
206/*======== Data structures kept in memory ========*/
207
208/*
209 * struct hfs_mdb
210 *
211 * The fields from the MDB of an HFS filesystem
212 */
213struct hfs_mdb {
214	int			magic;		/* A magic number */
215	unsigned char		vname[28];	/* The volume name */
216	hfs_sysmdb		sys_mdb;	/* superblock */
217	hfs_buffer		buf;		/* The hfs_buffer
218						   holding the real
219						   superblock (aka VIB
220						   or MDB) */
221	hfs_buffer		alt_buf;	/* The hfs_buffer holding
222						   the alternate superblock */
223	hfs_buffer		bitmap[16];	/* The hfs_buffer holding the
224						   allocation bitmap */
225	struct hfs_btree *	ext_tree;	/* Information about
226						   the extents b-tree */
227	struct hfs_btree *	cat_tree;	/* Information about
228						   the catalog b-tree */
229	hfs_u32			file_count;	/* The number of
230						   regular files in
231						   the filesystem */
232	hfs_u32			dir_count;	/* The number of
233						   directories in the
234						   filesystem */
235	hfs_u32			next_id;	/* The next available
236						   file id number */
237	hfs_u32			clumpablks;	/* The number of allocation
238						   blocks to try to add when
239						   extending a file */
240	hfs_u32			write_count;	/* The number of MDB
241						   writes (a sort of
242						   version number) */
243	hfs_u32			fs_start;	/* The first 512-byte
244						   block represented
245						   in the bitmap */
246	hfs_u32			create_date;	/* In network byte-order */
247	hfs_u32			modify_date;	/* In network byte-order */
248	hfs_u32			backup_date;	/* In network byte-order */
249	hfs_u16			root_files;	/* The number of
250						   regular
251						   (non-directory)
252						   files in the root
253						   directory */
254	hfs_u16			root_dirs;	/* The number of
255						   directories in the
256						   root directory */
257	hfs_u16			fs_ablocks;	/* The number of
258						   allocation blocks
259						   in the filesystem */
260	hfs_u16			free_ablocks;	/* The number of unused
261						   allocation blocks
262						   in the filesystem */
263	hfs_u32			alloc_blksz;	/* The number of
264						   512-byte blocks per
265						   "allocation block" */
266	hfs_u16			attrib;		/* Attribute word */
267	hfs_wait_queue		rename_wait;
268	int			rename_lock;
269	hfs_wait_queue		bitmap_wait;
270	int			bitmap_lock;
271        struct list_head        entry_dirty;
272};
273
274/*
275 * struct hfs_extent
276 *
277 * The offset to allocation block mapping for a given file is
278 * contained in a series of these structures.  Each (struct
279 * hfs_extent) records up to three runs of contiguous allocation
280 * blocks.  An allocation block is a contiguous group of physical
281 * blocks.
282 */
283struct hfs_extent {
284	int		   magic;     /* A magic number */
285	unsigned short	   start;     /* Where in the file this record
286					 begins (in allocation blocks) */
287	unsigned short	   end;	      /* Where in the file this record
288					 ends (in allocation blocks) */
289	unsigned short	   block[3];  /* The allocation block on disk which
290					 begins this extent */
291	unsigned short	   length[3]; /* The number of allocation blocks
292					 in this extent */
293	struct hfs_extent  *next;     /* Next extent record for this file */
294	struct hfs_extent  *prev;     /* Previous extent record for this file */
295	int		   count;     /* Number of times it is used */
296};
297
298/*
299 * struct hfs_dir
300 *
301 * This structure holds information specific
302 * to a directory in an HFS filesystem.
303 */
304struct hfs_dir {
305	int		magic;		/* A magic number */
306	hfs_u16		flags;
307	hfs_u16		dirs;		/* Number of directories in this one */
308	hfs_u16		files;		/* Number of files in this directory */
309	int		readers;
310	hfs_wait_queue	read_wait;
311	int		writers;
312	hfs_wait_queue	write_wait;
313};
314
315/*
316 * struct hfs_fork
317 *
318 * This structure holds the information
319 * specific to a single fork of a file.
320 */
321struct hfs_fork {
322	struct hfs_cat_entry	*entry;    /* The file this fork is part of */
323	struct hfs_extent	first;     /* The first extent record for
324						 this fork */
325	struct hfs_extent	*cache;    /* The most-recently accessed
326						 extent record for this fork */
327	hfs_u32			lsize;     /* The logical size in bytes */
328	hfs_u32			psize;     /* The phys size (512-byte blocks) */
329        hfs_u8			fork;      /* Which fork is this? */
330};
331
332/*
333 * struct hfs_file
334 *
335 * This structure holds information specific
336 * to a file in an HFS filesystem.
337 */
338struct hfs_file {
339	int		   magic;
340	struct hfs_fork    data_fork;
341	struct hfs_fork    rsrc_fork;
342	hfs_u16		   clumpablks;
343	hfs_u8		   flags;
344};
345
346/*
347 * struct hfs_file
348 *
349 * This structure holds information about a
350 * file or directory in an HFS filesystem.
351 *
352 * 'wait' must remain 1st and 'hash' 2nd since we do some pointer arithmetic.
353 */
354struct hfs_cat_entry {
355	hfs_wait_queue		wait;
356        struct list_head        hash;
357        struct list_head        list;
358	struct hfs_mdb		*mdb;
359	hfs_sysentry		sys_entry;
360	struct hfs_cat_key	key;
361	union hfs_finder_info	info;
362	hfs_u32			cnid;		/* In network byte-order */
363	hfs_u32			create_date;	/* In network byte-order */
364	hfs_u32			modify_date;	/* In network byte-order */
365	hfs_u32			backup_date;	/* In network byte-order */
366	unsigned short		count;
367        unsigned long           state;
368	hfs_u8			type;
369	union {
370		struct hfs_dir	dir;
371		struct hfs_file file;
372	} u;
373};
374
375/* hfs entry state bits */
376#define HFS_DIRTY        1
377#define HFS_KEYDIRTY     2
378#define HFS_LOCK         4
379#define HFS_DELETED      8
380
381/*
382 * struct hfs_bnode_ref
383 *
384 * A pointer to a (struct hfs_bnode) and the type of lock held on it.
385 */
386struct hfs_bnode_ref {
387        struct hfs_bnode *bn;
388        int lock_type;
389};
390
391/*
392 * struct hfs_belem
393 *
394 * An element of the path from the root of a B-tree to a leaf.
395 * Includes the reference to a (struct hfs_bnode), the index of
396 * the appropriate record in that node, and some flags.
397 */
398struct hfs_belem {
399	struct hfs_bnode_ref	bnr;
400	int			record;
401	int			flags;
402};
403
404/*
405 * struct hfs_brec
406 *
407 * The structure returned by hfs_bfind() to describe the requested record.
408 */
409struct hfs_brec {
410	int			keep_flags;
411	struct hfs_btree	*tree;
412	struct hfs_belem	*top;
413	struct hfs_belem	*bottom;
414	struct hfs_belem	elem[9];
415	struct hfs_bkey		*key;
416	void			*data;	/* The actual data */
417};
418
419/*================ Function prototypes ================*/
420
421/* bdelete.c */
422extern int hfs_bdelete(struct hfs_btree *, const struct hfs_bkey *);
423
424/* bfind.c */
425extern void hfs_brec_relse(struct hfs_brec *, struct hfs_belem *);
426extern int hfs_bsucc(struct hfs_brec *, int);
427extern int hfs_bfind(struct hfs_brec *, struct hfs_btree *,
428		     const struct hfs_bkey *, int);
429
430/* binsert.c */
431extern int hfs_binsert(struct hfs_btree *, const struct hfs_bkey *,
432		       const void *, hfs_u16);
433
434/* bitmap.c */
435extern hfs_u16 hfs_vbm_count_free(const struct hfs_mdb *, hfs_u16);
436extern hfs_u16 hfs_vbm_search_free(const struct hfs_mdb *, hfs_u16 *);
437extern int hfs_set_vbm_bits(struct hfs_mdb *, hfs_u16, hfs_u16);
438extern int hfs_clear_vbm_bits(struct hfs_mdb *, hfs_u16, hfs_u16);
439
440/* bitops.c */
441extern hfs_u32 hfs_find_zero_bit(const hfs_u32 *, hfs_u32, hfs_u32);
442extern hfs_u32 hfs_count_zero_bits(const hfs_u32 *, hfs_u32, hfs_u32);
443
444/* btree.c */
445extern struct hfs_btree *hfs_btree_init(struct hfs_mdb *, ino_t,
446				        hfs_byte_t *, hfs_u32, hfs_u32);
447extern void hfs_btree_free(struct hfs_btree *);
448extern void hfs_btree_commit(struct hfs_btree *, hfs_byte_t *, hfs_lword_t);
449
450/* catalog.c */
451extern void hfs_cat_init(void);
452extern void hfs_cat_put(struct hfs_cat_entry *);
453extern void hfs_cat_mark_dirty(struct hfs_cat_entry *);
454extern struct hfs_cat_entry *hfs_cat_get(struct hfs_mdb *,
455					 const struct hfs_cat_key *);
456
457extern void hfs_cat_invalidate(struct hfs_mdb *);
458extern void hfs_cat_commit(struct hfs_mdb *);
459extern void hfs_cat_free(void);
460
461extern int hfs_cat_compare(const struct hfs_cat_key *,
462			   const struct hfs_cat_key *);
463extern void hfs_cat_build_key(hfs_u32, const struct hfs_name *,
464			      struct hfs_cat_key *);
465extern struct hfs_cat_entry *hfs_cat_parent(struct hfs_cat_entry *);
466
467extern int hfs_cat_open(struct hfs_cat_entry *, struct hfs_brec *);
468extern int hfs_cat_next(struct hfs_cat_entry *, struct hfs_brec *,
469			hfs_u16, hfs_u32 *, hfs_u8 *);
470extern void hfs_cat_close(struct hfs_cat_entry *, struct hfs_brec *);
471
472extern int hfs_cat_create(struct hfs_cat_entry *, struct hfs_cat_key *,
473			  hfs_u8, hfs_u32, hfs_u32, struct hfs_cat_entry **);
474extern int hfs_cat_mkdir(struct hfs_cat_entry *, struct hfs_cat_key *,
475			 struct hfs_cat_entry **);
476extern int hfs_cat_delete(struct hfs_cat_entry *, struct hfs_cat_entry *, int);
477extern int hfs_cat_move(struct hfs_cat_entry *, struct hfs_cat_entry *,
478			struct hfs_cat_entry *, struct hfs_cat_key *,
479			struct hfs_cat_entry **);
480
481/* extent.c */
482extern int hfs_ext_compare(const struct hfs_ext_key *,
483			   const struct hfs_ext_key *);
484extern void hfs_extent_in(struct hfs_fork *, const hfs_byte_t *);
485extern void hfs_extent_out(const struct hfs_fork *, hfs_byte_t *);
486extern int hfs_extent_map(struct hfs_fork *, int, int);
487extern void hfs_extent_adj(struct hfs_fork *);
488extern void hfs_extent_free(struct hfs_fork *);
489
490/* file.c */
491extern int hfs_get_block(struct inode *, long, struct buffer_head *, int);
492
493/* mdb.c */
494extern struct hfs_mdb *hfs_mdb_get(hfs_sysmdb, int, hfs_s32);
495extern void hfs_mdb_commit(struct hfs_mdb *, int);
496extern void hfs_mdb_put(struct hfs_mdb *, int);
497
498/* part_tbl.c */
499extern int hfs_part_find(hfs_sysmdb, int, int, hfs_s32 *, hfs_s32 *);
500
501/* string.c */
502extern unsigned int hfs_strhash(const unsigned char *, unsigned int);
503extern int hfs_strcmp(const unsigned char *, unsigned int,
504		      const unsigned char *, unsigned int);
505extern int hfs_streq(const unsigned char *, unsigned int,
506		     const unsigned char *, unsigned int);
507extern void hfs_tolower(unsigned char *, int);
508
509static __inline__ struct dentry
510*hfs_lookup_dentry(struct dentry *base, const char *name, const int len)
511{
512  struct qstr this;
513
514  this.name = name;
515  this.len = len;
516  this.hash = hfs_strhash(name, len);
517
518  return d_lookup(base, &this);
519}
520
521/* drop a dentry for one of the special directories.
522 * it's in the form of base/name/dentry. */
523static __inline__ void hfs_drop_special(struct dentry *base,
524					const struct hfs_name *name,
525					struct dentry *dentry)
526{
527  struct dentry *dparent, *de;
528
529  dparent = hfs_lookup_dentry(base, name->Name, name->Len);
530  if (dparent) {
531	  de = hfs_lookup_dentry(dparent, dentry->d_name.name,
532				 dentry->d_name.len);
533	  if (de) {
534		  if (!de->d_inode)
535			  d_drop(de);
536		  dput(de);
537	  }
538	  dput(dparent);
539  }
540}
541
542extern struct dentry_operations hfs_dentry_operations;
543#endif
544