]> git.saurik.com Git - apple/hfs.git/commitdiff
hfs-154.tar.gz mac-os-x-104 mac-os-x-1041 mac-os-x-1042 v154
authorApple <opensource@apple.com>
Tue, 1 Feb 2005 00:20:44 +0000 (00:20 +0000)
committerApple <opensource@apple.com>
Tue, 1 Feb 2005 00:20:44 +0000 (00:20 +0000)
hfs_util/Info.plist
hfs_util/InfoPlist.strings
hfs_util/hfs.util.8
hfs_util/hfsutil_jnl.c
hfs_util/hfsutil_main.c

index 5024f3d37ae8e36c6c0d3ca99acdd23b9574bbc4..cdbc0dac572126c3cb0d6e893bc9b7a40e5678ff 100644 (file)
        <key>CFBundlePackageType</key>
        <string>fs  </string>
        <key>CFBundleShortVersionString</key>
-       <string>1.3.1</string>
+       <string>1.4</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.3.1</string>
+       <string>1.4</string>
        <key>FSMediaTypes</key>
        <dict>
+               <key>48465300-0000-11AA-AA11-00306543ECAC</key>
+               <dict>
+                       <key>FSMediaProperties</key>
+                       <dict>
+                               <key>Content Hint</key>
+                               <string>48465300-0000-11AA-AA11-00306543ECAC</string>
+                               <key>Leaf</key>
+                               <true/>
+                       </dict>
+                       <key>FSProbeArguments</key>
+                       <string>-p</string>
+                       <key>FSProbeExecutable</key>
+                       <string>../../hfs.util</string>
+                       <key>FSProbeOrder</key>
+                       <integer>1000</integer>
+               </dict>
                <key>Apple_HFS</key>
                <dict>
                        <key>FSMediaProperties</key>
                        <key>FSProbeOrder</key>
                        <integer>1000</integer>
                </dict>
-                <key>Apple_HFSX</key>
-                <dict>
-                        <key>FSMediaProperties</key>
-                        <dict>
-                                <key>Content Hint</key>
-                                <string>Apple_HFSX</string>
-                                <key>Leaf</key>
-                                <true/>
-                        </dict>
-                        <key>FSProbeArguments</key>
-                        <string>-p</string>
-                        <key>FSProbeExecutable</key>
-                        <string>../../hfs.util</string>
-                        <key>FSProbeOrder</key>
-                        <integer>1000</integer>
-                </dict>
-               <key>CD</key>
+               <key>Apple_HFSX</key>
+               <dict>
+                       <key>FSMediaProperties</key>
+                       <dict>
+                               <key>Content Hint</key>
+                               <string>Apple_HFSX</string>
+                               <key>Leaf</key>
+                               <true/>
+                       </dict>
+                       <key>FSProbeArguments</key>
+                       <string>-p</string>
+                       <key>FSProbeExecutable</key>
+                       <string>../../hfs.util</string>
+                       <key>FSProbeOrder</key>
+                       <integer>1000</integer>
+               </dict>
+               <key>CD_ROM_Mode_1</key>
                <dict>
                        <key>FSMediaProperties</key>
                        <dict>
@@ -68,7 +84,7 @@
                        <key>FSProbeOrder</key>
                        <integer>2000</integer>
                </dict>
-               <key>Partitionless</key>
+               <key>Whole</key>
                <dict>
                        <key>FSMediaProperties</key>
                        <dict>
                        <string>../../../../../../sbin/mount_hfs</string>
                        <key>FSName</key>
                        <string>Mac OS Standard</string>
+                       <key>FSSubType</key>
+                       <integer>128</integer>
                        <key>FSRepairArguments</key>
                        <string>-y</string>
                        <key>FSRepairExecutable</key>
                        <key>FSVerificationExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                </dict>
