]> git.saurik.com Git - apple/xnu.git/blame - bsd/hfs/hfs.h
xnu-201.tar.gz
[apple/xnu.git] / bsd / hfs / hfs.h
CommitLineData
1c79356b 1/*
0b4e3aa0 2 * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
1c79356b
A
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*
1c79356b
A
30*/
31
32#ifndef __HFS__
33#define __HFS__
34
35#include <sys/param.h>
36#include <sys/lock.h>
37#include <sys/queue.h>
38#include <sys/attr.h>
39
40#include <sys/dirent.h>
41
42#include <hfs/hfs_format.h>
43#include <hfs/hfs_macos_defs.h>
44#include <hfs/hfs_encodings.h>
0b4e3aa0 45#include <hfs/rangelist.h>
1c79356b
A
46
47
48struct uio; // This is more effective than #include <sys/uio.h> in case KERNEL is undefined...
49struct hfslockf; // For advisory locking
50
51/*
52 * Just reported via MIG interface.
53 */
54#define VERSION_STRING "hfs-2 (4-12-99)"
55
56#define HFS_LINK_MAX 32767
57
58/*
59 * Set to force READ_ONLY.
60 */
61#define FORCE_READONLY 0
62
63enum { kMDBSize = 512 }; /* Size of I/O transfer to read entire MDB */
64
65enum { kMasterDirectoryBlock = 2 }; /* MDB offset on disk in 512-byte blocks */
66enum { kMDBOffset = kMasterDirectoryBlock * 512 }; /* MDB offset on disk in bytes */
67
68enum {
69 kUnknownID = 0,
70 kRootParID = 1,
71 kRootDirID = 2
72};
73
74enum {
75 kUndefinedFork = 0,
1c79356b
A
76 kDataFork,
77 kRsrcFork,
78 kDirectory,
79 kSysFile,
0b4e3aa0
A
80 kDefault,
81 kAnyFork
1c79356b
A
82};
83
0b4e3aa0
A
84/* number of locked buffer caches to hold for b-tree meta data */
85#define kMaxLockedMetaBuffers 32
1c79356b
A
86
87/*
88 * File type and creator for symbolic links
89 */
90enum {
91 kSymLinkFileType = 0x736C6E6B, /* 'slnk' */
92 kSymLinkCreator = 0x72686170 /* 'rhap' */
93};
94
95#define BUFFERPTRLISTSIZE 25
96
97extern char * gBufferAddress[BUFFERPTRLISTSIZE];
98extern struct buf *gBufferHeaderPtr[BUFFERPTRLISTSIZE];
99extern int gBufferListIndex;
100extern simple_lock_data_t gBufferPtrListLock;
101
102extern struct timezone gTimeZone;
103
104/* Flag values for bexpand: */
105#define RELEASE_BUFFER 0x00000001
106
107
0b4e3aa0
A
108/* How many free extents to cache per volume */
109#define kMaxFreeExtents 10
110
1c79356b
A
111/* Internal Data structures*/
112
113struct vcb_t {
1c79356b 114 u_int16_t vcbSigWord;
1c79356b 115 int16_t vcbAtrb;
0b4e3aa0 116 int16_t vcbFlags;
1c79356b 117 int16_t vcbVRefNum;
0b4e3aa0
A
118
119 u_int32_t vcbCrDate;
120 u_int32_t vcbLsMod;
1c79356b 121 u_int32_t vcbVolBkUp;
0b4e3aa0
A
122 u_int32_t checkedDate; /* time of last disk check */
123
1c79356b
A
124 int32_t vcbFilCnt;
125 int32_t vcbDirCnt;
0b4e3aa0
A
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 */
130 int32_t vcbClpSiz;
131 u_int32_t vcbNxtCNID;
132 u_int32_t vcbCNIDGen;
133 int32_t vcbWrCnt;
134
1c79356b 135 int32_t vcbFndrInfo[8];
0b4e3aa0
A
136
137 u_int64_t encodingsBitmap; /* HFS Plus only */
138
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 */
143
1c79356b
A
144 struct vnode * extentsRefNum;
145 struct vnode * catalogRefNum;
146 struct vnode * allocationsRefNum;
0b4e3aa0
A
147
148 u_int8_t vcbVN[256]; /* volume name in UTF-8 */
149 u_int32_t volumeNameEncodingHint;
1c79356b 150 u_int32_t altIDSector; /* location of alternate MDB/VH */
0b4e3aa0
A
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 */
154
155 /* cache of largest known free extents */
156 u_int32_t vcbFreeExtCnt;
157 HFSPlusExtentDescriptor vcbFreeExt[kMaxFreeExtents];
158
1c79356b
A
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 */
161};
162typedef struct vcb_t ExtendedVCB;
163
0b4e3aa0 164
1c79356b
A
165/* vcbFlags */
166#define kHFS_DamagedVolume 0x1 /* This volume has errors, unmount dirty */
167#define MARK_VOLUMEDAMAGED(fcb) FCBTOVCB((fcb))->vcbFlags |= kHFS_DamagedVolume;
168
169
170/*
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!!
174 *
175 * vcbFlags, vcbLsMod, vcbFilCnt, vcbDirCnt, vcbNxtCNID, etc
176 * are locked by the hfs_lock simple lock.
177 */
178typedef struct vfsVCB {
179 ExtendedVCB vcb_vcb;
180 struct hfsmount *vcb_hfsmp; /* Pointer to hfsmount structure */
181} vfsVCB_t;
182
183
184
185/* This structure describes the HFS specific mount structure data. */
186typedef 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 */
191
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 */
195
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 */
202
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 */
209
210 /* simple lock for shared meta renaming */
211 simple_lock_data_t hfs_renamelock;
212
213 /* HFS Specific */
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;
219} hfsmount_t;
220
0b4e3aa0
A
221#define HFSPLUS_PRIVATE_DIR \
222 "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data"
223
1c79356b
A
224
225/*****************************************************************************
226*
227* hfsnode structure
228*
229*
230*
231*****************************************************************************/
232
233#define MAXHFSVNODELEN 31
234typedef u_char FileNameStr[MAXHFSVNODELEN+1];
235
236CIRCLEQ_HEAD(siblinghead, hfsnode) ; /* Head of the sibling list */
237
238
239struct hfsnode {
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. */
243 union {
244 struct hfslockf *hu_lockf; /* Head of byte-level lock list. */
245 void *hu_sysdata; /* private data for system files */
0b4e3aa0
A
246 char hu_symlinkdata[4]; /* symbolic link (4 chars or less) */
247 char *hu_symlinkptr; /* symbolic link pathname */
1c79356b
A
248 } h_un;
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 */
0b4e3aa0 254 struct rl_head h_invalidranges;/* Areas of disk that should read back as zeroes */
1c79356b
A
255 u_int64_t fcbEOF; /* Logical length or EOF in bytes */
256 u_int64_t fcbPLen; /* Physical file length in bytes */
1c79356b
A
257 u_int32_t fcbClmpSize; /* Number of bytes per clump */
258 HFSPlusExtentRecord fcbExtents; /* Extents of file */
259
260#if HFS_DIAGNOSTIC
261 u_int32_t h_valid; /* is the vnode reference valid */
262#endif
263};
264#define h_lockf h_un.hu_lockf
265#define fcbBTCBPtr h_un.hu_sysdata
0b4e3aa0
A
266#define h_symlinkptr h_un.hu_symlinkptr
267#define h_symlinkdata h_un.hu_symlinkdata
1c79356b
A
268
269typedef struct hfsnode FCB;
270
271
272typedef 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. */
277
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 */
282
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. */
289 union {
290 dev_t hu_rdev; /* Special device info for this node */
291 u_int32_t hu_indnodeno; /* internal indirect node number (never exported) */
292 } h_spun;
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 */
302} hfsfilemeta;
303#define h_rdev h_spun.hu_rdev
304#define h_indnodeno h_spun.hu_indnodeno
305
306#define H_EXTENDSIZE(VP,BYTES) ((VP)->h_meta->h_size += (BYTES))
307#define H_TRUNCSIZE(VP,BYTES) ((VP)->h_meta->h_size -= (BYTES))
308
309#define MAKE_INODE_NAME(name,linkno) \
310 (void) sprintf((name), "%s%d", HFS_INODE_PREFIX, (linkno))
311
312
313/*
314 * Macros for quick access to fields buried in the fcb inside an hfs node:
315 */
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)
322
0b4e3aa0
A
323#define H_ISBIGLINK(HP) ((HP)->fcbEOF > 4)
324#define H_SYMLINK(HP) (H_ISBIGLINK((HP)) ? (HP)->h_symlinkptr : (HP)->h_symlinkdata)
325
1c79356b
A
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. */
0b4e3aa0 334#define IN_BYCNID 0x0100 /* Dir was found by CNID */
1c79356b
A
335#define IN_ALLOCATING 0x1000 /* vnode is in transit, wait or ignore */
336#define IN_WANT 0x2000 /* Its being waited for */
337
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 */
343#if HFS_HARDLINKS
344#define IN_DATANODE 0x2000 /* File is a data node (hard-linked) */
345#endif
346
347
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. */
355
356/* File types */
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. */
366
367/* Value to make sure vnode is real and defined */
368#define HFS_VNODE_MAGIC 0x4846532b /* 'HFS+' */
369
370/* To test wether the forkType is a sibling type */
371#define SIBLING_FORKTYPE(FORK) ((FORK==kDataFork) || (FORK==kRsrcFork))
372
373/*
374 * Write check macro
375 */
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", \
379 FUNC_NAME)); \
380 return(EROFS); \
381 } \
382}
383
384
385/*
386 * hfsmount locking and unlocking.
387 *
388 * mvl_lock_flags
389 */
390#define MVL_LOCKED 0x00000001 /* debug only */
391
392#if HFS_DIAGNOSTIC
393#define MVL_LOCK(mvip) { \
394 (simple_lock(&(mvip)->mvl_lock)); \
395 (mvip)->mvl_flags |= MVL_LOCKED; \
396}
397
398#define MVL_UNLOCK(mvip) { \
399 if(((mvip)->mvl_flags & MVL_LOCKED) == 0) { \
400 panic("MVL_UNLOCK - hfsnode not locked"); \
401 } \
402 (simple_unlock(&(mvip)->mvl_lock)); \
403 (mvip)->mvl_flags &= ~MVL_LOCKED; \
404}
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 */
409
410
411/* structure to hold a "." or ".." directory entry (12 bytes) */
412typedef 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 ".." */
418} hfsdotentry;
419
420#define AVERAGE_HFSDIRENTRY_SIZE (8+22+4)
421#define MAX_HFSDIRENTRY_SIZE sizeof(struct dirent)
422
423#define DIRENTRY_SIZE(namlen) \
424 ((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3))
425
426enum {
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 */
433};
434
435/*
436 * CatalogNameSpecifier is a structure that contains a name and possibly its form
437 *
438 * Special care needs to be taken with the flags, they can cause side effects.
439 */
440struct 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 */
446};
447/*
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.
451 *
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.
457 */
458
459
460enum {
461 kCatalogFolderNode = 1,
462 kCatalogFileNode = 2
463};
464
465/*
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.
468 *
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.
471 *
472 * IMPORTANT!!!!!!
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.
475 *
476 * If you do not need to have the name, then pass in kCatNameNoCopyName for flags
477 */
478struct CatalogNodeData {
479 int16_t cnd_type;
480 u_int16_t cnd_flags;
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 */
493 union {
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 */
497 } cnd_un;
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_int8_t cnd_extra[268]; /* make struct at least 520 bytes long */
505 struct CatalogNameSpecifier cnd_namespecifier;
506};
507typedef struct CatalogNodeData CatalogNodeData;
508
509#define cnd_iNodeNum cnd_un.cndu_iNodeNum
510#define cnd_linkCount cnd_un.cndu_linkCount
511#define cnd_rawDevice cnd_un.cndu_rawDevice
512
513#define cnm_flags cnd_namespecifier.cnm_flags
514#define cnm_length cnd_namespecifier.cnm_length
515#define cnm_parID cnd_namespecifier.cnm_parID
516#define cnm_nameptr cnd_namespecifier.cnm_nameptr
517#define cnm_namespace cnd_namespecifier.cnm_namespace
518
519#define INIT_CATALOGDATA(C,F) do { bzero(&((C)->cnd_namespecifier), sizeof(struct CatalogNameSpecifier)); (C)->cnm_flags=(F);}while(0);
520#if HFS_DIAGNOSTIC
521extern void debug_check_catalogdata(struct CatalogNodeData *cat);
522#define CLEAN_CATALOGDATA(C) do { debug_check_catalogdata(C); \
523 if ((C)->cnm_flags & kCatNameIsAllocated) {\
524 FREE((C)->cnm_nameptr, M_TEMP);\
525 (C)->cnm_flags &= ~kCatNameIsAllocated;\
526 (C)->cnm_nameptr = NULL;\
527 }}while(0);
528#else
529#define CLEAN_CATALOGDATA(C) do { if ((C)->cnm_flags & kCatNameIsAllocated) {\
530 FREE((C)->cnm_nameptr, M_TEMP);\
531 (C)->cnm_flags &= ~kCatNameIsAllocated;\
532 (C)->cnm_nameptr = NULL;\
533 }}while(0);
534#endif
535
536/* structure to hold a catalog record information */
537/* Of everything you wanted to know about a catalog entry, file and directory */
538typedef struct hfsCatalogInfo {
539 CatalogNodeData nodeData;
540 u_int32_t hint;
541} hfsCatalogInfo;
542
543enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
544
545enum { kdirentMaxNameBytes = NAME_MAX };
546
547// structure definition of the searchfs system trap for the search criterea.
548struct directoryInfoSpec
549{
550 u_long numFiles;
551};
552
553struct fileInfoSpec
554{
555 off_t dataLogicalLength;
556 off_t dataPhysicalLength;
557 off_t resourceLogicalLength;
558 off_t resourcePhysicalLength;
559};
560
561struct searchinfospec
562{
563 u_char name[kHFSPlusMaxFileNameBytes];
564 u_long nameLength;
565 char attributes; // see IM:Files 2-100
566 u_long nodeID;
567 u_long parentDirID;
568 struct timespec creationDate;
569 struct timespec modificationDate;
570 struct timespec changeDate;
571 struct timespec lastBackupDate;
572 u_long finderInfo[8];
573 uid_t uid;
574 gid_t gid;
575 mode_t mask;
576 struct fileInfoSpec f;
577 struct directoryInfoSpec d;
578};
579typedef struct searchinfospec searchinfospec_t;
580
581#define HFSTIMES(hp, t1, t2) { \
582 if ((hp)->h_nodeflags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
583 (hp)->h_nodeflags |= IN_MODIFIED; \
584 if ((hp)->h_nodeflags & IN_ACCESS) { \
585 (hp)->h_meta->h_atime = (t1)->tv_sec; \
586 }; \
587 if ((hp)->h_nodeflags & IN_UPDATE) { \
588 (hp)->h_meta->h_mtime = (t2)->tv_sec; \
589 } \
590 if ((hp)->h_nodeflags & IN_CHANGE) { \
591 (hp)->h_meta->h_ctime = time.tv_sec; \
592 }; \
593 (hp)->h_nodeflags &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
594 } \
595}
596
597/* This overlays the fid structure (see mount.h). */
598struct hfsfid {
599 u_int16_t hfsfid_len; /* Length of structure. */
600 u_int16_t hfsfid_pad; /* Force 32-bit alignment. */
601 /* The following data is filesystem-dependent, up to MAXFIDSZ (16) bytes: */
602 u_int32_t hfsfid_cnid; /* Catalog node ID. */
603 u_int32_t hfsfid_gen; /* Generation number (create date). */
604};
605
606/* macro to determine if hfs or hfsplus */
607#define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord)
608#define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord)
609
610
611/*
612 * Various ways to acquire a VNode pointer:
613 */
614#define HTOV(HP) ((HP)->h_vp)
615
616/*
617 * Various ways to acquire an HFS Node pointer:
618 */
619#define VTOH(VP) ((struct hfsnode *)((VP)->v_data))
620#define FCBTOH(FCB) ((struct hfsnode *)FCB)
621
622/*
623 * Various ways to acquire an FCB pointer:
624 */
625#define HTOFCB(HP) (HP)
626#define VTOFCB(VP) ((FCB *)((VP)->v_data)) /* Should be the same as VTOH */
627
628/*
629 * Various ways to acquire a VFS mount point pointer:
630 */
631#define VTOVFS(VP) ((VP)->v_mount)
632#define HTOVFS(HP) ((HP)->h_vp->v_mount)
633#define FCBTOVFS(FCB) ((FCB)->h_vp->v_mount)
634#define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp)
635#define VCBTOVFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp->hfs_mp)
636
637/*
638 * Various ways to acquire an HFS mount point pointer:
639 */
640#define VTOHFS(VP) ((struct hfsmount *)((VP)->v_mount->mnt_data))
641#define HTOHFS(HP) ((struct hfsmount *)(HP)->h_vp->v_mount->mnt_data)
642#define FCBTOHFS(FCB) ((struct hfsmount *)(FCB)->h_vp->v_mount->mnt_data)
643#define VFSTOHFS(MP) ((struct hfsmount *)(MP)->mnt_data)
644#define VCBTOHFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp)
645
646/*
647 * Various ways to acquire a VCB pointer:
648 */
649#define VTOVCB(VP) (&(((struct hfsmount *)((VP)->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
650#define HTOVCB(HP) (&(((struct hfsmount *)((HP)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
651#define FCBTOVCB(FCB) (&(((struct hfsmount *)((FCB)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
652#define VFSTOVCB(MP) (&(((struct hfsmount *)(MP)->mnt_data)->hfs_vcb.vcb_vcb))
653#define HFSTOVCB(HFSMP) (&(HFSMP)->hfs_vcb.vcb_vcb)
654
655
656#define E_NONE 0
657#define kHFSBlockSize 512
658#define kHFSBlockShift 9 /* 2^9 = 512 */
659
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)))
669
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)))
677
678#define MAKE_VREFNUM(x) ((int32_t)((x) & 0xffff))
679/*
680 * This is the straight GMT conversion constant:
681 * 00:00:00 January 1, 1970 - 00:00:00 January 1, 1904
682 * (3600 * 24 * ((365 * (1970 - 1904)) + (((1970 - 1904) / 4) + 1)))
683 */
684#define MAC_GMT_FACTOR 2082844800UL
685
686#define HFS_ATTR_CMN_LOOKUPMASK (ATTR_CMN_SCRIPT | ATTR_CMN_FNDRINFO | ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)
687#define HFS_ATTR_DIR_LOOKUPMASK (ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT)
688#define HFS_ATTR_FILE_LOOKUPMASK (ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | ATTR_FILE_ALLOCSIZE | \
689 ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_DATAEXTENTS | \
690 ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE | ATTR_FILE_RSRCEXTENTS)
691
692u_int32_t to_bsd_time(u_int32_t hfs_time);
693u_int32_t to_hfs_time(u_int32_t bsd_time);
694
695int hfs_flushfiles(struct mount *mp, int flags);
696short hfs_flushMDB(struct hfsmount *hfsmp, int waitfor);
697short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor);
698
699short hfs_getcatalog (ExtendedVCB *vcb, u_int32_t dirID, char *name, short len, hfsCatalogInfo *catInfo);
700short hfsMoveRename (ExtendedVCB *vcb, u_int32_t oldDirID, char *oldName, u_int32_t newDirID, char *newName, u_int32_t *hint);
0b4e3aa0 701short hfsCreate (ExtendedVCB *vcb, u_int32_t dirID, char *name, int mode, u_int32_t tehint);
1c79356b
A
702short hfsCreateFileID (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, u_int32_t catalogHint, u_int32_t *fileIDPtr);
703short hfs_vcreate (ExtendedVCB *vcb, hfsCatalogInfo *catInfo, u_int8_t forkType, struct vnode **vpp);
704short hfsDelete (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, short isfile, u_int32_t catalogHint);
705short hfsUnmount(struct hfsmount *hfsmp, struct proc *p);
706
707extern int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flags, struct proc *p);
708extern int hasOverflowExtents(struct hfsnode *hp);
709
710void hfs_set_metaname(char *, struct hfsfilemeta *, struct hfsmount *);
711
712short MacToVFSError(OSErr err);
713int hfs_owner_rights(struct vnode *vp, struct ucred *cred, struct proc *p, Boolean invokesuperuserstatus);
714
715void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData);
716void CopyCatalogToHFSNode(struct hfsCatalogInfo *catalogInfo, struct hfsnode *hp);
717u_long FindMetaDataDirectory(ExtendedVCB *vcb);
718
719
720short make_dir_entry(FCB **fileptr, char *name, u_int32_t fileID);
721
722int AttributeBlockSize(struct attrlist *attrlist);
723void PackCommonAttributeBlock(struct attrlist *alist,
724 struct vnode *vp,
725 struct hfsCatalogInfo *catInfo,
726 void **attrbufptrptr,
727 void **varbufptrptr);
728void PackVolAttributeBlock(struct attrlist *alist,
729 struct vnode *vp,
730 struct hfsCatalogInfo *catInfo,
731 void **attrbufptrptr,
732 void **varbufptrptr);
733void PackFileDirAttributeBlock(struct attrlist *alist,
734 struct vnode *vp,
735 struct hfsCatalogInfo *catInfo,
736 void **attrbufptrptr,
737 void **varbufptrptr);
738void PackForkAttributeBlock(struct attrlist *alist,
739 struct vnode *vp,
740 struct hfsCatalogInfo *catInfo,
741 void **attrbufptrptr,
742 void **varbufptrptr);
743void PackAttributeBlock(struct attrlist *alist,
744 struct vnode *vp,
745 struct hfsCatalogInfo *catInfo,
746 void **attrbufptrptr,
747 void **varbufptrptr);
748void PackCatalogInfoAttributeBlock (struct attrlist *alist,
749 struct vnode * root_vp,
750 struct hfsCatalogInfo *catInfo,
751 void **attrbufptrptr,
752 void **varbufptrptr);
753void UnpackCommonAttributeBlock(struct attrlist *alist,
754 struct vnode *vp,
755 struct hfsCatalogInfo *catInfo,
756 void **attrbufptrptr,
757 void **varbufptrptr);
758void UnpackAttributeBlock(struct attrlist *alist,
759 struct vnode *vp,
760 struct hfsCatalogInfo *catInfo,
761 void **attrbufptrptr,
762 void **varbufptrptr);
763unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
764 unsigned long blockSizeLimit,
765 unsigned long baseMultiple);
766
767OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
768 u_long sectors, struct proc *p);
769OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
770 u_long embBlkOffset, u_long sectors, struct proc *p);
0b4e3aa0 771OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode);
1c79356b
A
772
773int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode,
774 unicode_to_hfs_func_t *get_hfsname);
775
776int hfs_relconverter(u_int32_t encoding);
777
778int hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen,
779 ByteCount *actualDstLen, unsigned char* dstStr);
780
781int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr,
782 Str31 dstStr);
783
784int mac_roman_to_utf8(Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen,
785 unsigned char* dstStr);
786
787int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr);
788
0b4e3aa0
A
789u_int32_t hfs_pickencoding(const u_int16_t *src, int len);
790
1c79356b 791#endif /* __HFS__ */