Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs/lfs Prevent new dirops while we issue lfs_flush_dirops.



details:   https://anonhg.NetBSD.org/src/rev/316fa843adc5
branches:  trunk
changeset: 745126:316fa843adc5
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Feb 23 08:39:28 2020 +0000

description:
Prevent new dirops while we issue lfs_flush_dirops.

lfs_flush_dirops assumes (by KASSERT((ip->i_state & IN_ADIROP) == 0))
that vnodes on the dchain will not become involved in active dirops
even while holding no other locks (lfs_lock, v_interlock), so we must
set lfs_writer here.  All other callers already set lfs_writer.

We set fs->lfs_writer++ without explicitly doing lfs_writer_enter
because

(a) we already waited for the dirops to drain, and
(b) we hold lfs_lock and cannot drop it before setting lfs_writer.

diffstat:

 sys/ufs/lfs/lfs_bio.c |  9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diffs (33 lines):

diff -r ae0bd5f70b1f -r 316fa843adc5 sys/ufs/lfs/lfs_bio.c
--- a/sys/ufs/lfs/lfs_bio.c     Sun Feb 23 08:39:18 2020 +0000
+++ b/sys/ufs/lfs/lfs_bio.c     Sun Feb 23 08:39:28 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_bio.c,v 1.145 2020/02/18 20:23:17 chs Exp $        */
+/*     $NetBSD: lfs_bio.c,v 1.146 2020/02/23 08:39:28 riastradh Exp $  */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_bio.c,v 1.145 2020/02/18 20:23:17 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_bio.c,v 1.146 2020/02/23 08:39:28 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -653,9 +653,14 @@
        /* If there are too many pending dirops, we have to flush them. */
        if (fs->lfs_dirvcount > LFS_MAX_FSDIROP(fs) ||
            lfs_dirvcount > LFS_MAX_DIROP || fs->lfs_diropwait > 0) {
+               KASSERT(fs->lfs_dirops == 0);
+               fs->lfs_writer++;
                mutex_exit(&lfs_lock);
                lfs_flush_dirops(fs);
                mutex_enter(&lfs_lock);
+               if (--fs->lfs_writer == 0)
+                       cv_broadcast(&fs->lfs_diropscv);
+               KASSERT(fs->lfs_dirops == 0);
        } else if (locked_queue_count + INOCOUNT(fs) > LFS_MAX_BUFS ||
            locked_queue_bytes + INOBYTES(fs) > LFS_MAX_BYTES ||
            lfs_subsys_pages > LFS_MAX_PAGES ||



Home | Main Index | Thread Index | Old Index