diff options
| author | thorpej <thorpej@NetBSD.org> | 2021-10-20 03:08:16 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2021-10-20 03:08:16 +0000 |
| commit | 8abbca48b237c9edc3ffb387e9074ddcff8b645d (patch) | |
| tree | 41861906d64ee2ea60ac288b69c2b14012886108 /sys/miscfs | |
| parent | 6ddcd84a3618d73c6acd9eb1ba9c92a563467245 (diff) | |
Overhaul of the EVFILT_VNODE kevent(2) filter:
- Centralize vnode kevent handling in the VOP_*() wrappers, rather than
forcing each individual file system to deal with it (except VOP_RENAME(),
because VOP_RENAME() is a mess and we currently have 2 different ways
of handling it; at least it's reasonably well-centralized in the "new"
way).
- Add support for NOTE_OPEN, NOTE_CLOSE, NOTE_CLOSE_WRITE, and NOTE_READ,
compatible with the same events in FreeBSD.
- Track which kevent notifications clients are interested in receiving
to avoid doing work for events no one cares about (avoiding, e.g.
taking locks and traversing the klist to send a NOTE_WRITE when
someone is merely watching for a file to be deleted, for example).
In support of the above:
- Add support in vnode_if.sh for specifying PRE- and POST-op handlers,
to be invoked before and after vop_pre() and vop_post(), respectively.
Basic idea from FreeBSD, but implemented differently.
- Add support in vnode_if.sh for specifying CONTEXT fields in the
vop_*_args structures. These context fields are used to convey information
between the file system VOP function and the VOP wrapper, but do not
occupy an argument slot in the VOP_*() call itself. These context fields
are initialized and subsequently interpreted by PRE- and POST-op handlers.
- Version VOP_REMOVE(), uses the a context field for the file system to report
back the resulting link count of the target vnode. Return this in tmpfs,
udf, nfs, chfs, ext2fs, lfs, and ufs.
NetBSD 9.99.92.
Diffstat (limited to 'sys/miscfs')
| -rw-r--r-- | sys/miscfs/deadfs/dead_vnops.c | 7 | ||||
| -rw-r--r-- | sys/miscfs/genfs/genfs.h | 8 | ||||
| -rw-r--r-- | sys/miscfs/genfs/genfs_rename.c | 36 | ||||
| -rw-r--r-- | sys/miscfs/genfs/genfs_vnops.c | 12 | ||||
| -rw-r--r-- | sys/miscfs/genfs/layer_vnops.c | 9 | ||||
| -rw-r--r-- | sys/miscfs/umapfs/umap_vnops.c | 6 |
6 files changed, 40 insertions, 38 deletions
diff --git a/sys/miscfs/deadfs/dead_vnops.c b/sys/miscfs/deadfs/dead_vnops.c index 232afd7081c..6db83af5101 100644 --- a/sys/miscfs/deadfs/dead_vnops.c +++ b/sys/miscfs/deadfs/dead_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: dead_vnops.c,v 1.65 2021/07/18 23:57:14 dholland Exp $ */ +/* $NetBSD: dead_vnops.c,v 1.66 2021/10/20 03:08:18 thorpej Exp $ */ /* * Copyright (c) 1989, 1993 @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.65 2021/07/18 23:57:14 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.66 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -225,10 +225,11 @@ dead_poll(void *v) int dead_remove(void *v) { - struct vop_remove_v2_args /* { + struct vop_remove_v3_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; + nlink_t ctx_vp_new_nlink; } */ *ap = v; vput(ap->a_vp); diff --git a/sys/miscfs/genfs/genfs.h b/sys/miscfs/genfs/genfs.h index 331981685d8..1b861b7f427 100644 --- a/sys/miscfs/genfs/genfs.h +++ b/sys/miscfs/genfs/genfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: genfs.h,v 1.37 2021/06/29 22:34:08 dholland Exp $ */ +/* $NetBSD: genfs.h,v 1.38 2021/10/20 03:08:18 thorpej Exp $ */ #ifndef _MISCFS_GENFS_GENFS_H_ #define _MISCFS_GENFS_GENFS_H_ @@ -84,7 +84,7 @@ int genfs_sane_rename(const struct genfs_rename_ops *, kauth_cred_t, bool); void genfs_rename_knote(struct vnode *, struct vnode *, struct vnode *, - struct vnode *, bool); + struct vnode *, nlink_t); void genfs_rename_cache_purge(struct vnode *, struct vnode *, struct vnode *, struct vnode *); @@ -119,10 +119,10 @@ struct genfs_rename_ops { struct vnode *fdvp, struct componentname *fcnp, void *fde, struct vnode *fvp, struct vnode *tdvp, struct componentname *tcnp, - void *tde, struct vnode *tvp); + void *tde, struct vnode *tvp, nlink_t *tvp_nlinkp); int (*gro_remove)(struct mount *mp, kauth_cred_t cred, struct vnode *dvp, struct componentname *cnp, void *de, - struct vnode *vp); + struct vnode *vp, nlink_t *tvp_nlinkp); int (*gro_lookup)(struct mount *mp, struct vnode *dvp, struct componentname *cnp, void *de_ret, struct vnode **vp_ret); int (*gro_genealogy)(struct mount *mp, kauth_cred_t cred, diff --git a/sys/miscfs/genfs/genfs_rename.c b/sys/miscfs/genfs/genfs_rename.c index c054ceb3e84..6f0dc08420c 100644 --- a/sys/miscfs/genfs/genfs_rename.c +++ b/sys/miscfs/genfs/genfs_rename.c @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_rename.c,v 1.5 2020/09/05 02:47:03 riastradh Exp $ */ +/* $NetBSD: genfs_rename.c,v 1.6 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_rename.c,v 1.5 2020/09/05 02:47:03 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_rename.c,v 1.6 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/kauth.h> @@ -129,7 +129,7 @@ static void genfs_rename_exit(const struct genfs_rename_ops *, struct mount *, struct vnode *, struct vnode *); static int genfs_rename_remove(const struct genfs_rename_ops *, struct mount *, kauth_cred_t, - struct vnode *, struct componentname *, void *, struct vnode *); + struct vnode *, struct componentname *, void *, struct vnode *, nlink_t *); /* * genfs_insane_rename: Generic implementation of the insane API for @@ -163,7 +163,7 @@ genfs_insane_rename(void *v, struct vnode *tdvp, struct componentname *tcnp, kauth_cred_t cred, bool posixly_correct)) { - struct vop_rename_args /* { + struct vop_rename_args /* { struct vnode *a_fdvp; struct vnode *a_fvp; struct componentname *a_fcnp; @@ -247,6 +247,7 @@ genfs_sane_rename(const struct genfs_rename_ops *ops, { struct mount *mp; struct vnode *fvp = NULL, *tvp = NULL; + nlink_t tvp_new_nlink = 0; int error; KASSERT(ops != NULL); @@ -314,7 +315,7 @@ genfs_sane_rename(const struct genfs_rename_ops *ops, else /* XXX Can't use VOP_REMOVE because of locking. */ error = genfs_rename_remove(ops, mp, cred, - fdvp, fcnp, fde, fvp); + fdvp, fcnp, fde, fvp, &tvp_new_nlink); goto out; } KASSERT(fvp != tvp); @@ -363,25 +364,29 @@ genfs_sane_rename(const struct genfs_rename_ops *ops, */ error = ops->gro_rename(mp, cred, fdvp, fcnp, fde, fvp, - tdvp, tcnp, tde, tvp); + tdvp, tcnp, tde, tvp, + &tvp_new_nlink); if (error) goto out; /* Success! */ -out: genfs_rename_exit(ops, mp, fdvp, fvp, tdvp, tvp); +out: if (error == 0) { + genfs_rename_knote(fdvp, fvp, tdvp, tvp, tvp_new_nlink); + } + genfs_rename_exit(ops, mp, fdvp, fvp, tdvp, tvp); return error; } /* * genfs_rename_knote: Note events about the various vnodes in a * rename. To be called by gro_rename on success. The only pair of - * vnodes that may be identical is {fdvp, tdvp}. deleted_p is true iff - * the rename overwrote the last link to tvp. + * vnodes that may be identical is {fdvp, tdvp}. tvp_new_nlink is + * the resulting link count of tvp. */ void genfs_rename_knote(struct vnode *fdvp, struct vnode *fvp, - struct vnode *tdvp, struct vnode *tvp, bool deleted_p) + struct vnode *tdvp, struct vnode *tvp, nlink_t tvp_new_nlink) { long fdvp_events, tdvp_events; bool directory_p, reparent_p, replaced_p; @@ -404,7 +409,6 @@ genfs_rename_knote(struct vnode *fdvp, struct vnode *fvp, replaced_p = (tvp != NULL); KASSERT((tvp == NULL) || (directory_p == (tvp->v_type == VDIR))); - KASSERT(!deleted_p || replaced_p); fdvp_events = NOTE_WRITE; if (directory_p && reparent_p) @@ -424,7 +428,7 @@ genfs_rename_knote(struct vnode *fdvp, struct vnode *fvp, } if (replaced_p) - VN_KNOTE(tvp, (deleted_p? NOTE_DELETE : NOTE_LINK)); + VN_KNOTE(tvp, (tvp_new_nlink == 0 ? NOTE_DELETE : NOTE_LINK)); } /* @@ -994,15 +998,15 @@ genfs_rename_exit(const struct genfs_rename_ops *ops, /* * genfs_rename_remove: Remove the entry for the non-directory vp with * componentname cnp from the directory dvp, using the lookup results - * de. It is the responsibility of gro_remove to purge the name cache - * and note kevents. + * de. It is the responsibility of gro_remove to purge the name cache. * * Everything must be locked and referenced. */ static int genfs_rename_remove(const struct genfs_rename_ops *ops, struct mount *mp, kauth_cred_t cred, - struct vnode *dvp, struct componentname *cnp, void *de, struct vnode *vp) + struct vnode *dvp, struct componentname *cnp, void *de, struct vnode *vp, + nlink_t *tvp_nlinkp) { int error; @@ -1029,7 +1033,7 @@ genfs_rename_remove(const struct genfs_rename_ops *ops, if (error) return error; - error = ops->gro_remove(mp, cred, dvp, cnp, de, vp); + error = ops->gro_remove(mp, cred, dvp, cnp, de, vp, tvp_nlinkp); if (error) return error; diff --git a/sys/miscfs/genfs/genfs_vnops.c b/sys/miscfs/genfs/genfs_vnops.c index 776850886f2..c3f5e107ab4 100644 --- a/sys/miscfs/genfs/genfs_vnops.c +++ b/sys/miscfs/genfs/genfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_vnops.c,v 1.215 2021/10/11 01:49:08 thorpej Exp $ */ +/* $NetBSD: genfs_vnops.c,v 1.216 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.215 2021/10/11 01:49:08 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.216 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -507,9 +507,7 @@ filt_genfsdetach(struct knote *kn) { struct vnode *vp = (struct vnode *)kn->kn_hook; - mutex_enter(vp->v_interlock); - SLIST_REMOVE(&vp->v_klist, kn, knote, kn_selnext); - mutex_exit(vp->v_interlock); + vn_knote_detach(vp, kn); } static int @@ -644,9 +642,7 @@ genfs_kqfilter(void *v) kn->kn_hook = vp; - mutex_enter(vp->v_interlock); - SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext); - mutex_exit(vp->v_interlock); + vn_knote_attach(vp, kn); return (0); } diff --git a/sys/miscfs/genfs/layer_vnops.c b/sys/miscfs/genfs/layer_vnops.c index d47d6996aa6..08054b6c7cc 100644 --- a/sys/miscfs/genfs/layer_vnops.c +++ b/sys/miscfs/genfs/layer_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: layer_vnops.c,v 1.71 2020/05/16 18:31:51 christos Exp $ */ +/* $NetBSD: layer_vnops.c,v 1.72 2021/10/20 03:08:18 thorpej Exp $ */ /* * Copyright (c) 1999 National Aeronautics & Space Administration @@ -170,7 +170,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.71 2020/05/16 18:31:51 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.72 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -611,10 +611,11 @@ layer_inactive(void *v) int layer_remove(void *v) { - struct vop_remove_v2_args /* { + struct vop_remove_v3_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; + nlink_t ctx_vp_new_nlink; } */ *ap = v; struct vnode *vp = ap->a_vp; int error; @@ -632,7 +633,7 @@ layer_remove(void *v) int layer_rename(void *v) { - struct vop_rename_args /* { + struct vop_rename_args /* { struct vnode *a_fdvp; struct vnode *a_fvp; struct componentname *a_fcnp; diff --git a/sys/miscfs/umapfs/umap_vnops.c b/sys/miscfs/umapfs/umap_vnops.c index 54c7cd53c42..8172069bc8d 100644 --- a/sys/miscfs/umapfs/umap_vnops.c +++ b/sys/miscfs/umapfs/umap_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: umap_vnops.c,v 1.61 2020/05/16 18:31:51 christos Exp $ */ +/* $NetBSD: umap_vnops.c,v 1.62 2021/10/20 03:08:18 thorpej Exp $ */ /* * Copyright (c) 1992, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umap_vnops.c,v 1.61 2020/05/16 18:31:51 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umap_vnops.c,v 1.62 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -517,7 +517,7 @@ umap_print(void *v) int umap_rename(void *v) { - struct vop_rename_args /* { + struct vop_rename_args /* { struct vnode *a_fdvp; struct vnode *a_fvp; struct componentname *a_fcnp; |
