Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Use a marker node to iterate lfs_dchainhd / i_lf...
details: https://anonhg.NetBSD.org/src/rev/5fe06b801832
branches: trunk
changeset: 745123:5fe06b801832
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Feb 23 08:38:58 2020 +0000
description:
Use a marker node to iterate lfs_dchainhd / i_lfs_dchain.
I believe elements can be removed while the lock is dropped,
including the next node we're hanging on to.
diffstat:
sys/ufs/lfs/lfs_inode.h | 3 ++-
sys/ufs/lfs/lfs_subr.c | 40 +++++++++++++++++++++++++++++++---------
sys/ufs/lfs/lfs_vnops.c | 32 +++++++++++++++++++++++++++-----
3 files changed, 60 insertions(+), 15 deletions(-)
diffs (189 lines):
diff -r c28793d20ff3 -r 5fe06b801832 sys/ufs/lfs/lfs_inode.h
--- a/sys/ufs/lfs/lfs_inode.h Sun Feb 23 07:17:01 2020 +0000
+++ b/sys/ufs/lfs/lfs_inode.h Sun Feb 23 08:38:58 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_inode.h,v 1.24 2020/02/18 20:23:17 chs Exp $ */
+/* $NetBSD: lfs_inode.h,v 1.25 2020/02/23 08:38:58 riastradh Exp $ */
/* from NetBSD: ulfs_inode.h,v 1.5 2013/06/06 00:51:50 dholland Exp */
/* from NetBSD: inode.h,v 1.72 2016/06/03 15:36:03 christos Exp */
@@ -123,6 +123,7 @@
/* unused 0x0400 */ /* was FFS-only IN_SPACECOUNTED */
#define IN_PAGING 0x1000 /* LFS: file is on paging queue */
#define IN_CDIROP 0x4000 /* LFS: dirop completed pending i/o */
+#define IN_MARKER 0x00010000 /* LFS: marker inode for iteration */
/* XXX this is missing some of the flags */
#define IN_ALLMOD (IN_MODIFIED|IN_ACCESS|IN_CHANGE|IN_UPDATE|IN_MODIFY|IN_ACCESSED|IN_CLEANING)
diff -r c28793d20ff3 -r 5fe06b801832 sys/ufs/lfs/lfs_subr.c
--- a/sys/ufs/lfs/lfs_subr.c Sun Feb 23 07:17:01 2020 +0000
+++ b/sys/ufs/lfs/lfs_subr.c Sun Feb 23 08:38:58 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_subr.c,v 1.97 2017/07/26 16:42:37 maya Exp $ */
+/* $NetBSD: lfs_subr.c,v 1.98 2020/02/23 08:38:58 riastradh Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_subr.c,v 1.97 2017/07/26 16:42:37 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_subr.c,v 1.98 2020/02/23 08:38:58 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -337,10 +337,14 @@
static void lfs_unmark_dirop(struct lfs *);
+static struct evcnt lfs_dchain_marker_pass_dirop =
+ EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "lfs", "dchain marker pass dirop");
+EVCNT_ATTACH_STATIC(lfs_dchain_marker_pass_dirop);
+
static void
lfs_unmark_dirop(struct lfs *fs)
{
- struct inode *ip, *nip;
+ struct inode *ip, *marker;
struct vnode *vp;
int doit;
@@ -349,13 +353,28 @@
doit = !(fs->lfs_flags & LFS_UNDIROP);
if (doit)
fs->lfs_flags |= LFS_UNDIROP;
- if (!doit) {
- mutex_exit(&lfs_lock);
+ mutex_exit(&lfs_lock);
+
+ if (!doit)
return;
- }
+
+ marker = pool_get(&lfs_inode_pool, PR_WAITOK);
+ KASSERT(fs != NULL);
+ memset(marker, 0, sizeof(*marker));
+ marker->inode_ext.lfs = pool_get(&lfs_inoext_pool, PR_WAITOK);
+ memset(marker->inode_ext.lfs, 0, sizeof(*marker->inode_ext.lfs));
+ marker->i_state |= IN_MARKER;
- for (ip = TAILQ_FIRST(&fs->lfs_dchainhd); ip != NULL; ip = nip) {
- nip = TAILQ_NEXT(ip, i_lfs_dchain);
+ mutex_enter(&lfs_lock);
+ TAILQ_INSERT_HEAD(&fs->lfs_dchainhd, marker, i_lfs_dchain);
+ while ((ip = TAILQ_NEXT(marker, i_lfs_dchain)) != NULL) {
+ TAILQ_REMOVE(&fs->lfs_dchainhd, marker, i_lfs_dchain);
+ TAILQ_INSERT_AFTER(&fs->lfs_dchainhd, ip, marker,
+ i_lfs_dchain);
+ if (ip->i_state & IN_MARKER) {
+ lfs_dchain_marker_pass_dirop.ev_count++;
+ continue;
+ }
vp = ITOV(ip);
if ((ip->i_state & (IN_ADIROP | IN_CDIROP)) == IN_CDIROP) {
--lfs_dirvcount;
@@ -371,10 +390,13 @@
ip->i_state &= ~IN_CDIROP;
}
}
-
+ TAILQ_REMOVE(&fs->lfs_dchainhd, marker, i_lfs_dchain);
fs->lfs_flags &= ~LFS_UNDIROP;
wakeup(&fs->lfs_flags);
mutex_exit(&lfs_lock);
+
+ pool_put(&lfs_inoext_pool, marker->inode_ext.lfs);
+ pool_put(&lfs_inode_pool, marker);
}
static void
diff -r c28793d20ff3 -r 5fe06b801832 sys/ufs/lfs/lfs_vnops.c
--- a/sys/ufs/lfs/lfs_vnops.c Sun Feb 23 07:17:01 2020 +0000
+++ b/sys/ufs/lfs/lfs_vnops.c Sun Feb 23 08:38:58 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_vnops.c,v 1.325 2019/09/18 17:59:15 christos Exp $ */
+/* $NetBSD: lfs_vnops.c,v 1.326 2020/02/23 08:38:58 riastradh Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -125,7 +125,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.325 2019/09/18 17:59:15 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.326 2020/02/23 08:38:58 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -1595,6 +1595,10 @@
return VOP_STRATEGY(vp, bp);
}
+static struct evcnt lfs_dchain_marker_pass_flush =
+ EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "lfs", "dchain marker pass flush");
+EVCNT_ATTACH_STATIC(lfs_dchain_marker_pass_flush);
+
/*
* Inline lfs_segwrite/lfs_writevnodes, but just for dirops.
* Technically this is a checkpoint (the on-disk state is valid)
@@ -1603,7 +1607,7 @@
int
lfs_flush_dirops(struct lfs *fs)
{
- struct inode *ip, *nip;
+ struct inode *ip, *marker;
struct vnode *vp;
extern int lfs_dostats; /* XXX this does not belong here */
struct segment *sp;
@@ -1627,6 +1631,12 @@
if (lfs_dostats)
++lfs_stats.flush_invoked;
+ marker = pool_get(&lfs_inode_pool, PR_WAITOK);
+ memset(marker, 0, sizeof(*marker));
+ marker->inode_ext.lfs = pool_get(&lfs_inoext_pool, PR_WAITOK);
+ memset(marker->inode_ext.lfs, 0, sizeof(*marker->inode_ext.lfs));
+ marker->i_state = IN_MARKER;
+
lfs_imtime(fs);
lfs_seglock(fs, flags);
sp = fs->lfs_sp;
@@ -1645,8 +1655,15 @@
*
*/
mutex_enter(&lfs_lock);
- for (ip = TAILQ_FIRST(&fs->lfs_dchainhd); ip != NULL; ip = nip) {
- nip = TAILQ_NEXT(ip, i_lfs_dchain);
+ TAILQ_INSERT_HEAD(&fs->lfs_dchainhd, marker, i_lfs_dchain);
+ while ((ip = TAILQ_NEXT(marker, i_lfs_dchain)) != NULL) {
+ TAILQ_REMOVE(&fs->lfs_dchainhd, marker, i_lfs_dchain);
+ TAILQ_INSERT_AFTER(&fs->lfs_dchainhd, ip, marker,
+ i_lfs_dchain);
+ if (ip->i_state & IN_MARKER) {
+ lfs_dchain_marker_pass_flush.ev_count++;
+ continue;
+ }
mutex_exit(&lfs_lock);
vp = ITOV(ip);
mutex_enter(vp->v_interlock);
@@ -1705,7 +1722,9 @@
/* XXX only for non-directories? --KS */
LFS_SET_UINO(ip, IN_MODIFIED);
}
+ TAILQ_REMOVE(&fs->lfs_dchainhd, marker, i_lfs_dchain);
mutex_exit(&lfs_lock);
+
/* We've written all the dirops there are */
ssp = (SEGSUM *)sp->segsum;
lfs_ss_setflags(fs, ssp, lfs_ss_getflags(fs, ssp) & ~(SS_CONT));
@@ -1713,6 +1732,9 @@
(void) lfs_writeseg(fs, sp);
lfs_segunlock(fs);
+ pool_put(&lfs_inoext_pool, marker->inode_ext.lfs);
+ pool_put(&lfs_inode_pool, marker);
+
return error;
}
Home |
Main Index |
Thread Index |
Old Index