Re: 回复: 回复: 回复: 回复: HFS/HFS+ maintainership action items

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2025-04-26 at 06:17 +0000, 李扬韬 wrote:
> Hi Slava and Adrian,

> I plan on looking at a few hfsplus failures first, or if there is something else planned I'll go for that too.
> 

Sounds good! I think I can share some resources [1, 2] if you need to take a
deeper look into HFS/HFS+ on-disk layout.

I already started to take a look into HFS issues. Currently, I am investigating
generic/001 case.

fsck.hfs -d -n ./test-image.bin 
** ./test-image.bin (NO WRITE)
	Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K.
   Executing fsck_hfs (version 540.1-Linux).
** Checking HFS volume.
   The volume name is untitled
** Checking extents overflow file.
** Checking catalog file.
   Unused node is not erased (node = 2)
   Unused node is not erased (node = 4)
   Unused node is not erased (node = 5)
   Unused node is not erased (node = 6)
   Unused node is not erased (node = 7)
   Unused node is not erased (node = 8)
   Unused node is not erased (node = 9)
   Unused node is not erased (node = 10)
   Unused node is not erased (node = 11)
   Unused node is not erased (node = 12)
   Unused node is not erased (node = 13)
   Unused node is not erased (node = 14)
   Unused node is not erased (node = 16)
   Unused node is not erased (node = 17)
   Unused node is not erased (node = 18)
   Unused node is not erased (node = 19)
   Unused node is not erased (node = 20)
   Unused node is not erased (node = 21)
   Unused node is not erased (node = 22)
   Unused node is not erased (node = 23)
   Unused node is not erased (node = 24)
   Unused node is not erased (node = 25)
   Unused node is not erased (node = 26)
   Unused node is not erased (node = 27)
   Unused node is not erased (node = 28)
   Unused node is not erased (node = 29)
   Unused node is not erased (node = 30)
   Unused node is not erased (node = 31)
   Unused node is not erased (node = 32)
   Unused node is not erased (node = 33)
   Unused node is not erased (node = 34)
   Unused node is not erased (node = 35)
   Unused node is not erased (node = 36)
   Unused node is not erased (node = 37)
   Unused node is not erased (node = 38)
   Unused node is not erased (node = 39)
   Unused node is not erased (node = 40)
   Unused node is not erased (node = 41)
   Unused node is not erased (node = 42)
   Unused node is not erased (node = 43)
   Unused node is not erased (node = 44)
   Unused node is not erased (node = 45)
   Unused node is not erased (node = 46)
   Unused node is not erased (node = 47)
   Unused node is not erased (node = 48)
   Unused node is not erased (node = 49)
   Unused node is not erased (node = 50)
   Unused node is not erased (node = 51)
   Unused node is not erased (node = 52)
   Unused node is not erased (node = 53)
   Unused node is not erased (node = 54)
   Unused node is not erased (node = 55)
   Unused node is not erased (node = 56)
   Unused node is not erased (node = 57)
   Unused node is not erased (node = 58)
   Unused node is not erased (node = 59)
   Unused node is not erased (node = 60)
   Unused node is not erased (node = 61)
   Unused node is not erased (node = 62)
   Unused node is not erased (node = 63)
   Unused node is not erased (node = 64)
   Unused node is not erased (node = 65)
   Unused node is not erased (node = 66)
   Unused node is not erased (node = 67)
   Unused node is not erased (node = 68)
   Unused node is not erased (node = 69)
   Unused node is not erased (node = 70)
   Unused node is not erased (node = 71)
   Unused node is not erased (node = 72)
   Unused node is not erased (node = 73)
   Unused node is not erased (node = 74)
   Unused node is not erased (node = 75)
   Unused node is not erased (node = 76)
   Unused node is not erased (node = 77)
   Unused node is not erased (node = 78)
   Unused node is not erased (node = 79)
   Unused node is not erased (node = 80)
   Unused node is not erased (node = 81)
   Unused node is not erased (node = 82)
   Unused node is not erased (node = 83)
   Unused node is not erased (node = 84)
   Unused node is not erased (node = 85)
   Unused node is not erased (node = 86)
   Unused node is not erased (node = 87)
   Unused node is not erased (node = 88)
   Unused node is not erased (node = 89)
   Unused node is not erased (node = 90)
   Unused node is not erased (node = 91)
   Unused node is not erased (node = 92)
   Unused node is not erased (node = 93)
   Unused node is not erased (node = 95)
   Unused node is not erased (node = 96)
   Unused node is not erased (node = 97)
   Unused node is not erased (node = 98)
   Unused node is not erased (node = 99)
   Unused node is not erased (node = 100)
   Unused node is not erased (node = 101)
   Unused node is not erased (node = 102)
   Unused node is not erased (node = 103)
   Unused node is not erased (node = 104)
   Unused node is not erased (node = 105)
   Unused node is not erased (node = 106)
   Unused node is not erased (node = 107)
   Unused node is not erased (node = 108)
   Unused node is not erased (node = 109)
   Unused node is not erased (node = 110)
   Unused node is not erased (node = 111)
   Unused node is not erased (node = 112)
   Unused node is not erased (node = 113)
   Unused node is not erased (node = 114)
   Unused node is not erased (node = 115)
   Unused node is not erased (node = 116)
   Unused node is not erased (node = 117)
   Unused node is not erased (node = 118)
   Unused node is not erased (node = 119)
   Unused node is not erased (node = 120)
   Unused node is not erased (node = 121)
   Unused node is not erased (node = 122)
   Unused node is not erased (node = 123)
   Unused node is not erased (node = 124)
   Unused node is not erased (node = 125)
   Unused node is not erased (node = 126)
   Unused node is not erased (node = 127)
   Unused node is not erased (node = 128)
   Unused node is not erased (node = 129)
   Unused node is not erased (node = 130)
   Unused node is not erased (node = 131)
   Unused node is not erased (node = 132)
   Unused node is not erased (node = 133)
   Unused node is not erased (node = 134)
   Unused node is not erased (node = 135)
   Unused node is not erased (node = 136)
   Unused node is not erased (node = 137)
   Unused node is not erased (node = 138)
   Unused node is not erased (node = 139)
   Unused node is not erased (node = 140)
   Unused node is not erased (node = 141)
   Unused node is not erased (node = 142)
   Unused node is not erased (node = 143)
   Unused node is not erased (node = 144)
   Unused node is not erased (node = 145)
   Unused node is not erased (node = 146)
   Unused node is not erased (node = 147)
   Unused node is not erased (node = 148)
   Unused node is not erased (node = 149)
   Unused node is not erased (node = 150)
   Unused node is not erased (node = 151)
   Unused node is not erased (node = 152)
   Unused node is not erased (node = 153)
   Unused node is not erased (node = 154)
   Unused node is not erased (node = 155)
   Unused node is not erased (node = 156)
   Unused node is not erased (node = 157)
   Unused node is not erased (node = 158)
   Unused node is not erased (node = 159)
   Unused node is not erased (node = 160)
   Unused node is not erased (node = 161)
   Unused node is not erased (node = 162)
   Unused node is not erased (node = 163)
   Unused node is not erased (node = 164)
   Unused node is not erased (node = 165)
   Unused node is not erased (node = 166)
   Unused node is not erased (node = 167)
   Unused node is not erased (node = 168)
   Unused node is not erased (node = 169)
   Unused node is not erased (node = 170)
   Unused node is not erased (node = 171)
   Unused node is not erased (node = 172)
   Unused node is not erased (node = 173)
   Unused node is not erased (node = 174)
   Unused node is not erased (node = 175)
   Unused node is not erased (node = 176)
   Unused node is not erased (node = 177)
   Unused node is not erased (node = 178)
   Unused node is not erased (node = 179)
   Unused node is not erased (node = 180)
   Unused node is not erased (node = 181)
   Unused node is not erased (node = 182)
   Unused node is not erased (node = 183)
   Unused node is not erased (node = 184)
   Unused node is not erased (node = 185)
   Unused node is not erased (node = 186)
   Unused node is not erased (node = 187)
   Unused node is not erased (node = 188)
   Unused node is not erased (node = 189)
   Unused node is not erased (node = 190)
   Unused node is not erased (node = 191)
   Unused node is not erased (node = 192)
   Unused node is not erased (node = 193)
   Unused node is not erased (node = 194)
   Unused node is not erased (node = 195)
   Unused node is not erased (node = 196)
   Unused node is not erased (node = 197)
   Unused node is not erased (node = 198)
   Unused node is not erased (node = 199)
   Unused node is not erased (node = 200)
   Unused node is not erased (node = 201)
   Unused node is not erased (node = 202)
   Unused node is not erased (node = 203)
   Unused node is not erased (node = 204)
   Unused node is not erased (node = 205)
   Unused node is not erased (node = 206)
   Unused node is not erased (node = 207)
   Unused node is not erased (node = 208)
   Unused node is not erased (node = 209)
   Unused node is not erased (node = 210)
   Unused node is not erased (node = 211)
   Unused node is not erased (node = 212)
   Unused node is not erased (node = 213)
   Unused node is not erased (node = 214)
   Unused node is not erased (node = 215)
   Unused node is not erased (node = 216)
   Unused node is not erased (node = 217)
   Unused node is not erased (node = 218)
   Unused node is not erased (node = 219)
   Unused node is not erased (node = 220)
   Unused node is not erased (node = 221)
   Unused node is not erased (node = 222)
   Unused node is not erased (node = 223)
   Unused node is not erased (node = 224)
   Unused node is not erased (node = 225)
   Unused node is not erased (node = 226)
   Unused node is not erased (node = 227)
   Unused node is not erased (node = 228)
   Unused node is not erased (node = 229)
   Unused node is not erased (node = 230)
   Unused node is not erased (node = 231)
   Unused node is not erased (node = 232)
   Unused node is not erased (node = 233)
   Unused node is not erased (node = 234)
   Unused node is not erased (node = 235)
   Unused node is not erased (node = 236)
   Unused node is not erased (node = 237)
   Unused node is not erased (node = 238)
   Unused node is not erased (node = 239)
   Unused node is not erased (node = 240)
   Unused node is not erased (node = 241)
   Unused node is not erased (node = 242)
   Unused node is not erased (node = 243)
   Unused node is not erased (node = 244)
   Unused node is not erased (node = 245)
   Unused node is not erased (node = 246)
   Unused node is not erased (node = 247)
   Unused node is not erased (node = 248)
   Unused node is not erased (node = 249)
   Unused node is not erased (node = 250)
   Unused node is not erased (node = 251)
   Unused node is not erased (node = 252)
   Unused node is not erased (node = 253)
   Unused node is not erased (node = 254)
   Unused node is not erased (node = 255)
   Unused node is not erased (node = 256)
** Checking catalog hierarchy.
** Checking volume bitmap.
** Checking volume information.
   Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000
                  CBTStat = 0x0004 CatStat = 0x00000000
** The volume untitled was found corrupt and needs to be repaired.
	volume type is HFS 
	primary MDB is at block 2 0x02 
	alternate MDB is at block 20971518 0x13ffffe 
	primary VHB is at block 0 0x00 
	alternate VHB is at block 0 0x00 
	sector size = 512 0x200 
	VolumeObject flags = 0x19 
	total sectors for volume = 20971520 0x1400000 
	total sectors for embedded volume = 0 0x00

It looks like that HFS driver doesn't erase deleted nodes of catalog file. So, I
need to refresh my knowledge of HFS on-disk layout.

Somehow, scratch volume becomes corrupted too. But I don't quite follow yet
which operation makes it happened. We lost magic signature in the first MDB.

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  00 00 e4 31 b7 03 e4 31  b7 03 01 00 00 00 00 03  |...1...1........|  
00000410  00 00 ff 33 00 02 82 00  00 0a 08 00 00 13 00 00  |...3............|
00000420  00 10 ff 27 08 75 6e 74  69 74 6c 65 64 00 00 00  |...'.untitled...|
00000430  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000440  00 00 00 00 00 00 00 00  00 03 00 0f 0c 00 00 0f  |................|
00000450  0c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000460  00 00 00 00 00 00 00 00  00 00 00 00 00 63 6e 65  |.............cne|
00000470  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000480  00 00 00 0f 0c 00 00 00  00 06 00 00 00 00 00 00  |................|
00000490  00 00 00 0f 0c 00 00 06  00 06 00 00 00 00 00 00  |................|
000004a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000600  ff f0 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000610  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002600  00 00 00 00 00 00 00 00  01 00 00 03 00 00 00 00  |................|
00002610  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00002620  02 00 00 07 00 00 07 86  00 00 07 85 00 00 00 0f  |................|
00002630  0c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00002640  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000026f0  00 00 00 00 00 00 00 00  80 00 00 00 00 00 00 00  |................|
00002700  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000027f0  00 00 00 00 00 00 00 00  01 f8 00 f8 00 78 00 0e  |.............x..|
00002800  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000f3200  00 00 00 00 00 00 00 00  01 00 00 03 00 00 00 01  |................|
000f3210  00 00 00 01 00 00 00 02  00 00 00 01 00 00 00 01  |................|
000f3220  02 00 00 25 00 00 07 86  00 00 07 84 00 00 00 0f  |...%............|
000f3230  0c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000f3240  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000f32f0  00 00 00 00 00 00 00 00  c0 00 00 00 00 00 00 00  |................|
000f3300  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000f33f0  00 00 00 00 00 00 00 00  01 f8 00 f8 00 78 00 0e  |.............x..|
000f3400  00 00 00 00 00 00 00 00  ff 01 00 02 00 00 0f 00  |................|
000f3410  00 00 00 01 08 75 6e 74  69 74 6c 65 64 00 01 00  |.....untitled...|
000f3420  00 00 00 00 00 00 00 02  e4 31 b7 03 e4 31 b7 03  |.........1...1..|
000f3430  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000f3460  00 00 00 00 06 00 00 00  00 02 00 00 03 00 00 00  |................|
000f3470  00 00 00 00 00 00 00 00  00 01 08 75 6e 74 69 74  |...........untit|
000f3480  6c 65 64 00 00 00 00 00  00 00 00 00 00 00 00 00  |led.............|
000f3490  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000f35f0  00 00 00 00 00 00 00 00  00 00 00 9a 00 64 00 0e  |.............d..|
000f3600  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
27ffffc00  42 44 e4 31 b7 03 e4 31  b7 03 01 00 00 00 00 03  |BD.1...1........|
27ffffc10  00 00 ff 33 00 02 82 00  00 0a 08 00 00 13 00 00  |...3............|
27ffffc20  00 10 ff 27 08 75 6e 74  69 74 6c 65 64 00 00 00  |...'.untitled...|
27ffffc30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
27ffffc40  00 00 00 00 00 00 00 00  00 02 00 0f 0c 00 00 0f  |................|
27ffffc50  0c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
27ffffc60  00 00 00 00 00 00 00 00  00 00 00 00 00 63 6e 65  |.............cne|
27ffffc70  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
27ffffc80  00 00 00 0f 0c 00 00 00  00 06 00 00 00 00 00 00  |................|
27ffffc90  00 00 00 0f 0c 00 00 06  00 06 00 00 00 00 00 00  |................|
27ffffca0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
280000000

