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)

Reply via email to