From c7ca4fb3098c30ac3af51e9d700a3320aca37bec Mon Sep 17 00:00:00 2001 From: Apple Date: Fri, 4 Sep 2015 17:28:27 +0000 Subject: [PATCH] hfs-304.tar.gz --- fs/Info.plist | 12 ++ fsck_hfs/dfalib/SExtents.c | 10 +- fsck_hfs/fsck_hfs.c | 8 +- ...entitlements => fsck_hfs.ios.entitlements} | 0 fsck_hfs/fsck_hfs.osx.entitlements | 8 + fsck_hfs/fsck_hfs_msgnums.h | 2 +- fsck_hfs/fsck_hfs_strings.c | 2 +- hfs.xcodeproj/project.pbxproj | 51 +++--- hfs_japanese/Makefile.postamble | 2 +- ...entitlements => hfs_util.ios.entitlements} | 0 hfs_util/hfs_util.osx.entitlements | 8 + hfs_util/hfsutil_jnl.c | 9 -- hfs_util/hfsutil_main.c | 4 +- mount_hfs/mount_hfs.8 | 3 + mount_hfs/mount_hfs.c | 13 +- ...ntitlements => mount_hfs.ios.entitlements} | 0 mount_hfs/mount_hfs.osx.entitlements | 8 + newfs_hfs/makehfs.c | 50 +++--- newfs_hfs/newfs_hfs.8 | 20 +++ newfs_hfs/newfs_hfs.c | 149 ++++++++++++++++-- newfs_hfs/newfs_hfs.h | 5 +- 21 files changed, 272 insertions(+), 92 deletions(-) rename fsck_hfs/{fsck_hfs.entitlements => fsck_hfs.ios.entitlements} (100%) create mode 100644 fsck_hfs/fsck_hfs.osx.entitlements rename hfs_util/{hfs_util.entitlements => hfs_util.ios.entitlements} (100%) create mode 100644 hfs_util/hfs_util.osx.entitlements rename mount_hfs/{mount_hfs.entitlements => mount_hfs.ios.entitlements} (100%) create mode 100644 mount_hfs/mount_hfs.osx.entitlements diff --git a/fs/Info.plist b/fs/Info.plist index 18bcc30..543f88e 100644 --- a/fs/Info.plist +++ b/fs/Info.plist @@ -74,6 +74,18 @@ FSProbeOrder 1000 + 7C3457EF-0000-11AA-AA11-00306543ECAC + + FSMediaProperties + + Content Hint + 7C3457EF-0000-11AA-AA11-00306543ECAC + Leaf + + + autodiskmount + + Apple_HFS FSMediaProperties diff --git a/fsck_hfs/dfalib/SExtents.c b/fsck_hfs/dfalib/SExtents.c index 8619b28..1297905 100644 --- a/fsck_hfs/dfalib/SExtents.c +++ b/fsck_hfs/dfalib/SExtents.c @@ -679,7 +679,10 @@ OSErr DeallocateFile(SVCB *vcb, CatalogRecord * fileRec) if (fileRec->recordType == kHFSFileRecord) { HFSPlusExtentRecord dataForkExtents; HFSPlusExtentRecord rsrcForkExtents; - + + ClearMemory(&dataForkExtents, sizeof(dataForkExtents)); + ClearMemory(&rsrcForkExtents, sizeof(rsrcForkExtents)); + for (i = 0; i < kHFSExtentDensity; ++i) { dataForkExtents[i].startBlock = (UInt32) (fileRec->hfsFile.dataExtents[i].startBlock); @@ -691,11 +694,6 @@ OSErr DeallocateFile(SVCB *vcb, CatalogRecord * fileRec) rsrcForkExtents[i].blockCount = (UInt32) (fileRec->hfsFile.rsrcExtents[i].blockCount); } - ClearMemory(&dataForkExtents[i].startBlock, - sizeof(HFSPlusExtentRecord) - sizeof(HFSExtentRecord)); - - ClearMemory(&rsrcForkExtents[i].startBlock, - sizeof(HFSPlusExtentRecord) - sizeof(HFSExtentRecord)); errDF = DeallocateFork(vcb, fileRec->hfsFile.fileID, kDataForkType, dataForkExtents, &recordDeleted ); diff --git a/fsck_hfs/fsck_hfs.c b/fsck_hfs/fsck_hfs.c index 35ccbc9..de092f9 100644 --- a/fsck_hfs/fsck_hfs.c +++ b/fsck_hfs/fsck_hfs.c @@ -434,16 +434,20 @@ checkfilesys(char * filesys) if (fs_fd < 0) { plog("ERROR: could not open %s to freeze the volume.\n", mntonname); free(mntonname); - return 0; + return EEXIT; } if (fcntl(fs_fd, F_FREEZE_FS, NULL) != 0) { free(mntonname); plog("ERROR: could not freeze volume (%s)\n", strerror(errno)); - return 0; + return EEXIT; } } else if (stfs_buf.f_flags & MNT_RDONLY) { hotmount = 1; + } else { + /* MNT_RDONLY is not set and this is not a live verification */ + plog("ERROR: volume %s is mounted with write access. Re-run with (-l) to freeze volume.\n", mntonname); + return EEXIT; } } } diff --git a/fsck_hfs/fsck_hfs.entitlements b/fsck_hfs/fsck_hfs.ios.entitlements similarity index 100% rename from fsck_hfs/fsck_hfs.entitlements rename to fsck_hfs/fsck_hfs.ios.entitlements diff --git a/fsck_hfs/fsck_hfs.osx.entitlements b/fsck_hfs/fsck_hfs.osx.entitlements new file mode 100644 index 0000000..0288bfa --- /dev/null +++ b/fsck_hfs/fsck_hfs.osx.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.rootless.install + + + diff --git a/fsck_hfs/fsck_hfs_msgnums.h b/fsck_hfs/fsck_hfs_msgnums.h index ff40ecd..37db4d3 100644 --- a/fsck_hfs/fsck_hfs_msgnums.h +++ b/fsck_hfs/fsck_hfs_msgnums.h @@ -121,7 +121,7 @@ enum { E_FreeBlocks = 553, /* Invalid volume free block count */ E_MDBDamaged = 554, /* Master Directory Block needs minor repair */ E_VolumeHeaderDamaged = 555, /* Volume Header needs minor repair */ - E_VBMDamaged = 556, /* Volume Bit Map needs minor repair */ + E_VBMDamaged = 556, /* Volume Bit Map needs repair */ E_InvalidNodeSize = -557, /* Invalid B-tree node size */ E_LeafCnt = 558, /* Invalid leaf record count */ E_BadValue = 559, /* (It should be %s instead of %s) */ diff --git a/fsck_hfs/fsck_hfs_strings.c b/fsck_hfs/fsck_hfs_strings.c index 23cc2e5..fb2f3b5 100644 --- a/fsck_hfs/fsck_hfs_strings.c +++ b/fsck_hfs/fsck_hfs_strings.c @@ -130,7 +130,7 @@ hfs_errors[] = { { E_FreeBlocks, "Invalid volume free block count", fsckMsgError, fsckLevel1, 0, }, { E_MDBDamaged, "Master Directory Block needs minor repair", fsckMsgError, fsckLevel1, 0, }, { E_VolumeHeaderDamaged, "Volume header needs minor repair", fsckMsgError, fsckLevel1, 0, }, - { E_VBMDamaged, "Volume bitmap needs minor repair for under-allocation", fsckMsgError, fsckLevel1, 0, }, + { E_VBMDamaged, "Volume bitmap needs repair for under-allocation", fsckMsgError, fsckLevel0, 0, }, { E_InvalidNodeSize, "Invalid B-tree node size", fsckMsgError, fsckLevel1, 0, }, { E_LeafCnt, "Invalid leaf record count", fsckMsgError, fsckLevel1, 0, }, { E_BadValue, "(It should be %s instead of %s)", fsckMsgDamageInfo,fsckLevel1, 2, (const int[]){ fsckTypeString, fsckTypeString } }, diff --git a/hfs.xcodeproj/project.pbxproj b/hfs.xcodeproj/project.pbxproj index 17c6702..16da236 100644 --- a/hfs.xcodeproj/project.pbxproj +++ b/hfs.xcodeproj/project.pbxproj @@ -304,10 +304,10 @@ 4D0E89A71534FF48004CD678 /* mount_hfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mount_hfs.c; sourceTree = ""; }; 4D0E89A81534FF48004CD678 /* optical.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = optical.c; sourceTree = ""; }; 4D0E89A91534FF48004CD678 /* optical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = optical.h; sourceTree = ""; }; - 4D6E7827191D3E7E004E3F93 /* fsck_hfs.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = fsck_hfs.entitlements; sourceTree = ""; }; + 4D6E7827191D3E7E004E3F93 /* fsck_hfs.ios.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = fsck_hfs.ios.entitlements; sourceTree = ""; }; 4D6E7828191D3F26004E3F93 /* newfs_hfs.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = newfs_hfs.entitlements; path = newfs_hfs/newfs_hfs.entitlements; sourceTree = SOURCE_ROOT; }; - 4D6E7829191D3F41004E3F93 /* mount_hfs.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = mount_hfs.entitlements; sourceTree = ""; }; - 4D7C8964192141CA002013C9 /* hfs_util.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = hfs_util.entitlements; sourceTree = ""; }; + 4D6E7829191D3F41004E3F93 /* mount_hfs.ios.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = mount_hfs.ios.entitlements; sourceTree = ""; }; + 4D7C8964192141CA002013C9 /* hfs_util.ios.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = hfs_util.ios.entitlements; sourceTree = ""; }; 4D7C8965192141DB002013C9 /* CopyHFSMeta.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = CopyHFSMeta.entitlements; sourceTree = ""; }; 4D7C8966192141ED002013C9 /* fstyp_hfs.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = fstyp_hfs.entitlements; sourceTree = ""; }; 4DE6C7461535012200C11066 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; @@ -386,6 +386,9 @@ 863D03961820761900A4F0C4 /* util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = util.c; sourceTree = ""; }; 86CBF37F183186C300A64A93 /* libhfs_metadata.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libhfs_metadata.a; sourceTree = BUILT_PRODUCTS_DIR; }; 86CBF3851831880F00A64A93 /* iterate_hfs_metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iterate_hfs_metadata.c; path = libhfs_metadata/iterate_hfs_metadata.c; sourceTree = SOURCE_ROOT; }; + 9D7AAC861B44874E0001F573 /* mount_hfs.osx.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = mount_hfs.osx.entitlements; sourceTree = ""; }; + 9D7AAC871B44880B0001F573 /* hfs_util.osx.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = hfs_util.osx.entitlements; sourceTree = ""; }; + 9D9067881B44633C003D2117 /* fsck_hfs.osx.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = fsck_hfs.osx.entitlements; sourceTree = ""; }; C1B6FA0610CC0A0A00778D48 /* hfsutil_jnl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hfsutil_jnl.c; sourceTree = ""; }; C1B6FA0710CC0A0A00778D48 /* hfsutil_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hfsutil_main.c; sourceTree = ""; }; C1B6FA2210CC0AF400778D48 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; @@ -522,7 +525,8 @@ 4D0E89A71534FF48004CD678 /* mount_hfs.c */, 4D0E89A81534FF48004CD678 /* optical.c */, 4D0E89A61534FF48004CD678 /* mount_hfs.8 */, - 4D6E7829191D3F41004E3F93 /* mount_hfs.entitlements */, + 4D6E7829191D3F41004E3F93 /* mount_hfs.ios.entitlements */, + 9D7AAC861B44874E0001F573 /* mount_hfs.osx.entitlements */, ); path = mount_hfs; sourceTree = ""; @@ -563,7 +567,8 @@ 4DFD9418153600060039B6BA /* dfalib */, 4DFD9440153600060039B6BA /* docs */, 4DFD9446153600060039B6BA /* fsck_hfs.8 */, - 4D6E7827191D3E7E004E3F93 /* fsck_hfs.entitlements */, + 4D6E7827191D3E7E004E3F93 /* fsck_hfs.ios.entitlements */, + 9D9067881B44633C003D2117 /* fsck_hfs.osx.entitlements */, ); path = fsck_hfs; sourceTree = ""; @@ -665,7 +670,8 @@ C1B6FA2F10CC0B8A00778D48 /* hfs.util.8 */, C1B6FA0610CC0A0A00778D48 /* hfsutil_jnl.c */, C1B6FA0710CC0A0A00778D48 /* hfsutil_main.c */, - 4D7C8964192141CA002013C9 /* hfs_util.entitlements */, + 4D7C8964192141CA002013C9 /* hfs_util.ios.entitlements */, + 9D7AAC871B44880B0001F573 /* hfs_util.osx.entitlements */, ); path = hfs_util; sourceTree = ""; @@ -859,7 +865,6 @@ 8DD76FAB0486AB0100D96B5E /* Sources */, 8DD76FAD0486AB0100D96B5E /* Frameworks */, 8DD76FAF0486AB0100D96B5E /* Copy man8 */, - 4DFD9541153785060039B6BA /* Create symlink */, ); buildRules = ( ); @@ -1005,23 +1010,6 @@ shellScript = "ln -sfhv ${FS_BUNDLE_BIN_PATH}/fsck_hfs ${DSTROOT}/sbin/fsck_hfs\nchgrp -h wheel ${DSTROOT}/sbin/fsck_hfs\n"; showEnvVarsInLog = 0; }; - 4DFD9541153785060039B6BA /* Create symlink */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - "$(DSTROOT)$(FS_BUNDLE_BIN_PATH)/hfs.util", - ); - name = "Create symlink"; - outputPaths = ( - "$(DSTROOT)$(FS_BUNDLE_PATH)/hfs.util", - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "ln -sfhv ${FS_BUNDLE_BIN_DIR}/hfs.util ${DSTROOT}${FS_BUNDLE_PATH}/hfs.util"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1228,8 +1216,9 @@ 1DEB928708733DD80010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = hfs_util/hfs_util.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; + "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = hfs_util/hfs_util.ios.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = hfs_util/hfs_util.osx.entitlements; + CODE_SIGN_IDENTITY = "-"; INSTALL_PATH = $FS_BUNDLE_BIN_PATH; PRODUCT_NAME = hfs.util; }; @@ -1255,8 +1244,9 @@ 4D0E89A41534FE65004CD678 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = mount_hfs/mount_hfs.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; + "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = mount_hfs/mount_hfs.ios.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = mount_hfs/mount_hfs.osx.entitlements; + CODE_SIGN_IDENTITY = "-"; EXCLUDED_SOURCE_FILE_NAMES = ""; "EXCLUDED_SOURCE_FILE_NAMES[sdk=iphoneos*]" = optical.c; "EXCLUDED_SOURCE_FILE_NAMES[sdk=iphonesimulator*]" = optical.c; @@ -1299,8 +1289,9 @@ 4DFD93FB1535FF510039B6BA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = fsck_hfs/fsck_hfs.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; + "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = fsck_hfs/fsck_hfs.ios.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = fsck_hfs/fsck_hfs.osx.entitlements; + CODE_SIGN_IDENTITY = "-"; GCC_PREPROCESSOR_DEFINITIONS = ( "BSD=1", "CONFIG_HFS_TRIM=1", diff --git a/hfs_japanese/Makefile.postamble b/hfs_japanese/Makefile.postamble index e82b537..12a1655 100644 --- a/hfs_japanese/Makefile.postamble +++ b/hfs_japanese/Makefile.postamble @@ -100,7 +100,7 @@ # SYS_EXTENSIONS_DIR = /System/Library/Extensions -HFS_ENCODINGS_DIR = /System/Library/Filesystems/hfs.fs/Encodings +HFS_ENCODINGS_DIR = /System/Library/Filesystems/hfs.fs/Contents/Resources/Encodings after_install: $(MKDIRS) $(DSTROOT)/$(HFS_ENCODINGS_DIR) diff --git a/hfs_util/hfs_util.entitlements b/hfs_util/hfs_util.ios.entitlements similarity index 100% rename from hfs_util/hfs_util.entitlements rename to hfs_util/hfs_util.ios.entitlements diff --git a/hfs_util/hfs_util.osx.entitlements b/hfs_util/hfs_util.osx.entitlements new file mode 100644 index 0000000..0288bfa --- /dev/null +++ b/hfs_util/hfs_util.osx.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.rootless.install + + + diff --git a/hfs_util/hfsutil_jnl.c b/hfs_util/hfsutil_jnl.c index 663a43f..1f2f8b5 100644 --- a/hfs_util/hfsutil_jnl.c +++ b/hfs_util/hfsutil_jnl.c @@ -414,15 +414,11 @@ DoMakeJournaled(char *volname, int jsize) { } // printf("Embedded offset == 0x%llx\n", embedded_offset); -#if TARGET_OS_EMBEDDED /* * Must use open_dprotected_np to create a class D file. This will * be the same as standard open(2) on systems that do not support content protection */ fd = open_dprotected_np (journal_fname, O_CREAT|O_TRUNC|O_RDWR, PROTECTION_CLASS_D, 0, 000); -#else - fd = open (journal_fname, O_CREAT|O_TRUNC|O_RDWR, 000); -#endif if (fd < 0) { fprintf(stderr, "Can't create journal file on volume %s (%s)\n", volname, strerror(errno)); @@ -511,16 +507,11 @@ retry: jib.offset = (off_t)((unsigned int)jstart_block) * (off_t)((unsigned int)block_size); jib.size = (off_t)((unsigned int)journal_size); -#if TARGET_OS_EMBEDDED /* * Use open_dprotected_np to create JIB as a class D file. This will * behave the same as a standard open(2) on systems that do not support content protection */ fd = open_dprotected_np(jib_fname, O_CREAT|O_TRUNC|O_RDWR, PROTECTION_CLASS_D, 0, 000); -#else - fd = open(jib_fname, O_CREAT|O_TRUNC|O_RDWR, 000); -#endif - if (fd < 0) { fprintf(stderr, "Could not create journal info block file on volume %s (%s)\n", volname, strerror(errno)); diff --git a/hfs_util/hfsutil_main.c b/hfs_util/hfsutil_main.c index bb84345..1118def 100644 --- a/hfs_util/hfsutil_main.c +++ b/hfs_util/hfsutil_main.c @@ -77,7 +77,7 @@ #include -#include +#include #include #define READ_DEFAULT_ENCODING 1 @@ -322,7 +322,7 @@ static struct hfs_mnt_encoding hfs_mnt_encodinglist[] = { }; #define KEXT_LOAD_COMMAND "/sbin/kextload" -#define ENCODING_MODULE_PATH "/System/Library/Filesystems/hfs.fs/Encodings/" +#define ENCODING_MODULE_PATH "/System/Library/Filesystems/hfs.fs/Contents/Resources/Encodings/" static int load_encoding(CFStringEncoding encoding) { diff --git a/mount_hfs/mount_hfs.8 b/mount_hfs/mount_hfs.8 index eaca8df..6a44440 100644 --- a/mount_hfs/mount_hfs.8 +++ b/mount_hfs/mount_hfs.8 @@ -29,6 +29,7 @@ .Op Fl m Ar mask .Op Fl o Ar options .Op Fl j +.Op Fl c .Op Fl w .Op Fl x .Ar special @@ -88,6 +89,8 @@ See the man page for possible options and their meanings. .It Fl j Ignore the journal for this mount. +.It Fl c +Disable group commit for journaling. .It Fl w Mount the HFS wrapper volume. .It Fl x diff --git a/mount_hfs/mount_hfs.c b/mount_hfs/mount_hfs.c index a737aaf..4c531c7 100644 --- a/mount_hfs/mount_hfs.c +++ b/mount_hfs/mount_hfs.c @@ -52,6 +52,11 @@ #include +#if TARGET_OS_EMBEDDED +#include +#include +#endif /* TARGET_OS_EMBEDDED */ + /* Sensible wrappers over the byte-swapping routines */ #include "hfs_endian.h" #if !TARGET_OS_EMBEDDED @@ -132,7 +137,7 @@ typedef struct CreateDateAttrBuf { #define KEXT_LOAD_COMMAND "/sbin/kextload" -#define ENCODING_MODULE_PATH "/System/Library/Filesystems/hfs.fs/Encodings/" +#define ENCODING_MODULE_PATH "/System/Library/Filesystems/hfs.fs/Contents/Resources/Encodings/" #define MXENCDNAMELEN 16 /* Maximun length of encoding name string */ @@ -441,6 +446,7 @@ load_encoding(struct hfs_mnt_encoding *encp) return (0); } + int main(argc, argv) int argc; @@ -634,6 +640,8 @@ main(argc, argv) if (args.hfs_mask == (mode_t)VNOVAL) args.hfs_mask = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); } + + #if DEBUG printf("mount_hfs: calling mount: \n" ); printf("\tdevice = %s\n", dev); @@ -674,9 +682,7 @@ main(argc, argv) } if ((mountStatus = mount(HFS_MOUNT_TYPE, dir, mntflags, &args)) < 0) { -#if DEBUG printf("mount_hfs: error on mount(): error = %d.\n", mountStatus); -#endif err(1, NULL); }; @@ -893,7 +899,6 @@ usage() { (void)fprintf(stderr, "usage: mount_hfs [-xw] [-u user] [-g group] [-m mask] [-e encoding] [-t tbuffer-size] [-j] [-c] [-o options] special-device filesystem-node\n"); - (void)fprintf(stderr, " -j disables journaling; -c disables group-commit for journaling\n"); exit(1); } diff --git a/mount_hfs/mount_hfs.entitlements b/mount_hfs/mount_hfs.ios.entitlements similarity index 100% rename from mount_hfs/mount_hfs.entitlements rename to mount_hfs/mount_hfs.ios.entitlements diff --git a/mount_hfs/mount_hfs.osx.entitlements b/mount_hfs/mount_hfs.osx.entitlements new file mode 100644 index 0000000..0288bfa --- /dev/null +++ b/mount_hfs/mount_hfs.osx.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.rootless.install + + + diff --git a/newfs_hfs/makehfs.c b/newfs_hfs/makehfs.c index 0fdaba9..38fdd77 100644 --- a/newfs_hfs/makehfs.c +++ b/newfs_hfs/makehfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2014 Apple Inc. All rights reserved. + * Copyright (c) 1999-2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -517,7 +517,7 @@ make_hfsplus(const DriveInfo *driveInfo, hfsparams_t *defaults) /*--- WRITE FILE ATTRIBUTES B-TREE TO DISK: */ - if (defaults->attributesClumpSize) { + if (defaults->attributesInitialSize) { btNodeSize = defaults->attributesNodeSize; sectorsPerNode = btNodeSize/kBytesPerSector; @@ -739,8 +739,8 @@ InitVH(hfsparams_t *defaults, UInt64 sectors, HFSPlusVolumeHeader *hp) /* set up extents b-tree file */ hp->extentsFile.clumpSize = defaults->extentsClumpSize; - hp->extentsFile.logicalSize = defaults->extentsClumpSize; - hp->extentsFile.totalBlocks = defaults->extentsClumpSize / blockSize; + hp->extentsFile.logicalSize = defaults->extentsInitialSize; + hp->extentsFile.totalBlocks = defaults->extentsInitialSize / blockSize; if (NEWFS_HFS_DEBUG && defaults->extentsStartBlock) allocateBlock = defaults->extentsStartBlock; else { @@ -755,10 +755,10 @@ InitVH(hfsparams_t *defaults, UInt64 sectors, HFSPlusVolumeHeader *hp) printf ("extentsFile : (%10u, %10u)\n", hp->extentsFile.extents[0].startBlock, hp->extentsFile.totalBlocks); /* set up attributes b-tree file */ - if (defaults->attributesClumpSize) { + if (defaults->attributesInitialSize) { hp->attributesFile.clumpSize = defaults->attributesClumpSize; - hp->attributesFile.logicalSize = defaults->attributesClumpSize; - hp->attributesFile.totalBlocks = defaults->attributesClumpSize / blockSize; + hp->attributesFile.logicalSize = defaults->attributesInitialSize; + hp->attributesFile.totalBlocks = defaults->attributesInitialSize / blockSize; if (NEWFS_HFS_DEBUG && defaults->attributesStartBlock) allocateBlock = defaults->attributesStartBlock; else { @@ -781,8 +781,8 @@ InitVH(hfsparams_t *defaults, UInt64 sectors, HFSPlusVolumeHeader *hp) /* set up catalog b-tree file */ hp->catalogFile.clumpSize = defaults->catalogClumpSize; - hp->catalogFile.logicalSize = defaults->catalogClumpSize; - hp->catalogFile.totalBlocks = defaults->catalogClumpSize / blockSize; + hp->catalogFile.logicalSize = defaults->catalogInitialSize; + hp->catalogFile.totalBlocks = defaults->catalogInitialSize / blockSize; if (NEWFS_HFS_DEBUG && defaults->catalogStartBlock) allocateBlock = defaults->catalogStartBlock; else { @@ -935,10 +935,15 @@ MarkExtentUsed(const DriveInfo *driveInfo, UInt32 blockCount) { size_t bufSize = driveInfo->physSectorSize; - uint8_t buf[bufSize]; + void *buf; uint32_t blocksLeft = blockCount; uint32_t curBlock = startBlock; static const int kBitsPerByte = 8; + int status = -1; + + buf = valloc(bufSize); + if (buf == NULL) + err(1, NULL); /* * We loop through physSectorSize blocks. @@ -982,12 +987,12 @@ MarkExtentUsed(const DriveInfo *driveInfo, if (nbytes < (ssize_t)bufSize) { if (nbytes == -1) err(1, "%s::pread(%d, %p, %zu, %lld)", __FUNCTION__, driveInfo->fd, buf, bufSize, offset); - return -1; + goto exit; } if (AllocateExtent(buf, blockOffset, numBlocks) == -1) { warnx("In-use allocation block in <%u, %u>", blockOffset, numBlocks); - return -1; + goto exit; } nwritten = pwrite(driveInfo->fd, buf, bufSize, offset); /* @@ -996,14 +1001,19 @@ MarkExtentUsed(const DriveInfo *driveInfo, * means a return value of 0 or -1, neither of which I could do anything about. */ if (nwritten != (ssize_t)bufSize) - return -1; + goto exit; // And go get the next set, if needed blocksLeft -= numBlocks; curBlock += numBlocks; } - return 0; + status = 0; + +exit: + free(buf); + + return status; } /* * WriteExtentsFile @@ -1028,7 +1038,7 @@ WriteExtentsFile(const DriveInfo *driveInfo, UInt64 startingSector, SInt16 offset; *mapNodes = 0; - fileSize = dp->extentsClumpSize; + fileSize = dp->extentsInitialSize; nodeSize = dp->extentsNodeSize; bzero(buffer, nodeSize); @@ -1062,7 +1072,7 @@ WriteExtentsFile(const DriveInfo *driveInfo, UInt64 startingSector, bthp->nodeSize = SWAP_BE16 (nodeSize); bthp->totalNodes = SWAP_BE32 (fileSize / nodeSize); bthp->freeNodes = SWAP_BE32 (SWAP_BE32 (bthp->totalNodes) - (numOverflowExtents ? 2 : 1)); /* header */ - bthp->clumpSize = SWAP_BE32 (fileSize); + bthp->clumpSize = SWAP_BE32 (dp->extentsClumpSize); bthp->attributes |= SWAP_BE32 (kBTBigKeysMask); bthp->maxKeyLength = SWAP_BE16 (kHFSPlusExtentKeyMaximumLength); @@ -1174,7 +1184,7 @@ WriteAttributesFile(const DriveInfo *driveInfo, UInt64 startingSector, int set_cp_level = 0; *mapNodes = 0; - fileSize = dp->attributesClumpSize; + fileSize = dp->attributesInitialSize; nodeSize = dp->attributesNodeSize; #ifdef DEBUG_BUILD @@ -1229,7 +1239,7 @@ WriteAttributesFile(const DriveInfo *driveInfo, UInt64 startingSector, /* Take the header into account */ bthp->freeNodes = SWAP_BE32 (SWAP_BE32 (bthp->totalNodes) - 1); } - bthp->clumpSize = SWAP_BE32 (fileSize); + bthp->clumpSize = SWAP_BE32 (dp->attributesClumpSize); bthp->attributes |= SWAP_BE32 (kBTBigKeysMask | kBTVariableIndexKeysMask); bthp->maxKeyLength = SWAP_BE16 (kHFSPlusAttrKeyMaximumLength); @@ -1481,7 +1491,7 @@ WriteCatalogFile(const DriveInfo *driveInfo, UInt64 startingSector, SInt16 offset; *mapNodes = 0; - fileSize = dp->catalogClumpSize; + fileSize = dp->catalogInitialSize; nodeSize = dp->catalogNodeSize; bzero(buffer, nodeSize); @@ -1506,7 +1516,7 @@ WriteCatalogFile(const DriveInfo *driveInfo, UInt64 startingSector, bthp->nodeSize = SWAP_BE16 (nodeSize); bthp->totalNodes = SWAP_BE32 (fileSize / nodeSize); bthp->freeNodes = SWAP_BE32 (SWAP_BE32 (bthp->totalNodes) - 2); /* header and root */ - bthp->clumpSize = SWAP_BE32 (fileSize); + bthp->clumpSize = SWAP_BE32 (dp->catalogClumpSize); bthp->attributes |= SWAP_BE32 (kBTVariableIndexKeysMask + kBTBigKeysMask); diff --git a/newfs_hfs/newfs_hfs.8 b/newfs_hfs/newfs_hfs.8 index 8d4ec83..91f32f8 100644 --- a/newfs_hfs/newfs_hfs.8 +++ b/newfs_hfs/newfs_hfs.8 @@ -137,6 +137,26 @@ Set the resource fork clump size. .It Fl i Ar first-cnid This specifies the initial catalog node ID for user files and directories. The default value is 16. +.It Fl I Ar initial-size-list +This specifies the +.Em initial +size, in allocation +blocks, for the various metadata files. +.Em Initial +sizes are specified with the +.Fl I +option followed by a comma +separated list of the form arg=blocks. +.Pp +Example: -I c=5000,e=500 +.Bl -tag -width Fl +.It Em a=blocks +Set the initial attribute file size. +.It Em c=blocks +Set the initial catalog file size. +.It Em e=blocks +Set the initial extent overflow file size. +.El .It Fl J Ar [journal-size] Creates a journaled HFS+ volume. The default journal size varies, based on the size of the volume. Appending an 'M' to the diff --git a/newfs_hfs/newfs_hfs.c b/newfs_hfs/newfs_hfs.c index bd7b076..466fdc1 100644 --- a/newfs_hfs/newfs_hfs.c +++ b/newfs_hfs/newfs_hfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2014 Apple Inc. All rights reserved. + * Copyright (c) 1999-2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -73,6 +73,7 @@ #define ROUNDUP(x,y) (((x)+(y)-1)/(y)*(y)) static void getnodeopts __P((char* optlist)); +static void getinitialopts __P((char* optlist)); static void getclumpopts __P((char* optlist)); #ifdef DEBUG_BUILD static void getstartopts __P((char *optlist)); @@ -84,6 +85,7 @@ static mode_t a_mask __P((char *)); static int hfs_newfs __P((char *device)); static void validate_hfsplus_block_size __P((UInt64 sectorCount, UInt32 sectorSize)); static void hfsplus_params __P((const DriveInfo* dip, hfsparams_t *defaults)); +static UInt32 initialsizecalc __P((UInt32 initialblocks)); static UInt32 clumpsizecalc __P((UInt32 clumpblocks)); static UInt32 CalcHFSPlusBTreeClumpSize __P((UInt32 blockSize, UInt32 nodeSize, UInt64 sectors, int fileID)); static void usage __P((void)); @@ -105,6 +107,9 @@ int gNoCreate = FALSE; int gUserCatNodeSize = FALSE; int gCaseSensitive = FALSE; int gUserAttrSize = FALSE; +int gUserAttrInitialSize = FALSE; +int gUserCatInitialSize = FALSE; +int gUserExtInitialSize = FALSE; int gContentProtect = FALSE; static UInt32 attrExtCount = 1, blkallocExtCount = 1, catExtCount = 1, extExtCount = 1; @@ -136,6 +141,10 @@ UInt32 catnodesiz = 8192; UInt32 extnodesiz = 4096; UInt32 atrnodesiz = 8192; +UInt32 catinitialblks = 0; +UInt32 extinitialblks = 0; +UInt32 atrinitialblks = 0; + UInt32 catclumpblks = 0; UInt32 extclumpblks = 0; UInt32 atrclumpblks = 0; @@ -204,7 +213,7 @@ main(argc, argv) // No semicolon at end of line deliberately! - static const char *options = "G:J:D:M:N:PU:hsb:c:i:n:v:" + static const char *options = "G:J:D:M:N:PU:hsb:c:i:I:n:v:" #ifdef DEBUG_BUILD "p:a:E:" #endif @@ -307,6 +316,10 @@ main(argc, argv) fatal("%s: starting catalog node id too small (must be > 15)", optarg); break; + case 'I': + getinitialopts(optarg); + break; + case 'n': getnodeopts(optarg); break; @@ -422,6 +435,43 @@ static void getnodeopts(char* optlist) } +static void getinitialopts(char* optlist) +{ + char *strp = optlist; + char *ndarg; + char *p; + UInt32 inblocks; + + while((ndarg = strsep(&strp, ",")) != NULL && *ndarg != '\0') { + + p = strchr(ndarg, '='); + if (p == NULL) + usage(); + + inblocks = atoi(p+1); + + switch (*ndarg) { + case 'a': + atrinitialblks = inblocks; + gUserAttrInitialSize = TRUE; + gUserAttrSize = TRUE; + break; + case 'c': + catinitialblks = inblocks; + gUserCatInitialSize = TRUE; + break; + case 'e': + extinitialblks = inblocks; + gUserExtInitialSize = TRUE; + break; + + default: + usage(); + } + } +} + + static void getclumpopts(char* optlist) { char *strp = optlist; @@ -440,6 +490,9 @@ static void getclumpopts(char* optlist) switch (*ndarg) { case 'a': atrclumpblks = clpblocks; + if (!gUserAttrInitialSize) { + atrinitialblks = atrclumpblks; + } gUserAttrSize = TRUE; break; case 'b': @@ -447,12 +500,18 @@ static void getclumpopts(char* optlist) break; case 'c': catclumpblks = clpblocks; + if (!gUserCatInitialSize) { + catinitialblks = catclumpblks; + } break; case 'd': datclumpblks = clpblocks; break; case 'e': extclumpblks = clpblocks; + if (!gUserExtInitialSize) { + extinitialblks = extclumpblks; + } break; case 'r': rsrclumpblks = clpblocks; @@ -947,6 +1006,7 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) uint32_t totalBlocks; UInt32 minClumpSize; UInt32 clumpSize; + UInt32 initialSize; UInt32 oddBitmapBytes; defaults->flags = 0; @@ -1094,9 +1154,9 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) if (datclumpblks == 0) { if (gBlockSize > DFL_BLKSIZE) - defaults->dataClumpSize = ROUNDUP(kHFSPlusRsrcClumpFactor * DFL_BLKSIZE, gBlockSize); + defaults->dataClumpSize = ROUNDUP(kHFSPlusDataClumpFactor * DFL_BLKSIZE, gBlockSize); else - defaults->dataClumpSize = kHFSPlusRsrcClumpFactor * gBlockSize; + defaults->dataClumpSize = kHFSPlusDataClumpFactor * gBlockSize; } else defaults->dataClumpSize = clumpsizecalc(datclumpblks); @@ -1115,11 +1175,22 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) } else { clumpSize = clumpsizecalc(catclumpblks); - if (clumpSize % catnodesiz != 0) fatal("c=%ld: clump size is not a multiple of node size\n", clumpSize/gBlockSize); } + if (catinitialblks == 0) { + initialSize = CalcHFSPlusBTreeClumpSize(gBlockSize, catnodesiz, sectorCount, kHFSCatalogFileID); + } + else { + initialSize = initialsizecalc(catinitialblks); + if (initialSize % catnodesiz != 0) + fatal("c=%ld: initial size is not a multiple of node size\n", initialSize/gBlockSize); + } + if (initialSize < clumpSize) { + fatal("c=%ld: initial size is less than clump size\n", initialSize/gBlockSize); + } defaults->catalogClumpSize = clumpSize; + defaults->catalogInitialSize = initialSize; defaults->catalogNodeSize = catnodesiz; defaults->catalogExtsCount = catExtCount; defaults->catalogStartBlock = catExtStart; @@ -1135,7 +1206,19 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) if (clumpSize % extnodesiz != 0) fatal("e=%ld: clump size is not a multiple of node size\n", clumpSize/gBlockSize); } + if (extinitialblks == 0) { + initialSize = CalcHFSPlusBTreeClumpSize(gBlockSize, extnodesiz, sectorCount, kHFSExtentsFileID); + } + else { + initialSize = initialsizecalc(extinitialblks); + if (initialSize % extnodesiz != 0) + fatal("e=%ld: initial size is not a multiple of node size\n", initialSize/gBlockSize); + } + if (initialSize < clumpSize) { + fatal("e=%ld: initial size is less than clump size\n", initialSize/gBlockSize); + } defaults->extentsClumpSize = clumpSize; + defaults->extentsInitialSize = initialSize; defaults->extentsNodeSize = extnodesiz; defaults->extentsExtsCount = extExtCount; defaults->extentsStartBlock = extExtStart; @@ -1146,20 +1229,35 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) warnx("Warning: extents overflow extent requested count %u exceeds maximum 8, capping at 8\n", defaults->extentsExtsCount); defaults->extentsExtsCount = 8; } + if (atrclumpblks == 0) { + clumpSize = CalcHFSPlusBTreeClumpSize(gBlockSize, atrnodesiz, sectorCount, kHFSAttributesFileID); + } + else { + clumpSize = clumpsizecalc(atrclumpblks); + if (clumpSize % atrnodesiz != 0) + fatal("a=%ld: clump size is not a multiple of node size\n", clumpSize/gBlockSize); + } + if (atrinitialblks == 0) { if (gUserAttrSize) { - clumpSize = 0; + initialSize = 0; } else { - clumpSize = CalcHFSPlusBTreeClumpSize(gBlockSize, atrnodesiz, sectorCount, kHFSAttributesFileID); + initialSize = CalcHFSPlusBTreeClumpSize(gBlockSize, atrnodesiz, sectorCount, kHFSAttributesFileID); } } else { - clumpSize = clumpsizecalc(atrclumpblks); - if (clumpSize % atrnodesiz != 0) - fatal("a=%ld: clump size is not a multiple of node size\n", clumpSize/gBlockSize); + initialSize = initialsizecalc(atrinitialblks); + if (initialSize % atrnodesiz != 0) + fatal("a=%ld: initial size is not a multiple of node size\n", initialSize/gBlockSize); + } + if (initialSize) { + if (initialSize < clumpSize) { + fatal("a=%ld: initial size is less than clump size\n", initialSize/gBlockSize); + } } defaults->attributesClumpSize = clumpSize; + defaults->attributesInitialSize = initialSize; defaults->attributesNodeSize = atrnodesiz; defaults->attributesExtsCount = attrExtCount; defaults->attributesStartBlock = attrExtStart; @@ -1222,11 +1320,14 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) printf("\tjournal-size: %uk\n", defaults->journalSize/1024); printf("\tfirst free catalog node id: %u\n", defaults->nextFreeFileID); printf("\tcatalog b-tree node size: %u\n", defaults->catalogNodeSize); - printf("\tinitial catalog file size: %u\n", defaults->catalogClumpSize); + printf("\tcatalog clump size: %u\n", defaults->catalogClumpSize); + printf("\tinitial catalog file size: %u\n", defaults->catalogInitialSize); printf("\textents b-tree node size: %u\n", defaults->extentsNodeSize); - printf("\tinitial extents file size: %u\n", defaults->extentsClumpSize); + printf("\textents clump size: %u\n", defaults->extentsClumpSize); + printf("\tinitial extents file size: %u\n", defaults->extentsInitialSize); printf("\tattributes b-tree node size: %u\n", defaults->attributesNodeSize); - printf("\tinitial attributes file size: %u\n", defaults->attributesClumpSize); + printf("\tattributes clump size: %u\n", defaults->attributesClumpSize); + printf("\tinitial attributes file size: %u\n", defaults->attributesInitialSize); printf("\tinitial allocation file size: %u (%u blocks)\n", defaults->allocationClumpSize, defaults->allocationClumpSize / gBlockSize); printf("\tdata fork clump size: %u\n", defaults->dataClumpSize); @@ -1241,6 +1342,20 @@ static void hfsplus_params (const DriveInfo* dip, hfsparams_t *defaults) } +static UInt32 +initialsizecalc(UInt32 initialblocks) +{ + UInt64 initialsize; + + initialsize = (UInt64)initialblocks * (UInt64)gBlockSize; + + if (initialsize & (UInt64)(0xFFFFFFFF00000000ULL)) + fatal("=%ld: too many blocks for initial size!", initialblocks); + + return ((UInt32)initialsize); +} + + static UInt32 clumpsizecalc(UInt32 clumpblocks) { @@ -1425,10 +1540,14 @@ void usage() fprintf(stderr, "\t\te=blocks (extents file)\n"); fprintf(stderr, "\t\tr=blocks (user resource fork)\n"); fprintf(stderr, "\t-i starting catalog node id\n"); - fprintf(stderr, "\t-n b-tree node size list (comma separated)\n"); - fprintf(stderr, "\t\te=size (extents b-tree)\n"); + fprintf(stderr, "\t-I initial size list (comma separated)\n"); + fprintf(stderr, "\t\ta=size (attributes b-tree)\n"); fprintf(stderr, "\t\tc=size (catalog b-tree)\n"); + fprintf(stderr, "\t\te=size (extents b-tree)\n"); + fprintf(stderr, "\t-n b-tree node size list (comma separated)\n"); fprintf(stderr, "\t\ta=size (attributes b-tree)\n"); + fprintf(stderr, "\t\tc=size (catalog b-tree)\n"); + fprintf(stderr, "\t\te=size (extents b-tree)\n"); fprintf(stderr, "\t-v volume name (in ascii or UTF-8)\n"); #ifdef DEBUG_BUILD fprintf(stderr, "\t-E extent count list (comma separated)\n"); diff --git a/newfs_hfs/newfs_hfs.h b/newfs_hfs/newfs_hfs.h index 79d9624..2dc3216 100644 --- a/newfs_hfs/newfs_hfs.h +++ b/newfs_hfs/newfs_hfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2014 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2015 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -218,16 +218,19 @@ struct hfsparams { uint32_t nextFreeFileID; uint32_t catalogClumpSize; + uint32_t catalogInitialSize; uint32_t catalogNodeSize; uint32_t catalogExtsCount; uint32_t catalogStartBlock; uint32_t extentsClumpSize; + uint32_t extentsInitialSize; uint32_t extentsNodeSize; uint32_t extentsExtsCount; uint32_t extentsStartBlock; uint32_t attributesClumpSize; + uint32_t attributesInitialSize; uint32_t attributesNodeSize; uint32_t attributesExtsCount; uint32_t attributesStartBlock; -- 2.45.2