summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorad <ad@NetBSD.org>2008-05-31 21:37:08 +0000
committerad <ad@NetBSD.org>2008-05-31 21:37:08 +0000
commit3592ae48827b6de1c8a4ef15971f5080fecd141a (patch)
treee299f4a0116884a12008d827b0c64fcbd5621ad9 /sys
parent736a4d9b7870c657841320ebee34cd39d1c751e5 (diff)
XXX softdep:
If the number of deletes in progress is getting too high, newdirrem() requests the syncer to flush faster, and in some cases will block to prevent deletes accumulating faster than the disk can service them. The syncer will try to lock vnodes that the remover holds locked, leading to the syncer and remover proceeding in lockstep and making very little overall forward progress. Put a hook into ufs_rmdir() and ufs_remove() so that the softdep code can pace itself without holding vnode locks if the number of deletes is running out of control.
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c19
-rw-r--r--sys/ufs/ffs/ffs_softdep.stub.c11
-rw-r--r--sys/ufs/ufs/ufs_extern.h3
-rw-r--r--sys/ufs/ufs/ufs_vnops.c22
4 files changed, 48 insertions, 7 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 72dee0c4a31..744b812634f 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_softdep.c,v 1.112 2008/05/16 09:22:00 hannken Exp $ */
+/* $NetBSD: ffs_softdep.c,v 1.113 2008/05/31 21:37:08 ad Exp $ */
/*
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.c,v 1.112 2008/05/16 09:22:00 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.c,v 1.113 2008/05/31 21:37:08 ad Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -2948,6 +2948,21 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
return (dirrem);
}
+void
+softdep_pace_dirrem(void)
+{
+ int limit;
+
+ limit = max_softdeps >> 1;
+ if (num_dirrem <= limit)
+ return;
+
+ mutex_enter(&bufcache_lock);
+ if (num_dirrem > limit)
+ (void)cv_timedwait(&proc_wait_cv, &bufcache_lock, tickdelay);
+ mutex_exit(&bufcache_lock);
+}
+
/*
* Directory entry change dependencies.
*
diff --git a/sys/ufs/ffs/ffs_softdep.stub.c b/sys/ufs/ffs/ffs_softdep.stub.c
index b1fd1c2080d..bf3ea2ea23a 100644
--- a/sys/ufs/ffs/ffs_softdep.stub.c
+++ b/sys/ufs/ffs/ffs_softdep.stub.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_softdep.stub.c,v 1.22 2008/01/02 11:49:09 ad Exp $ */
+/* $NetBSD: ffs_softdep.stub.c,v 1.23 2008/05/31 21:37:08 ad Exp $ */
/*
* Copyright 1997 Marshall Kirk McKusick. All Rights Reserved.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.stub.c,v 1.22 2008/01/02 11:49:09 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.stub.c,v 1.23 2008/05/31 21:37:08 ad Exp $");
#include <sys/param.h>
#include <sys/vnode.h>
@@ -221,3 +221,10 @@ softdep_unmount(struct mount *mp)
return;
}
+
+void
+softdep_pace_dirrem(void)
+{
+
+ panic("softdep_pace_dirrem called");
+}
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index 273bdf63244..d0d1967dea3 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_extern.h,v 1.59 2008/05/16 09:22:01 hannken Exp $ */
+/* $NetBSD: ufs_extern.h,v 1.60 2008/05/31 21:37:08 ad Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -184,6 +184,7 @@ void softdep_setup_directory_change(struct buf *, struct inode *,
struct inode *, ino_t, int);
void softdep_change_linkcnt(struct inode *);
void softdep_releasefile(struct inode *);
+void softdep_pace_dirrem(void);
__END_DECLS
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 7d32294842d..c6c64e17c7e 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_vnops.c,v 1.164 2008/01/30 09:50:27 ad Exp $ */
+/* $NetBSD: ufs_vnops.c,v 1.165 2008/05/31 21:37:08 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993, 1995
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.164 2008/01/30 09:50:27 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.165 2008/05/31 21:37:08 ad Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -642,6 +642,7 @@ ufs_remove(void *v)
struct vnode *vp, *dvp;
struct inode *ip;
int error;
+ bool pace;
vp = ap->a_vp;
dvp = ap->a_dvp;
@@ -658,8 +659,16 @@ ufs_remove(void *v)
vrele(vp);
else
vput(vp);
+ pace = DOINGSOFTDEP(dvp);
vput(dvp);
fstrans_done(dvp->v_mount);
+ if (pace) {
+ /*
+ * Give the syncer some breathing room so that it
+ * can flush removes. XXX
+ */
+ softdep_pace_dirrem();
+ }
return (error);
}
@@ -1447,6 +1456,7 @@ ufs_rmdir(void *v)
struct componentname *cnp;
struct inode *ip, *dp;
int error;
+ bool pace;
vp = ap->a_vp;
dvp = ap->a_dvp;
@@ -1537,8 +1547,16 @@ ufs_rmdir(void *v)
out:
VN_KNOTE(vp, NOTE_DELETE);
fstrans_done(dvp->v_mount);
+ pace = DOINGSOFTDEP(dvp);
vput(dvp);
vput(vp);
+ if (pace) {
+ /*
+ * Give the syncer some breathing room so that it
+ * can flush removes. XXX
+ */
+ softdep_pace_dirrem();
+ }
return (error);
}