Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Fixed lfs_update (and related functions) so that...
details: https://anonhg.NetBSD.org/src/rev/c59783d643b2
branches: trunk
changeset: 473390:c59783d643b2
user: perseant <perseant%NetBSD.org@localhost>
date: Tue Jun 01 03:00:40 1999 +0000
description:
Fixed lfs_update (and related functions) so that calls from lfs_fsync
will DTRT with vnodes marked VDIROP. In particular, the message
"flushing VDIROP" will no longer appear, and the filesystem will remain
stable in the event of a crash.
This was particularly a problem with NFS-exported LFSes, since fsync
was called on every file close.
diffstat:
sys/ufs/lfs/lfs.h | 3 +-
sys/ufs/lfs/lfs_bio.c | 66 ++++++++++++++++++++++++++---------------------
sys/ufs/lfs/lfs_extern.h | 3 +-
sys/ufs/lfs/lfs_inode.c | 24 +++++++++++++++--
sys/ufs/lfs/lfs_vfsops.c | 4 +-
5 files changed, 64 insertions(+), 36 deletions(-)
diffs (218 lines):
diff -r 8c62c0434e4c -r c59783d643b2 sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Tue Jun 01 02:39:25 1999 +0000
+++ b/sys/ufs/lfs/lfs.h Tue Jun 01 03:00:40 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs.h,v 1.14 1999/03/25 21:39:18 perseant Exp $ */
+/* $NetBSD: lfs.h,v 1.15 1999/06/01 03:00:40 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -315,6 +315,7 @@
daddr_t lfs_sbactive; /* disk address of in-progress sb write */
#endif
struct vnode *lfs_flushvp; /* vnode being flushed */
+ u_int32_t lfs_diropwait; /* # procs waiting on dirop flush */
};
/*
diff -r 8c62c0434e4c -r c59783d643b2 sys/ufs/lfs/lfs_bio.c
--- a/sys/ufs/lfs/lfs_bio.c Tue Jun 01 02:39:25 1999 +0000
+++ b/sys/ufs/lfs/lfs_bio.c Tue Jun 01 03:00:40 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_bio.c,v 1.10 1999/04/12 00:36:47 perseant Exp $ */
+/* $NetBSD: lfs_bio.c,v 1.11 1999/06/01 03:00:40 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -267,6 +267,38 @@
return (0);
}
+void lfs_flush_fs(mp, flags)
+ struct mount *mp;
+ int flags;
+{
+ struct lfs *lfsp;
+
+ lfsp = ((struct ufsmount *)mp->mnt_data)->ufsmount_u.lfs;
+ if((mp->mnt_flag & MNT_RDONLY) == 0 &&
+ lfsp->lfs_dirops==0)
+ {
+ /* disallow dirops during flush */
+ lfsp->lfs_writer++;
+
+ /*
+ * We set the queue to 0 here because we
+ * are about to write all the dirty
+ * buffers we have. If more come in
+ * while we're writing the segment, they
+ * may not get written, so we want the
+ * count to reflect these new writes
+ * after the segwrite completes.
+ */
+ if(lfs_dostats)
+ ++lfs_stats.flush_invoked;
+ lfs_segwrite(mp, flags);
+
+ /* XXX KS - allow dirops again */
+ if(--lfsp->lfs_writer==0)
+ wakeup(&lfsp->lfs_dirops);
+ }
+}
+
/*
* XXX
* This routine flushes buffers out of the B_LOCKED queue when LFS has too
@@ -281,7 +313,6 @@
int flags;
{
register struct mount *mp, *nmp;
- struct lfs *lfsp;
if(lfs_dostats)
++lfs_stats.write_exceeded;
@@ -296,32 +327,7 @@
continue;
}
if (strncmp(&mp->mnt_stat.f_fstypename[0], MOUNT_LFS, MFSNAMELEN)==0)
- {
- lfsp = ((struct ufsmount *)mp->mnt_data)->ufsmount_u.lfs;
- if((mp->mnt_flag & MNT_RDONLY) == 0 &&
- lfsp->lfs_dirops==0)
- {
- /* disallow dirops during flush */
- lfsp->lfs_writer++;
-
- /*
- * We set the queue to 0 here because we
- * are about to write all the dirty
- * buffers we have. If more come in
- * while we're writing the segment, they
- * may not get written, so we want the
- * count to reflect these new writes
- * after the segwrite completes.
- */
- if(lfs_dostats)
- ++lfs_stats.flush_invoked;
- lfs_segwrite(mp, flags);
-
- /* XXX KS - allow dirops again */
- if(--lfsp->lfs_writer==0)
- wakeup(&lfsp->lfs_dirops);
- }
- }
+ lfs_flush_fs(mp, flags);
simple_lock(&mountlist_slock);
nmp = mp->mnt_list.cqe_next;
vfs_unbusy(mp);
@@ -359,13 +365,15 @@
if (locked_queue_count > LFS_MAX_BUFS
|| locked_queue_bytes > LFS_MAX_BYTES
- || fs->lfs_dirvcount > LFS_MAXDIROP)
+ || fs->lfs_dirvcount > LFS_MAXDIROP
+ || fs->lfs_diropwait > 0)
{
++fs->lfs_writer;
lfs_flush(fs, flags);
if(--fs->lfs_writer==0)
wakeup(&fs->lfs_dirops);
}
+
while (locked_queue_count > LFS_WAIT_BUFS
|| locked_queue_bytes > LFS_WAIT_BYTES)
{
diff -r 8c62c0434e4c -r c59783d643b2 sys/ufs/lfs/lfs_extern.h
--- a/sys/ufs/lfs/lfs_extern.h Tue Jun 01 02:39:25 1999 +0000
+++ b/sys/ufs/lfs/lfs_extern.h Tue Jun 01 03:00:40 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_extern.h,v 1.13 1999/03/10 00:20:00 perseant Exp $ */
+/* $NetBSD: lfs_extern.h,v 1.14 1999/06/01 03:00:40 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -115,6 +115,7 @@
/* lfs_bio.c */
int lfs_bwrite_ext __P((struct buf *, int));
+void lfs_flush_fs __P((struct mount *, int));
void lfs_flush __P((struct lfs *, int));
int lfs_check __P((struct vnode *, ufs_daddr_t, int));
void lfs_freebuf __P((struct buf *));
diff -r 8c62c0434e4c -r c59783d643b2 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c Tue Jun 01 02:39:25 1999 +0000
+++ b/sys/ufs/lfs/lfs_inode.c Tue Jun 01 03:00:40 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_inode.c,v 1.24 1999/04/12 00:30:08 perseant Exp $ */
+/* $NetBSD: lfs_inode.c,v 1.25 1999/06/01 03:00:40 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -128,6 +128,7 @@
struct vnode *vp = ap->a_vp;
int mod, oflag;
struct timespec ts;
+ struct lfs *fs = VFSTOUFS(vp->v_mount)->um_lfs;
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (0);
@@ -142,7 +143,7 @@
*/
while((ap->a_waitfor & LFS_SYNC) && WRITEINPROG(vp)) {
#ifdef DEBUG_LFS
- printf("lfs_update: sleeping on inode %d\n",ip->i_number);
+ printf("lfs_update: sleeping on inode %d (in-progress)\n",ip->i_number);
#endif
tsleep(vp, (PRIBIO+1), "lfs_update", 0);
}
@@ -159,7 +160,24 @@
}
/* If sync, push back the vnode and any dirty blocks it may have. */
- return (ap->a_waitfor & LFS_SYNC ? lfs_vflush(vp) : 0);
+ if(ap->a_waitfor & LFS_SYNC) {
+ /* Avoid flushing VDIROP. */
+ ++fs->lfs_diropwait;
+ while(vp->v_flag & VDIROP) {
+#ifdef DEBUG_LFS
+ printf("lfs_update: sleeping on inode %d (dirops)\n",ip->i_number);
+#endif
+ if(fs->lfs_dirops==0)
+ lfs_flush_fs(vp->v_mount,0);
+ else
+ tsleep(&fs->lfs_writer, PRIBIO+1, "lfs_fsync", 0);
+ /* XXX KS - by falling out here, are we writing the vn
+ twice? */
+ }
+ --fs->lfs_diropwait;
+ return lfs_vflush(vp);
+ }
+ return 0;
}
/* Update segment usage information when removing a block. */
diff -r 8c62c0434e4c -r c59783d643b2 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c Tue Jun 01 02:39:25 1999 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c Tue Jun 01 03:00:40 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_vfsops.c,v 1.33 1999/05/04 00:35:37 scottr Exp $ */
+/* $NetBSD: lfs_vfsops.c,v 1.34 1999/06/01 03:00:40 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -71,7 +71,6 @@
*/
#if defined(_KERNEL) && !defined(_LKM)
-#include "opt_ddb.h"
#include "opt_quota.h"
#endif
@@ -395,6 +394,7 @@
/* Set up the I/O information */
fs->lfs_iocount = 0;
fs->lfs_dirvcount = 0;
+ fs->lfs_diropwait = 0;
fs->lfs_activesb = 0;
#ifdef LFS_CANNOT_ROLLFW
fs->lfs_sbactive = NULL;
Home |
Main Index |
Thread Index |
Old Index