linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
To: "frank.li@vivo.com" <frank.li@vivo.com>,
	"glaubitz@physik.fu-berlin.de" <glaubitz@physik.fu-berlin.de>
Cc: "linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
	"brauner@kernel.org" <brauner@kernel.org>,
	"slava@dubeyko.com" <slava@dubeyko.com>
Subject: Re:  回复:  回复:  回复: 回复: HFS/HFS+ maintainership action items
Date: Sun, 27 Apr 2025 20:28:37 +0000	[thread overview]
Message-ID: <7b76ad938f586658950d2e878759d9cbcd8644e1.camel@ibm.com> (raw)
In-Reply-To: <SEZPR06MB52699F3D7B651C40266E4445E8872@SEZPR06MB5269.apcprd06.prod.outlook.com>

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

  parent reply	other threads:[~2025-04-27 20:28 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-21 21:52 HFS/HFS+ maintainership action items Viacheslav Dubeyko
2025-04-22  2:43 ` Theodore Ts'o
2025-04-22  4:16   ` Darrick J. Wong
2025-04-22  7:21     ` John Paul Adrian Glaubitz
2025-04-22  7:20   ` John Paul Adrian Glaubitz
2025-04-22 12:35 ` John Paul Adrian Glaubitz
2025-04-22 21:12   ` Viacheslav Dubeyko
2025-04-22 21:47     ` John Paul Adrian Glaubitz
2025-04-22 21:48       ` John Paul Adrian Glaubitz
2025-04-25  1:06         ` Viacheslav Dubeyko
2025-04-25 10:17           ` 回复: " 李扬韬
2025-04-25 11:32             ` John Paul Adrian Glaubitz
2025-04-25 11:39               ` 回复: " 李扬韬
2025-04-25 18:25                 ` Viacheslav Dubeyko
2025-04-25 19:36                   ` 回复: " 李扬韬
2025-04-25 19:44                     ` Viacheslav Dubeyko
2025-04-26  6:17                       ` 回复: " 李扬韬
2025-04-26  6:59                         ` John Paul Adrian Glaubitz
2025-04-27 20:28                         ` Viacheslav Dubeyko [this message]
2025-05-02  3:01                           ` Theodore Ts'o
2025-05-02 19:14                             ` Viacheslav Dubeyko
2025-05-03  5:39                               ` Theodore Ts'o
2025-05-05 23:08                                 ` Viacheslav Dubeyko
2025-04-25 20:51                     ` John Paul Adrian Glaubitz
2025-04-25 18:02             ` Viacheslav Dubeyko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7b76ad938f586658950d2e878759d9cbcd8644e1.camel@ibm.com \
    --to=slava.dubeyko@ibm.com \
    --cc=brauner@kernel.org \
    --cc=frank.li@vivo.com \
    --cc=glaubitz@physik.fu-berlin.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=slava@dubeyko.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).