|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* @(#)hfs.h 3.0 ! 23: * ! 24: * (c) 1990, 1992 NeXT Computer, Inc. All Rights Reserved ! 25: * (c) 1997-1999 Apple Computer, Inc. All Rights Reserved ! 26: * ! 27: * hfs.h -- constants, structures, function declarations. etc. ! 28: * for Macintosh file system vfs. ! 29: * ! 30: * HISTORY ! 31: * 12-Aug-1999 Scott Roberts Merge into HFSStruct, the FCB ! 32: * 6-Jun-1999 Don Brady Minor cleanup of hfsmount struct. ! 33: * 22-Mar-1999 Don Brady For POSIX delete semantics: add private metadata strings. ! 34: * 13-Jan-1999 Don Brady Add ATTR_CMN_SCRIPT to HFS_ATTR_CMN_LOOKUPMASK (radar #2296613). ! 35: * 20-Nov-1998 Don Brady Remove UFSToHFSStr and HFSToUFSStr prototypes (obsolete). ! 36: * Move filename entry from FCB to hfsfilemeta, hfsdirentry ! 37: * names are now 255 byte long. ! 38: * 10-Nov-1998 Pat Dirks Added MAXLOGBLOCKSIZE and MAXLOGBLOCKSIZEBLOCKS and RELEASE_BUFFER flag. ! 39: * Added hfsLogicalBlockTableEntry and h_logicalblocktable field in struct hfsnode. ! 40: * 4-Sep-1998 Pat Dirks Added hfs_log_block_size to hfsmount struct [again] and BestBlockSizeFit routine. ! 41: * 31-aug-1998 Don Brady Add UL to MAC_GMT_FACTOR constant. ! 42: * 04-jun-1998 Don Brady Add hfsMoveRename prototype to replace hfsMove and hfsRename. ! 43: * Add VRELE and VPUT macros to catch bad ref counts. ! 44: * 28-May-1998 Pat Dirks Move internal 'struct searchinfo' def'n here from attr.h ! 45: * 03-may-1998 Brent Knight Add gTimeZone. ! 46: * 23-apr-1998 Don Brady Add File type and creator for symbolic links. ! 47: * 22-apr-1998 Don Brady Removed kMetaFile. ! 48: * 21-apr-1998 Don Brady Add to_bsd_time and to_hfs_time prototypes. ! 49: * 20-apr-1998 Don Brady Remove course-grained hfs metadata locking. ! 50: * 15-apr-1998 Don Brady Add hasOverflowExtents and hfs_metafilelocking prototypes. Add kSysFile constant. ! 51: * 14-apr-1998 Deric Horn Added searchinfo_t, definition of search criteria used by searchfs. ! 52: * 9-apr-1998 Don Brady Added hfs_flushMDB and hfs_flushvolumeheader prototypes. ! 53: * 8-apr-1998 Don Brady Add MAKE_VREFNUM macro. ! 54: * 26-mar-1998 Don Brady Removed CloseBTreeFile and OpenBtreeFile prototypes. ! 55: * ! 56: * 12-nov-1997 Scott Roberts Added changes for HFSPlus ! 57: */ ! 58: ! 59: #ifndef __HFS__ ! 60: #define __HFS__ ! 61: ! 62: #include <sys/param.h> ! 63: #include <sys/lock.h> ! 64: #include <sys/queue.h> ! 65: #include <sys/attr.h> ! 66: ! 67: #include <sys/dirent.h> ! 68: ! 69: #include <hfs/hfs_format.h> ! 70: #include <hfs/hfs_macos_defs.h> ! 71: #include <hfs/hfs_encodings.h> ! 72: ! 73: ! 74: struct uio; // This is more effective than #include <sys/uio.h> in case KERNEL is undefined... ! 75: struct hfslockf; // For advisory locking ! 76: ! 77: /* ! 78: * Just reported via MIG interface. ! 79: */ ! 80: #define VERSION_STRING "hfs-2 (4-12-99)" ! 81: ! 82: ! 83: #define HFS_LINK_MAX 32767 ! 84: ! 85: /* ! 86: * Set to force READ_ONLY. ! 87: */ ! 88: #define FORCE_READONLY 0 ! 89: ! 90: enum { kMDBSize = 512 }; /* Size of I/O transfer to read entire MDB */ ! 91: ! 92: enum { kMasterDirectoryBlock = 2 }; /* MDB offset on disk in 512-byte blocks */ ! 93: enum { kMDBOffset = kMasterDirectoryBlock * 512 }; /* MDB offset on disk in bytes */ ! 94: ! 95: enum { ! 96: kUnknownID = 0, ! 97: kRootParID = 1, ! 98: kRootDirID = 2 ! 99: }; ! 100: ! 101: enum { ! 102: kUndefinedFork = 0, ! 103: kAnyFork, ! 104: kDataFork, ! 105: kRsrcFork, ! 106: kDirectory, ! 107: kSysFile, ! 108: kDefault ! 109: }; ! 110: ! 111: ! 112: /* ! 113: * File type and creator for symbolic links ! 114: */ ! 115: enum { ! 116: #if HFS_HARDLINKS ! 117: kHardLinkFileType = 0x686C6E6B, /* 'hlnk' */ ! 118: kHardLinkCreator = 0x72686170, /* 'rhap' */ ! 119: #endif ! 120: kSymLinkFileType = 0x736C6E6B, /* 'slnk' */ ! 121: kSymLinkCreator = 0x72686170 /* 'rhap' */ ! 122: }; ! 123: ! 124: ! 125: #define MAXLOGBLOCKSIZE PAGE_SIZE ! 126: #define MAXLOGBLOCKSIZEBLOCKS (MAXLOGBLOCKSIZE/512) ! 127: /* NOTE: Special support will be needed for LOGBLOCKMAPENTRIES > kHFSPlusExtentDensity (=8) */ ! 128: #define LOGBLOCKMAPENTRIES 8 ! 129: ! 130: #define BUFFERPTRLISTSIZE 25 ! 131: ! 132: extern char * gBufferAddress[BUFFERPTRLISTSIZE]; ! 133: extern struct buf *gBufferHeaderPtr[BUFFERPTRLISTSIZE]; ! 134: extern int gBufferListIndex; ! 135: extern simple_lock_data_t gBufferPtrListLock; ! 136: ! 137: extern struct timezone gTimeZone; ! 138: ! 139: /* Flag values for bexpand: */ ! 140: #define RELEASE_BUFFER 0x00000001 ! 141: ! 142: ! 143: /* Internal Data structures*/ ! 144: ! 145: struct vcb_t { ! 146: int16_t vcbFlags; ! 147: u_int16_t vcbSigWord; ! 148: u_int32_t vcbCrDate; ! 149: u_int32_t vcbLsMod; ! 150: int16_t vcbAtrb; ! 151: u_int16_t vcbNmFls; /* HFS only */ ! 152: int16_t vcbVBMSt; ! 153: int16_t vcbAlBlSt; ! 154: int32_t vcbClpSiz; ! 155: int32_t vcbNxtCNID; ! 156: u_int8_t vcbVN[256]; ! 157: int16_t vcbVRefNum; ! 158: u_int16_t vcbVSeqNum; ! 159: u_int32_t vcbVolBkUp; ! 160: int32_t vcbWrCnt; ! 161: u_int16_t vcbNmRtDirs; /* HFS only */ ! 162: u_int16_t vcbReserved; ! 163: int32_t vcbFilCnt; ! 164: int32_t vcbDirCnt; ! 165: int32_t vcbFndrInfo[8]; ! 166: struct vnode * extentsRefNum; ! 167: struct vnode * catalogRefNum; ! 168: struct vnode * allocationsRefNum; ! 169: u_int32_t blockSize; /* size of allocation blocks - vcbAlBlkSiz*/ ! 170: u_int32_t totalBlocks; /* number of allocation blocks in volume */ ! 171: u_int32_t freeBlocks; /* number of unused allocation blocks - vcbFreeBks*/ ! 172: u_int32_t nextAllocation; /* start of next allocation search - vcbAllocPtr*/ ! 173: u_int32_t altIDSector; /* location of alternate MDB/VH */ ! 174: u_int32_t hfsPlusIOPosOffset; /* Disk block where HFS+ starts */ ! 175: u_int32_t checkedDate; /* date and time of last disk check */ ! 176: u_int64_t encodingsBitmap; /* HFS Plus only*/ ! 177: u_int32_t volumeNameEncodingHint; /* Text encoding used for volume name*/ ! 178: char * hintCachePtr; /* points to this volumes heuristicHint cache*/ ! 179: simple_lock_data_t vcbSimpleLock; /* simple lock to allow concurrent access to vcb data */ ! 180: }; ! 181: typedef struct vcb_t ExtendedVCB; ! 182: ! 183: /* vcbFlags */ ! 184: #define kHFS_DamagedVolume 0x1 /* This volume has errors, unmount dirty */ ! 185: ! 186: ! 187: /* ! 188: * NOTE: The code relies on being able to cast an ExtendedVCB* to a vfsVCB* in order ! 189: * to gain access to the mount point pointer from a pointer ! 190: * to an ExtendedVCB. DO NOT INSERT OTHER FIELDS BEFORE THE vcb FIELD!! ! 191: * ! 192: * vcbFlags, vcbLsMod, vcbFilCnt, vcbDirCnt, vcbNxtCNID, etc ! 193: * are locked by the hfs_lock simple lock. ! 194: */ ! 195: typedef struct vfsVCB { ! 196: ExtendedVCB vcb_vcb; ! 197: struct hfsmount *vcb_hfsmp; /* Pointer to hfsmount structure */ ! 198: } vfsVCB_t; ! 199: ! 200: ! 201: ! 202: /* This structure describes the HFS specific mount structure data. */ ! 203: typedef struct hfsmount { ! 204: u_long hfs_mount_flags; ! 205: u_int8_t hfs_fs_clean; /* Whether contents have been flushed in clean state */ ! 206: u_int8_t hfs_fs_ronly; /* Whether this was mounted as read-initially */ ! 207: ! 208: /* Physical Description */ ! 209: u_long hfs_phys_block_count; /* Num of PHYSICAL blocks of volume */ ! 210: u_long hfs_phys_block_size; /* Always a multiple of 512 */ ! 211: ! 212: /* Access to VFS and devices */ ! 213: struct mount *hfs_mp; /* filesystem vfs structure */ ! 214: struct vnode *hfs_devvp; /* block device mounted vnode */ ! 215: dev_t hfs_raw_dev; /* device mounted */ ! 216: u_int32_t hfs_logBlockSize; /* Size of buffer cache buffer for I/O */ ! 217: ! 218: /* Default values for HFS standard and non-init access */ ! 219: uid_t hfs_uid; /* uid to set as owner of the files */ ! 220: gid_t hfs_gid; /* gid to set as owner of the files */ ! 221: mode_t hfs_dir_mask; /* mask to and with directory protection bits */ ! 222: mode_t hfs_file_mask; /* mask to and with file protection bits */ ! 223: u_long hfs_encoding; /* Defualt encoding for non hfs+ volumes */ ! 224: ! 225: /* HFS Specific */ ! 226: struct vfsVCB hfs_vcb; ! 227: u_long hfs_private_metadata_dir; /* private/hidden directory for unlinked files */ ! 228: hfs_to_unicode_func_t hfs_get_unicode; ! 229: unicode_to_hfs_func_t hfs_get_hfsname; ! 230: } hfsmount_t; ! 231: ! 232: ! 233: /***************************************************************************** ! 234: * ! 235: * hfsnode structure ! 236: * ! 237: * ! 238: * ! 239: *****************************************************************************/ ! 240: ! 241: #define MAXHFSVNODELEN 31 ! 242: typedef u_char FileNameStr[MAXHFSVNODELEN+1]; ! 243: ! 244: CIRCLEQ_HEAD(siblinghead, hfsnode) ; /* Head of the sibling list */ ! 245: ! 246: struct hfsLogicalBlockTableEntry { ! 247: u_int32_t logicalBlockCount; ! 248: off_t extentLength; ! 249: }; ! 250: ! 251: ! 252: struct hfsnode { ! 253: LIST_ENTRY(hfsnode) h_hash; /* links on valid files */ ! 254: CIRCLEQ_ENTRY(hfsnode) h_sibling; /* links on siblings */ ! 255: struct lock__bsd__ h_lock; /* node lock. */ ! 256: struct hfslockf * h_lockf; /* Head of byte-level lock list. */ ! 257: u_int32_t h_nodeflags; /* flags, see below */ ! 258: struct vnode * h_vp; /* vnode associated with this inode. */ ! 259: struct hfsfilemeta *h_meta; /* Ptr to file meta data */ ! 260: u_int8_t h_type; /* Type of info: dir, data, rsrc */ ! 261: ! 262: /* Buffered Cache information */ ! 263: struct hfsLogicalBlockTableEntry h_logicalblocktable[LOGBLOCKMAPENTRIES]; ! 264: off_t h_optimizedblocksizelimit; /* End of range covered by h_logicalblocktable */ ! 265: daddr_t h_uniformblocksizestart; /* First LBN in fixed-size log. block range */ ! 266: ! 267: /* FCB struct */ ! 268: int8_t fcbFlags; /* FCB flags */ ! 269: u_int64_t fcbEOF; /* Logical length or EOF in bytes */ ! 270: u_int64_t fcbPLen; /* Physical file length in bytes */ ! 271: u_int32_t fcbClmpSize; /* Number of bytes per clump */ ! 272: HFSPlusExtentRecord fcbExtents; /* Extents of file */ ! 273: ! 274: /* Used for Meta files */ ! 275: void * fcbBTCBPtr; /* Pointer to B*-Tree control block for file, opaque */ ! 276: ! 277: u_int32_t h_valid; /* is the vnode reference valid */ ! 278: }; ! 279: typedef struct hfsnode FCB; ! 280: typedef struct hfsnode *hfsnodeptr; ! 281: ! 282: ! 283: typedef struct hfsfilemeta { ! 284: struct siblinghead h_siblinghead; /* Head of the sibling list */ ! 285: simple_lock_data_t h_siblinglock; /* sibling list lock. */ ! 286: simple_lock_data_t h_metalock; /* SER XXX Should be deprecated. Locks the meta data. */ ! 287: u_int32_t h_metaflags; /* IN_LONGNAME, etc */ ! 288: struct vnode *h_devvp; /* vnode for block I/O. */ ! 289: ! 290: dev_t h_dev; /* Device associated with the inode. */ ! 291: u_int32_t h_nodeID; /* specific id of this node */ ! 292: u_int32_t h_dirID; /* Parent Directory ID */ ! 293: u_int32_t h_hint; /* Catalog hint */ ! 294: ! 295: off_t h_size; /* Total physical size of object */ ! 296: u_int16_t h_usecount; /* How many siblings */ ! 297: u_int16_t h_mode; /* IFMT, permissions; see below. */ ! 298: u_int32_t h_pflags; /* Permission flags (NODUMP, IMMUTABLE, APPEND etc.) */ ! 299: u_int32_t h_uid; /* File owner. */ ! 300: u_int32_t h_gid; /* File group. */ ! 301: dev_t h_rdev; /* Special device info for this node */ ! 302: u_int32_t h_crtime; /* UNIX-format creation date in secs. */ ! 303: u_int32_t h_atime; /* UNIX-format access date in secs. */ ! 304: u_int32_t h_mtime; /* UNIX-format mod date in seconds */ ! 305: u_int32_t h_ctime; /* UNIX-format status change date */ ! 306: u_int32_t h_butime; /* UNIX-format last backup date in secs. */ ! 307: int16_t h_nlink; /* File link count */ ! 308: u_short h_namelen; /* Length of name string */ ! 309: char * h_namePtr; /* Points the name of the file */ ! 310: FileNameStr h_fileName; /* CName of file */ ! 311: u_int32_t h_valence; /* directory child count */ ! 312: } hfsfilemeta; ! 313: ! 314: ! 315: /* ! 316: * Macros for quick access to fields buried in the fcb inside an hfs node: ! 317: */ ! 318: #define H_FORKTYPE(HP) ((HP)->h_type) ! 319: #define H_FILEID(HP) ((HP)->h_meta->h_nodeID) ! 320: #define H_DIRID(HP) ((HP)->h_meta->h_dirID) ! 321: #define H_NAME(HP) ((HP)->h_meta->h_namePtr) ! 322: #define H_HINT(HP) ((HP)->h_meta->h_hint) ! 323: #define H_DEV(HP) ((HP)->h_meta->h_dev) ! 324: ! 325: /* These flags are kept in flags. */ ! 326: #define IN_ACCESS 0x0001 /* Access time update request. */ ! 327: #define IN_CHANGE 0x0002 /* Change time update request. */ ! 328: #define IN_UPDATE 0x0004 /* Modification time update request. */ ! 329: #define IN_MODIFIED 0x0008 /* Node has been modified. */ ! 330: #define IN_RENAME 0x0010 /* Node is being renamed. */ ! 331: #define IN_SHLOCK 0x0020 /* File has shared lock. */ ! 332: #define IN_EXLOCK 0x0040 /* File has exclusive lock. */ ! 333: #define IN_ALLOCATING 0x1000 /* vnode is in transit, wait or ignore */ ! 334: #define IN_WANT 0x2000 /* Its being waited for */ ! 335: ! 336: /* These flags are kept in meta flags. */ ! 337: #define IN_LONGNAME 0x0400 /* File has long name buffer. */ ! 338: #define IN_UNSETACCESS 0x0200 /* File has unset access. */ ! 339: #define IN_DELETED 0x0800 /* File has been marked to be deleted */ ! 340: #if HFS_HARDLINKS ! 341: #define IN_DATANODE 0x1000 /* File is a data node (hard-linked) */ ! 342: #endif ! 343: ! 344: ! 345: /* File permissions stored in mode */ ! 346: #define IEXEC 0000100 /* Executable. */ ! 347: #define IWRITE 0000200 /* Writeable. */ ! 348: #define IREAD 0000400 /* Readable. */ ! 349: #define ISVTX 0001000 /* Sticky bit. */ ! 350: #define ISGID 0002000 /* Set-gid. */ ! 351: #define ISUID 0004000 /* Set-uid. */ ! 352: ! 353: /* File types */ ! 354: #define IFMT 0170000 /* Mask of file type. */ ! 355: #define IFIFO 0010000 /* Named pipe (fifo). */ ! 356: #define IFCHR 0020000 /* Character device. */ ! 357: #define IFDIR 0040000 /* Directory file. */ ! 358: #define IFBLK 0060000 /* Block device. */ ! 359: #define IFREG 0100000 /* Regular file. */ ! 360: #define IFLNK 0120000 /* Symbolic link. */ ! 361: #define IFSOCK 0140000 /* UNIX domain socket. */ ! 362: #define IFWHT 0160000 /* Whiteout. */ ! 363: ! 364: /* Value to make sure vnode is real and defined */ ! 365: #define HFS_VNODE_MAGIC 0x4846532b /* 'HFS+' */ ! 366: ! 367: /* To test wether the forkType is a sibling type */ ! 368: #define SIBLING_FORKTYPE(FORK) ((FORK==kDataFork) || (FORK==kRsrcFork)) ! 369: ! 370: /* ! 371: * Write check macro ! 372: */ ! 373: #define WRITE_CK(VNODE, FUNC_NAME) { \ ! 374: if ((VNODE)->v_mount->mnt_flag & MNT_RDONLY) { \ ! 375: DBG_ERR(("%s: ATTEMPT TO WRITE A READONLY VOLUME\n", \ ! 376: FUNC_NAME)); \ ! 377: return(EROFS); \ ! 378: } \ ! 379: } ! 380: ! 381: ! 382: /* ! 383: * hfsmount locking and unlocking. ! 384: * ! 385: * mvl_lock_flags ! 386: */ ! 387: #define MVL_LOCKED 0x00000001 /* debug only */ ! 388: ! 389: #if HFS_DIAGNOSTIC ! 390: #define MVL_LOCK(mvip) { \ ! 391: (simple_lock(&(mvip)->mvl_lock)); \ ! 392: (mvip)->mvl_flags |= MVL_LOCKED; \ ! 393: } ! 394: ! 395: #define MVL_UNLOCK(mvip) { \ ! 396: if(((mvip)->mvl_flags & MVL_LOCKED) == 0) { \ ! 397: panic("MVL_UNLOCK - hfsnode not locked"); \ ! 398: } \ ! 399: (simple_unlock(&(mvip)->mvl_lock)); \ ! 400: (mvip)->mvl_flags &= ~MVL_LOCKED; \ ! 401: } ! 402: #else /* HFS_DIAGNOSTIC */ ! 403: #define MVL_LOCK(mvip) (simple_lock(&(mvip)->mvl_lock)) ! 404: #define MVL_UNLOCK(mvip) (simple_unlock(&(mvip)->mvl_lock)) ! 405: #endif /* HFS_DIAGNOSTIC */ ! 406: ! 407: ! 408: /* structure to hold a "." or ".." directory entry (12 bytes) */ ! 409: typedef struct hfsdotentry { ! 410: u_int32_t d_fileno; /* unique file number */ ! 411: u_int16_t d_reclen; /* length of this structure */ ! 412: u_int8_t d_type; /* dirent file type */ ! 413: u_int8_t d_namelen; /* len of filename */ ! 414: char d_name[4]; /* "." or ".." */ ! 415: } hfsdotentry; ! 416: ! 417: #define AVERAGE_HFSDIRENTRY_SIZE (8+22+4) ! 418: #define MAX_HFSDIRENTRY_SIZE sizeof(struct dirent) ! 419: ! 420: #define DIRENTRY_SIZE(namlen) \ ! 421: ((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3)) ! 422: ! 423: ! 424: enum { ! 425: kCatalogFolderNode = 1, ! 426: kCatalogFileNode = 2 ! 427: }; ! 428: ! 429: /* ! 430: * CatalogNodeData has same layout as the on-disk HFS Plus file/dir records. ! 431: * Classic hfs file/dir records are converted to match this layout. ! 432: * ! 433: * The cnd_extra padding allows big hfs plus thread records (520 bytes max) ! 434: * to be read onto this stucture during a cnid lookup. ! 435: */ ! 436: struct CatalogNodeData { ! 437: int16_t cnd_type; ! 438: u_int16_t cnd_flags; ! 439: union { ! 440: u_int32_t cndu_valence; /* dirs only */ ! 441: u_int32_t cndu_linkCount; /* files only */ ! 442: } cnd_un; ! 443: u_int32_t cnd_nodeID; ! 444: u_int32_t cnd_createDate; ! 445: u_int32_t cnd_contentModDate; ! 446: u_int32_t cnd_attributeModDate; ! 447: u_int32_t cnd_accessDate; ! 448: u_int32_t cnd_backupDate; ! 449: u_int32_t cnd_ownerID; ! 450: u_int32_t cnd_groupID; ! 451: u_int32_t cnd_permissions; ! 452: u_int32_t cnd_specialDevice; ! 453: u_int8_t cnd_finderInfo[32]; ! 454: u_int32_t cnd_textEncoding; ! 455: u_int32_t cnd_reserved; ! 456: HFSPlusForkData cnd_datafork; ! 457: HFSPlusForkData cnd_rsrcfork; ! 458: u_int8_t cnd_extra[272]; /* make struct at least 520 bytes long */ ! 459: }; ! 460: typedef struct CatalogNodeData CatalogNodeData; ! 461: ! 462: #define cnd_valence cnd_un.cndu_valence ! 463: #define cnd_linkCount cnd_un.cndu_linkCount ! 464: ! 465: ! 466: /* structure to hold a catalog record information */ ! 467: /* Of everything you wanted to know about a catalog entry, file and directory */ ! 468: typedef struct hfsCatalogInfo { ! 469: CatalogNodeData nodeData; ! 470: FSSpec spec; /* filename */ ! 471: u_int32_t hint; ! 472: } hfsCatalogInfo; ! 473: ! 474: // structure definition of the searchfs system trap for the search criterea. ! 475: struct directoryInfoSpec ! 476: { ! 477: u_long numFiles; ! 478: }; ! 479: ! 480: struct fileInfoSpec ! 481: { ! 482: off_t dataLogicalLength; ! 483: off_t dataPhysicalLength; ! 484: off_t resourceLogicalLength; ! 485: off_t resourcePhysicalLength; ! 486: }; ! 487: ! 488: struct searchinfospec ! 489: { ! 490: u_char name[512]; ! 491: u_long nameLength; ! 492: char attributes; // see IM:Files 2-100 ! 493: u_long parentDirID; ! 494: struct timespec creationDate; ! 495: struct timespec modificationDate; ! 496: struct timespec lastBackupDate; ! 497: u_long finderInfo[8]; ! 498: struct fileInfoSpec f; ! 499: struct directoryInfoSpec d; ! 500: }; ! 501: typedef struct searchinfospec searchinfospec_t; ! 502: ! 503: #define HFSTIMES(hp, t1, t2) { \ ! 504: if ((hp)->h_nodeflags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \ ! 505: (hp)->h_nodeflags |= IN_MODIFIED; \ ! 506: if ((hp)->h_nodeflags & IN_ACCESS) { \ ! 507: (hp)->h_meta->h_atime = (t1)->tv_sec; \ ! 508: }; \ ! 509: if ((hp)->h_nodeflags & IN_UPDATE) { \ ! 510: (hp)->h_meta->h_mtime = (t2)->tv_sec; \ ! 511: } \ ! 512: if ((hp)->h_nodeflags & IN_CHANGE) { \ ! 513: (hp)->h_meta->h_ctime = time.tv_sec; \ ! 514: }; \ ! 515: (hp)->h_nodeflags &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \ ! 516: } \ ! 517: } ! 518: ! 519: /* macro to determine if hfsplus */ ! 520: #define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord) ! 521: ! 522: ! 523: /* ! 524: * Various ways to acquire a VNode pointer: ! 525: */ ! 526: #define HTOV(HP) ((HP)->h_vp) ! 527: ! 528: /* ! 529: * Various ways to acquire an HFS Node pointer: ! 530: */ ! 531: #define VTOH(VP) ((struct hfsnode *)((VP)->v_data)) ! 532: #define FCBTOH(FCB) ((struct hfsnode *)FCB) ! 533: ! 534: /* ! 535: * Various ways to acquire an FCB pointer: ! 536: */ ! 537: #define HTOFCB(HP) (HP) ! 538: #define VTOFCB(VP) ((FCB *)((VP)->v_data)) /* Should be the same as VTOH */ ! 539: ! 540: /* ! 541: * Various ways to acquire a VFS mount point pointer: ! 542: */ ! 543: #define VTOVFS(VP) ((VP)->v_mount) ! 544: #define HTOVFS(HP) ((HP)->h_vp->v_mount) ! 545: #define FCBTOVFS(FCB) ((FCB)->h_vp->v_mount) ! 546: #define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp) ! 547: #define VCBTOVFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp->hfs_mp) ! 548: ! 549: /* ! 550: * Various ways to acquire an HFS mount point pointer: ! 551: */ ! 552: #define VTOHFS(VP) ((struct hfsmount *)((VP)->v_mount->mnt_data)) ! 553: #define HTOHFS(HP) ((struct hfsmount *)(HP)->h_vp->v_mount->mnt_data) ! 554: #define FCBTOHFS(FCB) ((struct hfsmount *)(FCB)->h_vp->v_mount->mnt_data) ! 555: #define VFSTOHFS(MP) ((struct hfsmount *)(MP)->mnt_data) ! 556: #define VCBTOHFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp) ! 557: ! 558: /* ! 559: * Various ways to acquire a VCB pointer: ! 560: */ ! 561: #define VTOVCB(VP) (&(((struct hfsmount *)((VP)->v_mount->mnt_data))->hfs_vcb.vcb_vcb)) ! 562: #define HTOVCB(HP) (&(((struct hfsmount *)((HP)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb)) ! 563: #define FCBTOVCB(FCB) (&(((struct hfsmount *)((FCB)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb)) ! 564: #define VFSTOVCB(MP) (&(((struct hfsmount *)(MP)->mnt_data)->hfs_vcb.vcb_vcb)) ! 565: #define HFSTOVCB(HFSMP) (&(HFSMP)->hfs_vcb.vcb_vcb) ! 566: ! 567: ! 568: #define E_NONE 0 ! 569: #define kHFSBlockSize 512 ! 570: #define kHFSBlockShift 9 /* 2^9 = 512 */ ! 571: ! 572: #define IOBLKNOFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBLOCK) / ((BLOCKSIZEINBYTES) >> 9))) ! 573: #define IOBLKCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \ ! 574: ((int)(IOBLKNOFORBYTE(((STARTINGBLOCK) * 512) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \ ! 575: IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) + 1)) ! 576: #define IOBYTECCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \ ! 577: (IOBLKCNTFORBLK((STARTINGBLOCK),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)) ! 578: #define IOBYTEOFFSETFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) \ ! 579: (((STARTINGBLOCK) * 512) - \ ! 580: (IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))) ! 581: ! 582: #define IOBLKNOFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBYTE) / (BLOCKSIZEINBYTES))) ! 583: #define IOBLKCNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \ ! 584: ((int)(IOBLKNOFORBYTE((STARTINGBYTE) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \ ! 585: IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) + 1)) ! 586: #define IOBYTECNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \ ! 587: (IOBLKCNTFORBYTE((STARTINGBYTE),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)) ! 588: #define IOBYTEOFFSETFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((STARTINGBYTE) - (IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))) ! 589: ! 590: #define MAKE_VREFNUM(x) ((int32_t)((x) & 0xffff)) ! 591: /* ! 592: * This is the straight GMT conversion constant: ! 593: * 00:00:00 January 1, 1970 - 00:00:00 January 1, 1904 ! 594: * (3600 * 24 * ((365 * (1970 - 1904)) + (((1970 - 1904) / 4) + 1))) ! 595: */ ! 596: #define MAC_GMT_FACTOR 2082844800UL ! 597: ! 598: #define HFS_ATTR_CMN_LOOKUPMASK (ATTR_CMN_SCRIPT | ATTR_CMN_FNDRINFO | ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST) ! 599: #define HFS_ATTR_DIR_LOOKUPMASK (ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT) ! 600: #define HFS_ATTR_FILE_LOOKUPMASK (ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | ATTR_FILE_ALLOCSIZE | \ ! 601: ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_DATAEXTENTS | \ ! 602: ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE | ATTR_FILE_RSRCEXTENTS) ! 603: ! 604: #define VPUT(vp) if (((vp)->v_usecount > 0) && (*((volatile int *)(&(vp)->v_interlock))==0)) vput((vp)); else panic("hfs: vput bad ref cnt (%d)!", (vp)->v_usecount) ! 605: #define VRELE(vp) if (((vp)->v_usecount > 0) && (*((volatile int *)(&(vp)->v_interlock))==0)) vrele((vp)); else panic("hfs: vrele bad ref cnt (%d)!", (vp)->v_usecount) ! 606: ! 607: u_int32_t to_bsd_time(u_int32_t hfs_time); ! 608: u_int32_t to_hfs_time(u_int32_t bsd_time); ! 609: ! 610: int hfs_flushfiles(struct mount *mp, int flags); ! 611: short hfs_flushMDB(struct hfsmount *hfsmp, int waitfor); ! 612: short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor); ! 613: ! 614: short hfsLookup (ExtendedVCB *vcb, u_int32_t dirID, char *name, short len, hfsCatalogInfo *catInfo); ! 615: short hfsMoveRename (ExtendedVCB *vcb, u_int32_t oldDirID, char *oldName, u_int32_t newDirID, char *newName, u_int32_t *hint); ! 616: short hfsCreate (ExtendedVCB *vcb, u_int32_t dirID, char *name, int mode); ! 617: short hfsCreateFileID (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, u_int32_t catalogHint, u_int32_t *fileIDPtr); ! 618: short hfs_vcreate (ExtendedVCB *vcb, hfsCatalogInfo *catInfo, u_int8_t forkType, struct vnode **vpp); ! 619: short hfsDelete (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, short isfile, u_int32_t catalogHint); ! 620: short hfsUnmount(struct hfsmount *hfsmp, struct proc *p); ! 621: ! 622: extern int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flags, struct proc *p); ! 623: extern int hasOverflowExtents(struct hfsnode *hp); ! 624: ! 625: short MacToVFSError(OSErr err); ! 626: void MapFileOffset(struct hfsnode *hp, off_t filePosition, daddr_t *logBlockNumber, long *blockSize, long *blockOffset); ! 627: long LogicalBlockSize(struct hfsnode *hp, daddr_t logicalBlockNumber); ! 628: void UpdateBlockMappingTable(struct hfsnode *hp); ! 629: void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData); ! 630: void CopyCatalogToHFSNode(struct hfsCatalogInfo *catalogInfo, struct hfsnode *hp); ! 631: int bexpand(struct buf *bp, int newsize, struct buf **nbpp, long flags); ! 632: u_long FindMetaDataDirectory(ExtendedVCB *vcb); ! 633: ! 634: ! 635: short make_dir_entry(FCB **fileptr, char *name, u_int32_t fileID); ! 636: ! 637: int AttributeBlockSize(struct attrlist *attrlist); ! 638: void PackCommonAttributeBlock(struct attrlist *alist, ! 639: struct vnode *vp, ! 640: struct hfsCatalogInfo *catInfo, ! 641: void **attrbufptrptr, ! 642: void **varbufptrptr); ! 643: void PackVolAttributeBlock(struct attrlist *alist, ! 644: struct vnode *vp, ! 645: struct hfsCatalogInfo *catInfo, ! 646: void **attrbufptrptr, ! 647: void **varbufptrptr); ! 648: void PackFileDirAttributeBlock(struct attrlist *alist, ! 649: struct vnode *vp, ! 650: struct hfsCatalogInfo *catInfo, ! 651: void **attrbufptrptr, ! 652: void **varbufptrptr); ! 653: void PackForkAttributeBlock(struct attrlist *alist, ! 654: struct vnode *vp, ! 655: struct hfsCatalogInfo *catInfo, ! 656: void **attrbufptrptr, ! 657: void **varbufptrptr); ! 658: void PackAttributeBlock(struct attrlist *alist, ! 659: struct vnode *vp, ! 660: struct hfsCatalogInfo *catInfo, ! 661: void **attrbufptrptr, ! 662: void **varbufptrptr); ! 663: void PackCatalogInfoAttributeBlock (struct attrlist *alist, ! 664: struct vnode * root_vp, ! 665: struct hfsCatalogInfo *catInfo, ! 666: void **attrbufptrptr, ! 667: void **varbufptrptr); ! 668: void UnpackCommonAttributeBlock(struct attrlist *alist, ! 669: struct vnode *vp, ! 670: struct hfsCatalogInfo *catInfo, ! 671: void **attrbufptrptr, ! 672: void **varbufptrptr); ! 673: void UnpackAttributeBlock(struct attrlist *alist, ! 674: struct vnode *vp, ! 675: struct hfsCatalogInfo *catInfo, ! 676: void **attrbufptrptr, ! 677: void **varbufptrptr); ! 678: unsigned long BestBlockSizeFit(unsigned long allocationBlockSize, ! 679: unsigned long blockSizeLimit, ! 680: unsigned long baseMultiple); ! 681: ! 682: OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb, ! 683: u_long sectors, struct proc *p); ! 684: OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, ! 685: u_long embBlkOffset, u_long sectors, struct proc *p); ! 686: OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode ); ! 687: ! 688: int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode, ! 689: unicode_to_hfs_func_t *get_hfsname); ! 690: ! 691: int hfs_relconverter(u_int32_t encoding); ! 692: ! 693: int hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen, ! 694: ByteCount *actualDstLen, unsigned char* dstStr); ! 695: ! 696: int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr, ! 697: Str31 dstStr); ! 698: ! 699: #endif /* __HFS__ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.