And it looks like that mkfs.hfs simply ignores the -v option. I requested the
test volume label, but it's untitled, finally. 

mkfs.hfs -v test ./scratch-image.bin 
Initialized ./scratch-image.bin as a 10240 MB HFS volume

hexdump -C ./scratch-image.bin
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  42 44 e4 34 41 f8 e4 34  41 f8 01 00 00 00 00 03  |BD.4A..4A.......|
00000410  00 00 ff 33 00 02 82 00  00 0a 08 00 00 13 00 00  |...3............|
00000420  00 10 ff 27 08 75 6e 74  69 74 6c 65 64 00 00 00  |...'.untitled...|
00000430  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000440  00 00 00 00 00 00 00 00  00 02 00 0f 0c 00 00 0f  |................|
00000450  0c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000460  00 00 00 00 00 00 00 00  00 00 00 00 00 63 6e 65  |.............cne|
00000470  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000480  00 00 00 0f 0c 00 00 00  00 06 00 00 00 00 00 00  |................|
00000490  00 00 00 0f 0c 00 00 06  00 06 00 00 00 00 00 00  |................|
000004a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

mkfs.hfs -h
usage: mkfs.hfs [-N [partition-size]] [hfsplus-options] special-device
  options:
	-h create an HFS format filesystem (HFS Plus is the default)
	-N do not create file system, just print out parameters
	-s use case-sensitive filenames (default is case-insensitive)
	-w add a HFS wrapper (i.e. Native Mac OS 9 bootable)
  where hfsplus-options are:
	-J [journal-size] make this HFS+ volume journaled
	-D journal-dev use 'journal-dev' for an external journal
	-G group-id (for root directory)
	-U user-id (for root directory)
	-M octal access-mask (for root directory)
	-b allocation block size (4096 optimal)
	-c clump size list (comma separated)
		a=blocks (attributes file)
		b=blocks (bitmap file)
		c=blocks (catalog file)
		d=blocks (user data fork)
		e=blocks (extents file)
		r=blocks (user resource fork)
	-i starting catalog node id
	-n b-tree node size list (comma separated)
		e=size (extents b-tree)
		c=size (catalog b-tree)
		a=size (attributes b-tree)
	-v volume name (in ascii or UTF-8)
  examples:
	mkfs.hfs -v Untitled /dev/rdisk0s7 
	mkfs.hfs -v Untitled -n c=4096,e=1024 /dev/rdisk0s7 
	mkfs.hfs -v Untitled -c b=64,c=1024 /dev/rdisk0s

Thanks,
Slava.

[1] https://dubeyko.com/development/FileSystems/hfs.html
[2] https://dubeyko.com/development/FileSystems/hfsplus.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux