]> git.saurik.com Git - apple/xnu.git/blob - bsd/hfs/hfs.h
9c5b866e90b9e8a0b9fda590d30c420b621beb3e
[apple/xnu.git] / bsd / hfs / hfs.h
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 #define HFS_LINK_MAX 32767
83
84 /*
85 * Set to force READ_ONLY.
86 */
87 #define FORCE_READONLY 0
88
89 enum { kMDBSize = 512 }; /* Size of I/O transfer to read entire MDB */
90
91 enum { kMasterDirectoryBlock = 2 }; /* MDB offset on disk in 512-byte blocks */
92 enum { kMDBOffset = kMasterDirectoryBlock * 512 }; /* MDB offset on disk in bytes */
93
94 enum {
95 kUnknownID = 0,
96 kRootParID = 1,
97 kRootDirID = 2
98 };
99
100 enum {
101 kUndefinedFork = 0,
102 kAnyFork,
103 kDataFork,
104 kRsrcFork,
105 kDirectory,
106 kSysFile,
107 kDefault
108 };
109
110
111 /*
112 * File type and creator for symbolic links
113 */
114 enum {
115 kSymLinkFileType = 0x736C6E6B, /* 'slnk' */
116 kSymLinkCreator = 0x72686170 /* 'rhap' */
117 };
118
119 #define BUFFERPTRLISTSIZE 25
120
121 extern char * gBufferAddress[BUFFERPTRLISTSIZE];
122 extern struct buf *gBufferHeaderPtr[BUFFERPTRLISTSIZE];
123 extern int gBufferListIndex;
124 extern simple_lock_data_t gBufferPtrListLock;
125
126 extern struct timezone gTimeZone;
127
128 /* Flag values for bexpand: */
129 #define RELEASE_BUFFER 0x00000001
130
131
132 /* Internal Data structures*/
133
134 struct vcb_t {
135 int16_t vcbFlags;
136 u_int16_t vcbSigWord;
137 u_int32_t vcbCrDate;
138 u_int32_t vcbLsMod;
139 int16_t vcbAtrb;
140 u_int16_t vcbNmFls; /* HFS only */
141 int16_t vcbVBMSt;
142 int16_t vcbAlBlSt;
143 int32_t vcbClpSiz;
144 u_int32_t vcbNxtCNID;
145 u_int8_t vcbVN[256];
146 int16_t vcbVRefNum;
147 u_int16_t vcbVSeqNum;
148 u_int32_t vcbVolBkUp;
149 int32_t vcbWrCnt;
150 u_int16_t vcbNmRtDirs; /* HFS only */
151 u_int16_t vcbReserved;
152 int32_t vcbFilCnt;
153 int32_t vcbDirCnt;
154 int32_t vcbFndrInfo[8];
155 struct vnode * extentsRefNum;
156 struct vnode * catalogRefNum;
157 struct vnode * allocationsRefNum;
158 u_int32_t blockSize; /* size of allocation blocks - vcbAlBlkSiz*/
159 u_int32_t totalBlocks; /* number of allocation blocks in volume */
160 u_int32_t freeBlocks; /* number of unused allocation blocks - vcbFreeBks*/
161 u_int32_t nextAllocation; /* start of next allocation search - vcbAllocPtr*/
162 u_int32_t altIDSector; /* location of alternate MDB/VH */
163 u_int32_t hfsPlusIOPosOffset; /* Disk block where HFS+ starts */
164 u_int32_t checkedDate; /* date and time of last disk check */
165 u_int64_t encodingsBitmap; /* HFS Plus only*/
166 u_int32_t volumeNameEncodingHint; /* Text encoding used for volume name*/
167 char * hintCachePtr; /* points to this volumes heuristicHint cache*/
168 u_int32_t localCreateDate; /* creation times for HFS+ volumes are in local time */
169 simple_lock_data_t vcbSimpleLock; /* simple lock to allow concurrent access to vcb data */
170 };
171 typedef struct vcb_t ExtendedVCB;
172
173 /* vcbFlags */
174 #define kHFS_DamagedVolume 0x1 /* This volume has errors, unmount dirty */
175 #define MARK_VOLUMEDAMAGED(fcb) FCBTOVCB((fcb))->vcbFlags |= kHFS_DamagedVolume;
176
177
178 /*
179 * NOTE: The code relies on being able to cast an ExtendedVCB* to a vfsVCB* in order
180 * to gain access to the mount point pointer from a pointer
181 * to an ExtendedVCB. DO NOT INSERT OTHER FIELDS BEFORE THE vcb FIELD!!
182 *
183 * vcbFlags, vcbLsMod, vcbFilCnt, vcbDirCnt, vcbNxtCNID, etc
184 * are locked by the hfs_lock simple lock.
185 */
186 typedef struct vfsVCB {
187 ExtendedVCB vcb_vcb;
188 struct hfsmount *vcb_hfsmp; /* Pointer to hfsmount structure */
189 } vfsVCB_t;
190
191
192
193 /* This structure describes the HFS specific mount structure data. */
194 typedef struct hfsmount {
195 u_long hfs_mount_flags;
196 u_int8_t hfs_fs_clean; /* Whether contents have been flushed in clean state */
197 u_int8_t hfs_fs_ronly; /* Whether this was mounted as read-initially */
198 u_int8_t hfs_unknownpermissions; /* Whether this was mounted with MNT_UNKNOWNPERMISSIONS */
199
200 /* Physical Description */
201 u_long hfs_phys_block_count; /* Num of PHYSICAL blocks of volume */
202 u_long hfs_phys_block_size; /* Always a multiple of 512 */
203
204 /* Access to VFS and devices */
205 struct mount *hfs_mp; /* filesystem vfs structure */
206 struct vnode *hfs_devvp; /* block device mounted vnode */
207 dev_t hfs_raw_dev; /* device mounted */
208 struct netexport hfs_export; /* Export information */
209 u_int32_t hfs_logBlockSize; /* Size of buffer cache buffer for I/O */
210
211 /* Default values for HFS standard and non-init access */
212 uid_t hfs_uid; /* uid to set as owner of the files */
213 gid_t hfs_gid; /* gid to set as owner of the files */
214 mode_t hfs_dir_mask; /* mask to and with directory protection bits */
215 mode_t hfs_file_mask; /* mask to and with file protection bits */
216 u_long hfs_encoding; /* Defualt encoding for non hfs+ volumes */
217
218 /* simple lock for shared meta renaming */
219 simple_lock_data_t hfs_renamelock;
220
221 /* HFS Specific */
222 struct vfsVCB hfs_vcb;
223 u_long hfs_private_metadata_dir; /* private/hidden directory for unlinked files */
224 u_int32_t hfs_metadata_createdate;
225 hfs_to_unicode_func_t hfs_get_unicode;
226 unicode_to_hfs_func_t hfs_get_hfsname;
227 } hfsmount_t;
228
229
230 /*****************************************************************************
231 *
232 * hfsnode structure
233 *
234 *
235 *
236 *****************************************************************************/
237
238 #define MAXHFSVNODELEN 31
239 typedef u_char FileNameStr[MAXHFSVNODELEN+1];
240
241 CIRCLEQ_HEAD(siblinghead, hfsnode) ; /* Head of the sibling list */
242
243
244 struct hfsnode {
245 LIST_ENTRY(hfsnode) h_hash; /* links on valid files */
246 CIRCLEQ_ENTRY(hfsnode) h_sibling; /* links on siblings */
247 struct lock__bsd__ h_lock; /* node lock. */
248 union {
249 struct hfslockf *hu_lockf; /* Head of byte-level lock list. */
250 void *hu_sysdata; /* private data for system files */
251 } h_un;
252 struct vnode * h_vp; /* vnode associated with this inode. */
253 struct hfsfilemeta * h_meta; /* Ptr to file meta data */
254 u_int16_t h_nodeflags; /* flags, see below */
255 u_int8_t h_type; /* Type of info: dir, data, rsrc */
256 int8_t fcbFlags; /* FCB flags */
257 u_int64_t fcbEOF; /* Logical length or EOF in bytes */
258 u_int64_t fcbPLen; /* Physical file length in bytes */
259 u_int64_t fcbMaxEOF; /* Maximum logical length or EOF in bytes */
260 u_int32_t fcbClmpSize; /* Number of bytes per clump */
261 HFSPlusExtentRecord fcbExtents; /* Extents of file */
262
263 #if HFS_DIAGNOSTIC
264 u_int32_t h_valid; /* is the vnode reference valid */
265 #endif
266 };
267 #define h_lockf h_un.hu_lockf
268 #define fcbBTCBPtr h_un.hu_sysdata
269
270 typedef struct hfsnode FCB;
271
272
273 typedef struct hfsfilemeta {
274 struct siblinghead h_siblinghead; /* Head of the sibling list */
275 simple_lock_data_t h_siblinglock; /* sibling list lock. */
276 u_int32_t h_metaflags; /* IN_LONGNAME, etc */
277 struct vnode *h_devvp; /* vnode for block I/O. */
278
279 dev_t h_dev; /* Device associated with the inode. */
280 u_int32_t h_nodeID; /* specific id of this node */
281 u_int32_t h_dirID; /* Parent Directory ID */
282 u_int32_t h_hint; /* Catalog hint */
283
284 off_t h_size; /* Total physical size of object */
285 u_int16_t h_usecount; /* How many siblings */
286 u_int16_t h_mode; /* IFMT, permissions; see below. */
287 u_int32_t h_pflags; /* Permission flags (NODUMP, IMMUTABLE, APPEND etc.) */
288 u_int32_t h_uid; /* File owner. */
289 u_int32_t h_gid; /* File group. */
290 union {
291 dev_t hu_rdev; /* Special device info for this node */
292 u_int32_t hu_indnodeno; /* internal indirect node number (never exported) */
293 } h_spun;
294 u_int32_t h_crtime; /* BSD-format creation date in secs. */
295 u_int32_t h_atime; /* BSD-format access date in secs. */
296 u_int32_t h_mtime; /* BSD-format mod date in seconds */
297 u_int32_t h_ctime; /* BSD-format status change date */
298 u_int32_t h_butime; /* BSD-format last backup date in secs. */
299 u_int16_t h_nlink; /* link count (aprox. for dirs) */
300 u_short h_namelen; /* Length of name string */
301 char * h_namePtr; /* Points the name of the file */
302 FileNameStr h_fileName; /* CName of file */
303 } hfsfilemeta;
304 #define h_rdev h_spun.hu_rdev
305 #define h_indnodeno h_spun.hu_indnodeno
306
307 #define H_EXTENDSIZE(VP,BYTES) ((VP)->h_meta->h_size += (BYTES))
308 #define H_TRUNCSIZE(VP,BYTES) ((VP)->h_meta->h_size -= (BYTES))
309
310 #define MAKE_INODE_NAME(name,linkno) \
311 (void) sprintf((name), "%s%d", HFS_INODE_PREFIX, (linkno))
312
313
314 /*
315 * Macros for quick access to fields buried in the fcb inside an hfs node:
316 */
317 #define H_FORKTYPE(HP) ((HP)->h_type)
318 #define H_FILEID(HP) ((HP)->h_meta->h_nodeID)
319 #define H_DIRID(HP) ((HP)->h_meta->h_dirID)
320 #define H_NAME(HP) ((HP)->h_meta->h_namePtr)
321 #define H_HINT(HP) ((HP)->h_meta->h_hint)
322 #define H_DEV(HP) ((HP)->h_meta->h_dev)
323
324 /* These flags are kept in flags. */
325 #define IN_ACCESS 0x0001 /* Access time update request. */
326 #define IN_CHANGE 0x0002 /* Change time update request. */
327 #define IN_UPDATE 0x0004 /* Modification time update request. */
328 #define IN_MODIFIED 0x0008 /* Node has been modified. */
329 #define IN_RENAME 0x0010 /* Node is being renamed. */
330 #define IN_SHLOCK 0x0020 /* File has shared lock. */
331 #define IN_EXLOCK 0x0040 /* File has exclusive lock. */
332 #define IN_ALLOCATING 0x1000 /* vnode is in transit, wait or ignore */
333 #define IN_WANT 0x2000 /* Its being waited for */
334
335 /* These flags are kept in meta flags. */
336 #define IN_LONGNAME 0x0400 /* File has long name buffer. */
337 #define IN_UNSETACCESS 0x0200 /* File has unset access. */
338 #define IN_DELETED 0x0800 /* File has been marked to be deleted */
339 #define IN_NOEXISTS 0x1000 /* File has been deleted, catalog entry is gone */
340 #if HFS_HARDLINKS
341 #define IN_DATANODE 0x2000 /* 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 enum {
424 kCatNameIsAllocated = 0x1, /* The name is malloc'd and is in cnm_nameptr */
425 kCatNameIsMangled = 0x2, /* The name is mangled */
426 kCatNameUsesReserved = 0x4, /* It overides the space reserved by cnm_namespace into cndu_extra, careful */
427 kCatNameIsConsumed = 0x8, /* The name has been already processed, no freeing or work is needed */
428 kCatNameNoCopyName = 0x10, /* Dont copy the name */
429 kCatNameMangleName = 0x20 /* Mangle name if greater than passed in length */
430 };
431
432 /*
433 * CatalogNameSpecifier is a structure that contains a name and possibly its form
434 *
435 * Special care needs to be taken with the flags, they can cause side effects.
436 */
437 struct CatalogNameSpecifier {
438 u_int16_t cnm_flags; /* See above */
439 u_int16_t cnm_length; /* Length of the name */
440 u_int32_t cnm_parID; /* ID of the parent directory */
441 unsigned char *cnm_nameptr; /* If allocated, a ptr to the space, else NULL */
442 unsigned char cnm_namespace[MAXHFSVNODELEN+1]; /* Space where the name can be kept */
443 };
444 /*
445 * NOTE IT IS REQUIRED that KMaxMangleNameLen >= MAXHFSVNODELEN
446 * Also the total size of CatalogNameSpecifier should be less then cndu_extra, which
447 * currently it easily is, this is not a requirement, just a nicety.
448 *
449 * The rules to how to store a name:
450 * If its less than MAXHFSVNODELEN always store it in cnm_namespace.
451 * If we can get by doing mangling then cnm_namespace
452 * else allocate the space needed to cnm_nameptr.
453 * This reflects what is done at vnode creation.
454 */
455
456
457 enum {
458 kCatalogFolderNode = 1,
459 kCatalogFileNode = 2
460 };
461
462 /*
463 * CatalogNodeData has same layout as the on-disk HFS Plus file/dir records.
464 * Classic hfs file/dir records are converted to match this layout.
465 *
466 * The cnd_extra padding allows big hfs plus thread records (520 bytes max)
467 * to be read onto this stucture during a cnid lookup.
468 *
469 * IMPORTANT!!!!!!
470 * After declaring this structure, you must use the macro INIT_CATALOGDATA to prepare it
471 * and CLEAN_CATALOGDATA after using it, to clean any allocated structures.
472 *
473 * If you do not need to have the name, then pass in kCatNameNoCopyName for flags
474 */
475 struct CatalogNodeData {
476 int16_t cnd_type;
477 u_int16_t cnd_flags;
478 u_int32_t cnd_valence; /* dirs only */
479 u_int32_t cnd_nodeID;
480 u_int32_t cnd_createDate;
481 u_int32_t cnd_contentModDate;
482 u_int32_t cnd_attributeModDate;
483 u_int32_t cnd_accessDate;
484 u_int32_t cnd_backupDate;
485 u_int32_t cnd_ownerID;
486 u_int32_t cnd_groupID;
487 u_int8_t cnd_adminFlags; /* super-user changeable flags */
488 u_int8_t cnd_ownerFlags; /* owner changeable flags */
489 u_int16_t cnd_mode; /* file type + permission bits */
490 union {
491 u_int32_t cndu_iNodeNum; /* indirect links only */
492 u_int32_t cndu_linkCount; /* indirect nodes only */
493 u_int32_t cndu_rawDevice; /* special files (FBLK and FCHR) only */
494 } cnd_un;
495 u_int8_t cnd_finderInfo[32];
496 u_int32_t cnd_textEncoding;
497 u_int32_t cnd_reserved;
498 HFSPlusForkData cnd_datafork;
499 HFSPlusForkData cnd_rsrcfork;
500 u_int32_t cnd_iNodeNumCopy;
501 u_int8_t cnd_extra[268]; /* make struct at least 520 bytes long */
502 struct CatalogNameSpecifier cnd_namespecifier;
503 };
504 typedef struct CatalogNodeData CatalogNodeData;
505
506 #define cnd_iNodeNum cnd_un.cndu_iNodeNum
507 #define cnd_linkCount cnd_un.cndu_linkCount
508 #define cnd_rawDevice cnd_un.cndu_rawDevice
509
510 #define cnm_flags cnd_namespecifier.cnm_flags
511 #define cnm_length cnd_namespecifier.cnm_length
512 #define cnm_parID cnd_namespecifier.cnm_parID
513 #define cnm_nameptr cnd_namespecifier.cnm_nameptr
514 #define cnm_namespace cnd_namespecifier.cnm_namespace
515
516 #define INIT_CATALOGDATA(C,F) do { bzero(&((C)->cnd_namespecifier), sizeof(struct CatalogNameSpecifier)); (C)->cnm_flags=(F);}while(0);
517 #if HFS_DIAGNOSTIC
518 extern void debug_check_catalogdata(struct CatalogNodeData *cat);
519 #define CLEAN_CATALOGDATA(C) do { debug_check_catalogdata(C); \
520 if ((C)->cnm_flags & kCatNameIsAllocated) {\
521 FREE((C)->cnm_nameptr, M_TEMP);\
522 (C)->cnm_flags &= ~kCatNameIsAllocated;\
523 (C)->cnm_nameptr = NULL;\
524 }}while(0);
525 #else
526 #define CLEAN_CATALOGDATA(C) do { if ((C)->cnm_flags & kCatNameIsAllocated) {\
527 FREE((C)->cnm_nameptr, M_TEMP);\
528 (C)->cnm_flags &= ~kCatNameIsAllocated;\
529 (C)->cnm_nameptr = NULL;\
530 }}while(0);
531 #endif
532
533 /* structure to hold a catalog record information */
534 /* Of everything you wanted to know about a catalog entry, file and directory */
535 typedef struct hfsCatalogInfo {
536 CatalogNodeData nodeData;
537 u_int32_t hint;
538 } hfsCatalogInfo;
539
540 enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
541
542 enum { kdirentMaxNameBytes = NAME_MAX };
543
544 // structure definition of the searchfs system trap for the search criterea.
545 struct directoryInfoSpec
546 {
547 u_long numFiles;
548 };
549
550 struct fileInfoSpec
551 {
552 off_t dataLogicalLength;
553 off_t dataPhysicalLength;
554 off_t resourceLogicalLength;
555 off_t resourcePhysicalLength;
556 };
557
558 struct searchinfospec
559 {
560 u_char name[kHFSPlusMaxFileNameBytes];
561 u_long nameLength;
562 char attributes; // see IM:Files 2-100
563 u_long nodeID;
564 u_long parentDirID;
565 struct timespec creationDate;
566 struct timespec modificationDate;
567 struct timespec changeDate;
568 struct timespec lastBackupDate;
569 u_long finderInfo[8];
570 uid_t uid;
571 gid_t gid;
572 mode_t mask;
573 struct fileInfoSpec f;
574 struct directoryInfoSpec d;
575 };
576 typedef struct searchinfospec searchinfospec_t;
577
578 #define HFSTIMES(hp, t1, t2) { \
579 if ((hp)->h_nodeflags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
580 (hp)->h_nodeflags |= IN_MODIFIED; \
581 if ((hp)->h_nodeflags & IN_ACCESS) { \
582 (hp)->h_meta->h_atime = (t1)->tv_sec; \
583 }; \
584 if ((hp)->h_nodeflags & IN_UPDATE) { \
585 (hp)->h_meta->h_mtime = (t2)->tv_sec; \
586 } \
587 if ((hp)->h_nodeflags & IN_CHANGE) { \
588 (hp)->h_meta->h_ctime = time.tv_sec; \
589 }; \
590 (hp)->h_nodeflags &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
591 } \
592 }
593
594 /* This overlays the fid structure (see mount.h). */
595 struct hfsfid {
596 u_int16_t hfsfid_len; /* Length of structure. */
597 u_int16_t hfsfid_pad; /* Force 32-bit alignment. */
598 /* The following data is filesystem-dependent, up to MAXFIDSZ (16) bytes: */
599 u_int32_t hfsfid_cnid; /* Catalog node ID. */
600 u_int32_t hfsfid_gen; /* Generation number (create date). */
601 };
602
603 /* macro to determine if hfs or hfsplus */
604 #define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord)
605 #define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord)
606
607
608 /*
609 * Various ways to acquire a VNode pointer:
610 */
611 #define HTOV(HP) ((HP)->h_vp)
612
613 /*
614 * Various ways to acquire an HFS Node pointer:
615 */
616 #define VTOH(VP) ((struct hfsnode *)((VP)->v_data))
617 #define FCBTOH(FCB) ((struct hfsnode *)FCB)
618
619 /*
620 * Various ways to acquire an FCB pointer:
621 */
622 #define HTOFCB(HP) (HP)
623 #define VTOFCB(VP) ((FCB *)((VP)->v_data)) /* Should be the same as VTOH */
624
625 /*
626 * Various ways to acquire a VFS mount point pointer:
627 */
628 #define VTOVFS(VP) ((VP)->v_mount)
629 #define HTOVFS(HP) ((HP)->h_vp->v_mount)
630 #define FCBTOVFS(FCB) ((FCB)->h_vp->v_mount)
631 #define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp)
632 #define VCBTOVFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp->hfs_mp)
633
634 /*
635 * Various ways to acquire an HFS mount point pointer:
636 */
637 #define VTOHFS(VP) ((struct hfsmount *)((VP)->v_mount->mnt_data))
638 #define HTOHFS(HP) ((struct hfsmount *)(HP)->h_vp->v_mount->mnt_data)
639 #define FCBTOHFS(FCB) ((struct hfsmount *)(FCB)->h_vp->v_mount->mnt_data)
640 #define VFSTOHFS(MP) ((struct hfsmount *)(MP)->mnt_data)
641 #define VCBTOHFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp)
642
643 /*
644 * Various ways to acquire a VCB pointer:
645 */
646 #define VTOVCB(VP) (&(((struct hfsmount *)((VP)->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
647 #define HTOVCB(HP) (&(((struct hfsmount *)((HP)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
648 #define FCBTOVCB(FCB) (&(((struct hfsmount *)((FCB)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
649 #define VFSTOVCB(MP) (&(((struct hfsmount *)(MP)->mnt_data)->hfs_vcb.vcb_vcb))
650 #define HFSTOVCB(HFSMP) (&(HFSMP)->hfs_vcb.vcb_vcb)
651
652
653 #define E_NONE 0
654 #define kHFSBlockSize 512
655 #define kHFSBlockShift 9 /* 2^9 = 512 */
656
657 #define IOBLKNOFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBLOCK) / ((BLOCKSIZEINBYTES) >> 9)))
658 #define IOBLKCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
659 ((int)(IOBLKNOFORBYTE(((STARTINGBLOCK) * 512) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \
660 IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) + 1))
661 #define IOBYTECCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
662 (IOBLKCNTFORBLK((STARTINGBLOCK),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))
663 #define IOBYTEOFFSETFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) \
664 (((STARTINGBLOCK) * 512) - \
665 (IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)))
666
667 #define IOBLKNOFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBYTE) / (BLOCKSIZEINBYTES)))
668 #define IOBLKCNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
669 ((int)(IOBLKNOFORBYTE((STARTINGBYTE) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \
670 IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) + 1))
671 #define IOBYTECNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
672 (IOBLKCNTFORBYTE((STARTINGBYTE),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))
673 #define IOBYTEOFFSETFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((STARTINGBYTE) - (IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)))
674
675 #define MAKE_VREFNUM(x) ((int32_t)((x) & 0xffff))
676 /*
677 * This is the straight GMT conversion constant:
678 * 00:00:00 January 1, 1970 - 00:00:00 January 1, 1904
679 * (3600 * 24 * ((365 * (1970 - 1904)) + (((1970 - 1904) / 4) + 1)))
680 */
681 #define MAC_GMT_FACTOR 2082844800UL
682
683 #define HFS_ATTR_CMN_LOOKUPMASK (ATTR_CMN_SCRIPT | ATTR_CMN_FNDRINFO | ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)
684 #define HFS_ATTR_DIR_LOOKUPMASK (ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT)
685 #define HFS_ATTR_FILE_LOOKUPMASK (ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | ATTR_FILE_ALLOCSIZE | \
686 ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_DATAEXTENTS | \
687 ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE | ATTR_FILE_RSRCEXTENTS)
688
689 u_int32_t to_bsd_time(u_int32_t hfs_time);
690 u_int32_t to_hfs_time(u_int32_t bsd_time);
691
692 int hfs_flushfiles(struct mount *mp, int flags);
693 short hfs_flushMDB(struct hfsmount *hfsmp, int waitfor);
694 short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor);
695
696 short hfs_getcatalog (ExtendedVCB *vcb, u_int32_t dirID, char *name, short len, hfsCatalogInfo *catInfo);
697 short hfsMoveRename (ExtendedVCB *vcb, u_int32_t oldDirID, char *oldName, u_int32_t newDirID, char *newName, u_int32_t *hint);
698 short hfsCreate (ExtendedVCB *vcb, u_int32_t dirID, char *name, int mode);
699 short hfsCreateFileID (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, u_int32_t catalogHint, u_int32_t *fileIDPtr);
700 short hfs_vcreate (ExtendedVCB *vcb, hfsCatalogInfo *catInfo, u_int8_t forkType, struct vnode **vpp);
701 short hfsDelete (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, short isfile, u_int32_t catalogHint);
702 short hfsUnmount(struct hfsmount *hfsmp, struct proc *p);
703
704 extern int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flags, struct proc *p);
705 extern int hasOverflowExtents(struct hfsnode *hp);
706
707 void hfs_set_metaname(char *, struct hfsfilemeta *, struct hfsmount *);
708
709 short MacToVFSError(OSErr err);
710 int hfs_owner_rights(struct vnode *vp, struct ucred *cred, struct proc *p, Boolean invokesuperuserstatus);
711
712 void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData);
713 void CopyCatalogToHFSNode(struct hfsCatalogInfo *catalogInfo, struct hfsnode *hp);
714 u_long FindMetaDataDirectory(ExtendedVCB *vcb);
715
716
717 short make_dir_entry(FCB **fileptr, char *name, u_int32_t fileID);
718
719 int AttributeBlockSize(struct attrlist *attrlist);
720 void PackCommonAttributeBlock(struct attrlist *alist,
721 struct vnode *vp,
722 struct hfsCatalogInfo *catInfo,
723 void **attrbufptrptr,
724 void **varbufptrptr);
725 void PackVolAttributeBlock(struct attrlist *alist,
726 struct vnode *vp,
727 struct hfsCatalogInfo *catInfo,
728 void **attrbufptrptr,
729 void **varbufptrptr);
730 void PackFileDirAttributeBlock(struct attrlist *alist,
731 struct vnode *vp,
732 struct hfsCatalogInfo *catInfo,
733 void **attrbufptrptr,
734 void **varbufptrptr);
735 void PackForkAttributeBlock(struct attrlist *alist,
736 struct vnode *vp,
737 struct hfsCatalogInfo *catInfo,
738 void **attrbufptrptr,
739 void **varbufptrptr);
740 void PackAttributeBlock(struct attrlist *alist,
741 struct vnode *vp,
742 struct hfsCatalogInfo *catInfo,
743 void **attrbufptrptr,
744 void **varbufptrptr);
745 void PackCatalogInfoAttributeBlock (struct attrlist *alist,
746 struct vnode * root_vp,
747 struct hfsCatalogInfo *catInfo,
748 void **attrbufptrptr,
749 void **varbufptrptr);
750 void UnpackCommonAttributeBlock(struct attrlist *alist,
751 struct vnode *vp,
752 struct hfsCatalogInfo *catInfo,
753 void **attrbufptrptr,
754 void **varbufptrptr);
755 void UnpackAttributeBlock(struct attrlist *alist,
756 struct vnode *vp,
757 struct hfsCatalogInfo *catInfo,
758 void **attrbufptrptr,
759 void **varbufptrptr);
760 unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
761 unsigned long blockSizeLimit,
762 unsigned long baseMultiple);
763
764 OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
765 u_long sectors, struct proc *p);
766 OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
767 u_long embBlkOffset, u_long sectors, struct proc *p);
768 OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode, int init_ubc);
769
770 int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode,
771 unicode_to_hfs_func_t *get_hfsname);
772
773 int hfs_relconverter(u_int32_t encoding);
774
775 int hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen,
776 ByteCount *actualDstLen, unsigned char* dstStr);
777
778 int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr,
779 Str31 dstStr);
780
781 int mac_roman_to_utf8(Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen,
782 unsigned char* dstStr);
783
784 int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr);
785
786 #endif /* __HFS__ */