+               <key>HFS+</key>
+               <dict>
+                       <key>FSFormatArguments</key>
+                       <string></string>
+                       <key>FSFormatContentMask</key>
+                       <string>Apple_HFS</string>
+                       <key>FSFormatExecutable</key>
+                       <string>../../../../../../sbin/newfs_hfs</string>
+                       <key>FSFormatMinimumSize</key>
+                       <integer>524288</integer>
+                       <key>FSFormatMaximumSize</key>
+                       <integer>9223372034707292160</integer>
+                       <key>FSMountArguments</key>
+                       <string></string>
+                       <key>FSMountExecutable</key>
+                       <string>../../../../../../sbin/mount_hfs</string>
+                       <key>FSName</key>
+                       <string>Mac OS Extended</string>
+                       <key>FSSubType</key>
+                       <integer>0</integer>
+                       <key>FSRepairArguments</key>
+                       <string>-y</string>
+                       <key>FSRepairExecutable</key>
+                       <string>../../../../../../sbin/fsck_hfs</string>
+                       <key>FSVerificationArguments</key>
+                       <string>-fn</string>
+                       <key>FSVerificationExecutable</key>
+                       <string>../../../../../../sbin/fsck_hfs</string>
+               </dict>
                <key>Journaled HFS+</key>
                <dict>
                        <key>FSFormatArguments</key>
                        <key>FSFormatMinimumSize</key>
                        <integer>4194304</integer>
                        <key>FSFormatMaximumSize</key>
-                       <integer>17592186040320</integer>
+                       <integer>9223372034707292160</integer>
                        <key>FSMountArguments</key>
                        <string></string>
                        <key>FSMountExecutable</key>
                        <string>../../../../../../sbin/mount_hfs</string>
                        <key>FSName</key>
                        <string>Mac OS Extended (Journaled)</string>
+                       <key>FSSubType</key>
+                       <integer>1</integer>
                        <key>FSRepairArguments</key>
                        <string>-y</string>
                        <key>FSRepairExecutable</key>
                <key>Case-sensitive HFS+</key>
                <dict>
                        <key>FSFormatArguments</key>
-                       <string>-s -J</string>
+                       <string>-s</string>
                        <key>FSFormatContentMask</key>
                        <string>Apple_HFSX</string>
                        <key>FSFormatExecutable</key>
                        <key>FSFormatMinimumSize</key>
                        <integer>4194304</integer>
                        <key>FSFormatMaximumSize</key>
-                       <integer>17592186040320</integer>
+                       <integer>9223372034707292160</integer>
                        <key>FSMountArguments</key>
                        <string></string>
                        <key>FSMountExecutable</key>
                        <string>../../../../../../sbin/mount_hfs</string>
                        <key>FSName</key>
-                       <string>Mac OS Extended (Case-sensitive/Journaled)</string>
+                       <string>Mac OS Extended (Case-sensitive)</string>
+                       <key>FSSubType</key>
+                       <integer>2</integer>
                        <key>FSRepairArguments</key>
                        <string>-y</string>
                        <key>FSRepairExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
-                       <key>FSServerOnly</key>
-                       <true/>
                        <key>FSVerificationArguments</key>
                        <string>-fn</string>
                        <key>FSVerificationExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                </dict>
-               <key>HFS+</key>
+               <key>Case-sensitive Journaled HFS+</key>
                <dict>
                        <key>FSFormatArguments</key>
-                       <string></string>
+                       <string>-s -J</string>
                        <key>FSFormatContentMask</key>
-                       <string>Apple_HFS</string>
+                       <string>Apple_HFSX</string>
                        <key>FSFormatExecutable</key>
                        <string>../../../../../../sbin/newfs_hfs</string>
                        <key>FSFormatMinimumSize</key>
-                       <integer>524288</integer>
+                       <integer>4194304</integer>
                        <key>FSFormatMaximumSize</key>
-                       <integer>17592186040320</integer>
+                       <integer>9223372034707292160</integer>
                        <key>FSMountArguments</key>
                        <string></string>
                        <key>FSMountExecutable</key>
                        <string>../../../../../../sbin/mount_hfs</string>
                        <key>FSName</key>
-                       <string>Mac OS Extended</string>
+                       <string>Mac OS Extended (Case-sensitive, Journaled)</string>
+                       <key>FSSubType</key>
+                       <integer>3</integer>
                        <key>FSRepairArguments</key>
                        <string>-y</string>
                        <key>FSRepairExecutable</key>
