Module Name: src Committed By: martin Date: Tue Jan 7 16:16:51 UTC 2025
Modified Files: src/sys/ufs/ext2fs [netbsd-9]: ext2fs_vfsops.c src/sys/ufs/ffs [netbsd-9]: ffs_vfsops.c ffs_wapbl.c src/sys/ufs/lfs [netbsd-9]: lfs_vfsops.c Log Message: Pull up following revision(s) (requested by hannken in ticket #1934): sys/ufs/ext2fs/ext2fs_vfsops.c: revision 1.228 sys/ufs/lfs/lfs_vfsops.c: revision 1.383 sys/ufs/ffs/ffs_wapbl.c: revision 1.50 sys/ufs/ffs/ffs_vfsops.c: revision 1.383 (patch) sys/ufs/ffs/ffs_vfsops.c: revision 1.384 (patch) Remove comment "we are always called with the filesystem marked `MPBUSY'." above some xxx_sync() operations. These operations get called without any exclusive lock. This comment appeared with "add quota support" on 1990-05-02. On 1998/02/18 MNT_MPBUSY disappeared when vfs_busy() was changed from an exclusive lock to a shared lock. PR kern/58837 "ffs: Missing locking around fs_fmod/time" Protect test/clear fs->fs_fmod with um_lock like it is already protected in ffs_alloc.c. When writing to disk protect moving superblock to buffer with um_lock. Set/clear fs->fmod while mounting, updating a mount or unmounting is safe as these operations run exclusive, either mounting creates a new file system or the file system is suspended. Assert suspension for update and unmount. PR kern/58837 "ffs: Missing locking around fs_fmod/time" To generate a diff of this commit: cvs rdiff -u -r1.214 -r1.214.2.1 src/sys/ufs/ext2fs/ext2fs_vfsops.c cvs rdiff -u -r1.362.2.1 -r1.362.2.2 src/sys/ufs/ffs/ffs_vfsops.c cvs rdiff -u -r1.44 -r1.44.4.1 src/sys/ufs/ffs/ffs_wapbl.c cvs rdiff -u -r1.365.2.1 -r1.365.2.2 src/sys/ufs/lfs/lfs_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.214 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.214.2.1 --- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.214 Thu Jun 20 03:31:30 2019 +++ src/sys/ufs/ext2fs/ext2fs_vfsops.c Tue Jan 7 16:16:50 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vfsops.c,v 1.214 2019/06/20 03:31:30 pgoyette Exp $ */ +/* $NetBSD: ext2fs_vfsops.c,v 1.214.2.1 2025/01/07 16:16:50 martin Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1994 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.214 2019/06/20 03:31:30 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.214.2.1 2025/01/07 16:16:50 martin Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -904,8 +904,6 @@ ext2fs_sync_selector(void *cl, struct vn * Go through the disk queues to initiate sandbagged IO; * go through the inodes to write those that have been modified; * initiate the writing of the super block if it has been modified. - * - * Note: we are always called with the filesystem marked `MPBUSY'. */ int ext2fs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) Index: src/sys/ufs/ffs/ffs_vfsops.c diff -u src/sys/ufs/ffs/ffs_vfsops.c:1.362.2.1 src/sys/ufs/ffs/ffs_vfsops.c:1.362.2.2 --- src/sys/ufs/ffs/ffs_vfsops.c:1.362.2.1 Tue Nov 28 13:11:37 2023 +++ src/sys/ufs/ffs/ffs_vfsops.c Tue Jan 7 16:16:50 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_vfsops.c,v 1.362.2.1 2023/11/28 13:11:37 martin Exp $ */ +/* $NetBSD: ffs_vfsops.c,v 1.362.2.2 2025/01/07 16:16:50 martin Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.362.2.1 2023/11/28 13:11:37 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.362.2.2 2025/01/07 16:16:50 martin Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -75,6 +75,7 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c #include <sys/proc.h> #include <sys/kernel.h> #include <sys/vnode.h> +#include <sys/fstrans.h> #include <sys/socket.h> #include <sys/mount.h> #include <sys/buf.h> @@ -547,8 +548,9 @@ ffs_mount(struct mount *mp, const char * fs = ump->um_fs; } else { /* - * Update the mount. + * Update the mount. The file system is suspended. */ + KASSERT(fstrans_is_owner(mp)); /* * The initial mount got a reference on this @@ -689,25 +691,26 @@ ffs_mount(struct mount *mp, const char * DPRINTF("set_statvfs_info returned %d", error); } fs->fs_flags &= ~FS_DOSOFTDEP; - if (fs->fs_fmod != 0) { /* XXX */ - int err; - - fs->fs_fmod = 0; - if (fs->fs_clean & FS_WASCLEAN) - fs->fs_time = time_second; - else { - printf("%s: file system not clean (fs_clean=%#x); " - "please fsck(8)\n", mp->mnt_stat.f_mntfromname, - fs->fs_clean); - printf("%s: lost blocks %" PRId64 " files %d\n", - mp->mnt_stat.f_mntfromname, fs->fs_pendingblocks, - fs->fs_pendinginodes); - } - err = UFS_WAPBL_BEGIN(mp); - if (err == 0) { + if (UFS_WAPBL_BEGIN(mp) == 0) { + mutex_enter(&ump->um_lock); + if (fs->fs_fmod != 0) { + fs->fs_fmod = 0; + if (fs->fs_clean & FS_WASCLEAN) + fs->fs_time = time_second; + else { + printf("%s: file system not clean " + "(fs_clean=%#x); please fsck(8)\n", + mp->mnt_stat.f_mntfromname, fs->fs_clean); + printf("%s: lost blocks %" PRId64 + " files %d\n", mp->mnt_stat.f_mntfromname, + fs->fs_pendingblocks, fs->fs_pendinginodes); + } + mutex_exit(&ump->um_lock); (void) ffs_cgupdate(ump, MNT_WAIT); - UFS_WAPBL_END(mp); + } else { + mutex_exit(&ump->um_lock); } + UFS_WAPBL_END(mp); } if ((mp->mnt_flag & MNT_SOFTDEP) != 0) { printf("%s: `-o softdep' is no longer supported, " @@ -1673,6 +1676,9 @@ ffs_unmount(struct mount *mp, int mntfla extern int doforce; #endif + /* The file system is suspended. */ + KASSERT(fstrans_is_owner(mp)); + if (ump->um_discarddata) { ffs_discard_finish(ump->um_discarddata, mntflags); ump->um_discarddata = NULL; @@ -1683,17 +1689,17 @@ ffs_unmount(struct mount *mp, int mntfla flags |= FORCECLOSE; if ((error = ffs_flushfiles(mp, flags, l)) != 0) return (error); - error = UFS_WAPBL_BEGIN(mp); - if (error == 0) - if (fs->fs_ronly == 0 && - ffs_cgupdate(ump, MNT_WAIT) == 0 && + if (fs->fs_ronly == 0 && UFS_WAPBL_BEGIN(mp) == 0) { + if (ffs_cgupdate(ump, MNT_WAIT) == 0 && fs->fs_clean & FS_WASCLEAN) { + mutex_enter(&ump->um_lock); fs->fs_clean = FS_ISCLEAN; fs->fs_fmod = 0; + mutex_exit(&ump->um_lock); (void) ffs_sbupdate(ump, MNT_WAIT); } - if (error == 0) UFS_WAPBL_END(mp); + } #ifdef WAPBL KASSERT(!(mp->mnt_wapbl_replay && mp->mnt_wapbl)); if (mp->mnt_wapbl_replay) { @@ -1874,8 +1880,6 @@ ffs_sync_selector(void *cl, struct vnode * Go through the disk queues to initiate sandbagged IO; * go through the inodes to write those that have been modified; * initiate the writing of the super block if it has been modified. - * - * Note: we are always called with the filesystem marked `MPBUSY'. */ int ffs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) @@ -1952,17 +1956,21 @@ ffs_sync(struct mount *mp, int waitfor, /* * Write back modified superblock. */ - if (fs->fs_fmod != 0) { - fs->fs_fmod = 0; - fs->fs_time = time_second; - error = UFS_WAPBL_BEGIN(mp); - if (error) - allerror = error; - else { + error = UFS_WAPBL_BEGIN(mp); + if (error) { + allerror = error; + } else { + mutex_enter(&ump->um_lock); + if (fs->fs_fmod != 0) { + fs->fs_fmod = 0; + fs->fs_time = time_second; + mutex_exit(&ump->um_lock); if ((error = ffs_cgupdate(ump, waitfor))) allerror = error; - UFS_WAPBL_END(mp); + } else { + mutex_exit(&ump->um_lock); } + UFS_WAPBL_END(mp); } #ifdef WAPBL @@ -2308,26 +2316,28 @@ int ffs_sbupdate(struct ufsmount *mp, int waitfor) { struct fs *fs = mp->um_fs; + struct fs *bfs; struct buf *bp; int error; - u_int32_t saveflag; error = ffs_getblk(mp->um_devvp, fs->fs_sblockloc / DEV_BSIZE, FFS_NOBLK, fs->fs_sbsize, false, &bp); if (error) return error; - saveflag = fs->fs_flags & FS_INTERNAL; - fs->fs_flags &= ~FS_INTERNAL; + mutex_enter(&mp->um_lock); memcpy(bp->b_data, fs, fs->fs_sbsize); + mutex_exit(&mp->um_lock); + + bfs = (struct fs *)bp->b_data; + bfs->fs_flags &= ~FS_INTERNAL; ffs_oldfscompat_write((struct fs *)bp->b_data, mp); #ifdef FFS_EI if (mp->um_flags & UFS_NEEDSWAP) - ffs_sb_swap((struct fs *)bp->b_data, (struct fs *)bp->b_data); + ffs_sb_swap(bfs, bfs); #endif - fs->fs_flags |= saveflag; if (waitfor == MNT_WAIT) error = bwrite(bp); Index: src/sys/ufs/ffs/ffs_wapbl.c diff -u src/sys/ufs/ffs/ffs_wapbl.c:1.44 src/sys/ufs/ffs/ffs_wapbl.c:1.44.4.1 --- src/sys/ufs/ffs/ffs_wapbl.c:1.44 Tue Jan 1 10:06:55 2019 +++ src/sys/ufs/ffs/ffs_wapbl.c Tue Jan 7 16:16:50 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_wapbl.c,v 1.44 2019/01/01 10:06:55 hannken Exp $ */ +/* $NetBSD: ffs_wapbl.c,v 1.44.4.1 2025/01/07 16:16:50 martin Exp $ */ /*- * Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.44 2019/01/01 10:06:55 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.44.4.1 2025/01/07 16:16:50 martin Exp $"); #define WAPBL_INTERNAL @@ -191,11 +191,15 @@ ffs_wapbl_sync_metadata(struct mount *mp FFS_DBTOFSB(fs, wd->wd_blkno), wd->wd_len, -1); } + mutex_enter(&ump->um_lock); if (fs->fs_fmod != 0) { fs->fs_fmod = 0; fs->fs_time = time_second; + mutex_exit(&ump->um_lock); error = ffs_cgupdate(ump, 0); KASSERT(error == 0); + } else { + mutex_exit(&ump->um_lock); } } Index: src/sys/ufs/lfs/lfs_vfsops.c diff -u src/sys/ufs/lfs/lfs_vfsops.c:1.365.2.1 src/sys/ufs/lfs/lfs_vfsops.c:1.365.2.2 --- src/sys/ufs/lfs/lfs_vfsops.c:1.365.2.1 Mon Aug 17 10:30:22 2020 +++ src/sys/ufs/lfs/lfs_vfsops.c Tue Jan 7 16:16:50 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vfsops.c,v 1.365.2.1 2020/08/17 10:30:22 martin Exp $ */ +/* $NetBSD: lfs_vfsops.c,v 1.365.2.2 2025/01/07 16:16:50 martin Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007 @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.365.2.1 2020/08/17 10:30:22 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.365.2.2 2025/01/07 16:16:50 martin Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -1500,8 +1500,6 @@ lfs_statvfs(struct mount *mp, struct sta * Go through the disk queues to initiate sandbagged IO; * go through the inodes to write those that have been modified; * initiate the writing of the super block if it has been modified. - * - * Note: we are always called with the filesystem marked `MPBUSY'. */ int lfs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)