kern/60523: mount_lfs can break inode freelist consistency in ifile
"Shinichi Doyashiki via gnats" <[email protected]> Sat, 1 Aug 2026 11:50:00 +0000 (UTC)
| Newsgroups | gmane.os.netbsd.bugs |
|---|---|
| Message-ID | <[email protected]> |
>Number: 60523 >Category: kern >Synopsis: mount_lfs can break inode freelist consistency in ifile >Confidential: no >Severity: serious >Priority: medium >Responsible: kern-bug-people >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Sat Aug 01 11:50:00 +0000 2026 >Originator: Shinichi Doyashiki >Release: NetBSD 11.99.7 around 2026-07 >Organization: at home >Environment: System: NetBSD kanade2.hq.csel.org 11.99.7 NetBSD 11.99.7 (KANADE2_12) #60: Sat Aug 1 19:49:26 JST 2026 [email protected]:/export/netbsd/debuglfs/src/sys/arch/amd64/compile/KANADE2_12 amd64 Architecture: x86_64 Machine: amd64 >Description: mount_lfs can break inode freelist consistency in ifile. *** PREPARE TEST *** ===> create lfs Creating a version 2 LFS32 with roll-forward ident 0x7e39d1b3 1023.0MB in 1023 segments of size 1048576 super-block backups (for fsck -b #) at: 16, 208896, 417792, 626688, 835584, 1044480, 1253376, 1462272, 1671168, 1880064. ===> mount lfs ===> create files ===> umount lfs ===> fsck lfs ** /dev/rdk3 (NO WRITE) ** File system is already clean ** Last Mounted on /lfs ** Phase 0 - Check Inode Free List ** Phase 1 - Check Blocks and Sizes ** Phase 2 - Check Pathnames ** Phase 3 - Check Connectivity ** Phase 4 - Check Reference Counts ** Phase 5 - Check Segment Block Accounting 2 files, 41 used, 942948 free ===> dumplfs lfs *** RUN TEST *** ===> mount lfs ===> umount lfs ===> fsck lfs ** /dev/rdk3 (NO WRITE) ** File system is already clean ** Last Mounted on /lfs ** Phase 0 - Check Inode Free List INO 18 FREE BUT NOT ON FREE LIST FIX? no INO 17 FREE BUT NOT ON FREE LIST FIX? no INO 16 FREE BUT NOT ON FREE LIST FIX? no INO 15 FREE BUT NOT ON FREE LIST FIX? no INO 14 FREE BUT NOT ON FREE LIST FIX? no INO 13 FREE BUT NOT ON FREE LIST FIX? no INO 12 FREE BUT NOT ON FREE LIST FIX? no INO 11 FREE BUT NOT ON FREE LIST FIX? no INO 10 FREE BUT NOT ON FREE LIST FIX? no INO 9 FREE BUT NOT ON FREE LIST FIX? no INO 8 FREE BUT NOT ON FREE LIST FIX? no INO 7 FREE BUT NOT ON FREE LIST FIX? no INO 6 FREE BUT NOT ON FREE LIST FIX? no INO 5 FREE BUT NOT ON FREE LIST FIX? no INO 4 FREE BUT NOT ON FREE LIST FIX? no ** Phase 1 - Check Blocks and Sizes ** Phase 2 - Check Pathnames ** Phase 3 - Check Connectivity ** Phase 4 - Check Reference Counts ** Phase 5 - Check Segment Block Accounting 2 files, 41 used, 942946 free ===> dumplfs lfs >How-To-Repeat: #!/bin/sh echo "*** PREPARE TEST ***" mkdir -p /lfs echo "===> create lfs" newfs_lfs /dev/rdk3 echo "===> mount lfs" mount_lfs -n /dev/dk3 /lfs echo "===> create files" ( cd /lfs for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do touch $i done sync sync for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do rm $i done ) echo "===> umount lfs" umount /lfs echo "===> fsck lfs" fsck_lfs -nf /dev/rdk3 | tee before.fsck echo "===> dumplfs lfs" dumplfs -i /dev/rdk3 > before.dumplfs echo "*** RUN TEST ***" echo "===> mount lfs" mount_lfs -n /dev/dk3 /lfs echo "===> umount lfs" umount /lfs echo "===> fsck lfs" fsck_lfs -nf /dev/rdk3 | tee after.fsck echo "===> dumplfs lfs" dumplfs -i /dev/rdk3 > after.dumplfs >Fix: the following patch is diagnostic workaround; not the fix. Index: lfs_bio.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_bio.c,v retrieving revision 1.153 diff -u -1 -0 -r1.153 lfs_bio.c --- lfs_bio.c 2 Dec 2025 01:23:09 -0000 1.153 +++ lfs_bio.c 1 Aug 2026 10:47:08 -0000 @@ -426,21 +426,22 @@ KASSERT((bp->b_flags & B_LOCKED) || !(bp->b_oflags & BO_DELWRI)); KASSERT(!(flags & BW_CLEAN) || lfs_cleanerlock_held(fs)); /* * Don't write *any* blocks if we're mounted read-only, or * if we are "already unmounted". * * In particular the cleaner can't write blocks either. */ - if (fs->lfs_ronly || (lfs_sb_getpflags(fs) & LFS_PF_CLEAN)) { + if (fs->lfs_ronly || + ((lfs_sb_getpflags(fs) & LFS_PF_CLEAN) && !(fs->lfs_flags & LFS_NOTYET))) { bp->b_oflags &= ~BO_DELWRI; bp->b_flags |= B_READ; /* XXX is this right? --ks */ bp->b_error = 0; mutex_enter(&bufcache_lock); LFS_UNLOCK_BUF(bp); if (LFS_IS_MALLOC_BUF(bp)) bp->b_cflags &= ~BC_BUSY; else brelsel(bp, 0); mutex_exit(&bufcache_lock);