]> git.saurik.com Git - apple/xnu.git/blame - bsd/hfs/hfs.h
xnu-3248.60.10.tar.gz
[apple/xnu.git] / bsd / hfs / hfs.h
CommitLineData
1c79356b 1/*
04b8595b 2 * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
5d5c5d0d 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b 27 */
1c79356b
A
28
29#ifndef __HFS__
30#define __HFS__
31
6d2010ae
A
32/* If set to 1, enables the code to allocate blocks from the start
33 * of the disk instead of the nextAllocation for sparse devices like
34 * sparse disk images or sparsebundle images. The free extent cache
35 * for such volumes is also maintained based on the start block instead
36 * of number of contiguous allocation blocks. These devices prefer
37 * allocation of blocks near the start of the disk to avoid the
38 * increasing the image size, but it can also result in file fragmentation.
39 */
55e303ae
A
40#define HFS_SPARSE_DEV 1
41
b0d623f7 42#if DEBUG
2d21ac55
A
43#define HFS_CHECK_LOCK_ORDER 1
44#endif
45
3e170ce0
A
46#define HFS_TMPDBG 0
47
9bccf70c
A
48#include <sys/appleapiopts.h>
49
50#ifdef KERNEL
51#ifdef __APPLE_API_PRIVATE
1c79356b 52#include <sys/param.h>
1c79356b 53#include <sys/queue.h>
9bccf70c 54#include <sys/mount.h>
9bccf70c
A
55#include <sys/vnode.h>
56#include <sys/quota.h>
1c79356b 57#include <sys/dirent.h>
55e303ae 58#include <sys/event.h>
060df5ea 59#include <sys/disk.h>
e2fac8b1 60#include <kern/thread_call.h>
1c79356b 61
91447636
A
62#include <kern/locks.h>
63
b4c24cb9
A
64#include <vfs/vfs_journal.h>
65
1c79356b 66#include <hfs/hfs_format.h>
9bccf70c
A
67#include <hfs/hfs_catalog.h>
68#include <hfs/hfs_cnode.h>
1c79356b
A
69#include <hfs/hfs_macos_defs.h>
70#include <hfs/hfs_encodings.h>
55e303ae 71#include <hfs/hfs_hotfiles.h>
fe8ab488 72#include <hfs/hfs_fsctl.h>
1c79356b 73
316670eb
A
74#if CONFIG_PROTECT
75/* Forward declare the cprotect struct */
76struct cprotect;
3e170ce0
A
77
78
316670eb
A
79#endif
80
1c79356b
A
81/*
82 * Just reported via MIG interface.
83 */
84#define VERSION_STRING "hfs-2 (4-12-99)"
85
86#define HFS_LINK_MAX 32767
87
9bccf70c
A
88#define HFS_MAX_DEFERED_ALLOC (1024*1024)
89
2d21ac55 90// 400 megs is a "big" file (i.e. one that when deleted
55e303ae 91// would touch enough data that we should break it into
2d21ac55 92// multiple separate transactions)
0c530ab8 93#define HFS_BIGFILE_SIZE (400LL * 1024LL * 1024LL)
55e303ae 94
1c79356b
A
95
96enum { kMDBSize = 512 }; /* Size of I/O transfer to read entire MDB */
97
98enum { kMasterDirectoryBlock = 2 }; /* MDB offset on disk in 512-byte blocks */
99enum { kMDBOffset = kMasterDirectoryBlock * 512 }; /* MDB offset on disk in bytes */
100
91447636 101#define kRootDirID kHFSRootFolderID
1c79356b 102
1c79356b 103
0b4e3aa0
A
104/* number of locked buffer caches to hold for b-tree meta data */
105#define kMaxLockedMetaBuffers 32
1c79356b 106
1c79356b
A
107extern struct timezone gTimeZone;
108
1c79356b 109
0b4e3aa0
A
110/* How many free extents to cache per volume */
111#define kMaxFreeExtents 10
112
04b8595b
A
113/* The maximum time hfs locks can be held while performing hfs statistics gathering */
114#define HFS_FSINFO_MAX_LOCKHELD_TIME 20 * 1000000ULL /* at most 20 milliseconds. */
115
9bccf70c
A
116/*
117 * HFS_MINFREE gives the minimum acceptable percentage
118 * of file system blocks which may be free (but this
119 * minimum will never exceed HFS_MAXRESERVE bytes). If
120 * the free block count drops below this level only the
121 * superuser may continue to allocate blocks.
122 */
123#define HFS_MINFREE 1
55e303ae 124#define HFS_MAXRESERVE ((u_int64_t)(250*1024*1024))
39236c6e 125#define HFS_BT_MAXRESERVE ((u_int64_t)(10*1024*1024))
55e303ae
A
126
127/*
128 * The system distinguishes between the desirable low-disk
129 * notifiaction levels for root volumes and non-root volumes.
130 * The various thresholds are computed as a fraction of the
131 * volume size, all capped at a certain fixed level
132 */
133
b0d623f7 134#define HFS_ROOTVERYLOWDISKTRIGGERFRACTION 5
6d2010ae 135#define HFS_ROOTVERYLOWDISKTRIGGERLEVEL ((u_int64_t)(512*1024*1024))
b0d623f7 136#define HFS_ROOTLOWDISKTRIGGERFRACTION 10
6d2010ae 137#define HFS_ROOTLOWDISKTRIGGERLEVEL ((u_int64_t)(1024*1024*1024))
b0d623f7 138#define HFS_ROOTLOWDISKSHUTOFFFRACTION 11
6d2010ae 139#define HFS_ROOTLOWDISKSHUTOFFLEVEL ((u_int64_t)(1024*1024*1024 + 250*1024*1024))
55e303ae 140
b0d623f7
A
141#define HFS_VERYLOWDISKTRIGGERFRACTION 1
142#define HFS_VERYLOWDISKTRIGGERLEVEL ((u_int64_t)(100*1024*1024))
143#define HFS_LOWDISKTRIGGERFRACTION 2
144#define HFS_LOWDISKTRIGGERLEVEL ((u_int64_t)(150*1024*1024))
145#define HFS_LOWDISKSHUTOFFFRACTION 3
146#define HFS_LOWDISKSHUTOFFLEVEL ((u_int64_t)(200*1024*1024))
9bccf70c 147
1c79356b
A
148/* Internal Data structures*/
149
1c79356b
A
150/* This structure describes the HFS specific mount structure data. */
151typedef struct hfsmount {
91447636
A
152 u_int32_t hfs_flags; /* see below */
153
1c79356b 154 /* Physical Description */
593a1d5f 155 u_int32_t hfs_logical_block_size; /* Logical block size of the disk as reported by ioctl(DKIOCGETBLOCKSIZE), always a multiple of 512 */
fe8ab488 156 daddr64_t hfs_logical_block_count; /* Number of logical blocks on the disk, as reported by ioctl(DKIOCGETBLOCKCOUNT) */
316670eb 157 u_int64_t hfs_logical_bytes; /* Number of bytes on the disk device this HFS is mounted on (blockcount * blocksize) */
fe8ab488
A
158 /*
159 * Regarding the two AVH sector fields below:
160 * Under normal circumstances, the filesystem's notion of the "right" location for the AVH is such that
161 * the partition and filesystem's are in sync. However, during a filesystem resize, HFS proactively
162 * writes a new AVH at the end of the filesystem, assuming that the partition will be resized accordingly.
163 *
164 * However, it is not technically a corruption if the partition size is never modified. As a result, we need
165 * to keep two copies of the AVH around "just in case" the partition size is not modified.
166 */
167 daddr64_t hfs_partition_avh_sector; /* location of Alt VH w.r.t partition size */
168 daddr64_t hfs_fs_avh_sector; /* location of Alt VH w.r.t filesystem size */
169
593a1d5f
A
170 u_int32_t hfs_physical_block_size; /* Physical block size of the disk as reported by ioctl(DKIOCGETPHYSICALBLOCKSIZE) */
171 u_int32_t hfs_log_per_phys; /* Number of logical blocks per physical block size */
1c79356b
A
172
173 /* Access to VFS and devices */
174 struct mount *hfs_mp; /* filesystem vfs structure */
175 struct vnode *hfs_devvp; /* block device mounted vnode */
91447636
A
176 struct vnode * hfs_extents_vp;
177 struct vnode * hfs_catalog_vp;
178 struct vnode * hfs_allocation_vp;
179 struct vnode * hfs_attribute_vp;
2d21ac55
A
180 struct vnode * hfs_startup_vp;
181 struct vnode * hfs_attrdata_vp; /* pseudo file */
182 struct cnode * hfs_extents_cp;
183 struct cnode * hfs_catalog_cp;
184 struct cnode * hfs_allocation_cp;
185 struct cnode * hfs_attribute_cp;
186 struct cnode * hfs_startup_cp;
91447636
A
187 dev_t hfs_raw_dev; /* device mounted */
188 u_int32_t hfs_logBlockSize; /* Size of buffer cache buffer for I/O */
1c79356b
A
189
190 /* Default values for HFS standard and non-init access */
91447636
A
191 uid_t hfs_uid; /* uid to set as owner of the files */
192 gid_t hfs_gid; /* gid to set as owner of the files */
193 mode_t hfs_dir_mask; /* mask to and with directory protection bits */
194 mode_t hfs_file_mask; /* mask to and with file protection bits */
b0d623f7 195 u_int32_t hfs_encoding; /* Default encoding for non hfs+ volumes */
91447636
A
196
197 /* Persistent fields (on disk, dynamic) */
198 time_t hfs_mtime; /* file system last modification time */
199 u_int32_t hfs_filecount; /* number of files in file system */
200 u_int32_t hfs_dircount; /* number of directories in file system */
3e170ce0
A
201 u_int32_t freeBlocks; /* free allocation blocks */
202 u_int32_t reclaimBlocks; /* number of blocks we are reclaiming during resize */
203 u_int32_t tentativeBlocks; /* tentative allocation blocks -- see note below */
91447636 204 u_int32_t nextAllocation; /* start of next allocation search */
b0d623f7 205 u_int32_t sparseAllocation; /* start of allocations for sparse devices */
2d21ac55 206 u_int32_t vcbNxtCNID; /* next unused catalog node ID - protected by catalog lock */
91447636
A
207 u_int32_t vcbWrCnt; /* file system write count */
208 u_int64_t encodingsBitmap; /* in-use encodings */
209 u_int16_t vcbNmFls; /* HFS Only - root dir file count */
210 u_int16_t vcbNmRtDirs; /* HFS Only - root dir directory count */
211
212 /* Persistent fields (on disk, static) */
213 u_int16_t vcbSigWord;
3e170ce0
A
214
215 // Volume will be inconsistent if header is not flushed
216 bool hfs_header_dirty;
217
218 // Volume header is dirty, but won't be inconsistent if not flushed
219 bool hfs_header_minor_change;
220
91447636
A
221 u_int32_t vcbAtrb;
222 u_int32_t vcbJinfoBlock;
6d2010ae
A
223 u_int32_t localCreateDate;/* volume create time from volume header (For HFS+, value is in local time) */
224 time_t hfs_itime; /* file system creation time (creation date of the root folder) */
225 time_t hfs_btime; /* file system last backup time */
91447636
A
226 u_int32_t blockSize; /* size of allocation blocks */
227 u_int32_t totalBlocks; /* total allocation blocks */
2d21ac55
A
228 u_int32_t allocLimit; /* Do not allocate this block or beyond */
229 /*
230 * NOTE: When resizing a volume to make it smaller, allocLimit is set to the allocation
231 * block number which will contain the new alternate volume header. At all other times,
232 * allocLimit is set to totalBlocks. The allocation code uses allocLimit instead of
233 * totalBlocks to limit which blocks may be allocated, so that during a resize, we don't
234 * put new content into the blocks we're trying to truncate away.
235 */
91447636
A
236 int32_t vcbClpSiz;
237 u_int32_t vcbFndrInfo[8];
238 int16_t vcbVBMSt; /* HFS only */
239 int16_t vcbAlBlSt; /* HFS only */
240
241 /* vcb stuff */
242 u_int8_t vcbVN[256]; /* volume name in UTF-8 */
243 u_int32_t volumeNameEncodingHint;
244 u_int32_t hfsPlusIOPosOffset; /* Disk block where HFS+ starts */
245 u_int32_t vcbVBMIOSize; /* volume bitmap I/O size */
246
247 /* cache of largest known free extents */
248 u_int32_t vcbFreeExtCnt;
249 HFSPlusExtentDescriptor vcbFreeExt[kMaxFreeExtents];
6d2010ae
A
250 lck_spin_t vcbFreeExtLock;
251
39236c6e
A
252 /* Summary Table */
253 u_int8_t *hfs_summary_table; /* Each bit is 1 vcbVBMIOSize of bitmap, byte indexed */
254 u_int32_t hfs_summary_size; /* number of BITS in summary table defined above (not bytes!) */
255 u_int32_t hfs_summary_bytes; /* number of BYTES in summary table */
91447636 256
39236c6e 257 u_int32_t scan_var; /* For initializing the summary table */
6d2010ae
A
258
259
91447636
A
260 u_int32_t reserveBlocks; /* free block reserve */
261 u_int32_t loanedBlocks; /* blocks on loan for delayed allocations */
3e170ce0 262 u_int32_t lockedBlocks; /* blocks reserved and locked */
2d21ac55
A
263
264 /*
265 * HFS+ Private system directories (two). Any access
266 * (besides looking at the cd_cnid) requires holding
267 * the Catalog File lock.
268 */
269 struct cat_desc hfs_private_desc[2];
270 struct cat_attr hfs_private_attr[2];
271
1c79356b
A
272 u_int32_t hfs_metadata_createdate;
273 hfs_to_unicode_func_t hfs_get_unicode;
274 unicode_to_hfs_func_t hfs_get_hfsname;
9bccf70c 275
55e303ae 276 /* Quota variables: */
9bccf70c 277 struct quotafile hfs_qfiles[MAXQUOTAS]; /* quota files */
b4c24cb9 278
55e303ae 279 /* Journaling variables: */
fe8ab488 280 struct journal *jnl; // the journal for this volume (if one exists)
b4c24cb9
A
281 struct vnode *jvp; // device where the journal lives (may be equal to devvp)
282 u_int32_t jnl_start; // start block of the journal file (so we don't delete it)
55e303ae 283 u_int32_t jnl_size;
b4c24cb9
A
284 u_int32_t hfs_jnlfileid;
285 u_int32_t hfs_jnlinfoblkid;
fe8ab488 286 lck_rw_t hfs_global_lock;
fe8ab488 287 thread_t hfs_global_lockowner;
3e170ce0 288 u_int32_t hfs_transaction_nesting;
fe8ab488 289
55e303ae 290 /* Notification variables: */
b0d623f7
A
291 u_int32_t hfs_notification_conditions;
292 u_int32_t hfs_freespace_notify_dangerlimit;
55e303ae
A
293 u_int32_t hfs_freespace_notify_warninglimit;
294 u_int32_t hfs_freespace_notify_desiredlevel;
295
91447636
A
296 /* time mounted and last mounted mod time "snapshot" */
297 time_t hfs_mount_time;
298 time_t hfs_last_mounted_mtime;
299
55e303ae
A
300 /* Metadata allocation zone variables: */
301 u_int32_t hfs_metazone_start;
302 u_int32_t hfs_metazone_end;
303 u_int32_t hfs_hotfile_start;
304 u_int32_t hfs_hotfile_end;
b0d623f7
A
305 u_int32_t hfs_min_alloc_start;
306 u_int32_t hfs_freed_block_count;
3e170ce0 307 u_int64_t hfs_cs_hotfile_size; // in bytes
55e303ae 308 int hfs_hotfile_freeblks;
3e170ce0 309 int hfs_hotfile_blk_adjust;
55e303ae
A
310 int hfs_hotfile_maxblks;
311 int hfs_overflow_maxblks;
312 int hfs_catalog_maxblks;
313
314 /* Hot File Clustering variables: */
91447636 315 lck_mtx_t hfc_mutex; /* serialize hot file stages */
55e303ae
A
316 enum hfc_stage hfc_stage; /* what are we up to... */
317 time_t hfc_timebase; /* recording period start time */
318 time_t hfc_timeout; /* recording period stop time */
319 void * hfc_recdata; /* recording data (opaque) */
3e170ce0 320 uint32_t hfc_maxfiles; /* maximum files to track */
55e303ae
A
321 struct vnode * hfc_filevp;
322
6d2010ae 323#if HFS_SPARSE_DEV
55e303ae
A
324 /* Sparse device variables: */
325 struct vnode * hfs_backingfs_rootvp;
2d21ac55 326 u_int32_t hfs_last_backingstatfs;
fe8ab488 327 u_int32_t hfs_sparsebandblks;
b0d623f7 328 u_int64_t hfs_backingfs_maxblocks;
55e303ae 329#endif
91447636
A
330 size_t hfs_max_inline_attrsize;
331
332 lck_mtx_t hfs_mutex; /* protects access to hfsmount data */
fe8ab488
A
333
334 uint32_t hfs_syncers; // Count of the number of syncers running
335 enum {
336 HFS_THAWED,
337 HFS_WANT_TO_FREEZE, // This state stops hfs_sync from starting
338 HFS_FREEZING, // We're in this state whilst we're flushing
339 HFS_FROZEN // Everything gets blocked in hfs_lock_global
340 } hfs_freeze_state;
341 union {
342 /*
343 * When we're freezing (HFS_FREEZING) but not yet
344 * frozen (HFS_FROZEN), we record the freezing thread
345 * so that we stop other threads from taking locks,
346 * but allow the freezing thread.
347 */
348 const struct thread *hfs_freezing_thread;
349 /*
350 * Once we have frozen (HFS_FROZEN), we record the
351 * process so that if it dies, we can automatically
352 * unfreeze.
353 */
354 proc_t hfs_freezing_proc;
355 };
356
357 thread_t hfs_downgrading_thread; /* thread who's downgrading to rdonly */
0c530ab8
A
358
359 /* Resize variables: */
6d2010ae
A
360 u_int32_t hfs_resize_blocksmoved;
361 u_int32_t hfs_resize_totalblocks;
362 u_int32_t hfs_resize_progress;
316670eb 363#if CONFIG_PROTECT
fe8ab488 364 /* Data Protection fields */
3e170ce0 365 cpx_t hfs_resize_cpx;
316670eb 366 u_int16_t hfs_running_cp_major_vers;
fe8ab488
A
367 uint32_t default_cp_class; /* default effective class value */
368 uint64_t cproot_flags;
369 uint8_t cp_crypto_generation;
370 uint8_t hfs_cp_lock_state; /* per-mount device lock state info */
3e170ce0
A
371#if HFS_TMPDBG
372#if !SECURE_KERNEL
373 boolean_t hfs_cp_verbose;
374#endif
316670eb
A
375#endif
376
3e170ce0 377#endif
e2fac8b1 378
b0d623f7
A
379 /* Per mount cnode hash variables: */
380 lck_mtx_t hfs_chash_mutex; /* protects access to cnode hash table */
381 u_long hfs_cnodehash; /* size of cnode hash table - 1 */
382 LIST_HEAD(cnodehashhead, cnode) *hfs_cnodehashtbl; /* base of cnode hash */
383
39236c6e
A
384 /* Per mount fileid hash variables (protected by catalog lock!) */
385 u_long hfs_idhash; /* size of cnid/fileid hash table -1 */
386 LIST_HEAD(idhashhead, cat_preflightid) *hfs_idhashtbl; /* base of ID hash */
b0d623f7 387
22ba694c
A
388 // Records the oldest outstanding sync request
389 struct timeval hfs_sync_req_oldest;
390
391 // Records whether a sync has been queued or is in progress
392 boolean_t hfs_sync_incomplete;
6d2010ae 393
22ba694c
A
394 thread_call_t hfs_syncer; // removeable devices get sync'ed by this guy
395
396 /* Records the syncer thread so that we can avoid the syncer
397 queing more syncs. */
398 thread_t hfs_syncer_thread;
399
400 // Not currently used except for debugging purposes
401 uint32_t hfs_active_threads;
3e170ce0
A
402
403 enum {
404 // These are indices into the array below
405
406 // Tentative ranges can be claimed back at any time
407 HFS_TENTATIVE_BLOCKS = 0,
408
409 // Locked ranges cannot be claimed back, but the allocation
410 // won't have been written to disk yet
411 HFS_LOCKED_BLOCKS = 1,
412 };
413 // These lists are not sorted like a range list usually is
414 struct rl_head hfs_reserved_ranges[2];
1c79356b
A
415} hfsmount_t;
416
39236c6e 417/*
22ba694c
A
418 * HFS_META_DELAY is a duration (in usecs) used for triggering the
419 * hfs_syncer() routine. We will back off if writes are in
420 * progress, but...
421 * HFS_MAX_META_DELAY is the maximum time we will allow the
422 * syncer to be delayed.
39236c6e 423 */
22ba694c
A
424enum {
425 HFS_META_DELAY = 100 * 1000, // 0.1 secs
426 HFS_MAX_META_DELAY = 5000 * 1000 // 5 secs
427};
e2fac8b1 428
91447636
A
429typedef hfsmount_t ExtendedVCB;
430
2d21ac55 431/* Aliases for legacy (Mac OS 9) field names */
91447636
A
432#define vcbLsMod hfs_mtime
433#define vcbVolBkUp hfs_btime
434#define extentsRefNum hfs_extents_vp
435#define catalogRefNum hfs_catalog_vp
436#define allocationsRefNum hfs_allocation_vp
437#define vcbFilCnt hfs_filecount
438#define vcbDirCnt hfs_dircount
439
3e170ce0 440static inline void MarkVCBDirty(hfsmount_t *hfsmp)
2d21ac55 441{
3e170ce0
A
442 hfsmp->hfs_header_dirty = true;
443}
444
445static inline void MarkVCBClean(hfsmount_t *hfsmp)
446{
447 hfsmp->hfs_header_dirty = false;
448 hfsmp->hfs_header_minor_change = false;
449}
450
451static inline bool IsVCBDirty(ExtendedVCB *vcb)
452{
453 return vcb->hfs_header_minor_change || vcb->hfs_header_dirty;
2d21ac55
A
454}
455
3e170ce0
A
456// Header is changed but won't be inconsistent if we don't write it
457static inline void hfs_note_header_minor_change(hfsmount_t *hfsmp)
2d21ac55 458{
3e170ce0 459 hfsmp->hfs_header_minor_change = true;
2d21ac55
A
460}
461
3e170ce0
A
462// Must header be flushed for volume to be consistent?
463static inline bool hfs_header_needs_flushing(hfsmount_t *hfsmp)
2d21ac55 464{
3e170ce0
A
465 return (hfsmp->hfs_header_dirty
466 || ISSET(hfsmp->hfs_catalog_cp->c_flag, C_MODIFIED)
467 || ISSET(hfsmp->hfs_extents_cp->c_flag, C_MODIFIED)
468 || (hfsmp->hfs_attribute_cp
469 && ISSET(hfsmp->hfs_attribute_cp->c_flag, C_MODIFIED))
470 || (hfsmp->hfs_allocation_cp
471 && ISSET(hfsmp->hfs_allocation_cp->c_flag, C_MODIFIED))
472 || (hfsmp->hfs_startup_cp
473 && ISSET(hfsmp->hfs_startup_cp->c_flag, C_MODIFIED)));
2d21ac55 474}
55e303ae 475
2d21ac55
A
476/*
477 * There are two private directories in HFS+.
478 *
479 * One contains inodes for files that are hardlinked or open/unlinked.
480 * The other contains inodes for directories that are hardlinked.
481 */
482enum privdirtype {FILE_HARDLINKS, DIR_HARDLINKS};
55e303ae 483
39236c6e 484#define HFS_ALLOCATOR_SCAN_INFLIGHT 0x0001 /* scan started */
fe8ab488 485#define HFS_ALLOCATOR_SCAN_COMPLETED 0x0002 /* initial scan was completed */
1c79356b 486
2d21ac55
A
487/* HFS mount point flags */
488#define HFS_READ_ONLY 0x00001
489#define HFS_UNKNOWN_PERMS 0x00002
490#define HFS_WRITEABLE_MEDIA 0x00004
491#define HFS_CLEANED_ORPHANS 0x00008
492#define HFS_X 0x00010
493#define HFS_CASE_SENSITIVE 0x00020
494#define HFS_STANDARD 0x00040
495#define HFS_METADATA_ZONE 0x00080
496#define HFS_FRAGMENTED_FREESPACE 0x00100
497#define HFS_NEED_JNL_RESET 0x00200
498#define HFS_HAS_SPARSE_DEVICE 0x00400
499#define HFS_RESIZE_IN_PROGRESS 0x00800
500#define HFS_QUOTAS 0x01000
501#define HFS_CREATING_BTREE 0x02000
502/* When set, do not update nextAllocation in the mount structure */
503#define HFS_SKIP_UPDATE_NEXT_ALLOCATION 0x04000
6d2010ae 504/* When set, the file system supports extent-based extended attributes */
2d21ac55
A
505#define HFS_XATTR_EXTENTS 0x08000
506#define HFS_FOLDERCOUNT 0x10000
507/* When set, the file system exists on a virtual device, like disk image */
508#define HFS_VIRTUAL_DEVICE 0x20000
593a1d5f
A
509/* When set, we're in hfs_changefs, so hfs_sync should do nothing. */
510#define HFS_IN_CHANGEFS 0x40000
c910b4d9 511/* When set, we are in process of downgrading or have downgraded to read-only,
b0d623f7
A
512 * so hfs_start_transaction should return EROFS.
513 */
c910b4d9 514#define HFS_RDONLY_DOWNGRADE 0x80000
b0d623f7 515#define HFS_DID_CONTIG_SCAN 0x100000
316670eb 516#define HFS_UNMAP 0x200000
fe8ab488
A
517#define HFS_SSD 0x400000
518#define HFS_SUMMARY_TABLE 0x800000
519#define HFS_CS 0x1000000
3e170ce0
A
520#define HFS_CS_METADATA_PIN 0x2000000
521#define HFS_CS_HOTFILE_PIN 0x4000000 /* cooperative fusion (enables a hotfile variant) */
522#define HFS_FEATURE_BARRIER 0x8000000 /* device supports barrier-only flush */
523#define HFS_CS_SWAPFILE_PIN 0x10000000
316670eb 524
2d21ac55
A
525/* Macro to update next allocation block in the HFS mount structure. If
526 * the HFS_SKIP_UPDATE_NEXT_ALLOCATION is set, do not update
527 * nextAllocation block.
528 */
529#define HFS_UPDATE_NEXT_ALLOCATION(hfsmp, new_nextAllocation) \
530 { \
531 if ((hfsmp->hfs_flags & HFS_SKIP_UPDATE_NEXT_ALLOCATION) == 0)\
532 hfsmp->nextAllocation = new_nextAllocation; \
533 } \
534
2d21ac55
A
535/* Macro for incrementing and decrementing the folder count in a cnode
536 * attribute only if the HFS_FOLDERCOUNT bit is set in the mount flags
537 * and kHFSHasFolderCount bit is set in the cnode flags. Currently these
538 * bits are only set for case sensitive HFS+ volumes.
539 */
540#define INC_FOLDERCOUNT(hfsmp, cattr) \
541 if ((hfsmp->hfs_flags & HFS_FOLDERCOUNT) && \
542 (cattr.ca_recflags & kHFSHasFolderCountMask)) { \
543 cattr.ca_dircount++; \
544 } \
545
546#define DEC_FOLDERCOUNT(hfsmp, cattr) \
547 if ((hfsmp->hfs_flags & HFS_FOLDERCOUNT) && \
548 (cattr.ca_recflags & kHFSHasFolderCountMask) && \
549 (cattr.ca_dircount > 0)) { \
550 cattr.ca_dircount--; \
551 } \
1c79356b 552
9bccf70c 553typedef struct filefork FCB;
1c79356b 554
2d21ac55
A
555/*
556 * Macros for creating item names for our special/private directories.
557 */
558#define MAKE_INODE_NAME(name, size, linkno) \
559 (void) snprintf((name), size, "%s%d", HFS_INODE_PREFIX, (linkno))
560#define HFS_INODE_PREFIX_LEN 5
1c79356b 561
2d21ac55
A
562#define MAKE_DIRINODE_NAME(name, size, linkno) \
563 (void) snprintf((name), size, "%s%d", HFS_DIRINODE_PREFIX, (linkno))
564#define HFS_DIRINODE_PREFIX_LEN 4
1c79356b 565
2d21ac55
A
566#define MAKE_DELETED_NAME(NAME, size, FID) \
567 (void) snprintf((NAME), size, "%s%d", HFS_DELETE_PREFIX, (FID))
568#define HFS_DELETE_PREFIX_LEN 4
1c79356b 569
1c79356b 570
9bccf70c
A
571#define HFS_AVERAGE_NAME_SIZE 22
572#define AVERAGE_HFSDIRENTRY_SIZE (8+HFS_AVERAGE_NAME_SIZE+4)
1c79356b 573
91447636
A
574#define STD_DIRENT_LEN(namlen) \
575 ((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3))
1c79356b 576
91447636 577#define EXT_DIRENT_LEN(namlen) \
39236c6e 578 ((sizeof(struct direntry) + (namlen) - (MAXPATHLEN-1) + 7) & ~7)
1c79356b 579
1c79356b
A
580
581enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
582
1c79356b
A
583
584/* macro to determine if hfs or hfsplus */
585#define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord)
586#define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord)
587
588
1c79356b
A
589/*
590 * Various ways to acquire a VFS mount point pointer:
591 */
91447636 592#define VTOVFS(VP) vnode_mount((VP))
1c79356b 593#define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp)
91447636 594#define VCBTOVFS(VCB) HFSTOVFS(VCB)
1c79356b
A
595
596/*
597 * Various ways to acquire an HFS mount point pointer:
598 */
91447636
A
599#define VTOHFS(VP) ((struct hfsmount *)vfs_fsprivate(vnode_mount((VP))))
600#define VFSTOHFS(MP) ((struct hfsmount *)vfs_fsprivate((MP)))
601#define VCBTOHFS(VCB) (VCB)
602#define FCBTOHFS(FCB) ((struct hfsmount *)vfs_fsprivate(vnode_mount((FCB)->ff_cp->c_vp)))
1c79356b
A
603
604/*
91447636 605 * Various ways to acquire a VCB (legacy) pointer:
1c79356b 606 */
91447636
A
607#define VTOVCB(VP) VTOHFS(VP)
608#define VFSTOVCB(MP) VFSTOHFS(MP)
609#define HFSTOVCB(HFSMP) (HFSMP)
610#define FCBTOVCB(FCB) FCBTOHFS(FCB)
1c79356b
A
611
612
613#define E_NONE 0
614#define kHFSBlockSize 512
1c79356b 615
9bccf70c
A
616/*
617 * Macros for getting the MDB/VH sector and offset
618 */
619#define HFS_PRI_SECTOR(blksize) (1024 / (blksize))
620#define HFS_PRI_OFFSET(blksize) ((blksize) > 1024 ? 1024 : 0)
d52fe63f
A
621
622#define HFS_ALT_SECTOR(blksize, blkcnt) (((blkcnt) - 1) - (512 / (blksize)))
623#define HFS_ALT_OFFSET(blksize) ((blksize) > 1024 ? (blksize) - 1024 : 0)
624
593a1d5f
A
625/* Convert the logical sector number to be aligned on physical block size boundary.
626 * We are assuming the partition is a multiple of physical block size.
627 */
628#define HFS_PHYSBLK_ROUNDDOWN(sector_num, log_per_phys) ((sector_num / log_per_phys) * log_per_phys)
91447636
A
629
630/*
631 * HFS specific fcntl()'s
632 */
91447636
A
633#define HFS_GET_BOOT_INFO (FCNTL_FS_SPECIFIC_BASE + 0x00004)
634#define HFS_SET_BOOT_INFO (FCNTL_FS_SPECIFIC_BASE + 0x00005)
6d2010ae
A
635/* See HFSIOC_EXT_BULKACCESS and friends for HFS specific fsctls*/
636
91447636
A
637
638
1c79356b
A
639/*
640 * This is the straight GMT conversion constant:
641 * 00:00:00 January 1, 1970 - 00:00:00 January 1, 1904
642 * (3600 * 24 * ((365 * (1970 - 1904)) + (((1970 - 1904) / 4) + 1)))
643 */
644#define MAC_GMT_FACTOR 2082844800UL
645
fe8ab488 646static inline __attribute__((const))
3e170ce0 647off_t hfs_blk_to_bytes(uint32_t blk, uint32_t blk_size)
fe8ab488 648{
3e170ce0 649 return (off_t)blk * blk_size; // Avoid the overflow
fe8ab488 650}
1c79356b 651
3e170ce0
A
652/*
653 * For now, we use EIO to indicate consistency issues. It is safe to
654 * return or assign an error value to HFS_EINCONSISTENT but it is
655 * *not* safe to compare against it because EIO can be generated for
656 * other reasons. We take advantage of the fact that == has
657 * left-to-right associativity and so any uses of:
658 *
659 * if (error == HFS_EINCONSISTENT)
660 *
661 * will produce a compiler warning: "comparison between pointer and
662 * integer".
663 *
664 * Note that not everwhere is consistent with the use of
665 * HFS_EINCONSISTENT. Some places return EINVAL, EIO directly or
666 * other error codes.
667 */
668#define HFS_EINCONSISTENT (void *)0 == (void *)0 ? EIO : EIO
669
2d21ac55
A
670/*****************************************************************************
671 FUNCTION PROTOTYPES
672******************************************************************************/
1c79356b 673
2d21ac55
A
674/*****************************************************************************
675 hfs_vnop_xxx functions from different files
676******************************************************************************/
677int hfs_vnop_readdirattr(struct vnop_readdirattr_args *); /* in hfs_attrlist.c */
fe8ab488 678int hfs_vnop_getattrlistbulk(struct vnop_getattrlistbulk_args *); /* in hfs_attrlist.c */
1c79356b 679
2d21ac55
A
680int hfs_vnop_inactive(struct vnop_inactive_args *); /* in hfs_cnode.c */
681int hfs_vnop_reclaim(struct vnop_reclaim_args *); /* in hfs_cnode.c */
316670eb 682
6d2010ae
A
683int hfs_set_backingstore (struct vnode *vp, int val); /* in hfs_cnode.c */
684int hfs_is_backingstore (struct vnode *vp, int *val); /* in hfs_cnode.c */
685
2d21ac55 686int hfs_vnop_link(struct vnop_link_args *); /* in hfs_link.c */
9bccf70c 687
2d21ac55 688int hfs_vnop_lookup(struct vnop_lookup_args *); /* in hfs_lookup.c */
b4c24cb9 689
2d21ac55 690int hfs_vnop_search(struct vnop_searchfs_args *); /* in hfs_search.c */
1c79356b 691
2d21ac55
A
692int hfs_vnop_read(struct vnop_read_args *); /* in hfs_readwrite.c */
693int hfs_vnop_write(struct vnop_write_args *); /* in hfs_readwrite.c */
694int hfs_vnop_ioctl(struct vnop_ioctl_args *); /* in hfs_readwrite.c */
695int hfs_vnop_select(struct vnop_select_args *); /* in hfs_readwrite.c */
696int hfs_vnop_strategy(struct vnop_strategy_args *); /* in hfs_readwrite.c */
697int hfs_vnop_allocate(struct vnop_allocate_args *); /* in hfs_readwrite.c */
698int hfs_vnop_pagein(struct vnop_pagein_args *); /* in hfs_readwrite.c */
699int hfs_vnop_pageout(struct vnop_pageout_args *); /* in hfs_readwrite.c */
700int hfs_vnop_bwrite(struct vnop_bwrite_args *); /* in hfs_readwrite.c */
701int hfs_vnop_blktooff(struct vnop_blktooff_args *); /* in hfs_readwrite.c */
702int hfs_vnop_offtoblk(struct vnop_offtoblk_args *); /* in hfs_readwrite.c */
703int hfs_vnop_blockmap(struct vnop_blockmap_args *); /* in hfs_readwrite.c */
3e170ce0 704errno_t hfs_flush_invalid_ranges(vnode_t vp); /* in hfs_readwrite.c */
1c79356b 705
2d21ac55
A
706int hfs_vnop_getxattr(struct vnop_getxattr_args *); /* in hfs_xattr.c */
707int hfs_vnop_setxattr(struct vnop_setxattr_args *); /* in hfs_xattr.c */
708int hfs_vnop_removexattr(struct vnop_removexattr_args *); /* in hfs_xattr.c */
709int hfs_vnop_listxattr(struct vnop_listxattr_args *); /* in hfs_xattr.c */
710#if NAMEDSTREAMS
711extern int hfs_vnop_getnamedstream(struct vnop_getnamedstream_args*);
712extern int hfs_vnop_makenamedstream(struct vnop_makenamedstream_args*);
713extern int hfs_vnop_removenamedstream(struct vnop_removenamedstream_args*);
714#endif
9bccf70c 715
1c79356b 716
2d21ac55
A
717/*****************************************************************************
718 Functions from MacOSStubs.c
719******************************************************************************/
720time_t to_bsd_time(u_int32_t hfs_time);
9bccf70c 721
2d21ac55 722u_int32_t to_hfs_time(time_t bsd_time);
1c79356b 723
1c79356b 724
2d21ac55
A
725/*****************************************************************************
726 Functions from hfs_encodinghint.c
727******************************************************************************/
728u_int32_t hfs_pickencoding(const u_int16_t *src, int len);
9bccf70c 729
2d21ac55 730u_int32_t hfs_getencodingbias(void);
1c79356b 731
2d21ac55 732void hfs_setencodingbias(u_int32_t bias);
b4c24cb9 733
2d21ac55
A
734
735/*****************************************************************************
736 Functions from hfs_encodings.c
737******************************************************************************/
738void hfs_converterinit(void);
1c79356b 739
39236c6e
A
740int hfs_relconverter (u_int32_t encoding);
741
1c79356b
A
742int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode,
743 unicode_to_hfs_func_t *get_hfsname);
744
39236c6e 745#if CONFIG_HFS_STD
2d21ac55 746int hfs_to_utf8(ExtendedVCB *vcb, const Str31 hfs_str, ByteCount maxDstLen,
1c79356b
A
747 ByteCount *actualDstLen, unsigned char* dstStr);
748
749int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr,
750 Str31 dstStr);
751
2d21ac55 752int mac_roman_to_utf8(const Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen,
1c79356b
A
753 unsigned char* dstStr);
754
755int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr);
756
2d21ac55 757int mac_roman_to_unicode(const Str31 hfs_str, UniChar *uni_str, u_int32_t maxCharLen, u_int32_t *usedCharLen);
0b4e3aa0 758
2d21ac55 759int unicode_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, u_int16_t* srcStr, Str31 dstStr, int retry);
39236c6e 760#endif
9bccf70c 761
2d21ac55
A
762/*****************************************************************************
763 Functions from hfs_notifications.c
764******************************************************************************/
765void hfs_generate_volume_notifications(struct hfsmount *hfsmp);
9bccf70c
A
766
767
2d21ac55
A
768/*****************************************************************************
769 Functions from hfs_readwrite.c
770******************************************************************************/
771extern int hfs_relocate(struct vnode *, u_int32_t, kauth_cred_t, struct proc *);
9bccf70c 772
3e170ce0
A
773/* flags for hfs_pin_block_range() and hfs_pin_vnode() */
774#define HFS_PIN_IT 0x0001
775#define HFS_UNPIN_IT 0x0002
776#define HFS_TEMP_PIN 0x0004
777#define HFS_EVICT_PIN 0x0008
778#define HFS_DATALESS_PIN 0x0010
779
780//
781// pin/un-pin an explicit range of blocks to the "fast" (usually ssd) device
782//
783int hfs_pin_block_range(struct hfsmount *hfsmp, int pin_state, uint32_t start_block, uint32_t nblocks, vfs_context_t ctx);
784
785//
786// pin/un-pin all the extents belonging to a vnode.
787// also, if it is non-null, "num_blocks_pinned" returns the number of blocks pin/unpinned by the function
788//
789int hfs_pin_vnode(struct hfsmount *hfsmp, struct vnode *vp, int pin_state, uint32_t *num_blocks_pinned, vfs_context_t ctx);
790
791
792int hfs_pin_overflow_extents (struct hfsmount *hfsmp, uint32_t fileid, uint8_t forktype, uint32_t *pinned);
793
794
39236c6e 795/* Flags for HFS truncate */
fe8ab488
A
796#define HFS_TRUNCATE_SKIPTIMES 0x00000002 /* implied by skipupdate; it is a subset */
797
39236c6e 798
fe8ab488 799extern int hfs_truncate(struct vnode *, off_t, int, int, vfs_context_t);
d7e50217 800
6d2010ae
A
801extern int hfs_release_storage (struct hfsmount *hfsmp, struct filefork *datafork,
802 struct filefork *rsrcfork, u_int32_t fileid);
803
804extern int hfs_prepare_release_storage (struct hfsmount *hfsmp, struct vnode *vp);
805
2d21ac55 806extern int hfs_bmap(struct vnode *, daddr_t, struct vnode **, daddr64_t *, unsigned int *);
55e303ae 807
fe8ab488
A
808extern errno_t hfs_ubc_setsize(vnode_t vp, off_t len, bool have_cnode_lock);
809
810
811/*****************************************************************************
812 Functions from hfs_resize.c
813******************************************************************************/
814int hfs_extendfs(struct hfsmount *hfsmp, u_int64_t newsize, vfs_context_t context);
815int hfs_truncatefs(struct hfsmount *hfsmp, u_int64_t newsize, vfs_context_t context);
91447636 816
91447636 817
2d21ac55
A
818/*****************************************************************************
819 Functions from hfs_vfsops.c
820******************************************************************************/
821int hfs_mountroot(mount_t mp, vnode_t rvp, vfs_context_t context);
91447636 822
2d21ac55
A
823/* used as a callback by the journaling code */
824extern void hfs_sync_metadata(void *arg);
91447636 825
6d2010ae 826extern int hfs_vget(struct hfsmount *, cnid_t, struct vnode **, int, int);
91447636 827
2d21ac55 828extern void hfs_setencodingbits(struct hfsmount *hfsmp, u_int32_t encoding);
91447636 829
2d21ac55
A
830enum volop {VOL_UPDATE, VOL_MKDIR, VOL_RMDIR, VOL_MKFILE, VOL_RMFILE};
831extern int hfs_volupdate(struct hfsmount *hfsmp, enum volop op, int inroot);
832
3e170ce0
A
833enum {
834 HFS_FVH_WAIT = 0x0001,
835 HFS_FVH_WRITE_ALT = 0x0002,
836 HFS_FVH_FLUSH_IF_DIRTY = 0x0004,
837};
838typedef uint32_t hfs_flush_volume_header_options_t;
839int hfs_flushvolumeheader(struct hfsmount *hfsmp, hfs_flush_volume_header_options_t);
91447636
A
840
841extern int hfs_extendfs(struct hfsmount *, u_int64_t, vfs_context_t);
842extern int hfs_truncatefs(struct hfsmount *, u_int64_t, vfs_context_t);
0c530ab8 843extern int hfs_resize_progress(struct hfsmount *, u_int32_t *);
91447636 844
2d21ac55
A
845/* If a runtime corruption is detected, mark the volume inconsistent
846 * bit in the volume attributes.
847 */
fe8ab488
A
848
849typedef enum {
850 HFS_INCONSISTENCY_DETECTED,
851
852 // Used when unable to rollback an operation that failed
853 HFS_ROLLBACK_FAILED,
854
855 // Used when the latter part of an operation failed, but we chose not to roll back
856 HFS_OP_INCOMPLETE,
857
858 // Used when someone told us to force an fsck on next mount
859 HFS_FSCK_FORCED,
860} hfs_inconsistency_reason_t;
861
862void hfs_mark_inconsistent(struct hfsmount *hfsmp,
863 hfs_inconsistency_reason_t reason);
2d21ac55 864
39236c6e
A
865void hfs_scan_blocks (struct hfsmount *hfsmp);
866
2d21ac55
A
867/*****************************************************************************
868 Functions from hfs_vfsutils.c
869******************************************************************************/
b0d623f7
A
870u_int32_t BestBlockSizeFit(u_int32_t allocationBlockSize,
871 u_int32_t blockSizeLimit,
872 u_int32_t baseMultiple);
2d21ac55 873
39236c6e 874#if CONFIG_HFS_STD
2d21ac55
A
875OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
876 struct proc *p);
39236c6e 877#endif
2d21ac55
A
878OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
879 off_t embeddedOffset, u_int64_t disksize, struct proc *p, void *args, kauth_cred_t cred);
880
c18c124e
A
881OSErr hfs_ValidateHFSPlusVolumeHeader(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp);
882
2d21ac55
A
883extern int hfsUnmount(struct hfsmount *hfsmp, struct proc *p);
884
fe8ab488 885extern bool overflow_extents(struct filefork *fp);
2d21ac55
A
886
887extern int hfs_owner_rights(struct hfsmount *hfsmp, uid_t cnode_uid, kauth_cred_t cred,
888 struct proc *p, int invokesuperuserstatus);
91447636 889
6d2010ae
A
890extern int check_for_tracked_file(struct vnode *vp, time_t ctime, uint64_t op_type, void *arg);
891extern int check_for_dataless_file(struct vnode *vp, uint64_t op_type);
22ba694c 892extern int hfs_generate_document_id(struct hfsmount *hfsmp, uint32_t *docid);
3e170ce0 893extern void hfs_pin_fs_metadata(struct hfsmount *hfsmp);
22ba694c 894
fe8ab488
A
895/* Return information about number of metadata blocks for volume */
896extern int hfs_getinfo_metadata_blocks(struct hfsmount *hfsmp, struct hfsinfo_metadata *hinfo);
6d2010ae
A
897
898/*
899 * Journal lock function prototypes
900 */
39236c6e 901int hfs_lock_global (struct hfsmount *hfsmp, enum hfs_locktype locktype);
6d2010ae
A
902void hfs_unlock_global (struct hfsmount *hfsmp);
903
39236c6e
A
904/* HFS mount lock/unlock prototypes */
905void hfs_lock_mount (struct hfsmount *hfsmp);
906void hfs_unlock_mount (struct hfsmount *hfsmp);
907
91447636
A
908
909/* HFS System file locking */
910#define SFL_CATALOG 0x0001
911#define SFL_EXTENTS 0x0002
912#define SFL_BITMAP 0x0004
913#define SFL_ATTRIBUTE 0x0008
2d21ac55 914#define SFL_STARTUP 0x0010
fe8ab488
A
915#define SFL_VM_PRIV 0x0020
916#define SFL_VALIDMASK (SFL_CATALOG | SFL_EXTENTS | SFL_BITMAP | SFL_ATTRIBUTE | SFL_STARTUP | SFL_VM_PRIV)
91447636 917
b0d623f7 918extern u_int32_t GetFileInfo(ExtendedVCB *vcb, u_int32_t dirid, const char *name,
2d21ac55
A
919 struct cat_attr *fattr, struct cat_fork *forkinfo);
920
921extern void hfs_remove_orphans(struct hfsmount *);
922
923u_int32_t GetLogicalBlockSize(struct vnode *vp);
924
925extern u_int32_t hfs_freeblks(struct hfsmount * hfsmp, int wantreserve);
926
927short MacToVFSError(OSErr err);
928
6d2010ae 929void hfs_metadatazone_init(struct hfsmount *hfsmp, int disable);
0b4c1975 930
2d21ac55
A
931/* HFS directory hint functions. */
932extern directoryhint_t * hfs_getdirhint(struct cnode *, int, int);
933extern void hfs_reldirhint(struct cnode *, directoryhint_t *);
934extern void hfs_reldirhints(struct cnode *, int);
935extern void hfs_insertdirhint(struct cnode *, directoryhint_t *);
936
937extern int hfs_namecmp(const u_int8_t *str1, size_t len1, const u_int8_t *str2, size_t len2);
938
939extern int hfs_early_journal_init(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
940 void *_args, off_t embeddedOffset, daddr64_t mdb_offset,
941 HFSMasterDirectoryBlock *mdbp, kauth_cred_t cred);
942
943extern int hfs_virtualmetafile(struct cnode *);
944
945extern int hfs_start_transaction(struct hfsmount *hfsmp);
946extern int hfs_end_transaction(struct hfsmount *hfsmp);
fe8ab488
A
947extern void hfs_journal_lock(struct hfsmount *hfsmp);
948extern void hfs_journal_unlock(struct hfsmount *hfsmp);
22ba694c
A
949extern void hfs_syncer_lock(struct hfsmount *hfsmp);
950extern void hfs_syncer_unlock(struct hfsmount *hfsmp);
951extern void hfs_syncer_wait(struct hfsmount *hfsmp);
952extern void hfs_syncer_wakeup(struct hfsmount *hfsmp);
953extern void hfs_syncer_queue(thread_call_t syncer);
e2fac8b1 954extern void hfs_sync_ejectable(struct hfsmount *hfsmp);
2d21ac55 955
3e170ce0
A
956typedef enum hfs_flush_mode {
957 HFS_FLUSH_JOURNAL, // Flush journal
958 HFS_FLUSH_JOURNAL_META, // Flush journal and metadata blocks
959 HFS_FLUSH_FULL, // Flush journal and does a cache flush
960 HFS_FLUSH_CACHE, // Flush track cache to media
961 HFS_FLUSH_BARRIER, // Barrier-only flush to ensure write order
962 HFS_FLUSH_JOURNAL_BARRIER // Flush journal with barrier
963} hfs_flush_mode_t;
964
965extern errno_t hfs_flush(struct hfsmount *hfsmp, hfs_flush_mode_t mode);
966
6d2010ae
A
967extern void hfs_trim_callback(void *arg, uint32_t extent_count, const dk_extent_t *extents);
968
b0d623f7
A
969/* Erase unused Catalog nodes due to <rdar://problem/6947811>. */
970extern int hfs_erase_unused_nodes(struct hfsmount *hfsmp);
971
22ba694c
A
972extern uint64_t hfs_usecs_to_deadline(uint64_t usecs);
973
fe8ab488
A
974extern int hfs_freeze(struct hfsmount *hfsmp);
975extern int hfs_thaw(struct hfsmount *hfsmp, const struct proc *process);
976
2d21ac55
A
977
978/*****************************************************************************
979 Functions from hfs_vnops.c
980******************************************************************************/
981int hfs_write_access(struct vnode *vp, kauth_cred_t cred, struct proc *p, Boolean considerFlags);
982
983int hfs_chmod(struct vnode *vp, int mode, kauth_cred_t cred, struct proc *p);
984
985int hfs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, struct proc *p);
986
987#define kMaxSecsForFsync 5
988#define HFS_SYNCTRANS 1
989extern int hfs_btsync(struct vnode *vp, int sync_transaction);
990
991extern void replace_desc(struct cnode *cp, struct cat_desc *cdp);
992
993extern int hfs_vgetrsrc(struct hfsmount *hfsmp, struct vnode *vp,
fe8ab488 994 struct vnode **rvpp);
2d21ac55 995
3e170ce0
A
996typedef enum {
997 // Push all modifications to disk (including minor ones)
998 HFS_UPDATE_FORCE = 0x01,
999} hfs_update_options_t;
1000
1001extern int hfs_update(struct vnode *, int options);
1002
1003typedef enum hfs_sync_mode {
1004 HFS_FSYNC,
1005 HFS_FSYNC_FULL,
1006 HFS_FSYNC_BARRIER
1007} hfs_fsync_mode_t;
1008
1009extern int hfs_fsync(struct vnode *, int, hfs_fsync_mode_t, struct proc *);
2d21ac55 1010
3e170ce0
A
1011const struct cat_fork *
1012hfs_prepare_fork_for_update(filefork_t *ff,
1013 const struct cat_fork *cf,
1014 struct cat_fork *cf_buf,
1015 uint32_t block_size);
2d21ac55
A
1016
1017/*****************************************************************************
1018 Functions from hfs_xattr.c
1019******************************************************************************/
6d2010ae 1020
39236c6e
A
1021/*
1022 * Maximum extended attribute size supported for all extended attributes except
6d2010ae
A
1023 * resource fork and finder info.
1024 */
39236c6e 1025#define HFS_XATTR_MAXSIZE INT32_MAX
6d2010ae
A
1026
1027/* Number of bits used to represent maximum extended attribute size */
39236c6e 1028#define HFS_XATTR_SIZE_BITS 31
6d2010ae 1029
2d21ac55
A
1030int hfs_attrkeycompare(HFSPlusAttrKey *searchKey, HFSPlusAttrKey *trialKey);
1031int hfs_buildattrkey(u_int32_t fileID, const char *attrname, HFSPlusAttrKey *key);
1032void hfs_xattr_init(struct hfsmount * hfsmp);
1033int file_attribute_exist(struct hfsmount *hfsmp, uint32_t fileID);
6d2010ae 1034int init_attrdata_vnode(struct hfsmount *hfsmp);
fe8ab488
A
1035int hfs_xattr_read(vnode_t vp, const char *name, void *data, size_t *size);
1036int hfs_getxattr_internal(cnode_t *, struct vnop_getxattr_args *,
1037 struct hfsmount *, u_int32_t);
1038int hfs_xattr_write(vnode_t vp, const char *name, const void *data, size_t size);
1039int hfs_setxattr_internal(struct cnode *, const void *, size_t,
1040 struct vnop_setxattr_args *, struct hfsmount *, u_int32_t);
3e170ce0
A
1041extern int hfs_removeallattr(struct hfsmount *hfsmp, u_int32_t fileid,
1042 bool *open_transaction);
04b8595b
A
1043extern int hfs_set_volxattr(struct hfsmount *hfsmp, unsigned int xattrtype, int state);
1044
2d21ac55
A
1045
1046
1047/*****************************************************************************
1048 Functions from hfs_link.c
1049******************************************************************************/
1050
1051extern int hfs_unlink(struct hfsmount *hfsmp, struct vnode *dvp, struct vnode *vp,
1052 struct componentname *cnp, int skip_reserve);
6d2010ae 1053extern int hfs_lookup_siblinglinks(struct hfsmount *hfsmp, cnid_t linkfileid,
2d21ac55 1054 cnid_t *prevlinkid, cnid_t *nextlinkid);
39236c6e
A
1055extern int hfs_lookup_lastlink(struct hfsmount *hfsmp, cnid_t linkfileid,
1056 cnid_t *nextlinkid, struct cat_desc *cdesc);
2d21ac55
A
1057extern void hfs_privatedir_init(struct hfsmount *, enum privdirtype);
1058
1059extern void hfs_savelinkorigin(cnode_t *cp, cnid_t parentcnid);
1060extern void hfs_relorigins(struct cnode *cp);
1061extern void hfs_relorigin(struct cnode *cp, cnid_t parentcnid);
1062extern int hfs_haslinkorigin(cnode_t *cp);
3e170ce0 1063extern cnid_t hfs_currentparent(cnode_t *cp, bool have_lock);
2d21ac55 1064extern cnid_t hfs_currentcnid(cnode_t *cp);
3e170ce0 1065errno_t hfs_first_link(hfsmount_t *hfsmp, cnode_t *cp, cnid_t *link_id);
2d21ac55
A
1066
1067
04b8595b
A
1068/*****************************************************************************
1069 Functions from VolumeAllocation.c
1070 ******************************************************************************/
3e170ce0 1071extern int hfs_isallocated(struct hfsmount *hfsmp, u_int32_t startingBlock, u_int32_t numBlocks);
04b8595b 1072
3e170ce0
A
1073extern int hfs_count_allocated(struct hfsmount *hfsmp, u_int32_t startBlock,
1074 u_int32_t numBlocks, u_int32_t *alloc_count);
04b8595b
A
1075
1076extern int hfs_isrbtree_active (struct hfsmount *hfsmp);
1077
1078/*****************************************************************************
1079 Functions from hfs_fsinfo.c
1080 ******************************************************************************/
1081extern errno_t hfs_get_fsinfo(struct hfsmount *hfsmp, void *a_data);
1082extern void hfs_fsinfo_data_add(struct hfs_fsinfo_data *fsinfo, uint64_t entry);
1083
9bccf70c
A
1084#endif /* __APPLE_API_PRIVATE */
1085#endif /* KERNEL */
1c79356b 1086#endif /* __HFS__ */