2 * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
24 * (c) 1990, 1992 NeXT Computer, Inc. All Rights Reserved
25 * (c) 1997-1999 Apple Computer, Inc. All Rights Reserved
27 * hfs.h -- constants, structures, function declarations. etc.
28 * for Macintosh file system vfs.
35 #include <sys/param.h>
37 #include <sys/queue.h>
40 #include <sys/dirent.h>
42 #include <hfs/hfs_format.h>
43 #include <hfs/hfs_macos_defs.h>
44 #include <hfs/hfs_encodings.h>
45 #include <hfs/rangelist.h>
48 struct uio
; // This is more effective than #include <sys/uio.h> in case KERNEL is undefined...
49 struct hfslockf
; // For advisory locking
52 * Just reported via MIG interface.
54 #define VERSION_STRING "hfs-2 (4-12-99)"
56 #define HFS_LINK_MAX 32767
59 * Set to force READ_ONLY.
61 #define FORCE_READONLY 0
63 enum { kMDBSize
= 512 }; /* Size of I/O transfer to read entire MDB */
65 enum { kMasterDirectoryBlock
= 2 }; /* MDB offset on disk in 512-byte blocks */
66 enum { kMDBOffset
= kMasterDirectoryBlock
* 512 }; /* MDB offset on disk in bytes */
84 /* number of locked buffer caches to hold for b-tree meta data */
85 #define kMaxLockedMetaBuffers 32
88 * File type and creator for symbolic links
91 kSymLinkFileType
= 0x736C6E6B, /* 'slnk' */
92 kSymLinkCreator
= 0x72686170 /* 'rhap' */
95 #define BUFFERPTRLISTSIZE 25
97 extern char * gBufferAddress
[BUFFERPTRLISTSIZE
];
98 extern struct buf
*gBufferHeaderPtr
[BUFFERPTRLISTSIZE
];
99 extern int gBufferListIndex
;
100 extern simple_lock_data_t gBufferPtrListLock
;
102 extern struct timezone gTimeZone
;
104 /* Flag values for bexpand: */
105 #define RELEASE_BUFFER 0x00000001
108 /* How many free extents to cache per volume */
109 #define kMaxFreeExtents 10
111 /* Internal Data structures*/
114 u_int16_t vcbSigWord
;
121 u_int32_t vcbVolBkUp
;
122 u_int32_t checkedDate
; /* time of last disk check */
126 u_int32_t blockSize
; /* size of allocation blocks */
127 u_int32_t totalBlocks
; /* total allocation blocks */
128 u_int32_t freeBlocks
; /* free allocation blocks */
129 u_int32_t nextAllocation
; /* start of next allocation search */
131 u_int32_t vcbNxtCNID
;
132 u_int32_t vcbCNIDGen
;
135 int32_t vcbFndrInfo
[8];
137 u_int64_t encodingsBitmap
; /* HFS Plus only */
139 u_int16_t vcbNmFls
; /* HFS only */
140 u_int16_t vcbNmRtDirs
; /* HFS only */
141 int16_t vcbVBMSt
; /* HFS only */
142 int16_t vcbAlBlSt
; /* HFS only */
144 struct vnode
* extentsRefNum
;
145 struct vnode
* catalogRefNum
;
146 struct vnode
* allocationsRefNum
;
148 u_int8_t vcbVN
[256]; /* volume name in UTF-8 */
149 u_int32_t volumeNameEncodingHint
;
150 u_int32_t altIDSector
; /* location of alternate MDB/VH */
151 u_int32_t hfsPlusIOPosOffset
; /* Disk block where HFS+ starts */
152 u_int32_t vcbVBMIOSize
; /* volume bitmap I/O size */
153 char * hintCachePtr
; /* volume heuristicHint cache */
155 /* cache of largest known free extents */
156 u_int32_t vcbFreeExtCnt
;
157 HFSPlusExtentDescriptor vcbFreeExt
[kMaxFreeExtents
];
159 u_int32_t localCreateDate
; /* creation times for HFS+ volumes are in local time */
160 simple_lock_data_t vcbSimpleLock
; /* simple lock to allow concurrent access to vcb data */
162 typedef struct vcb_t ExtendedVCB
;
166 #define kHFS_DamagedVolume 0x1 /* This volume has errors, unmount dirty */
167 #define MARK_VOLUMEDAMAGED(fcb) FCBTOVCB((fcb))->vcbFlags |= kHFS_DamagedVolume;
171 * NOTE: The code relies on being able to cast an ExtendedVCB* to a vfsVCB* in order
172 * to gain access to the mount point pointer from a pointer
173 * to an ExtendedVCB. DO NOT INSERT OTHER FIELDS BEFORE THE vcb FIELD!!
175 * vcbFlags, vcbLsMod, vcbFilCnt, vcbDirCnt, vcbNxtCNID, etc
176 * are locked by the hfs_lock simple lock.
178 typedef struct vfsVCB
{
180 struct hfsmount
*vcb_hfsmp
; /* Pointer to hfsmount structure */
185 /* This structure describes the HFS specific mount structure data. */
186 typedef struct hfsmount
{
187 u_long hfs_mount_flags
;
188 u_int8_t hfs_fs_clean
; /* Whether contents have been flushed in clean state */
189 u_int8_t hfs_fs_ronly
; /* Whether this was mounted as read-initially */
190 u_int8_t hfs_unknownpermissions
; /* Whether this was mounted with MNT_UNKNOWNPERMISSIONS */
192 /* Physical Description */
193 u_long hfs_phys_block_count
; /* Num of PHYSICAL blocks of volume */
194 u_long hfs_phys_block_size
; /* Always a multiple of 512 */
196 /* Access to VFS and devices */
197 struct mount
*hfs_mp
; /* filesystem vfs structure */
198 struct vnode
*hfs_devvp
; /* block device mounted vnode */
199 dev_t hfs_raw_dev
; /* device mounted */
200 struct netexport hfs_export
; /* Export information */
201 u_int32_t hfs_logBlockSize
; /* Size of buffer cache buffer for I/O */
203 /* Default values for HFS standard and non-init access */
204 uid_t hfs_uid
; /* uid to set as owner of the files */
205 gid_t hfs_gid
; /* gid to set as owner of the files */
206 mode_t hfs_dir_mask
; /* mask to and with directory protection bits */
207 mode_t hfs_file_mask
; /* mask to and with file protection bits */
208 u_long hfs_encoding
; /* Defualt encoding for non hfs+ volumes */
210 /* simple lock for shared meta renaming */
211 simple_lock_data_t hfs_renamelock
;
214 struct vfsVCB hfs_vcb
;
215 u_long hfs_private_metadata_dir
; /* private/hidden directory for unlinked files */
216 u_int32_t hfs_metadata_createdate
;
217 hfs_to_unicode_func_t hfs_get_unicode
;
218 unicode_to_hfs_func_t hfs_get_hfsname
;
221 #define HFSPLUS_PRIVATE_DIR \
222 "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data"
225 /*****************************************************************************
231 *****************************************************************************/
233 #define MAXHFSVNODELEN 31
234 typedef u_char FileNameStr
[MAXHFSVNODELEN
+1];
236 CIRCLEQ_HEAD(siblinghead
, hfsnode
) ; /* Head of the sibling list */
240 LIST_ENTRY(hfsnode
) h_hash
; /* links on valid files */
241 CIRCLEQ_ENTRY(hfsnode
) h_sibling
; /* links on siblings */
242 struct lock__bsd__ h_lock
; /* node lock. */
244 struct hfslockf
*hu_lockf
; /* Head of byte-level lock list. */
245 void *hu_sysdata
; /* private data for system files */
246 char hu_symlinkdata
[4]; /* symbolic link (4 chars or less) */
247 char *hu_symlinkptr
; /* symbolic link pathname */
249 struct vnode
* h_vp
; /* vnode associated with this inode. */
250 struct hfsfilemeta
* h_meta
; /* Ptr to file meta data */
251 u_int16_t h_nodeflags
; /* flags, see below */
252 u_int8_t h_type
; /* Type of info: dir, data, rsrc */
253 int8_t fcbFlags
; /* FCB flags */
254 struct rl_head h_invalidranges
;/* Areas of disk that should read back as zeroes */
255 u_int64_t fcbEOF
; /* Logical length or EOF in bytes */
256 u_int64_t fcbPLen
; /* Physical file length in bytes */
257 u_int32_t fcbClmpSize
; /* Number of bytes per clump */
258 HFSPlusExtentRecord fcbExtents
; /* Extents of file */
261 u_int32_t h_valid
; /* is the vnode reference valid */
264 #define h_lockf h_un.hu_lockf
265 #define fcbBTCBPtr h_un.hu_sysdata
266 #define h_symlinkptr h_un.hu_symlinkptr
267 #define h_symlinkdata h_un.hu_symlinkdata
269 typedef struct hfsnode FCB
;
272 typedef struct hfsfilemeta
{
273 struct siblinghead h_siblinghead
; /* Head of the sibling list */
274 simple_lock_data_t h_siblinglock
; /* sibling list lock. */
275 u_int32_t h_metaflags
; /* IN_LONGNAME, etc */
276 struct vnode
*h_devvp
; /* vnode for block I/O. */
278 dev_t h_dev
; /* Device associated with the inode. */
279 u_int32_t h_nodeID
; /* specific id of this node */
280 u_int32_t h_dirID
; /* Parent Directory ID */
281 u_int32_t h_hint
; /* Catalog hint */
283 off_t h_size
; /* Total physical size of object */
284 u_int16_t h_usecount
; /* How many siblings */
285 u_int16_t h_mode
; /* IFMT, permissions; see below. */
286 u_int32_t h_pflags
; /* Permission flags (NODUMP, IMMUTABLE, APPEND etc.) */
287 u_int32_t h_uid
; /* File owner. */
288 u_int32_t h_gid
; /* File group. */
290 dev_t hu_rdev
; /* Special device info for this node */
291 u_int32_t hu_indnodeno
; /* internal indirect node number (never exported) */
293 u_int32_t h_crtime
; /* BSD-format creation date in secs. */
294 u_int32_t h_atime
; /* BSD-format access date in secs. */
295 u_int32_t h_mtime
; /* BSD-format mod date in seconds */
296 u_int32_t h_ctime
; /* BSD-format status change date */
297 u_int32_t h_butime
; /* BSD-format last backup date in secs. */
298 u_int16_t h_nlink
; /* link count (aprox. for dirs) */
299 u_short h_namelen
; /* Length of name string */
300 char * h_namePtr
; /* Points the name of the file */
301 FileNameStr h_fileName
; /* CName of file */
303 #define h_rdev h_spun.hu_rdev
304 #define h_indnodeno h_spun.hu_indnodeno
306 #define H_EXTENDSIZE(VP,BYTES) ((VP)->h_meta->h_size += (BYTES))
307 #define H_TRUNCSIZE(VP,BYTES) ((VP)->h_meta->h_size -= (BYTES))
309 #define MAKE_INODE_NAME(name,linkno) \
310 (void) sprintf((name), "%s%d", HFS_INODE_PREFIX, (linkno))
314 * Macros for quick access to fields buried in the fcb inside an hfs node:
316 #define H_FORKTYPE(HP) ((HP)->h_type)
317 #define H_FILEID(HP) ((HP)->h_meta->h_nodeID)
318 #define H_DIRID(HP) ((HP)->h_meta->h_dirID)
319 #define H_NAME(HP) ((HP)->h_meta->h_namePtr)
320 #define H_HINT(HP) ((HP)->h_meta->h_hint)
321 #define H_DEV(HP) ((HP)->h_meta->h_dev)
323 #define H_ISBIGLINK(HP) ((HP)->fcbEOF > 4)
324 #define H_SYMLINK(HP) (H_ISBIGLINK((HP)) ? (HP)->h_symlinkptr : (HP)->h_symlinkdata)
326 /* These flags are kept in flags. */
327 #define IN_ACCESS 0x0001 /* Access time update request. */
328 #define IN_CHANGE 0x0002 /* Change time update request. */
329 #define IN_UPDATE 0x0004 /* Modification time update request. */
330 #define IN_MODIFIED 0x0008 /* Node has been modified. */
331 #define IN_RENAME 0x0010 /* Node is being renamed. */
332 #define IN_SHLOCK 0x0020 /* File has shared lock. */
333 #define IN_EXLOCK 0x0040 /* File has exclusive lock. */
334 #define IN_BYCNID 0x0100 /* Dir was found by CNID */
335 #define IN_ALLOCATING 0x1000 /* vnode is in transit, wait or ignore */
336 #define IN_WANT 0x2000 /* Its being waited for */
338 /* These flags are kept in meta flags. */
339 #define IN_LONGNAME 0x0400 /* File has long name buffer. */
340 #define IN_UNSETACCESS 0x0200 /* File has unset access. */
341 #define IN_DELETED 0x0800 /* File has been marked to be deleted */
342 #define IN_NOEXISTS 0x1000 /* File has been deleted, catalog entry is gone */
344 #define IN_DATANODE 0x2000 /* File is a data node (hard-linked) */
348 /* File permissions stored in mode */
349 #define IEXEC 0000100 /* Executable. */
350 #define IWRITE 0000200 /* Writeable. */
351 #define IREAD 0000400 /* Readable. */
352 #define ISVTX 0001000 /* Sticky bit. */
353 #define ISGID 0002000 /* Set-gid. */
354 #define ISUID 0004000 /* Set-uid. */
357 #define IFMT 0170000 /* Mask of file type. */
358 #define IFIFO 0010000 /* Named pipe (fifo). */
359 #define IFCHR 0020000 /* Character device. */
360 #define IFDIR 0040000 /* Directory file. */
361 #define IFBLK 0060000 /* Block device. */
362 #define IFREG 0100000 /* Regular file. */
363 #define IFLNK 0120000 /* Symbolic link. */
364 #define IFSOCK 0140000 /* UNIX domain socket. */
365 #define IFWHT 0160000 /* Whiteout. */
367 /* Value to make sure vnode is real and defined */
368 #define HFS_VNODE_MAGIC 0x4846532b /* 'HFS+' */
370 /* To test wether the forkType is a sibling type */
371 #define SIBLING_FORKTYPE(FORK) ((FORK==kDataFork) || (FORK==kRsrcFork))
376 #define WRITE_CK(VNODE, FUNC_NAME) { \
377 if ((VNODE)->v_mount->mnt_flag & MNT_RDONLY) { \
378 DBG_ERR(("%s: ATTEMPT TO WRITE A READONLY VOLUME\n", \
386 * hfsmount locking and unlocking.
390 #define MVL_LOCKED 0x00000001 /* debug only */
393 #define MVL_LOCK(mvip) { \
394 (simple_lock(&(mvip)->mvl_lock)); \
395 (mvip)->mvl_flags |= MVL_LOCKED; \
398 #define MVL_UNLOCK(mvip) { \
399 if(((mvip)->mvl_flags & MVL_LOCKED) == 0) { \
400 panic("MVL_UNLOCK - hfsnode not locked"); \
402 (simple_unlock(&(mvip)->mvl_lock)); \
403 (mvip)->mvl_flags &= ~MVL_LOCKED; \
405 #else /* HFS_DIAGNOSTIC */
406 #define MVL_LOCK(mvip) (simple_lock(&(mvip)->mvl_lock))
407 #define MVL_UNLOCK(mvip) (simple_unlock(&(mvip)->mvl_lock))
408 #endif /* HFS_DIAGNOSTIC */
411 /* structure to hold a "." or ".." directory entry (12 bytes) */
412 typedef struct hfsdotentry
{
413 u_int32_t d_fileno
; /* unique file number */
414 u_int16_t d_reclen
; /* length of this structure */
415 u_int8_t d_type
; /* dirent file type */
416 u_int8_t d_namelen
; /* len of filename */
417 char d_name
[4]; /* "." or ".." */
420 #define AVERAGE_HFSDIRENTRY_SIZE (8+22+4)
421 #define MAX_HFSDIRENTRY_SIZE sizeof(struct dirent)
423 #define DIRENTRY_SIZE(namlen) \
424 ((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3))
427 kCatNameIsAllocated
= 0x1, /* The name is malloc'd and is in cnm_nameptr */
428 kCatNameIsMangled
= 0x2, /* The name is mangled */
429 kCatNameUsesReserved
= 0x4, /* It overides the space reserved by cnm_namespace into cndu_extra, careful */
430 kCatNameIsConsumed
= 0x8, /* The name has been already processed, no freeing or work is needed */
431 kCatNameNoCopyName
= 0x10, /* Dont copy the name */
432 kCatNameMangleName
= 0x20 /* Mangle name if greater than passed in length */
436 * CatalogNameSpecifier is a structure that contains a name and possibly its form
438 * Special care needs to be taken with the flags, they can cause side effects.
440 struct CatalogNameSpecifier
{
441 u_int16_t cnm_flags
; /* See above */
442 u_int16_t cnm_length
; /* Length of the name */
443 u_int32_t cnm_parID
; /* ID of the parent directory */
444 unsigned char *cnm_nameptr
; /* If allocated, a ptr to the space, else NULL */
445 unsigned char cnm_namespace
[MAXHFSVNODELEN
+1]; /* Space where the name can be kept */
448 * NOTE IT IS REQUIRED that KMaxMangleNameLen >= MAXHFSVNODELEN
449 * Also the total size of CatalogNameSpecifier should be less then cndu_extra, which
450 * currently it easily is, this is not a requirement, just a nicety.
452 * The rules to how to store a name:
453 * If its less than MAXHFSVNODELEN always store it in cnm_namespace.
454 * If we can get by doing mangling then cnm_namespace
455 * else allocate the space needed to cnm_nameptr.
456 * This reflects what is done at vnode creation.
461 kCatalogFolderNode
= 1,
466 * CatalogNodeData has same layout as the on-disk HFS Plus file/dir records.
467 * Classic hfs file/dir records are converted to match this layout.
469 * The cnd_extra padding allows big hfs plus thread records (520 bytes max)
470 * to be read onto this stucture during a cnid lookup.
473 * After declaring this structure, you must use the macro INIT_CATALOGDATA to prepare it
474 * and CLEAN_CATALOGDATA after using it, to clean any allocated structures.
476 * If you do not need to have the name, then pass in kCatNameNoCopyName for flags
478 struct CatalogNodeData
{
481 u_int32_t cnd_valence
; /* dirs only */
482 u_int32_t cnd_nodeID
;
483 u_int32_t cnd_createDate
;
484 u_int32_t cnd_contentModDate
;
485 u_int32_t cnd_attributeModDate
;
486 u_int32_t cnd_accessDate
;
487 u_int32_t cnd_backupDate
;
488 u_int32_t cnd_ownerID
;
489 u_int32_t cnd_groupID
;
490 u_int8_t cnd_adminFlags
; /* super-user changeable flags */
491 u_int8_t cnd_ownerFlags
; /* owner changeable flags */
492 u_int16_t cnd_mode
; /* file type + permission bits */
494 u_int32_t cndu_iNodeNum
; /* indirect links only */
495 u_int32_t cndu_linkCount
; /* indirect nodes only */
496 u_int32_t cndu_rawDevice
; /* special files (FBLK and FCHR) only */
498 u_int8_t cnd_finderInfo
[32];
499 u_int32_t cnd_textEncoding
;
500 u_int32_t cnd_reserved
;
501 HFSPlusForkData cnd_datafork
;
502 HFSPlusForkData cnd_rsrcfork
;
503 u_int32_t cnd_iNodeNumCopy
;
504 u_int32_t cnd_linkCNID
; /* for hard links only */
505 u_int8_t cnd_extra
[264]; /* make struct at least 520 bytes long */
506 struct CatalogNameSpecifier cnd_namespecifier
;
508 typedef struct CatalogNodeData CatalogNodeData
;
510 #define cnd_iNodeNum cnd_un.cndu_iNodeNum
511 #define cnd_linkCount cnd_un.cndu_linkCount
512 #define cnd_rawDevice cnd_un.cndu_rawDevice
514 #define cnm_flags cnd_namespecifier.cnm_flags
515 #define cnm_length cnd_namespecifier.cnm_length
516 #define cnm_parID cnd_namespecifier.cnm_parID
517 #define cnm_nameptr cnd_namespecifier.cnm_nameptr
518 #define cnm_namespace cnd_namespecifier.cnm_namespace
520 #define INIT_CATALOGDATA(C,F) do { bzero(&((C)->cnd_namespecifier), sizeof(struct CatalogNameSpecifier)); (C)->cnm_flags=(F);}while(0);
522 extern void debug_check_catalogdata(struct CatalogNodeData
*cat
);
523 #define CLEAN_CATALOGDATA(C) do { debug_check_catalogdata(C); \
524 if ((C)->cnm_flags & kCatNameIsAllocated) {\
525 FREE((C)->cnm_nameptr, M_TEMP);\
526 (C)->cnm_flags &= ~kCatNameIsAllocated;\
527 (C)->cnm_nameptr = NULL;\
530 #define CLEAN_CATALOGDATA(C) do { if ((C)->cnm_flags & kCatNameIsAllocated) {\
531 FREE((C)->cnm_nameptr, M_TEMP);\
532 (C)->cnm_flags &= ~kCatNameIsAllocated;\
533 (C)->cnm_nameptr = NULL;\
537 /* structure to hold a catalog record information */
538 /* Of everything you wanted to know about a catalog entry, file and directory */
539 typedef struct hfsCatalogInfo
{
540 CatalogNodeData nodeData
;
544 enum { kHFSPlusMaxFileNameBytes
= kHFSPlusMaxFileNameChars
* 3 };
546 enum { kdirentMaxNameBytes
= NAME_MAX
};
548 // structure definition of the searchfs system trap for the search criterea.
549 struct directoryInfoSpec
556 off_t dataLogicalLength
;
557 off_t dataPhysicalLength
;
558 off_t resourceLogicalLength
;
559 off_t resourcePhysicalLength
;
562 struct searchinfospec
564 u_char name
[kHFSPlusMaxFileNameBytes
];
566 char attributes
; // see IM:Files 2-100
569 struct timespec creationDate
;
570 struct timespec modificationDate
;
571 struct timespec changeDate
;
572 struct timespec lastBackupDate
;
573 u_long finderInfo
[8];
577 struct fileInfoSpec f
;
578 struct directoryInfoSpec d
;
580 typedef struct searchinfospec searchinfospec_t
;
582 #define HFSTIMES(hp, t1, t2) { \
583 if ((hp)->h_nodeflags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
584 (hp)->h_nodeflags |= IN_MODIFIED; \
585 if ((hp)->h_nodeflags & IN_ACCESS) { \
586 (hp)->h_meta->h_atime = (t1)->tv_sec; \
588 if ((hp)->h_nodeflags & IN_UPDATE) { \
589 (hp)->h_meta->h_mtime = (t2)->tv_sec; \
591 if ((hp)->h_nodeflags & IN_CHANGE) { \
592 (hp)->h_meta->h_ctime = time.tv_sec; \
594 (hp)->h_nodeflags &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
598 /* This overlays the fid structure (see mount.h). */
600 u_int16_t hfsfid_len
; /* Length of structure. */
601 u_int16_t hfsfid_pad
; /* Force 32-bit alignment. */
602 /* The following data is filesystem-dependent, up to MAXFIDSZ (16) bytes: */
603 u_int32_t hfsfid_cnid
; /* Catalog node ID. */
604 u_int32_t hfsfid_gen
; /* Generation number (create date). */
607 /* macro to determine if hfs or hfsplus */
608 #define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord)
609 #define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord)
613 * Various ways to acquire a VNode pointer:
615 #define HTOV(HP) ((HP)->h_vp)
618 * Various ways to acquire an HFS Node pointer:
620 #define VTOH(VP) ((struct hfsnode *)((VP)->v_data))
621 #define FCBTOH(FCB) ((struct hfsnode *)FCB)
624 * Various ways to acquire an FCB pointer:
626 #define HTOFCB(HP) (HP)
627 #define VTOFCB(VP) ((FCB *)((VP)->v_data)) /* Should be the same as VTOH */
630 * Various ways to acquire a VFS mount point pointer:
632 #define VTOVFS(VP) ((VP)->v_mount)
633 #define HTOVFS(HP) ((HP)->h_vp->v_mount)
634 #define FCBTOVFS(FCB) ((FCB)->h_vp->v_mount)
635 #define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp)
636 #define VCBTOVFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp->hfs_mp)
639 * Various ways to acquire an HFS mount point pointer:
641 #define VTOHFS(VP) ((struct hfsmount *)((VP)->v_mount->mnt_data))
642 #define HTOHFS(HP) ((struct hfsmount *)(HP)->h_vp->v_mount->mnt_data)
643 #define FCBTOHFS(FCB) ((struct hfsmount *)(FCB)->h_vp->v_mount->mnt_data)
644 #define VFSTOHFS(MP) ((struct hfsmount *)(MP)->mnt_data)
645 #define VCBTOHFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp)
648 * Various ways to acquire a VCB pointer:
650 #define VTOVCB(VP) (&(((struct hfsmount *)((VP)->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
651 #define HTOVCB(HP) (&(((struct hfsmount *)((HP)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
652 #define FCBTOVCB(FCB) (&(((struct hfsmount *)((FCB)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
653 #define VFSTOVCB(MP) (&(((struct hfsmount *)(MP)->mnt_data)->hfs_vcb.vcb_vcb))
654 #define HFSTOVCB(HFSMP) (&(HFSMP)->hfs_vcb.vcb_vcb)
658 #define kHFSBlockSize 512
660 #define IOBLKNOFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBLOCK) / ((BLOCKSIZEINBYTES) >> 9)))
661 #define IOBLKCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
662 ((int)(IOBLKNOFORBYTE(((STARTINGBLOCK) * 512) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \
663 IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) + 1))
664 #define IOBYTECCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
665 (IOBLKCNTFORBLK((STARTINGBLOCK),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))
666 #define IOBYTEOFFSETFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) \
667 (((STARTINGBLOCK) * 512) - \
668 (IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)))
670 #define IOBLKNOFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBYTE) / (BLOCKSIZEINBYTES)))
671 #define IOBLKCNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
672 ((int)(IOBLKNOFORBYTE((STARTINGBYTE) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \
673 IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) + 1))
674 #define IOBYTECNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
675 (IOBLKCNTFORBYTE((STARTINGBYTE),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))
676 #define IOBYTEOFFSETFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((STARTINGBYTE) - (IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)))
679 #define HFS_PRI_SECTOR(blksize) (1024 / (blksize))
680 #define HFS_PRI_OFFSET(blksize) ((blksize) > 1024 ? 1024 : 0)
682 #define HFS_ALT_SECTOR(blksize, blkcnt) (((blkcnt) - 1) - (512 / (blksize)))
683 #define HFS_ALT_OFFSET(blksize) ((blksize) > 1024 ? (blksize) - 1024 : 0)
685 #define MAKE_VREFNUM(x) ((int32_t)((x) & 0xffff))
687 * This is the straight GMT conversion constant:
688 * 00:00:00 January 1, 1970 - 00:00:00 January 1, 1904
689 * (3600 * 24 * ((365 * (1970 - 1904)) + (((1970 - 1904) / 4) + 1)))
691 #define MAC_GMT_FACTOR 2082844800UL
693 #define HFS_ATTR_CMN_LOOKUPMASK (ATTR_CMN_SCRIPT | ATTR_CMN_FNDRINFO | ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)
694 #define HFS_ATTR_DIR_LOOKUPMASK (ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT)
695 #define HFS_ATTR_FILE_LOOKUPMASK (ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | ATTR_FILE_ALLOCSIZE | \
696 ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_DATAEXTENTS | \
697 ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE | ATTR_FILE_RSRCEXTENTS)
699 u_int32_t
to_bsd_time(u_int32_t hfs_time
);
700 u_int32_t
to_hfs_time(u_int32_t bsd_time
);
702 int hfs_flushfiles(struct mount
*mp
, int flags
);
703 short hfs_flushMDB(struct hfsmount
*hfsmp
, int waitfor
);
704 short hfs_flushvolumeheader(struct hfsmount
*hfsmp
, int waitfor
);
706 short hfs_getcatalog (ExtendedVCB
*vcb
, u_int32_t dirID
, char *name
, short len
, hfsCatalogInfo
*catInfo
);
707 short hfsMoveRename (ExtendedVCB
*vcb
, u_int32_t oldDirID
, char *oldName
, u_int32_t newDirID
, char *newName
, u_int32_t
*hint
);
708 short hfsCreate (ExtendedVCB
*vcb
, u_int32_t dirID
, char *name
, int mode
, u_int32_t tehint
);
709 short hfsCreateFileID (ExtendedVCB
*vcb
, u_int32_t parentDirID
, StringPtr name
, u_int32_t catalogHint
, u_int32_t
*fileIDPtr
);
710 short hfs_vcreate (ExtendedVCB
*vcb
, hfsCatalogInfo
*catInfo
, u_int8_t forkType
, struct vnode
**vpp
);
711 short hfsDelete (ExtendedVCB
*vcb
, u_int32_t parentDirID
, StringPtr name
, short isfile
, u_int32_t catalogHint
);
712 short hfsUnmount(struct hfsmount
*hfsmp
, struct proc
*p
);
714 extern int hfs_metafilelocking(struct hfsmount
*hfsmp
, u_long fileID
, u_int flags
, struct proc
*p
);
715 extern int hasOverflowExtents(struct hfsnode
*hp
);
717 void hfs_set_metaname(char *, struct hfsfilemeta
*, struct hfsmount
*);
719 short MacToVFSError(OSErr err
);
720 int hfs_owner_rights(struct vnode
*vp
, struct ucred
*cred
, struct proc
*p
, Boolean invokesuperuserstatus
);
722 void CopyVNodeToCatalogNode (struct vnode
*vp
, struct CatalogNodeData
*nodeData
);
723 void CopyCatalogToHFSNode(struct hfsCatalogInfo
*catalogInfo
, struct hfsnode
*hp
);
724 u_long
FindMetaDataDirectory(ExtendedVCB
*vcb
);
727 short make_dir_entry(FCB
**fileptr
, char *name
, u_int32_t fileID
);
729 int AttributeBlockSize(struct attrlist
*attrlist
);
730 void PackCommonAttributeBlock(struct attrlist
*alist
,
732 struct hfsCatalogInfo
*catInfo
,
733 void **attrbufptrptr
,
734 void **varbufptrptr
);
735 void PackVolAttributeBlock(struct attrlist
*alist
,
737 struct hfsCatalogInfo
*catInfo
,
738 void **attrbufptrptr
,
739 void **varbufptrptr
);
740 void PackFileDirAttributeBlock(struct attrlist
*alist
,
742 struct hfsCatalogInfo
*catInfo
,
743 void **attrbufptrptr
,
744 void **varbufptrptr
);
745 void PackForkAttributeBlock(struct attrlist
*alist
,
747 struct hfsCatalogInfo
*catInfo
,
748 void **attrbufptrptr
,
749 void **varbufptrptr
);
750 void PackAttributeBlock(struct attrlist
*alist
,
752 struct hfsCatalogInfo
*catInfo
,
753 void **attrbufptrptr
,
754 void **varbufptrptr
);
755 void PackCatalogInfoAttributeBlock (struct attrlist
*alist
,
756 struct vnode
* root_vp
,
757 struct hfsCatalogInfo
*catInfo
,
758 void **attrbufptrptr
,
759 void **varbufptrptr
);
760 void UnpackCommonAttributeBlock(struct attrlist
*alist
,
762 struct hfsCatalogInfo
*catInfo
,
763 void **attrbufptrptr
,
764 void **varbufptrptr
);
765 void UnpackAttributeBlock(struct attrlist
*alist
,
767 struct hfsCatalogInfo
*catInfo
,
768 void **attrbufptrptr
,
769 void **varbufptrptr
);
770 unsigned long BestBlockSizeFit(unsigned long allocationBlockSize
,
771 unsigned long blockSizeLimit
,
772 unsigned long baseMultiple
);
774 OSErr
hfs_MountHFSVolume(struct hfsmount
*hfsmp
, HFSMasterDirectoryBlock
*mdb
,
776 OSErr
hfs_MountHFSPlusVolume(struct hfsmount
*hfsmp
, HFSPlusVolumeHeader
*vhp
,
777 off_t embeddedOffset
, off_t disksize
, struct proc
*p
);
778 OSStatus
GetInitializedVNode(struct hfsmount
*hfsmp
, struct vnode
**tmpvnode
);
780 int hfs_getconverter(u_int32_t encoding
, hfs_to_unicode_func_t
*get_unicode
,
781 unicode_to_hfs_func_t
*get_hfsname
);
783 int hfs_relconverter(u_int32_t encoding
);
785 int hfs_to_utf8(ExtendedVCB
*vcb
, Str31 hfs_str
, ByteCount maxDstLen
,
786 ByteCount
*actualDstLen
, unsigned char* dstStr
);
788 int utf8_to_hfs(ExtendedVCB
*vcb
, ByteCount srcLen
, const unsigned char* srcStr
,
791 int mac_roman_to_utf8(Str31 hfs_str
, ByteCount maxDstLen
, ByteCount
*actualDstLen
,
792 unsigned char* dstStr
);
794 int utf8_to_mac_roman(ByteCount srcLen
, const unsigned char* srcStr
, Str31 dstStr
);
796 u_int32_t
hfs_pickencoding(const u_int16_t
*src
, int len
);