Lines Matching defs:hfsmp

148 static int hfs_flushMDB(struct hfsmount *hfsmp, int waitfor, int altflush);
155 static int hfs_file_extent_overlaps(struct hfsmount *hfsmp, u_int32_t allocLimit, struct HFSPlusCatalogFile *filerec);
157 static int hfs_reclaimspace(struct hfsmount *hfsmp, u_int32_t allocLimit, u_int32_t reclaimblks, vfs_context_t context);
158 static int hfs_extend_journal(struct hfsmount *hfsmp, u_int32_t sector_size, u_int64_t sector_count, vfs_context_t context);
160 void hfs_initialize_allocator (struct hfsmount *hfsmp);
161 int hfs_teardown_allocator (struct hfsmount *hfsmp);
162 void hfs_unmap_blocks (struct hfsmount *hfsmp);
180 struct hfsmount *hfsmp;
193 /* Init hfsmp */
194 hfsmp = VFSTOHFS(mp);
196 hfsmp->hfs_uid = UNKNOWNUID;
197 hfsmp->hfs_gid = UNKNOWNGID;
198 hfsmp->hfs_dir_mask = (S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH); /* 0755 */
199 hfsmp->hfs_file_mask = (S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH); /* 0755 */
202 vcb = HFSTOVCB(hfsmp);
223 struct hfsmount *hfsmp = NULL;
236 hfsmp = VFSTOHFS(mp);
243 printf("hfs_mount: hfs_reload returned %d on %s \n", error, hfsmp->vcbVN);
249 printf("hfs_mount: MNT_RELOAD not supported on rdwr filesystem %s\n", hfsmp->vcbVN);
256 if (((hfsmp->hfs_flags & HFS_READ_ONLY) == 0) &&
264 hfs_lock_global (hfsmp, HFS_EXCLUSIVE_LOCK);
265 hfsmp->hfs_flags |= HFS_RDONLY_DOWNGRADE;
266 hfsmp->hfs_downgrading_proc = current_thread();
267 hfs_unlock_global (hfsmp);
272 hfsmp->hfs_flags &= ~HFS_RDONLY_DOWNGRADE;
273 hfsmp->hfs_downgrading_proc = NULL;
275 printf("hfs_mount: VFS_SYNC returned %d during b-tree sync of %s \n", retval, hfsmp->vcbVN);
285 hfsmp->hfs_flags &= ~HFS_RDONLY_DOWNGRADE;
286 hfsmp->hfs_downgrading_proc = NULL;
288 printf("hfs_mount: hfs_flushfiles returned %d on %s \n", retval, hfsmp->vcbVN);
294 hfsmp->vcbAtrb |= kHFSVolumeUnmountedMask;
295 retval = hfs_flushvolumeheader(hfsmp, MNT_WAIT, 0);
296 hfsmp->hfs_flags |= HFS_READ_ONLY;
313 if (hfsmp->jnl) {
314 hfs_lock_global (hfsmp, HFS_EXCLUSIVE_LOCK);
316 journal_close(hfsmp->jnl);
317 hfsmp->jnl = NULL;
323 hfs_unlock_global (hfsmp);
332 if (vnode_mount(hfsmp->hfs_devvp) == mp) {
333 retval = hfs_fsync(hfsmp->hfs_devvp, MNT_WAIT, 0, p);
335 vnode_get(hfsmp->hfs_devvp);
336 retval = VNOP_FSYNC(hfsmp->hfs_devvp, MNT_WAIT, context);
337 vnode_put(hfsmp->hfs_devvp);
343 printf("hfs_mount: FSYNC on devvp returned %d for fs %s\n", retval, hfsmp->vcbVN);
345 hfsmp->hfs_flags &= ~HFS_RDONLY_DOWNGRADE;
346 hfsmp->hfs_downgrading_proc = NULL;
347 hfsmp->hfs_flags &= ~HFS_READ_ONLY;
352 (void) hfs_teardown_allocator(hfsmp);
354 hfsmp->hfs_downgrading_proc = NULL;
368 (hfsmp->vcbAtrb & kHFSVolumeInconsistentMask)) {
370 printf("hfs_mount: attempting to mount inconsistent non-root volume %s\n", (hfsmp->vcbVN));
379 if ( (HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask)
380 && hfsmp->jnl == NULL
381 && hfsmp->jvp != NULL) {
384 if (hfsmp->hfs_flags & HFS_NEED_JNL_RESET) {
390 hfs_lock_global (hfsmp, HFS_EXCLUSIVE_LOCK);
392 hfsmp->jnl = journal_open(hfsmp->jvp,
393 (hfsmp->jnl_start * HFSTOVCB(hfsmp)->blockSize) + (off_t)HFSTOVCB(hfsmp)->hfsPlusIOPosOffset,
394 hfsmp->jnl_size,
395 hfsmp->hfs_devvp,
396 hfsmp->hfs_logical_block_size,
399 hfs_sync_metadata, hfsmp->hfs_mp);
407 if (hfsmp->jnl)
408 journal_trim_set_callback(hfsmp->jnl, hfs_trim_callback, hfsmp);
410 hfs_unlock_global (hfsmp);
412 if (hfsmp->jnl == NULL) {
414 printf("hfs_mount: journal_open == NULL; couldn't be opened on %s \n", (hfsmp->vcbVN));
419 hfsmp->hfs_flags &= ~HFS_NEED_JNL_RESET;
425 retval = hfs_erase_unused_nodes(hfsmp);
428 printf("hfs_mount: hfs_erase_unused_nodes returned %d for fs %s\n", retval, hfsmp->vcbVN);
437 hfsmp->hfs_flags &= ~HFS_RDONLY_DOWNGRADE;
438 hfsmp->hfs_downgrading_proc = NULL;
441 hfsmp->vcbAtrb &= ~kHFSVolumeUnmountedMask;
443 retval = hfs_flushvolumeheader(hfsmp, MNT_WAIT, 0);
446 printf("hfs_mount: hfs_flushvolumeheader returned %d for fs %s\n", retval, hfsmp->vcbVN);
452 hfsmp->hfs_flags &= ~HFS_READ_ONLY;
455 if (!(hfsmp->hfs_flags & (HFS_READ_ONLY | HFS_STANDARD))) {
457 hfs_privatedir_init(hfsmp, FILE_HARDLINKS);
458 hfs_privatedir_init(hfsmp, DIR_HARDLINKS);
460 hfs_remove_orphans(hfsmp);
465 if ((hfsmp->hfs_flags & HFS_METADATA_ZONE) &&
466 ((hfsmp->hfs_mp->mnt_kern_flag & MNTK_SSD) == 0)) {
467 (void) hfs_recording_init(hfsmp);
470 if (vfs_extendedsecurity(HFSTOVFS(hfsmp)) == 0) {
471 vfs_setextendedsecurity(HFSTOVFS(hfsmp));
497 if (hfsmp->extent_tree_flags == 0) {
498 hfsmp->extent_tree_flags |= (HFS_ALLOC_TREEBUILD_INFLIGHT | HFS_ALLOC_RB_ENABLED);
500 hfsmp->offset_block_end = 0;
502 InitTree(hfsmp);
504 kernel_thread_start ((thread_continue_t) hfs_initialize_allocator , hfsmp, &allocator_thread);
514 printf("hfs_mount: hfs_changefs returned %d for %s\n", retval, hfsmp->vcbVN);
542 hfsmp = vfs_fsprivate(mp);
545 err = cp_getrootxattr (hfsmp, xattr);
558 err = cp_setrootxattr (hfsmp, xattr);
588 struct hfsmount *hfsmp;
608 vcb = HFSTOVCB(args->hfsmp);
610 lockflags = hfs_systemfile_lock(args->hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
611 error = cat_lookup(args->hfsmp, &cp->c_desc, 0, &cndesc, &cnattr, NULL, NULL);
612 hfs_systemfile_unlock(args->hfsmp, lockflags);
641 cp->c_desc.cd_encoding = args->hfsmp->hfs_encoding;
655 struct hfsmount *hfsmp;
663 hfsmp = VFSTOHFS(mp);
664 vcb = HFSTOVCB(hfsmp);
667 hfsmp->hfs_flags |= HFS_IN_CHANGEFS;
669 permswitch = (((hfsmp->hfs_flags & HFS_UNKNOWN_PERMS) &&
671 (((hfsmp->hfs_flags & HFS_UNKNOWN_PERMS) == 0) &&
681 hfsmp->hfs_flags |= HFS_UNKNOWN_PERMS;
683 hfsmp->hfs_flags &= ~HFS_UNKNOWN_PERMS;
692 (void) hfs_recording_suspend(hfsmp);
701 if ((args->hfs_uid != (uid_t)VNOVAL) && (hfsmp->hfs_uid != args->hfs_uid)) {
702 hfsmp->hfs_uid = args->hfs_uid;
706 if ((args->hfs_gid != (gid_t)VNOVAL) && (hfsmp->hfs_gid != args->hfs_gid)) {
707 hfsmp->hfs_gid = args->hfs_gid;
712 if (hfsmp->hfs_dir_mask != (args->hfs_mask & ALLPERMS)) {
713 hfsmp->hfs_dir_mask = args->hfs_mask & ALLPERMS;
714 hfsmp->hfs_file_mask = args->hfs_mask & ALLPERMS;
716 hfsmp->hfs_file_mask = (args->hfs_mask & DEFFILEMODE);
725 (hfsmp->hfs_encoding != args->hfs_encoding)) {
741 hfsmp->hfs_get_unicode = get_unicode_func;
742 old_encoding = hfsmp->hfs_encoding;
743 hfsmp->hfs_encoding = args->hfs_encoding;
753 hfsmp->hfs_uid == UNKNOWNUID ? KAUTH_UID_NONE : hfsmp->hfs_uid,
754 hfsmp->hfs_gid == UNKNOWNGID ? KAUTH_GID_NONE : hfsmp->hfs_gid);
768 cargs.hfsmp = hfsmp;
781 hfsmp->hfs_get_hfsname = get_hfsname_func;
786 hfsmp->hfs_flags &= ~HFS_IN_CHANGEFS;
792 struct hfsmount *hfsmp;
826 lockflags = hfs_systemfile_lock(args->hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
827 args->error = cat_idlookup(args->hfsmp, cp->c_fileid, 0, 0, &desc, &cp->c_attr, datafork);
828 hfs_systemfile_unlock(args->hfsmp, lockflags);
859 struct hfsmount *hfsmp;
867 hfsmp = VFSTOHFS(mountp);
868 vcb = HFSTOVCB(hfsmp);
876 devvp = hfsmp->hfs_devvp;
880 args.hfsmp = hfsmp;
897 priIDSector = (daddr64_t)((vcb->hfsPlusIOPosOffset / hfsmp->hfs_logical_block_size) +
898 HFS_PRI_SECTOR(hfsmp->hfs_logical_block_size));
900 error = (int)buf_meta_bread(hfsmp->hfs_devvp,
901 HFS_PHYSBLK_ROUNDDOWN(priIDSector, hfsmp->hfs_log_per_phys),
902 hfsmp->hfs_physical_block_size, NOCRED, &bp);
909 vhp = (HFSPlusVolumeHeader *) (buf_dataptr(bp) + HFS_PRI_OFFSET(hfsmp->hfs_physical_block_size));
963 if (hfsmp->hfs_attribute_vp) {
964 forkp = VTOF(hfsmp->hfs_attribute_vp);
1001 if (hfsmp->hfs_attribute_vp) {
1002 forkp = VTOF(hfsmp->hfs_attribute_vp);
1008 if ((error = cat_idlookup(hfsmp, kHFSRootFolderID, 0, 0, &cndesc, NULL, NULL)))
1015 hfs_privatedir_init(hfsmp, FILE_HARDLINKS);
1016 hfs_privatedir_init(hfsmp, DIR_HARDLINKS);
1019 hfs_generate_volume_notifications(hfsmp);
1031 struct hfsmount *hfsmp = arg0;
1045 if (hfsmp->hfs_mp->mnt_pending_write_size > hfsmp->hfs_max_pending_io) {
1051 hfs_start_transaction(hfsmp); // so we hold off any new i/o's
1053 pending_io = hfsmp->hfs_mp->mnt_pending_write_size;
1058 while(hfsmp->hfs_mp->mnt_pending_write_size > (pending_io/3) && counter++ < 500) {
1059 tsleep((caddr_t)hfsmp, PRIBIO, "hfs-wait-for-io-to-drain", 10);
1063 printf("hfs: timed out waiting for io to drain (%lld)\n", (int64_t)hfsmp->hfs_mp->mnt_pending_write_size);
1066 if (hfsmp->jnl) {
1067 journal_flush(hfsmp->jnl, FALSE);
1069 hfs_sync(hfsmp->hfs_mp, MNT_WAIT, vfs_context_kernel());
1074 hfsmp->hfs_last_sync_time = now;
1079 hfs_end_transaction(hfsmp);
1092 hfsmp->hfs_max_pending_io = (rate * 150ULL) / 100ULL;
1096 } else if ( ((now - hfsmp->hfs_last_sync_time) >= 5000000ULL)
1097 || (((now - hfsmp->hfs_last_sync_time) >= 100000LL)
1098 && ((now - hfsmp->hfs_last_sync_request_time) >= 100000LL)
1099 && (hfsmp->hfs_active_threads == 0)
1100 && (hfsmp->hfs_global_lock_nesting == 0))) {
1109 if (hfsmp->jnl) {
1110 hfs_lock_global (hfsmp, HFS_SHARED_LOCK);
1112 journal_flush(hfsmp->jnl, FALSE);
1114 hfs_unlock_global (hfsmp);
1116 hfs_sync(hfsmp->hfs_mp, MNT_WAIT, vfs_context_kernel());
1121 hfsmp->hfs_last_sync_time = now;
1123 } else if (hfsmp->hfs_active_threads == 0) {
1127 thread_call_enter_delayed(hfsmp->hfs_syncer, deadline);
1141 OSDecrementAtomic((volatile SInt32 *)&hfsmp->hfs_sync_scheduled);
1142 OSDecrementAtomic((volatile SInt32 *)&hfsmp->hfs_sync_incomplete);
1143 wakeup((caddr_t)&hfsmp->hfs_sync_incomplete);
1160 hfs_initialize_allocator (struct hfsmount *hfsmp) {
1169 int flags = hfs_systemfile_lock(hfsmp, SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
1177 err = GenerateTree(hfsmp, hfsmp->totalBlocks, &flags, 1);
1182 hfsmp->extent_tree_flags |= HFS_ALLOC_RB_ACTIVE;
1190 hfsmp->extent_tree_flags &= ~HFS_ALLOC_TREEBUILD_INFLIGHT;
1193 wakeup((caddr_t)&hfsmp->extent_tree_flags);
1196 hfs_systemfile_unlock(hfsmp, flags);
1198 #pragma unused (hfsmp)
1202 void hfs_unmap_blocks (struct hfsmount *hfsmp) {
1207 int flags = hfs_systemfile_lock(hfsmp, SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
1213 (void) UnmapBlocks(hfsmp);
1215 hfs_systemfile_unlock(hfsmp, flags);
1230 hfs_teardown_allocator (struct hfsmount *hfsmp) {
1242 flags = hfs_systemfile_lock(hfsmp, SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
1245 while (hfsmp->extent_tree_flags & HFS_ALLOC_TREEBUILD_INFLIGHT) {
1246 hfsmp->extent_tree_flags |= HFS_ALLOC_TEARDOWN_INFLIGHT;
1248 lck_rw_sleep(&(VTOC(hfsmp->hfs_allocation_vp))->c_rwlock, LCK_SLEEP_EXCLUSIVE,
1249 &hfsmp->extent_tree_flags, THREAD_UNINT);
1252 if (hfs_isrbtree_active (hfsmp)) {
1256 DestroyTrees(hfsmp);
1260 hfs_systemfile_unlock(hfsmp, flags);
1262 #pragma unused (hfsmp)
1282 struct hfsmount *hfsmp = NULL;
1318 hfsmp = NULL;
1457 MALLOC(hfsmp, struct hfsmount *, sizeof(struct hfsmount), M_HFSMNT, M_WAITOK);
1458 if (hfsmp == NULL) {
1465 bzero(hfsmp, sizeof(struct hfsmount));
1467 hfs_chashinit_finish(hfsmp);
1477 hfsmp->hfs_flags |= HFS_UNMAP;
1487 hfsmp->hfs_flags |= HFS_SSD;
1496 lck_mtx_init(&hfsmp->hfs_mutex, hfs_mutex_group, hfs_lock_attr);
1497 lck_mtx_init(&hfsmp->hfc_mutex, hfs_mutex_group, hfs_lock_attr);
1498 lck_rw_init(&hfsmp->hfs_global_lock, hfs_rwlock_group, hfs_lock_attr);
1499 lck_rw_init(&hfsmp->hfs_insync, hfs_rwlock_group, hfs_lock_attr);
1500 lck_spin_init(&hfsmp->vcbFreeExtLock, hfs_spinlock_group, hfs_lock_attr);
1502 vfs_setfsprivate(mp, hfsmp);
1503 hfsmp->hfs_mp = mp; /* Make VFSTOHFS work */
1504 hfsmp->hfs_raw_dev = vnode_specrdev(devvp);
1505 hfsmp->hfs_devvp = devvp;
1506 vnode_ref(devvp); /* Hold a ref on the device, dropped when hfsmp is freed. */
1507 hfsmp->hfs_logical_block_size = log_blksize;
1508 hfsmp->hfs_logical_block_count = log_blkcnt;
1509 hfsmp->hfs_logical_bytes = (uint64_t) log_blksize * (uint64_t) log_blkcnt;
1510 hfsmp->hfs_physical_block_size = phys_blksize;
1511 hfsmp->hfs_log_per_phys = (phys_blksize / log_blksize);
1512 hfsmp->hfs_flags |= HFS_WRITEABLE_MEDIA;
1514 hfsmp->hfs_flags |= HFS_READ_ONLY;
1516 hfsmp->hfs_flags |= HFS_UNKNOWN_PERMS;
1520 dqfileinit(&hfsmp->hfs_qfiles[i]);
1524 hfsmp->hfs_uid = (args->hfs_uid == (uid_t)VNOVAL) ? UNKNOWNUID : args->hfs_uid;
1525 if (hfsmp->hfs_uid == 0xfffffffd) hfsmp->hfs_uid = UNKNOWNUID;
1526 hfsmp->hfs_gid = (args->hfs_gid == (gid_t)VNOVAL) ? UNKNOWNGID : args->hfs_gid;
1527 if (hfsmp->hfs_gid == 0xfffffffd) hfsmp->hfs_gid = UNKNOWNGID;
1528 vfs_setowner(mp, hfsmp->hfs_uid, hfsmp->hfs_gid); /* tell the VFS */
1530 hfsmp->hfs_dir_mask = args->hfs_mask & ALLPERMS;
1532 hfsmp->hfs_file_mask = (args->hfs_mask & DEFFILEMODE);
1534 hfsmp->hfs_file_mask = args->hfs_mask & ALLPERMS;
1537 hfsmp->hfs_dir_mask = UNKNOWNPERMISSIONS & ALLPERMS; /* 0777: rwx---rwx */
1538 hfsmp->hfs_file_mask = UNKNOWNPERMISSIONS & DEFFILEMODE; /* 0666: no --x by default? */
1545 hfsmp->hfs_uid = UNKNOWNUID;
1546 hfsmp->hfs_gid = UNKNOWNGID;
1547 vfs_setowner(mp, hfsmp->hfs_uid, hfsmp->hfs_gid); /* tell the VFS */
1548 hfsmp->hfs_dir_mask = UNKNOWNPERMISSIONS & ALLPERMS; /* 0777: rwx---rwx */
1549 hfsmp->hfs_file_mask = UNKNOWNPERMISSIONS & DEFFILEMODE; /* 0666: no --x by default? */
1556 hfsmp->hfs_flags |= HFS_WRITEABLE_MEDIA;
1558 hfsmp->hfs_flags &= ~HFS_WRITEABLE_MEDIA;
1564 hfsmp->hfs_mount_time = tv.tv_sec;
1579 hfsmp->hfs_flags |= HFS_READ_ONLY;
1580 hfsmp->hfs_flags &= ~HFS_WRITEABLE_MEDIA;
1603 hfsmp->hfs_logical_block_size = log_blksize;
1604 hfsmp->hfs_logical_block_count = log_blkcnt;
1605 hfsmp->hfs_logical_bytes = (uint64_t) log_blksize * (uint64_t) log_blkcnt;
1606 hfsmp->hfs_physical_block_size = log_blksize;
1607 hfsmp->hfs_log_per_phys = 1;
1610 hfsmp->hfs_encoding = args->hfs_encoding;
1611 HFSTOVCB(hfsmp)->volumeNameEncodingHint = args->hfs_encoding;
1617 retval = hfs_getconverter(hfsmp->hfs_encoding, &hfsmp->hfs_get_unicode,
1618 &hfsmp->hfs_get_hfsname);
1622 retval = hfs_MountHFSVolume(hfsmp, mdbp, p);
1624 (void) hfs_relconverter(hfsmp->hfs_encoding);
1671 hfsmp->hfs_logical_block_count *=
1672 hfsmp->hfs_logical_block_size / log_blksize;
1675 hfsmp->hfs_logical_block_size = log_blksize;
1676 hfsmp->hfs_physical_block_size = log_blksize;
1679 hfsmp->hfs_log_per_phys = 1;
1685 hfsmp->hfs_logical_block_count = disksize / log_blksize;
1687 hfsmp->hfs_logical_bytes = (uint64_t) hfsmp->hfs_logical_block_count * (uint64_t) hfsmp->hfs_logical_block_size;
1690 retval = (int)buf_meta_bread(devvp, HFS_PHYSBLK_ROUNDDOWN(mdb_offset, hfsmp->hfs_log_per_phys),
1723 && !(hfsmp->hfs_flags & HFS_READ_ONLY)) {
1735 hfsmp->jnl = NULL;
1736 hfsmp->jvp = NULL;
1758 if ((retval = hfs_early_journal_init(hfsmp, vhp, args, embeddedOffset, mdb_offset, mdbp, cred)) == 0) {
1782 hfsmp->hfs_flags |= HFS_NEED_JNL_RESET;
1790 HFS_PHYSBLK_ROUNDDOWN(mdb_offset, hfsmp->hfs_log_per_phys),
1834 (void) hfs_getconverter(0, &hfsmp->hfs_get_unicode, &hfsmp->hfs_get_hfsname);
1836 retval = hfs_MountHFSPlusVolume(hfsmp, vhp, embeddedOffset, disksize, p, args, cred);
1861 hfsmp->hfs_logical_block_count *= hfsmp->hfs_logical_block_size / log_blksize;
1862 hfsmp->hfs_logical_block_size = log_blksize;
1863 hfsmp->hfs_log_per_phys = hfsmp->hfs_physical_block_size / log_blksize;
1865 hfsmp->hfs_logical_bytes = (uint64_t) hfsmp->hfs_logical_block_count * (uint64_t) hfsmp->hfs_logical_block_size;
1867 if (hfsmp->jnl && hfsmp->jvp == devvp) {
1869 journal_close(hfsmp->jnl);
1870 hfsmp->jnl = NULL;
1871 if (hfs_early_journal_init(hfsmp, vhp, args, embeddedOffset, mdb_offset, mdbp, cred) == 0) {
1883 hfsmp->hfs_flags |= HFS_NEED_JNL_RESET;
1890 retval = (int)buf_meta_bread(devvp, HFS_PHYSBLK_ROUNDDOWN(mdb_offset, hfsmp->hfs_log_per_phys),
1925 retval = hfs_MountHFSPlusVolume(hfsmp, vhp, embeddedOffset, disksize, p, args, cred);
1936 hfsmp->hfs_last_mounted_mtime = hfsmp->hfs_mtime;
1953 if (!(hfsmp->hfs_flags & HFS_STANDARD)) {
1970 hfsmp->hfs_freespace_notify_dangerlimit =
1971 MIN(HFS_VERYLOWDISKTRIGGERLEVEL / HFSTOVCB(hfsmp)->blockSize,
1972 (HFSTOVCB(hfsmp)->totalBlocks / 100) * HFS_VERYLOWDISKTRIGGERFRACTION);
1973 hfsmp->hfs_freespace_notify_warninglimit =
1974 MIN(HFS_LOWDISKTRIGGERLEVEL / HFSTOVCB(hfsmp)->blockSize,
1975 (HFSTOVCB(hfsmp)->totalBlocks / 100) * HFS_LOWDISKTRIGGERFRACTION);
1976 hfsmp->hfs_freespace_notify_desiredlevel =
1977 MIN(HFS_LOWDISKSHUTOFFLEVEL / HFSTOVCB(hfsmp)->blockSize,
1978 (HFSTOVCB(hfsmp)->totalBlocks / 100) * HFS_LOWDISKSHUTOFFFRACTION);
1988 hfsmp->hfs_freespace_notify_dangerlimit =
1989 MIN(HFS_ROOTVERYLOWDISKTRIGGERLEVEL / HFSTOVCB(hfsmp)->blockSize,
1990 (HFSTOVCB(hfsmp)->totalBlocks / 100) * HFS_ROOTVERYLOWDISKTRIGGERFRACTION);
1991 hfsmp->hfs_freespace_notify_warninglimit =
1992 MIN(HFS_ROOTLOWDISKTRIGGERLEVEL / HFSTOVCB(hfsmp)->blockSize,
1993 (HFSTOVCB(hfsmp)->totalBlocks / 100) * HFS_ROOTLOWDISKTRIGGERFRACTION);
1994 hfsmp->hfs_freespace_notify_desiredlevel =
1995 MIN(HFS_ROOTLOWDISKSHUTOFFLEVEL / HFSTOVCB(hfsmp)->blockSize,
1996 (HFSTOVCB(hfsmp)->totalBlocks / 100) * HFS_ROOTLOWDISKSHUTOFFFRACTION);
2002 hfsmp->hfs_flags |= HFS_VIRTUAL_DEVICE;
2008 if ((hfsmp->hfs_flags & HFS_VIRTUAL_DEVICE) == 0 &&
2010 hfsmp->hfs_max_pending_io = 4096*1024; // a reasonable value to start with.
2011 hfsmp->hfs_syncer = thread_call_allocate(hfs_syncer, hfsmp);
2012 if (hfsmp->hfs_syncer == NULL) {
2024 if ((hfsmp->hfs_flags & HFS_READ_ONLY) == 0) {
2025 if (hfsmp->hfs_flags & HFS_UNMAP) {
2026 hfs_unmap_blocks(hfsmp);
2045 if ((hfsmp->hfs_flags & HFS_READ_ONLY) == 0) {
2046 hfsmp->extent_tree_flags |= (HFS_ALLOC_TREEBUILD_INFLIGHT | HFS_ALLOC_RB_ENABLED);
2049 hfsmp->offset_block_end = 0;
2050 InitTree(hfsmp);
2052 kernel_thread_start ((thread_continue_t) hfs_initialize_allocator , hfsmp, &allocator_thread);
2062 hfsmp->hfs_notification_conditions = 0;
2063 hfs_generate_volume_notifications(hfsmp);
2066 (void) hfs_flushvolumeheader(hfsmp, MNT_WAIT, 0);
2077 if (hfsmp && hfsmp->jvp && hfsmp->jvp != hfsmp->hfs_devvp) {
2078 vnode_clearmountedon(hfsmp->jvp);
2079 (void)VNOP_CLOSE(hfsmp->jvp, ronly ? FREAD : FREAD|FWRITE, vfs_context_kernel());
2080 hfsmp->jvp = NULL;
2082 if (hfsmp) {
2083 if (hfsmp->hfs_devvp) {
2084 vnode_rele(hfsmp->hfs_devvp);
2086 hfs_delete_chash(hfsmp);
2088 FREE(hfsmp, M_HFSMNT);
2114 struct hfsmount *hfsmp = VFSTOHFS(mp);
2131 if (hfsmp->hfs_flags & HFS_METADATA_ZONE)
2132 (void) hfs_recording_suspend(hfsmp);
2138 if (hfsmp->hfs_syncer)
2148 if (thread_call_cancel(hfsmp->hfs_syncer))
2149 OSDecrementAtomic((volatile SInt32 *)&hfsmp->hfs_sync_incomplete);
2150 thread_call_free(hfsmp->hfs_syncer);
2151 hfsmp->hfs_syncer = NULL;
2157 while(hfsmp->hfs_sync_incomplete > 0)
2159 msleep((caddr_t)&hfsmp->hfs_sync_incomplete, NULL, PWAIT, "hfs_unmount", &ts);
2162 if (hfsmp->hfs_sync_incomplete < 0)
2167 rb_used = hfs_teardown_allocator(hfsmp);
2173 if ((hfsmp->hfs_flags & HFS_READ_ONLY) == 0) {
2174 retval = hfs_start_transaction(hfsmp);
2181 if (hfsmp->hfs_startup_vp) {
2182 (void) hfs_lock(VTOC(hfsmp->hfs_startup_vp), HFS_EXCLUSIVE_LOCK);
2183 retval = hfs_fsync(hfsmp->hfs_startup_vp, MNT_WAIT, 0, p);
2184 hfs_unlock(VTOC(hfsmp->hfs_startup_vp));
2189 if (hfsmp->hfs_attribute_vp) {
2190 (void) hfs_lock(VTOC(hfsmp->hfs_attribute_vp), HFS_EXCLUSIVE_LOCK);
2191 retval = hfs_fsync(hfsmp->hfs_attribute_vp, MNT_WAIT, 0, p);
2192 hfs_unlock(VTOC(hfsmp->hfs_attribute_vp));
2197 (void) hfs_lock(VTOC(hfsmp->hfs_catalog_vp), HFS_EXCLUSIVE_LOCK);
2198 retval = hfs_fsync(hfsmp->hfs_catalog_vp, MNT_WAIT, 0, p);
2199 hfs_unlock(VTOC(hfsmp->hfs_catalog_vp));
2203 (void) hfs_lock(VTOC(hfsmp->hfs_extents_vp), HFS_EXCLUSIVE_LOCK);
2204 retval = hfs_fsync(hfsmp->hfs_extents_vp, MNT_WAIT, 0, p);
2205 hfs_unlock(VTOC(hfsmp->hfs_extents_vp));
2209 if (hfsmp->hfs_allocation_vp) {
2210 (void) hfs_lock(VTOC(hfsmp->hfs_allocation_vp), HFS_EXCLUSIVE_LOCK);
2211 retval = hfs_fsync(hfsmp->hfs_allocation_vp, MNT_WAIT, 0, p);
2212 hfs_unlock(VTOC(hfsmp->hfs_allocation_vp));
2217 if (hfsmp->hfc_filevp && vnode_issystem(hfsmp->hfc_filevp)) {
2218 retval = hfs_fsync(hfsmp->hfc_filevp, MNT_WAIT, 0, p);
2226 if (hfsmp->vcbAtrb & kHFSVolumeInconsistentMask) {
2227 HFSTOVCB(hfsmp)->vcbAtrb &= ~kHFSVolumeUnmountedMask;
2229 HFSTOVCB(hfsmp)->vcbAtrb |= kHFSVolumeUnmountedMask;
2235 hfsmp->nextAllocation = 0;
2238 if (hfsmp->hfs_flags & HFS_HAS_SPARSE_DEVICE) {
2240 u_int32_t min_start = hfsmp->totalBlocks;
2244 lck_spin_lock(&hfsmp->vcbFreeExtLock);
2245 for(i=0; i < (int)hfsmp->vcbFreeExtCnt; i++) {
2246 if (hfsmp->vcbFreeExt[i].startBlock < min_start) {
2247 min_start = hfsmp->vcbFreeExt[i].startBlock;
2250 lck_spin_unlock(&hfsmp->vcbFreeExtLock);
2251 if (min_start < hfsmp->nextAllocation) {
2252 hfsmp->nextAllocation = min_start;
2258 retval = hfs_flushvolumeheader(hfsmp, MNT_WAIT, 0);
2260 HFSTOVCB(hfsmp)->vcbAtrb &= ~kHFSVolumeUnmountedMask;
2266 hfs_end_transaction(hfsmp);
2271 if (hfsmp->jnl) {
2272 hfs_journal_flush(hfsmp, FALSE);
2278 (void) hfsUnmount(hfsmp, p);
2280 if (HFSTOVCB(hfsmp)->vcbSigWord == kHFSSigWord)
2281 (void) hfs_relconverter(hfsmp->hfs_encoding);
2284 if (hfsmp->jnl) {
2285 journal_close(hfsmp->jnl);
2286 hfsmp->jnl = NULL;
2289 VNOP_FSYNC(hfsmp->hfs_devvp, MNT_WAIT, context);
2291 if (hfsmp->jvp && hfsmp->jvp != hfsmp->hfs_devvp) {
2292 vnode_clearmountedon(hfsmp->jvp);
2293 retval = VNOP_CLOSE(hfsmp->jvp,
2294 hfsmp->hfs_flags & HFS_READ_ONLY ? FREAD : FREAD|FWRITE,
2296 vnode_put(hfsmp->jvp);
2297 hfsmp->jvp = NULL;
2308 if ((hfsmp->hfs_flags & HFS_HAS_SPARSE_DEVICE) && hfsmp->hfs_backingfs_rootvp) {
2311 hfsmp->hfs_flags &= ~HFS_HAS_SPARSE_DEVICE;
2312 tmpvp = hfsmp->hfs_backingfs_rootvp;
2313 hfsmp->hfs_backingfs_rootvp = NULLVP;
2317 lck_mtx_destroy(&hfsmp->hfc_mutex, hfs_mutex_group);
2318 lck_spin_destroy(&hfsmp->vcbFreeExtLock, hfs_spinlock_group);
2319 vnode_rele(hfsmp->hfs_devvp);
2321 hfs_delete_chash(hfsmp);
2322 FREE(hfsmp, M_HFSMNT);
2328 hfs_end_transaction(hfsmp);
2436 struct hfsmount *hfsmp = VFSTOHFS(mp);
2445 sbp->f_bfree = (u_int64_t)((u_int32_t )hfs_freeblks(hfsmp, 0));
2446 sbp->f_bavail = (u_int64_t)((u_int32_t )hfs_freeblks(hfsmp, 1));
2460 if (hfsmp->hfs_flags & HFS_STANDARD) {
2463 if (hfsmp->jnl)
2465 if (hfsmp->hfs_flags & HFS_CASE_SENSITIVE)
2487 struct hfsmount *hfsmp;
2492 hfsmp = VFSTOHFS(mp);
2493 vcb = HFSTOVCB(hfsmp);
2496 priIDSector = (daddr64_t)((vcb->hfsPlusIOPosOffset / hfsmp->hfs_logical_block_size) +
2497 HFS_PRI_SECTOR(hfsmp->hfs_logical_block_size));
2499 retval = (int)buf_meta_bread(hfsmp->hfs_devvp,
2500 HFS_PHYSBLK_ROUNDDOWN(priIDSector, hfsmp->hfs_log_per_phys),
2501 hfsmp->hfs_physical_block_size, NOCRED, &bp);
2517 if (hfsmp->hfs_alt_id_sector) {
2518 retval = (int)buf_meta_bread(hfsmp->hfs_devvp,
2519 HFS_PHYSBLK_ROUNDDOWN(hfsmp->hfs_alt_id_sector, hfsmp->hfs_log_per_phys),
2520 hfsmp->hfs_physical_block_size, NOCRED, &bp);
2578 struct hfsmount *hfsmp;
2585 hfsmp = VFSTOHFS(mp);
2590 if (hfsmp->hfs_flags & HFS_IN_CHANGEFS)
2593 if (hfsmp->hfs_flags & HFS_READ_ONLY)
2597 if (!lck_rw_try_lock_shared(&hfsmp->hfs_insync))
2614 vcb = HFSTOVCB(hfsmp);
2619 meta_vp[3] = hfsmp->hfs_attribute_vp; /* Optional file */
2657 if ((error = VNOP_FSYNC(hfsmp->hfs_devvp, waitfor, context))) {
2665 hfs_hotfilesync(hfsmp, vfs_context_kernel());
2671 error = hfs_flushvolumeheader(hfsmp, waitfor, 0);
2676 if (hfsmp->jnl) {
2677 hfs_journal_flush(hfsmp, FALSE);
2687 hfsmp->hfs_last_sync_time = now;
2690 lck_rw_unlock_shared(&hfsmp->hfs_insync);
2805 struct hfsmount * hfsmp;
2818 hfsmp = VTOHFS(vp);
2820 if (HFSTOVCB(hfsmp)->vcbSigWord == kHFSSigWord)
2823 *hfsmpp = hfsmp;
2840 struct hfsmount *hfsmp;
2859 if ((error = hfs_getmountpoint(vp, &hfsmp)))
2865 error = hfs_extendfs(hfsmp, newsize, context);
2924 hfsmp = VTOHFS(vp);
2925 if (hfsmp->hfs_flags & HFS_READ_ONLY) {
2928 if (HFSTOVCB(hfsmp)->vcbSigWord == kHFSSigWord) {
2933 if (hfsmp->jnl) {
2938 vcb = HFSTOVCB(hfsmp);
2939 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG | SFL_EXTENTS, HFS_EXCLUSIVE_LOCK);
2944 hfs_systemfile_unlock(hfsmp, lockflags);
2947 hfs_systemfile_unlock(hfsmp, lockflags);
2956 hfs_sync(hfsmp->hfs_mp, MNT_WAIT, context);
2969 jvp = hfsmp->hfs_devvp;
2971 (off_t)name[2] * (off_t)HFSTOVCB(hfsmp)->blockSize
2972 + HFSTOVCB(hfsmp)->hfsPlusIOPosOffset,
2974 hfsmp->hfs_devvp,
2975 hfsmp->hfs_logical_block_size,
2978 hfs_sync_metadata, hfsmp->hfs_mp);
2987 journal_trim_set_callback(jnl, hfs_trim_callback, hfsmp);
2991 if (jvp && jvp != hfsmp->hfs_devvp) {
2993 VNOP_CLOSE(jvp, hfsmp->hfs_flags & HFS_READ_ONLY ? FREAD : FREAD|FWRITE, vfs_context_kernel());
3000 hfs_lock_global (hfsmp, HFS_EXCLUSIVE_LOCK);
3005 buf_flushdirtyblks(hfsmp->hfs_devvp, TRUE, 0, "hfs_sysctl");
3006 buf_flushdirtyblks(hfsmp->hfs_extents_vp, TRUE, 0, "hfs_sysctl");
3007 buf_flushdirtyblks(hfsmp->hfs_catalog_vp, TRUE, 0, "hfs_sysctl");
3008 buf_flushdirtyblks(hfsmp->hfs_allocation_vp, TRUE, 0, "hfs_sysctl");
3009 if (hfsmp->hfs_attribute_vp)
3010 buf_flushdirtyblks(hfsmp->hfs_attribute_vp, TRUE, 0, "hfs_sysctl");
3012 HFSTOVCB(hfsmp)->vcbJinfoBlock = name[1];
3013 HFSTOVCB(hfsmp)->vcbAtrb |= kHFSVolumeJournaledMask;
3014 hfsmp->jvp = jvp;
3015 hfsmp->jnl = jnl;
3018 hfsmp->jnl_start = (u_int32_t)name[2];
3019 hfsmp->jnl_size = (off_t)((unsigned)name[3]);
3020 hfsmp->hfs_jnlinfoblkid = jinfo_attr.ca_fileid;
3021 hfsmp->hfs_jnlfileid = jnl_attr.ca_fileid;
3023 vfs_setflags(hfsmp->hfs_mp, (u_int64_t)((unsigned int)MNT_JOURNALED));
3025 hfs_unlock_global (hfsmp);
3026 hfs_flushvolumeheader(hfsmp, MNT_WAIT, 1);
3031 fsid.val[0] = (int32_t)hfsmp->hfs_raw_dev;
3032 fsid.val[1] = (int32_t)vfs_typenum(HFSTOVFS(hfsmp));
3047 hfsmp = VTOHFS(vp);
3053 if (hfsmp->hfs_private_attr[DIR_HARDLINKS].ca_entries != 0){
3060 hfs_lock_global (hfsmp, HFS_EXCLUSIVE_LOCK);
3063 journal_close(hfsmp->jnl);
3064 hfsmp->jnl = NULL;
3066 if (hfsmp->jvp && hfsmp->jvp != hfsmp->hfs_devvp) {
3067 vnode_clearmountedon(hfsmp->jvp);
3068 VNOP_CLOSE(hfsmp->jvp, hfsmp->hfs_flags & HFS_READ_ONLY ? FREAD : FREAD|FWRITE, vfs_context_kernel());
3069 vnode_put(hfsmp->jvp);
3071 hfsmp->jvp = NULL;
3072 vfs_clearflags(hfsmp->hfs_mp, (u_int64_t)((unsigned int)MNT_JOURNALED));
3073 hfsmp->jnl_start = 0;
3074 hfsmp->hfs_jnlinfoblkid = 0;
3075 hfsmp->hfs_jnlfileid = 0;
3077 HFSTOVCB(hfsmp)->vcbAtrb &= ~kHFSVolumeJournaledMask;
3079 hfs_unlock_global (hfsmp);
3081 hfs_flushvolumeheader(hfsmp, MNT_WAIT, 1);
3086 fsid.val[0] = (int32_t)hfsmp->hfs_raw_dev;
3087 fsid.val[1] = (int32_t)vfs_typenum(HFSTOVFS(hfsmp));
3102 hfsmp = VTOHFS(vp);
3103 if (hfsmp->jnl == NULL) {
3107 jnl_start = (off_t)(hfsmp->jnl_start * HFSTOVCB(hfsmp)->blockSize) + (off_t)HFSTOVCB(hfsmp)->hfsPlusIOPosOffset;
3108 jnl_size = (off_t)hfsmp->jnl_size;
3137 hfsmp = VFSTOHFS(mp);
3139 vq.vq_flags = hfsmp->hfs_notification_conditions;
3181 struct hfsmount *hfsmp;
3183 hfsmp = VFSTOHFS(mp);
3185 error = hfs_vget(hfsmp, (cnid_t)ino, vpp, 1, 0);
3202 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
3203 error = cat_findname(hfsmp, (cnid_t)ino, &cdesc);
3204 hfs_systemfile_unlock(hfsmp, lockflags);
3206 if ((cdesc.cd_parentcnid != hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) &&
3207 (cdesc.cd_parentcnid != hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid)) {
3227 hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock, int allow_deleted)
3242 if (cnid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid ||
3243 cnid == hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) {
3249 vp = hfs_chash_getvnode(hfsmp, cnid, 0, skiplock, allow_deleted);
3281 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
3282 error = cat_idlookup(hfsmp, cnid, 0, 0, &cndesc, &cnattr, &cnfork);
3283 hfs_systemfile_unlock(hfsmp, lockflags);
3296 if ((pid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid) &&
3300 } else if ((pid == hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) &&
3304 } else if ((pid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid) &&
3329 if ((hfs_lookup_siblinglinks(hfsmp, linkref, &prevlinkid, &nextlinkid) == 0) &&
3331 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
3332 error = cat_findname(hfsmp, nextlinkid, &linkdesc);
3333 hfs_systemfile_unlock(hfsmp, lockflags);
3344 error = hfs_getnewvnode(hfsmp, NULL, NULL, &cndesc, 0, &cnattr,
3366 error = hfs_getnewvnode(hfsmp, NULLVP, &cn, &cndesc, 0, &cnattr,
3394 struct hfsmount *hfsmp;
3402 hfsmp = VFSTOHFS(mp);
3415 if (hfsmp->hfs_qfiles[i].qf_vp != NULLVP)
3420 skipvp = hfs_chash_getvnode(hfsmp, kHFSRootFolderID, 0, 0, 0);
3449 if (hfsmp->hfs_qfiles[i].qf_vp == NULLVP)
3465 hfs_setencodingbits(struct hfsmount *hfsmp, u_int32_t encoding)
3484 if (index < 64 && (hfsmp->encodingsBitmap & (u_int64_t)(1ULL << index)) == 0) {
3485 HFS_MOUNT_LOCK(hfsmp, TRUE)
3486 hfsmp->encodingsBitmap |= (u_int64_t)(1ULL << index);
3487 MarkVCBDirty(hfsmp);
3488 HFS_MOUNT_UNLOCK(hfsmp, TRUE);
3498 hfs_volupdate(struct hfsmount *hfsmp, enum volop op, int inroot)
3504 lck_mtx_lock(&hfsmp->hfs_mutex);
3506 MarkVCBDirty(hfsmp);
3507 hfsmp->hfs_mtime = tv.tv_sec;
3513 if (hfsmp->hfs_dircount != 0xFFFFFFFF)
3514 ++hfsmp->hfs_dircount;
3515 if (inroot && hfsmp->vcbNmRtDirs != 0xFFFF)
3516 ++hfsmp->vcbNmRtDirs;
3519 if (hfsmp->hfs_dircount != 0)
3520 --hfsmp->hfs_dircount;
3521 if (inroot && hfsmp->vcbNmRtDirs != 0xFFFF)
3522 --hfsmp->vcbNmRtDirs;
3525 if (hfsmp->hfs_filecount != 0xFFFFFFFF)
3526 ++hfsmp->hfs_filecount;
3527 if (inroot && hfsmp->vcbNmFls != 0xFFFF)
3528 ++hfsmp->vcbNmFls;
3531 if (hfsmp->hfs_filecount != 0)
3532 --hfsmp->hfs_filecount;
3533 if (inroot && hfsmp->vcbNmFls != 0xFFFF)
3534 --hfsmp->vcbNmFls;
3538 lck_mtx_unlock(&hfsmp->hfs_mutex);
3540 if (hfsmp->jnl) {
3541 hfs_flushvolumeheader(hfsmp, 0, 0);
3549 hfs_flushMDB(struct hfsmount *hfsmp, int waitfor, int altflush)
3551 ExtendedVCB *vcb = HFSTOVCB(hfsmp);
3559 sector_size = hfsmp->hfs_logical_block_size;
3560 retval = (int)buf_bread(hfsmp->hfs_devvp, (daddr64_t)HFS_PRI_SECTOR(sector_size), sector_size, NOCRED, &bp);
3567 lck_mtx_lock(&hfsmp->hfs_mutex);
3618 lck_mtx_unlock(&hfsmp->hfs_mutex);
3624 if (buf_meta_bread(hfsmp->hfs_devvp, hfsmp->hfs_alt_id_sector, sector_size, NOCRED, &alt_bp) == 0) {
3649 hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor, int altflush)
3651 ExtendedVCB *vcb = HFSTOVCB(hfsmp);
3662 if (hfsmp->hfs_flags & HFS_READ_ONLY) {
3665 if (hfsmp->hfs_flags & HFS_STANDARD) {
3666 return hfs_flushMDB(hfsmp, waitfor, altflush);
3669 priIDSector = (daddr64_t)((vcb->hfsPlusIOPosOffset / hfsmp->hfs_logical_block_size) +
3670 HFS_PRI_SECTOR(hfsmp->hfs_logical_block_size));
3672 if (hfs_start_transaction(hfsmp) != 0) {
3679 retval = (int)buf_meta_bread(hfsmp->hfs_devvp,
3680 HFS_PHYSBLK_ROUNDDOWN(priIDSector, hfsmp->hfs_log_per_phys),
3681 hfsmp->hfs_physical_block_size, NOCRED, &bp);
3688 HFS_PRI_OFFSET(hfsmp->hfs_physical_block_size));
3702 hfsmp->hfs_alt_id_sector ? "; trying alternate" : "");
3703 hfs_mark_volume_inconsistent(hfsmp);
3705 if (hfsmp->hfs_alt_id_sector) {
3706 retval = buf_meta_bread(hfsmp->hfs_devvp,
3707 HFS_PHYSBLK_ROUNDDOWN(hfsmp->hfs_alt_id_sector, hfsmp->hfs_log_per_phys),
3708 hfsmp->hfs_physical_block_size, NOCRED, &alt_bp);
3715 HFS_ALT_OFFSET(hfsmp->hfs_physical_block_size));
3740 if (hfsmp->jnl) {
3741 journal_modify_block_start(hfsmp->jnl, bp);
3753 retval = (int)buf_meta_bread(hfsmp->hfs_devvp,
3754 HFS_PHYSBLK_ROUNDDOWN(HFS_PRI_SECTOR(hfsmp->hfs_logical_block_size), hfsmp->hfs_log_per_phys),
3755 hfsmp->hfs_physical_block_size, NOCRED, &bp2);
3762 HFS_PRI_OFFSET(hfsmp->hfs_physical_block_size));
3766 if (hfsmp->jnl) {
3767 journal_modify_block_start(hfsmp->jnl, bp2);
3772 if (hfsmp->jnl) {
3773 journal_modify_block_end(hfsmp->jnl, bp2, NULL, NULL);
3785 lck_mtx_lock(&hfsmp->hfs_mutex);
3790 if (hfsmp->jnl) {
3867 if (hfsmp->hfs_attribute_vp) {
3868 fp = VTOF(hfsmp->hfs_attribute_vp);
3882 if (hfsmp->hfs_startup_vp) {
3883 fp = VTOF(hfsmp->hfs_startup_vp);
3899 MarkVCBClean(hfsmp);
3900 lck_mtx_unlock(&hfsmp->hfs_mutex);
3903 if (altflush && hfsmp->hfs_alt_id_sector) {
3904 if (buf_meta_bread(hfsmp->hfs_devvp,
3905 HFS_PHYSBLK_ROUNDDOWN(hfsmp->hfs_alt_id_sector, hfsmp->hfs_log_per_phys),
3906 hfsmp->hfs_physical_block_size, NOCRED, &alt_bp) == 0) {
3907 if (hfsmp->jnl) {
3908 journal_modify_block_start(hfsmp->jnl, alt_bp);
3912 HFS_ALT_OFFSET(hfsmp->hfs_physical_block_size),
3915 if (hfsmp->jnl) {
3916 journal_modify_block_end(hfsmp->jnl, alt_bp, NULL, NULL);
3924 if (hfsmp->jnl) {
3925 journal_modify_block_end(hfsmp->jnl, bp, NULL, NULL);
3933 (void) VNOP_IOCTL(hfsmp->hfs_devvp, DKIOCSYNCHRONIZECACHE,
3938 hfs_end_transaction(hfsmp);
3947 hfs_end_transaction(hfsmp);
3956 hfs_extendfs(struct hfsmount *hfsmp, u_int64_t newsize, vfs_context_t context)
3982 devvp = hfsmp->hfs_devvp;
3983 vcb = HFSTOVCB(hfsmp);
3991 (hfsmp->jnl == NULL) ||
4000 error = hfs_vget(hfsmp, kHFSRootFolderID, &vp, 0, 0);
4004 error = hfs_owner_rights(hfsmp, VTOC(vp)->c_uid, cred, p, 0);
4020 if (sector_size != hfsmp->hfs_logical_block_size) {
4038 oldsize = (u_int64_t)hfsmp->totalBlocks * (u_int64_t)hfsmp->blockSize;
4054 printf ("hfs_extendfs: old: size=%qu, blkcnt=%u\n", oldsize, hfsmp->totalBlocks);
4059 HFS_MOUNT_LOCK(hfsmp, TRUE);
4060 if (hfsmp->hfs_flags & HFS_RESIZE_IN_PROGRESS) {
4061 HFS_MOUNT_UNLOCK(hfsmp, TRUE);
4065 hfsmp->hfs_flags |= HFS_RESIZE_IN_PROGRESS;
4066 HFS_MOUNT_UNLOCK(hfsmp, TRUE);
4069 hfs_journal_flush(hfsmp, TRUE);
4074 if (hfs_start_transaction(hfsmp) != 0) {
4081 /* Update the hfsmp fields for the physical information about the device */
4082 prev_phys_block_count = hfsmp->hfs_logical_block_count;
4083 prev_alt_sector = hfsmp->hfs_alt_id_sector;
4085 hfsmp->hfs_logical_block_count = sector_count;
4090 hfsmp->hfs_alt_id_sector = (hfsmp->hfsPlusIOPosOffset / sector_size) +
4091 HFS_ALT_SECTOR(sector_size, hfsmp->hfs_logical_block_count);
4092 hfsmp->hfs_logical_bytes = (uint64_t) sector_count * (uint64_t) sector_size;
4099 lockflags = hfs_systemfile_lock(hfsmp, SFL_ATTRIBUTE | SFL_EXTENTS | SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
4254 error = hfs_flushvolumeheader(hfsmp, MNT_WAIT, HFS_ALTFLUSH);
4275 hfsmp->hfs_logical_block_count = prev_phys_block_count;
4276 hfsmp->hfs_alt_id_sector = prev_alt_sector;
4280 hfs_mark_volume_inconsistent(hfsmp);
4284 hfs_mark_volume_inconsistent(hfsmp);
4294 if (buf_meta_bread(hfsmp->hfs_devvp,
4295 HFS_PHYSBLK_ROUNDDOWN(prev_alt_sector, hfsmp->hfs_log_per_phys),
4296 hfsmp->hfs_physical_block_size, NOCRED, &bp) == 0) {
4297 journal_modify_block_start(hfsmp->jnl, bp);
4299 bzero((char *)buf_dataptr(bp) + HFS_ALT_OFFSET(hfsmp->hfs_physical_block_size), kMDBSize);
4301 journal_modify_block_end(hfsmp->jnl, bp, NULL, NULL);
4310 hfs_metadatazone_init(hfsmp, false);
4313 * Adjust the size of hfsmp->hfs_attrdata_vp
4315 if (hfsmp->hfs_attrdata_vp) {
4319 if (vnode_get(hfsmp->hfs_attrdata_vp) == 0) {
4320 attr_cp = VTOC(hfsmp->hfs_attrdata_vp);
4321 attr_fp = VTOF(hfsmp->hfs_attrdata_vp);
4326 attr_fp->ff_size = (off_t) newblkcnt * hfsmp->blockSize;
4327 ubc_setsize(hfsmp->hfs_attrdata_vp, attr_fp->ff_size);
4328 vnode_put(hfsmp->hfs_attrdata_vp);
4341 * We only update hfsmp->allocLimit if totalBlocks actually increased.
4344 UpdateAllocLimit(hfsmp, hfsmp->totalBlocks);
4351 hfs_systemfile_unlock(hfsmp, lockflags);
4355 hfs_end_transaction(hfsmp);
4356 hfs_journal_flush(hfsmp, TRUE);
4361 error = hfs_extend_journal(hfsmp, sector_size, sector_count, context);
4369 hfsmp->vcbVN, hfsmp->totalBlocks, (u_int32_t)(oldsize/hfsmp->blockSize));
4380 HFS_MOUNT_LOCK(hfsmp, TRUE);
4381 hfsmp->hfs_flags &= ~HFS_RESIZE_IN_PROGRESS;
4382 HFS_MOUNT_UNLOCK(hfsmp, TRUE);
4384 hfs_systemfile_unlock(hfsmp, lockflags);
4387 hfs_end_transaction(hfsmp);
4388 hfs_journal_flush(hfsmp, FALSE);
4390 (void) VNOP_IOCTL(hfsmp->hfs_devvp, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, context);
4402 hfs_truncatefs(struct hfsmount *hfsmp, u_int64_t newsize, vfs_context_t context)
4414 lck_mtx_lock(&hfsmp->hfs_mutex);
4415 if (hfsmp->hfs_flags & HFS_RESIZE_IN_PROGRESS) {
4416 lck_mtx_unlock(&hfsmp->hfs_mutex);
4419 hfsmp->hfs_flags |= HFS_RESIZE_IN_PROGRESS;
4420 hfsmp->hfs_resize_blocksmoved = 0;
4421 hfsmp->hfs_resize_totalblocks = 0;
4422 hfsmp->hfs_resize_progress = 0;
4423 lck_mtx_unlock(&hfsmp->hfs_mutex);
4429 if ((hfsmp->jnl == NULL) ||
4430 (hfsmp->hfsPlusIOPosOffset != 0)) {
4434 oldsize = (u_int64_t)hfsmp->totalBlocks * (u_int64_t)hfsmp->blockSize;
4435 newblkcnt = newsize / hfsmp->blockSize;
4436 reclaimblks = hfsmp->totalBlocks - newblkcnt;
4439 printf ("hfs_truncatefs: old: size=%qu, blkcnt=%u, freeblks=%u\n", oldsize, hfsmp->totalBlocks, hfs_freeblks(hfsmp, 1));
4446 (newsize % hfsmp->hfs_logical_block_size) ||
4447 (newsize % hfsmp->hfs_physical_block_size)) {
4494 if (reclaimblks >= hfs_freeblks(hfsmp, 1)) {
4495 printf("hfs_truncatefs: insufficient space (need %u blocks; have %u free blocks)\n", reclaimblks, hfs_freeblks(hfsmp, 1));
4501 hfs_journal_flush(hfsmp, TRUE);
4503 if (hfs_start_transaction(hfsmp) != 0) {
4510 lockflags = hfs_systemfile_lock(hfsmp, SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
4523 if (hfsmp->blockSize == 512) {
4524 error = UpdateAllocLimit (hfsmp, newblkcnt - 2);
4527 error = UpdateAllocLimit (hfsmp, newblkcnt - 1);
4543 HFS_MOUNT_LOCK(hfsmp, TRUE);
4544 if (hfsmp->hfs_flags & HFS_HAS_SPARSE_DEVICE) {
4545 hfsmp->hfs_flags &= ~HFS_HAS_SPARSE_DEVICE;
4546 ResetVCBFreeExtCache(hfsmp);
4561 hfsmp->freeBlocks -= reclaimblks;
4563 HFS_MOUNT_UNLOCK(hfsmp, TRUE);
4566 hfs_systemfile_unlock(hfsmp, lockflags);
4574 hfs_metadatazone_init(hfsmp, false);
4586 if (hfs_isallocated(hfsmp, hfsmp->allocLimit, reclaimblks)) {
4591 hfs_end_transaction(hfsmp);
4595 error = hfs_reclaimspace(hfsmp, hfsmp->allocLimit, reclaimblks, context);
4597 printf("hfs_truncatefs: couldn't reclaim space on %s (error=%d)\n", hfsmp->vcbVN, error);
4601 if (hfs_start_transaction(hfsmp) != 0) {
4608 error = hfs_isallocated(hfsmp, hfsmp->allocLimit, reclaimblks);
4610 printf("hfs_truncatefs: didn't reclaim enough space on %s (error=%d)\n", hfsmp->vcbVN, error);
4620 lockflags = hfs_systemfile_lock(hfsmp, SFL_ATTRIBUTE | SFL_EXTENTS | SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
4625 error = BlockMarkAllocated(hfsmp, hfsmp->allocLimit, (hfsmp->blockSize == 512) ? 2 : 1);
4635 if (hfsmp->blockSize == 512)
4636 (void) BlockMarkFree(hfsmp, hfsmp->totalBlocks - 2, 2);
4638 (void) BlockMarkFree(hfsmp, hfsmp->totalBlocks - 1, 1);
4646 if (hfsmp->hfs_alt_id_sector) {
4647 error = buf_meta_bread(hfsmp->hfs_devvp,
4648 HFS_PHYSBLK_ROUNDDOWN(hfsmp->hfs_alt_id_sector, hfsmp->hfs_log_per_phys),
4649 hfsmp->hfs_physical_block_size, NOCRED, &bp);
4651 bzero((void*)((char *)buf_dataptr(bp) + HFS_ALT_OFFSET(hfsmp->hfs_physical_block_size)), kMDBSize);
4663 hfsmp->vcbVN, newblkcnt, hfsmp->totalBlocks);
4668 hfsmp->totalBlocks = newblkcnt;
4669 hfsmp->hfs_logical_block_count = newsize / hfsmp->hfs_logical_block_size;
4670 hfsmp->hfs_logical_bytes = (uint64_t) hfsmp->hfs_logical_block_count * (uint64_t) hfsmp->hfs_logical_block_size;
4678 hfsmp->hfs_alt_id_sector = HFS_ALT_SECTOR(hfsmp->hfs_logical_block_size, hfsmp->hfs_logical_block_count);
4679 MarkVCBDirty(hfsmp);
4680 error = hfs_flushvolumeheader(hfsmp, MNT_WAIT, HFS_ALTFLUSH);
4685 * Adjust the size of hfsmp->hfs_attrdata_vp
4687 if (hfsmp->hfs_attrdata_vp) {
4691 if (vnode_get(hfsmp->hfs_attrdata_vp) == 0) {
4692 cp = VTOC(hfsmp->hfs_attrdata_vp);
4693 fp = VTOF(hfsmp->hfs_attrdata_vp);
4698 fp->ff_size = (off_t) newblkcnt * hfsmp->blockSize;
4699 ubc_setsize(hfsmp->hfs_attrdata_vp, fp->ff_size);
4700 vnode_put(hfsmp->hfs_attrdata_vp);
4709 UpdateAllocLimit (hfsmp, hfsmp->totalBlocks);
4711 HFS_MOUNT_LOCK(hfsmp, TRUE);
4718 hfsmp->hfs_flags |= HFS_HAS_SPARSE_DEVICE;
4719 ResetVCBFreeExtCache(hfsmp);
4723 hfsmp->freeBlocks += reclaimblks;
4726 if (hfsmp->nextAllocation >= hfsmp->allocLimit) {
4727 hfsmp->nextAllocation = hfsmp->hfs_metazone_end + 1;
4729 hfsmp->hfs_flags &= ~HFS_RESIZE_IN_PROGRESS;
4730 HFS_MOUNT_UNLOCK(hfsmp, TRUE);
4734 hfs_metadatazone_init(hfsmp, false);
4738 hfs_systemfile_unlock(hfsmp, lockflags);
4741 hfs_end_transaction(hfsmp);
4742 hfs_journal_flush(hfsmp, FALSE);
4744 (void) VNOP_IOCTL(hfsmp->hfs_devvp, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, context);
4795 struct hfsmount *hfsmp,
4811 u_int32_t sectorsPerBlock = hfsmp->blockSize / hfsmp->hfs_logical_block_size;
4824 if (cp != hfsmp->hfs_allocation_cp && cp->c_lockowner != current_thread())
4836 if (!vnode_issystem (vp) && vnode_isreg(vp) && cp_fs_protected (hfsmp->hfs_mp)) {
4854 cp_err = cp_handle_relocate(cp, hfsmp);
4874 vfs_ioattr(hfsmp->hfs_mp, &ioattr);
4880 bp = buf_alloc(hfsmp->hfs_devvp);
4883 resid = (off_t) blockCount * (off_t) hfsmp->blockSize;
4884 srcSector = (daddr64_t) oldStart * hfsmp->blockSize / hfsmp->hfs_logical_block_size;
4885 destSector = (daddr64_t) newStart * hfsmp->blockSize / hfsmp->hfs_logical_block_size;
4888 ioSizeSectors = ioSize / hfsmp->hfs_logical_block_size;
4910 buf_setcpaddr(bp, hfsmp->hfs_resize_cpentry);
4946 if (vnode_issystem(vp) && journal_uses_fua(hfsmp->jnl))
4953 buf_setcpaddr(bp, hfsmp->hfs_resize_cpentry);
4972 vnode_startwrite(hfsmp->hfs_devvp);
4998 if (vnode_issystem(vp) && !journal_uses_fua(hfsmp->jnl)) {
4999 err = VNOP_IOCTL(hfsmp->hfs_devvp, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, context);
5549 hfs_reclaim_extent(struct hfsmount *hfsmp, const u_long allocLimit, struct hfs_reclaim_extent_info *extent_info, vfs_context_t context)
5585 error = hfs_start_transaction(hfsmp);
5589 extent_info->lockflags = hfs_systemfile_lock(hfsmp, extent_info->lockflags, HFS_EXCLUSIVE_LOCK);
5616 if (node_size > hfsmp->blockSize) {
5617 remainder_blocks = newBlockCount % (node_size / hfsmp->blockSize);
5621 printf ("hfs_reclaim_extent: Round-down newBlockCount to be multiple of nodeSize, node_allocblks=%u, old=%u, new=%u\n", node_size/hfsmp->blockSize, newBlockCount + remainder_blocks, newBlockCount);
5671 error = BlockAllocate(hfsmp, 1, oldBlockCount, oldBlockCount, alloc_flags,
5677 error = BlockAllocate(hfsmp, 1, oldBlockCount, oldBlockCount,
5686 error = BlockAllocate(hfsmp, 1, oldBlockCount, oldBlockCount,
5700 if (node_size > hfsmp->blockSize) {
5701 remainder_blocks = newBlockCount % (node_size / hfsmp->blockSize);
5705 BlockDeallocate(hfsmp, newStartBlock + roundedBlockCount,
5710 printf ("hfs_reclaim_extent: Fixing extent block count, node_blks=%u, old=%u, new=%u\n", node_size/hfsmp->blockSize, newBlockCount + remainder_blocks, newBlockCount);
5741 error = hfs_copy_extent(hfsmp, extent_info->vp, oldStartBlock,
5755 error = cat_update_dirlink(hfsmp, extent_info->forkType,
5762 error = hfs_flushvolumeheader(hfsmp, MNT_WAIT, HFS_ALTFLUSH);
5776 error = BlockDeallocate(hfsmp, oldStartBlock, oldBlockCount, HFS_ALLOC_SKIPFREEBLKS);
5790 BlockDeallocate(hfsmp, newStartBlock, newBlockCount, HFS_ALLOC_SKIPFREEBLKS);
5797 hfs_systemfile_unlock(hfsmp, extent_info->lockflags);
5808 hfs_end_transaction(hfsmp);
5815 hfs_truncatefs_progress(struct hfsmount *hfsmp)
5819 hfs_resize_progress(hfsmp, &cur_progress);
5820 if (cur_progress > (hfsmp->hfs_resize_progress + 9)) {
5822 hfsmp->hfs_resize_progress = cur_progress;
5847 * hfsmp The volume being resized.
5859 * hfsmp->hfs_resize_blocksmoved is incremented by the number of allocation
5863 hfs_reclaim_file(struct hfsmount *hfsmp, struct vnode *vp, u_int32_t fileID,
5917 extent_info->fcb = VTOF(hfsmp->hfs_extents_vp);
5933 error = hfs_journal_flush(hfsmp, TRUE);
5998 lockflags = hfs_systemfile_lock(hfsmp, lockflags, HFS_EXCLUSIVE_LOCK);
5999 error = cat_lookup_dirlink(hfsmp, fileID, forktype,
6002 hfs_systemfile_unlock(hfsmp, lockflags);
6021 error = hfs_reclaim_extent(hfsmp, allocLimit, extent_info, context);
6062 lockflags = hfs_systemfile_lock(hfsmp, lockflags, HFS_EXCLUSIVE_LOCK);
6066 hfs_systemfile_unlock(hfsmp, lockflags);
6076 error = hfs_reclaim_extent(hfsmp, allocLimit, extent_info, context);
6084 lockflags = hfs_systemfile_lock(hfsmp, lockflags, HFS_EXCLUSIVE_LOCK);
6088 hfs_systemfile_unlock(hfsmp, lockflags);
6104 hfsmp->hfs_resize_blocksmoved += extent_info->blocks_relocated;
6105 hfs_truncatefs_progress(hfsmp);
6108 extent_info->blocks_relocated, fileID, hfsmp->vcbVN);
6156 struct hfsmount *hfsmp;
6167 struct hfsmount *hfsmp = args->hfsmp;
6171 error = buf_meta_bread(hfsmp->hfs_devvp,
6172 hfsmp->vcbJinfoBlock * (hfsmp->blockSize/hfsmp->hfs_logical_block_size),
6173 hfsmp->blockSize, vfs_context_ucred(args->context), &bp);
6182 jibp->offset = SWAP_BE64((u_int64_t)args->newStartBlock * hfsmp->blockSize);
6183 jibp->size = SWAP_BE64((u_int64_t)args->newBlockCount * hfsmp->blockSize);
6184 if (journal_uses_fua(hfsmp->jnl))
6191 if (!journal_uses_fua(hfsmp->jnl)) {
6192 error = VNOP_IOCTL(hfsmp->hfs_devvp, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, args->context);
6217 hfs_relocate_journal_file(struct hfsmount *hfsmp, u_int32_t jnl_size, int resize_type, vfs_context_t context)
6234 jnlBlockCount = howmany(jnl_size, hfsmp->blockSize);
6256 error = hfs_start_transaction(hfsmp);
6261 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG | SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
6263 error = BlockAllocate(hfsmp, 1, jnlBlockCount, jnlBlockCount,
6275 error = cat_idlookup(hfsmp, hfsmp->hfs_jnlfileid, 1, 0, &journal_desc, &journal_attr, &journal_fork);
6283 error = BlockDeallocate(hfsmp, oldStartBlock, oldBlockCount, alloc_skipfreeblks);
6290 journal_fork.cf_size = newBlockCount * hfsmp->blockSize;
6294 error = cat_update(hfsmp, &journal_desc, &journal_attr, &journal_fork, NULL);
6306 if (hfsmp->jvp == hfsmp->hfs_devvp) {
6307 callback_args.hfsmp = hfsmp;
6312 error = journal_relocate(hfsmp->jnl, (off_t)newStartBlock*hfsmp->blockSize,
6313 (off_t)newBlockCount*hfsmp->blockSize, 0,
6323 hfsmp->jnl_start = newStartBlock;
6324 hfsmp->jnl_size = (off_t)newBlockCount * hfsmp->blockSize;
6327 hfs_systemfile_unlock(hfsmp, lockflags);
6328 error = hfs_end_transaction(hfsmp);
6336 journal_err = BlockDeallocate(hfsmp, newStartBlock, newBlockCount, HFS_ALLOC_SKIPFREEBLKS);
6339 hfs_mark_volume_inconsistent(hfsmp);
6342 hfs_systemfile_unlock(hfsmp, lockflags);
6343 (void) hfs_end_transaction(hfsmp);
6358 hfs_reclaim_journal_file(struct hfsmount *hfsmp, u_int32_t allocLimit, vfs_context_t context)
6362 u_int32_t blockCount = hfsmp->jnl_size / hfsmp->blockSize;
6368 if (hfsmp->jvp == hfsmp->hfs_devvp) {
6369 startBlock = hfsmp->jnl_start;
6370 blockCount = hfsmp->jnl_size / hfsmp->blockSize;
6382 old_jnlfileid = hfsmp->hfs_jnlfileid;
6383 hfsmp->hfs_jnlfileid = 0;
6384 fileid = GetFileInfo(hfsmp, kHFSRootFolderID, ".journal", &attr, &fork);
6385 hfsmp->hfs_jnlfileid = old_jnlfileid;
6400 error = hfs_relocate_journal_file(hfsmp, blockCount * hfsmp->blockSize, HFS_RESIZE_TRUNCATE, context);
6402 hfsmp->hfs_resize_blocksmoved += blockCount;
6403 hfs_truncatefs_progress(hfsmp);
6405 blockCount, hfsmp->vcbVN);
6418 hfs_reclaim_journal_info_block(struct hfsmount *hfsmp, u_int32_t allocLimit, vfs_context_t context)
6431 if (hfsmp->vcbJinfoBlock <= allocLimit) {
6436 error = hfs_start_transaction(hfsmp);
6441 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG | SFL_BITMAP, HFS_EXCLUSIVE_LOCK);
6443 error = BlockAllocate(hfsmp, 1, 1, 1,
6454 error = BlockDeallocate(hfsmp, hfsmp->vcbJinfoBlock, 1, HFS_ALLOC_SKIPFREEBLKS);
6461 error = buf_meta_bread(hfsmp->hfs_devvp,
6462 hfsmp->vcbJinfoBlock * (hfsmp->blockSize/hfsmp->hfs_logical_block_size),
6463 hfsmp->blockSize, vfs_context_ucred(context), &old_bp);
6471 new_bp = buf_getblk(hfsmp->hfs_devvp,
6472 newBlock * (hfsmp->blockSize/hfsmp->hfs_logical_block_size),
6473 hfsmp->blockSize, 0, 0, BLK_META);
6474 bcopy((char*)buf_dataptr(old_bp), (char*)buf_dataptr(new_bp), hfsmp->blockSize);
6476 if (journal_uses_fua(hfsmp->jnl))
6483 if (!journal_uses_fua(hfsmp->jnl)) {
6484 error = VNOP_IOCTL(hfsmp->hfs_devvp, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, context);
6492 error = cat_idlookup(hfsmp, hfsmp->hfs_jnlinfoblkid, 1, 0, &jib_desc, &jib_attr, &jib_fork);
6498 jib_fork.cf_size = hfsmp->blockSize;
6502 error = cat_update(hfsmp, &jib_desc, &jib_attr, &jib_fork, NULL);
6510 hfsmp->vcbJinfoBlock = newBlock;
6511 error = hfs_flushvolumeheader(hfsmp, MNT_WAIT, HFS_ALTFLUSH);
6516 hfs_systemfile_unlock(hfsmp, lockflags);
6517 error = hfs_end_transaction(hfsmp);
6521 error = hfs_journal_flush(hfsmp, FALSE);
6527 hfsmp->hfs_resize_blocksmoved += 1;
6528 hfs_truncatefs_progress(hfsmp);
6531 hfsmp->vcbVN);
6539 journal_err = BlockDeallocate(hfsmp, newBlock, blockCount, HFS_ALLOC_SKIPFREEBLKS);
6542 hfs_mark_volume_inconsistent(hfsmp);
6546 hfs_systemfile_unlock(hfsmp, lockflags);
6547 (void) hfs_end_transaction(hfsmp);
6556 calculate_journal_size(struct hfsmount *hfsmp, u_int32_t sector_size, u_int64_t sector_count)
6575 if (journal_size < hfsmp->blockSize) {
6576 journal_size = hfsmp->blockSize;
6588 hfs_extend_journal(struct hfsmount *hfsmp, u_int32_t sector_size, u_int64_t sector_count, vfs_context_t context)
6593 if (hfsmp->jvp != hfsmp->hfs_devvp) {
6600 calc_journal_size = calculate_journal_size(hfsmp, sector_size, sector_count);
6601 if (calc_journal_size <= hfsmp->jnl_size) {
6607 printf ("hfs_extend_journal: journal old=%u, new=%qd\n", hfsmp->jnl_size, calc_journal_size);
6611 error = hfs_relocate_journal_file(hfsmp, calc_journal_size, HFS_RESIZE_EXTEND, context);
6614 hfsmp->jnl_size, hfsmp->vcbVN);
6633 * hfsmp->hfs_resize_blocksmoved is incremented by the number of allocation
6640 hfs_reclaim_xattr(struct hfsmount *hfsmp, struct vnode *vp, u_int32_t fileID, u_int32_t allocLimit, vfs_context_t context)
6662 extent_info->fcb = VTOF(hfsmp->hfs_attribute_vp);
6697 hfs_lock_truncate(VTOC(hfsmp->hfs_attrdata_vp), HFS_EXCLUSIVE_LOCK);
6698 (void)cluster_push(hfsmp->hfs_attrdata_vp, 0);
6699 error = vnode_waitforwrites(hfsmp->hfs_attrdata_vp, 0, 0, 0, "hfs_reclaim_xattr");
6700 hfs_unlock_truncate(VTOC(hfsmp->hfs_attrdata_vp), 0);
6708 *lockflags = hfs_systemfile_lock(hfsmp, *lockflags, HFS_EXCLUSIVE_LOCK);
6712 hfs_systemfile_unlock(hfsmp, *lockflags);
6723 *lockflags = hfs_systemfile_lock(hfsmp, *lockflags, HFS_EXCLUSIVE_LOCK);
6727 hfs_systemfile_unlock(hfsmp, *lockflags);
6757 error = hfs_reclaim_extent(hfsmp, allocLimit, extent_info, context);
6768 hfsmp->hfs_resize_blocksmoved += extent_info->blocks_relocated;
6769 hfs_truncatefs_progress(hfsmp);
6801 hfs_reclaim_xattrspace(struct hfsmount *hfsmp, u_int32_t allocLimit, vfs_context_t context)
6818 fcb = VTOF(hfsmp->hfs_attribute_vp);
6820 prev_blocksmoved = hfsmp->hfs_resize_blocksmoved;
6835 lockflags = hfs_systemfile_lock(hfsmp, SFL_ATTRIBUTE, HFS_SHARED_LOCK);
6837 hfs_systemfile_unlock(hfsmp, lockflags);
6893 if (hfs_vget(hfsmp, key->fileID, &vp, 0, 1) != 0) {
6897 error = hfs_reclaim_xattr(hfsmp, vp, key->fileID, allocLimit, context);
6910 (hfsmp->hfs_resize_blocksmoved - prev_blocksmoved),
6911 files_moved, hfsmp->vcbVN);
6930 hfs_reclaim_filespace(struct hfsmount *hfsmp, u_int32_t allocLimit, vfs_context_t context)
6945 fcb = VTOF(hfsmp->hfs_catalog_vp);
6947 prev_blocksmoved = hfsmp->hfs_resize_blocksmoved;
6963 if (cp_fs_protected (hfsmp->hfs_mp)) {
6964 error = cp_entry_gentempkeys(&hfsmp->hfs_resize_cpentry, hfsmp);
6980 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
6982 hfs_systemfile_unlock(hfsmp, lockflags);
6996 if (hfs_file_extent_overlaps(hfsmp, allocLimit, &filerec) == false) {
7001 if (hfs_vget(hfsmp, filerec.fileID, &vp, 0, 1) != 0) {
7011 error = hfs_reclaim_file(hfsmp, vp, filerec.fileID,
7029 error = hfs_vgetrsrc(hfsmp, vp, &rvp, TRUE, FALSE);
7039 error = hfs_reclaim_file(hfsmp, rvp, filerec.fileID,
7060 (hfsmp->hfs_resize_blocksmoved - prev_blocksmoved),
7061 files_moved, hfsmp->vcbVN);
7071 cp_entry_destroy(&hfsmp->hfs_resize_cpentry);
7085 hfs_reclaimspace(struct hfsmount *hfsmp, u_int32_t allocLimit, u_int32_t reclaimblks, vfs_context_t context)
7097 error = hfs_count_allocated(hfsmp, allocLimit, reclaimblks, &(hfsmp->hfs_resize_totalblocks));
7103 printf ("hfs_reclaimspace: Total number of blocks to reclaim = %u\n", hfsmp->hfs_resize_totalblocks);
7107 hfs_journal_flush(hfsmp, TRUE);
7115 error = hfs_reclaim_journal_file(hfsmp, allocLimit, context);
7122 error = hfs_reclaim_journal_info_block(hfsmp, allocLimit, context);
7134 error = hfs_reclaim_file(hfsmp, hfsmp->hfs_extents_vp, kHFSExtentsFileID,
7142 error = hfs_reclaim_file(hfsmp, hfsmp->hfs_allocation_vp, kHFSAllocationFileID,
7150 error = hfs_reclaim_file(hfsmp, hfsmp->hfs_catalog_vp, kHFSCatalogFileID,
7158 error = hfs_reclaim_file(hfsmp, hfsmp->hfs_attribute_vp, kHFSAttributesFileID,
7166 error = hfs_reclaim_file(hfsmp, hfsmp->hfs_startup_vp, kHFSStartupFileID,
7183 if (hfsmp->hfs_resize_blocksmoved) {
7184 hfs_journal_flush(hfsmp, TRUE);
7188 error = hfs_reclaim_filespace(hfsmp, allocLimit, context);
7195 error = hfs_reclaim_xattrspace(hfsmp, allocLimit, context);
7214 hfs_file_extent_overlaps(struct hfsmount *hfsmp, u_int32_t allocLimit, struct HFSPlusCatalogFile *filerec)
7272 fcb = VTOF(hfsmp->hfs_extents_vp);
7274 lockflags = hfs_systemfile_lock(hfsmp, SFL_EXTENTS, HFS_SHARED_LOCK);
7311 hfs_systemfile_unlock(hfsmp, lockflags);
7325 hfs_resize_progress(struct hfsmount *hfsmp, u_int32_t *progress)
7327 if ((hfsmp->hfs_flags & HFS_RESIZE_IN_PROGRESS) == 0) {
7331 if (hfsmp->hfs_resize_totalblocks > 0) {
7332 *progress = (u_int32_t)((hfsmp->hfs_resize_blocksmoved * 100ULL) / hfsmp->hfs_resize_totalblocks);
7346 hfs_getvoluuid(struct hfsmount *hfsmp, uuid_t result)
7351 ((uint32_t *)rawUUID)[0] = hfsmp->vcbFndrInfo[6];
7352 ((uint32_t *)rawUUID)[1] = hfsmp->vcbFndrInfo[7];
7374 struct hfsmount *hfsmp = VFSTOHFS(mp);
7377 freeCNIDs = (u_int32_t)0xFFFFFFFF - (u_int32_t)hfsmp->vcbNxtCNID;
7379 VFSATTR_RETURN(fsap, f_objcount, (u_int64_t)hfsmp->vcbFilCnt + (u_int64_t)hfsmp->vcbDirCnt);
7380 VFSATTR_RETURN(fsap, f_filecount, (u_int64_t)hfsmp->vcbFilCnt);
7381 VFSATTR_RETURN(fsap, f_dircount, (u_int64_t)hfsmp->vcbDirCnt);
7384 VFSATTR_RETURN(fsap, f_blocks, (u_int64_t)hfsmp->totalBlocks);
7385 VFSATTR_RETURN(fsap, f_bfree, (u_int64_t)hfs_freeblks(hfsmp, 0));
7386 VFSATTR_RETURN(fsap, f_bavail, (u_int64_t)hfs_freeblks(hfsmp, 1));
7389 VFSATTR_RETURN(fsap, f_bused, hfsmp->totalBlocks - hfs_freeblks(hfsmp, 1));
7391 VFSATTR_RETURN(fsap, f_files, (u_int64_t)(hfsmp->totalBlocks - 2));
7392 VFSATTR_RETURN(fsap, f_ffree, MIN((u_int64_t)freeCNIDs, (u_int64_t)hfs_freeblks(hfsmp, 1)));
7394 fsap->f_fsid.val[0] = hfsmp->hfs_raw_dev;
7406 if (hfsmp->hfs_flags & HFS_STANDARD) {
7420 (hfsmp->jnl ? VOL_CAP_FMT_JOURNAL_ACTIVE : 0) |
7421 (hfsmp->hfs_flags & HFS_CASE_SENSITIVE ? VOL_CAP_FMT_CASE_SENSITIVE : 0) |
7511 fsap->f_create_time.tv_sec = hfsmp->hfs_itime;
7514 fsap->f_modify_time.tv_sec = hfsmp->vcbLsMod;
7518 fsap->f_backup_time.tv_sec = hfsmp->vcbVolBkUp;
7534 if (hfsmp->hfs_flags & HFS_STANDARD) {
7537 if (hfsmp->jnl)
7539 if (hfsmp->hfs_flags & HFS_CASE_SENSITIVE)
7547 strlcpy(fsap->f_vol_name, (char *) hfsmp->vcbVN, MAXPATHLEN);
7551 hfs_getvoluuid(hfsmp, fsap->f_uuid);
7565 struct hfsmount *hfsmp = VTOHFS(vp);
7599 if ((error = hfs_start_transaction(hfsmp)) == 0) {
7600 if ((error = cat_preflight(hfsmp, CAT_RENAME, &cookie, p)) == 0) {
7601 lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_EXCLUSIVE_LOCK);
7603 error = cat_rename(hfsmp, &cp->c_desc, &todir_desc, &to_desc, &new_desc);
7615 (void) VNOP_IOCTL (hfsmp->hfs_devvp, DKIOCCSSETLVNAME, converted_volname, 0, vfs_context_current());
7620 hfs_systemfile_unlock(hfsmp, lockflags);
7621 cat_postflight(hfsmp, &cookie, p);
7625 (void) hfs_flushvolumeheader(hfsmp, MNT_WAIT, 0);
7627 hfs_end_transaction(hfsmp);
7693 void hfs_mark_volume_inconsistent(struct hfsmount *hfsmp)
7695 HFS_MOUNT_LOCK(hfsmp, TRUE);
7696 if ((hfsmp->vcbAtrb & kHFSVolumeInconsistentMask) == 0) {
7697 hfsmp->vcbAtrb |= kHFSVolumeInconsistentMask;
7698 MarkVCBDirty(hfsmp);
7700 if ((hfsmp->hfs_flags & HFS_READ_ONLY)==0) {
7702 fslog_fs_corrupt(hfsmp->hfs_mp);
7703 printf("hfs: Runtime corruption detected on %s, fsck will be forced on next mount.\n", hfsmp->vcbVN);
7705 HFS_MOUNT_UNLOCK(hfsmp, TRUE);