+ Contains: Tool to generate tables for use by FixDecomps (CatalogCheck.c). It takes raw data on combining classes and decomposition changes, massages it into the trie form needed by
+ the function, and emits it on stdout (which should be directed to a file DecompData.h).
+/* this procedure receives progress calls and will allow canceling of procedures - we are using it here to print out the progress of the current operation for DFA and DiskUtility - ESP 1/10/00 */
+ //if ( ((ticks - 10) > GPtr->lastTickCount) || (dfaStage == kAboutToRepairStage) ) // To reduce cursor flicker on fast machines, call through on a timed interval
+ result = SearchBTreeRecord( GPtr->calculatedCatalogFCB, &key, kNoHint,
+ &foundKey, &record, &recSize, &hint);
+
+ if (result) {
+ DPRINT(stderr, "UpdFolderCount: second SearchBTreeRecord failed (thread.parentID = %u, result = %d), just returning without complaint\n", record.hfsPlusThread.parentID, result);
+ return 0;
+ }
+
+ if (record.recordType != kHFSPlusFolderRecord) {
+ DPRINT(stderr, "UpdFolderCount: actual record type (%d) != FolderRecord\n", record.recordType);
+ return IntError(GPtr, R_IntErr);
+ }
+
+#if 0
+ /*
+ * If we've had to make a folder on an HFSX volume, we set the folderCount to what
+ * it should be -- which may not be what it found at a different part of the pass.
+ */
+ if ((UInt32)p->incorrect != record.hfsPlusFolder.folderCount) {
+ if ( (fileID > kHFSBadBlockFileID) && (lastFileID != fileID) ) // Keep us out of reserved file trouble
+ {
+ lastFileID = fileID;
+
+ if ( isHFSPlus )
+ {
+ err = LocateCatalogThread( calculatedVCB, fileID, &threadData, (UInt16*)&recordSize, &hint ); // This call returns nodeName as either Str31 or HFSUniStr255, no need to call PrepareInputName()
+
+ if ( err == noErr ) // Thread is found, just verify actual record exists.
+ if (foundKey.hfsPlus.parentID != record2.hfsPlusFile.fileID) {
+ err = btNotFound;
+ if (fsckGetVerbosity(GPtr->context) >= kDebugLog) {
+ plog ("\t%s: fileID do not match (threadKey=%u fileRecord=%u), parentID=%u\n", __FUNCTION__, foundKey.hfsPlus.parentID, record2.hfsPlusFile.fileID, record.hfsPlusThread.parentID);
+ }
+ }
+ } else { /* plain HFS */
+ /* Check recordType */
+ foundRecType = record2.hfsFile.recordType;
+ if (isDirectory == true) {
+ if (foundRecType != kHFSFolderRecord) {
+ err = btNotFound;
+ if (fsckGetVerbosity(GPtr->context) >= kDebugLog) {
+ if (foundKey.hfs.parentID != record2.hfsFile.fileID) {
+ err = btNotFound;
+ if (fsckGetVerbosity(GPtr->context) >= kDebugLog) {
+ if (recordType == kHFSFolderThreadRecord) {
+ plog ("\t%s: fileID do not match (threadKey=%u fileRecord=%u), parentID=%u\n", __FUNCTION__, foundKey.hfs.parentID, record2.hfsFolder.folderID, record.hfsThread.parentID);
+ } else {
+ plog ("\t%s: fileID do not match (threadKey=%u fileRecord=%u), parentID=%u\n", __FUNCTION__, foundKey.hfs.parentID, record2.hfsFile.fileID, record.hfsThread.parentID);
+ plog ("%s: Not enough disk space to allocate extent for fileID = %d (start=%d, count=%d)\n", __FUNCTION__, extentInfo->fileID, extentInfo->startBlock, extentInfo->blockCount);
+#endif
+ }
+ }
+
+ /* For every extent info, copy the extent into new location and create symlink */
+ DPRINTF (d_error|d_overlap, "%s: No matching extent record found in extents btree for fileID = %d (err=%d)\n", __FUNCTION__, extentInfo->fileID, err);
+ goto out;
+ }
+ } else {
+ /* No more extents exist for this file */
+ DPRINTF (d_error|d_overlap, "%s: No matching extent record found for fileID = %d\n", __FUNCTION__, extentInfo->fileID);
+ goto out;
+ }
+ }
+ }
+ /* Copy disk blocks from old extent to new extent */
+ rbFreeBit = 3, /* free the buffer (save in the hash) */
+ rbFreeMask = 0x000A /* rbFreeMask (rbFreeBit + rbTrashBit) works as rbTrash on < System 7.0 RamCache; on >= System 7.0, rbfreeMask overrides rbTrash */
+};
+
+
+/*
+ * UTFlushCache options
+ */
+enum {
+ fcDefault = 0, /* default value - pass this fcOption to just flush any dirty buffers */
+ /* bits and masks */
+ fcTrashBit = 0, /* (don't pass this as fcOption, use only for testing bit) */
+ fcTrashMask = 0x0001, /* pass this fcOption value to flush and trash cache blocks */
+ fcFreeBit = 1, /* (don't pass this as fcOption, use only for testing bit) */
+ fcFreeMask = 0x0003 /* pass this fcOption to flush and free cache blocks (Note: both fcTrash and fcFree bits are set) */
+};
+
+
+/*
+ * UTCacheReadIP and UTCacheWriteIP cacheOption bits and masks are the ioPosMode
+ * bits and masks in Files.x
+ */
+
+/*
+ * Cache routine internal error codes
+ */
+enum {
+ chNoBuf = 1, /* no free cache buffers (all in use) */
+ chInUse = 2, /* requested block in use */
+ chnotfound = 3, /* requested block not found */
+ chNotInUse = 4 /* block being released was not in use */
+};
+
+
+/*
+ * FCBRec.fcbFlags bits
+ */
+enum {
+ fcbWriteBit = 0, /* Data can be written to this file */
+ fcbWriteMask = 0x01,
+ fcbResourceBit = 1, /* This file is a resource fork */
+ fcbResourceMask = 0x02,
+ fcbWriteLockedBit = 2, /* File has a locked byte range */
+ fcbWriteLockedMask = 0x04,
+ fcbSharedWriteBit = 4, /* File is open for shared write access */
+ fcbSharedWriteMask = 0x10,
+ fcbFileLockedBit = 5, /* File is locked (write-protected) */
+ fcbFileLockedMask = 0x20,
+ fcbOwnClumpBit = 6, /* File has clump size specified in FCB */
+ fcbOwnClumpMask = 0x40,
+ fcbModifiedBit = 7, /* File has changed since it was last flushed */
+ fcbModifiedMask = 0x80
+};
+
+enum {
+ fcbLargeFileBit = 3, /* File may grow beyond 2GB; cache uses file blocks, not bytes */
+ fcbLargeFileMask = 0x08
+};
+
+#define kSectorShift 9 /* log2(kSectorSize); used for bit shifts */
+
+/*
+ Fork Level Access Method Block get options
+*/
+enum {
+ kGetBlock = 0x00000000,
+ kForceReadBlock = 0x00000002,
+ kGetEmptyBlock = 0x00000008,
+ kSkipEndianSwap = 0x00000010
+};
+typedef OptionBits GetBlockOptions;
+
+/*
+ Fork Level Access Method Block release options
+*/
+enum {
+ kReleaseBlock = 0x00000000,
+ kForceWriteBlock = 0x00000001,
+ kMarkBlockDirty = 0x00000002,
+ kTrashBlock = 0x00000004
+};
+typedef OptionBits ReleaseBlockOptions;
+
+struct BlockDescriptor{
+ void *buffer;
+ void *blockHeader;
+ UInt64 blockNum;
+ UInt32 blockSize;
+ Boolean blockReadFromDisk;
+ Boolean fragmented;
+};
+typedef struct BlockDescriptor BlockDescriptor;
+typedef BlockDescriptor *BlockDescPtr;
+
+
+
+struct SFCB;
+
+struct SVCB {
+ UInt16 vcbSignature;
+ UInt16 vcbVersion;
+ UInt32 vcbAttributes;
+ UInt32 vcbLastMountedVersion;
+ UInt32 vcbReserved1;
+ UInt32 vcbCreateDate;
+ UInt32 vcbModifyDate;
+ UInt32 vcbBackupDate;
+ UInt32 vcbCheckedDate;
+ UInt32 vcbFileCount;
+ UInt32 vcbFolderCount;
+ UInt32 vcbBlockSize;
+ UInt32 vcbTotalBlocks;
+ UInt32 vcbFreeBlocks;
+ UInt32 vcbNextAllocation;
+ UInt32 vcbRsrcClumpSize;
+ UInt32 vcbDataClumpSize;
+ UInt32 vcbNextCatalogID;
+ UInt32 vcbWriteCount;
+ UInt64 vcbEncodingsBitmap;
+ UInt8 vcbFinderInfo[32];
+
+ /* MDB-specific fields... */
+ SInt16 vcbNmFls; /* number of files in root folder */
+ SInt16 vcbNmRtDirs; /* number of directories in root folder */
+ UInt16 vcbVBMSt; /* first sector of HFS volume bitmap */
+ UInt16 vcbAlBlSt; /* first allocation block in HFS volume */
+ UInt16 vcbVSeqNum; /* volume backup sequence number */
+ UInt16 vcbReserved2;
+ Str27 vcbVN; /* HFS volume name */
+
+ /* runtime fields... */
+ struct SFCB * vcbAllocationFile;
+ struct SFCB * vcbExtentsFile;
+ struct SFCB * vcbCatalogFile;
+ struct SFCB * vcbAttributesFile;
+ struct SFCB * vcbStartupFile;
+
+ UInt32 vcbEmbeddedOffset; /* Byte offset where HFS+ starts */
+ repairLevelVeryMinorErrors, // Missing Custom Icon, Locked Directory name,..., Errors that don't need fixing from CheckDisk (Installer), Non Volume corruption bugs.
+ repairLevelVolumeRecoverable, // Minor Volume corruption exists
+ repairLevelSomeDataLoss, // Overlapping extents, some data loss but no scavaging will get it back
+ repairLevelWillCauseDataLoss, // Missing leaf nodes, repair will lose nodes without scavaging (proceed at your own risk, check disk with other utils)
+ repairLevelCatalogBtreeRebuild, // Catalog Btree is damaged, repair may lose some data
+The documents uses fsck collectively for any file system check programs like fsck_hfs, fsck_msdos, fsck_ufs, etc. Any GUI client like Disk Utility that displays the output of fsck in GUI or parses the GUI output of fsck is termed as GUI or client.\
+\f1\b0 \cf0 \ulnone This document describes the design of interaction interface between fsck and any GUI client (like Disk Utility or other program). The aims for this change are:\
+1. Provide flexibility in fsck to add/change message strings in the fsck output after the project's UI freeze.\
+ a. Make it possible to hide extra details of disk verify/repair operation from normal user.\
+ b. Provide all details of disk verify/repair\'caoperation for expert users, developers, AppleCare when required.\
+\
+2. Provide a sustainable and extensible interface for communication between fsck and client.\
+ a. Standardize the message format sent from fsck to client.\
+ b. Provide more information like type of operation, name of corruption files in the message being sent from fsck to client. c. Provide flexibility to add a new message type or information from fsck to client easily.\
+If we look closely, requirement (1a) contradicts (1b).\'ca Therefore we propose a multi-level fsck GUI output which will tag every message from fsck with a verbosity level. This is described in more details later with example.\cf2 \
+\cf0 The design aims towards an independent interface between fsck and client which does not require string comparison and provide more information about the type of message being sent from fsck. Due to ease of extensibility, we use XML format. The output generated will be well-formed and valid XML format. If a client wants to display the output of fsck in realtime, it will have to parse the XML output in real time. Note that all fsck will generate this output on a -g option (GUI option).\
+\cf0 fsck will generate an XML output with a standard set of XML tags for achieving a sustainable and extensible communication interface. All fscks will generate similar XML output which the client will be able to parse. If a new message is added to fsck which belongs to existing message type, no change in the client code will be required. If a new message is added to fsck which does not belong to existing message types, a new XML tag will be created and the client will have to change to recognize it. \
+\cf0 Aims (3) and (4) are bonus as (3) is similar to aim (2) and will be achieved if we fix (2). Aim (4) deals more with standardizing multiple fscks (fsck_hfs, fsck_msdos, fsck_ufs, etc). In the process of converting fscks to the new format described in this design document, we will be achieving (4) (except for 4c).\
+\f1\b0\fs24 \cf0 \ulnone All messages sent by fsck to client will have a verbosity level associated with it. The verbosity level allows a client to filter its output; for example, it might choose to only show level 0 messages to a naive user, but log messages of all levels.\cf2 \
+\cf0 \
+Currently there will be two verbosity levels of client output:\
+a. level 0 or default level and \
+b. level 1 or expert level.\
+\
+Verbosity level 0 includes generic status messages such as verify, repair, success and fail. The text of the message displayed in level 0 will be consistent across all volume types. Each message has a unique positive number so that engineering or technical support can identify the message even if it has been localized. The message numbers at level 0 will be consistent across all volume types. Verbosity level 1 provides details about the verify and repair operation including error messages. Every volume format will define the message text and message number displayed in level 1 independent from other volume formats. \
+1. Strings that indicate generic status of verify/repair operation and its final result independent of file system type.\
+2. Strings that display information about how repair operation has changed the user-level view of the file system and its data. \
+3. Strings that make sense to grandma-like users.\
+\
+
+\f0\b Where do level 0 strings exist?
+\f1\b0 \
+All level 0 strings are pre-defined, and all fscks must use these pre-defined strings for all level 0 output. No other strings must be identified as level 0. Any given fsck may output only a subset of the level 0 strings. Similar to level 0 strings, level 0 message numbers are also pre-defined and all fscks must use these pre-defined values.\
+\
+
+\f0\b What are the valid message numbers for level 0 strings?
+\f1\b0 \
+All level 0 strings will have pre-defined values for message numbers. The message numbers in range 1-99 are reserved for level 0 strings. \
+\
+The pre-defined level 0 strings and message numbers will be located in common location and will be localized.\
+\
+
+\f0\b Which are the common strings?
+\f1\b0 \
+ "Checking volume.",\
+\'ca \'ca "Rechecking volume.",\
+\'ca "Repairing volume.",\
+\'ca \'ca "The volume appears to be OK.",\
+\'ca \'ca "The volume was repaired successfully.", \
+\'ca \'ca "The volume could not be verified completely.",\
+ "The volume could not be verified completely and can not be repaired.",\
+ "The volume was found corrupt and can not be repaired.",\
+ "The volume was found corrupt and needs to be repaired.",\
+ "The volume could not be repaired.", \
+
+\f0\b
+\f1\b0 "The volume cannot be repaired when it is in use.",\
+ "The volume cannot be verified when it is in use.",\cf3 \
+ 1. The above messages are classified in different types (described later).\
+ 2. All\'cafsck must print "Repairing volume" in level 0 when it starts the first repair on the disk. \
+ 3. The parameter in the following messages must be a file system object and of type "path" (described later):\
+ "%s may be damaged." \
+ "%s could not be repaired." \
+ 4. The set of pre-defined strings do not have a parameter for volume name in its strings because all file systems do not require a volume to have a volume name. This means that we will have to support two incarnations of every strings - one with volume name and one without volume name. Therefore we choose not to display volume name in level 0 strings. \
+1. All file system specific messages for detailed information about verify/repair operation as well as error messages.\
+\
+Level 1 includes messages like verify, repair, error, debug, etc. The text of message will be chosen by fsck implementation and will be independent across different file system types. Every unique message string displayed in this level will have a unique number associated with it. Every implementation of fsck can choose any unique number independently. Therefore a message number 234 in fsck_hfs might not mean the same message for message number 234 in fsck_msdos. But once a message number is defined, its meaning must not be changed in future versions. The location of level 1 strings and message numbers of every file system is left to individual fsck implementation.\
+\cf0 The strings displayed in level 0 do not support volume name. All fsck must send details about fsck and corresponding file system it is verifying/repairing including volume name to the client. A message number 100 is reserved for this message. This is described in more detail in message type INFORMATION.\
+\f0\b \cf0 What are the valid message numbers for level 1 strings?
+\f1\b0 \
+Numbers 1-99 are reserved for level 0 strings. Message number 100 is reserved for fsck information message (described later). fsck can choose a positive number greater than 100 for level 1 strings.\
+\
+Example: Listed below is an example fsck output. The message string is prefixed by the message number. Note that the numbers displayed are currently representative numbers and may not be same after implementation. Level 1 messages are distinguished from level 0 message with an extra tab on the output line. Note that this is not the literal fsck output and indentation is only to distinguish between different levels. It does not represent the way in which fsck or client should display their output.\cf2 \
+\cf0 fsck will generate an XML output only when called with "-g" option for GUI output.\cf2 \cf0 A message is a set of information like message type, message string, message number, etc which describes state/action of fsck. The XML chosen will be the standard plist ("Property List") uncompressed format. Each message will begin with "<plist version=\\"1.0\\">", and each message will end with "</plist>\\n". Newlines may appear between the two tags.\
+\f1\b0 \cf0 The producer and consumer for XML format must agree on the XML tags (or keys) that they recognize. These keys will be provided as a part of common header file in /usr/local/include/fsck_common.h.\
+\
+\pard\pardeftab720\ql\qnatural
+\cf0 The output consists of a single <plist> element which shall contain a single <dict> (dictionary) element.\'ca Inside that element are one or more <key> elements. Messages always have one key with the name "fsck_type." The messages describing percent progress have a value of "fsck_progress" for the "fsck_type" key. All other types of messages have several keys, including "verbosity", "fsck_msg_number", "fsck_msg_string" and an optional "parameter".\'ca The parameter element has a value component that is an array; each element of the array may be a <string> or <integer>, or a <dict> with a single key-value pair.\
+\f1\b0 \cf0 This key describes the percentage progress of the verify/repair operation.\cf3 \cf0 The value for this key indicates a non-negative integer with a value between 0 and 100.\
+ This key is the only key that must be present in the progress indicator messages (except "type") and must exist only as child of "message". This key must not exist in any other type of messages. \
+\f1\b0 \cf0 This key describes the string that needs to be displayed in the client. Some message strings will require parameter substitutions which is described in detail later. The associated value is a <string> object.\
+\f1\b0 \cf0 This key describes the message number associated with the "msg_string" in the message. This message number is an unique unsigned 32-bit integer for every unique string. Every implementation of fsck can choose any unique number independently. All message numbers sent by fsck will be positive integer. Therefore a message number 234 in fsck_hfs might not mean the same message for message number 234 in fsck_msdos. The associated value is an <integer> object.\
+ This key describes the verbosity level in which the current message must be displayed in the client. This key-value pair must be sent by fsck with an exception of messages for percentage progress indicator. The verbosity level will be described as an <integer> object.\
+\
+
+\f0\b parameters
+\f1\b0 \
+ fsck does not localize strings itself but sends the strings in the same format as they exist in localized files (i.e. without parameters) to the client. This key describes the parameters to substitute instead of "%@" or "%n$@" where 'n' is the parameter number generated in localized strings in the message strings in "msg_string". A message string can have multiple parameters therefore the values are sent in the order they must be replaced. The value associated with this key is an <array>; the elements of the array may be <string> or <integer>, or they may be <dict> objects with a single <key> and a corresponding value of either a <string> or an <integer>.\
+ This key is optional; if present, it may contain no elements.\
+\
+
+\f0\b fstype
+\f1\b0 \
+ This key describes the type of file system being checked by fsck as a UTF-8 string. The value can also specify a sub-type of file system to provide details. For example, fsck_hfs can send the values for this key as "HFS+", "Journaled HFS+", "Case-sensitive Journaled HFS+", etc. Every fsck implementation can choose the text of the string to be displayed.\
+\f1\b0 \cf0 \ulnone The output generated by fsck will be well-formed and valid plist XML format. If a client wants to display the output of fsck in realtime, it will have to parse the XML output in real time. The start tag for each individual message will be "<plist version=\\"1.0\\">"; the end tag will be "</plist>\\n"; there may be zero more newlines between the tags. There will be only one newline between two different messages and the client must not assume any extra newlines (i.e. between </plist> and the next <plist version=\\"1.0\\">).\
+\f1\b0 \cf0 The messages sent from fsck can be classified into eight types. A message can only belong to one message type. The sequence of messages sent by fsck to client is independent of the type of message. Client must not expect any particular order of messages, like a repair message always preceded by a verify message. \
+\
+fsck must classify the messages based on the following guildelines and must send correct message type to the client. For example, fsck must never send any repair message to client if no repairs were ever performed on the disk.\
+\f1\b0 \cf0 \'ca\'ca \'caThis type indicates that fsck is performing a read-only operation to either check or to prepare to check the file system. \'ca\
+\cf0 Some fsck support option "-n" and "-y" to force answers like "no" and "yes" for any intermediate questions asked during verify operation. This message type is independent of these options and must only be sent for message string describing read-only check. \
+ This is an optional message type as fsck implementation can choose to repair a volume directly. This message type can exist in all verbosity levels.\
+\f1\b0 \cf0 This type indicates that fsck is writing to file system to repair a corruption. \
+ This type does not describe messages when fsck is writing to file system for any other reason than repairing the file system. These type of messages are classified as information messages (described later). For example, if the disk has a "last verified date" that is updated even if no problems are found.\'ca Or a journal might be replayed, and no errors are subsequently found.\
+ Some fsck support option "-n" and "-y" to force answers like "no" and "yes" for any intermediate questions asked during repair operation. This message type is independent of these options and must only be sent for message string describing write operation on the file system. All\'cafsck must print "Repairing volume" in verbosity level 0 when it starts the first repair on the disk.\
+ This is an optional message type as repairing a file system is not required always. This message type can exist in all verbosity levels.\
+\cf0 1. verify operation succeeded and found that the volume is clean.\
+ 2. repair operation has repaired the volume successfully.\
+ The last message output by fsck must be of type SUCCESS or FAIL, to indicate whether the verify or repair operation completed successfully.\'ca No other message may be of type SUCCESS or FAIL. This message type must have verbosity level 0.\
+ 1. fsck was told to verify but not repair and has found that the volume is corrupt\
+ 2. verify operation was not completed due to error and fsck cannot determine if the volume is clean or corrupt.\
+ 3. repair operation has failed.\
+ The last message output by fsck must be of type SUCCESS or FAIL, to indicate whether the verify or repair operation completed successfully.\'ca No other message may be of type SUCCESS or FAIL. This message type must have verbosity level 0.\
+ 2. information/result of any fsck operation or any of its intermediate state.\
+ This type includes messages when fsck is writing to file system for any other reason than repairing the file system. For example, if the disk has a "last verified date" that is updated even if no problems are found.\'ca Or a journal might be replayed, and no errors are subsequently found.\
+\f1\b0 All fsck must send an information message with verbosity level 1 and message number 100 to summarize details about fsck verify/repair operation to facilitate debugging. The information sent will be file used for verify/repair, the version number for that file, name of the volume, if available, and the type of file system. There is no specific requirement about the order of occurrence of this message but it must be sent as early as possible in the verify/repair operation i.e. as soon as fsck gets all information that needs to be sent. All fsck must send the following string: \
+\
+ "Using %1$@ (version %2$@) for checking volume %3$@ of type %4$@." \
+where,\
+ the first parameter is the name of binary file used for verify/repair operation, \
+ the second parameter is the source number used to generate the binary (like diskdev_cmds-332.5, msdosfs-90), \
+ the third parameter is the name of the volume, and \
+ the last parameter is the type of file system (like Journaled HFS+, MSDOS (FAT16), etc). \
+\
+ All fsck must use the same message number 100 for this string. If fsck can not obtain one or more information, it should send NULL value (i.e. just start and end tags) for that parameter.\
+\f1\b0 \cf0 \ulnone If the client receives an unknown key, it should ignore it in its current implementations but enhance its XML parser to recognize that key.\cf3 \cf0 \
+\
+If the client receives an unknown message type and the message has "fsck_msg_string", it should display the "fsck_msg_string" (with parameter substitution, if any) in the verbosity level specified with the message.\
+\
+If the clients receives unknown key which is child of "parameters", the client consider it as "string". \
+\f1\b0 \cf0 \ulnone Some fsck might choose not send messages to client in the new XML format described in this document. This can be because of any reason like phasing out an implementation, development of new fsck, etc. An implementation of fsck under such conditions must send messages to the client as UTF-8 strings which client must display in its UI. The client must handle such unsupported fscks gracefully.\
+\f1\b0 \cf0 \ulnone If a client requires additional data from fsck in future which is not accommodated by the existing keys and/or message types, fsck and client can establish a known key and/or message type. The client will have to change to recognize the new key and/or message type. Only relevant fsck implementations will have to change to generate the new key and/or message type.\
+\
+Since fsck is the producer of the XML data, it may add new keys and/or message types. It is the responsibility of fsck to update the common header file, update this design document and inform clients about the changes.\
+\cf0 \ulnone 1. The strings displayed in verbosity level 1 are more information strings about verify/repair operation. These strings are very file-system specific and can include lot of debugging information. We suggest that these strings should not be localized. This will also enable fsck to add strings independent of localization deadlines.\
+ { fsckVolumeOK, "The volume %s appears to be OK.", fsckMsgSuccess, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckRepairSuccessful, "The volume %s was repaired successfully.", fsckMsgSuccess, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckVolumeVerifyIncomplete, "The volume %s could not be verified completely.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckVolumeVerifyIncompleteNoRepair, "The volume %s could not be verified completely and can not be repaired.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckVolumeCorruptNoRepair, "The volume %s was found corrupt and can not be repaired.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckVolumeCorruptNeedsRepair, "The volume %s was found corrupt and needs to be repaired.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckVolumeNotRepaired, "The volume %s could not be repaired.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+
+ /* 111 - 122 */
+ { fsckVolumeNotRepairedInUse, "The volume %s cannot be repaired when it is in use.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckVolumeNotVerifiedInUse, "The volume %s cannot be verified when it is in use.", fsckMsgFail, fsckLevel0, 1, (const int[]) { fsckTypeVolume } },
+ { fsckFileFolderDamage, "File/folder %s may be damaged.", fsckMsgDamageInfo, fsckLevel0, 1, (const int[]) { fsckTypePath } },
+ { fsckFileFolderNotRepaired, "File/folder %s could not be repaired.", fsckMsgDamageInfo, fsckLevel0, 1, (const int[]) { fsckTypePath } },
+ { fsckVolumeNotRepairedTries, "The volume %s could not be repaired after %d attempts.", fsckMsgFail, fsckLevel0, 2, (const int[]) { fsckTypeVolume, fsckTypeInt }},
+ { fsckLostFoundDirectory, "Look for missing items in %s directory.", fsckMsgRepair, fsckLevel0, 1, (const int[]) { fsckTypeDirectory } },
+ { fsckCorruptFilesDirectory, "Look for links to corrupt files in %s directory.", fsckMsgDamageInfo, fsckLevel0, 1, (const int[]) { fsckTypeDirectory }},
+ * Determine the default based on a sliding scale. The maximum number of
+ * allocation blocks is always 4294967295 == (32 bits worth). At 1 bit per
+ * allocation block, that yields 512 MB of bitmap no matter what size we use
+ * for the allocation block.
+ *
+ * The general default policy is to allow the filesystem to grow up to 8x the
+ * current maximum size. So for a 1.5TB filesystem, an 8x multiplier would be
+ * 12TB. That means we can use the default size of 4096 bytes. The boundary begins
+ * at 2TB, since at that point, we can no longer use the default 4096 block size to
+ * extend the filesystem by 8x. For a 16KB block size, the max is 64 TB, but the 8x
+ * multiplier begins at 8 TB. Thereafter, we increase for every power of 2 that
+ * the current filesystem size grows.
+ */
+
+ gBlockSize = DFL_BLKSIZE; /* Prefer the default of 4K */
+
+ int bit_index = get_high_bit (fs_size);
+ bit_index -= GROWTH_BOUNDARY;
+
+ /*
+ * After subtracting the GROWTH_BOUNDARY to index into the array, we'll
+ * use the values in the static array if we have a non-negative index.
+ * That means that if the filesystem is >= 1 TB, then we'll use the index
+ * value. At 2TB, we grow to the 8K block size.
+ */
+ if ((bit_index >= 0) && (bit_index < 22)) {
+ gBlockSize = alloc_blocksize[bit_index];
+ }
+
+ if (bit_index >= 22) {
+ fatal("Error: Disk Device is too big (%llu sectors, %d bytes per sector", sectorCount, sectorSize);
+ }
+ }
+ else {
+ /* Make sure a user-specified block size is reasonable */
+ if ((gBlockSize & (gBlockSize-1)) != 0) {
+ fatal("%s: bad HFS Plus allocation block size (must be a power of two)", optarg);
+ }
+
+ if ((sectorCount / (gBlockSize / sectorSize)) > 0xFFFFFFFF) {
+ fatal("%s: block size is too small for %lld sectors", optarg, gBlockSize, sectorCount);
+ }
+
+ if (gBlockSize < HFSOPTIMALBLKSIZE) {
+ warnx("Warning: %u is a non-optimal block size (4096 would be a better choice)", (unsigned int)gBlockSize);
+ }
+ }
+
+ if (gFSStartBlock) {
+ u_int64_t fs_size = sectorCount * sectorSize;
+ u_int32_t totalBlocks = fs_size/gBlockSize;
+
+ if (gFSStartBlock >= totalBlocks) {
+ warnx("Warning: %u is invalid file system start allocation block number, must be less than total allocation blocks (%u)", (unsigned int)gFSStartBlock, (unsigned int)totalBlocks);
+ warnx("Warning: Resetting file system start block to zero");
+ fprintf(stderr, "\t-a <num>[,list] metadata start allocation block, all btrees and journal will be created starting at this allocation block offset\n");
+ fprintf(stderr, "\t\tlist is as with -E above, plus:\n");