Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133614863
D25573.id74219.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D25573.id74219.diff
View Options
Index: sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
===================================================================
--- sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
+++ sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
@@ -154,6 +154,7 @@
vput(vp);
return (error);
}
+ vn_seqc_write_begin(vp);
VOP_UNLOCK(vp);
/*
@@ -206,6 +207,7 @@
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
+ vn_seqc_write_end(vp);
vput(vp);
vfs_unbusy(mp);
vfs_freeopts(mp->mnt_optnew);
@@ -241,6 +243,7 @@
vfs_event_signal(NULL, VQ_MOUNT, 0);
if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp))
panic("mount: lost mount");
+ vn_seqc_write_end(vp);
VOP_UNLOCK(vp);
vfs_op_exit(mp);
vfs_unbusy(mp);
Index: sys/kern/vfs_mount.c
===================================================================
--- sys/kern/vfs_mount.c
+++ sys/kern/vfs_mount.c
@@ -947,6 +947,7 @@
vput(vp);
return (error);
}
+ vn_seqc_write_begin(vp);
VOP_UNLOCK(vp);
/* Allocate and initialize the filesystem. */
@@ -979,9 +980,11 @@
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
+ vn_seqc_write_end(vp);
vrele(vp);
return (error);
}
+ vn_seqc_write_begin(newdp);
VOP_UNLOCK(newdp);
if (mp->mnt_opt != NULL)
@@ -1018,6 +1021,8 @@
EVENTHANDLER_DIRECT_INVOKE(vfs_mounted, mp, newdp, td);
VOP_UNLOCK(newdp);
mountcheckdirs(vp, newdp);
+ vn_seqc_write_end(vp);
+ vn_seqc_write_end(newdp);
vrele(newdp);
if ((mp->mnt_flag & MNT_RDONLY) == 0)
vfs_allocate_syncvnode(mp);
@@ -1094,7 +1099,9 @@
VOP_UNLOCK(vp);
vfs_op_enter(mp);
+ vn_seqc_write_begin(vp);
+ rootvp = NULL;
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) {
MNT_IUNLOCK(mp);
@@ -1108,8 +1115,6 @@
mp->mnt_kern_flag &= ~MNTK_ASYNC;
rootvp = vfs_cache_root_clear(mp);
MNT_IUNLOCK(mp);
- if (rootvp != NULL)
- vrele(rootvp);
mp->mnt_optnew = *optlist;
vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt);
@@ -1233,6 +1238,11 @@
vfs_deallocate_syncvnode(mp);
end:
vfs_op_exit(mp);
+ if (rootvp != NULL) {
+ vn_seqc_write_end(rootvp);
+ vrele(rootvp);
+ }
+ vn_seqc_write_end(vp);
vfs_unbusy(mp);
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
@@ -1723,14 +1733,19 @@
}
mp->mnt_kern_flag |= MNTK_UNMOUNT;
rootvp = vfs_cache_root_clear(mp);
+ if (coveredvp != NULL)
+ vn_seqc_write_begin(coveredvp);
if (flags & MNT_NONBUSY) {
MNT_IUNLOCK(mp);
error = vfs_check_usecounts(mp);
MNT_ILOCK(mp);
if (error != 0) {
+ vn_seqc_write_end(coveredvp);
dounmount_cleanup(mp, coveredvp, MNTK_UNMOUNT);
- if (rootvp != NULL)
+ if (rootvp != NULL) {
+ vn_seqc_write_end(rootvp);
vrele(rootvp);
+ }
return (error);
}
}
@@ -1759,22 +1774,19 @@
("%s: invalid return value for msleep in the drain path @ %s:%d",
__func__, __FILE__, __LINE__));
- if (rootvp != NULL)
+ /*
+ * We want to keep the vnode around so that we can vn_seqc_write_end
+ * after we are done with unmount. Downgrade our reference to a mere
+ * hold count so that we don't interefere with anything.
+ */
+ if (rootvp != NULL) {
+ vhold(rootvp);
vrele(rootvp);
+ }
if (mp->mnt_flag & MNT_EXPUBLIC)
vfs_setpublicfs(NULL, NULL, NULL);
- /*
- * From now, we can claim that the use reference on the
- * coveredvp is ours, and the ref can be released only by
- * successfull unmount by us, or left for later unmount
- * attempt. The previously acquired hold reference is no
- * longer needed to protect the vnode from reuse.
- */
- if (coveredvp != NULL)
- vdrop(coveredvp);
-
vfs_periodic(mp, MNT_WAIT);
MNT_ILOCK(mp);
async_flag = mp->mnt_flag & MNT_ASYNC;
@@ -1809,8 +1821,15 @@
}
vfs_op_exit_locked(mp);
MNT_IUNLOCK(mp);
- if (coveredvp)
+ if (coveredvp) {
+ vn_seqc_write_end(coveredvp);
VOP_UNLOCK(coveredvp);
+ vdrop(coveredvp);
+ }
+ if (rootvp != NULL) {
+ vn_seqc_write_end(rootvp);
+ vdrop(rootvp);
+ }
return (error);
}
mtx_lock(&mountlist_mtx);
@@ -1819,7 +1838,13 @@
EVENTHANDLER_DIRECT_INVOKE(vfs_unmounted, mp, td);
if (coveredvp != NULL) {
coveredvp->v_mountedhere = NULL;
+ vn_seqc_write_end(coveredvp);
VOP_UNLOCK(coveredvp);
+ vdrop(coveredvp);
+ }
+ if (rootvp != NULL) {
+ vn_seqc_write_end(rootvp);
+ vdrop(rootvp);
}
vfs_event_signal(NULL, VQ_UNMOUNT, 0);
if (rootvnode != NULL && mp == rootvnode->v_mount) {
Index: sys/kern/vfs_subr.c
===================================================================
--- sys/kern/vfs_subr.c
+++ sys/kern/vfs_subr.c
@@ -1760,6 +1760,12 @@
* so as not to contaminate the freshly allocated vnode.
*/
CTR2(KTR_VFS, "%s: destroying the vnode %p", __func__, vp);
+ /*
+ * Paired with vgone.
+ */
+ vn_seqc_write_end_locked(vp);
+ VNPASS(vp->v_seqc_users == 0, vp);
+
bo = &vp->v_bufobj;
VNASSERT(vp->v_data == NULL, vp, ("cleaned vnode isn't"));
VNPASS(vp->v_holdcnt == VHOLD_NO_SMR, vp);
@@ -3999,6 +4005,10 @@
*/
if (vp->v_irflag & VIRF_DOOMED)
return;
+ /*
+ * Paired with freevnode.
+ */
+ vn_seqc_write_begin_locked(vp);
vunlazy_gone(vp);
vp->v_irflag |= VIRF_DOOMED;
@@ -4141,8 +4151,9 @@
printf("%p: ", (void *)vp);
printf("type %s\n", typename[vp->v_type]);
holdcnt = atomic_load_int(&vp->v_holdcnt);
- printf(" usecount %d, writecount %d, refcount %d",
- vp->v_usecount, vp->v_writecount, holdcnt & ~VHOLD_ALL_FLAGS);
+ printf(" usecount %d, writecount %d, refcount %d seqc users %d",
+ vp->v_usecount, vp->v_writecount, holdcnt & ~VHOLD_ALL_FLAGS,
+ vp->v_seqc_users);
switch (vp->v_type) {
case VDIR:
printf(" mountedhere %p\n", vp->v_mountedhere);
@@ -5489,6 +5500,14 @@
ASSERT_VOP_LOCKED(a->a_tvp, "vop_rename: tvp not locked");
ASSERT_VOP_LOCKED(a->a_tdvp, "vop_rename: tdvp not locked");
#endif
+ /*
+ * It may be tempting to add vn_seqc_write_begin/end calls here and
+ * in vop_rename_post but that's not going to work out since some
+ * filesystems relookup vnodes mid-rename. This is probably a bug.
+ *
+ * For now filesystems are expected to do the relevant calls after they
+ * decide what vnodes to operate on.
+ */
if (a->a_tdvp != a->a_fdvp)
vhold(a->a_fdvp);
if (a->a_tvp != a->a_fvp)
@@ -5569,70 +5588,194 @@
}
#endif
+void
+vop_create_pre(void *ap)
+{
+ struct vop_create_args *a;
+ struct vnode *dvp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_begin(dvp);
+}
+
void
vop_create_post(void *ap, int rc)
{
- struct vop_create_args *a = ap;
+ struct vop_create_args *a;
+ struct vnode *dvp;
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_end(dvp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE);
+ VFS_KNOTE_LOCKED(dvp, NOTE_WRITE);
+}
+
+void
+vop_whiteout_pre(void *ap)
+{
+ struct vop_whiteout_args *a;
+ struct vnode *dvp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_begin(dvp);
+}
+
+void
+vop_whiteout_post(void *ap, int rc)
+{
+ struct vop_whiteout_args *a;
+ struct vnode *dvp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_end(dvp);
+}
+
+void
+vop_deleteextattr_pre(void *ap)
+{
+ struct vop_deleteextattr_args *a;
+ struct vnode *vp;
+
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_begin(vp);
}
void
vop_deleteextattr_post(void *ap, int rc)
{
- struct vop_deleteextattr_args *a = ap;
+ struct vop_deleteextattr_args *a;
+ struct vnode *vp;
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_end(vp);
if (!rc)
VFS_KNOTE_LOCKED(a->a_vp, NOTE_ATTRIB);
}
+void
+vop_link_pre(void *ap)
+{
+ struct vop_link_args *a;
+ struct vnode *vp, *tdvp;
+
+ a = ap;
+ vp = a->a_vp;
+ tdvp = a->a_tdvp;
+ vn_seqc_write_begin(vp);
+ vn_seqc_write_begin(tdvp);
+}
+
void
vop_link_post(void *ap, int rc)
{
- struct vop_link_args *a = ap;
+ struct vop_link_args *a;
+ struct vnode *vp, *tdvp;
+ a = ap;
+ vp = a->a_vp;
+ tdvp = a->a_tdvp;
+ vn_seqc_write_end(vp);
+ vn_seqc_write_end(tdvp);
if (!rc) {
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_LINK);
- VFS_KNOTE_LOCKED(a->a_tdvp, NOTE_WRITE);
+ VFS_KNOTE_LOCKED(vp, NOTE_LINK);
+ VFS_KNOTE_LOCKED(tdvp, NOTE_WRITE);
}
}
+void
+vop_mkdir_pre(void *ap)
+{
+ struct vop_mkdir_args *a;
+ struct vnode *dvp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_begin(dvp);
+}
+
void
vop_mkdir_post(void *ap, int rc)
{
- struct vop_mkdir_args *a = ap;
+ struct vop_mkdir_args *a;
+ struct vnode *dvp;
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_end(dvp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE | NOTE_LINK);
+ VFS_KNOTE_LOCKED(dvp, NOTE_WRITE | NOTE_LINK);
+}
+
+void
+vop_mknod_pre(void *ap)
+{
+ struct vop_mknod_args *a;
+ struct vnode *dvp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_begin(dvp);
}
void
vop_mknod_post(void *ap, int rc)
{
- struct vop_mknod_args *a = ap;
+ struct vop_mknod_args *a;
+ struct vnode *dvp;
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_end(dvp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE);
+ VFS_KNOTE_LOCKED(dvp, NOTE_WRITE);
}
void
vop_reclaim_post(void *ap, int rc)
{
- struct vop_reclaim_args *a = ap;
+ struct vop_reclaim_args *a;
+ struct vnode *vp;
+ a = ap;
+ vp = a->a_vp;
+ ASSERT_VOP_IN_SEQC(vp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_REVOKE);
+ VFS_KNOTE_LOCKED(vp, NOTE_REVOKE);
+}
+
+void
+vop_remove_pre(void *ap)
+{
+ struct vop_remove_args *a;
+ struct vnode *dvp, *vp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vp = a->a_vp;
+ vn_seqc_write_begin(dvp);
+ vn_seqc_write_begin(vp);
}
void
vop_remove_post(void *ap, int rc)
{
- struct vop_remove_args *a = ap;
+ struct vop_remove_args *a;
+ struct vnode *dvp, *vp;
+ a = ap;
+ dvp = a->a_dvp;
+ vp = a->a_vp;
+ vn_seqc_write_end(dvp);
+ vn_seqc_write_end(vp);
if (!rc) {
- VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE);
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_DELETE);
+ VFS_KNOTE_LOCKED(dvp, NOTE_WRITE);
+ VFS_KNOTE_LOCKED(vp, NOTE_DELETE);
}
}
@@ -5674,42 +5817,128 @@
vdrop(a->a_tvp);
}
+void
+vop_rmdir_pre(void *ap)
+{
+ struct vop_rmdir_args *a;
+ struct vnode *dvp, *vp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vp = a->a_vp;
+ vn_seqc_write_begin(dvp);
+ vn_seqc_write_begin(vp);
+}
+
void
vop_rmdir_post(void *ap, int rc)
{
- struct vop_rmdir_args *a = ap;
+ struct vop_rmdir_args *a;
+ struct vnode *dvp, *vp;
+ a = ap;
+ dvp = a->a_dvp;
+ vp = a->a_vp;
+ vn_seqc_write_end(dvp);
+ vn_seqc_write_end(vp);
if (!rc) {
- VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE | NOTE_LINK);
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_DELETE);
+ VFS_KNOTE_LOCKED(dvp, NOTE_WRITE | NOTE_LINK);
+ VFS_KNOTE_LOCKED(vp, NOTE_DELETE);
}
}
+void
+vop_setattr_pre(void *ap)
+{
+ struct vop_setattr_args *a;
+ struct vnode *vp;
+
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_begin(vp);
+}
+
void
vop_setattr_post(void *ap, int rc)
{
- struct vop_setattr_args *a = ap;
+ struct vop_setattr_args *a;
+ struct vnode *vp;
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_end(vp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_ATTRIB);
+ VFS_KNOTE_LOCKED(vp, NOTE_ATTRIB);
+}
+
+void
+vop_setacl_pre(void *ap)
+{
+ struct vop_setacl_args *a;
+ struct vnode *vp;
+
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_begin(vp);
+}
+
+void
+vop_setacl_post(void *ap, int rc __unused)
+{
+ struct vop_setacl_args *a;
+ struct vnode *vp;
+
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_end(vp);
+}
+
+void
+vop_setextattr_pre(void *ap)
+{
+ struct vop_setextattr_args *a;
+ struct vnode *vp;
+
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_begin(vp);
}
void
vop_setextattr_post(void *ap, int rc)
{
- struct vop_setextattr_args *a = ap;
+ struct vop_setextattr_args *a;
+ struct vnode *vp;
+ a = ap;
+ vp = a->a_vp;
+ vn_seqc_write_end(vp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_ATTRIB);
+ VFS_KNOTE_LOCKED(vp, NOTE_ATTRIB);
+}
+
+void
+vop_symlink_pre(void *ap)
+{
+ struct vop_symlink_args *a;
+ struct vnode *dvp;
+
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_begin(dvp);
}
void
vop_symlink_post(void *ap, int rc)
{
- struct vop_symlink_args *a = ap;
+ struct vop_symlink_args *a;
+ struct vnode *dvp;
+ a = ap;
+ dvp = a->a_dvp;
+ vn_seqc_write_end(dvp);
if (!rc)
- VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE);
+ VFS_KNOTE_LOCKED(dvp, NOTE_WRITE);
}
void
@@ -6262,6 +6491,8 @@
*/
MPASS(mp->mnt_vfs_ops > 0);
vp = mp->mnt_rootvnode;
+ if (vp != NULL)
+ vn_seqc_write_begin(vp);
mp->mnt_rootvnode = NULL;
return (vp);
}
@@ -6558,3 +6789,44 @@
return (VOP_ACCESS(vp, VEXEC, cnp->cn_cred, cnp->cn_thread));
}
+
+void
+vn_seqc_write_begin_locked(struct vnode *vp)
+{
+
+ ASSERT_VI_LOCKED(vp, __func__);
+ VNPASS(vp->v_holdcnt > 0, vp);
+ VNPASS(vp->v_seqc_users >= 0, vp);
+ vp->v_seqc_users++;
+ if (vp->v_seqc_users == 1)
+ seqc_sleepable_write_begin(&vp->v_seqc);
+}
+
+void
+vn_seqc_write_begin(struct vnode *vp)
+{
+
+ VI_LOCK(vp);
+ vn_seqc_write_begin_locked(vp);
+ VI_UNLOCK(vp);
+}
+
+void
+vn_seqc_write_end_locked(struct vnode *vp)
+{
+
+ ASSERT_VI_LOCKED(vp, __func__);
+ VNPASS(vp->v_seqc_users > 0, vp);
+ vp->v_seqc_users--;
+ if (vp->v_seqc_users == 0)
+ seqc_sleepable_write_end(&vp->v_seqc);
+}
+
+void
+vn_seqc_write_end(struct vnode *vp)
+{
+
+ VI_LOCK(vp);
+ vn_seqc_write_end_locked(vp);
+ VI_UNLOCK(vp);
+}
Index: sys/kern/vnode_if.src
===================================================================
--- sys/kern/vnode_if.src
+++ sys/kern/vnode_if.src
@@ -88,6 +88,7 @@
%% create dvp E E E
%% create vpp - L -
+%! create pre vop_create_pre
%! create post vop_create_post
vop_create {
@@ -99,6 +100,8 @@
%% whiteout dvp E E E
+%! whiteout pre vop_whiteout_pre
+%! whiteout post vop_whiteout_post
vop_whiteout {
IN struct vnode *dvp;
@@ -109,6 +112,7 @@
%% mknod dvp E E E
%% mknod vpp - L -
+%! mknod pre vop_mknod_pre
%! mknod post vop_mknod_post
vop_mknod {
@@ -172,6 +176,7 @@
%% setattr vp E E E
+%! setattr pre vop_setattr_pre
%! setattr post vop_setattr_post
vop_setattr {
@@ -260,6 +265,7 @@
%% remove dvp E E E
%% remove vp E E E
+%! remove pre vop_remove_pre
%! remove post vop_remove_post
vop_remove {
@@ -271,6 +277,7 @@
%% link tdvp E E E
%% link vp E E E
+%! link pre vop_link_pre
%! link post vop_link_post
vop_link {
@@ -295,6 +302,7 @@
%% mkdir dvp E E E
%% mkdir vpp - E -
+%! mkdir pre vop_mkdir_pre
%! mkdir post vop_mkdir_post
vop_mkdir {
@@ -307,6 +315,7 @@
%% rmdir dvp E E E
%% rmdir vp E E E
+%! rmdir pre vop_rmdir_pre
%! rmdir post vop_rmdir_post
vop_rmdir {
@@ -318,6 +327,7 @@
%% symlink dvp E E E
%% symlink vpp - E -
+%! symlink pre vop_symlink_pre
%! symlink post vop_symlink_post
vop_symlink {
@@ -523,6 +533,8 @@
%% setacl vp E E E
+%! setacl pre vop_setacl_pre
+%! setacl post vop_setacl_post
vop_setacl {
IN struct vnode *vp;
@@ -589,6 +601,7 @@
%% deleteextattr vp E E E
+%! deleteextattr pre vop_deleteextattr_pre
%! deleteextattr post vop_deleteextattr_post
vop_deleteextattr {
@@ -601,6 +614,7 @@
%% setextattr vp E E E
+%! setextattr pre vop_setextattr_pre
%! setextattr post vop_setextattr_post
vop_setextattr {
Index: sys/sys/_seqc.h
===================================================================
--- /dev/null
+++ sys/sys/_seqc.h
@@ -0,0 +1,6 @@
+#ifndef _SYS__SEQC_H_
+#define _SYS__SEQC_H_
+
+typedef uint32_t seqc_t;
+
+#endif /* _SYS__SEQC_H */
Index: sys/sys/seqc.h
===================================================================
--- sys/sys/seqc.h
+++ sys/sys/seqc.h
@@ -36,7 +36,7 @@
/*
* seqc_t may be included in structs visible to userspace
*/
-typedef uint32_t seqc_t;
+#include <sys/_seqc.h>
#ifdef _KERNEL
@@ -111,5 +111,26 @@
return (seqc_consistent_nomb(seqcp, oldseqc));
}
+/*
+ * Variant which does not critical enter/exit.
+ */
+static __inline void
+seqc_sleepable_write_begin(seqc_t *seqcp)
+{
+
+ MPASS(!seqc_in_modify(*seqcp));
+ *seqcp += 1;
+ atomic_thread_fence_rel();
+}
+
+static __inline void
+seqc_sleepable_write_end(seqc_t *seqcp)
+{
+
+ atomic_thread_fence_rel();
+ *seqcp += 1;
+ MPASS(!seqc_in_modify(*seqcp));
+}
+
#endif /* _KERNEL */
#endif /* _SYS_SEQC_H_ */
Index: sys/sys/vnode.h
===================================================================
--- sys/sys/vnode.h
+++ sys/sys/vnode.h
@@ -45,6 +45,7 @@
#include <sys/uio.h>
#include <sys/acl.h>
#include <sys/ktr.h>
+#include <sys/_seqc.h>
/*
* The vnode is the focus of all file activity in UNIX. There is a
@@ -105,6 +106,7 @@
*/
enum vtype v_type:8; /* u vnode type */
short v_irflag; /* i frequently read flags */
+ seqc_t v_seqc; /* i modification count */
struct vop_vector *v_op; /* u vnode operations vector */
void *v_data; /* u private data for fs */
@@ -175,6 +177,7 @@
short v_dbatchcpu; /* i LRU requeue deferral batch */
int v_writecount; /* I ref count of writers or
(negative) text users */
+ int v_seqc_users; /* i modifications pending */
u_int v_hash;
};
@@ -539,6 +542,18 @@
#define ASSERT_VOP_LOCKED(vp, str) assert_vop_locked((vp), (str))
#define ASSERT_VOP_UNLOCKED(vp, str) assert_vop_unlocked((vp), (str))
+#define ASSERT_VOP_IN_SEQC(vp) do { \
+ struct vnode *_vp = (vp); \
+ \
+ VNPASS(seqc_in_modify(_vp->v_seqc), _vp); \
+} while (0)
+
+#define ASSERT_VOP_NOT_IN_SEQC(vp) do { \
+ struct vnode *_vp = (vp); \
+ \
+ VNPASS(!seqc_in_modify(_vp->v_seqc), _vp); \
+} while (0)
+
#else /* !DEBUG_VFS_LOCKS */
#define ASSERT_VI_LOCKED(vp, str) ((void)0)
@@ -546,6 +561,10 @@
#define ASSERT_VOP_ELOCKED(vp, str) ((void)0)
#define ASSERT_VOP_LOCKED(vp, str) ((void)0)
#define ASSERT_VOP_UNLOCKED(vp, str) ((void)0)
+
+#define ASSERT_VOP_IN_SEQC(vp) ((void)0)
+#define ASSERT_VOP_NOT_IN_SEQC(vp) ((void)0)
+
#endif /* DEBUG_VFS_LOCKS */
@@ -738,6 +757,13 @@
int vn_io_fault_pgmove(vm_page_t ma[], vm_offset_t offset, int xfersize,
struct uio *uio);
+void vn_seqc_write_begin_locked(struct vnode *vp);
+void vn_seqc_write_begin(struct vnode *vp);
+void vn_seqc_write_end_locked(struct vnode *vp);
+void vn_seqc_write_end(struct vnode *vp);
+#define vn_seqc_read_any(vp) seqc_read_any(&(vp)->v_seqc)
+#define vn_seqc_consistent(vp, seq) seqc_consistent(&(vp)->v_seqc, seq)
+
#define vn_rangelock_unlock(vp, cookie) \
rangelock_unlock(&(vp)->v_rl, (cookie), VI_MTX(vp))
#define vn_rangelock_unlock_range(vp, cookie, start, end) \
@@ -804,23 +830,37 @@
/* These are called from within the actual VOPS. */
void vop_close_post(void *a, int rc);
+void vop_create_pre(void *a);
void vop_create_post(void *a, int rc);
+void vop_whiteout_pre(void *a);
+void vop_whiteout_post(void *a, int rc);
+void vop_deleteextattr_pre(void *a);
void vop_deleteextattr_post(void *a, int rc);
+void vop_link_pre(void *a);
void vop_link_post(void *a, int rc);
void vop_lookup_post(void *a, int rc);
void vop_lookup_pre(void *a);
+void vop_mkdir_pre(void *a);
void vop_mkdir_post(void *a, int rc);
+void vop_mknod_pre(void *a);
void vop_mknod_post(void *a, int rc);
void vop_open_post(void *a, int rc);
void vop_read_post(void *a, int rc);
void vop_readdir_post(void *a, int rc);
void vop_reclaim_post(void *a, int rc);
+void vop_remove_pre(void *a);
void vop_remove_post(void *a, int rc);
void vop_rename_post(void *a, int rc);
void vop_rename_pre(void *a);
+void vop_rmdir_pre(void *a);
void vop_rmdir_post(void *a, int rc);
+void vop_setattr_pre(void *a);
void vop_setattr_post(void *a, int rc);
+void vop_setacl_pre(void *a);
+void vop_setacl_post(void *a, int rc);
+void vop_setextattr_pre(void *a);
void vop_setextattr_post(void *a, int rc);
+void vop_symlink_pre(void *a);
void vop_symlink_post(void *a, int rc);
int vop_sigdefer(struct vop_vector *vop, struct vop_generic_args *a);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 28, 1:07 AM (13 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24327738
Default Alt Text
D25573.id74219.diff (19 KB)
Attached To
Mode
D25573: (lookup 1) vfs: add sequence counters to vnodes
Attached
Detach File
Event Timeline
Log In to Comment