NetBSD-Users archive

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

Re: disks, partitions, slices, etc.



On Fri, 9 Oct 2026 at 13:23, Ramiro Aceves <ea1abz%gmail.com@localhost> wrote:
>
> En Fri, Oct 09, 2026 at 12:59:31PM +0100, Chavdar Ivanov escribió:
> >
> >
> >  On Linux:
> > mkfs.ext2 -L commons /dev/sda4            # optionally -O ^dir_index,^ext_attr
> >
> > On NetBSD:
> > dkctl ld0 listwedges                      # find the wedge, e.g. dk3 /
> > GUID b5bff367-...
> > mount -t ext2fs NAME=b5bff367-4977-4887-bea0-7e42f7a04fe4 /mnt
> >
> > In fstab:
> > NAME=b5bff367-4977-4887-bea0-7e42f7a04fe4  /commons  ext2fs  rw  0 0
> >
> > To repair: use Linux e2fsck or pkgsrc e2fsck -- never
> > /sbin/fsck_ext2fs on 11/-current
> >
> > Setting a GPT partition label (`gpt label -i 4 -l commons ld0` on
> > NetBSD, or `sgdisk -c 4:commons` on Linux) gives you `NAME=commons` in
> > fstab.
> >
>
> Many thanks Chavdar for the recipes!

Attached is a suggestion for three PRs - I am not going to file them,
as they were dome partially with the help of an LLM,
but if someone is interested, he can verify and file them. I have
verified the conclusions myself. Choose your pill.

> Regards.
> Ramiro.
>
>
> > --
> > ----

Chavdar

-- 
----
NetBSD PR drafts: ext2fs group descriptor issues


Facts were verified on ym1r (NetBSD 11.99.9 amd64, src as of 2026-10-06) and with Linux e2fsprogs 1.47.4.

1. bin: newfs_ext2fs, fsck_ext2fs and libsa use a 64-byte on-disk group descriptor stride

>Submitter-Id:	net
>Originator:	
>Organization:
>Confidential:	no
>Synopsis:	newfs_ext2fs/fsck_ext2fs/libsa use 64-byte group descriptor stride; filesystems unusable by Linux
>Severity:	serious
>Priority:	high
>Category:	bin
>Class:		sw-bug
>Release:	NetBSD 11.0, NetBSD-current (11.99.9)
>Environment:
System: NetBSD ym1r.lorien.lan 11.99.9 NetBSD 11.99.9 (GENERIC) #2: Tue Oct  6 14:49:12 BST 2026 amd64
Architecture: x86_64
Machine: amd64
>Description:
The INCOMPAT_64BIT import (ext2fs.h 1.49, ext2fs_vfsops.c 1.222,
2023-08-25) grew the in-memory struct ext2_gd from 32 to 64 bytes.
On disk, group descriptors remain 32 bytes (E2FS_REV0_GD_SIZE) unless
INCOMPAT_64BIT is set, which is never the case for ext2/ext3.

The kernel was converted to use e2fs_group_desc_shift and per-entry
copy functions (with the indexing fixed later in kern/58388).  The
userland and libsa were not.  ext2fs.h 1.50 restored the plain-memcpy
e2fs_cgload/e2fs_cgsave macros for !_KERNEL as a "stop-gap until they
can be taught to handle the new version", and they still use
sizeof(struct ext2_gd) as the on-disk entry size:

  sbin/newfs_ext2fs/mke2fs.c 1.28
    - lines 295, 329: blocks_gd = howmany(sizeof(struct ext2_gd) * ncg, bsize)
    - line 444: target_ngdb for the RESIZE reserved GDT
    - lines 679-680, 710-712: e2fs_cgsave(gd, ..., sizeof(struct ext2_gd) * ncg)
      copies the 64-byte in-memory array to disk verbatim
  sbin/fsck_ext2fs/setup.c 1.39
    - line 236: GDT blocks read raw into &e2fs_gd[i * bsize / sizeof(struct ext2_gd)]
    - lines 342, 536: e2fs_ngdb = howmany(ncg, bsize / sizeof(struct ext2_gd))
  sbin/fsck_ext2fs/utilities.c 1.23
    - line 240: GDT written back the same way
  sys/lib/libsa/ext2fs.c 1.35
    - lines 451, 466, 478: same ngdb/gdpb computation and raw e2fs_cgload

Consequences:

1. Every filesystem made by newfs_ext2fs on netbsd-11 and -current is
   corrupt to any 32-byte reader (Linux, e2fsprogs, and the NetBSD
   kernel itself).  32-byte slot 2k holds group k's descriptor, and
   slot 2k+1 holds its zero _hi half.  Odd groups therefore have
   bitmaps and inode table at block 0 with zero free counts, and even
   groups point at another group's metadata.  The GDT is also twice
   as large as needed.  Linux refuses to mount ("Structure needs
   cleaning" / "block overlap").  e2fsck "relocates" every odd group
   and data is lost.  This has been seen by several users on
   netbsd-users (thread "disks, partitions, slices, etc.",
   Oct 2026).

2. fsck_ext2fs reads the GDT in the same broken way.  It therefore
   reports newfs_ext2fs output as clean, and it misreads correct
   (Linux-made) filesystems: each in-memory descriptor fuses two
   on-disk ones, and only half of the GDT is read.  On a clean
   mke2fs-made 1 GB image, "fsck_ext2fs -n -f" reports
   "PARTIALLY ALLOCATED INODE I=32773" etc.  Without -n it would write
   the fused layout back and damage a good filesystem.

3. libsa (i386/amd64 boot, bootxx, efiboot, cobalt, zaurus) misreads
   correct ext2 filesystems in the same way, for inodes outside group
   0.  Today it happens to agree with newfs_ext2fs output, such as the
   cobalt /boot partition created by sysinst (see install/54065), so
   fixing newfs_ext2fs alone would break those boots.  All three
   consumers must be fixed together.

netbsd-10 (ext2fs.h 1.48, 32-byte struct) is not affected.  This was
verified on a stock 10.1 GENERIC.  newfs_ext2fs on 1 GB/4K and
512 MB/1K vnd devices, followed by writes from the NetBSD kernel,
gives filesystems that both fsck_ext2fs and Linux e2fsck report
clean.  The identical procedure on 11.99.9 fails as described.
This is therefore a regression in netbsd-11.
>How-To-Repeat:
On NetBSD 11 or -current:

	newfs_ext2fs -F -s 2097152 img.img

On Linux:

	e2fsck -fn img.img
	ext2fs_check_desc: Corrupt group descriptor: bad block for block bitmap
	Block bitmap for group 1 is not in group.  (block 0)
	...
	dumpe2fs img.img
	Group 1: ... Block bitmap at 0, Inode bitmap at 0, Inode table at 0-511
	Group 2: ... Block bitmap at 32897   (= group 1's: 32768 + 129)
	Group 4: ... Block bitmap at 65536   (= group 2's)

This was reproduced with 1 GB, 50 GB and 58 GB images (4 KB blocks).

Reverse direction: on Linux, "mke2fs -t ext2 good.img 1G"
(e2fsck clean).  On NetBSD, "fsck_ext2fs -n -f good.img" reports
spurious PARTIALLY ALLOCATED INODE errors.
>Fix:
Teach the userland and libsa the same on-disk/in-memory split as the
kernel:

- Move the shift-aware e2fs_cgload()/e2fs_cgsave() from
  ext2fs_vfsops.c into code shared with libsa and userland (for
  example ext2fs_bswap.c), and drop the ext2fs.h 1.50 memcpy macros.
- Derive the descriptor shift as the kernel does: 5
  (E2FS_REV0_GD_SIZE) unless INCOMPAT_64BIT, otherwise log2
  e3fs_desc_size.  Use it, not sizeof(struct ext2_gd), for ngdb,
  blocks_gd, target_ngdb, the per-block descriptor count, and the
  on-disk copy in mke2fs.c, fsck_ext2fs/setup.c, fsck_ext2fs/utilities.c
  and libsa/ext2fs.c.
- Add an ATF test: newfs_ext2fs -F, then fsck_ext2fs -n -f, then a
  rump_ext2fs mount, write and fsck.  riastradh asked for one in the
  ext2fs_vfsops.c 1.226 log ("XXX Evidently we need some more
  automatic tests for this!").

Please pull up to netbsd-11.  Users should meanwhile be advised to
create shared ext2 filesystems on Linux and to repair them with
e2fsprogs, not fsck_ext2fs.

2. kern: ext2fs_cg_get_csum() pointer arithmetic breaks metadata_csum with 64-byte descriptors

>Submitter-Id:	net
>Originator:	
>Organization:
>Confidential:	no
>Synopsis:	ext2fs: metadata_csum group descriptor checksum uses struct pointer arithmetic, 64bit ext4 fails to mount
>Severity:	non-critical
>Priority:	medium
>Category:	kern
>Class:		sw-bug
>Release:	NetBSD 11.0, NetBSD-current (11.99.9)
>Environment:
System: NetBSD ym1r.lorien.lan 11.99.9 NetBSD 11.99.9 (GENERIC) #2: Tue Oct  6 14:49:12 BST 2026 amd64
Architecture: x86_64
Machine: amd64
>Description:
In sys/ufs/ext2fs/ext2fs_alloc.c (1.59), ext2fs_cg_get_csum(), the
METADATA_CKSUM branch does:

	crc32 = ext2fs_crc32c(crc32, gd + off + 2, cgsize - (off + 2));

gd is a struct ext2_gd *, so "gd + off + 2" advances by
(30 + 2) * sizeof(struct ext2_gd) = 2048 bytes instead of 32.  The
GDT_CSUM (crc16) branch a few lines below correctly casts to
(uint8_t *).

With 32-byte descriptors, cgsize - (off + 2) is 0 and the bug is
harmless.  With 64-byte descriptors (INCOMPAT_64BIT + METADATA_CKSUM),
32 bytes are checksummed from the wrong address, which can be past the
end of the e2fs_gd allocation.  The checksum never matches, so
ext2fs_cg_verify_and_initialize() fails and the mount returns EINVAL.

This was introduced in ext2fs_alloc.c 1.55 ("Fix metadata_cksum",
2023-08-26), so it is present in netbsd-11.
>How-To-Repeat:
On Linux (e2fsprogs 1.47.4).  metadata_csum_seed is turned off only
because INCOMPAT_CSUM_SEED is not supported at all:

	mke2fs -t ext4 -O ^metadata_csum_seed e4.img 64M

On NetBSD:

	vnconfig vnd0 e4.img
	mount -r -t ext2fs /dev/vnd0d /mnt
	mount_ext2fs: /dev/vnd0d on /mnt: incorrect super block
	dmesg: ext2fs_cg_verify_and_initialize: group 0 invalid csum (0xcd67 != 0xf078)

The same image made with "-O ^64bit,^metadata_csum_seed" (32-byte
descriptors) mounts fine, and so does "-O ^metadata_csum" (64-byte,
no checksum).

An independent re-implementation of the corrected formula reproduces
the stored on-disk checksums exactly (0xcd67 for the 64-byte image,
0x3ac0 for the 32-byte one).

>Fix:
--- sys/ufs/ext2fs/ext2fs_alloc.c
+++ sys/ufs/ext2fs/ext2fs_alloc.c
@@ -812,7 +812,8 @@
 		crc32 = ext2fs_crc32c(crc32, &cg_bswapped, sizeof(cg_bswapped));
 		crc32 = ext2fs_crc32c(crc32, gd, off);
 		crc32 = ext2fs_crc32c(crc32, dummy, 2);
-		crc32 = ext2fs_crc32c(crc32, gd + off + 2, cgsize - (off + 2));
+		crc32 = ext2fs_crc32c(crc32, (uint8_t *)gd + off + 2,
+		    cgsize - (off + 2));
 
 		return h2fs16(crc32 & 0xffff);
 	}

(The patch has not been built into a kernel.  The checksum
arithmetic was verified offline against the images above.)


3. Follow-up to kern/57617 (request to close)

Send to `gnats-bugs%NetBSD.org@localhost` with the subject `Re: kern/57617: ext2fs broken`:

The group descriptor indexing problem described here (ext2fs_vfsops.c
1.225 using i * e2fs_bsize / sizeof(struct ext2_gd) as the destination
index) was reported again as kern/58388.  It was fixed by
ext2fs_vfsops.c 1.226 (riastradh) and 1.227 (rin) in July 2024, and
kern/58388 was closed on 2024-07-23.  The fix is in netbsd-11
(branched at 1.229), and netbsd-10 never had the bad code.

I verified this on 11.99.9 with the How-To-Repeat case here
(1 KB blocks, more than one GDT block).  I made a 512 MB ext2 with
"mke2fs -t ext2 -b 1024" on Linux (64 groups, 2 GDT blocks) and
mounted it read-write on NetBSD.  I wrote 60 directories with 4 MB
files (241 MB in total) and unmounted.  Linux "e2fsck -fn" then
reports the filesystem clean.  This PR can be closed as fixed
(duplicate of kern/58388).

Note that the same 64-byte struct ext2_gd change was never applied to
userland or libsa: newfs_ext2fs, fsck_ext2fs and libsa still use a
64-byte on-disk stride.  That is reported separately as bin/NNNNN.



Home | Main Index | Thread Index | Old Index