]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_format.h
xnu-2782.40.9.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_format.h
index e34bf9c4af8369434e9a651d80ae55824c3943b1..ba00a272a2f52e8b68bb541ba288e3666b9497a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
 
 #include <sys/types.h>
 #include <sys/appleapiopts.h>
+#include <hfs/hfs_unistr.h>
 
 /*
- * hfs_format.c
+ * hfs_format.h
  *
  * This file describes the on-disk format for HFS and HFS Plus volumes.
  * The HFS Plus volume format is desciibed in detail in Apple Technote 1150.
  *
  * http://developer.apple.com/technotes/tn/tn1150.html
  *
+ * Note: Starting 10.9, definition of struct HFSUniStr255 exists in hfs_unitstr.h
+ *
  */
 
 #ifdef __cplusplus
@@ -46,7 +49,6 @@ extern "C" {
 #endif
 
 /* some on-disk hfs structures have 68K alignment (misaligned) */
-#pragma options align=mac68k
 
 /* Signatures used to differentiate between HFS and HFS Plus volumes */
 enum {
@@ -65,26 +67,54 @@ enum {
 
 #ifdef __APPLE_API_PRIVATE
 /*
- * Mac OS X has a special directory for linked and unlinked files (HFS Plus only).
- * This directory and its contents are never exported from the filesystem under
- * Mac OS X.
+ * Mac OS X has two special directories on HFS+ volumes for hardlinked files
+ * and hardlinked directories as well as for open-unlinked files.
  *
- * To make this folder name sort last,  it has embedded null prefix.
- * (0xC0, 0x80 in UTF-8)
+ * These directories and their contents are not exported from the filesystem
+ * under Mac OS X.
  */
-#define HFSPLUSMETADATAFOLDER  "\xC0\x80\xC0\x80\xC0\x80\xC0\x80HFS+ Private Data"
+#define HFSPLUSMETADATAFOLDER       "\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data"
+#define HFSPLUS_DIR_METADATA_FOLDER ".HFS+ Private Directory Data\xd"
 
 /*
- * Files in the HFS Private Data folder have one of the following prefixes
- * followed by a decimal number (no leading zeros).  For indirect nodes this
- * number is a 32 bit random number.  For unlinked (deleted) files that are
- * still open, the number is the file ID for that file.
+ * Files in the "HFS+ Private Data" folder have one of the following prefixes
+ * followed by a decimal number (no leading zeros) for the file ID.
+ *
+ * Note: Earlier version of Mac OS X used a 32 bit random number for the link
+ * ref number instead of the file id.
  *
  * e.g.  iNode7182000 and temp3296
  */
 #define HFS_INODE_PREFIX       "iNode"
 #define HFS_DELETE_PREFIX      "temp"
 
+/*
+ * Files in the ".HFS+ Private Directory Data" folder have the following 
+ * prefix followed by a decimal number (no leading zeros) for the file ID.
+ *
+ * e.g. dir_555
+ */
+#define HFS_DIRINODE_PREFIX    "dir_"
+
+/*
+ * Hardlink inodes save the head of the link chain in
+ * an extended attribute named FIRST_LINK_XATTR_NAME.
+ * The attribute data is the decimal value in ASCII
+ * of the cnid for the first link in the chain.
+ *
+ * This extended attribute is private (i.e. its not
+ * exported in the getxattr/listxattr POSIX APIs).
+ */
+#define FIRST_LINK_XATTR_NAME  "com.apple.system.hfs.firstlink"
+#define FIRST_LINK_XATTR_REC_SIZE (sizeof(HFSPlusAttrData) - 2 + 12)
+
+/*
+ * The name space ID for generating an HFS volume UUID
+ *
+ * B3E20F39-F292-11D6-97A4-00306543ECAC
+ */
+#define HFS_UUID_NAMESPACE_ID  "\xB3\xE2\x0F\x39\xF2\x92\x11\xD6\x97\xA4\x00\x30\x65\x43\xEC\xAC"
+
 #endif /* __APPLE_API_PRIVATE */
 
 /*
@@ -96,16 +126,14 @@ enum {
 };
 
 
-#ifndef _HFSUNISTR255_DEFINED_
-#define _HFSUNISTR255_DEFINED_
-/* Unicode strings are used for HFS Plus file and folder names */
-struct HFSUniStr255 {
-       u_int16_t       length;         /* number of unicode characters */
-       u_int16_t       unicode[255];   /* unicode characters */
+/*
+ *     File type and creator for symbolic links
+ */
+enum {
+      kSymLinkFileType  = 0x736C6E6B, /* 'slnk' */
+      kSymLinkCreator   = 0x72686170  /* 'rhap' */
 };
-typedef struct HFSUniStr255 HFSUniStr255;
-typedef const HFSUniStr255 *ConstHFSUniStr255Param;
-#endif /* _HFSUNISTR255_DEFINED_ */
+
 
 enum {
        kHFSMaxVolumeNameChars          = 27,
@@ -122,7 +150,7 @@ struct HFSExtentKey {
        u_int8_t        forkType;       /* 0 = data fork, FF = resource fork */
        u_int32_t       fileID;         /* file ID */
        u_int16_t       startBlock;     /* first file allocation block number in this extent */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSExtentKey HFSExtentKey;
 
 /* HFS Plus Extent key */
@@ -132,7 +160,7 @@ struct HFSPlusExtentKey {
        u_int8_t        pad;                    /* make the other fields align on 32-bit boundary */
        u_int32_t       fileID;                 /* file ID */
        u_int32_t       startBlock;             /* first file allocation block number in this extent */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusExtentKey HFSPlusExtentKey;
 
 /* Number of extent descriptors per extent record */
@@ -145,14 +173,14 @@ enum {
 struct HFSExtentDescriptor {
        u_int16_t       startBlock;             /* first allocation block */
        u_int16_t       blockCount;             /* number of allocation blocks */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSExtentDescriptor HFSExtentDescriptor;
 
 /* HFS Plus extent descriptor */
 struct HFSPlusExtentDescriptor {
        u_int32_t       startBlock;             /* first allocation block */
        u_int32_t       blockCount;             /* number of allocation blocks */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusExtentDescriptor HFSPlusExtentDescriptor;
 
 /* HFS extent record */
@@ -172,7 +200,7 @@ struct FndrFileInfo {
            int16_t     h;
        } fdLocation;
        int16_t         opaque;
-};
+} __attribute__((aligned(2), packed));
 typedef struct FndrFileInfo FndrFileInfo;
 
 struct FndrDirInfo {
@@ -188,14 +216,29 @@ struct FndrDirInfo {
            u_int16_t   h;
        } frLocation;
        int16_t         opaque;
-};
+} __attribute__((aligned(2), packed));
 typedef struct FndrDirInfo FndrDirInfo;
 
 struct FndrOpaqueInfo {
        int8_t opaque[16];
-};
+} __attribute__((aligned(2), packed));
 typedef struct FndrOpaqueInfo FndrOpaqueInfo;
 
+struct FndrExtendedDirInfo {
+       u_int32_t document_id;
+       u_int32_t date_added;
+       u_int16_t extended_flags;
+       u_int16_t reserved3;
+       u_int32_t write_gen_counter;
+} __attribute__((aligned(2), packed));
+
+struct FndrExtendedFileInfo {
+       u_int32_t document_id;
+       u_int32_t date_added;
+       u_int16_t extended_flags;
+       u_int16_t reserved2;
+       u_int32_t write_gen_counter;
+} __attribute__((aligned(2), packed));
 
 /* HFS Plus Fork data info - 80 bytes */
 struct HFSPlusForkData {
@@ -203,7 +246,7 @@ struct HFSPlusForkData {
        u_int32_t               clumpSize;      /* fork's clump size in bytes */
        u_int32_t               totalBlocks;    /* total blocks used by this fork */
        HFSPlusExtentRecord     extents;        /* initial set of extents */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusForkData HFSPlusForkData;
 
 
@@ -213,8 +256,8 @@ typedef struct HFSPlusForkData HFSPlusForkData;
  * should preserve, but not change, this information.
  */
 struct HFSPlusBSDInfo {
-       u_int32_t       ownerID;        /* user or group ID of file/folder owner */
-       u_int32_t       groupID;        /* additional user of group ID */
+       u_int32_t       ownerID;        /* user-id of owner or hard link chain previous link */
+       u_int32_t       groupID;        /* group-id of owner or hard link chain next link */
        u_int8_t        adminFlags;     /* super-user changeable flags */
        u_int8_t        ownerFlags;     /* owner changeable flags */
        u_int16_t       fileMode;       /* file type and permission bits */
@@ -223,9 +266,28 @@ struct HFSPlusBSDInfo {
            u_int32_t   linkCount;      /* links that refer to this indirect node */
            u_int32_t   rawDevice;      /* special file device (FBLK and FCHR only) */
        } special;
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusBSDInfo HFSPlusBSDInfo;
 
+/*
+ * Hardlink "links" resolve to an inode
+ * and the actual uid/gid comes from that
+ * inode.
+ *
+ * We repurpose the links's uid/gid fields
+ * for the hardlink link chain. The chain
+ * consists of a doubly linked list of file
+ * ids.
+ */
+#define hl_firstLinkID     reserved1         /* Valid only if HasLinkChain flag is set (indirect nodes only) */
+
+#define hl_prevLinkID      bsdInfo.ownerID   /* Valid only if HasLinkChain flag is set */
+#define hl_nextLinkID      bsdInfo.groupID   /* Valid only if HasLinkChain flag is set */
+
+#define hl_linkReference   bsdInfo.special.iNodeNum
+#define hl_linkCount       bsdInfo.special.linkCount
+
 
 /* Catalog file data structures */
 
@@ -238,6 +300,8 @@ enum {
        kHFSAllocationFileID            = 6,    /* File ID of the allocation file (HFS Plus only) */
        kHFSStartupFileID               = 7,    /* File ID of the startup file (HFS Plus only) */
        kHFSAttributesFileID            = 8,    /* File ID of the attribute file (HFS Plus only) */
+       kHFSAttributeDataFileID         = 13,   /* Used in Mac OS X runtime for extent based attributes */
+                                               /* kHFSAttributeDataFileID is never stored on disk. */
        kHFSRepairCatalogFileID         = 14,   /* Used when rebuilding Catalog B-tree */
        kHFSBogusExtentFileID           = 15,   /* Used for exchanging extents in extents file */
        kHFSFirstUserCatalogNodeID      = 16
@@ -249,7 +313,7 @@ struct HFSCatalogKey {
        u_int8_t        reserved;               /* reserved (set to zero) */
        u_int32_t       parentID;               /* parent folder ID */
        u_int8_t        nodeName[kHFSMaxFileNameChars + 1]; /* catalog node name */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSCatalogKey HFSCatalogKey;
 
 /* HFS Plus catalog key */
@@ -257,7 +321,7 @@ struct HFSPlusCatalogKey {
        u_int16_t               keyLength;      /* key length (in bytes) */
        u_int32_t               parentID;       /* parent folder ID */
        HFSUniStr255            nodeName;       /* catalog node name */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusCatalogKey HFSPlusCatalogKey;
 
 /* Catalog record types */
@@ -288,7 +352,19 @@ enum {
        kHFSHasAttributesMask   = 0x0004,
 
        kHFSHasSecurityBit      = 0x0003,       /* object has security data (ACLs) */
-       kHFSHasSecurityMask     = 0x0008
+       kHFSHasSecurityMask     = 0x0008,
+
+       kHFSHasFolderCountBit   = 0x0004,       /* only for HFSX, folder maintains a separate sub-folder count */
+       kHFSHasFolderCountMask  = 0x0010,       /* (sum of folder records and directory hard links) */
+
+       kHFSHasLinkChainBit     = 0x0005,       /* has hardlink chain (inode or link) */
+       kHFSHasLinkChainMask    = 0x0020,
+
+       kHFSHasChildLinkBit     = 0x0006,       /* folder has a child that's a dir link */
+       kHFSHasChildLinkMask    = 0x0040,
+
+       kHFSHasDateAddedBit = 0x0007,   /* File/Folder has the date-added stored in the finder info. */
+       kHFSHasDateAddedMask = 0x0080 
 };
 
 
@@ -304,14 +380,14 @@ struct HFSCatalogFolder {
        FndrDirInfo             userInfo;               /* Finder information */
        FndrOpaqueInfo          finderInfo;             /* additional Finder information */
        u_int32_t               reserved[4];            /* reserved - initialized as zero */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSCatalogFolder HFSCatalogFolder;
 
 /* HFS Plus catalog folder record - 88 bytes */
 struct HFSPlusCatalogFolder {
        int16_t                 recordType;             /* == kHFSPlusFolderRecord */
        u_int16_t               flags;                  /* file flags */
-       u_int32_t               valence;                /* folder's valence (limited to 2^16 in Mac OS) */
+       u_int32_t               valence;                /* folder's item count */
        u_int32_t               folderID;               /* folder ID */
        u_int32_t               createDate;             /* date and time of creation */
        u_int32_t               contentModDate;         /* date and time of last content modification */
@@ -322,8 +398,8 @@ struct HFSPlusCatalogFolder {
        FndrDirInfo             userInfo;               /* Finder information */
        FndrOpaqueInfo          finderInfo;             /* additional Finder information */
        u_int32_t               textEncoding;           /* hint for name conversions */
-       u_int32_t               attrBlocks;             /* cached count of attribute data blocks */
-};
+       u_int32_t               folderCount;            /* number of enclosed folders, active when HasFolderCount is set */
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder;
 
 /* HFS catalog file record - 102 bytes */
@@ -347,7 +423,7 @@ struct HFSCatalogFile {
        HFSExtentRecord         dataExtents;            /* first data fork extent record */
        HFSExtentRecord         rsrcExtents;            /* first resource fork extent record */
        u_int32_t               reserved;               /* reserved - initialized as zero */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSCatalogFile HFSCatalogFile;
 
 /* HFS Plus catalog file record - 248 bytes */
@@ -365,12 +441,12 @@ struct HFSPlusCatalogFile {
        FndrFileInfo            userInfo;               /* Finder information */
        FndrOpaqueInfo          finderInfo;             /* additional Finder information */
        u_int32_t               textEncoding;           /* hint for name conversions */
-       u_int32_t               attrBlocks;             /* cached count of attribute data blocks */
+       u_int32_t               reserved2;              /* reserved - initialized as zero */
 
-       /* Note: these start on double long (64 bit) boundry */
+       /* Note: these start on double long (64 bit) boundary */
        HFSPlusForkData         dataFork;               /* size and block data for data fork */
        HFSPlusForkData         resourceFork;           /* size and block data for resource fork */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusCatalogFile HFSPlusCatalogFile;
 
 /* HFS catalog thread record - 46 bytes */
@@ -379,7 +455,7 @@ struct HFSCatalogThread {
        int32_t         reserved[2];            /* reserved - initialized as zero */
        u_int32_t       parentID;               /* parent ID for this catalog node */
        u_int8_t        nodeName[kHFSMaxFileNameChars + 1]; /* name of this catalog node */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSCatalogThread HFSCatalogThread;
 
 /* HFS Plus catalog thread record -- 264 bytes */
@@ -388,44 +464,44 @@ struct HFSPlusCatalogThread {
        int16_t         reserved;               /* reserved - initialized as zero */
        u_int32_t       parentID;               /* parent ID for this catalog node */
        HFSUniStr255    nodeName;               /* name of this catalog node (variable length) */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusCatalogThread HFSPlusCatalogThread;
 
 #ifdef __APPLE_API_UNSTABLE
 /*
      These are the types of records in the attribute B-tree.  The values were
      chosen so that they wouldn't conflict with the catalog record types.
-*/
*     These are the types of records in the attribute B-tree.  The values were
*     chosen so that they wouldn't conflict with the catalog record types.
+ */
 enum {
-       kHFSPlusAttrInlineData  = 0x10,    /* if size <  kAttrOverflowSize */
-       kHFSPlusAttrForkData    = 0x20,    /* if size >= kAttrOverflowSize */
-       kHFSPlusAttrExtents     = 0x30     /* overflow extents for large attributes */
+       kHFSPlusAttrInlineData  = 0x10,   /* attributes whose data fits in a b-tree node */
+       kHFSPlusAttrForkData    = 0x20,   /* extent based attributes (data lives in extents) */
+       kHFSPlusAttrExtents     = 0x30    /* overflow extents for large attributes */
 };
 
 
 /*
      HFSPlusAttrForkData
      For larger attributes, whose value is stored in allocation blocks.
      If the attribute has more than 8 extents, there will be additonal
      records (of type HFSPlusAttrExtents) for this attribute.
-*/
*     HFSPlusAttrForkData
*     For larger attributes, whose value is stored in allocation blocks.
*     If the attribute has more than 8 extents, there will be additional
*     records (of type HFSPlusAttrExtents) for this attribute.
+ */
 struct HFSPlusAttrForkData {
        u_int32_t       recordType;             /* == kHFSPlusAttrForkData*/
        u_int32_t       reserved;
        HFSPlusForkData theFork;                /* size and first extents of value*/
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusAttrForkData HFSPlusAttrForkData;
 
 /*
      HFSPlusAttrExtents
      This record contains information about overflow extents for large,
      fragmented attributes.
-*/
*     HFSPlusAttrExtents
*     This record contains information about overflow extents for large,
*     fragmented attributes.
+ */
 struct HFSPlusAttrExtents {
        u_int32_t               recordType;     /* == kHFSPlusAttrExtents*/
        u_int32_t               reserved;
        HFSPlusExtentRecord     extents;        /* additional extents*/
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusAttrExtents HFSPlusAttrExtents;
 
 /*
@@ -439,7 +515,7 @@ struct HFSPlusAttrData {
        u_int32_t    reserved[2];
        u_int32_t    attrSize;     /* size of attribute data in bytes */
        u_int8_t     attrData[2];  /* variable length */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusAttrData HFSPlusAttrData;
 
 
@@ -449,11 +525,11 @@ struct HFSPlusAttrInlineData {
        u_int32_t       reserved;
        u_int32_t       logicalSize;
        u_int8_t        userData[2];
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData;
 
 
-/*     A generic Attribute Record*/
+/* A generic Attribute Record */
 union HFSPlusAttrRecord {
        u_int32_t               recordType;
        HFSPlusAttrInlineData   inlineData;   /* NOT USED */
@@ -469,10 +545,10 @@ struct HFSPlusAttrKey {
        u_int16_t     keyLength;       /* key length (in bytes) */
        u_int16_t     pad;             /* set to zero */
        u_int32_t     fileID;          /* file associated with attribute */
-       u_int32_t     startBlock;      /* first attribue allocation block number for extents */
+       u_int32_t     startBlock;      /* first allocation block number for extents */
        u_int16_t     attrNameLen;     /* number of unicode characters */
        u_int16_t     attrName[kHFSMaxAttrNameLen];   /* attribute name (Unicode) */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusAttrKey HFSPlusAttrKey;
 
 #define kHFSPlusAttrKeyMaximumLength   (sizeof(HFSPlusAttrKey) - sizeof(u_int16_t))
@@ -496,7 +572,7 @@ enum {
 
 /* HFS and HFS Plus volume attribute bits */
 enum {
-                                                       /* Bits 0-6 are reserved (always cleared by MountVol call) */
+       /* Bits 0-6 are reserved (always cleared by MountVol call) */
        kHFSVolumeHardwareLockBit       = 7,            /* volume is locked by hardware */
        kHFSVolumeUnmountedBit          = 8,            /* volume was successfully unmounted */
        kHFSVolumeSparedBlocksBit       = 9,            /* volume has bad blocks spared */
@@ -506,19 +582,35 @@ enum {
        kHFSVolumeJournaledBit = 13,                    /* this volume has a journal on it */
        kHFSVolumeInconsistentBit = 14,                 /* serious inconsistencies detected at runtime */
        kHFSVolumeSoftwareLockBit       = 15,           /* volume is locked by software */
-
-       kHFSVolumeHardwareLockMask      = 1 << kHFSVolumeHardwareLockBit,
-       kHFSVolumeUnmountedMask         = 1 << kHFSVolumeUnmountedBit,
-       kHFSVolumeSparedBlocksMask      = 1 << kHFSVolumeSparedBlocksBit,
-       kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit,
-       kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit,
-       kHFSCatalogNodeIDsReusedMask = 1 << kHFSCatalogNodeIDsReusedBit,
-       kHFSVolumeJournaledMask = 1 << kHFSVolumeJournaledBit,
-       kHFSVolumeInconsistentMask = 1 << kHFSVolumeInconsistentBit,
-       kHFSVolumeSoftwareLockMask      = 1 << kHFSVolumeSoftwareLockBit,
-       kHFSMDBAttributesMask           = 0x8380
+       /*
+        * HFS only has 16 bits of attributes in the MDB, but HFS Plus has 32 bits.
+        * Therefore, bits 16-31 can only be used on HFS Plus.
+        */
+       kHFSUnusedNodeFixBit = 31,                              /* Unused nodes in the Catalog B-tree have been zero-filled.  See Radar #6947811. */
+       kHFSContentProtectionBit = 30,                  /* Volume has per-file content protection */
+
+       /***  Keep these in sync with the bits above ! ****/
+       kHFSVolumeHardwareLockMask              = 0x00000080,
+       kHFSVolumeUnmountedMask                 = 0x00000100,
+       kHFSVolumeSparedBlocksMask              = 0x00000200,
+       kHFSVolumeNoCacheRequiredMask   = 0x00000400,
+       kHFSBootVolumeInconsistentMask  = 0x00000800,
+       kHFSCatalogNodeIDsReusedMask    = 0x00001000,
+       kHFSVolumeJournaledMask                 = 0x00002000,
+       kHFSVolumeInconsistentMask              = 0x00004000,
+       kHFSVolumeSoftwareLockMask              = 0x00008000,
+       
+       /* Bits 16-31 are allocated from high to low */
+
+       kHFSContentProtectionMask               = 0x40000000,
+       kHFSUnusedNodeFixMask                   = 0x80000000,
+       
+       kHFSMDBAttributesMask                   = 0x8380
 };
 
+enum {
+       kHFSUnusedNodesFixDate = 0xc5ef2480             /* March 25, 2009 */
+};
 
 /* HFS Master Directory Block - 162 bytes */
 /* Stored at sector #2 (3rd sector) and second-to-last sector. */
@@ -552,7 +644,7 @@ struct HFSMasterDirectoryBlock {
        HFSExtentRecord         drXTExtRec;     /* extent record for extents overflow file */
        u_int32_t               drCTFlSize;     /* size of catalog file */
        HFSExtentRecord         drCTExtRec;     /* extent record for catalog file */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSMasterDirectoryBlock HFSMasterDirectoryBlock;
 
 
@@ -600,7 +692,7 @@ struct HFSPlusVolumeHeader {
        HFSPlusForkData  catalogFile;           /* catalog B-tree file */
        HFSPlusForkData  attributesFile;        /* extended attributes B-tree file */
        HFSPlusForkData  startupFile;           /* boot file (secondary loader) */
-};
+} __attribute__((aligned(2), packed));
 typedef struct HFSPlusVolumeHeader HFSPlusVolumeHeader;
 
 
@@ -625,7 +717,7 @@ struct BTNodeDescriptor {
        u_int8_t        height;                 /* zero for header, map; child is one more than parent*/
        u_int16_t       numRecords;             /* number of records in this node*/
        u_int16_t       reserved;               /* reserved - initialized as zero */
-};
+} __attribute__((aligned(2), packed));
 typedef struct BTNodeDescriptor BTNodeDescriptor;
 
 /* Constants for BTNodeDescriptor kind */
@@ -653,7 +745,7 @@ struct BTHeaderRec {
        u_int8_t        keyCompareType;         /* Key string Comparison Type */
        u_int32_t       attributes;             /* persistent attributes about the tree */
        u_int32_t       reserved3[16];          /* reserved */
-};
+} __attribute__((aligned(2), packed));
 typedef struct BTHeaderRec BTHeaderRec;
 
 /* Constants for BTHeaderRec attributes */
@@ -670,14 +762,27 @@ enum {
        kHFSBinaryCompare = 0xBC  /* binary compare (case-sensitive) */
 };
 
+#include <uuid/uuid.h>
+
 /* JournalInfoBlock - Structure that describes where our journal lives */
+
+// the original size of the reserved field in the JournalInfoBlock was
+// 32*sizeof(u_int32_t).  To keep the total size of the structure the 
+// same we subtract the size of new fields (currently: ext_jnl_uuid and
+// machine_uuid).  If you add additional fields, place them before the
+// reserved field and subtract their size in this macro.
+//
+#define JIB_RESERVED_SIZE  ((32*sizeof(u_int32_t)) - sizeof(uuid_string_t) - 48)
+
 struct JournalInfoBlock {
        u_int32_t       flags;
        u_int32_t       device_signature[8];  // signature used to locate our device.
        u_int64_t       offset;               // byte offset to the journal on the device
        u_int64_t       size;                 // size in bytes of the journal
-       u_int32_t       reserved[32];
-};
+       uuid_string_t   ext_jnl_uuid;
+       char            machine_serial_num[48];
+       char            reserved[JIB_RESERVED_SIZE];
+} __attribute__((aligned(2), packed));
 typedef struct JournalInfoBlock JournalInfoBlock;
 
 enum {
@@ -686,8 +791,13 @@ enum {
     kJIJournalNeedInitMask      = 0x00000004
 };
 
+//
+// This the content type uuid for "external journal" GPT 
+// partitions.  Each instance of a partition also has a
+// uuid that uniquely identifies that instance.
+//
+#define EXTJNL_CONTENT_TYPE_UUID "4A6F7572-6E61-11AA-AA11-00306543ECAC"
 
-#pragma options align=reset
 
 #ifdef __cplusplus
 }