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.
This commit is contained in:
parent
736a4d9b78
commit
3592ae4882
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue