diff options
| author | ad <ad@NetBSD.org> | 2008-05-31 21:37:08 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2008-05-31 21:37:08 +0000 |
| commit | 3592ae48827b6de1c8a4ef15971f5080fecd141a (patch) | |
| tree | e299f4a0116884a12008d827b0c64fcbd5621ad9 /sys | |
| parent | 736a4d9b7870c657841320ebee34cd39d1c751e5 (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.c | 19 | ||||
| -rw-r--r-- | sys/ufs/ffs/ffs_softdep.stub.c | 11 | ||||
| -rw-r--r-- | sys/ufs/ufs/ufs_extern.h | 3 | ||||
| -rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 22 |
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); } |
