Subject: Now: Fs suspension take 2
To: Bill Studenmund <wrstuden@netbsd.org>
From: Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
List: tech-kern
Date: 08/03/2006 16:11:29
--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Wed, Jul 05, 2006 at 10:30:32AM -0700, Bill Studenmund wrote:
> On Tue, Jul 04, 2006 at 04:23:55PM +0200, Juergen Hannken-Illjes wrote:
> > On Mon, Jul 03, 2006 at 03:51:35PM -0700, Jason Thorpe wrote:
[snip]
> > 2) Put all gates inside the file systems as
>
> My preference.
Ok, the attached diff puts transaction locks so we can suspend ffs file systems.
- The fstrans implementation goes to files sys/fstrans.h and kern/vfs_trans.c.
- Add new VFS operation VFS_SUSPENDCTL(MP, C) to request a file system to
suspend/resume.
- Transaction locks are used if mnt_iflag has IMNT_HAS_TRANS. Otherwise the
current (vn_start_write) are used. With this diff IMNT_HAS_TRANS gets
set for ffs type file systems if kernel option NEWVNGATE is set.
- The ufs_lock/ufs_unlock part may look strange but it is ok to ignore
vnode lock requests for the thread currently suspending.
- I left the throttling part of my first attempt because it is only needed
for multiple softdep enabled file systems on the same disk. This problem
should be solved by a congestion control inside softdep.
--
Juergen Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)
--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="Current.diff"
Index: sys/sys/fstrans.h
--- /dev/null 2006-07-30 17:17:49.000000000 +0200
+++ sys/sys/fstrans.h 2006-07-28 16:53:32.000000000 +0200
@@ -0,0 +1,64 @@
+/* $NetBSD: Exp $ */
+
+/*-
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * File system transaction operations.
+ */
+
+#ifndef _SYS_FSTRANS_H_
+#define _SYS_FSTRANS_H_
+
+#define FSTRANS_NOWAIT 0x0001 /* fstrans_*: no wait */
+#define FSTRANS_SHARED 0x0002 /* fstrans_*: shared lock */
+#define FSTRANS_EXCL 0x0004 /* fstrans_*: exclusive lock */
+
+#define SUSPEND_SUSPEND 0x0001 /* VFS_SUSPENDCTL: suspend */
+#define SUSPEND_RESUME 0x0002 /* VFS_SUSPENDCTL: resume */
+
+int fstrans_start(struct mount *, int);
+void fstrans_done(struct mount *);
+int fstrans_status(struct mount *, int);
+void fstrans_exit(struct lwp *);
+#ifdef DEBUG
+void fstrans_list_all(void);
+#endif
+
+int vfs_suspend(struct mount *, int);
+void vfs_resume(struct mount *);
+
+#endif /* _SYS_FSTRANS_H_ */
Index: sys/sys/fstypes.h
===================================================================
RCS file: /cvsroot/src/sys/sys/fstypes.h,v
retrieving revision 1.12
diff -p -u -4 -r1.12 fstypes.h
--- sys/sys/fstypes.h 14 Jul 2006 18:30:35 -0000 1.12
+++ sys/sys/fstypes.h 30 Jul 2006 16:54:08 -0000
@@ -205,8 +205,9 @@ typedef struct fhandle fhandle_t;
#define IMNT_SUSPEND 0x00000008 /* request upper write suspension */
#define IMNT_SUSPENDLOW 0x00000010 /* request lower write suspension */
#define IMNT_SUSPENDED 0x00000020 /* write operations are suspended */
#define IMNT_DTYPE 0x00000040 /* returns d_type fields */
+#define IMNT_HAS_TRANS 0x00000080 /* supports transactions */
#define __MNT_FLAGS \
__MNT_BASIC_FLAGS \
__MNT_EXPORTED_FLAGS \
@@ -249,8 +250,9 @@ typedef struct fhandle fhandle_t;
"\01MNT_RDONLY"
#define __IMNT_FLAG_BITS \
"\20" \
+ "\10IMNT_HAS_TRANS" \
"\07IMNT_DTYPE" \
"\06IMNT_SUSPENDED" \
"\05IMNT_SUSPENDLOW" \
"\04IMNT_SUSPEND" \
Index: sys/sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.40
diff -p -u -4 -r1.40 lwp.h
--- sys/sys/lwp.h 20 Jul 2006 00:17:10 -0000 1.40
+++ sys/sys/lwp.h 30 Jul 2006 16:54:09 -0000
@@ -74,8 +74,9 @@ struct lwp {
int l_holdcnt; /* If non-zero, don't swap. */
void *l_ctxlink; /* uc_link {get,set}context */
int l_dupfd; /* Sideways return value from cloning devices XXX */
struct sadata_vp *l_savp; /* SA "virtual processor" */
+ void *l_vntrans; /* vn_trans private data */
int l_locks; /* DEBUG: lockmgr count of held locks */
void *l_private; /* svr4-style lwp-private data */
Index: sys/sys/mount.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mount.h,v
retrieving revision 1.146
diff -p -u -4 -r1.146 mount.h
--- sys/sys/mount.h 14 Jul 2006 18:29:40 -0000 1.146
+++ sys/sys/mount.h 30 Jul 2006 16:54:09 -0000
@@ -97,8 +97,9 @@ struct mount {
struct vnode *mnt_vnodecovered; /* vnode we mounted on */
struct vnode *mnt_syncer; /* syncer vnode */
struct vnodelst mnt_vnodelist; /* list of vnodes this mount */
struct lock mnt_lock; /* mount structure lock */
+ struct lock mnt_trans_lock; /* mount transaction lock */
int mnt_flag; /* flags */
int mnt_iflag; /* internal flags */
int mnt_fs_bshift; /* offset shift for lblkno */
int mnt_dev_bshift; /* shift for device sectors */
@@ -208,8 +209,9 @@ struct vfsops {
struct timespec *);
int (*vfs_extattrctl) (struct mount *, int,
struct vnode *, int, const char *,
struct lwp *);
+ int (*vfs_suspendctl) (struct mount *, int);
const struct vnodeopv_desc * const *vfs_opv_descs;
int vfs_refcount;
LIST_ENTRY(vfsops) vfs_list;
};
@@ -229,8 +231,9 @@ struct vfsops {
#define VFS_VPTOFH(VP, FIDP, FIDSZP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP, FIDSZP)
#define VFS_SNAPSHOT(MP, VP, TS) (*(MP)->mnt_op->vfs_snapshot)(MP, VP, TS)
#define VFS_EXTATTRCTL(MP, C, VP, AS, AN, L) \
(*(MP)->mnt_op->vfs_extattrctl)(MP, C, VP, AS, AN, L)
+#define VFS_SUSPENDCTL(MP, C) (*(MP)->mnt_op->vfs_suspendctl)(MP, C)
struct vfs_hooks {
void (*vh_unmount)(struct mount *);
};
@@ -289,8 +292,9 @@ void vfs_reinit(void);
struct vfsops *vfs_getopsbyname(const char *);
int vfs_stdextattrctl(struct mount *, int, struct vnode *,
int, const char *, struct lwp *);
+int vfs_stdsuspendctl(struct mount *, int);
extern CIRCLEQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */
extern struct vfsops *vfssw[]; /* filesystem type table */
extern int nvfssw;
Index: sys/sys/vnode.h
===================================================================
RCS file: /cvsroot/src/sys/sys/vnode.h,v
retrieving revision 1.155
diff -p -u -4 -r1.155 vnode.h
--- sys/sys/vnode.h 23 Jun 2006 14:13:02 -0000 1.155
+++ sys/sys/vnode.h 30 Jul 2006 16:54:09 -0000
@@ -493,17 +493,8 @@ struct vop_generic_args {
#define VDESC(OP) (& __CONCAT(OP,_desc))
#define VOFFSET(OP) (VDESC(OP)->vdesc_offset)
/*
- * Functions to gate filesystem write operations. Declared static inline
- * here because they usually go into time critical code paths.
- */
-#include <sys/mount.h>
-
-int vn_start_write(struct vnode *, struct mount **, int);
-void vn_finished_write(struct mount *, int);
-
-/*
* Finally, include the default set of vnode operations.
*/
#include <sys/vnode_if.h>
@@ -571,8 +562,10 @@ int vn_cow_establish(struct vnode *, int
void *);
int vn_cow_disestablish(struct vnode *, int (*)(void *, struct buf *),
void *);
void vn_ra_allocctx(struct vnode *);
+int vn_start_write(struct vnode *, struct mount **, int);
+void vn_finished_write(struct mount *, int);
/* initialise global vnode management */
void vntblinit(void);
@@ -586,10 +579,8 @@ int getvnode(struct filedesc *, int, str
/* see vfssubr(9) */
void vfs_getnewfsid(struct mount *);
int vfs_drainvnodes(long target, struct lwp *);
-void vfs_write_resume(struct mount *);
-int vfs_write_suspend(struct mount *, int, int);
void vfs_timestamp(struct timespec *);
#ifdef DDB
void vfs_vnode_print(struct vnode *, int, void (*)(const char *, ...));
void vfs_mount_print(struct mount *, int, void (*)(const char *, ...));
Index: sys/kern/vfs_trans.c
--- /dev/null 2006-07-30 17:17:49.000000000 +0200
+++ sys/kern/vfs_trans.c 2006-07-30 17:51:51.000000000 +0200
@@ -0,0 +1,322 @@
+/* $NetBSD: Exp $ */
+
+/*-
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: $");
+
+/*
+ * File system transaction operations.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/fstrans.h>
+
+#include <miscfs/syncfs/syncfs.h>
+
+struct fstrans_entry {
+ struct fstrans_entry *fte_succ;
+ struct mount *fte_mount;
+ int fte_count;
+ int fte_flags;
+};
+
+static struct lock vfs_suspend_lock = /* Serialize suspensions. */
+ LOCK_INITIALIZER(PUSER, "suspwt", 0, 0);
+
+POOL_INIT(fstrans_pl, sizeof(struct fstrans_entry), 0, 0, 0, "vntrans", NULL);
+
+/*
+ * Clear transition locks on thread exit.
+ */
+void
+fstrans_exit(struct lwp *l)
+{
+ struct fstrans_entry *fte, *ftn;
+
+ for (fte = l->l_vntrans; fte; fte = ftn) {
+ KASSERT(fte->fte_mount == NULL);
+ KASSERT(fte->fte_count == 0);
+ ftn = fte->fte_succ;
+ pool_put(&fstrans_pl, fte);
+ }
+}
+
+/*
+ * Start a transaction. If this thread already has a transaction on this
+ * file system increment the reference counter.
+ * A thread with an exclusive transaction lock may get a shared one.
+ * A thread with a shared transaction lock cannot get an exclusive one.
+ */
+int
+fstrans_start(struct mount *mp, int flags)
+{
+ int error, lflags, pflags;
+ struct fstrans_entry *fte, *new_fte;
+
+ KASSERT((flags & (FSTRANS_SHARED | FSTRANS_EXCL)) == FSTRANS_SHARED ||
+ (flags & (FSTRANS_SHARED | FSTRANS_EXCL)) == FSTRANS_EXCL);
+
+ pflags = 0;
+ lflags = (flags & FSTRANS_SHARED) ? LK_SHARED : LK_EXCLUSIVE;
+ if ((flags & FSTRANS_NOWAIT) != 0) {
+ pflags |= PR_NOWAIT;
+ lflags |= LK_NOWAIT;
+ }
+
+ if (mp == NULL)
+ return 0;
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) == 0)
+ return 0;
+
+ new_fte = NULL;
+ for (fte = curlwp->l_vntrans; fte; fte = fte->fte_succ) {
+ if (fte->fte_mount == NULL && new_fte == NULL)
+ new_fte = fte;
+ if (fte->fte_mount == mp) {
+ KASSERT(fte->fte_count > 0);
+ KASSERT(fte->fte_flags != 0);
+ if (fte->fte_flags == FSTRANS_SHARED &&
+ (flags & FSTRANS_EXCL) == FSTRANS_EXCL)
+ panic("fstrans_start: cannot upgrade lock");
+ fte->fte_count += 1;
+ return 0;
+ }
+ }
+
+ if (new_fte == NULL) {
+ if ((new_fte = pool_get(&fstrans_pl, pflags)) == NULL)
+ return EWOULDBLOCK;
+ new_fte->fte_mount = NULL;
+ new_fte->fte_count = 0;
+ new_fte->fte_flags = 0;
+ new_fte->fte_succ = curlwp->l_vntrans;
+ curlwp->l_vntrans = new_fte;
+ }
+
+ KASSERT(new_fte->fte_mount == NULL);
+ KASSERT(new_fte->fte_count == 0);
+
+ if ((error = lockmgr(&mp->mnt_trans_lock, lflags, NULL)) != 0)
+ return error;
+
+ new_fte->fte_mount = mp;
+ new_fte->fte_count = 1;
+ new_fte->fte_flags = (flags & (FSTRANS_SHARED | FSTRANS_EXCL));
+
+ return 0;
+}
+
+/*
+ * Finish a transaction.
+ */
+void
+fstrans_done(struct mount *mp)
+{
+ struct fstrans_entry *fte;
+
+ if (mp == NULL)
+ return;
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) == 0)
+ return;
+
+ for (fte = curlwp->l_vntrans; fte; fte = fte->fte_succ) {
+ if (fte->fte_mount == mp) {
+ fte->fte_count -= 1;
+ if (fte->fte_count > 0)
+ return;
+ break;
+ }
+ }
+
+ KASSERT(fte != NULL);
+ KASSERT(fte->fte_mount == mp);
+ KASSERT(fte->fte_count == 0);
+ fte->fte_mount = NULL;
+ fte->fte_flags = 0;
+
+ lockmgr(&mp->mnt_trans_lock, LK_RELEASE, NULL);
+}
+
+/*
+ * Check if this thread has at least this level of transaction lock.
+ */
+int
+fstrans_status(struct mount *mp, int flags)
+{
+ struct fstrans_entry *fte;
+
+ KASSERT(flags == FSTRANS_SHARED || flags == FSTRANS_EXCL);
+
+ if (mp == NULL)
+ return 0;
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) == 0)
+ return 0;
+
+ for (fte = curlwp->l_vntrans; fte; fte = fte->fte_succ)
+ if (fte->fte_mount == mp)
+ break;
+
+ if (fte == NULL)
+ return 0;
+
+ KASSERT(fte->fte_mount == mp);
+ KASSERT(fte->fte_count > 0);
+ return (fte->fte_flags == flags ||
+ (fte->fte_flags == FSTRANS_EXCL && flags == FSTRANS_SHARED));
+}
+
+/*
+ * Request a filesystem to suspend all operations.
+ */
+int
+vfs_suspend(struct mount *mp, int nowait)
+{
+ struct lwp *l = curlwp; /* XXX */
+ int error, flags;
+
+ flags = LK_EXCLUSIVE;
+ if (nowait)
+ flags |= LK_NOWAIT;
+ if (lockmgr(&vfs_suspend_lock, flags, NULL) != 0)
+ return EWOULDBLOCK;
+
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) != 0) {
+ lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+
+ if ((error = VFS_SUSPENDCTL(mp, SUSPEND_SUSPEND)) != 0)
+ lockmgr(&vfs_suspend_lock, LK_RELEASE, NULL);
+
+ return error;
+ }
+
+ KASSERT((mp->mnt_iflag &
+ (IMNT_SUSPEND|IMNT_SUSPENDLOW|IMNT_SUSPENDED)) == 0);
+
+ mp->mnt_iflag |= IMNT_SUSPEND;
+
+ simple_lock(&mp->mnt_slock);
+ if (mp->mnt_writeopcountupper > 0)
+ ltsleep(&mp->mnt_writeopcountupper, PUSER - 1, "suspwt",
+ 0, &mp->mnt_slock);
+ simple_unlock(&mp->mnt_slock);
+
+ error = VFS_SYNC(mp, MNT_WAIT, l->l_proc->p_cred, l);
+ if (error) {
+ vfs_resume(mp);
+ return error;
+ }
+ mp->mnt_iflag |= IMNT_SUSPENDLOW;
+
+ simple_lock(&mp->mnt_slock);
+ if (mp->mnt_writeopcountlower > 0)
+ ltsleep(&mp->mnt_writeopcountlower, PUSER - 1, "suspwt",
+ 0, &mp->mnt_slock);
+ mp->mnt_iflag |= IMNT_SUSPENDED;
+ simple_unlock(&mp->mnt_slock);
+
+ return 0;
+}
+
+/*
+ * Request a filesystem to resume all operations.
+ */
+void
+vfs_resume(struct mount *mp)
+{
+
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) != 0) {
+ VFS_SUSPENDCTL(mp, SUSPEND_RESUME);
+ lockmgr(&syncer_lock, LK_RELEASE, NULL);
+ lockmgr(&vfs_suspend_lock, LK_RELEASE, NULL);
+ return;
+ }
+
+ if ((mp->mnt_iflag & IMNT_SUSPEND) == 0)
+ return;
+ mp->mnt_iflag &= ~(IMNT_SUSPEND | IMNT_SUSPENDLOW | IMNT_SUSPENDED);
+ wakeup(&mp->mnt_flag);
+
+ lockmgr(&vfs_suspend_lock, LK_RELEASE, NULL);
+}
+
+/*
+ * Default vfs_suspendctl routine for file systems that do not support it.
+ */
+/*ARGSUSED*/
+int
+vfs_stdsuspendctl(struct mount *mp, int mode)
+{
+ return EOPNOTSUPP;
+}
+
+#ifdef DEBUG
+static void
+fstrans_print(struct proc *p, struct lwp *l)
+{
+ char prefix[9];
+ struct fstrans_entry *fte;
+
+ snprintf(prefix, sizeof(prefix), "%d.%d", p->p_pid, l->l_lid);
+ for (fte = l->l_vntrans; fte; fte = fte->fte_succ) {
+ if (fte->fte_count == 0)
+ continue;
+ printf("%-8s (%s) %s %d\n", prefix,
+ fte->fte_mount->mnt_stat.f_mntonname,
+ fte->fte_flags == FSTRANS_SHARED ? "shared" : "excl",
+ fte->fte_count);
+ prefix[0] = '\0';
+ }
+}
+
+void
+fstrans_list_all(void)
+{
+ const struct proclist_desc *pd;
+ struct proc *p;
+ struct lwp *l;
+
+ printf("Fstrans locks by lwp:\n");
+ for (pd = proclists; pd->pd_list != NULL; pd++)
+ LIST_FOREACH(p, pd->pd_list, p_list)
+ LIST_FOREACH(l, &p->p_lwps, l_sibling)
+ fstrans_print(p, l);
+}
+#endif
Index: sys/miscfs/genfs/genfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/genfs/genfs_vnops.c,v
retrieving revision 1.127
diff -p -u -4 -r1.127 genfs_vnops.c
--- sys/miscfs/genfs/genfs_vnops.c 22 Jul 2006 08:49:13 -0000 1.127
+++ sys/miscfs/genfs/genfs_vnops.c 30 Jul 2006 16:54:08 -0000
@@ -49,8 +49,9 @@ __KERNEL_RCSID(0, "$NetBSD: genfs_vnops.
#include <sys/poll.h>
#include <sys/mman.h>
#include <sys/file.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/genfs/genfs_node.h>
#include <miscfs/specfs/specdev.h>
@@ -457,8 +458,9 @@ genfs_getpages(void *v)
kauth_cred_t cred = curproc->p_cred; /* XXXUBC curlwp */
boolean_t async = (flags & PGO_SYNCIO) == 0;
boolean_t write = (ap->a_access_type & VM_PROT_WRITE) != 0;
boolean_t sawhole = FALSE;
+ boolean_t has_trans = FALSE;
boolean_t overwrite = (flags & PGO_OVERWRITE) != 0;
boolean_t blockalloc = write && (flags & PGO_NOBLOCKALLOC) == 0;
voff_t origvsize;
UVMHIST_FUNC("genfs_getpages"); UVMHIST_CALLED(ubchist);
@@ -714,8 +716,15 @@ startover:
/*
* read the desired page(s).
*/
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0) {
+ if (pgs != pgs_onstack)
+ free(pgs, M_DEVBUF);
+ return error;
+ }
+ has_trans = TRUE;
+
totalbytes = npages << PAGE_SHIFT;
bytes = MIN(totalbytes, MAX(diskeof - startoffset, 0));
tailbytes = totalbytes - bytes;
skipbytes = 0;
@@ -877,8 +886,10 @@ loopdone:
UVMHIST_LOG(ubchist, "returning 0 (async)",0,0,0,0);
lockmgr(&gp->g_glock, LK_RELEASE, NULL);
if (pgs != pgs_onstack)
free(pgs, M_DEVBUF);
+ if (has_trans)
+ fstrans_done(vp->v_mount);
return (0);
}
if (bp != NULL) {
error = biowait(mbp);
@@ -937,8 +948,10 @@ loopdone:
simple_unlock(&uobj->vmobjlock);
UVMHIST_LOG(ubchist, "returning error %d", error,0,0,0);
if (pgs != pgs_onstack)
free(pgs, M_DEVBUF);
+ if (has_trans)
+ fstrans_done(vp->v_mount);
return (error);
}
out:
@@ -982,8 +995,10 @@ out:
orignpages * sizeof(struct vm_page *));
}
if (pgs != pgs_onstack)
free(pgs, M_DEVBUF);
+ if (has_trans)
+ fstrans_done(vp->v_mount);
return (0);
}
/*
@@ -1063,9 +1078,12 @@ genfs_putpages(void *v)
boolean_t pagedaemon = curproc == uvm.pagedaemon_proc;
struct lwp *l = curlwp ? curlwp : &lwp0;
struct genfs_node *gp = VTOG(vp);
int dirtygen;
+ int tflag = (flags & (PGO_SYNCIO|PGO_CLEANIT)) != 0 ?
+ FSTRANS_SHARED : (FSTRANS_SHARED|FSTRANS_NOWAIT);
boolean_t modified = FALSE;
+ boolean_t has_trans = FALSE;
boolean_t cleanall;
UVMHIST_FUNC("genfs_putpages"); UVMHIST_CALLED(ubchist);
@@ -1374,9 +1392,13 @@ genfs_putpages(void *v)
TAILQ_INSERT_AFTER(&uobj->memq, pg, &curmp,
listq);
}
simple_unlock(slock);
- error = GOP_WRITE(vp, pgs, npages, flags);
+ if (!has_trans &&
+ (error = fstrans_start(vp->v_mount, tflag)) == 0)
+ has_trans = TRUE;
+ if (has_trans)
+ error = GOP_WRITE(vp, pgs, npages, flags);
simple_lock(slock);
if (by_list) {
pg = TAILQ_NEXT(&curmp, listq);
TAILQ_REMOVE(&uobj->memq, &curmp, listq);
@@ -1454,8 +1476,12 @@ skip_scan:
}
splx(s);
}
simple_unlock(&uobj->vmobjlock);
+
+ if (has_trans)
+ fstrans_done(vp->v_mount);
+
return (error);
}
int
Index: sys/ufs/ufs/ufs_bmap.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_bmap.c,v
retrieving revision 1.40
diff -p -u -4 -r1.40 ufs_bmap.c
--- sys/ufs/ufs/ufs_bmap.c 4 Apr 2006 17:12:57 -0000 1.40
+++ sys/ufs/ufs/ufs_bmap.c 30 Jul 2006 16:54:12 -0000
@@ -46,8 +46,9 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/resourcevar.h>
#include <sys/trace.h>
+#include <sys/fstrans.h>
#include <miscfs/specfs/specdev.h>
#include <ufs/ufs/inode.h>
@@ -80,8 +81,10 @@ ufs_bmap(void *v)
struct vnode **a_vpp;
daddr_t *a_bnp;
int *a_runp;
} */ *ap = v;
+ int error;
+
/*
* Check for underlying vnode requests and ensure that logical
* to physical mapping is requested.
*/
@@ -89,10 +92,14 @@ ufs_bmap(void *v)
*ap->a_vpp = VTOI(ap->a_vp)->i_devvp;
if (ap->a_bnp == NULL)
return (0);
- return (ufs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL, NULL,
- ap->a_runp, ufs_issequential));
+ if ((error = fstrans_start(ap->a_vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+ error = ufs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL, NULL,
+ ap->a_runp, ufs_issequential);
+ fstrans_done(ap->a_vp->v_mount);
+ return error;
}
/*
* Indirect blocks are now on the vnode for the file. They are given negative
Index: sys/ufs/ufs/ufs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extern.h,v
retrieving revision 1.49
diff -p -u -4 -r1.49 ufs_extern.h
--- sys/ufs/ufs/ufs_extern.h 14 May 2006 21:33:39 -0000 1.49
+++ sys/ufs/ufs/ufs_extern.h 30 Jul 2006 16:54:12 -0000
@@ -65,12 +65,12 @@ int ufs_create(void *);
int ufs_getattr(void *);
int ufs_inactive(void *);
#define ufs_fcntl genfs_fcntl
#define ufs_ioctl genfs_enoioctl
-#define ufs_islocked genfs_islocked
+int ufs_islocked(void *);
#define ufs_lease_check genfs_lease_check
int ufs_link(void *);
-#define ufs_lock genfs_lock
+int ufs_lock(void *);
int ufs_lookup(void *);
int ufs_mkdir(void *);
int ufs_mknod(void *);
#define ufs_mmap genfs_mmap
@@ -87,9 +87,9 @@ int ufs_rmdir(void *);
#define ufs_poll genfs_poll
int ufs_setattr(void *);
int ufs_strategy(void *);
int ufs_symlink(void *);
-#define ufs_unlock genfs_unlock
+int ufs_unlock(void *);
int ufs_whiteout(void *);
int ufsspec_close(void *);
int ufsspec_read(void *);
int ufsspec_write(void *);
Index: sys/ufs/ufs/ufs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_inode.c,v
retrieving revision 1.59
diff -p -u -4 -r1.59 ufs_inode.c
--- sys/ufs/ufs/ufs_inode.c 14 May 2006 21:33:39 -0000 1.59
+++ sys/ufs/ufs/ufs_inode.c 30 Jul 2006 16:54:12 -0000
@@ -51,8 +51,9 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,
#include <sys/mount.h>
#include <sys/kernel.h>
#include <sys/namei.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
@@ -79,16 +80,19 @@ ufs_inactive(void *v)
struct lwp *a_l;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
- struct mount *mp;
+ struct mount *mp, *transmp;
struct lwp *l = ap->a_l;
mode_t mode;
int error = 0;
if (prtactive && vp->v_usecount != 0)
vprint("ufs_inactive: pushing active", vp);
+ transmp = vp->v_mount;
+ if ((error = fstrans_start(transmp, FSTRANS_SHARED)) != 0)
+ return error;
/*
* Ignore inodes related to stale file handles.
*/
if (ip->i_mode == 0)
@@ -141,8 +145,9 @@ out:
*/
if (ip->i_mode == 0)
vrecycle(vp, NULL, l);
+ fstrans_done(transmp);
return (error);
}
/*
Index: sys/ufs/ufs/ufs_lookup.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_lookup.c,v
retrieving revision 1.78
diff -p -u -4 -r1.78 ufs_lookup.c
--- sys/ufs/ufs/ufs_lookup.c 23 Jun 2006 14:13:02 -0000 1.78
+++ sys/ufs/ufs/ufs_lookup.c 30 Jul 2006 16:54:12 -0000
@@ -52,8 +52,9 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c
#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/kernel.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/dir.h>
#ifdef UFS_DIRHASH
@@ -150,17 +151,21 @@ ufs_lookup(void *v)
*vpp = NULL;
lockparent = flags & LOCKPARENT;
wantparent = flags & (LOCKPARENT|WANTPARENT);
endsearch = 0; /* silence compiler warning */
+ if ((error = fstrans_start(vdp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
/*
* Check accessiblity of directory.
*/
if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_lwp)) != 0)
- return (error);
+ goto out;
if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
- (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
- return (EROFS);
+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
+ error = EROFS;
+ goto out;
+ }
/*
* We now have a segment name to search for, and a directory to search.
*
@@ -168,9 +173,9 @@ ufs_lookup(void *v)
* check the name cache to see if the directory/name pair
* we are looking for is known already.
*/
if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
- return (error);
+ goto out;
/*
* Suppress search for slots unless creating
* file and at end of pathname, in which case
@@ -245,9 +250,9 @@ ufs_lookup(void *v)
} else {
dp->i_offset = dp->i_diroff;
if ((entryoffsetinblock = dp->i_offset & bmask) &&
(error = ufs_blkatoff(vdp, (off_t)dp->i_offset, NULL, &bp)))
- return (error);
+ goto out;
numdirpasses = 2;
nchstats.ncs_2passes++;
}
prevoff = dp->i_offset;
@@ -266,9 +271,9 @@ searchloop:
brelse(bp);
error = ufs_blkatoff(vdp, (off_t)dp->i_offset, NULL,
&bp);
if (error)
- return (error);
+ goto out;
entryoffsetinblock = 0;
}
/*
* If still looking for a slot, and at a DIRBLKSIZE
@@ -423,9 +428,9 @@ notfound:
* creation of files in the directory.
*/
error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_lwp);
if (error)
- return (error);
+ goto out;
/*
* Return an indication of where the new directory
* entry should be put. If we didn't find a slot,
* then set dp->i_count to 0 indicating
@@ -471,16 +476,18 @@ notfound:
if (!lockparent) {
VOP_UNLOCK(vdp, 0);
cnp->cn_flags |= PDIRUNLOCK;
}
- return (EJUSTRETURN);
+ error = EJUSTRETURN;
+ goto out;
}
/*
* Insert name into cache (as non-existent) if appropriate.
*/
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
cache_enter(vdp, *vpp, cnp);
- return (ENOENT);
+ error = ENOENT;
+ goto out;
found:
if (numdirpasses == 2)
nchstats.ncs_pass2++;
@@ -516,9 +523,9 @@ found:
* Write access to directory required to delete files.
*/
error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_lwp);
if (error)
- return (error);
+ goto out;
/*
* Return pointer to current entry in dp->i_offset,
* and distance past previous entry (if there
* is a previous entry in this block) in dp->i_count.
@@ -530,17 +537,18 @@ found:
dp->i_count = dp->i_offset - prevoff;
if (dp->i_number == foundino) {
VREF(vdp);
*vpp = vdp;
- return (0);
+ error = 0;
+ goto out;
}
if (flags & ISDOTDOT)
VOP_UNLOCK(vdp, 0); /* race to get the inode */
error = VFS_VGET(vdp->v_mount, foundino, &tdp);
if (flags & ISDOTDOT)
vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY);
if (error)
- return (error);
+ goto out;
/*
* If directory is "sticky", then user must own
* the directory, or the file in it, else she
* may not delete it (unless she's root). This
@@ -550,16 +558,18 @@ found:
kauth_cred_geteuid(cred) != 0 &&
kauth_cred_geteuid(cred) != dp->i_uid &&
VTOI(tdp)->i_uid != kauth_cred_geteuid(cred)) {
vput(tdp);
- return (EPERM);
+ error = EPERM;
+ goto out;
}
*vpp = tdp;
if (!lockparent) {
VOP_UNLOCK(vdp, 0);
cnp->cn_flags |= PDIRUNLOCK;
}
- return (0);
+ error = 0;
+ goto out;
}
/*
* If rewriting (RENAME), return the inode and the
@@ -569,29 +579,32 @@ found:
*/
if (nameiop == RENAME && wantparent && (flags & ISLASTCN)) {
error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_lwp);
if (error)
- return (error);
+ goto out;
/*
* Careful about locking second inode.
* This can only occur if the target is ".".
*/
- if (dp->i_number == foundino)
- return (EISDIR);
+ if (dp->i_number == foundino) {
+ error = EISDIR;
+ goto out;
+ }
if (flags & ISDOTDOT)
VOP_UNLOCK(vdp, 0); /* race to get the inode */
error = VFS_VGET(vdp->v_mount, foundino, &tdp);
if (flags & ISDOTDOT)
vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY);
if (error)
- return (error);
+ goto out;
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
if (!lockparent) {
VOP_UNLOCK(vdp, 0);
cnp->cn_flags |= PDIRUNLOCK;
}
- return (0);
+ error = 0;
+ goto out;
}
/*
* Step through the translation in the name. We do not `vput' the
@@ -619,14 +632,14 @@ found:
error = VFS_VGET(vdp->v_mount, foundino, &tdp);
if (error) {
if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY) == 0)
cnp->cn_flags &= ~PDIRUNLOCK;
- return (error);
+ goto out;
}
if (lockparent && (flags & ISLASTCN)) {
if ((error = vn_lock(pdp, LK_EXCLUSIVE))) {
vput(tdp);
- return (error);
+ goto out;
}
cnp->cn_flags &= ~PDIRUNLOCK;
}
*vpp = tdp;
@@ -635,9 +648,9 @@ found:
*vpp = vdp;
} else {
error = VFS_VGET(vdp->v_mount, foundino, &tdp);
if (error)
- return (error);
+ goto out;
if (!lockparent || !(flags & ISLASTCN)) {
VOP_UNLOCK(pdp, 0);
cnp->cn_flags |= PDIRUNLOCK;
}
@@ -648,9 +661,13 @@ found:
* Insert name into cache if appropriate.
*/
if (cnp->cn_flags & MAKEENTRY)
cache_enter(vdp, *vpp, cnp);
- return (0);
+ error = 0;
+
+out:
+ fstrans_done(vdp->v_mount);
+ return error;
}
void
ufs_dirbad(struct inode *ip, doff_t offset, const char *how)
Index: sys/ufs/ufs/ufs_readwrite.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_readwrite.c,v
retrieving revision 1.68
diff -p -u -4 -r1.68 ufs_readwrite.c
--- sys/ufs/ufs/ufs_readwrite.c 14 May 2006 21:33:39 -0000 1.68
+++ sys/ufs/ufs/ufs_readwrite.c 30 Jul 2006 16:54:12 -0000
@@ -102,8 +102,12 @@ READ(void *v)
if ((u_int64_t)uio->uio_offset > ump->um_maxfilesize)
return (EFBIG);
if (uio->uio_resid == 0)
return (0);
+
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+
if (uio->uio_offset >= ip->i_size)
goto out;
#ifdef LFS_READWRITE
@@ -178,8 +182,10 @@ READ(void *v)
ip->i_flag |= IN_ACCESS;
if ((ap->a_ioflag & IO_SYNC) == IO_SYNC)
error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
}
+
+ fstrans_done(vp->v_mount);
return (error);
}
/*
@@ -271,8 +277,11 @@ WRITE(void *v)
}
if (uio->uio_resid == 0)
return (0);
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+
flags = ioflag & IO_SYNC ? B_SYNC : 0;
async = vp->v_mount->mnt_flag & MNT_ASYNC;
origoff = uio->uio_offset;
resid = uio->uio_resid;
@@ -496,6 +505,9 @@ out:
uio->uio_resid = resid;
} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC)
error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
KASSERT(vp->v_size == ip->i_size);
+
+ fstrans_done(vp->v_mount);
+
return (error);
}
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.141
diff -p -u -4 -r1.141 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c 7 Jun 2006 22:34:44 -0000 1.141
+++ sys/ufs/ufs/ufs_vnops.c 30 Jul 2006 16:54:12 -0000
@@ -59,8 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,
#include <sys/malloc.h>
#include <sys/dirent.h>
#include <sys/lockf.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/fifofs/fifo.h>
@@ -104,11 +105,14 @@ ufs_create(void *v)
struct vattr *a_vap;
} */ *ap = v;
int error;
+ if ((error = fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
error =
ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
ap->a_dvp, ap->a_vpp, ap->a_cnp);
+ fstrans_done(ap->a_dvp->v_mount);
if (error)
return (error);
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
return (0);
@@ -135,12 +139,14 @@ ufs_mknod(void *v)
ino_t ino;
vap = ap->a_vap;
vpp = ap->a_vpp;
+ if ((error = fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
if ((error =
ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
ap->a_dvp, vpp, ap->a_cnp)) != 0)
- return (error);
+ goto out;
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
ip = VTOI(*vpp);
mp = (*vpp)->v_mount;
ino = ip->i_number;
@@ -166,8 +172,10 @@ ufs_mknod(void *v)
vput(*vpp);
(*vpp)->v_type = VNON;
vgone(*vpp);
error = VFS_VGET(mp, ino, vpp);
+out:
+ fstrans_done(ap->a_dvp->v_mount);
if (error != 0) {
*vpp = NULL;
return (error);
}
@@ -257,10 +265,15 @@ ufs_access(void *v)
case VREG:
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
#ifdef QUOTA
- if ((error = getinoquota(ip)) != 0)
- return (error);
+ if ((error =
+ fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+ error = getinoquota(ip);
+ fstrans_done(vp->v_mount);
+ if (error != 0)
+ return error;
#endif
break;
case VBAD:
case VBLK:
@@ -383,51 +396,71 @@ ufs_setattr(void *v)
(vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
return (EINVAL);
}
+
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+
if (vap->va_flags != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY) {
+ error = EROFS;
+ goto out;
+ }
if (kauth_cred_geteuid(cred) != ip->i_uid &&
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
&l->l_proc->p_acflag)))
- return (error);
+ goto out;
if (kauth_cred_geteuid(cred) == 0) {
if ((ip->i_flags & (SF_IMMUTABLE | SF_APPEND)) &&
- securelevel > 0)
- return (EPERM);
+ securelevel > 0) {
+ error = EPERM;
+ goto out;
+ }
/* Snapshot flag cannot be set or cleared */
if ((vap->va_flags & SF_SNAPSHOT) !=
- (ip->i_flags & SF_SNAPSHOT))
- return (EPERM);
+ (ip->i_flags & SF_SNAPSHOT)) {
+ error = EPERM;
+ goto out;
+ }
ip->i_flags = vap->va_flags;
DIP_ASSIGN(ip, flags, ip->i_flags);
} else {
if ((ip->i_flags & (SF_IMMUTABLE | SF_APPEND)) ||
- (vap->va_flags & UF_SETTABLE) != vap->va_flags)
- return (EPERM);
+ (vap->va_flags & UF_SETTABLE) != vap->va_flags) {
+ error = EPERM;
+ goto out;
+ }
if ((ip->i_flags & SF_SETTABLE) !=
- (vap->va_flags & SF_SETTABLE))
- return (EPERM);
+ (vap->va_flags & SF_SETTABLE)) {
+ error = EPERM;
+ goto out;
+ }
ip->i_flags &= SF_SETTABLE;
ip->i_flags |= (vap->va_flags & UF_SETTABLE);
DIP_ASSIGN(ip, flags, ip->i_flags);
}
ip->i_flag |= IN_CHANGE;
- if (vap->va_flags & (IMMUTABLE | APPEND))
- return (0);
+ if (vap->va_flags & (IMMUTABLE | APPEND)) {
+ error = 0;
+ goto out;
+ }
+ }
+ if (ip->i_flags & (IMMUTABLE | APPEND)) {
+ error = EPERM;
+ goto out;
}
- if (ip->i_flags & (IMMUTABLE | APPEND))
- return (EPERM);
/*
* Go through the fields and update iff not VNOVAL.
*/
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY) {
+ error = EROFS;
+ goto out;
+ }
error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, l->l_proc);
if (error)
- return (error);
+ goto out;
}
if (vap->va_size != VNOVAL) {
/*
* Disallow write attempts on read-only file systems;
@@ -435,39 +468,49 @@ ufs_setattr(void *v)
* character device resident on the file system.
*/
switch (vp->v_type) {
case VDIR:
- return (EISDIR);
+ error = EISDIR;
+ goto out;
case VCHR:
case VBLK:
case VFIFO:
break;
case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- if ((ip->i_flags & SF_SNAPSHOT) != 0)
- return (EPERM);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY) {
+ error = EROFS;
+ goto out;
+ }
+ if ((ip->i_flags & SF_SNAPSHOT) != 0) {
+ error = EPERM;
+ goto out;
+ }
error = UFS_TRUNCATE(vp, vap->va_size, 0, cred, l);
if (error)
- return (error);
+ goto out;
break;
default:
- return (EOPNOTSUPP);
+ error = EOPNOTSUPP;
+ goto out;
}
}
ip = VTOI(vp);
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
vap->va_birthtime.tv_sec != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- if ((ip->i_flags & SF_SNAPSHOT) != 0)
- return (EPERM);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY) {
+ error = EROFS;
+ goto out;
+ }
+ if ((ip->i_flags & SF_SNAPSHOT) != 0) {
+ error = EPERM;
+ goto out;
+ }
if (kauth_cred_geteuid(cred) != ip->i_uid &&
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
&l->l_proc->p_acflag)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(vp, VWRITE, cred, l))))
- return (error);
+ goto out;
if (vap->va_atime.tv_sec != VNOVAL)
if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
ip->i_flag |= IN_ACCESS;
if (vap->va_mtime.tv_sec != VNOVAL)
@@ -478,21 +521,27 @@ ufs_setattr(void *v)
ip->i_ffs2_birthnsec = vap->va_birthtime.tv_nsec;
}
error = UFS_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 0);
if (error)
- return (error);
+ goto out;
}
error = 0;
if (vap->va_mode != (mode_t)VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY) {
+ error = EROFS;
+ goto out;
+ }
if ((ip->i_flags & SF_SNAPSHOT) != 0 &&
(vap->va_mode & (S_IXUSR | S_IWUSR | S_IXGRP | S_IWGRP |
- S_IXOTH | S_IWOTH)))
- return (EPERM);
+ S_IXOTH | S_IWOTH))) {
+ error = EPERM;
+ goto out;
+ }
error = ufs_chmod(vp, (int)vap->va_mode, cred, l->l_proc);
}
VN_KNOTE(vp, NOTE_ATTRIB);
+out:
+ fstrans_done(vp->v_mount);
return (error);
}
/*
@@ -648,8 +697,10 @@ ufs_remove(void *v)
vp = ap->a_vp;
dvp = ap->a_dvp;
ip = VTOI(vp);
+ if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
if (vp->v_type == VDIR || (ip->i_flags & (IMMUTABLE | APPEND)) ||
(VTOI(dvp)->i_flags & APPEND))
error = EPERM;
else
@@ -660,8 +711,9 @@ ufs_remove(void *v)
vrele(vp);
else
vput(vp);
vput(dvp);
+ fstrans_done(dvp->v_mount);
return (error);
}
/*
@@ -687,8 +739,10 @@ ufs_link(void *v)
#ifdef DIAGNOSTIC
if ((cnp->cn_flags & HASBUF) == 0)
panic("ufs_link: no name");
#endif
+ if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
if (vp->v_type == VDIR) {
VOP_ABORTOP(dvp, cnp);
error = EPERM;
goto out2;
@@ -741,8 +795,9 @@ ufs_link(void *v)
out2:
VN_KNOTE(vp, NOTE_LINK);
VN_KNOTE(dvp, NOTE_WRITE);
vput(dvp);
+ fstrans_done(dvp->v_mount);
return (error);
}
/*
@@ -762,17 +817,21 @@ ufs_whiteout(void *v)
int error;
struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
error = 0;
+
switch (ap->a_flags) {
case LOOKUP:
/* 4.4 format directories support whiteout operations */
+ fstrans_done(dvp->v_mount);
if (ump->um_maxsymlinklen > 0)
return (0);
return (EOPNOTSUPP);
case CREATE:
/* create a new directory whiteout */
+ if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
#ifdef DIAGNOSTIC
if ((cnp->cn_flags & SAVENAME) == 0)
panic("ufs_whiteout: missing name");
if (ump->um_maxsymlinklen <= 0)
@@ -791,8 +850,10 @@ ufs_whiteout(void *v)
break;
case DELETE:
/* remove an existing directory whiteout */
+ if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
#ifdef DIAGNOSTIC
if (ump->um_maxsymlinklen <= 0)
panic("ufs_whiteout: old format filesystem");
#endif
@@ -807,8 +868,9 @@ ufs_whiteout(void *v)
if (cnp->cn_flags & HASBUF) {
PNBUF_PUT(cnp->cn_pnbuf);
cnp->cn_flags &= ~HASBUF;
}
+ fstrans_done(dvp->v_mount);
return (error);
}
@@ -849,8 +911,9 @@ ufs_rename(void *v)
} */ *ap = v;
struct vnode *tvp, *tdvp, *fvp, *fdvp;
struct componentname *tcnp, *fcnp;
struct inode *ip, *xp, *dp;
+ struct mount *mp;
struct direct *newdir;
int doingdirectory, oldparent, newparent, error;
tvp = ap->a_tvp;
@@ -959,8 +1022,12 @@ ufs_rename(void *v)
xp = NULL;
if (tvp)
xp = VTOI(tvp);
+ mp = fdvp->v_mount;
+ if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0)
+ return error;
+
/*
* 1) Bump link count while we're moving stuff
* around. If we crash somewhere before
* completing our work, the link count
@@ -1156,9 +1223,9 @@ ufs_rename(void *v)
fcnp->cn_flags &= ~(MODMASK | SAVESTART);
fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
if ((error = relookup(fdvp, &fvp, fcnp))) {
vrele(ap->a_fvp);
- return (error);
+ goto out2;
}
if (fvp != NULL) {
xp = VTOI(fvp);
dp = VTOI(fdvp);
@@ -1168,9 +1235,10 @@ ufs_rename(void *v)
*/
if (doingdirectory)
panic("rename: lost dir entry");
vrele(ap->a_fvp);
- return (0);
+ error = 0;
+ goto out2;
}
/*
* Ensure that the directory entry still exists and has not
* changed while the new name has been entered. If the source is
@@ -1203,9 +1271,9 @@ ufs_rename(void *v)
vput(fdvp);
if (xp)
vput(fvp);
vrele(ap->a_fvp);
- return (error);
+ goto out2;
/* exit routines from steps 1 & 2 */
bad:
if (xp)
@@ -1225,8 +1293,12 @@ ufs_rename(void *v)
vput(fvp);
} else
vrele(fvp);
vrele(fdvp);
+
+ /* exit routines from step 3 */
+ out2:
+ fstrans_done(mp);
return (error);
}
/*
@@ -1251,8 +1323,11 @@ ufs_mkdir(void *v)
int error, dmode, blkoff;
struct ufsmount *ump = dp->i_ump;
int dirblksiz = ump->um_dirblksiz;
+ if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+
#ifdef DIAGNOSTIC
if ((cnp->cn_flags & HASBUF) == 0)
panic("ufs_mkdir: no name");
#endif
@@ -1279,8 +1354,9 @@ ufs_mkdir(void *v)
if ((error = getinoquota(ip)) ||
(error = chkiq(ip, 1, cnp->cn_cred, 0))) {
PNBUF_PUT(cnp->cn_pnbuf);
UFS_VFREE(tvp, ip->i_number, dmode);
+ fstrans_done(dvp->v_mount);
vput(tvp);
vput(dvp);
return (error);
}
@@ -1408,8 +1484,9 @@ ufs_mkdir(void *v)
vput(tvp);
}
out:
PNBUF_PUT(cnp->cn_pnbuf);
+ fstrans_done(dvp->v_mount);
vput(dvp);
return (error);
}
@@ -1443,8 +1520,12 @@ ufs_rmdir(void *v)
VOP_UNLOCK(dvp, 0);
vput(vp);
return (EINVAL);
}
+
+ if ((error = fstrans_start(dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+
/*
* Do not remove a directory that is in the process of being renamed.
* Verify that the directory is empty (and valid). (Rmdir ".." won't
* be valid since ".." will contain a reference to the current
@@ -1513,8 +1594,9 @@ ufs_rmdir(void *v)
ufsdirhash_free(ip);
#endif
out:
VN_KNOTE(vp, NOTE_DELETE);
+ fstrans_done(dvp->v_mount);
vput(dvp);
vput(vp);
return (error);
}
@@ -1536,12 +1618,14 @@ ufs_symlink(void *v)
struct inode *ip;
int len, error;
vpp = ap->a_vpp;
+ if ((error = fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
vpp, ap->a_cnp);
if (error)
- return (error);
+ goto out;
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
vp = *vpp;
len = strlen(ap->a_target);
ip = VTOI(vp);
@@ -1556,8 +1640,10 @@ ufs_symlink(void *v)
UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, NULL,
NULL);
if (error)
vput(vp);
+out:
+ fstrans_done(ap->a_dvp->v_mount);
return (error);
}
/*
@@ -2218,4 +2304,71 @@ ufs_gop_markupdate(struct vnode *vp, int
ip->i_flag |= mask;
}
}
+
+/*
+ * Lock the node.
+ */
+int
+ufs_lock(void *v)
+{
+ struct vop_lock_args /* {
+ struct vnode *a_vp;
+ int a_flags;
+ } */ *ap = v;
+ struct vnode *vp = ap->a_vp;
+ struct mount *mp = vp->v_mount;
+
+ /*
+ * Fake lock during file system suspension.
+ */
+ if ((mp->mnt_iflag & (IMNT_SUSPEND|IMNT_SUSPENDED)) == IMNT_SUSPEND &&
+ (vp->v_type == VREG || vp->v_type == VDIR) &&
+ fstrans_status(mp, FSTRANS_EXCL)) {
+ if ((ap->a_flags & LK_INTERLOCK) != 0)
+ simple_unlock(&vp->v_interlock);
+ return 0;
+ }
+ return (lockmgr(vp->v_vnlock, ap->a_flags, &vp->v_interlock));
+}
+
+/*
+ * Unlock the node.
+ */
+int
+ufs_unlock(void *v)
+{
+ struct vop_unlock_args /* {
+ struct vnode *a_vp;
+ int a_flags;
+ } */ *ap = v;
+ struct vnode *vp = ap->a_vp;
+ struct mount *mp = vp->v_mount;
+
+ /*
+ * Fake unlock during file system suspension.
+ */
+ if ((mp->mnt_iflag & (IMNT_SUSPEND|IMNT_SUSPENDED)) == IMNT_SUSPEND &&
+ (vp->v_type == VREG || vp->v_type == VDIR) &&
+ fstrans_status(mp, FSTRANS_EXCL)) {
+ if ((ap->a_flags & LK_INTERLOCK) != 0)
+ simple_unlock(&vp->v_interlock);
+ return 0;
+ }
+ return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE,
+ &vp->v_interlock));
+}
+
+/*
+ * Return whether or not the node is locked.
+ */
+int
+ufs_islocked(void *v)
+{
+ struct vop_islocked_args /* {
+ struct vnode *a_vp;
+ } */ *ap = v;
+ struct vnode *vp = ap->a_vp;
+
+ return (lockstatus(vp->v_vnlock));
+}
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.183
diff -p -u -4 -r1.183 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c 13 Jul 2006 12:00:26 -0000 1.183
+++ sys/ufs/ffs/ffs_vfsops.c 30 Jul 2006 16:54:11 -0000
@@ -60,8 +60,9 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c
#include <sys/lock.h>
#include <sys/sysctl.h>
#include <sys/conf.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <miscfs/specfs/specdev.h>
#include <ufs/ufs/quota.h>
@@ -107,8 +108,9 @@ struct vfsops ffs_vfsops = {
ffs_done,
ffs_mountroot,
ffs_snapshot,
ffs_extattrctl,
+ ffs_suspendctl,
ffs_vnodeopv_descs,
};
VFS_ATTACH(ffs_vfsops);
@@ -963,8 +965,11 @@ ffs_mountfs(struct vnode *devvp, struct
}
mp->mnt_fs_bshift = fs->fs_bshift;
mp->mnt_dev_bshift = DEV_BSHIFT; /* XXX */
mp->mnt_flag |= MNT_LOCAL;
+#ifdef NEWVNGATE
+ mp->mnt_iflag |= IMNT_HAS_TRANS;
+#endif
#ifdef FFS_EI
if (needswap)
ump->um_flags |= UFS_NEEDSWAP;
#endif
@@ -1296,15 +1301,19 @@ ffs_sync(struct mount *mp, int waitfor,
struct vnode *vp, *nvp;
struct inode *ip;
struct ufsmount *ump = VFSTOUFS(mp);
struct fs *fs;
- int error, count, allerror = 0;
+ int error, count, suspend, allerror = 0;
fs = ump->um_fs;
+ suspend =
+ (mp->mnt_iflag & (IMNT_SUSPEND | IMNT_SUSPENDED)) == IMNT_SUSPEND;
if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */
printf("fs = %s\n", fs->fs_fsmnt);
panic("update: rofs mod");
}
+ if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0)
+ return error;
/*
* Write back each (modified) inode.
*/
simple_lock(&mntvnode_slock);
@@ -1327,8 +1336,12 @@ loop:
{
simple_unlock(&vp->v_interlock);
continue;
}
+ if (vp->v_type == VBLK && suspend) {
+ simple_unlock(&vp->v_interlock);
+ continue;
+ }
simple_unlock(&mntvnode_slock);
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK);
if (error) {
simple_lock(&mntvnode_slock);
@@ -1382,8 +1395,9 @@ loop:
fs->fs_time = time_second;
if ((error = ffs_cgupdate(ump, waitfor)))
allerror = error;
}
+ fstrans_done(mp);
return (allerror);
}
/*
@@ -1746,4 +1760,36 @@ ffs_extattrctl(struct mount *mp, int cmd
l));
#endif
return (vfs_stdextattrctl(mp, cmd, vp, attrnamespace, attrname, l));
}
+
+int
+ffs_suspendctl(struct mount *mp, int cmd)
+{
+ int error;
+ struct lwp *l = curlwp;
+
+ switch (cmd) {
+ case SUSPEND_SUSPEND:
+ if ((error = fstrans_start(mp, FSTRANS_EXCL)) != 0)
+ return error;
+ mp->mnt_iflag |= IMNT_SUSPEND;
+ error = ffs_sync(mp, MNT_WAIT, l->l_proc->p_cred, l);
+ if (error != 0) {
+ mp->mnt_iflag &= ~IMNT_SUSPEND;
+ fstrans_done(mp);
+ return error;
+ }
+ mp->mnt_iflag |= IMNT_SUSPENDED;
+ return 0;
+
+ case SUSPEND_RESUME:
+ KASSERT((mp->mnt_iflag & (IMNT_SUSPEND | IMNT_SUSPENDED)) ==
+ (IMNT_SUSPEND | IMNT_SUSPENDED));
+ mp->mnt_iflag &= ~(IMNT_SUSPEND | IMNT_SUSPENDED);
+ fstrans_done(mp);
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+}
Index: sys/ufs/ffs/ffs_extern.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_extern.h,v
retrieving revision 1.54
diff -p -u -4 -r1.54 ffs_extern.h
--- sys/ufs/ffs/ffs_extern.h 13 Jul 2006 12:00:26 -0000 1.54
+++ sys/ufs/ffs/ffs_extern.h 30 Jul 2006 16:54:09 -0000
@@ -124,8 +124,9 @@ int ffs_vget(struct mount *, ino_t, stru
int ffs_fhtovp(struct mount *, struct fid *, struct vnode **);
int ffs_vptofh(struct vnode *, struct fid *, size_t *);
int ffs_extattrctl(struct mount *, int, struct vnode *, int,
const char *, struct lwp *);
+int ffs_suspendctl(struct mount *, int);
int ffs_sbupdate(struct ufsmount *, int);
int ffs_cgupdate(struct ufsmount *, int);
/* ffs_vnops.c */
Index: sys/ufs/ffs/ffs_snapshot.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_snapshot.c,v
retrieving revision 1.30
diff -p -u -4 -r1.30 ffs_snapshot.c
--- sys/ufs/ffs/ffs_snapshot.c 7 Jun 2006 22:34:19 -0000 1.30
+++ sys/ufs/ffs/ffs_snapshot.c 30 Jul 2006 16:54:09 -0000
@@ -58,8 +58,9 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_snapshot
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/vnode.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <miscfs/specfs/specdev.h>
#include <ufs/ufs/quota.h>
@@ -284,9 +285,9 @@ ffs_snapshot(struct mount *mp, struct vn
* All allocations are done, so we can now snapshot the system.
*
* Suspend operation on filesystem.
*/
- if ((error = vfs_write_suspend(vp->v_mount, PUSER|PCATCH, 0)) != 0) {
+ if ((error = vfs_suspend(vp->v_mount, 0)) != 0) {
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
goto out;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
@@ -378,25 +379,33 @@ loop:
VI_UNLOCK(xvp);
MNT_ILOCK(mp);
continue;
}
+#ifndef NEWVNGATE
if (vn_lock(xvp, LK_EXCLUSIVE | LK_INTERLOCK) != 0) {
MNT_ILOCK(mp);
goto loop;
}
+#else /* NEWVNGATE */
+ VI_UNLOCK(xvp);
+#endif /* NEWVNGATE */
#ifdef DEBUG
if (snapdebug)
vprint("ffs_snapshot: busy vnode", xvp);
#endif
if (VOP_GETATTR(xvp, &vat, l->l_proc->p_cred, l) == 0 &&
vat.va_nlink > 0) {
+#ifndef NEWVNGATE
VOP_UNLOCK(xvp, 0);
+#endif /* NEWVNGATE */
MNT_ILOCK(mp);
continue;
}
xp = VTOI(xvp);
if (ffs_checkfreefile(copy_fs, vp, xp->i_number)) {
+#ifndef NEWVNGATE
VOP_UNLOCK(xvp, 0);
+#endif /* NEWVNGATE */
MNT_ILOCK(mp);
continue;
}
/*
@@ -424,9 +433,11 @@ loop:
db_assign(xp, loc, blkno);
if (!error)
error = ffs_freefile(copy_fs, vp, xp->i_number,
xp->i_mode);
+#ifndef NEWVNGATE
VOP_UNLOCK(xvp, 0);
+#endif /* NEWVNGATE */
if (error) {
free(copy_fs->fs_csp, M_UFSMNT);
goto out1;
}
@@ -507,9 +518,9 @@ loop:
out1:
/*
* Resume operation on filesystem.
*/
- vfs_write_resume(vp->v_mount);
+ vfs_resume(vp->v_mount);
/*
* Set the mtime to the time the snapshot has been taken.
*/
TIMEVAL_TO_TIMESPEC(&starttime, &ts);
Index: sys/ufs/ffs/ffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vnops.c,v
retrieving revision 1.80
diff -p -u -4 -r1.80 ffs_vnops.c
--- sys/ufs/ffs/ffs_vnops.c 14 May 2006 21:32:45 -0000 1.80
+++ sys/ufs/ffs/ffs_vnops.c 30 Jul 2006 16:54:11 -0000
@@ -47,8 +47,9 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,
#include <sys/vnode.h>
#include <sys/pool.h>
#include <sys/signalvar.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <miscfs/fifofs/fifo.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/specfs/specdev.h>
@@ -250,18 +251,22 @@ ffs_fsync(void *v)
int bsize;
daddr_t blk_high;
struct vnode *vp;
+ vp = ap->a_vp;
+
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
/*
* XXX no easy way to sync a range in a file with softdep.
*/
- if ((ap->a_offlo == 0 && ap->a_offhi == 0) || DOINGSOFTDEP(ap->a_vp) ||
- (ap->a_vp->v_type != VREG))
- return ffs_full_fsync(v);
-
- vp = ap->a_vp;
+ if ((ap->a_offlo == 0 && ap->a_offhi == 0) || DOINGSOFTDEP(vp) ||
+ (vp->v_type != VREG)) {
+ error = ffs_full_fsync(v);
+ goto out;
+ }
- bsize = ap->a_vp->v_mount->mnt_stat.f_iosize;
+ bsize = vp->v_mount->mnt_stat.f_iosize;
blk_high = ap->a_offhi / bsize;
if (ap->a_offhi % bsize != 0)
blk_high++;
@@ -273,9 +278,9 @@ ffs_fsync(void *v)
error = VOP_PUTPAGES(vp, trunc_page(ap->a_offlo),
round_page(ap->a_offhi), PGO_CLEANIT |
((ap->a_flags & FSYNC_WAIT) ? PGO_SYNCIO : 0));
if (error) {
- return error;
+ goto out;
}
/*
* Then, flush indirect blocks.
@@ -285,9 +290,9 @@ ffs_fsync(void *v)
if (blk_high >= NDADDR) {
error = ufs_getlbns(vp, blk_high, ia, &num);
if (error) {
splx(s);
- return error;
+ goto out;
}
for (i = 0; i < num; i++) {
bp = incore(vp, ia[i].in_lbn);
if (bp != NULL) {
@@ -325,8 +330,10 @@ ffs_fsync(void *v)
VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &l, FWRITE,
ap->a_l->l_proc->p_cred, ap->a_l);
}
+out:
+ fstrans_done(vp->v_mount);
return error;
}
/*
@@ -479,13 +486,18 @@ ffs_reclaim(void *v)
struct lwp *a_l;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
+ struct mount *mp = vp->v_mount;
struct ufsmount *ump = ip->i_ump;
int error;
- if ((error = ufs_reclaim(vp, ap->a_l)) != 0)
+ if ((error = fstrans_start(mp, FSTRANS_SHARED)) != 0)
+ return error;
+ if ((error = ufs_reclaim(vp, ap->a_l)) != 0) {
+ fstrans_done(mp);
return (error);
+ }
if (ip->i_din.ffs1_din != NULL) {
if (ump->um_fstype == UFS1)
pool_put(&ffs_dinode1_pool, ip->i_din.ffs1_din);
else
@@ -496,8 +508,9 @@ ffs_reclaim(void *v)
* XXX a separate pool for MFS inodes?
*/
pool_put(&ffs_inode_pool, vp->v_data);
vp->v_data = NULL;
+ fstrans_done(mp);
return (0);
}
int
@@ -606,14 +619,21 @@ ffs_getextattr(void *v)
size_t *a_size;
kauth_cred_t a_cred;
struct proc *a_p;
} */ *ap = v;
- struct inode *ip = VTOI(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct inode *ip = VTOI(vp);
struct fs *fs = ip->i_fs;
if (fs->fs_magic == FS_UFS1_MAGIC) {
#ifdef UFS_EXTATTR
- return (ufs_getextattr(ap));
+ int error;
+
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+ error = ufs_getextattr(ap);
+ fstrans_done(vp->v_mount);
+ return error;
#else
return (EOPNOTSUPP);
#endif
}
@@ -632,14 +652,21 @@ ffs_setextattr(void *v)
struct uio *a_uio;
kauth_cred_t a_cred;
struct proc *a_p;
} */ *ap = v;
- struct inode *ip = VTOI(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct inode *ip = VTOI(vp);
struct fs *fs = ip->i_fs;
if (fs->fs_magic == FS_UFS1_MAGIC) {
#ifdef UFS_EXTATTR
- return (ufs_setextattr(ap));
+ int error;
+
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+ error = ufs_setextattr(ap);
+ fstrans_done(vp->v_mount);
+ return error;
#else
return (EOPNOTSUPP);
#endif
}
@@ -678,14 +705,21 @@ ffs_deleteextattr(void *v)
int a_attrnamespace;
kauth_cred_t a_cred;
struct proc *a_p;
} */ *ap = v;
- struct inode *ip = VTOI(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
+ struct inode *ip = VTOI(vp);
struct fs *fs = ip->i_fs;
if (fs->fs_magic == FS_UFS1_MAGIC) {
#ifdef UFS_EXTATTR
- return (ufs_deleteextattr(ap));
+ int error;
+
+ if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
+ return error;
+ error = ufs_deleteextattr(ap);
+ fstrans_done(vp->v_mount);
+ return error;
#else
return (EOPNOTSUPP);
#endif
}
Index: sys/ufs/lfs/lfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v
retrieving revision 1.183
diff -p -u -4 -r1.183 lfs_vnops.c
--- sys/ufs/lfs/lfs_vnops.c 13 Jul 2006 22:08:00 -0000 1.183
+++ sys/ufs/lfs/lfs_vnops.c 30 Jul 2006 16:54:11 -0000
@@ -87,8 +87,9 @@ __KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,
#include <sys/pool.h>
#include <sys/signalvar.h>
#include <sys/kauth.h>
#include <sys/syslog.h>
+#include <sys/fstrans.h>
#include <miscfs/fifofs/fifo.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/specfs/specdev.h>
Index: sys/kern/kern_exit.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exit.c,v
retrieving revision 1.157
diff -p -u -4 -r1.157 kern_exit.c
--- sys/kern/kern_exit.c 19 Jul 2006 21:11:37 -0000 1.157
+++ sys/kern/kern_exit.c 30 Jul 2006 16:54:06 -0000
@@ -113,8 +113,9 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exit.c,
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/systrace.h>
#include <sys/kauth.h>
+#include <sys/fstrans.h>
#include <machine/cpu.h>
#include <uvm/uvm_extern.h>
@@ -358,8 +359,9 @@ exit1(struct lwp *l, int rv)
*/
#ifndef __NO_CPU_LWP_FREE
cpu_lwp_free(l, 1);
#endif
+ fstrans_exit(l);
pmap_deactivate(l);
/*
Index: sys/kern/tty_ptm.c
===================================================================
RCS file: /cvsroot/src/sys/kern/tty_ptm.c,v
retrieving revision 1.10
diff -p -u -4 -r1.10 tty_ptm.c
--- sys/kern/tty_ptm.c 17 Jul 2006 14:49:16 -0000 1.10
+++ sys/kern/tty_ptm.c 30 Jul 2006 16:54:06 -0000
@@ -48,8 +48,9 @@ __KERNEL_RCSID(0, "$NetBSD: tty_ptm.c,v
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/kernel.h>
+#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/namei.h>
#include <sys/signalvar.h>
#include <sys/uio.h>
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.267
diff -p -u -4 -r1.267 vfs_subr.c
--- sys/kern/vfs_subr.c 23 Jun 2006 14:13:02 -0000 1.267
+++ sys/kern/vfs_subr.c 30 Jul 2006 16:54:06 -0000
@@ -358,8 +358,9 @@ vfs_rootmountalloc(const char *fstypenam
return (ENODEV);
mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
memset((char *)mp, 0, (u_long)sizeof(struct mount));
lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+ lockinit(&mp->mnt_trans_lock, PVFS, "suspfs", 0, 0);
simple_lock_init(&mp->mnt_slock);
(void)vfs_busy(mp, LK_NOWAIT, 0);
LIST_INIT(&mp->mnt_vnodelist);
mp->mnt_op = vfsp;
@@ -1203,9 +1204,16 @@ vget(struct vnode *vp, int flags)
}
#endif
if (flags & LK_TYPE_MASK) {
if ((error = vn_lock(vp, flags | LK_INTERLOCK))) {
- vrele(vp);
+ simple_lock(&vp->v_interlock);
+ if (vp->v_usecount > 1) {
+ vp->v_usecount--;
+ simple_unlock(&vp->v_interlock);
+ } else {
+ simple_unlock(&vp->v_interlock);
+ vrele(vp);
+ }
}
return (error);
}
simple_unlock(&vp->v_interlock);
@@ -2434,62 +2442,8 @@ vfs_reinit(void)
}
}
}
-/*
- * Request a filesystem to suspend write operations.
- */
-int
-vfs_write_suspend(struct mount *mp, int slpflag, int slptimeo)
-{
- struct lwp *l = curlwp; /* XXX */
- int error;
-
- while ((mp->mnt_iflag & IMNT_SUSPEND)) {
- if (slptimeo < 0)
- return EWOULDBLOCK;
- error = tsleep(&mp->mnt_flag, slpflag, "suspwt1", slptimeo);
- if (error)
- return error;
- }
- mp->mnt_iflag |= IMNT_SUSPEND;
-
- simple_lock(&mp->mnt_slock);
- if (mp->mnt_writeopcountupper > 0)
- ltsleep(&mp->mnt_writeopcountupper, PUSER - 1, "suspwt",
- 0, &mp->mnt_slock);
- simple_unlock(&mp->mnt_slock);
-
- error = VFS_SYNC(mp, MNT_WAIT, l->l_proc->p_cred, l);
- if (error) {
- vfs_write_resume(mp);
- return error;
- }
- mp->mnt_iflag |= IMNT_SUSPENDLOW;
-
- simple_lock(&mp->mnt_slock);
- if (mp->mnt_writeopcountlower > 0)
- ltsleep(&mp->mnt_writeopcountlower, PUSER - 1, "suspwt",
- 0, &mp->mnt_slock);
- mp->mnt_iflag |= IMNT_SUSPENDED;
- simple_unlock(&mp->mnt_slock);
-
- return 0;
-}
-
-/*
- * Request a filesystem to resume write operations.
- */
-void
-vfs_write_resume(struct mount *mp)
-{
-
- if ((mp->mnt_iflag & IMNT_SUSPEND) == 0)
- return;
- mp->mnt_iflag &= ~(IMNT_SUSPEND | IMNT_SUSPENDLOW | IMNT_SUSPENDED);
- wakeup(&mp->mnt_flag);
-}
-
void
copy_statvfs_info(struct statvfs *sbp, const struct mount *mp)
{
const struct statvfs *mbp;
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.254
diff -p -u -4 -r1.254 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c 19 Jul 2006 12:45:19 -0000 1.254
+++ sys/kern/vfs_syscalls.c 30 Jul 2006 16:54:07 -0000
@@ -324,8 +324,9 @@ sys_mount(struct lwp *l, void *v, regist
mp = (struct mount *)malloc((u_long)sizeof(struct mount),
M_MOUNT, M_WAITOK);
memset((char *)mp, 0, (u_long)sizeof(struct mount));
lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+ lockinit(&mp->mnt_trans_lock, PVFS, "suspfs", 0, 0);
simple_lock_init(&mp->mnt_slock);
(void)vfs_busy(mp, LK_NOWAIT, 0);
mp->mnt_op = vfs;
vfs->vfs_refcount++;
@@ -650,8 +651,9 @@ dounmount(struct mount *mp, int flags, s
if (LIST_FIRST(&mp->mnt_vnodelist) != NULL)
panic("unmount: dangling vnode");
mp->mnt_iflag |= IMNT_GONE;
lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock);
+ lockmgr(&mp->mnt_trans_lock, LK_DRAIN, NULL);
if (used_syncer)
lockmgr(&syncer_lock, LK_RELEASE, NULL);
simple_lock(&mp->mnt_slock);
while (mp->mnt_wcnt > 0) {
Index: sys/kern/vfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.114
diff -p -u -4 -r1.114 vfs_vnops.c
--- sys/kern/vfs_vnops.c 16 Jul 2006 18:49:29 -0000 1.114
+++ sys/kern/vfs_vnops.c 30 Jul 2006 16:54:07 -0000
@@ -963,8 +963,10 @@ vn_start_write(struct vnode *vp, struct
}
if ((mp = *mpp) == NULL)
return (0);
mp = mp->mnt_leaf;
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) != 0)
+ return 0;
/*
* Check on status of suspension.
*/
prio = PUSER - 1;
@@ -1004,8 +1006,10 @@ vn_finished_write(struct mount *mp, int
{
if (mp == NULL)
return;
mp = mp->mnt_leaf;
+ if ((mp->mnt_iflag & IMNT_HAS_TRANS) != 0)
+ return;
simple_lock(&mp->mnt_slock);
if ((flags & V_LOWER) == 0) {
mp->mnt_writeopcountupper--;
if (mp->mnt_writeopcountupper < 0)
Index: sys/uvm/uvm_pdaemon.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_pdaemon.c,v
retrieving revision 1.76
diff -p -u -4 -r1.76 uvm_pdaemon.c
--- sys/uvm/uvm_pdaemon.c 14 Feb 2006 15:06:27 -0000 1.76
+++ sys/uvm/uvm_pdaemon.c 30 Jul 2006 16:54:13 -0000
@@ -82,8 +82,9 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.
#include <sys/kernel.h>
#include <sys/pool.h>
#include <sys/buf.h>
#include <sys/vnode.h>
+#include <sys/fstrans.h>
#include <uvm/uvm.h>
/*
@@ -174,13 +175,8 @@ uvmpd_tune(void)
UVMHIST_FUNC("uvmpd_tune"); UVMHIST_CALLED(pdhist);
uvmexp.freemin = uvmexp.npages / 20;
- /* between 16k and 256k */
- /* XXX: what are these values good for? */
- uvmexp.freemin = MAX(uvmexp.freemin, (16*1024) >> PAGE_SHIFT);
- uvmexp.freemin = MIN(uvmexp.freemin, (256*1024) >> PAGE_SHIFT);
-
/* Make sure there's always a user page free. */
if (uvmexp.freemin < uvmexp.reserve_kernel + 1)
uvmexp.freemin = uvmexp.reserve_kernel + 1;
@@ -704,12 +700,22 @@ uvmpd_scan_inactive(struct pglist *pglst
}
#endif /* defined(READAHEAD_STATS) */
if ((p->pqflags & PQ_SWAPBACKED) == 0) {
+ struct vnode *vp = (struct vnode *)uobj;
+
+ if (UVM_OBJ_IS_VNODE(uobj) && fstrans_start(vp->v_mount,
+ FSTRANS_SHARED | FSTRANS_NOWAIT) != 0) {
+ uvmexp.pdobscan--;
+ simple_unlock(slock);
+ continue;
+ }
uvm_unlock_pageq();
(void) (uobj->pgops->pgo_put)(uobj, p->offset,
p->offset + PAGE_SIZE, PGO_CLEANIT|PGO_FREE);
uvm_lock_pageq();
+ if (UVM_OBJ_IS_VNODE(uobj))
+ fstrans_done(vp->v_mount);
if (nextpg &&
(nextpg->pqflags & PQ_INACTIVE) == 0) {
nextpg = TAILQ_FIRST(pglst);
}
Index: common/lib/libc/gmon/mcount.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/gmon/mcount.c,v
retrieving revision 1.5
diff -p -u -4 -r1.5 mcount.c
--- common/lib/libc/gmon/mcount.c 8 Jan 2006 07:46:39 -0000 1.5
+++ common/lib/libc/gmon/mcount.c 30 Jul 2006 16:52:50 -0000
@@ -94,9 +94,9 @@ struct gmonparam *_m_gmon_alloc(void);
#endif
_MCOUNT_DECL __P((u_long, u_long))
#ifdef _KERNEL
- __attribute__((__unused__,__no_instrument_function__)); /* see below. */
+ __attribute__((__used__,__no_instrument_function__)); /* see below. */
#else
#ifdef __vax__
__attribute__((__unused__)); /* see below. */
#else
Index: sys/arch/sparc64/dev/psm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/dev/psm.c,v
retrieving revision 1.2
diff -p -u -4 -r1.2 psm.c
--- sys/arch/sparc64/dev/psm.c 12 Jul 2006 15:03:24 -0000 1.2
+++ sys/arch/sparc64/dev/psm.c 30 Jul 2006 16:54:02 -0000
@@ -127,9 +127,9 @@ STATIC void psm_attach(struct device *,
CFATTACH_DECL(psm, sizeof(struct psm_softc),
psm_match, psm_attach, NULL, NULL);
-static int
+STATIC int
psm_match(struct device *parent, struct cfdata *cf, void *aux)
{
struct ebus_attach_args *ea = aux;
@@ -137,9 +137,9 @@ psm_match(struct device *parent, struct
return (0);
return (1);
}
-static void
+STATIC void
psm_attach(struct device *parent, struct device *self, void *aux)
{
struct psm_softc *sc = (struct psm_softc *)self;
struct ebus_attach_args *ea = aux;
Index: sys/arch/xen/i386/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/i386/autoconf.c,v
retrieving revision 1.17
diff -p -u -4 -r1.17 autoconf.c
--- sys/arch/xen/i386/autoconf.c 15 May 2006 00:55:57 -0000 1.17
+++ sys/arch/xen/i386/autoconf.c 30 Jul 2006 16:54:03 -0000
@@ -63,8 +63,9 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v
#include <sys/reboot.h>
#endif
#include <sys/device.h>
#include <sys/malloc.h>
+#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/fcntl.h>
#include <sys/dkio.h>
#include <sys/proc.h>
Index: sys/conf/files
===================================================================
RCS file: /cvsroot/src/sys/conf/files,v
retrieving revision 1.789
diff -p -u -4 -r1.789 files
--- sys/conf/files 14 Jul 2006 18:41:40 -0000 1.789
+++ sys/conf/files 30 Jul 2006 16:54:03 -0000
@@ -1319,8 +1319,9 @@ file kern/vfs_init.c
file kern/vfs_lockf.c
file kern/vfs_lookup.c
file kern/vfs_subr.c
file kern/vfs_syscalls.c
+file kern/vfs_trans.c
file kern/vfs_vnops.c
file kern/vfs_xattr.c
file kern/vnode_if.c
file miscfs/deadfs/dead_vnops.c
Index: sys/dev/fss.c
===================================================================
RCS file: /cvsroot/src/sys/dev/fss.c,v
retrieving revision 1.26
diff -p -u -4 -r1.26 fss.c
--- sys/dev/fss.c 14 May 2006 21:42:26 -0000 1.26
+++ sys/dev/fss.c 30 Jul 2006 16:54:04 -0000
@@ -64,8 +64,9 @@ __KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.26
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/conf.h>
#include <sys/kthread.h>
+#include <sys/fstrans.h>
#include <miscfs/specfs/specdev.h>
#include <dev/fssvar.h>
@@ -739,9 +740,9 @@ fss_create_snapshot(struct fss_softc *sc
/*
* Activate the snapshot.
*/
- if ((error = vfs_write_suspend(sc->sc_mount, PUSER|PCATCH, 0)) != 0)
+ if ((error = vfs_suspend(sc->sc_mount, 0)) != 0)
goto bad;
microtime(&sc->sc_time);
@@ -750,9 +751,9 @@ fss_create_snapshot(struct fss_softc *sc
fss_copy_on_write, sc);
if (error == 0)
sc->sc_flags |= FSS_ACTIVE;
- vfs_write_resume(sc->sc_mount);
+ vfs_resume(sc->sc_mount);
if (error != 0)
goto bad;
@@ -1083,9 +1084,11 @@ fss_bs_thread(void *arg)
if (error) {
bp->b_error = error;
bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
- }
+ } else
+ bp->b_resid = 0;
+
biodone(bp);
continue;
}
Index: sys/fs/sysvbfs/sysvbfs.c
===================================================================
RCS file: /cvsroot/src/sys/fs/sysvbfs/sysvbfs.c,v
retrieving revision 1.2
diff -p -u -4 -r1.2 sysvbfs.c
--- sys/fs/sysvbfs/sysvbfs.c 1 Jul 2006 08:42:39 -0000 1.2
+++ sys/fs/sysvbfs/sysvbfs.c 30 Jul 2006 16:54:05 -0000
@@ -131,7 +131,8 @@ struct vfsops sysvbfs_vfsops = {
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *))
eopnotsupp, /* snapshot */
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
sysvbfs_vnodeopv_descs,
};
VFS_ATTACH(sysvbfs_vfsops);
Index: sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.99
diff -p -u -4 -r1.99 ext2fs_vfsops.c
--- sys/ufs/ext2fs/ext2fs_vfsops.c 13 Jul 2006 12:00:26 -0000 1.99
+++ sys/ufs/ext2fs/ext2fs_vfsops.c 30 Jul 2006 16:54:09 -0000
@@ -138,8 +138,9 @@ struct vfsops ext2fs_vfsops = {
ext2fs_done,
ext2fs_mountroot,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
ext2fs_vnodeopv_descs,
};
VFS_ATTACH(ext2fs_vfsops);
Index: sys/ufs/lfs/lfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vfsops.c,v
retrieving revision 1.216
diff -p -u -4 -r1.216 lfs_vfsops.c
--- sys/ufs/lfs/lfs_vfsops.c 13 Jul 2006 12:00:26 -0000 1.216
+++ sys/ufs/lfs/lfs_vfsops.c 30 Jul 2006 16:54:11 -0000
@@ -155,8 +155,9 @@ struct vfsops lfs_vfsops = {
lfs_done,
lfs_mountroot,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
lfs_vnodeopv_descs,
};
VFS_ATTACH(lfs_vfsops);
Index: sys/ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.72
diff -p -u -4 -r1.72 mfs_vfsops.c
--- sys/ufs/mfs/mfs_vfsops.c 15 Apr 2006 01:16:40 -0000 1.72
+++ sys/ufs/mfs/mfs_vfsops.c 30 Jul 2006 16:54:11 -0000
@@ -101,8 +101,9 @@ struct vfsops mfs_vfsops = {
mfs_done,
NULL,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
mfs_vnodeopv_descs,
};
VFS_ATTACH(mfs_vfsops);
Index: sys/coda/coda_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/coda/coda_vfsops.c,v
retrieving revision 1.48
diff -p -u -4 -r1.48 coda_vfsops.c
--- sys/coda/coda_vfsops.c 14 May 2006 21:24:49 -0000 1.48
+++ sys/coda/coda_vfsops.c 30 Jul 2006 16:54:03 -0000
@@ -118,8 +118,9 @@ struct vfsops coda_vfsops = {
coda_done,
(int (*)(void)) eopnotsupp,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
coda_vnodeopv_descs,
0
};
Index: sys/fs/adosfs/advfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/adosfs/advfsops.c,v
retrieving revision 1.29
diff -p -u -4 -r1.29 advfsops.c
--- sys/fs/adosfs/advfsops.c 13 Jul 2006 12:00:25 -0000 1.29
+++ sys/fs/adosfs/advfsops.c 30 Jul 2006 16:54:05 -0000
@@ -864,7 +864,8 @@ struct vfsops adosfs_vfsops = {
adosfs_done,
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
adosfs_vnodeopv_descs,
};
VFS_ATTACH(adosfs_vfsops);
Index: sys/fs/cd9660/cd9660_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.33
diff -p -u -4 -r1.33 cd9660_vfsops.c
--- sys/fs/cd9660/cd9660_vfsops.c 13 Jul 2006 12:00:25 -0000 1.33
+++ sys/fs/cd9660/cd9660_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -102,8 +102,9 @@ struct vfsops cd9660_vfsops = {
cd9660_done,
cd9660_mountroot,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
cd9660_vnodeopv_descs,
};
VFS_ATTACH(cd9660_vfsops);
Index: sys/fs/filecorefs/filecore_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/filecorefs/filecore_vfsops.c,v
retrieving revision 1.26
diff -p -u -4 -r1.26 filecore_vfsops.c
--- sys/fs/filecorefs/filecore_vfsops.c 13 Jul 2006 12:00:25 -0000 1.26
+++ sys/fs/filecorefs/filecore_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -120,8 +120,9 @@ struct vfsops filecore_vfsops = {
filecore_done,
NULL, /* filecore_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
filecore_vnodeopv_descs,
};
VFS_ATTACH(filecore_vfsops);
Index: sys/fs/msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.32
diff -p -u -4 -r1.32 msdosfs_vfsops.c
--- sys/fs/msdosfs/msdosfs_vfsops.c 13 Jul 2006 12:00:25 -0000 1.32
+++ sys/fs/msdosfs/msdosfs_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -132,8 +132,9 @@ struct vfsops msdosfs_vfsops = {
msdosfs_done,
msdosfs_mountroot,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
msdosfs_vnodeopv_descs,
};
VFS_ATTACH(msdosfs_vfsops);
Index: sys/fs/ntfs/ntfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/ntfs/ntfs_vfsops.c,v
retrieving revision 1.42
diff -p -u -4 -r1.42 ntfs_vfsops.c
--- sys/fs/ntfs/ntfs_vfsops.c 13 Jul 2006 12:00:25 -0000 1.42
+++ sys/fs/ntfs/ntfs_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -1020,8 +1020,9 @@ struct vfsops ntfs_vfsops = {
ntfs_done,
ntfs_mountroot,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
ntfs_vnodeopv_descs,
};
VFS_ATTACH(ntfs_vfsops);
#endif
Index: sys/fs/ptyfs/ptyfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vfsops.c,v
retrieving revision 1.17
diff -p -u -4 -r1.17 ptyfs_vfsops.c
--- sys/fs/ptyfs/ptyfs_vfsops.c 20 Jun 2006 09:17:14 -0000 1.17
+++ sys/fs/ptyfs/ptyfs_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -412,7 +412,8 @@ struct vfsops ptyfs_vfsops = {
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *))eopnotsupp,
(int (*)(struct mount *, int, struct vnode *, int, const char *,
struct lwp *))eopnotsupp,
+ vfs_stdsuspendctl,
ptyfs_vnodeopv_descs,
};
VFS_ATTACH(ptyfs_vfsops);
Index: sys/fs/smbfs/smbfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_vfsops.c,v
retrieving revision 1.52
diff -p -u -4 -r1.52 smbfs_vfsops.c
--- sys/fs/smbfs/smbfs_vfsops.c 14 May 2006 21:31:52 -0000 1.52
+++ sys/fs/smbfs/smbfs_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -137,8 +137,9 @@ struct vfsops smbfs_vfsops = {
smbfs_done,
(int (*) (void)) eopnotsupp, /* mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
smbfs_vnodeopv_descs,
};
VFS_ATTACH(smbfs_vfsops);
Index: sys/fs/tmpfs/tmpfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_vfsops.c,v
retrieving revision 1.13
diff -p -u -4 -r1.13 tmpfs_vfsops.c
--- sys/fs/tmpfs/tmpfs_vfsops.c 13 Jul 2006 12:00:25 -0000 1.13
+++ sys/fs/tmpfs/tmpfs_vfsops.c 30 Jul 2006 16:54:05 -0000
@@ -466,7 +466,8 @@ struct vfsops tmpfs_vfsops = {
tmpfs_done, /* vfs_done */
NULL, /* vfs_mountroot */
tmpfs_snapshot, /* vfs_snapshot */
vfs_stdextattrctl, /* vfs_extattrctl */
+ vfs_stdsuspendctl, /* vfs_suspendctl */
tmpfs_vnodeopv_descs,
};
VFS_ATTACH(tmpfs_vfsops);
Index: sys/fs/udf/udf_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/udf/udf_vfsops.c,v
retrieving revision 1.7
diff -p -u -4 -r1.7 udf_vfsops.c
--- sys/fs/udf/udf_vfsops.c 13 Jul 2006 12:00:25 -0000 1.7
+++ sys/fs/udf/udf_vfsops.c 30 Jul 2006 16:54:06 -0000
@@ -142,8 +142,9 @@ struct vfsops udf_vfsops = {
udf_done,
udf_mountroot,
udf_snapshot,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
udf_vnodeopv_descs,
/* int vfs_refcount */
/* LIST_ENTRY(vfsops) */
};
Index: sys/fs/union/union_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/union/union_vfsops.c,v
retrieving revision 1.35
diff -p -u -4 -r1.35 union_vfsops.c
--- sys/fs/union/union_vfsops.c 14 May 2006 21:31:52 -0000 1.35
+++ sys/fs/union/union_vfsops.c 30 Jul 2006 16:54:06 -0000
@@ -581,7 +581,8 @@ struct vfsops union_vfsops = {
union_done,
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
union_vnodeopv_descs,
};
VFS_ATTACH(union_vfsops);
Index: sys/miscfs/fdesc/fdesc_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/fdesc/fdesc_vfsops.c,v
retrieving revision 1.59
diff -p -u -4 -r1.59 fdesc_vfsops.c
--- sys/miscfs/fdesc/fdesc_vfsops.c 14 May 2006 21:31:52 -0000 1.59
+++ sys/miscfs/fdesc/fdesc_vfsops.c 30 Jul 2006 16:54:07 -0000
@@ -316,7 +316,8 @@ struct vfsops fdesc_vfsops = {
fdesc_done,
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
fdesc_vnodeopv_descs,
};
VFS_ATTACH(fdesc_vfsops);
Index: sys/miscfs/kernfs/kernfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/kernfs/kernfs_vfsops.c,v
retrieving revision 1.71
diff -p -u -4 -r1.71 kernfs_vfsops.c
--- sys/miscfs/kernfs/kernfs_vfsops.c 14 May 2006 21:31:52 -0000 1.71
+++ sys/miscfs/kernfs/kernfs_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -318,7 +318,8 @@ struct vfsops kernfs_vfsops = {
kernfs_done,
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
kernfs_vnodeopv_descs,
};
VFS_ATTACH(kernfs_vfsops);
Index: sys/miscfs/nullfs/null_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/nullfs/null_vfsops.c,v
retrieving revision 1.58
diff -p -u -4 -r1.58 null_vfsops.c
--- sys/miscfs/nullfs/null_vfsops.c 11 Dec 2005 12:24:51 -0000 1.58
+++ sys/miscfs/nullfs/null_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -312,7 +312,8 @@ struct vfsops nullfs_vfsops = {
layerfs_done,
NULL, /* vfs_mountroot */
layerfs_snapshot,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
nullfs_vnodeopv_descs,
};
VFS_ATTACH(nullfs_vfsops);
Index: sys/miscfs/overlay/overlay_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/overlay/overlay_vfsops.c,v
retrieving revision 1.33
diff -p -u -4 -r1.33 overlay_vfsops.c
--- sys/miscfs/overlay/overlay_vfsops.c 11 Dec 2005 12:24:51 -0000 1.33
+++ sys/miscfs/overlay/overlay_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -295,7 +295,8 @@ struct vfsops overlay_vfsops = {
layerfs_done,
NULL, /* vfs_mountroot */
layerfs_snapshot,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
ov_vnodeopv_descs,
};
VFS_ATTACH(overlay_vfsops);
Index: sys/miscfs/portal/portal_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/portal/portal_vfsops.c,v
retrieving revision 1.55
diff -p -u -4 -r1.55 portal_vfsops.c
--- sys/miscfs/portal/portal_vfsops.c 14 May 2006 21:31:53 -0000 1.55
+++ sys/miscfs/portal/portal_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -349,7 +349,8 @@ struct vfsops portal_vfsops = {
portal_done,
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
portal_vnodeopv_descs,
};
VFS_ATTACH(portal_vfsops);
Index: sys/miscfs/procfs/procfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vfsops.c,v
retrieving revision 1.64
diff -p -u -4 -r1.64 procfs_vfsops.c
--- sys/miscfs/procfs/procfs_vfsops.c 14 May 2006 21:31:53 -0000 1.64
+++ sys/miscfs/procfs/procfs_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -344,7 +344,8 @@ struct vfsops procfs_vfsops = {
procfs_done,
NULL, /* vfs_mountroot */
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
procfs_vnodeopv_descs,
};
VFS_ATTACH(procfs_vfsops);
Index: sys/miscfs/umapfs/umap_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/umapfs/umap_vfsops.c,v
retrieving revision 1.57
diff -p -u -4 -r1.57 umap_vfsops.c
--- sys/miscfs/umapfs/umap_vfsops.c 14 May 2006 21:32:21 -0000 1.57
+++ sys/miscfs/umapfs/umap_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -334,7 +334,8 @@ struct vfsops umapfs_vfsops = {
layerfs_done,
NULL, /* vfs_mountroot */
layerfs_snapshot,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
umapfs_vnodeopv_descs,
};
VFS_ATTACH(umapfs_vfsops);
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.158
diff -p -u -4 -r1.158 nfs_vfsops.c
--- sys/nfs/nfs_vfsops.c 13 Jul 2006 12:00:26 -0000 1.158
+++ sys/nfs/nfs_vfsops.c 30 Jul 2006 16:54:08 -0000
@@ -119,8 +119,9 @@ struct vfsops nfs_vfsops = {
nfs_vfs_done,
nfs_mountroot,
(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
vfs_stdextattrctl,
+ vfs_stdsuspendctl,
nfs_vnodeopv_descs,
};
VFS_ATTACH(nfs_vfsops);
--bp/iNruPH9dso1Pn--