1/* 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 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. 14 * 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 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 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. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#ifndef __HFS__ 30#define __HFS__ 31 32#define HFS_SPARSE_DEV 1 33 34#ifdef DEBUG 35#define HFS_CHECK_LOCK_ORDER 1 36#endif 37 38#include <sys/appleapiopts.h> 39 40#ifdef KERNEL 41#ifdef __APPLE_API_PRIVATE 42#include <sys/param.h> 43#include <sys/queue.h> 44#include <sys/mount.h> 45#include <sys/vnode.h> 46#include <sys/quota.h> 47#include <sys/dirent.h> 48#include <sys/event.h> 49#include <kern/thread_call.h> 50 51#include <kern/locks.h> 52 53#include <vfs/vfs_journal.h> 54 55#include <hfs/hfs_format.h> 56#include <hfs/hfs_catalog.h> 57#include <hfs/hfs_cnode.h> 58#include <hfs/hfs_macos_defs.h> 59#include <hfs/hfs_encodings.h> 60#include <hfs/hfs_hotfiles.h> 61 62/* 63 * Just reported via MIG interface. 64 */ 65#define VERSION_STRING "hfs-2 (4-12-99)" 66 67#define HFS_LINK_MAX 32767 68 69#define HFS_MAX_DEFERED_ALLOC (1024*1024) 70 71// 400 megs is a "big" file (i.e. one that when deleted 72// would touch enough data that we should break it into 73// multiple separate transactions) 74#define HFS_BIGFILE_SIZE (400LL * 1024LL * 1024LL) 75 76 77enum { kMDBSize = 512 }; /* Size of I/O transfer to read entire MDB */ 78 79enum { kMasterDirectoryBlock = 2 }; /* MDB offset on disk in 512-byte blocks */ 80enum { kMDBOffset = kMasterDirectoryBlock * 512 }; /* MDB offset on disk in bytes */ 81 82#define kRootDirID kHFSRootFolderID 83 84 85/* number of locked buffer caches to hold for b-tree meta data */ 86#define kMaxLockedMetaBuffers 32 87 88extern struct timezone gTimeZone; 89 90 91/* How many free extents to cache per volume */ 92#define kMaxFreeExtents 10 93 94/* 95 * HFS_MINFREE gives the minimum acceptable percentage 96 * of file system blocks which may be free (but this 97 * minimum will never exceed HFS_MAXRESERVE bytes). If 98 * the free block count drops below this level only the 99 * superuser may continue to allocate blocks. 100 */ 101#define HFS_MINFREE 1 102#define HFS_MAXRESERVE ((u_int64_t)(250*1024*1024)) 103 104/* 105 * The system distinguishes between the desirable low-disk 106 * notifiaction levels for root volumes and non-root volumes. 107 * The various thresholds are computed as a fraction of the 108 * volume size, all capped at a certain fixed level 109 */ 110 111#define HFS_ROOTLOWDISKTRIGGERFRACTION 5 112#define HFS_ROOTLOWDISKTRIGGERLEVEL ((u_int64_t)(250*1024*1024)) 113#define HFS_ROOTLOWDISKSHUTOFFFRACTION 6 114#define HFS_ROOTLOWDISKSHUTOFFLEVEL ((u_int64_t)(375*1024*1024)) 115 116#define HFS_LOWDISKTRIGGERFRACTION 1 117#define HFS_LOWDISKTRIGGERLEVEL ((u_int64_t)(50*1024*1024)) 118#define HFS_LOWDISKSHUTOFFFRACTION 2 119#define HFS_LOWDISKSHUTOFFLEVEL ((u_int64_t)(75*1024*1024)) 120 121/* Internal Data structures*/ 122 123/* This structure describes the HFS specific mount structure data. */ 124typedef struct hfsmount { 125 u_int32_t hfs_flags; /* see below */ 126 127 /* Physical Description */ 128 u_int32_t hfs_logical_block_size; /* Logical block size of the disk as reported by ioctl(DKIOCGETBLOCKSIZE), always a multiple of 512 */ 129 daddr64_t hfs_logical_block_count; /* Number of logical blocks on the disk */ 130 daddr64_t hfs_alt_id_sector; /* location of alternate VH/MDB */ 131 u_int32_t hfs_physical_block_size; /* Physical block size of the disk as reported by ioctl(DKIOCGETPHYSICALBLOCKSIZE) */ 132 u_int32_t hfs_log_per_phys; /* Number of logical blocks per physical block size */ 133 134 /* Access to VFS and devices */ 135 struct mount *hfs_mp; /* filesystem vfs structure */ 136 struct vnode *hfs_devvp; /* block device mounted vnode */ 137 struct vnode * hfs_extents_vp; 138 struct vnode * hfs_catalog_vp; 139 struct vnode * hfs_allocation_vp; 140 struct vnode * hfs_attribute_vp; 141 struct vnode * hfs_startup_vp; 142 struct vnode * hfs_attrdata_vp; /* pseudo file */ 143 struct cnode * hfs_extents_cp; 144 struct cnode * hfs_catalog_cp; 145 struct cnode * hfs_allocation_cp; 146 struct cnode * hfs_attribute_cp; 147 struct cnode * hfs_startup_cp; 148 dev_t hfs_raw_dev; /* device mounted */ 149 u_int32_t hfs_logBlockSize; /* Size of buffer cache buffer for I/O */ 150 151 /* Default values for HFS standard and non-init access */ 152 uid_t hfs_uid; /* uid to set as owner of the files */ 153 gid_t hfs_gid; /* gid to set as owner of the files */ 154 mode_t hfs_dir_mask; /* mask to and with directory protection bits */ 155 mode_t hfs_file_mask; /* mask to and with file protection bits */ 156 u_long hfs_encoding; /* Default encoding for non hfs+ volumes */ 157 158 /* Persistent fields (on disk, dynamic) */ 159 time_t hfs_mtime; /* file system last modification time */ 160 u_int32_t hfs_filecount; /* number of files in file system */ 161 u_int32_t hfs_dircount; /* number of directories in file system */ 162 u_int32_t freeBlocks; /* free allocation blocks */ 163 u_int32_t nextAllocation; /* start of next allocation search */ 164 u_int32_t vcbNxtCNID; /* next unused catalog node ID - protected by catalog lock */ 165 u_int32_t vcbWrCnt; /* file system write count */ 166 u_int64_t encodingsBitmap; /* in-use encodings */ 167 u_int16_t vcbNmFls; /* HFS Only - root dir file count */ 168 u_int16_t vcbNmRtDirs; /* HFS Only - root dir directory count */ 169 170 /* Persistent fields (on disk, static) */ 171 u_int16_t vcbSigWord; 172 int16_t vcbFlags; /* Runtime flag to indicate if volume is dirty/clean */ 173 u_int32_t vcbAtrb; 174 u_int32_t vcbJinfoBlock; 175 time_t hfs_itime; /* file system creation time */ 176 time_t hfs_btime; /* file system last backup time */ 177 u_int32_t blockSize; /* size of allocation blocks */ 178 u_int32_t totalBlocks; /* total allocation blocks */ 179 u_int32_t allocLimit; /* Do not allocate this block or beyond */ 180 /* 181 * NOTE: When resizing a volume to make it smaller, allocLimit is set to the allocation 182 * block number which will contain the new alternate volume header. At all other times, 183 * allocLimit is set to totalBlocks. The allocation code uses allocLimit instead of 184 * totalBlocks to limit which blocks may be allocated, so that during a resize, we don't 185 * put new content into the blocks we're trying to truncate away. 186 */ 187 int32_t vcbClpSiz; 188 u_int32_t vcbFndrInfo[8]; 189 int16_t vcbVBMSt; /* HFS only */ 190 int16_t vcbAlBlSt; /* HFS only */ 191 192 /* vcb stuff */ 193 u_int8_t vcbVN[256]; /* volume name in UTF-8 */ 194 u_int32_t volumeNameEncodingHint; 195 u_int32_t hfsPlusIOPosOffset; /* Disk block where HFS+ starts */ 196 u_int32_t vcbVBMIOSize; /* volume bitmap I/O size */ 197 198 /* cache of largest known free extents */ 199 u_int32_t vcbFreeExtCnt; 200 HFSPlusExtentDescriptor vcbFreeExt[kMaxFreeExtents]; 201 202 u_int32_t reserveBlocks; /* free block reserve */ 203 u_int32_t loanedBlocks; /* blocks on loan for delayed allocations */ 204 205 u_int32_t localCreateDate; /* creation times for HFS+ volumes are in local time */ 206 207 /* 208 * HFS+ Private system directories (two). Any access 209 * (besides looking at the cd_cnid) requires holding 210 * the Catalog File lock. 211 */ 212 struct cat_desc hfs_private_desc[2]; 213 struct cat_attr hfs_private_attr[2]; 214 215 u_int32_t hfs_metadata_createdate; 216 hfs_to_unicode_func_t hfs_get_unicode; 217 unicode_to_hfs_func_t hfs_get_hfsname; 218 219 /* Quota variables: */ 220 struct quotafile hfs_qfiles[MAXQUOTAS]; /* quota files */ 221 222 /* Journaling variables: */ 223 void *jnl; // the journal for this volume (if one exists) 224 struct vnode *jvp; // device where the journal lives (may be equal to devvp) 225 u_int32_t jnl_start; // start block of the journal file (so we don't delete it) 226 u_int32_t jnl_size; 227 u_int32_t hfs_jnlfileid; 228 u_int32_t hfs_jnlinfoblkid; 229 lck_rw_t hfs_global_lock; 230 u_int32_t hfs_global_lock_nesting; 231 232 /* Notification variables: */ 233 unsigned long hfs_notification_conditions; 234 u_int32_t hfs_freespace_notify_warninglimit; 235 u_int32_t hfs_freespace_notify_desiredlevel; 236 237 /* time mounted and last mounted mod time "snapshot" */ 238 time_t hfs_mount_time; 239 time_t hfs_last_mounted_mtime; 240 241 /* Metadata allocation zone variables: */ 242 u_int32_t hfs_metazone_start; 243 u_int32_t hfs_metazone_end; 244 u_int32_t hfs_hotfile_start; 245 u_int32_t hfs_hotfile_end; 246 int hfs_hotfile_freeblks; 247 int hfs_hotfile_maxblks; 248 int hfs_overflow_maxblks; 249 int hfs_catalog_maxblks; 250 251 /* Hot File Clustering variables: */ 252 lck_mtx_t hfc_mutex; /* serialize hot file stages */ 253 enum hfc_stage hfc_stage; /* what are we up to... */ 254 time_t hfc_timebase; /* recording period start time */ 255 time_t hfc_timeout; /* recording period stop time */ 256 void * hfc_recdata; /* recording data (opaque) */ 257 int hfc_maxfiles; /* maximum files to track */ 258 struct vnode * hfc_filevp; 259 260#ifdef HFS_SPARSE_DEV 261 /* Sparse device variables: */ 262 struct vnode * hfs_backingfs_rootvp; 263 u_int32_t hfs_last_backingstatfs; 264 int hfs_sparsebandblks; 265#endif 266 size_t hfs_max_inline_attrsize; 267 268 lck_mtx_t hfs_mutex; /* protects access to hfsmount data */ 269 void *hfs_freezing_proc; /* who froze the fs */ 270 void *hfs_downgrading_proc; /* process who's downgrading to rdonly */ 271 lck_rw_t hfs_insync; /* protects sync/freeze interaction */ 272 273 /* Resize variables: */ 274 u_int32_t hfs_resize_filesmoved; 275 u_int32_t hfs_resize_totalfiles; 276 277 /* 278 * About the sync counters: 279 * hfs_sync_scheduled keeps track whether a timer was scheduled but we 280 * haven't started processing the callback (i.e. we 281 * haven't begun the flush). This will be non-zero 282 * even if the callback has been invoked, before we 283 * start the flush. 284 * hfs_sync_incomplete keeps track of the number of callbacks that have 285 * not completed yet (including callbacks not yet 286 * invoked). We cannot safely unmount until this 287 * drops to zero. 288 * 289 * In both cases, we use counters, not flags, so that we can avoid 290 * taking locks. 291 */ 292 int32_t hfs_sync_scheduled; 293 int32_t hfs_sync_incomplete; 294 u_int64_t hfs_last_sync_request_time; 295 u_int64_t hfs_last_sync_time; 296 uint32_t hfs_active_threads; 297 thread_call_t hfs_syncer; // removeable devices get sync'ed by this guy 298 299} hfsmount_t; 300 301#define HFS_META_DELAY (100) 302#define HFS_MILLISEC_SCALE (1000*1000) 303 304typedef hfsmount_t ExtendedVCB; 305 306/* Aliases for legacy (Mac OS 9) field names */ 307#define vcbCrDate hfs_itime 308#define vcbLsMod hfs_mtime 309#define vcbVolBkUp hfs_btime 310#define extentsRefNum hfs_extents_vp 311#define catalogRefNum hfs_catalog_vp 312#define allocationsRefNum hfs_allocation_vp 313#define vcbFilCnt hfs_filecount 314#define vcbDirCnt hfs_dircount 315 316/* Inline functions to set/reset vcbFlags. Upper 8 bits indicate if the volume 317 * header/VCB is clean/dirty --- if set, volume header is dirty, and 318 * if clear, volume header is clean. This value is checked to determine 319 * if the in-memory copy of volume header should be flushed to the disk 320 * or not. 321 */ 322/* Set runtime flag to indicate that volume is dirty */ 323static __inline__ void MarkVCBDirty(ExtendedVCB *vcb) 324{ 325 vcb->vcbFlags |= 0xFF00; 326} 327 328/* Clear runtime flag to indicate that volume is dirty */ 329static __inline__ void MarkVCBClean(ExtendedVCB *vcb) 330{ 331 vcb->vcbFlags &= 0x00FF; 332} 333 334/* Check runtime flag to determine if the volume is dirty or not */ 335static __inline__ Boolean IsVCBDirty(ExtendedVCB *vcb) 336{ 337 return (vcb->vcbFlags & 0xFF00 ? true : false); 338} 339 340/* 341 * There are two private directories in HFS+. 342 * 343 * One contains inodes for files that are hardlinked or open/unlinked. 344 * The other contains inodes for directories that are hardlinked. 345 */ 346enum privdirtype {FILE_HARDLINKS, DIR_HARDLINKS}; 347 348 349/* HFS mount point flags */ 350#define HFS_READ_ONLY 0x00001 351#define HFS_UNKNOWN_PERMS 0x00002 352#define HFS_WRITEABLE_MEDIA 0x00004 353#define HFS_CLEANED_ORPHANS 0x00008 354#define HFS_X 0x00010 355#define HFS_CASE_SENSITIVE 0x00020 356#define HFS_STANDARD 0x00040 357#define HFS_METADATA_ZONE 0x00080 358#define HFS_FRAGMENTED_FREESPACE 0x00100 359#define HFS_NEED_JNL_RESET 0x00200 360#define HFS_HAS_SPARSE_DEVICE 0x00400 361#define HFS_RESIZE_IN_PROGRESS 0x00800 362#define HFS_QUOTAS 0x01000 363#define HFS_CREATING_BTREE 0x02000 364/* When set, do not update nextAllocation in the mount structure */ 365#define HFS_SKIP_UPDATE_NEXT_ALLOCATION 0x04000 366#define HFS_XATTR_EXTENTS 0x08000 367#define HFS_FOLDERCOUNT 0x10000 368/* When set, the file system exists on a virtual device, like disk image */ 369#define HFS_VIRTUAL_DEVICE 0x20000 370/* When set, we're in hfs_changefs, so hfs_sync should do nothing. */ 371#define HFS_IN_CHANGEFS 0x40000 372/* When set, we are in process of downgrading or have downgraded to read-only, 373 * so hfs_start_transaction should return EROFS. */ 374#define HFS_RDONLY_DOWNGRADE 0x80000 375 376 377/* Macro to update next allocation block in the HFS mount structure. If 378 * the HFS_SKIP_UPDATE_NEXT_ALLOCATION is set, do not update 379 * nextAllocation block. 380 */ 381#define HFS_UPDATE_NEXT_ALLOCATION(hfsmp, new_nextAllocation) \ 382 { \ 383 if ((hfsmp->hfs_flags & HFS_SKIP_UPDATE_NEXT_ALLOCATION) == 0)\ 384 hfsmp->nextAllocation = new_nextAllocation; \ 385 } \ 386 387#define HFS_MOUNT_LOCK(hfsmp, metadata) \ 388 { \ 389 if ((metadata) && 1) \ 390 lck_mtx_lock(&(hfsmp)->hfs_mutex); \ 391 } \ 392 393#define HFS_MOUNT_UNLOCK(hfsmp, metadata) \ 394 { \ 395 if ((metadata) && 1) \ 396 lck_mtx_unlock(&(hfsmp)->hfs_mutex); \ 397 } \ 398 399#define hfs_global_exclusive_lock_acquire(hfsmp) lck_rw_lock_exclusive(&(hfsmp)->hfs_global_lock) 400#define hfs_global_exclusive_lock_release(hfsmp) lck_rw_unlock_exclusive(&(hfsmp)->hfs_global_lock) 401 402/* Macro for incrementing and decrementing the folder count in a cnode 403 * attribute only if the HFS_FOLDERCOUNT bit is set in the mount flags 404 * and kHFSHasFolderCount bit is set in the cnode flags. Currently these 405 * bits are only set for case sensitive HFS+ volumes. 406 */ 407#define INC_FOLDERCOUNT(hfsmp, cattr) \ 408 if ((hfsmp->hfs_flags & HFS_FOLDERCOUNT) && \ 409 (cattr.ca_recflags & kHFSHasFolderCountMask)) { \ 410 cattr.ca_dircount++; \ 411 } \ 412 413#define DEC_FOLDERCOUNT(hfsmp, cattr) \ 414 if ((hfsmp->hfs_flags & HFS_FOLDERCOUNT) && \ 415 (cattr.ca_recflags & kHFSHasFolderCountMask) && \ 416 (cattr.ca_dircount > 0)) { \ 417 cattr.ca_dircount--; \ 418 } \ 419 420typedef struct filefork FCB; 421 422/* 423 * Macros for creating item names for our special/private directories. 424 */ 425#define MAKE_INODE_NAME(name, size, linkno) \ 426 (void) snprintf((name), size, "%s%d", HFS_INODE_PREFIX, (linkno)) 427#define HFS_INODE_PREFIX_LEN 5 428 429#define MAKE_DIRINODE_NAME(name, size, linkno) \ 430 (void) snprintf((name), size, "%s%d", HFS_DIRINODE_PREFIX, (linkno)) 431#define HFS_DIRINODE_PREFIX_LEN 4 432 433#define MAKE_DELETED_NAME(NAME, size, FID) \ 434 (void) snprintf((NAME), size, "%s%d", HFS_DELETE_PREFIX, (FID)) 435#define HFS_DELETE_PREFIX_LEN 4 436 437 438#define HFS_AVERAGE_NAME_SIZE 22 439#define AVERAGE_HFSDIRENTRY_SIZE (8+HFS_AVERAGE_NAME_SIZE+4) 440 441#define STD_DIRENT_LEN(namlen) \ 442 ((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3)) 443 444#define EXT_DIRENT_LEN(namlen) \ 445 ((sizeof(struct direntry) + (namlen) - (MAXPATHLEN-1) + 3) & ~3) 446 447 448enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 }; 449 450 451/* macro to determine if hfs or hfsplus */ 452#define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord) 453#define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord) 454 455 456/* 457 * Various ways to acquire a VFS mount point pointer: 458 */ 459#define VTOVFS(VP) vnode_mount((VP)) 460#define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp) 461#define VCBTOVFS(VCB) HFSTOVFS(VCB) 462 463/* 464 * Various ways to acquire an HFS mount point pointer: 465 */ 466#define VTOHFS(VP) ((struct hfsmount *)vfs_fsprivate(vnode_mount((VP)))) 467#define VFSTOHFS(MP) ((struct hfsmount *)vfs_fsprivate((MP))) 468#define VCBTOHFS(VCB) (VCB) 469#define FCBTOHFS(FCB) ((struct hfsmount *)vfs_fsprivate(vnode_mount((FCB)->ff_cp->c_vp))) 470 471/* 472 * Various ways to acquire a VCB (legacy) pointer: 473 */ 474#define VTOVCB(VP) VTOHFS(VP) 475#define VFSTOVCB(MP) VFSTOHFS(MP) 476#define HFSTOVCB(HFSMP) (HFSMP) 477#define FCBTOVCB(FCB) FCBTOHFS(FCB) 478 479 480#define HFS_KNOTE(vp, hint) KNOTE(&VTOC(vp)->c_knotes, (hint)) 481 482 483#define E_NONE 0 484#define kHFSBlockSize 512 485 486/* 487 * Macros for getting the MDB/VH sector and offset 488 */ 489#define HFS_PRI_SECTOR(blksize) (1024 / (blksize)) 490#define HFS_PRI_OFFSET(blksize) ((blksize) > 1024 ? 1024 : 0) 491 492#define HFS_ALT_SECTOR(blksize, blkcnt) (((blkcnt) - 1) - (512 / (blksize))) 493#define HFS_ALT_OFFSET(blksize) ((blksize) > 1024 ? (blksize) - 1024 : 0) 494 495/* Convert the logical sector number to be aligned on physical block size boundary. 496 * We are assuming the partition is a multiple of physical block size. 497 */ 498#define HFS_PHYSBLK_ROUNDDOWN(sector_num, log_per_phys) ((sector_num / log_per_phys) * log_per_phys) 499 500/* 501 * HFS specific fcntl()'s 502 */ 503#define HFS_BULKACCESS (FCNTL_FS_SPECIFIC_BASE + 0x00001) 504#define HFS_GET_MOUNT_TIME (FCNTL_FS_SPECIFIC_BASE + 0x00002) 505#define HFS_GET_LAST_MTIME (FCNTL_FS_SPECIFIC_BASE + 0x00003) 506#define HFS_GET_BOOT_INFO (FCNTL_FS_SPECIFIC_BASE + 0x00004) 507#define HFS_SET_BOOT_INFO (FCNTL_FS_SPECIFIC_BASE + 0x00005) 508#define HFS_EXT_BULKACCESS (FCNTL_FS_SPECIFIC_BASE + 0x00006) 509 510 511/* 512 * This is the straight GMT conversion constant: 513 * 00:00:00 January 1, 1970 - 00:00:00 January 1, 1904 514 * (3600 * 24 * ((365 * (1970 - 1904)) + (((1970 - 1904) / 4) + 1))) 515 */ 516#define MAC_GMT_FACTOR 2082844800UL 517 518 519/***************************************************************************** 520 FUNCTION PROTOTYPES 521******************************************************************************/ 522 523 524/***************************************************************************** 525 hfs_vnop_xxx functions from different files 526******************************************************************************/ 527int hfs_vnop_readdirattr(struct vnop_readdirattr_args *); /* in hfs_attrlist.c */ 528 529int hfs_vnop_inactive(struct vnop_inactive_args *); /* in hfs_cnode.c */ 530int hfs_vnop_reclaim(struct vnop_reclaim_args *); /* in hfs_cnode.c */ 531 532int hfs_vnop_link(struct vnop_link_args *); /* in hfs_link.c */ 533 534int hfs_vnop_lookup(struct vnop_lookup_args *); /* in hfs_lookup.c */ 535 536int hfs_vnop_search(struct vnop_searchfs_args *); /* in hfs_search.c */ 537 538int hfs_vnop_read(struct vnop_read_args *); /* in hfs_readwrite.c */ 539int hfs_vnop_write(struct vnop_write_args *); /* in hfs_readwrite.c */ 540int hfs_vnop_ioctl(struct vnop_ioctl_args *); /* in hfs_readwrite.c */ 541int hfs_vnop_select(struct vnop_select_args *); /* in hfs_readwrite.c */ 542int hfs_vnop_strategy(struct vnop_strategy_args *); /* in hfs_readwrite.c */ 543int hfs_vnop_allocate(struct vnop_allocate_args *); /* in hfs_readwrite.c */ 544int hfs_vnop_pagein(struct vnop_pagein_args *); /* in hfs_readwrite.c */ 545int hfs_vnop_pageout(struct vnop_pageout_args *); /* in hfs_readwrite.c */ 546int hfs_vnop_bwrite(struct vnop_bwrite_args *); /* in hfs_readwrite.c */ 547int hfs_vnop_blktooff(struct vnop_blktooff_args *); /* in hfs_readwrite.c */ 548int hfs_vnop_offtoblk(struct vnop_offtoblk_args *); /* in hfs_readwrite.c */ 549int hfs_vnop_blockmap(struct vnop_blockmap_args *); /* in hfs_readwrite.c */ 550 551int hfs_vnop_getxattr(struct vnop_getxattr_args *); /* in hfs_xattr.c */ 552int hfs_vnop_setxattr(struct vnop_setxattr_args *); /* in hfs_xattr.c */ 553int hfs_vnop_removexattr(struct vnop_removexattr_args *); /* in hfs_xattr.c */ 554int hfs_vnop_listxattr(struct vnop_listxattr_args *); /* in hfs_xattr.c */ 555#if NAMEDSTREAMS 556extern int hfs_vnop_getnamedstream(struct vnop_getnamedstream_args*); 557extern int hfs_vnop_makenamedstream(struct vnop_makenamedstream_args*); 558extern int hfs_vnop_removenamedstream(struct vnop_removenamedstream_args*); 559#endif 560 561 562/***************************************************************************** 563 Functions from MacOSStubs.c 564******************************************************************************/ 565time_t to_bsd_time(u_int32_t hfs_time); 566 567u_int32_t to_hfs_time(time_t bsd_time); 568 569 570/***************************************************************************** 571 Functions from hfs_encodinghint.c 572******************************************************************************/ 573u_int32_t hfs_pickencoding(const u_int16_t *src, int len); 574 575u_int32_t hfs_getencodingbias(void); 576 577void hfs_setencodingbias(u_int32_t bias); 578 579 580/***************************************************************************** 581 Functions from hfs_encodings.c 582******************************************************************************/ 583void hfs_converterinit(void); 584 585int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode, 586 unicode_to_hfs_func_t *get_hfsname); 587 588int hfs_relconverter(u_int32_t encoding); 589 590int hfs_to_utf8(ExtendedVCB *vcb, const Str31 hfs_str, ByteCount maxDstLen, 591 ByteCount *actualDstLen, unsigned char* dstStr); 592 593int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr, 594 Str31 dstStr); 595 596int mac_roman_to_utf8(const Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, 597 unsigned char* dstStr); 598 599int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr); 600 601int mac_roman_to_unicode(const Str31 hfs_str, UniChar *uni_str, u_int32_t maxCharLen, u_int32_t *usedCharLen); 602 603int unicode_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, u_int16_t* srcStr, Str31 dstStr, int retry); 604 605 606/***************************************************************************** 607 Functions from hfs_notifications.c 608******************************************************************************/ 609void hfs_generate_volume_notifications(struct hfsmount *hfsmp); 610 611 612/***************************************************************************** 613 Functions from hfs_readwrite.c 614******************************************************************************/ 615extern int hfs_relocate(struct vnode *, u_int32_t, kauth_cred_t, struct proc *); 616 617extern int hfs_truncate(struct vnode *, off_t, int, int, vfs_context_t); 618 619extern int hfs_bmap(struct vnode *, daddr_t, struct vnode **, daddr64_t *, unsigned int *); 620 621extern int hfs_fsync(struct vnode *, int, int, struct proc *); 622 623extern int hfs_access(struct vnode *, mode_t, kauth_cred_t, struct proc *); 624 625extern int hfs_removeallattr(struct hfsmount *hfsmp, u_int32_t fileid); 626 627extern int hfs_set_volxattr(struct hfsmount *hfsmp, unsigned int xattrtype, int state); 628 629extern void hfs_check_volxattr(struct hfsmount *hfsmp, unsigned int xattrtype); 630 631extern int hfs_isallocated(struct hfsmount *, u_long, u_long); 632 633 634/***************************************************************************** 635 Functions from hfs_vfsops.c 636******************************************************************************/ 637int hfs_mountroot(mount_t mp, vnode_t rvp, vfs_context_t context); 638 639/* used as a callback by the journaling code */ 640extern void hfs_sync_metadata(void *arg); 641 642extern int hfs_vget(struct hfsmount *, cnid_t, struct vnode **, int); 643 644extern void hfs_setencodingbits(struct hfsmount *hfsmp, u_int32_t encoding); 645 646enum volop {VOL_UPDATE, VOL_MKDIR, VOL_RMDIR, VOL_MKFILE, VOL_RMFILE}; 647extern int hfs_volupdate(struct hfsmount *hfsmp, enum volop op, int inroot); 648 649int hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor, int altflush); 650#define HFS_ALTFLUSH 1 651 652extern int hfs_extendfs(struct hfsmount *, u_int64_t, vfs_context_t); 653extern int hfs_truncatefs(struct hfsmount *, u_int64_t, vfs_context_t); 654extern int hfs_resize_progress(struct hfsmount *, u_int32_t *); 655 656/* If a runtime corruption is detected, mark the volume inconsistent 657 * bit in the volume attributes. 658 */ 659void hfs_mark_volume_inconsistent(struct hfsmount *hfsmp); 660 661/***************************************************************************** 662 Functions from hfs_vfsutils.c 663******************************************************************************/ 664unsigned long BestBlockSizeFit(unsigned long allocationBlockSize, 665 unsigned long blockSizeLimit, 666 unsigned long baseMultiple); 667 668OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb, 669 struct proc *p); 670OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, 671 off_t embeddedOffset, u_int64_t disksize, struct proc *p, void *args, kauth_cred_t cred); 672 673extern int hfsUnmount(struct hfsmount *hfsmp, struct proc *p); 674 675extern int overflow_extents(struct filefork *fp); 676 677extern int hfs_owner_rights(struct hfsmount *hfsmp, uid_t cnode_uid, kauth_cred_t cred, 678 struct proc *p, int invokesuperuserstatus); 679 680 681/* HFS System file locking */ 682#define SFL_CATALOG 0x0001 683#define SFL_EXTENTS 0x0002 684#define SFL_BITMAP 0x0004 685#define SFL_ATTRIBUTE 0x0008 686#define SFL_STARTUP 0x0010 687#define SFL_VALIDMASK (SFL_CATALOG | SFL_EXTENTS | SFL_BITMAP | SFL_ATTRIBUTE | SFL_STARTUP) 688 689extern int hfs_systemfile_lock(struct hfsmount *, int, enum hfslocktype); 690extern void hfs_systemfile_unlock(struct hfsmount *, int); 691 692extern u_long GetFileInfo(ExtendedVCB *vcb, u_int32_t dirid, const char *name, 693 struct cat_attr *fattr, struct cat_fork *forkinfo); 694 695extern void hfs_remove_orphans(struct hfsmount *); 696 697u_int32_t GetLogicalBlockSize(struct vnode *vp); 698 699extern u_int32_t hfs_freeblks(struct hfsmount * hfsmp, int wantreserve); 700 701short MacToVFSError(OSErr err); 702 703/* HFS directory hint functions. */ 704extern directoryhint_t * hfs_getdirhint(struct cnode *, int, int); 705extern void hfs_reldirhint(struct cnode *, directoryhint_t *); 706extern void hfs_reldirhints(struct cnode *, int); 707extern void hfs_insertdirhint(struct cnode *, directoryhint_t *); 708 709extern int hfs_namecmp(const u_int8_t *str1, size_t len1, const u_int8_t *str2, size_t len2); 710 711extern int hfs_early_journal_init(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, 712 void *_args, off_t embeddedOffset, daddr64_t mdb_offset, 713 HFSMasterDirectoryBlock *mdbp, kauth_cred_t cred); 714 715extern int hfs_virtualmetafile(struct cnode *); 716 717extern int hfs_start_transaction(struct hfsmount *hfsmp); 718extern int hfs_end_transaction(struct hfsmount *hfsmp); 719extern void hfs_sync_ejectable(struct hfsmount *hfsmp); 720 721 722/***************************************************************************** 723 Functions from hfs_vnops.c 724******************************************************************************/ 725int hfs_write_access(struct vnode *vp, kauth_cred_t cred, struct proc *p, Boolean considerFlags); 726 727int hfs_chmod(struct vnode *vp, int mode, kauth_cred_t cred, struct proc *p); 728 729int hfs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, struct proc *p); 730 731#define kMaxSecsForFsync 5 732#define HFS_SYNCTRANS 1 733extern int hfs_btsync(struct vnode *vp, int sync_transaction); 734 735extern void replace_desc(struct cnode *cp, struct cat_desc *cdp); 736 737extern int hfs_vgetrsrc(struct hfsmount *hfsmp, struct vnode *vp, 738 struct vnode **rvpp, int can_drop_lock); 739 740extern int hfs_update(struct vnode *, int); 741 742 743/***************************************************************************** 744 Functions from hfs_xattr.c 745******************************************************************************/ 746int hfs_attrkeycompare(HFSPlusAttrKey *searchKey, HFSPlusAttrKey *trialKey); 747int hfs_buildattrkey(u_int32_t fileID, const char *attrname, HFSPlusAttrKey *key); 748void hfs_xattr_init(struct hfsmount * hfsmp); 749int file_attribute_exist(struct hfsmount *hfsmp, uint32_t fileID); 750 751 752 753/***************************************************************************** 754 Functions from hfs_link.c 755******************************************************************************/ 756 757extern int hfs_unlink(struct hfsmount *hfsmp, struct vnode *dvp, struct vnode *vp, 758 struct componentname *cnp, int skip_reserve); 759extern int hfs_lookuplink(struct hfsmount *hfsmp, cnid_t linkfileid, 760 cnid_t *prevlinkid, cnid_t *nextlinkid); 761extern void hfs_privatedir_init(struct hfsmount *, enum privdirtype); 762 763extern void hfs_savelinkorigin(cnode_t *cp, cnid_t parentcnid); 764extern void hfs_relorigins(struct cnode *cp); 765extern void hfs_relorigin(struct cnode *cp, cnid_t parentcnid); 766extern int hfs_haslinkorigin(cnode_t *cp); 767extern cnid_t hfs_currentparent(cnode_t *cp); 768extern cnid_t hfs_currentcnid(cnode_t *cp); 769 770 771#endif /* __APPLE_API_PRIVATE */ 772#endif /* KERNEL */ 773#endif /* __HFS__ */ 774