index ccbb86e7f3c113446627d02fa053c669af9597ee..d96c886a9d7b38c99049a2ddb9a9ebf8bc5a2198 100644 (file)
                <key>Case-sensitive HFS+</key>
                <dict>
                        <key>FSName</key>
-                       <string>Mac OS Extended (Case-sensitive/Journaled)</string>
+                       <string>Mac OS Extended (Case-sensitive)</string>
+               </dict>
+               <key>Case-sensitive Journaled HFS+</key>
+               <dict>
+                       <key>FSName</key>
+                       <string>Mac OS Extended (Case-sensitive, Journaled)</string>
                </dict>
        </dict>
 </dict>
index fa39fed86ad5d9131c972e2c1f79074d9433b943..dd6ab4c10ed39ebaef2ad6c34cedea25510400f5 100644 (file)
@@ -57,7 +57,7 @@ The
 command supports the mounting, probing, and unmounting of HFS file systems.
 .Pp
 Options:
-.Bl -tag -width -indent "a"
+.Bl -tag -compact -offset indent
 .It Fl a 
 Adopt permissions for the HFS file system at
 .Ar device
@@ -108,7 +108,7 @@ Disable journaling on the HFS file system mounted on
 The
 .Ar mountflags 
 referenced above are either:
-.Bl -bullet -indent
+.Bl -bullet -compact -offset indent
 .It
 .Ar removable 
 or
index 931fb74a18519b85a1c4ff9d2e6c29a799ce8f91..2a619e87134568ea1e7a751c447e4e71fa4e6f4c 100644 (file)
@@ -37,6 +37,7 @@
 #include <sys/vmmeter.h>
 #include <sys/mount.h>
 #include <sys/wait.h>
+#include <sys/ioctl.h>
 
 #include <sys/disk.h>
 #include <sys/loadable_fs.h>
@@ -120,28 +121,218 @@ int hide_file(const char * file)
     return (result == -1 ? errno : result);
 }
 
-int
-get_start_block(const char *file)
+off_t
+get_start_block(const char *file, uint32_t fs_block_size)
 {
-    struct attrlist alist = {0};
-    ExtentsAttrBuf extentsbuf = {0};
+    off_t cur_pos, phys_start, len;
+    int fd, err;
+    struct log2phys l2p;
+    struct stat st;
 
-    alist.bitmapcount = ATTR_BIT_MAP_COUNT;
-    alist.fileattr = ATTR_FILE_DATAEXTENTS;
+    fd = open(file, O_RDONLY);
+    if (fd < 0) {
+       return -1;
+    }
 
-    if (getattrlist(file, &alist, &extentsbuf, sizeof(extentsbuf), 0)) {
-       fprintf(stderr, "could not get attrlist for %s (%s)", file, strerror(errno));
+    if (fstat(fd, &st) < 0) {
+       fprintf(stderr, "can't stat %s (%s)\n", file, strerror(errno));
+       close(fd);
        return -1;
     }
 
-    if (extentsbuf.extents[1].startBlock != 0) {
-       fprintf(stderr, "Journal File not contiguous!\n");
+    fs_block_size = st.st_blksize; // XXXdbg quick hack for now
+
+    phys_start = len = 0;
+    for(cur_pos=0; cur_pos < st.st_size; cur_pos += fs_block_size) {
+       memset(&l2p, 0, sizeof(l2p));
+       lseek(fd, cur_pos, SEEK_SET);
+       err = fcntl(fd, F_LOG2PHYS, &l2p);
+
+       if (phys_start == 0) {
+           phys_start = l2p.l2p_devoffset;
+           len = fs_block_size;
+       } else if (l2p.l2p_devoffset != (phys_start + len)) {
+           // printf("    %lld : %lld - %lld\n", cur_pos, phys_start / fs_block_size, len / fs_block_size);
+           fprintf(stderr, "%s : is not contiguous!\n", file);
+           close(fd);
+           return -1;
+           // phys_start = l2p.l2p_devoffset;
+           // len = fs_block_size;
+       } else {
+           len += fs_block_size;
+       }
+    }
+
+    close(fd);
+
+    //printf("%s start offset %lld; byte len %lld (blksize %d)\n",
+    // file, phys_start, len, fs_block_size);
+
+    if ((phys_start / (unsigned)fs_block_size) & 0xffffffff00000000LL) {
+       fprintf(stderr, "%s : starting block is > 32bits!\n", file);
        return -1;
     }
+       
+    return phys_start;
+}
+
+
+//
+// Get the embedded offset (if any) for an hfs+ volume.
+// This is pretty skanky that we have to do this but
+// that's life...
+//
+#include <sys/disk.h>
+#include <hfs/hfs_format.h>
+
+#include <machine/endian.h>
+
+#define HFS_PRI_SECTOR(blksize)          (1024 / (blksize))
+#define HFS_PRI_OFFSET(blksize)          ((blksize) > 1024 ? 1024 : 0)
+
+#define SWAP_BE16(x) ntohs(x)
+#define SWAP_BE32(x) ntohl(x)
+
+
+off_t
+get_embedded_offset(char *devname)
+{
+    int fd = -1;
+    off_t ret = 0;
+    char *buff = NULL, rawdev[256];
+    u_int64_t blkcnt;
+    u_int32_t blksize;
+    HFSMasterDirectoryBlock *mdbp;
+    off_t embeddedOffset;
+    struct statfs sfs;
+    struct stat   st;
+       
+  restart:
+    if (stat(devname, &st) != 0) {
+       fprintf(stderr, "Could not access %s (%s)\n", devname, strerror(errno));
+       ret = -1;
+       goto out;
+    }
+
+    if (S_ISCHR(st.st_mode) == 0) {
+       // hmmm, it's not the character special raw device so we
+       // should try to figure out the real device.
+       if (statfs(devname, &sfs) != 0) {
+           fprintf(stderr, "Can't find out any info about the fs for path %s (%s)\n",
+               devname, strerror(errno));
+           ret = -1;
+           goto out;
+       }
+
+       // copy the "/dev/"
+       strncpy(rawdev, sfs.f_mntfromname, 5);
+       rawdev[5] = 'r';
+       strcpy(&rawdev[6], &sfs.f_mntfromname[5]);
+       devname = &rawdev[0];
+       goto restart;
+    }
+
+    fd = open(devname, O_RDONLY);
+    if (fd < 0) {
+       fprintf(stderr, "can't open: %s (%s)\n", devname, strerror(errno));
+       ret = -1;
+       goto out;
+    }
+
+    /* Get the real physical block size. */
+    if (ioctl(fd, DKIOCGETBLOCKSIZE, (caddr_t)&blksize) != 0) {
+       fprintf(stderr, "can't get the device block size (%s). assuming 512\n", strerror(errno));
+       blksize = 512;
+       ret = -1;
+       goto out;
+    }
+
+    /* Get the number of physical blocks. */
+    if (ioctl(fd, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt)) {
+       struct stat st;
+       fprintf(stderr, "failed to get block count. trying stat().\n");
+       if (fstat(fd, &st) != 0) {
+           ret = -1;
+           goto out;
+       }
+
+       blkcnt = st.st_size / blksize;
+    }
+
+    /*
+     * There are only 31 bits worth of block count in
+     * the buffer cache.  So for large volumes a 4K
+     * physical block size is needed.
+     */
+    if (blksize == 512 && blkcnt > (u_int64_t)0x000000007fffffff) {
+       blksize = 4096;
+    }
+
+    /*
+     * At this point:
+     *   blksize has our prefered physical block size
+     *   blkcnt has the total number of physical blocks
+     */
+
+    buff = (char *)malloc(blksize);
+       
+    if (pread(fd, buff, blksize, HFS_PRI_SECTOR(blksize)*blksize) != blksize) {
+       fprintf(stderr, "failed to read volume header @ offset %d (%s)\n",
+           HFS_PRI_SECTOR(blksize), strerror(errno));
+       ret = -1;
+       goto out;
+    }
+
+    mdbp = (HFSMasterDirectoryBlock *)buff;
+    if (   (SWAP_BE16(mdbp->drSigWord) != kHFSSigWord) 
+        && (SWAP_BE16(mdbp->drSigWord) != kHFSPlusSigWord)
+        && (SWAP_BE16(mdbp->drSigWord) != kHFSXSigWord)) {
+       ret = -1;
+       goto out;
+    }
+
+    if ((SWAP_BE16(mdbp->drSigWord) == kHFSSigWord) && (SWAP_BE16(mdbp->drEmbedSigWord) != kHFSPlusSigWord)) {
+       ret = -1;
+       goto out;
+    } else if (SWAP_BE16(mdbp->drEmbedSigWord) == kHFSPlusSigWord) {
+       /* Get the embedded Volume Header */
+       embeddedOffset = SWAP_BE16(mdbp->drAlBlSt) * 512;
+       embeddedOffset += (u_int64_t)SWAP_BE16(mdbp->drEmbedExtent.startBlock) *
+                          (u_int64_t)SWAP_BE32(mdbp->drAlBlkSiz);
+
+       /*
+        * If the embedded volume doesn't start on a block
+        * boundary, then switch the device to a 512-byte
+        * block size so everything will line up on a block
+        * boundary.
+        */
+       if ((embeddedOffset % blksize) != 0) {
+           fprintf(stderr, "HFS Mount: embedded volume offset not"
+               " a multiple of physical block size (%d);"
+               " switching to 512\n", blksize);
+               
+           blkcnt  *= (blksize / 512);
+           blksize  = 512;
+       }
 
-    return extentsbuf.extents[0].startBlock;
+    } else { /* pure HFS+ */ 
+       embeddedOffset = 0;
+    }
+
+    ret = embeddedOffset;
+
+  out:
+    if (buff) {
+       free(buff);
+    }
+    if (fd >= 0) 
+       close(fd);
+
+    return ret;
 }
 
+
+
 static const char *journal_fname = ".journal";
 static const char *jib_fname = ".journal_info_block";
 
@@ -152,10 +343,12 @@ DoMakeJournaled(char *volname, int jsize)
     char            *buf;
     int              ret;
     fstore_t         fst;
-    int              jstart_block, jinfo_block, sysctl_info[8];
+    int32_t          jstart_block, jinfo_block;
+    int              sysctl_info[8];
     JournalInfoBlock jib;
     struct statfs    sfs;
     static char      tmpname[MAXPATHLEN];
+    off_t            start_block, embedded_offset;
 
     if (statfs(volname, &sfs) != 0) {
        fprintf(stderr, "Can't stat volume %s (%s).\n", volname, strerror(errno));
@@ -202,6 +395,15 @@ DoMakeJournaled(char *volname, int jsize)
        return 10;
     }
 
+
+    embedded_offset = get_embedded_offset(volname);
+    if (embedded_offset < 0) {
+       fprintf(stderr, "Can't calculate the embedded offset (if any) for %s.\n", volname);
+       fprintf(stderr, "Journal creation failure.\n");
+       return 15;
+    }
+    // printf("Embedded offset == 0x%llx\n", embedded_offset);
+
     fd = open(journal_fname, O_CREAT|O_TRUNC|O_RDWR, 000);
     if (fd < 0) {
        fprintf(stderr, "Can't create journal file on volume %s (%s)\n",
@@ -270,9 +472,16 @@ DoMakeJournaled(char *volname, int jsize)
     close(fd);
     hide_file(journal_fname);
 
-    jstart_block = get_start_block(journal_fname);
+    start_block = get_start_block(journal_fname, block_size);
+    if (start_block == (off_t)-1) {
+       fprintf(stderr, "Failed to get start block for %s (%s)\n",
+               journal_fname, strerror(errno));
+       unlink(journal_fname);
+       return 20;
+    }
+    jstart_block = (start_block / block_size) - (embedded_offset / block_size);
 
-    memset(&jib, 0, sizeof(jib));
+    memset(&jib, 'Z', sizeof(jib));
     jib.flags  = kJIJournalInFSMask;
     jib.offset = (off_t)((unsigned)jstart_block) * (off_t)((unsigned)block_size);
     jib.size   = (off_t)((unsigned)journal_size);
@@ -308,7 +517,15 @@ DoMakeJournaled(char *volname, int jsize)
     close(fd);
     hide_file(jib_fname);
 
-    jinfo_block = get_start_block(jib_fname);
+    start_block = get_start_block(jib_fname, block_size);
+    if (start_block == (off_t)-1) {
+       fprintf(stderr, "Failed to get start block for %s (%s)\n",
+               jib_fname, strerror(errno));
+       unlink(journal_fname);
+       unlink(jib_fname);
+       return 20;
+    }
+    jinfo_block = (start_block / block_size) - (embedded_offset / block_size);
 
 
     //
index 0ee11c9efe823499845f6f8dae74a6e70d6ea06d..3d899f87564db9faa8bce07eddc463c26715563b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -1866,6 +1866,7 @@ GetCatalogOverflowExtents(int fd, off_t hfsPlusVolumeOffset,
        off_t offset;
        u_int32_t nodeSize;
        u_int32_t leafNode;
+       u_int32_t blockSize;
     BTNodeDescriptor * bTreeNodeDescriptorPtr;
        HFSPlusExtentDescriptor * extents;
        size_t listsize;
@@ -1873,14 +1874,15 @@ GetCatalogOverflowExtents(int fd, off_t hfsPlusVolumeOffset,
        int i;
        int result;
 
+       blockSize = NXSwapBigLongToHost(volHdrPtr->blockSize);
        listsize = *catalogExtCount * sizeof(HFSPlusExtentDescriptor);
        extents = *catalogExtents;
        offset = (off_t)volHdrPtr->extentsFile.extents[0].startBlock *
-                   (off_t)volHdrPtr->blockSize;
+                   (off_t)blockSize;
 
        /* Read the header node of the extents B-Tree */
 
-       result = GetBTreeNodeInfo(fd, hfsPlusVolumeOffset, volHdrPtr->blockSize,
+       result = GetBTreeNodeInfo(fd, hfsPlusVolumeOffset, blockSize,
                        kHFSPlusExtentDensity, volHdrPtr->extentsFile.extents,
                    &nodeSize, &leafNode);
        if (result != FSUR_IO_SUCCESS || leafNode == 0)
@@ -1902,7 +1904,7 @@ GetCatalogOverflowExtents(int fd, off_t hfsPlusVolumeOffset,
 
 again:
        result = ReadFile(fd, bufPtr, offset, nodeSize,
-                                       hfsPlusVolumeOffset, volHdrPtr->blockSize,
+                                       hfsPlusVolumeOffset, blockSize,
                                        kHFSPlusExtentDensity, volHdrPtr->extentsFile.extents);
        if ( result == FSUR_IO_FAIL ) {
 #if TRACE_HFS_UTIL
@@ -1939,7 +1941,7 @@ again:
                /* grow list and copy additional extents */
                listsize += sizeof(HFSPlusExtentRecord);
                extents = (HFSPlusExtentDescriptor *) realloc(extents, listsize);
-               bcopy(p + k->keyLength + sizeof(u_int16_t),
+               bcopy(p + NXSwapBigShortToHost(k->keyLength) + sizeof(u_int16_t),
                        &extents[*catalogExtCount], sizeof(HFSPlusExtentRecord));
 
                *catalogExtCount += kHFSPlusExtentDensity;
@@ -2326,7 +2328,7 @@ void GenerateVolumeUUID(VolumeUUID *newVolumeID) {
        int sysdata;
        char sysctlstring[128];
        size_t datalen;
-       struct loadavg sysloadavg;
+       double sysloadavg[3];
        struct vmtotal sysvmtotal;
        
        do {
@@ -2375,10 +2377,8 @@ void GenerateVolumeUUID(VolumeUUID *newVolumeID) {
                SHA1_Update(&context, sysctlstring, datalen);
 
                /* The system's load average: */
-               mib[0] = CTL_VM;
-               mib[1] = VM_LOADAVG;
                datalen = sizeof(sysloadavg);
-               sysctl(mib, 2, &sysloadavg, &datalen, NULL, 0);
+               getloadavg(sysloadavg, 3);
                SHA1_Update(&context, &sysloadavg, datalen);
 
                /* The system's VM statistics: */