- add a new functions, lfs_writer_enter/leave, and use them instead of

duplicated code fragments.
- add an assertion.
This commit is contained in:
yamt 2003-07-02 13:40:51 +00:00
parent f3506a9599
commit 102c8a6a74
7 changed files with 84 additions and 68 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs.h,v 1.64 2003/04/23 07:20:37 perseant Exp $ */
/* $NetBSD: lfs.h,v 1.65 2003/07/02 13:40:51 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -977,4 +977,10 @@ struct lfs_fcntl_markv {
#define LFCNMARKV _FCNRW_FSPRIV('L', 3, struct lfs_fcntl_markv)
#define LFCNRECLAIM _FCNO_FSPRIV('L', 4)
#ifdef _KERNEL
/* XXX MP */
#define LFS_SEGLOCK_HELD(fs) \
((fs)->lfs_seglock != 0 && (fs)->lfs_lockpid == curproc->p_pid)
#endif /* _KERNEL */
#endif /* !_UFS_LFS_LFS_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_bio.c,v 1.66 2003/04/27 04:18:29 perseant Exp $ */
/* $NetBSD: lfs_bio.c,v 1.67 2003/07/02 13:40:52 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_bio.c,v 1.66 2003/04/27 04:18:29 perseant Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_bio.c,v 1.67 2003/07/02 13:40:52 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -160,10 +160,7 @@ lfs_reservebuf(struct lfs *fs, struct vnode *vp, struct vnode *vp2,
while (n > 0 && !lfs_fits_buf(fs, n, bytes)) {
int error;
++fs->lfs_writer;
lfs_flush(fs, 0);
if (--fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
error = tsleep(&locked_queue_count, PCATCH | PUSER,
"lfsresbuf", hz * LFS_BUFWAIT);
@ -482,23 +479,13 @@ lfs_flush_fs(struct lfs *fs, int flags)
if (fs->lfs_ronly)
return;
/* disallow dirops during flush */
fs->lfs_writer++;
/* drain dirops */
while (fs->lfs_dirops > 0) {
++fs->lfs_diropwait;
tsleep(&fs->lfs_writer, PRIBIO+1, "fldirop", 0);
--fs->lfs_diropwait;
}
lfs_writer_enter(fs, "fldirop");
if (lfs_dostats)
++lfs_stats.flush_invoked;
lfs_segwrite(fs->lfs_ivnode->v_mount, flags);
/* allow dirops again */
if (--fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
lfs_writer_leave(fs);
}
/*
@ -513,6 +500,8 @@ void
lfs_flush(struct lfs *fs, int flags)
{
struct mount *mp, *nmp;
KDASSERT(fs == NULL || !LFS_SEGLOCK_HELD(fs));
if (lfs_dostats)
++lfs_stats.write_exceeded;

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_extern.h,v 1.50 2003/06/29 22:32:38 fvdl Exp $ */
/* $NetBSD: lfs_extern.h,v 1.51 2003/07/02 13:40:52 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -190,6 +190,8 @@ void *lfs_malloc(struct lfs *, size_t, int);
void lfs_free(struct lfs *, void *, int);
int lfs_seglock(struct lfs *, unsigned long);
void lfs_segunlock(struct lfs *);
int lfs_writer_enter(struct lfs *, const char *);
void lfs_writer_leave(struct lfs *);
/* lfs_syscalls.c */
int lfs_fastvget(struct mount *, ino_t, daddr_t, struct vnode **, struct ufs1_dinode *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_segment.c,v 1.124 2003/06/29 22:32:39 fvdl Exp $ */
/* $NetBSD: lfs_segment.c,v 1.125 2003/07/02 13:40:52 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.124 2003/06/29 22:32:39 fvdl Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.125 2003/07/02 13:40:52 yamt Exp $");
#define ivndebug(vp,str) printf("ino %d: %s\n",VTOI(vp)->i_number,(str))
@ -583,19 +583,16 @@ lfs_segwrite(struct mount *mp, int flags)
else if (!(sp->seg_flags & SEGM_FORCE_CKP)) {
lfs_writevnodes(fs, mp, sp, VN_REG);
if (!fs->lfs_dirops || !fs->lfs_flushvp) {
while (fs->lfs_dirops)
if ((error = tsleep(&fs->lfs_writer, PRIBIO + 1,
"lfs writer", 0)))
{
printf("segwrite mysterious error\n");
/* XXX why not segunlock? */
pool_put(&fs->lfs_bpppool, sp->bpp);
sp->bpp = NULL;
pool_put(&fs->lfs_segpool, sp);
sp = fs->lfs_sp = NULL;
return (error);
}
fs->lfs_writer++;
error = lfs_writer_enter(fs, "lfs writer");
if (error) {
printf("segwrite mysterious error\n");
/* XXX why not segunlock? */
pool_put(&fs->lfs_bpppool, sp->bpp);
sp->bpp = NULL;
pool_put(&fs->lfs_segpool, sp);
sp = fs->lfs_sp = NULL;
return (error);
}
writer_set = 1;
lfs_writevnodes(fs, mp, sp, VN_DIROP);
((SEGSUM *)(sp->segsum))->ss_flags &= ~(SS_CONT);
@ -694,8 +691,8 @@ lfs_segwrite(struct mount *mp, int flags)
/* Note Ifile no longer needs to be written */
fs->lfs_doifile = 0;
if (writer_set && --fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
if (writer_set)
lfs_writer_leave(fs);
/*
* If we didn't write the Ifile, we didn't really do anything.

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_subr.c,v 1.40 2003/04/23 07:20:38 perseant Exp $ */
/* $NetBSD: lfs_subr.c,v 1.41 2003/07/02 13:40:53 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_subr.c,v 1.40 2003/04/23 07:20:38 perseant Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_subr.c,v 1.41 2003/07/02 13:40:53 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -545,3 +545,43 @@ lfs_segunlock(struct lfs *fs)
simple_unlock(&fs->lfs_interlock);
}
}
/*
* drain dirops and start writer.
*/
int
lfs_writer_enter(struct lfs *fs, const char *wmesg)
{
int error = 0;
simple_lock(&fs->lfs_interlock);
/* disallow dirops during flush */
fs->lfs_writer++;
while (fs->lfs_dirops > 0) {
++fs->lfs_diropwait;
error = ltsleep(&fs->lfs_writer, PRIBIO+1, wmesg, 0,
&fs->lfs_interlock);
--fs->lfs_diropwait;
}
if (error)
fs->lfs_writer--;
simple_unlock(&fs->lfs_interlock);
return error;
}
void
lfs_writer_leave(struct lfs *fs)
{
boolean_t dowakeup;
simple_lock(&fs->lfs_interlock);
dowakeup = !(--fs->lfs_writer);
simple_unlock(&fs->lfs_interlock);
if (dowakeup)
wakeup(&fs->lfs_dirops);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vfsops.c,v 1.121 2003/06/29 22:32:41 fvdl Exp $ */
/* $NetBSD: lfs_vfsops.c,v 1.122 2003/07/02 13:40:53 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.121 2003/06/29 22:32:41 fvdl Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.122 2003/07/02 13:40:53 yamt Exp $");
#if defined(_KERNEL_OPT)
#include "opt_quota.h"
@ -852,10 +852,9 @@ check_segsum(struct lfs *fs, daddr_t offset,
/* Don't clog the buffer queue */
if (locked_queue_count > LFS_MAX_BUFS ||
locked_queue_bytes > LFS_MAX_BYTES) {
++fs->lfs_writer;
lfs_writer_enter(fs, "cssdirop");
lfs_flush(fs, SEGM_CKP);
if (--fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
lfs_writer_leave(fs);
}
}
@ -1477,14 +1476,11 @@ lfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
fs = ((struct ufsmount *)mp->mnt_data)->ufsmount_u.lfs;
if (fs->lfs_ronly)
return 0;
while (fs->lfs_dirops)
error = tsleep(&fs->lfs_writer, PRIBIO + 1, "lfs_dirops", 0);
fs->lfs_writer++;
lfs_writer_enter(fs, "lfs_dirops");
/* All syncs must be checkpoints until roll-forward is implemented. */
error = lfs_segwrite(mp, SEGM_CKP | (waitfor ? SEGM_SYNC : 0));
if (--fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
lfs_writer_leave(fs);
#ifdef QUOTA
qsync(mp);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vnops.c,v 1.110 2003/07/02 13:39:03 yamt Exp $ */
/* $NetBSD: lfs_vnops.c,v 1.111 2003/07/02 13:40:54 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.110 2003/07/02 13:39:03 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.111 2003/07/02 13:40:54 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -1279,14 +1279,7 @@ lfs_fcntl(void *v)
* Flush dirops and write Ifile, allowing empty segments
* to be immediately reclaimed.
*/
/* XXX simplelock fs->lfs_dirops */
while (fs->lfs_dirops > 0) {
++fs->lfs_diropwait;
tsleep(&fs->lfs_writer, PRIBIO+1, "pndirop", 0);
--fs->lfs_diropwait;
}
/* disallow dirops during flush */
fs->lfs_writer++;
lfs_writer_enter(fs, "pndirop");
off = fs->lfs_offset;
lfs_seglock(fs, SEGM_FORCE_CKP | SEGM_CKP);
lfs_flush_dirops(fs);
@ -1295,8 +1288,7 @@ lfs_fcntl(void *v)
LFS_SYNC_CLEANERINFO(cip, fs, bp, 1);
lfs_segwrite(ap->a_vp->v_mount, SEGM_FORCE_CKP);
lfs_segunlock(fs);
if (--fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
lfs_writer_leave(fs);
#ifdef DEBUG_LFS
LFS_CLEANERINFO(cip, fs, bp);
@ -1690,12 +1682,7 @@ lfs_putpages(void *v)
int locked;
/* printf("putpages to clean VDIROP, flushing\n"); */
while (fs->lfs_dirops > 0) {
++fs->lfs_diropwait;
tsleep(&fs->lfs_writer, PRIBIO+1, "ppdirop", 0);
--fs->lfs_diropwait;
}
++fs->lfs_writer;
lfs_writer_enter(fs, "ppdirop");
locked = VOP_ISLOCKED(vp) && /* XXX */
vp->v_lock.lk_lockholder == curproc->p_pid;
if (locked)
@ -1707,8 +1694,7 @@ lfs_putpages(void *v)
simple_lock(&vp->v_interlock);
if (locked)
VOP_LOCK(vp, LK_EXCLUSIVE);
if (--fs->lfs_writer == 0)
wakeup(&fs->lfs_dirops);
lfs_writer_leave(fs);
/* XXX the flush should have taken care of this one too! */
}