-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtn1150.html
6803 lines (5630 loc) · 297 KB
/
tn1150.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML>
<!-- Template 03-24-01 -->
<!--Includes revisions to code listings-->
<head>
<meta name="ROBOTS" content="NOINDEX" />
<meta id="book-resource-type" name="book-resource-type" content="Technical Note">
<meta id="book-title" name="book-title" content="HFS Plus Volume Format">
<meta id="book-name" name="book-name" content="DTS_TN1150">
<meta id="book-root" name="book-root" content="./">
<meta id="devcenter" name="devcenter" content="Legacy">
<meta id="devcenter-url" name="devcenter-url" content="http://developer.apple.com/legacy">
<meta id="reflib" name="reflib" content="Retired Documents Library">
<meta id="book-assignments" name="book-assignments" content="{Type/Technical Note}">
<meta scheme="apple_ref" id="identifier" name="identifier" content="//apple_ref/doc/uid/DTS10002989">
<meta id="document-version" name="document-version" content="2.0.0">
<meta id="build" name="build" content="d46365bf75b5960db508d19a06816597">
<meta id="description" name="description" content="TN1150: Describes the physical layout of an HFS Plus volume.">
<meta id="resources-uri" name="resources-uri" content="../../Resources/893/">
<meta id="Generator" name="Generator" content="Gutenberg Static 003a3034">
<meta id="Copyright" name="Copyright" content="Copyright 2014 Apple Inc. All Rights Reserved.">
<link rel="stylesheet" type="text/css" href="../../Resources/893/CSS/screen.css" />
<link rel="stylesheet" type="text/css" href="../../Resources/893/CSS/feedback.css" />
<LINK REL="stylesheet" HREF="../../adcstyle.css" TYPE="text/css">
<LINK REL="stylesheet" HREF="../../style.css" TYPE="text/css">
<title>Technical Note TN1150: HFS Plus Volume Format</title>
<meta name="keywords" content="Mac OS 8 HFS Plus Volume format header B-trees catalog journal">
<meta name="Description" content="Technical Note TN1150: This Technical Note describes the
on-disk format for an HFS Plus volume. It does not describe
any programming interfaces for HFS Plus volumes. Topics include:
HFS Plus Basics, Volume Header (structure and types), B-Trees,
Catalog File, Extents Overflow File, Allocation File, Attributes
File, Startup File, Hard Links, Symbolic Links, Journal,
Unicode Subtleties, HFS Wrapper, and Volume Consistency Checks.">
<meta name="categories" content="Files and System Releases">
<meta name="week-posted" content="Dec 27, 1999 - Jan 7, 2000">
<LINK REL="stylesheet" HREF="../../css/adcstyle.css" TYPE="text/css"><script language="JavaScript" type="text/javascript" src="../../Resources/893/JavaScript/adc.js"></script>
</head>
<BODY BGCOLOR="#FFFFFF" id="StaticPage"><a name="//apple_ref/doc/uid/DTS10002989" title="HFS Plus Volume Format"></a>
<div id="adcHeader" class="hideOnPrint hideInXcodeSC">
<div id='ssi_Header' class="hideInXcodeSC default">
<a id="ssi_LibraryTitle" href='../../navigation/'>Retired Documents Library</a>
<a id="ssi_AppleDeveloperConnection" href='https://developer.apple.com/'>Developer</a>
<div id='ssi_SearchButton' role="button" title="Search">Search</div>
</div>
<form id='ssi_SearchMenu' method='get' action='../../search/' accept-charset='utf-8'>
<label for='adcsearch'>Search Retired Documents Library</label>
<input type='search' id='ssi_SearchField' name='q' accesskey='s' results='5' />
</form>
</div>
<header id="header">
<div id="title" role="banner">
<h1>HFS Plus Volume Format</h1>
<span id="file_links">
<a id="PDF_link" role="button" tabindex='4' rel="alternate" title="Download PDF"><span id="pdf_icon"></span>PDF</a>
<a id="Companion_link" role="button" tabindex='3' title="Download Companion File"><span id="companion_icon"></span>Companion File</a>
</span>
</div>
<ul id="headerButtons" class="hideOnPrint" role="toolbar">
<li id="toc_button" style="display:none">
<button tabindex="5" id="table_of_contents" class="open" role="checkbox" aria-label="Show Table of Contents">
<span class="disclosure"></span>Table of Contents</button>
</li>
<li id="jumpto_button" style="display:none" role="navigation">
<select tabindex="6" id="jumpTo">
<option value="top"><<Jump To…>></option>
</select>
</li>
<li id="downloadSample_button" style="display:none">
<a id="Sample_link"><button id="Sample_button">Download Sample Code</button></a>
</li>
</ul>
</header>
<nav id="tocContainer" class="" tabindex="7">
<ul id="toc" role="tree"></ul>
</nav>
<article id="contents">
<div id="technical">
<a NAME="top"></a>
<!-- begin_header_information --><p><a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../technicalnotes/index.html">Technical Notes</a> > <a href="../../technicalnotes/Carbon/index.html">Carbon</a> > <a href="../../technicalnotes/Carbon/idxFileManagement-date.html">File Management</a> > </p><!-- end_header_information -->
<!-- bottom_of_header_marker_comment -->
<!-- top_of_titles_marker_comment --><CENTER><table width="600" cellpadding="0" cellspacing="0" border="0">
<tr><td align="left" scope="row">
<h1>
<div id="pagehead">Technical Note TN1150</div>
<div id="pageheadsub">HFS Plus Volume Format</div>
</h1>
</td></tr></table></CENTER><!-- bottom_of_titles_marker_comment -->
<CENTER><table BORDER=0 CELLSPACING=1 WIDTH=600><TR><TD>
<!-- begin_header_box -->
<table width="600" cellpadding="0" cellspacing="0" border="0">
<tr>
<td width="300" valign="top" scope="row">
<table border="0" width="300" cellpadding="0" cellspacing="0">
<tr>
<td width="300"> <img src="images/tnmenutop.gif" alt="" align="bottom" width=300 height=7></td>
</tr>
<tr bgcolor="#e6e6e6">
<td background="images/tnmenubody.gif" width="300">
<span id="menutitle">
CONTENTS
<br>
<br>
</span>
</td>
</tr>
<tr bgcolor="#e6e6e6">
<td background="images/tnmenubody.gif" width="300">
<!-- begin_toc -->
<P id = "menutext"><a HREF = "#HFSPlusBasics">HFS Plus Basics</a><BR><BR>
<a HREF = "#CoreConcepts">Core Concepts</a><BR><BR>
<a HREF = "#VolumeHeader">Volume Header</a><BR><BR>
<a HREF = "#BTrees">B-Trees</a><BR><BR>
<a HREF = "#CatalogFile">Catalog File</a><BR><BR>
<a HREF = "#ExtentsOverflowFile">Extents Overflow File</a><BR><BR>
<a HREF = "#AllocationFile">Allocation File</a><BR><BR>
<a HREF = "#AttributesFile">Attributes File</a><BR><BR>
<a HREF = "#StartupFile">Startup File</a><BR><BR>
<a HREF = "#HardLinks">Hard Links</a><BR><BR>
<a HREF = "#Symlinks">Symbolic Links</a><BR><BR>
<a HREF = "#Journal">Journal</a><BR><BR>
<a HREF = "#HFSX">HFSX</a><BR><BR>
<a HREF = "#MetadataZone">Metadata Zone</a><BR><BR>
<a HREF = "#HotFile">Hot Files</a><BR><BR>
<a HREF = "#UnicodeSubtleties">Unicode Subtleties</a><BR><BR>
<a HREF = "#HFSWrapper">HFS Wrapper</a><BR><BR>
<a HREF = "#VolumeConsistencyChecks">Volume Consistency Checks</a><BR><BR>
<a HREF = "#Summary">Summary</a><BR><BR>
<a href="#Downloads">Downloadables</a></p>
<!-- end_toc -->
</td>
</tr>
<tr>
<td width="300" scope="row">
<img src="images/tnmenubottom.gif" alt="" width=300 height=16>
</td>
</tr>
</table>
</td>
<td width="300" valign="top">
<!-- begin_intro_text -->
<P id = "introtext">This Technote
describes the on-disk format for an HFS Plus volume. It does
<B>not</B> describe any programming interfaces for HFS Plus
volumes.</P>
<P id = "introtext">This technote is directed at developers who need to work
with HFS Plus at a very low level, below the abstraction
provided by the File Manager programming interface. This
includes developers of disk recovery utilities and
programmers implementing HFS Plus support on other
platforms.</P>
<P id = "introtext">This technote assumes that you have a conceptual
understanding of the HFS volume format, as described in
<a href="http://developer.apple.com/techpubs/mac/Files/Files-99.html#HEADING99-0">Inside
Macintosh: Files</a>.</p>
<!-- end_intro_text -->
<!-- begin_date --><H4 ALIGN=center>[Mar 05, 2004]</H4><!-- end_date -->
</TD>
</TR>
</table>
<!-- end_header_box -->
<BR><BR>
<hr width=500 align=center>
<BR><BR>
<!-- begin_content -->
<H2><a NAME="HFSPlusBasics"></a>HFS Plus Basics</H2>
<P>HFS Plus is a volume format for Mac OS. HFS
Plus was introduced with <a HREF =
"http://developer.apple.com/technotes/tn/tn1121.html#HFS%20Plus">Mac
OS 8.1</a>. HFS Plus is architecturally very similar to
HFS, although there have been a number of changes. The
following table summarizes the important differences.</P>
<P ALIGN=CENTER><B>Table 1</B> HFS and HFS Plus Compared
</P>
<CENTER><table BORDER=1>
<TR>
<TD>
<P><B>Feature</B></p>
</TD><TD>
<P><B>HFS</B></p>
</TD><TD>
<P><B>HFS Plus</B></p>
</TD><TD>
<P><B>Benefit/Comment</B></p>
</TD></TR>
<TR>
<TD>
<P>User visible name</p>
</TD><TD>
<P>Mac OS Standard</p>
</TD><TD>
<P>Mac OS Extended</p>
</TD><TD>
<P></p>
</TD></TR>
<TR>
<TD>
<P>Number of allocation blocks</p>
</TD><TD>
<P>16 bits worth</p>
</TD><TD>
<P>32 bits worth</p>
</TD><TD>
<P>Radical decrease in disk space used on large
volumes, and a larger number of files per volume.</p>
</TD></TR>
<TR>
<TD>
<P>Long file names</p>
</TD><TD>
<P>31 characters</p>
</TD><TD>
<P>255 characters</p>
</TD><TD>
<P>Obvious user benefit; also improves
cross-platform compatibility</p>
</TD></TR>
<TR>
<TD>
<P>File name encoding</p>
</TD><TD>
<P>MacRoman</p>
</TD><TD>
<P>Unicode</p>
</TD><TD>
<P>Allows for international-friendly file names,
including mixed script names</p>
</TD></TR>
<TR>
<TD>
<P>File/folder attributes</p>
</TD><TD>
<P>Support for fixed size attributes (FileInfo and
ExtendedFileInfo)</p>
</TD><TD>
<P>Allows for future meta-data extensions</p>
</TD><TD>
<P>Future systems may use metadata for a richer
Finder experience</p>
</TD></TR>
<TR>
<TD>
<P>OS startup support</p>
</TD><TD>
<P>System Folder ID</p>
</TD><TD>
<P>Also supports a dedicated startup file</p>
</TD><TD>
<P>May help non-Mac OS systems to boot from HFS
Plus volumes</p>
</TD></TR>
<TR>
<TD>
<P>catalog node size</p>
</TD><TD>
<P>512 bytes</p>
</TD><TD>
<P>4 KB</p>
</TD><TD>
<P>Maintains efficiency in the face of the other
changes. (This larger catalog node size is due to
the much longer file names [512 bytes as opposed to
32 bytes], and larger catalog records (because of
more/larger fields)).</p>
</TD></TR>
<TR>
<TD>
<P>Maximum file size</p>
</TD><TD>
<P>2<SUP>31</SUP> bytes</p>
</TD><TD>
<P>2<SUP>63</SUP> bytes</p>
</TD><TD>
<P>Obvious user benefit, especially for multimedia
content creators.</p></td>
</tr></table></CENTER>
<P>The extent to which these HFS Plus features are available
through a programming interface is OS dependent. Mac OS versions
less than 9.0 do not provide programming interfaces for any
HFS Plus-specific features.</P>
<P>To summarize, the key goals that guided the design of the
HFS Plus volume format were:</P>
<UL>
<li>efficient use of disk space,</li>
<li>international-friendly file names,</li>
<li>future support for named forks, and</li>
<li>ease booting on non-Mac OS operating systems.</li>
</UL>
<P>The following sections describes these goals, and the
differences between HFS and HFS Plus required to meet these
goals.</P>
<H3>Efficient Use of Disk Space</H3>
<P>HFS divides the total space on a volume into equal-sized
pieces called allocation blocks. It uses 16-bit fields to
identify a particular allocation block, so there must be
less than 2<SUP>16</SUP> (65,536) allocation blocks on an
HFS volume. The size of an allocation block is typically the
smallest multiple of 512 such that there are less than
65,536 allocation blocks on the volume (i.e., the volume
size divided by 65,535, rounded up to a multiple of 512).
Any non-empty fork must occupy an integral number of
allocation blocks. This means that the amount of space
occupied by a fork is rounded up to a multiple of the
allocation block size. As volumes (and therefore allocation
blocks) get bigger, the amount of allocated but unused space
increases.</P>
<P>HFS Plus uses 32-bit values to identify allocation
blocks. This allows up to 2 <SUP>32</SUP> (4,294,967,296)
allocation blocks on a volume. More allocation blocks means
a smaller allocation block size, especially on volumes of 1
GB or larger, which in turn means less average wasted space
(the fraction of an allocation block at the end of a fork,
where the entire allocation block is not actually used). It
also means you can have more files, since the available
space can be more finely distributed among a larger number
of files. This change is especially beneficial if the volume
contains a large number of small files.</P>
<H3>International-Friendly File Names</H3>
<P>HFS uses 31-byte strings to store file names. HFS does
not store any kind of script information with the file name
to indicate how it should be interpreted. File names are
compared and sorted using a routine that assumes a Roman
script, wreaking havoc for names that use some other script
(such as Japanese). Worse, this algorithm is buggy, even for
Roman scripts. The Finder and other applications interpret
the file name based on the script system in use at runtime.
</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>Note:</B><BR>
The problem with using non-Roman scripts in an HFS
file name is that HFS compares file names in a case-
insensitive fashion. The case-insensitive
comparison algorithm assume a MacRoman encoding.
When presented with non-Roman text, this algorithm
fails in strange ways. The upshot is that HFS
decides that certain non-Roman file names are
duplicates of other file names, even though they
are not duplicates in the source encoding.</p>
</TD></TR></table></CENTER>
<P>HFS Plus uses up to 255 Unicode characters to store file
names. Allowing up to 255 characters makes it easier to have
very descriptive names. Long names are especially useful
when the name is computer-generated (such as Java class
names).</P>
<P>The HFS catalog B-tree uses 512-byte nodes. An HFS Plus
file name can occupy up to 512 bytes (including the length
field). Since a B-tree index node must store at least two
keys (plus pointers and node descriptor), the HFS Plus
catalog must use a larger node size. The typical node size
for an HFS Plus catalog B-tree is 4 KB.</P>
<P>In the HFS catalog B-tree, the keys stored in an index
node always occupy a fixed amount of space, the maximum key
size. In HFS Plus, the keys in an index node may occupy a
variable amount of space determined by the actual size of
the key. This allows for less wasted space in index nodes
and creates, on typical disks, a substantially larger
branching factor in the tree (requiring fewer node accesses
to find any given record).</P>
<H3>Future Support for Named Forks</H3>
<P>Files on an HFS volume have two forks: a data fork and a
resource fork, either of which may be empty (zero length).
Files and directories also contain a small amount of
additional information (known as catalog information or
metadata) such as the modification date or Finder info.</P>
<P>Apple software teams and third-party developers often
need to store information associated with particular files
and directories. In some cases (for example, custom icons for
files), the data or resource fork is appropriate. But in
other cases (for example, custom icons for directories, or File
Sharing access privileges), using the data or resource fork
is not appropriate or not possible.</P>
<P>A number of products have implemented special-purpose
solutions for storing their file- and directory-related
data. But because these are not managed by the file system,
they can become inconsistent with the file and directory
structure.</P>
<P>HFS Plus has an attribute file, another B-tree, that can
be used to store additional information for a file or
directory. Since it is part of the volume format, this
information can be kept with the file or directory as is it
moved or renamed, and can be deleted when the file or
directory is deleted. The contents of the attribute file's
records have not been fully defined yet, but the goal is to
provide an arbitrary number of forks, identified by Unicode
names, for any file or directory.</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>Note:</B><BR>
Because the attributes file has not been fully
defined yet, current implementations are unable to
delete named forks when a file or directory is
deleted. Future implementations that properly
delete named forks will need to check for these
orphaned named forks and delete them when the
volume is mounted. The
<CODE>lastMountedVersion</CODE> field of the volume
header can be used to detect when such a check
needs to take place.</P>
<P>Whenever possible, an application should delete
named forks rather than orphan them.</p>
</TD></TR></table></CENTER>
<H3>Easy Startup of Alternative Operating Systems</H3>
<P>HFS Plus defines a special <STRONG>startup file</STRONG>,
an unstructured fork that can be found easily during system
startup. The location and size of the startup file is
described in the <a HREF = "#VolumeHeader">volume header</a>.
The startup file is especially useful on systems that don't
have HFS or HFS Plus support in ROM. In many respects, the
startup file is a generalization of the HFS boot blocks, one
that provides a much larger, variable-sized amount of
storage.</P>
<P><a HREF = "#top">Back to top</a></p>
<H2><a NAME="CoreConcepts"></a>Core Concepts</H2>
<P>HFS Plus uses a number of interrelated structures to
manage the organization of data on the volume. These
structures include:</P>
<UL>
<li>the <a HREF = "#VolumeHeader">volume header</a></li>
<li>the <a HREF = "#CatalogFile">catalog file</a></li>
<li>the <a HREF = "#ExtentsOverflowFile">extents overflow
file</a></li>
<li>the <a HREF = "#AttributesFile">attributes file</a></li>
<li>the <a HREF = "#AllocationFile">allocation file</a>
(bitmap)</li>
<li>the <a HREF = "#StartupFile">startup file</a></li>
</UL>
<P>Each of these complex structures is described in its own
section. The purpose of this section is to give an overview
of the volume format, describe how the structures fit
together, and define the primitive data types used by HFS
Plus.</P>
<H3>Terminology</H3>
<P>HFS Plus is a specification of how a <B>volume</B> (files
that contain user data, along with the structure to retrieve
that data) exists on a <B>disk</B> (the medium on which user
data is stored). The storage space on a disk is divided into
units called <B>sectors</B>. A sector is the smallest
part of a disk that the disk's driver software will read or write
in a single operation (without having to read or write additional
data before or after the requested data). The size of a sector is
usually based on the way the data is physically laid out on the disk.
For hard disks, sectors are typically 512 bytes. For optical media,
sectors are typically 2048 bytes.</P>
<P>Most of the data structures on an HFS Plus volume do not
depend on the size of a sector, with the exception of the
<a href="#Journal">journal</a>. Because the journal does rely
on accessing individual sectors, the sector size is stored
in the <code>jhdr_size</code> field of the
<a href="#JournalHeader">journal header</a> (if the
volume has a journal).</P>
<P>HFS Plus allocates space in units called <B>allocation
blocks</B>; an allocation block is simply a group of
consecutive bytes. The size (in bytes) of an allocation
block is a power of two, greater than or equal to 512, which
is set when the volume is initialized. This value cannot be
easily changed without reinitializing the volume. Allocation
blocks are identified by a 32-bit <B>allocation block
number</B>, so there can be at most 2<SUP>32</SUP>
allocation blocks on a volume. Current implementations of the
file system are optimized for 4K allocation blocks.</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>Note:</B><BR>
For the best performance, the allocation block size should
be a multiple of the sector size. If the
volume has an <a HREF = "#HFSWrapper">HFS wrapper</a>, the
wrapper's allocation block size and allocation block start
should also be multiples of the sector size to
allow the best performance.</p>
</TD></TR></table></CENTER>
<P>All of the volume's structures, including the volume
header, are part of one or more allocation blocks (with the possible
exception of the alternate volume header, discussed
<a HREF = "#OddSizeVolumes">below</a>). This differs from HFS,
which has several structures (including the boot blocks, master
directory block, and bitmap) which are not part of any
allocation block.</P>
<P><a NAME="Clump"></a>To promote file contiguity and avoid
fragmentation, disk space is typically allocated to files in
groups of allocation blocks, or <B>clumps</B>. The clump size
is always a multiple of the allocation block size. The default
clump size is specified in the volume header.</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>IMPORTANT:</B><BR>
The actual algorithm used to extend files is not part
of this specification. The implementation is not
required to act on the clump values in the volume
header; it merely provides space to store those
values.</p>
</TD></TR></table></CENTER>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>Note:</B><BR>
The current non-contiguous algorithm in Mac OS will
begin allocating at the next free block it finds.
It will extend its allocation up to a multiple of
the clump size if there is sufficient free space
contiguous with the end of the requested
allocation. Space is not allocated in contiguous
clump-sized pieces.</p>
</TD></TR></table></CENTER>
<P>Every HFS Plus volume must have a <B>volume header</B>.
The volume header contains sundry information about the
volume, such as the date and time of the volume's creation
and the number of files on the volume, as well as the
location of the other key structures on the volume. The
volume header is always located at 1024 bytes from the
start of the volume.</P>
<P>A copy of the volume header, known as the <B>alternate
volume header</B>, is stored starting at 1024 bytes before
the end of the volume. The first 1024 bytes of volume
(before the volume header), and the last 512 bytes of the
volume (after the alternate volume header) are
<a href="#ReservedAndPadFields">reserved</a>.
All of the allocation blocks containing the volume header,
alternate volume header, or the reserved areas before the
volume header or after the alternate volume header, are marked
as used in the <a href="#AllocationFile">allocation file</a>.
The actual number of allocation blocks marked this way depends
on the allocation block size.</P>
<P>An HFS Plus volume contains five <B>special files</B>,
which store the file system structures required to access
the file system payload: folders, <B>user files</B>, and
attributes. The special files are the catalog file, the
extents overflow file, the allocation file, the attributes
file and the startup file. Special files only have a single
fork (the data fork) and the extents of that fork are
described in the volume header.</P>
<P>The <B>catalog file</B> is a special file that describes
the folder and file hierarchy on a volume. The catalog file
contains vital information about all the files and folders
on a volume, as well as the <B>catalog information</B>, for
the files and folders that are stored in the catalog file.
The catalog file is organized as a B-tree (or "balanced
tree") to allow quick and efficient searches through a large
folder hierarchy.</P>
<P>The catalog file stores the file and folder names, which
consist of up to 255 Unicode characters, as described
<a HREF = "#HFSPlusNames">below</a>.</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>Note:</B><BR>
The <a HREF = "#BTrees">B-Trees</a> section contains
an in-depth description of the B-trees used by HFS
Plus.</p></TD></TR></table></CENTER>
<P>The <B>attributes file</B> is another special file which
contains additional data for a file or folder. Like the
catalog file, the attributes file is organized as a B-tree.
In the future, it will be used to store information about
additional forks. (This is similar to the way the catalog
file stores information about the data and resource forks of
a file.)</P>
<P>HFS Plus tracks which allocation blocks belong to a fork
by maintaining a list of the fork's extents. An
<B>extent</B> is a contiguous range of allocation blocks
allocated to some fork, represented by a pair of numbers:
the first allocation block number and the number of
allocation blocks. For a user file, the first eight extents
of each fork are stored in the volume's catalog file. Any
additional extents are stored in the <B>extents overflow
file</B>, which is also organized as a B-tree.</P>
<P>The extents overflow file also stores additional extents
for the special files except for the extents overflow file
itself. However, if the startup file requires more than the
eight extents in the Volume Header (and thus requires
additional extents in the extents overflow file), it would
be much harder to access, and defeat the purpose of the
startup file. So, in practice, a startup file should be
allocated such that it doesn't need additional extents in
the extents overflow file.</P>
<P>The <B>allocation file</B> is a special file which
specifies whether an allocation block is used or free. This
performs the same role as the HFS volume bitmap, although
making it a file adds flexibility to the volume format.</P>
<P>The <B>startup file</B> is another special file which
facilitates booting of non-Mac OS computers from HFS Plus
volumes.</P>
<P>Finally, the <B>bad block file</B> prevents the volume
from using certain allocation blocks because the portion of
the media that stores those blocks is defective. The bad
block file is neither a special file nor a user file; this
is merely convention used in the extents overflow file. See
<a HREF = "#BadBlockFile">Bad Block File</a> for more details.
</P>
<H3>Broad Structure</H3>
<P>The bulk of an HFS Plus volume consists of seven types of
information or areas:</P>
<OL>
<li>user file forks,</li>
<li>the allocation file (bitmap),</li>
<li>the catalog file,</li>
<li>the extents overflow file,</li>
<li>the attributes file,</li>
<li>the startup file, and</li>
<li>unused space.</li>
</OL>
<P>The general structure of an HFS Plus volume is
illustrated in Figure 1.</P>
<CENTER><img src="images/tn1150_001.png" alt="Organization of an HFS Plus Volume" width=297 height=450 align=bottom>
<P><B>Figure 1</B>. Organization of an HFS Plus
Volumes.</P>
</center>
<P>The volume header is always at a fixed
location (1024 bytes from the start of the volume).
However, the special files can appear anywhere between
the volume header block and the alternate volume header
block. These files can appear in any order and are not
necessarily contiguous.</P>
<P>The information on HFS Plus volumes (with the possible
exception of the alternate volume header, as discussed
<a HREF = "#OddSizeVolumes">below</a>) is organized solely
in allocation blocks. Allocation blocks are simply a means
of grouping space on the media into convenient parcels.
The size of an allocation block is a power of two,
and at least 512. The allocation block size is a volume
header parameter whose value is set when the volume is
initialized; it cannot be changed easily without
reinitializing the volume.</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>Note:</B><BR>
The allocation block size is a classic
speed-versus- space tradeoff. Increasing the
allocation block size decreases the size of the
allocation file, and often reduces the number of
separate extents that must be manipulated for every
file. It also tends to increase the average size of
a disk I/O, which decreases overhead. Decreasing
the allocation block size reduces the average
number of wasted bytes per file, making more
efficient use of the volume's space.</p>
</TD></TR></table></CENTER>
<a NAME="SmallAllocationBlockWarning"></a>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>WARNING:</B><BR>
While HFS Plus disks with an allocation block size
smaller than 4 KB are legal, DTS recommends that
you always use a minimum 4 KB allocation block
size. Disks with a smaller allocation block size
will be markedly slower when used on systems that
do 4 KB clustered I/O, such as Mac OS X Server.</p>
</TD></TR></table></CENTER>
<H3>Primitive Data Types</H3>
<P>This section describes the primitive data types used on
an HFS Plus volume. All data structures in this volume are
defined in the C language. The specification assumes that
the compiler will not insert any padding fields. Any
necessary padding fields are explicitly declared.</P>
<CENTER><table BORDER=0 WIDTH=550>
<TR><TD BGCOLOR="#E6E6E6">
<P><B>IMPORTANT:</B><BR>
The HFS Plus volume format is largely derived from
the HFS volume format. When defining the new
format, it was decided to remove unused fields
(primarily legacy MFS fields) and arrange all the
remaining fields so that similar fields were
grouped together and that all fields had proper
alignment (using PowerPC alignment rules).</p>
</TD></TR></table></CENTER>
<H4><a NAME="ReservedAndPadFields"></a>Reserved and Pad
Fields</H4>
<P>In many places this specification describes a field, or
bit within a field, as reserved. This has a definite
meaning, namely:</P>
<UL>
<li>When creating a structure with a reserved field, an
implementation must set the field to zero.</li>
<li>When reading existing structures, an implementation
must ignore any value in the field.</li>
<li>When modifying a structure with a reserved field, an
implementation must preserve the value of the reserved
field.</li>
</UL>
<P>This definition allows for backward-compatible
enhancements to the volume format.</P>
<P>Pad fields have exactly the same semantics as a reserved
field. The different name merely reflects the designer's
goals when including the field, not the behavior of the
implementation.</P>
<H4>Integer Types</H4>
<P>All integer values are defined by one of the following
primitive types: <CODE>UInt8</CODE>, <CODE>SInt8</CODE>,
<CODE>UInt16</CODE>, <CODE>SInt16</CODE>,
<CODE>UInt32</CODE>, <CODE>SInt32</CODE>,
<CODE>UInt64</CODE>, and <CODE>SInt64</CODE>. These
represent unsigned and signed (2's complement) 8-bit,
16-bit, 32-bit, and 64-bit numbers.</P>
<P>All multi-byte integer values are stored in big-endian
format. That is, the bytes are stored in order from most
significant byte through least significant byte, in
consecutive bytes, at increasing offset from the start of a
block. Bits are numbered from 0 to <i>n</i>-1 (for types
<code>UInt</code><i>n</i> and <code>SInt</code><i>n</i>),
with bit 0 being the least significant bit.</P>
<H4><a NAME="HFSPlusNames"></a>HFS Plus Names</H4>
<P>File and folder names on HFS Plus consist of up to 255
Unicode characters with a preceding 16-bit length, defined
by the type <CODE>HFSUniStr255</CODE>.</P>
<CENTER><table BORDER=0 CELLPADDING=5 WIDTH=550>
<TR>
<TD BGCOLOR="#E6E6E6">
<pre>struct HFSUniStr255 {
UInt16 length;
UniChar unicode[255];
};
typedef struct HFSUniStr255 HFSUniStr255;
typedef const HFSUniStr255 *ConstHFSUniStr255Param;</pre>
</TD>
</TR>
</table></CENTER>
<P><CODE>UniChar</CODE> is a <CODE>UInt16</CODE> that
represents a character as defined in the Unicode character
set defined by <I> The Unicode Standard, Version 2.0</I>
[Unicode, Inc. ISBN 0-201-48345-9].</P>
<P>HFS Plus stores strings fully decomposed and in canonical
order. HFS Plus compares strings in a case-insensitive
fashion. Strings may contain Unicode characters that must
be ignored by this comparison. For more details on these
subtleties, see <a HREF = "#UnicodeSubtleties">Unicode
Subtleties</a>.</P>
<P>A variant of HFS Plus, called <a href="#HFSX">HFSX</a>,
allows volumes whose names are compared in a case-sensitive
fashion. The names are fully decomposed and in canonical order,
but no Unicode characters are ignored during the comparison.</P>
<H4><a NAME="TextEncodings"></a>Text Encodings</H4>
<P>Traditional Mac OS programming interfaces pass filenames as
Pascal strings (either as a <CODE>StringPtr</CODE> or as a
<CODE>Str63</CODE> embedded in an <CODE>FSSpec</CODE>). The
characters in those strings are not Unicode; the encoding
varies depending on how the system software was localized
and what language kits are installed. Identical sequences of
bytes can represent vastly different Unicode character
sequences. Similarly, many Unicode characters belong to more
than one Mac OS text encoding.</P>
<P>HFS Plus includes two features specifically designed to
help Mac OS handle the conversion between Mac OS-encoded
Pascal strings and Unicode. The first feature is the
<CODE>textEncoding</CODE> field of the file and folder
catalog records. This field is defined as a hint to be used
when converting the record's Unicode name back to a Mac OS-
encoded Pascal string.</P>
<P>The valid values for the <CODE>textEncoding</CODE> field
are defined in Table 2.</P>
<P ALIGN=CENTER><B>Table 2</B> Text Encodings</p>
<CENTER><table BORDER=1>
<TR>
<TD WIDTH=140>
<P><B>Encoding Name</B></p>
</TD><TD WIDTH=60>
<P><B>Value</B></p>
</TD><TD WIDTH=140>
<P><B>Encoding Name</B></p>
</TD><TD WIDTH=60>
<P><B>Value</B></p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacRoman</p>
</TD><TD WIDTH=60>
<P>0</p>
</TD><TD WIDTH=140>
<P>MacThai</p>
</TD><TD WIDTH=60>
<P>21</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacJapanese</p>
</TD><TD WIDTH=60>
<P>1</p>
</TD><TD WIDTH=140>
<P>MacLaotian</p>
</TD><TD WIDTH=60>
<P>22</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacChineseTrad</p>
</TD><TD WIDTH=60>
<P>2</p>
</TD><TD WIDTH=140>
<P>MacGeorgian</p>
</TD><TD WIDTH=60>
<P>23</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacKorean</p>
</TD><TD WIDTH=60>
<P>3</p>
</TD><TD WIDTH=140>
<P>MacArmenian</p>
</TD><TD WIDTH=60>
<P>24</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacArabic</p>
</TD><TD WIDTH=60>
<P>4</p>
</TD><TD WIDTH=140>
<P>MacChineseSimp</p>
</TD><TD WIDTH=60>
<P>25</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacHebrew</p>
</TD><TD WIDTH=60>
<P>5</p>
</TD><TD WIDTH=140>
<P>MacTibetan</p>
</TD><TD WIDTH=60>
<P>26</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacGreek</p>
</TD><TD WIDTH=60>
<P>6</p>
</TD><TD WIDTH=140>
<P>MacMongolian</p>
</TD><TD WIDTH=60>
<P>27</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacCyrillic</p>
</TD><TD WIDTH=60>
<P>7</p>
</TD><TD WIDTH=140>
<P>MacEthiopic</p>
</TD><TD WIDTH=60>
<P>28</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacDevanagari</p>
</TD><TD WIDTH=60>
<P>9</p>
</TD><TD WIDTH=140>
<P>MacCentralEurRoman</p>
</TD><TD WIDTH=60>
<P>29</p>
</TD></TR>
<TR>
<TD WIDTH=140>
<P>MacGurmukhi</p>
</TD><TD WIDTH=60>
<P>10</p>
</TD><TD WIDTH=140>
<P>MacVietnamese</p>
</TD><TD WIDTH=60>
<P>30</p>