ffs_sync: Avoid unlocked access to v_numoutput/v_dirtyblkhd.

Found by lockdoc.

PR kern/57606
This commit is contained in:
riastradh 2023-09-08 23:21:55 +00:00
parent 9dbaa117f1
commit e4f01447d3
1 changed files with 21 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vfsops.c,v 1.381 2023/06/15 09:15:54 hannken Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.382 2023/09/08 23:21:55 riastradh 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.381 2023/06/15 09:15:54 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.382 2023/09/08 23:21:55 riastradh Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -2021,14 +2021,25 @@ ffs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
/*
* Force stale file system control information to be flushed.
*/
if (waitfor != MNT_LAZY && (ump->um_devvp->v_numoutput > 0 ||
!LIST_EMPTY(&ump->um_devvp->v_dirtyblkhd))) {
vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
if ((error = VOP_FSYNC(ump->um_devvp, cred,
(waitfor == MNT_WAIT ? FSYNC_WAIT : 0) | FSYNC_NOLOG,
0, 0)) != 0)
allerror = error;
VOP_UNLOCK(ump->um_devvp);
if (waitfor != MNT_LAZY) {
bool need_devvp_fsync;
mutex_enter(ump->um_devvp->v_interlock);
need_devvp_fsync = (ump->um_devvp->v_numoutput > 0 ||
!LIST_EMPTY(&ump->um_devvp->v_dirtyblkhd));
mutex_exit(ump->um_devvp->v_interlock);
if (need_devvp_fsync) {
int flags = FSYNC_NOLOG;
if (waitfor == MNT_WAIT)
flags |= FSYNC_WAIT;
vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
if ((error = VOP_FSYNC(ump->um_devvp, cred, flags, 0,
0)) != 0)
allerror = error;
VOP_UNLOCK(ump->um_devvp);
}
}
#if defined(QUOTA) || defined(QUOTA2)
qsync(mp);