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