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 | |
| 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')
44 files changed, 677 insertions, 407 deletions
diff --git a/sys/coda/coda_vnops.c b/sys/coda/coda_vnops.c index 0826ace04a3..4ea29ef7315 100644 --- a/sys/coda/coda_vnops.c +++ b/sys/coda/coda_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: coda_vnops.c,v 1.115 2021/06/29 22:34:05 dholland Exp $ */ +/* $NetBSD: coda_vnops.c,v 1.116 2021/10/20 03:08:16 thorpej Exp $ */ /* * @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.115 2021/06/29 22:34:05 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.116 2021/10/20 03:08:16 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1075,7 +1075,7 @@ int coda_remove(void *v) { /* true args */ - struct vop_remove_v2_args *ap = v; + struct vop_remove_v3_args *ap = v; vnode_t *dvp = ap->a_dvp; struct cnode *cp = VTOC(dvp); vnode_t *vp = ap->a_vp; diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 7425b5de334..81b11648620 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_vnops.c,v 1.106 2021/07/18 23:57:14 dholland Exp $ */ +/* $NetBSD: msdosfs_vnops.c,v 1.107 2021/10/20 03:08:17 thorpej Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.106 2021/07/18 23:57:14 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.107 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -151,7 +151,6 @@ msdosfs_create(void *v) DETIMES(&ndirent, NULL, NULL, NULL, pdep->de_pmp->pm_gmtoff); if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0) goto bad; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); *ap->a_vpp = DETOV(dep); cache_enter(ap->a_dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); @@ -427,7 +426,6 @@ msdosfs_setattr(void *v) } if (de_changed) { - VN_KNOTE(vp, NOTE_ATTRIB); error = deupdat(dep, 1); if (error) goto bad; @@ -545,7 +543,7 @@ msdosfs_write(void *v) int a_ioflag; kauth_cred_t a_cred; } */ *ap = v; - int resid, extended = 0; + int resid; int error = 0; int ioflag = ap->a_ioflag; u_long osize; @@ -625,7 +623,6 @@ msdosfs_write(void *v) if (rem > 0) ubc_zerorange(&vp->v_uobj, (off_t)dep->de_FileSize, rem, UBC_VNODE_FLAGS(vp)); - extended = 1; } do { @@ -664,8 +661,6 @@ msdosfs_write(void *v) * to the size it was before the write was attempted. */ errexit: - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); if (error) { detrunc(dep, osize, ioflag & IO_SYNC, NOCRED); uio->uio_offset -= resid - uio->uio_resid; @@ -717,10 +712,11 @@ msdosfs_update(struct vnode *vp, const struct timespec *acc, int msdosfs_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 denode *dep = VTODE(ap->a_vp); struct denode *ddep = VTODE(ap->a_dvp); @@ -734,8 +730,6 @@ msdosfs_remove(void *v) printf("msdosfs_remove(), dep %p, usecount %d\n", dep, vrefcnt(ap->a_vp)); #endif - VN_KNOTE(ap->a_vp, NOTE_DELETE); - VN_KNOTE(ap->a_dvp, NOTE_WRITE); if (ddep == dep) vrele(ap->a_vp); else @@ -1255,7 +1249,6 @@ msdosfs_mkdir(void *v) ndirent.de_devvp = pdep->de_devvp; if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0) goto bad; - VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK); *ap->a_vpp = DETOV(dep); return (0); @@ -1315,7 +1308,6 @@ msdosfs_rmdir(void *v) * directory. Since dos filesystems don't do this we just purge * the name cache and let go of the parent directory denode. */ - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); /* * Truncate the directory that is being deleted. @@ -1323,7 +1315,6 @@ msdosfs_rmdir(void *v) error = detrunc(ip, (u_long)0, IO_SYNC, cnp->cn_cred); cache_purge(vp); out: - VN_KNOTE(vp, NOTE_DELETE); vput(vp); return (error); } diff --git a/sys/fs/nilfs/nilfs_vnops.c b/sys/fs/nilfs/nilfs_vnops.c index 0a2f14d3486..9bf1aa33d03 100644 --- a/sys/fs/nilfs/nilfs_vnops.c +++ b/sys/fs/nilfs/nilfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_vnops.c,v 1.44 2021/07/24 21:31:38 andvar Exp $ */ +/* $NetBSD: nilfs_vnops.c,v 1.45 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 2008, 2009 Reinoud Zandijk @@ -28,7 +28,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.44 2021/07/24 21:31:38 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.45 2021/10/20 03:08:17 thorpej Exp $"); #endif /* not lint */ @@ -213,7 +213,7 @@ nilfs_write(void *v) struct nilfs_node *nilfs_node = VTOI(vp); uint64_t file_size; vsize_t len; - int error, resid, extended; + int error, resid; DPRINTF(WRITE, ("nilfs_write called\n")); @@ -285,10 +285,6 @@ nilfs_write(void *v) * the superuser as a precaution against tampering. */ - /* if we wrote a thing, note write action on vnode */ - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); - if (error) { /* bring back file size to its former size */ /* take notice of its errors? */ @@ -1196,9 +1192,6 @@ nilfs_link(void *v) if (error) VOP_ABORTOP(dvp, cnp); - VN_KNOTE(vp, NOTE_LINK); - VN_KNOTE(dvp, NOTE_WRITE); - return error; } @@ -1362,7 +1355,7 @@ nilfs_rename(void *v) } /* remove existing entry if present */ - if (tvp) + if (tvp) nilfs_dir_detach(tdnode->ump, tdnode, tnode, tcnp); /* create new directory entry for the node */ @@ -1401,10 +1394,11 @@ out_unlocked: int nilfs_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 *dvp = ap->a_dvp; struct vnode *vp = ap->a_vp; @@ -1423,11 +1417,6 @@ nilfs_remove(void *v) error = EPERM; } - if (error == 0) { - VN_KNOTE(vp, NOTE_DELETE); - VN_KNOTE(dvp, NOTE_WRITE); - } - if (dvp == vp) vrele(vp); else @@ -1476,7 +1465,6 @@ nilfs_rmdir(void *v) if (error == 0) { cache_purge(vp); // cache_purge(dvp); /* XXX from msdosfs, why? */ - VN_KNOTE(vp, NOTE_DELETE); } DPRINTFIF(NODE, error, ("\tgot error removing file\n")); diff --git a/sys/fs/ptyfs/ptyfs_vnops.c b/sys/fs/ptyfs/ptyfs_vnops.c index 0c007f51848..89cd5f1df7d 100644 --- a/sys/fs/ptyfs/ptyfs_vnops.c +++ b/sys/fs/ptyfs/ptyfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ptyfs_vnops.c,v 1.66 2021/07/18 23:57:34 dholland Exp $ */ +/* $NetBSD: ptyfs_vnops.c,v 1.67 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 1993, 1995 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.66 2021/07/18 23:57:34 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.67 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -477,7 +477,6 @@ ptyfs_setattr(void *v) if (error) return error; } - VN_KNOTE(vp, NOTE_ATTRIB); return 0; } diff --git a/sys/fs/puffs/puffs_vnops.c b/sys/fs/puffs/puffs_vnops.c index d1b6dfe9d43..8ccfd8e483e 100644 --- a/sys/fs/puffs/puffs_vnops.c +++ b/sys/fs/puffs/puffs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.222 2021/07/24 21:31:38 andvar Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.223 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.222 2021/07/24 21:31:38 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.223 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -1796,11 +1796,12 @@ callremove(struct puffs_mount *pmp, puffs_cookie_t dck, puffs_cookie_t ck, int puffs_vnop_remove(void *v) { - struct vop_remove_v2_args /* { + struct vop_remove_v3_args /* { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; + nlink_t ctx_vp_new_nlink; } */ *ap = v; PUFFS_MSG_VARS(vn, remove); struct vnode *dvp = ap->a_dvp; @@ -2172,6 +2173,8 @@ puffs_vnop_rename(void *v) if (PUFFS_USE_DOTDOTCACHE(pmp) && (VPTOPP(fvp)->pn_parent != tdvp)) update_parent(fvp, tdvp); + + /* XXX Update ap->ctx_vp_new_nlink */ } diff --git a/sys/fs/sysvbfs/sysvbfs_vnops.c b/sys/fs/sysvbfs/sysvbfs_vnops.c index 5b05755cc48..2d5e3dc9353 100644 --- a/sys/fs/sysvbfs/sysvbfs_vnops.c +++ b/sys/fs/sysvbfs/sysvbfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: sysvbfs_vnops.c,v 1.67 2020/06/27 17:29:18 christos Exp $ */ +/* $NetBSD: sysvbfs_vnops.c,v 1.68 2021/10/20 03:08:17 thorpej Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.67 2020/06/27 17:29:18 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.68 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -474,7 +474,6 @@ sysvbfs_write(void *arg) struct uio *uio = a->a_uio; int advice = IO_ADV_DECODE(a->a_ioflag); struct sysvbfs_node *bnode = v->v_data; - bool extended = false; vsize_t sz; int err = 0; @@ -489,7 +488,6 @@ sysvbfs_write(void *arg) if (bnode->size < uio->uio_offset + uio->uio_resid) { sysvbfs_file_setsize(v, uio->uio_offset + uio->uio_resid); - extended = true; } while (uio->uio_resid > 0) { @@ -503,19 +501,18 @@ sysvbfs_write(void *arg) if (err) sysvbfs_file_setsize(v, bnode->size - uio->uio_resid); - VN_KNOTE(v, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); - return err; } int sysvbfs_remove(void *arg) { - struct vop_remove_v2_args /* { + struct vop_remove_v3_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode * a_vp; struct componentname * a_cnp; + nlink_t ctx_vp_new_nlink; } */ *ap = arg; struct vnode *vp = ap->a_vp; struct vnode *dvp = ap->a_dvp; @@ -534,8 +531,6 @@ sysvbfs_remove(void *arg) if ((err = bfs_file_delete(bfs, ap->a_cnp->cn_nameptr, true)) != 0) DPRINTF("%s: bfs_file_delete failed.\n", __func__); - VN_KNOTE(ap->a_vp, NOTE_DELETE); - VN_KNOTE(ap->a_dvp, NOTE_WRITE); if (dvp == vp) vrele(vp); else diff --git a/sys/fs/tmpfs/tmpfs_rename.c b/sys/fs/tmpfs/tmpfs_rename.c index 583ee3131a1..18eb01d7c17 100644 --- a/sys/fs/tmpfs/tmpfs_rename.c +++ b/sys/fs/tmpfs/tmpfs_rename.c @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_rename.c,v 1.10 2019/12/03 04:59:05 riastradh Exp $ */ +/* $NetBSD: tmpfs_rename.c,v 1.11 2021/10/20 03:08:17 thorpej Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_rename.c,v 1.10 2019/12/03 04:59:05 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_rename.c,v 1.11 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/errno.h> @@ -264,7 +264,7 @@ tmpfs_gro_rename(struct mount *mp, kauth_cred_t cred, 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) { tmpfs_node_t *fdnode = VP_TO_TMPFS_DIR(fdvp); tmpfs_node_t *tdnode = VP_TO_TMPFS_DIR(tdvp); @@ -317,14 +317,6 @@ tmpfs_gro_rename(struct mount *mp, kauth_cred_t cred, if (fdvp != tdvp) { tmpfs_dir_detach(fdnode, *fdep); tmpfs_dir_attach(tdnode, *fdep, VP_TO_TMPFS_NODE(fvp)); - } else if (tvp == NULL) { - /* - * We are changing the directory. tmpfs_dir_attach and - * tmpfs_dir_detach note the events for us, but for - * this case we don't call them, so we must note the - * event explicitly. - */ - VN_KNOTE(fdvp, NOTE_WRITE); } /* @@ -350,6 +342,8 @@ tmpfs_gro_rename(struct mount *mp, kauth_cred_t cred, } tmpfs_dir_detach(tdnode, *tdep); tmpfs_free_dirent(VFS_TO_TMPFS(mp), *tdep); + + *tvp_nlinkp = VP_TO_TMPFS_NODE(tvp)->tn_links; } /* @@ -377,8 +371,6 @@ tmpfs_gro_rename(struct mount *mp, kauth_cred_t cred, tmpfs_update(tdvp, TMPFS_UPDATE_MTIME | TMPFS_UPDATE_CTIME); tmpfs_update(fvp, TMPFS_UPDATE_CTIME); - VN_KNOTE(fvp, NOTE_RENAME); - genfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); return 0; @@ -390,7 +382,8 @@ tmpfs_gro_rename(struct mount *mp, kauth_cred_t cred, */ static int tmpfs_gro_remove(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) { tmpfs_node_t *dnode = VP_TO_TMPFS_DIR(dvp); struct tmpfs_dirent **dep = de; @@ -413,6 +406,9 @@ tmpfs_gro_remove(struct mount *mp, kauth_cred_t cred, tmpfs_free_dirent(VFS_TO_TMPFS(mp), *dep); tmpfs_update(dvp, TMPFS_UPDATE_MTIME | TMPFS_UPDATE_CTIME); + KASSERT((*dep)->td_node == VP_TO_TMPFS_NODE(vp)); + *tvp_nlinkp = VP_TO_TMPFS_NODE(vp)->tn_links; + return 0; } diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index 221077f74b1..75f1b6e1d59 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_subr.c,v 1.113 2020/09/05 16:30:12 riastradh Exp $ */ +/* $NetBSD: tmpfs_subr.c,v 1.114 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 2005-2020 The NetBSD Foundation, Inc. @@ -73,7 +73,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.113 2020/09/05 16:30:12 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.114 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/cprng.h> @@ -537,7 +537,6 @@ tmpfs_dir_attach(tmpfs_node_t *dnode, tmpfs_dirent_t *de, tmpfs_node_t *node) TMPFS_VALIDATE_DIR(node); } - VN_KNOTE(dvp, events); } /* @@ -554,8 +553,7 @@ void tmpfs_dir_detach(tmpfs_node_t *dnode, tmpfs_dirent_t *de) { tmpfs_node_t *node = de->td_node; - vnode_t *vp, *dvp = dnode->tn_vnode; - int events = NOTE_WRITE; + vnode_t *dvp = dnode->tn_vnode; KASSERT(dvp == NULL || VOP_ISLOCKED(dvp)); @@ -566,11 +564,6 @@ tmpfs_dir_detach(tmpfs_node_t *dnode, tmpfs_dirent_t *de) KASSERT(node->tn_links > 0); node->tn_links--; - if ((vp = node->tn_vnode) != NULL) { - KASSERT(VOP_ISLOCKED(vp)); - VN_KNOTE(vp, node->tn_links ? NOTE_LINK : NOTE_DELETE); - } - /* If directory - decrease the link count of parent. */ if (node->tn_type == VDIR) { KASSERT(node->tn_spec.tn_dir.tn_parent == dnode); @@ -578,7 +571,6 @@ tmpfs_dir_detach(tmpfs_node_t *dnode, tmpfs_dirent_t *de) KASSERT(dnode->tn_links > 0); dnode->tn_links--; - events |= NOTE_LINK; } } de->td_node = NULL; @@ -593,7 +585,6 @@ tmpfs_dir_detach(tmpfs_node_t *dnode, tmpfs_dirent_t *de) if (dvp) { uvm_vnp_setsize(dvp, dnode->tn_size); - VN_KNOTE(dvp, events); } } @@ -952,9 +943,6 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize) /* Decrease the used-memory counter. */ tmpfs_mem_decr(tmp, (oldpages - newpages) << PAGE_SHIFT); } - if (newsize > oldsize) { - VN_KNOTE(vp, NOTE_EXTEND); - } return 0; } @@ -1014,7 +1002,6 @@ tmpfs_chflags(vnode_t *vp, int flags, kauth_cred_t cred, lwp_t *l) node->tn_flags = flags; } tmpfs_update(vp, TMPFS_UPDATE_CTIME); - VN_KNOTE(vp, NOTE_ATTRIB); return 0; } @@ -1044,7 +1031,6 @@ tmpfs_chmod(vnode_t *vp, mode_t mode, kauth_cred_t cred, lwp_t *l) } node->tn_mode = (mode & ALLPERMS); tmpfs_update(vp, TMPFS_UPDATE_CTIME); - VN_KNOTE(vp, NOTE_ATTRIB); cache_enter_id(vp, node->tn_mode, node->tn_uid, node->tn_gid, true); return 0; } @@ -1089,7 +1075,6 @@ tmpfs_chown(vnode_t *vp, uid_t uid, gid_t gid, kauth_cred_t cred, lwp_t *l) node->tn_uid = uid; node->tn_gid = gid; tmpfs_update(vp, TMPFS_UPDATE_CTIME); - VN_KNOTE(vp, NOTE_ATTRIB); cache_enter_id(vp, node->tn_mode, node->tn_uid, node->tn_gid, true); return 0; } @@ -1185,7 +1170,6 @@ tmpfs_chtimes(vnode_t *vp, const struct timespec *atime, node->tn_birthtime = *btime; } mutex_exit(&node->tn_timelock); - VN_KNOTE(vp, NOTE_ATTRIB); return 0; } diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 9c8df3b4639..210545fbe67 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vnops.c,v 1.147 2021/07/18 23:57:14 dholland Exp $ */ +/* $NetBSD: tmpfs_vnops.c,v 1.148 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 2005, 2006, 2007, 2020 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.147 2021/07/18 23:57:14 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.148 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/dirent.h> @@ -648,7 +648,6 @@ tmpfs_write(void *v) } tmpfs_update(vp, TMPFS_UPDATE_MTIME | TMPFS_UPDATE_CTIME); - VN_KNOTE(vp, NOTE_WRITE); out: if (error) { KASSERT(oldsize == node->tn_size); @@ -685,10 +684,11 @@ tmpfs_fsync(void *v) int tmpfs_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; vnode_t *dvp = ap->a_dvp, *vp = ap->a_vp; tmpfs_node_t *dnode, *node; @@ -747,6 +747,7 @@ tmpfs_remove(void *v) /* We removed a hard link. */ tflags |= TMPFS_UPDATE_CTIME; } + ap->ctx_vp_new_nlink = node->tn_links; tmpfs_update(dvp, tflags); error = 0; out: @@ -814,10 +815,7 @@ tmpfs_link(void *v) tmpfs_dir_attach(dnode, de, node); tmpfs_update(dvp, TMPFS_UPDATE_MTIME | TMPFS_UPDATE_CTIME); - /* Update the timestamps and trigger the event. */ - if (node->tn_vnode) { - VN_KNOTE(node->tn_vnode, NOTE_LINK); - } + /* Update the timestamps. */ tmpfs_update(vp, TMPFS_UPDATE_CTIME); error = 0; out: diff --git a/sys/fs/udf/udf_rename.c b/sys/fs/udf/udf_rename.c index a7be766eb92..5be685d676c 100644 --- a/sys/fs/udf/udf_rename.c +++ b/sys/fs/udf/udf_rename.c @@ -1,4 +1,4 @@ -/* $NetBSD: udf_rename.c,v 1.13 2020/01/17 20:08:08 ad Exp $ */ +/* $NetBSD: udf_rename.c,v 1.14 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 2013 Reinoud Zandijk @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udf_rename.c,v 1.13 2020/01/17 20:08:08 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_rename.c,v 1.14 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/errno.h> @@ -322,7 +322,7 @@ udf_gro_rename(struct mount *mp, kauth_cred_t cred, 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) { struct udf_node *fnode, *fdnode, *tnode, *tdnode; struct vattr fvap; @@ -364,8 +364,15 @@ udf_gro_rename(struct mount *mp, kauth_cred_t cred, return error; /* remove existing entry if present */ - if (tvp) + if (tvp) { udf_dir_detach(tdnode->ump, tdnode, tnode, tcnp); + if (tnode->fe) { + *tvp_nlinkp = udf_rw16(tnode->fe->link_cnt); + } else { + KASSERT(tnode->efe != NULL); + *tvp_nlinkp = udf_rw16(tnode->efe->link_cnt); + } + } /* create new directory entry for the node */ error = udf_dir_attach(tdnode->ump, tdnode, fnode, &fvap, tcnp); @@ -384,7 +391,6 @@ udf_gro_rename(struct mount *mp, kauth_cred_t cred, goto rollback; } - VN_KNOTE(fvp, NOTE_RENAME); genfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); return 0; @@ -404,7 +410,8 @@ rollback_attach: */ static int udf_gro_remove(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) { struct udf_node *dir_node, *udf_node; @@ -426,6 +433,13 @@ udf_gro_remove(struct mount *mp, kauth_cred_t cred, udf_node = VTOI(vp); udf_dir_detach(dir_node->ump, dir_node, udf_node, cnp); + if (udf_node->fe) { + *tvp_nlinkp = udf_rw16(udf_node->fe->link_cnt); + } else { + KASSERT(udf_node->efe != NULL); + *tvp_nlinkp = udf_rw16(udf_node->efe->link_cnt); + } + return 0; } diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c index 29912621240..a140c40c41a 100644 --- a/sys/fs/udf/udf_vnops.c +++ b/sys/fs/udf/udf_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.116 2021/07/24 21:31:38 andvar Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.117 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.116 2021/07/24 21:31:38 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.117 2021/10/20 03:08:17 thorpej Exp $"); #endif /* not lint */ @@ -398,10 +398,6 @@ udf_write(void *v) * the superuser as a precaution against tampering. */ - /* if we wrote a thing, note write action on vnode */ - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); - if (error) { /* bring back file size to its former size */ /* take notice of its errors? */ @@ -1139,7 +1135,6 @@ udf_chsize(struct vnode *vp, u_quad_t newsize, kauth_cred_t cred) udf_node->i_flags |= IN_CHANGE | IN_MODIFY; if (vp->v_mount->mnt_flag & MNT_RELATIME) udf_node->i_flags |= IN_ACCESS; - VN_KNOTE(vp, NOTE_ATTRIB | (extended ? NOTE_EXTEND : 0)); udf_update(vp, NULL, NULL, NULL, 0); } @@ -1273,7 +1268,6 @@ udf_setattr(void *v) error = udf_chtimes(vp, &vap->va_atime, &vap->va_mtime, &vap->va_birthtime, vap->va_vaflags, cred); } - VN_KNOTE(vp, NOTE_ATTRIB); return error; } @@ -1599,9 +1593,6 @@ udf_link(void *v) if (error) VOP_ABORTOP(dvp, cnp); - VN_KNOTE(vp, NOTE_LINK); - VN_KNOTE(dvp, NOTE_WRITE); - return error; } @@ -1939,10 +1930,11 @@ udf_readlink(void *v) int udf_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 *dvp = ap->a_dvp; struct vnode *vp = ap->a_vp; @@ -1956,16 +1948,21 @@ udf_remove(void *v) if (vp->v_type != VDIR) { error = udf_dir_detach(ump, dir_node, udf_node, cnp); DPRINTFIF(NODE, error, ("\tgot error removing file\n")); + if (error == 0) { + if (udf_node->fe) { + ap->ctx_vp_new_nlink = + udf_rw16(udf_node->fe->link_cnt); + } else { + KASSERT(udf_node->efe != NULL); + ap->ctx_vp_new_nlink = + udf_rw16(udf_node->efe->link_cnt); + } + } } else { DPRINTF(NODE, ("\tis a directory: perm. denied\n")); error = EPERM; } - if (error == 0) { - VN_KNOTE(vp, NOTE_DELETE); - VN_KNOTE(dvp, NOTE_WRITE); - } - if (dvp == vp) vrele(vp); else @@ -2031,7 +2028,6 @@ udf_rmdir(void *v) */ dirhash_purge(&udf_node->dir_hash); udf_shrink_node(udf_node, 0); - VN_KNOTE(vp, NOTE_DELETE); } DPRINTFIF(NODE, error, ("\tgot error removing dir\n")); diff --git a/sys/fs/union/union_vnops.c b/sys/fs/union/union_vnops.c index 8900c114586..78d437b0c05 100644 --- a/sys/fs/union/union_vnops.c +++ b/sys/fs/union/union_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.78 2021/07/04 11:24:09 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.79 2021/10/20 03:08:17 thorpej Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.78 2021/07/04 11:24:09 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.79 2021/10/20 03:08:17 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1179,10 +1179,11 @@ union_seek(void *v) int union_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; int error; struct union_node *dun = VTOUNION(ap->a_dvp); @@ -1296,7 +1297,7 @@ union_link(void *v) int union_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/fs/unionfs/unionfs_vnops.c b/sys/fs/unionfs/unionfs_vnops.c index f6b0601927a..12576ac6562 100644 --- a/sys/fs/unionfs/unionfs_vnops.c +++ b/sys/fs/unionfs/unionfs_vnops.c @@ -893,7 +893,7 @@ unionfs_fsync(void *v) static int unionfs_remove(void *v) { - struct vop_remove_v2_args *ap = v; + struct vop_remove_v3_args *ap = v; int error; struct unionfs_node *dunp; struct unionfs_node *unp; diff --git a/sys/fs/v7fs/v7fs_vnops.c b/sys/fs/v7fs/v7fs_vnops.c index a2ad30668a6..2aa7f346bc0 100644 --- a/sys/fs/v7fs/v7fs_vnops.c +++ b/sys/fs/v7fs/v7fs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: v7fs_vnops.c,v 1.31 2020/06/27 17:29:18 christos Exp $ */ +/* $NetBSD: v7fs_vnops.c,v 1.32 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.31 2020/06/27 17:29:18 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.32 2021/10/20 03:08:18 thorpej Exp $"); #if defined _KERNEL_OPT #include "opt_v7fs.h" #endif @@ -683,11 +683,12 @@ v7fs_fsync(void *v) int v7fs_remove(void *v) { - struct vop_remove_v2_args /* { + struct vop_remove_v3_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode * a_vp; struct componentname * a_cnp; + nlink_t ctx_vp_new_nlink; } */ *a = v; struct v7fs_node *parent_node = a->a_dvp->v_data; struct v7fs_mount *v7fsmount = parent_node->v7fsmount; diff --git a/sys/kern/vfs_vnode.c b/sys/kern/vfs_vnode.c index 310c8fff6ab..343b72d4272 100644 --- a/sys/kern/vfs_vnode.c +++ b/sys/kern/vfs_vnode.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnode.c,v 1.127 2021/04/01 06:26:14 simonb Exp $ */ +/* $NetBSD: vfs_vnode.c,v 1.128 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 1997-2011, 2019, 2020 The NetBSD Foundation, Inc. @@ -148,7 +148,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.127 2021/04/01 06:26:14 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.128 2021/10/20 03:08:18 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -1826,6 +1826,10 @@ vcache_reclaim(vnode_t *vp) vp->v_vflag |= VV_LOCKSWORK; VSTATE_CHANGE(vp, VS_RECLAIMING, VS_RECLAIMED); vp->v_tag = VT_NON; + /* + * Don't check for interest in NOTE_REVOKE; it's always posted + * because it sets EV_EOF. + */ KNOTE(&vp->v_klist, NOTE_REVOKE); mutex_exit(vp->v_interlock); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index ec70eeceebd..2422599a616 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnops.c,v 1.223 2021/09/11 10:09:13 riastradh Exp $ */ +/* $NetBSD: vfs_vnops.c,v 1.224 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.223 2021/09/11 10:09:13 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.224 2021/10/20 03:08:18 thorpej Exp $"); #include "veriexec.h" @@ -1365,3 +1365,91 @@ vn_bdev_openpath(struct pathbuf *pb, struct vnode **vpp, struct lwp *l) return vn_bdev_open(dev, vpp, l); } + +static long +vn_knote_to_interest(const struct knote *kn) +{ + switch (kn->kn_filter) { + case EVFILT_READ: + /* + * Writing to the file or changing its attributes can + * set the file size, which impacts the readability + * filter. + * + * (No need to set NOTE_EXTEND here; it's only ever + * send with other hints; see vnode_if.c.) + */ + return NOTE_WRITE | NOTE_ATTRIB; + + case EVFILT_VNODE: + return kn->kn_sfflags; + + case EVFILT_WRITE: + default: + return 0; + } +} + +void +vn_knote_attach(struct vnode *vp, struct knote *kn) +{ + long interest = 0; + + /* + * We maintain a bitmask of the kevents that there is interest in, + * to minimize the impact of having watchers. It's silly to have + * to traverse vn_klist every time a read or write happens simply + * because there is someone interested in knowing when the file + * is deleted, for example. + */ + + mutex_enter(vp->v_interlock); + SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext); + SLIST_FOREACH(kn, &vp->v_klist, kn_selnext) { + interest |= vn_knote_to_interest(kn); + } + vp->v_klist_interest = interest; + mutex_exit(vp->v_interlock); +} + +void +vn_knote_detach(struct vnode *vp, struct knote *kn) +{ + int interest = 0; + + /* + * We special case removing the head of the list, beacuse: + * + * 1. It's extremely likely that we're detaching the only + * knote. + * + * 2. We're already traversing the whole list, so we don't + * want to use the generic SLIST_REMOVE() which would + * traverse it *again*. + */ + + mutex_enter(vp->v_interlock); + if (__predict_true(kn == SLIST_FIRST(&vp->v_klist))) { + SLIST_REMOVE_HEAD(&vp->v_klist, kn_selnext); + SLIST_FOREACH(kn, &vp->v_klist, kn_selnext) { + interest |= vn_knote_to_interest(kn); + } + vp->v_klist_interest = interest; + } else { + struct knote *thiskn, *nextkn, *prevkn = NULL; + + SLIST_FOREACH_SAFE(thiskn, &vp->v_klist, kn_selnext, nextkn) { + if (thiskn == kn) { + KASSERT(kn != NULL); + KASSERT(prevkn != NULL); + SLIST_REMOVE_AFTER(prevkn, kn_selnext); + kn = NULL; + } else { + interest |= vn_knote_to_interest(thiskn); + prevkn = thiskn; + } + } + vp->v_klist_interest = interest; + } + mutex_exit(vp->v_interlock); +} diff --git a/sys/kern/vnode_if.sh b/sys/kern/vnode_if.sh index ad700621d2e..1edc3f4f8eb 100644 --- a/sys/kern/vnode_if.sh +++ b/sys/kern/vnode_if.sh @@ -29,7 +29,7 @@ copyright="\ * SUCH DAMAGE. */ " -SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.71 2021/08/12 19:15:15 andvar Exp $' +SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.72 2021/10/20 03:08:18 thorpej Exp $' # Script to produce VFS front-end sugar. # @@ -99,8 +99,13 @@ awk_parser=' name=$1; args_name=$1; argc=0; + have_context=0; + is_context=0; + ncontext=0; willmake=-1; fstrans=""; + do_pre=""; + do_post=""; next; } # Last line of description @@ -117,39 +122,64 @@ awk_parser=' fstrans = $1; sub("FSTRANS=", "", fstrans); next; + } else if ($1 ~ "^PRE=") { + do_pre = $1; + sub("PRE=", "", do_pre); + next; + } else if ($1 ~ "^POST=") { + do_post = $1; + sub("POST=", "", do_post); + next; } - argdir[argc] = $1; i=2; - - if ($2 == "LOCKED=YES") { - lockstate[argc] = 1; - i++; - } else if ($2 == "LOCKED=NO") { - lockstate[argc] = 0; - i++; - } else - lockstate[argc] = -1; - - if ($2 == "WILLRELE" || - $3 == "WILLRELE") { - willrele[argc] = 1; - i++; - } else if ($2 == "WILLPUT" || - $3 == "WILLPUT") { - willrele[argc] = 3; - i++; - } else - willrele[argc] = 0; - - if ($2 == "WILLMAKE") { - willmake=argc; - i++; + if ($1 == "CONTEXT") { + # CONTEXT require PRE and POST handlers. + if (do_pre == "" || do_post == "") + next; + is_context=1; + have_context=1; + } else { + if (have_context) { + # CONTEXT members must come at the end of + # the args structure, so everything else + # is ignored. + next; + } + argdir[argc] = $1; } - if (argc == 0 && fstrans == "") { - if (lockstate[0] == 1) - fstrans = "NO"; - else - fstrans = "YES"; + i=2; + + if (is_context == 0) { + if ($2 == "LOCKED=YES") { + lockstate[argc] = 1; + i++; + } else if ($2 == "LOCKED=NO") { + lockstate[argc] = 0; + i++; + } else + lockstate[argc] = -1; + + if ($2 == "WILLRELE" || + $3 == "WILLRELE") { + willrele[argc] = 1; + i++; + } else if ($2 == "WILLPUT" || + $3 == "WILLPUT") { + willrele[argc] = 3; + i++; + } else + willrele[argc] = 0; + + if ($2 == "WILLMAKE") { + willmake=argc; + i++; + } + if (argc == 0 && fstrans == "") { + if (lockstate[0] == 1) + fstrans = "NO"; + else + fstrans = "YES"; + } } # XXX: replace non-portable types for rump. We should really @@ -166,14 +196,17 @@ awk_parser=' if (at == "daddr_t") at = "int64_t" } - argtype[argc] = at; + argtype[argc + ncontext] = at; i++; while (i < NF) { - argtype[argc] = argtype[argc]" "$i; + argtype[argc + ncontext] = argtype[argc + ncontext]" "$i; i++; } - argname[argc] = $i; - argc++; + argname[argc + ncontext] = $i; + if (is_context) + ncontext++; + else + argc++; next; } ' @@ -240,6 +273,10 @@ function doit() { for (i=0; i<argc; i++) { printf("\t%s a_%s;\n", argtype[i], argname[i]); } + for (i=0; i<ncontext; i++) { + printf("\t%s ctx_%s;\n", argtype[argc+i], \ + argname[argc+i]); + } printf("};\n"); printf("extern const struct vnodeop_desc %s_desc;\n", name); } @@ -312,6 +349,7 @@ echo ' #include <sys/param.h> #include <sys/mount.h> #include <sys/buf.h> +#include <sys/fcntl.h> #include <sys/vnode.h> #include <sys/lock.h>' [ -z "${rump}" ] && echo '#include <sys/fstrans.h>' @@ -360,6 +398,199 @@ vop_pre(vnode_t *vp, struct mount **mp, bool *mpsafe, enum fst_op op) return 0; } +static inline u_quad_t +vop_pre_get_size(struct vnode *vp) +{ + mutex_enter(vp->v_interlock); + KASSERT(vp->v_size != VSIZENOTSET); + u_quad_t rv = (u_quad_t)vp->v_size; + mutex_exit(vp->v_interlock); + + return rv; +} + +/* + * VOP_RMDIR(), VOP_REMOVE(), and VOP_RENAME() need special handling + * because they each drop the caller's references on one or more of + * their arguments. While there must be an open file descriptor in + * associated with a vnode in order for knotes to be attached to it, + * that status could change during the course of the operation. So, + * for the vnode arguments that are WILLRELE or WILLPUT, we check + * pre-op if there are registered knotes, take a hold count if so, + * and post-op release the hold after activating any knotes still + * associated with the vnode. + */ + +#define VOP_POST_KNOTE(thisvp, e, n) \\ +do { \\ + if (__predict_true((e) == 0)) { \\ + /* \\ + * VN_KNOTE() does the VN_KEVENT_INTEREST() \\ + * check for us. \\ + */ \\ + VN_KNOTE((thisvp), (n)); \\ + } \\ +} while (/*CONSTCOND*/0) + +#define VOP_POST_KNOTE_HELD(thisvp, e, n) \\ +do { \\ + /* \\ + * We don't perform a VN_KEVENT_INTEREST() check here; it \\ + * was already performed when we did the pre-op work that \\ + * caused the vnode to be held in the first place. \\ + */ \\ + mutex_enter((thisvp)->v_interlock); \\ + if (__predict_true((e) == 0)) { \\ + knote(&(thisvp)->v_klist, (n)); \\ + } \\ + holdrelel((thisvp)); \\ + mutex_exit((thisvp)->v_interlock); \\ + /* \\ + * thisvp might be gone now! Don't touch! \\ + */ \\ +} while (/*CONSTCOND*/0) + +#define vop_create_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE) + +#define vop_mknod_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE) + +#define vop_setattr_pre(ap) \\ + u_quad_t osize = 0; \\ + long vp_events = \\ + VN_KEVENT_INTEREST((ap)->a_vp, NOTE_ATTRIB | NOTE_EXTEND) \\ + ? NOTE_ATTRIB : 0; \\ + bool check_extend = false; \\ + if (__predict_false(vp_events != 0 && \\ + (ap)->a_vap->va_size != VNOVALSIZE)) { \\ + check_extend = true; \\ + osize = vop_pre_get_size((ap)->a_vp); \\ + } + +#define vop_setattr_post(ap, e) \\ +do { \\ + if (__predict_false(vp_events != 0)) { \\ + if (__predict_false(check_extend && \\ + (ap)->a_vap->va_size > osize)) { \\ + vp_events |= NOTE_EXTEND; \\ + } \\ + VOP_POST_KNOTE((ap)->a_vp, (e), vp_events); \\ + } \\ +} while (/*CONSTCOND*/0) + +#define vop_setacl_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_ATTRIB) + +#define vop_link_post(ap, e) \\ +do { \\ + VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE); \\ + VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_LINK); \\ +} while (/*CONSTCOND*/0) + +#define vop_mkdir_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE | NOTE_LINK) + +#define vop_remove_pre_common(ap) \\ + bool post_event_vp = \\ + VN_KEVENT_INTEREST((ap)->a_vp, NOTE_DELETE | NOTE_LINK); \\ + if (__predict_false(post_event_vp)) { \\ + vhold((ap)->a_vp); \\ + } + +#define vop_remove_post_common(ap, e, dn, lc) \\ +do { \\ + VOP_POST_KNOTE((ap)->a_dvp, (e), (dn)); \\ + if (__predict_false(post_event_vp)) { \\ + VOP_POST_KNOTE_HELD((ap)->a_vp, (e), \\ + (lc) ? NOTE_LINK : NOTE_DELETE); \\ + } \\ +} while (/*CONSTCOND*/0) + +/* + * One could make the argument that VOP_REMOVE() should send NOTE_LINK + * on vp if the resulting link count is not zero, but that's not what + * the documentation says. + * + * We could change this easily by passing ap->ctx_vp_new_nlink to + * vop_remove_post_common(). + */ +#define vop_remove_pre(ap) \\ + vop_remove_pre_common((ap)); \\ + /* \\ + * We will assume that the file being removed is deleted unless \\ + * the file system tells us otherwise by updating vp_new_nlink. \\ + */ \\ + (ap)->ctx_vp_new_nlink = 0; + +#define vop_remove_post(ap, e) \\ + vop_remove_post_common((ap), (e), NOTE_WRITE, 0) + +#define vop_rmdir_pre(ap) \\ + vop_remove_pre_common(ap) + +#define vop_rmdir_post(ap, e) \\ + vop_remove_post_common((ap), (e), NOTE_WRITE | NOTE_LINK, 0) + +#define vop_symlink_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE) + +#define vop_open_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_OPEN) + +#define vop_close_post(ap, e) \\ +do { \\ + extern int (**dead_vnodeop_p)(void *); \\ + \\ + /* See the definition of VN_KNOTE() in <sys/vnode.h>. */ \\ + if (__predict_false(VN_KEVENT_INTEREST((ap)->a_vp, \\ + NOTE_CLOSE_WRITE | NOTE_CLOSE) && (e) == 0)) { \\ + struct vnode *thisvp = (ap)->a_vp; \\ + mutex_enter(thisvp->v_interlock); \\ + /* \\ + * Don't send NOTE_CLOSE when closing a vnode that's \\ + * been reclaimed or otherwise revoked; a NOTE_REVOKE \\ + * has already been sent, and this close is effectively \\ + * meaningless from the watcher's perspective. \\ + */ \\ + if (__predict_true(thisvp->v_op != dead_vnodeop_p)) { \\ + knote(&thisvp->v_klist, \\ + ((ap)->a_fflag & FWRITE) \\ + ? NOTE_CLOSE_WRITE : NOTE_CLOSE); \\ + } \\ + mutex_exit(thisvp->v_interlock); \\ + } \\ +} while (/*CONSTCOND*/0) + +#define vop_read_post(ap, e) \\ + VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_READ) + +#define vop_write_pre(ap) \\ + off_t ooffset = 0, noffset = 0; \\ + u_quad_t osize = 0; \\ + long vp_events = \\ + VN_KEVENT_INTEREST((ap)->a_vp, NOTE_WRITE | NOTE_EXTEND) \\ + ? NOTE_WRITE : 0; \\ + if (__predict_false(vp_events != 0)) { \\ + ooffset = (ap)->a_uio->uio_offset; \\ + osize = vop_pre_get_size((ap)->a_vp); \\ + } + +#define vop_write_post(ap, e) \\ +do { \\ + /* \\ + * If any data was written, we'll post an event, even if \\ + * there was an error. \\ + */ \\ + noffset = (ap)->a_uio->uio_offset; \\ + if (__predict_false(vp_events != 0 && noffset > ooffset)) { \\ + if (noffset > osize) { \\ + vp_events |= NOTE_EXTEND; \\ + } \\ + VN_KNOTE((ap)->a_vp, vp_events); \\ + } \\ +} while (/*CONSTCOND*/0) + static inline void vop_post(vnode_t *vp, struct mount *mp, bool mpsafe, enum fst_op op) { @@ -481,6 +712,10 @@ function bodynorm() { printf("#endif\n"); } } + # This is done before generic vop_pre() because we want + # to do any setup before beginning an fstrans. + if (do_pre != "") + printf("\t%s(&a);\n", do_pre); if (fstrans == "LOCK") printf("\terror = vop_pre(%s, &mp, &mpsafe, %s);\n", argname[0], "(!(flags & (LK_SHARED|LK_EXCLUSIVE)) ? FST_NO : (flags & LK_NOWAIT ? FST_TRY : FST_YES))"); @@ -502,6 +737,11 @@ function bodynorm() { else printf("\tvop_post(%s, mp, mpsafe, FST_%s);\n", argname[0], fstrans); + # This is done after generic vop_post() in order to minimize + # time spent with the KERNEL_LOCK held for file systems that + # still require it. + if (do_post != "") + printf("\t%s(&a, error);\n", do_post); if (willmake != -1) { printf("#ifdef DIAGNOSTIC\n"); printf("\tif (error == 0)\n" \ diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index a76d97221f8..fd8ed07cea9 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -1,4 +1,4 @@ -# $NetBSD: vnode_if.src,v 1.82 2021/07/02 16:56:22 dholland Exp $ +# $NetBSD: vnode_if.src,v 1.83 2021/10/20 03:08:18 thorpej Exp $ # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -95,6 +95,7 @@ vop_lookup { # vop_create { VERSION 3 + POST=vop_create_post IN LOCKED=YES struct vnode *dvp; OUT WILLMAKE struct vnode **vpp; IN struct componentname *cnp; @@ -109,6 +110,7 @@ vop_create { # vop_mknod { VERSION 3 + POST=vop_mknod_post IN LOCKED=YES struct vnode *dvp; OUT WILLMAKE struct vnode **vpp; IN struct componentname *cnp; @@ -119,6 +121,7 @@ vop_mknod { #% open vp L L L # vop_open { + POST=vop_open_post IN LOCKED=YES struct vnode *vp; IN int mode; IN kauth_cred_t cred; @@ -128,6 +131,7 @@ vop_open { #% close vp L L L # vop_close { + POST=vop_close_post IN LOCKED=YES struct vnode *vp; IN int fflag; IN kauth_cred_t cred; @@ -164,6 +168,8 @@ vop_getattr { #% setattr vp L L L # vop_setattr { + PRE=vop_setattr_pre + POST=vop_setattr_post IN LOCKED=YES struct vnode *vp; IN struct vattr *vap; IN kauth_cred_t cred; @@ -173,6 +179,7 @@ vop_setattr { #% read vp L L L # vop_read { + POST=vop_read_post IN LOCKED=YES struct vnode *vp; INOUT struct uio *uio; IN int ioflag; @@ -183,6 +190,8 @@ vop_read { #% write vp L L L # vop_write { + PRE=vop_write_pre + POST=vop_write_post IN LOCKED=YES struct vnode *vp; INOUT struct uio *uio; IN int ioflag; @@ -294,10 +303,13 @@ vop_seek { #! remove cnp DELETE, LOCKPARENT | LOCKLEAF # vop_remove { - VERSION 2 + VERSION 3 + PRE=vop_remove_pre + POST=vop_remove_post IN LOCKED=YES struct vnode *dvp; IN LOCKED=YES WILLPUT struct vnode *vp; IN struct componentname *cnp; + CONTEXT nlink_t vp_new_nlink; }; # @@ -308,6 +320,7 @@ vop_remove { # vop_link { VERSION 2 + POST=vop_link_post IN LOCKED=YES struct vnode *dvp; IN LOCKED=NO struct vnode *vp; IN struct componentname *cnp; @@ -339,6 +352,7 @@ vop_rename { # vop_mkdir { VERSION 3 + POST=vop_mkdir_post IN LOCKED=YES struct vnode *dvp; OUT WILLMAKE struct vnode **vpp; IN struct componentname *cnp; @@ -353,6 +367,8 @@ vop_mkdir { # vop_rmdir { VERSION 2 + PRE=vop_rmdir_pre + POST=vop_rmdir_post IN LOCKED=YES struct vnode *dvp; IN LOCKED=YES WILLPUT struct vnode *vp; IN struct componentname *cnp; @@ -366,6 +382,7 @@ vop_rmdir { # vop_symlink { VERSION 3 + POST=vop_symlink_post IN LOCKED=YES struct vnode *dvp; OUT WILLMAKE struct vnode **vpp; IN struct componentname *cnp; @@ -549,6 +566,7 @@ vop_getacl { #% setacl vp L L L # vop_setacl { + POST=vop_setacl_post IN struct vnode *vp; IN acl_type_t type; IN struct acl *aclp; 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; diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c index ec42e805bd9..b142f0872c1 100644 --- a/sys/nfs/nfs_bio.c +++ b/sys/nfs/nfs_bio.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_bio.c,v 1.199 2020/09/05 16:30:12 riastradh Exp $ */ +/* $NetBSD: nfs_bio.c,v 1.200 2021/10/20 03:08:18 thorpej Exp $ */ /* * Copyright (c) 1989, 1993 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.199 2020/09/05 16:30:12 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.200 2021/10/20 03:08:18 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -455,7 +455,6 @@ nfs_write(void *v) vsize_t bytelen; int error = 0; int ioflag = ap->a_ioflag; - int extended = 0, wrotedata = 0; #ifdef DIAGNOSTIC if (uio->uio_rw != UIO_WRITE) @@ -545,7 +544,6 @@ nfs_write(void *v) } break; } - wrotedata = 1; /* * update UVM's notion of the size now that we've @@ -554,7 +552,6 @@ nfs_write(void *v) if (vp->v_size < uio->uio_offset) { uvm_vnp_setsize(vp, uio->uio_offset); - extended = 1; } if ((oldoff & ~(nmp->nm_wsize - 1)) != @@ -566,8 +563,6 @@ nfs_write(void *v) ~(nmp->nm_wsize - 1)), PGO_CLEANIT); } } while (uio->uio_resid > 0); - if (wrotedata) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); if (error == 0 && (ioflag & IO_SYNC) != 0) { rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); error = VOP_PUTPAGES(vp, diff --git a/sys/nfs/nfs_kq.c b/sys/nfs/nfs_kq.c index b16b06ebe4c..62ec262afa0 100644 --- a/sys/nfs/nfs_kq.c +++ b/sys/nfs/nfs_kq.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_kq.c,v 1.31 2021/10/11 01:49:08 thorpej Exp $ */ +/* $NetBSD: nfs_kq.c,v 1.32 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_kq.c,v 1.31 2021/10/11 01:49:08 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_kq.c,v 1.32 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -191,9 +191,7 @@ filt_nfsdetach(struct knote *kn) struct vnode *vp = (struct vnode *)kn->kn_hook; struct kevq *ke; - mutex_enter(vp->v_interlock); - SLIST_REMOVE(&vp->v_klist, kn, knote, kn_selnext); - mutex_exit(vp->v_interlock); + vn_knote_detach(vp, kn); /* Remove the vnode from watch list */ mutex_enter(&nfskq_lock); @@ -364,10 +362,9 @@ nfs_kqfilter(void *v) SLIST_INSERT_HEAD(&kevlist, ke, kev_link); } - mutex_enter(vp->v_interlock); - SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext); kn->kn_hook = vp; - mutex_exit(vp->v_interlock); + + vn_knote_attach(vp, kn); /* kick the poller */ cv_signal(&nfskq_cv); diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index d0dd4398e5b..cea0bf15d44 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_vnops.c,v 1.320 2021/07/18 23:57:15 dholland Exp $ */ +/* $NetBSD: nfs_vnops.c,v 1.321 2021/10/20 03:08:18 thorpej Exp $ */ /* * Copyright (c) 1989, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.320 2021/07/18 23:57:15 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.321 2021/10/20 03:08:18 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -652,7 +652,6 @@ nfs_setattr(void *v) } genfs_node_unlock(vp); } - VN_KNOTE(vp, NOTE_ATTRIB); return (error); } @@ -1536,7 +1535,6 @@ nfs_mknod(void *v) int error; error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, ap->a_vap); - VN_KNOTE(dvp, NOTE_WRITE); if (error == 0 || error == EEXIST) cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0); return (error); @@ -1677,7 +1675,6 @@ again: VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp)); - VN_KNOTE(ap->a_dvp, NOTE_WRITE); return (error); } @@ -1695,11 +1692,12 @@ again: int nfs_remove(void *v) { - struct vop_remove_v2_args /* { + struct vop_remove_v3_args /* { struct vnodeop_desc *a_desc; 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; struct vnode *dvp = ap->a_dvp; @@ -1736,13 +1734,12 @@ nfs_remove(void *v) cnp->cn_namelen, cnp->cn_cred, curlwp); } else if (!np->n_sillyrename) error = nfs_sillyrename(dvp, vp, cnp, false); - if (!error && nfs_getattrcache(vp, &vattr) == 0 && - vattr.va_nlink == 1) { - np->n_flag |= NREMOVED; + if (error == 0 && nfs_getattrcache(vp, &vattr) == 0) { + ap->ctx_vp_new_nlink = vattr.va_nlink - 1; + if (vattr.va_nlink == 1) + np->n_flag |= NREMOVED; } NFS_INVALIDATE_ATTRCACHE(np); - VN_KNOTE(vp, NOTE_DELETE); - VN_KNOTE(dvp, NOTE_WRITE); if (dvp == vp) vrele(vp); else @@ -1812,7 +1809,7 @@ nfs_removerpc(struct vnode *dvp, const char *name, int namelen, kauth_cred_t cre int nfs_rename(void *v) { - struct vop_rename_args /* { + struct vop_rename_args /* { struct vnode *a_fdvp; struct vnode *a_fvp; struct componentname *a_fcnp; @@ -2029,8 +2026,6 @@ nfs_link(void *v) cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0); } VOP_UNLOCK(vp); - VN_KNOTE(vp, NOTE_LINK); - VN_KNOTE(dvp, NOTE_WRITE); return (error); } @@ -2120,7 +2115,6 @@ nfs_symlink(void *v) VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp)); - VN_KNOTE(dvp, NOTE_WRITE); return (error); } @@ -2207,7 +2201,6 @@ nfs_mkdir(void *v) vrele(newvp); } } else { - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); nfs_cache_enter(dvp, newvp, cnp); *ap->a_vpp = newvp; VOP_UNLOCK(newvp); @@ -2262,8 +2255,6 @@ nfs_rmdir(void *v) VTONFS(dvp)->n_flag |= NMODIFIED; if (!wccflag) NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp)); - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); - VN_KNOTE(vp, NOTE_DELETE); cache_purge(vp); vput(vp); /* diff --git a/sys/rump/librump/rumpvfs/rumpfs.c b/sys/rump/librump/rumpvfs/rumpfs.c index 7dad946badd..f5041bd611c 100644 --- a/sys/rump/librump/rumpvfs/rumpfs.c +++ b/sys/rump/librump/rumpvfs/rumpfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: rumpfs.c,v 1.165 2021/07/18 23:56:14 dholland Exp $ */ +/* $NetBSD: rumpfs.c,v 1.166 2021/10/20 03:08:18 thorpej Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.165 2021/07/18 23:56:14 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.166 2021/10/20 03:08:18 thorpej Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -1084,10 +1084,11 @@ out: static int rump_vop_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 *dvp = ap->a_dvp; struct vnode *vp = ap->a_vp; diff --git a/sys/sys/event.h b/sys/sys/event.h index 62261ff1eca..16161f353c3 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -1,4 +1,4 @@ -/* $NetBSD: event.h,v 1.48 2021/10/13 04:57:19 thorpej Exp $ */ +/* $NetBSD: event.h,v 1.49 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> @@ -145,6 +145,10 @@ _EV_SET(struct kevent *_kevp, uintptr_t _ident, uint32_t _filter, #define NOTE_LINK 0x0010U /* link count changed */ #define NOTE_RENAME 0x0020U /* vnode was renamed */ #define NOTE_REVOKE 0x0040U /* vnode access was revoked */ +#define NOTE_OPEN 0x0080U /* vnode was opened */ +#define NOTE_CLOSE 0x0100U /* file closed (no FWRITE) */ +#define NOTE_CLOSE_WRITE 0x0200U /* file closed (FWRITE) */ +#define NOTE_READ 0x0400U /* file was read */ /* * data/hint flags for EVFILT_PROC, shared with userspace diff --git a/sys/sys/param.h b/sys/sys/param.h index bfa89e07de8..a423c592983 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.704 2021/10/11 01:07:36 thorpej Exp $ */ +/* $NetBSD: param.h,v 1.705 2021/10/20 03:09:45 thorpej Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -67,7 +67,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 999009100 /* NetBSD 9.99.91 */ +#define __NetBSD_Version__ 999009200 /* NetBSD 9.99.92 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index fa00a650237..712d0e6b399 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.297 2021/06/29 22:40:53 dholland Exp $ */ +/* $NetBSD: vnode.h,v 1.298 2021/10/20 03:08:18 thorpej Exp $ */ /*- * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. @@ -180,6 +180,7 @@ struct vnode { enum vtagtype v_tag; /* - type of underlying data */ void *v_data; /* - private data for fs */ struct klist v_klist; /* i notes attached to vnode */ + long v_klist_interest; /* i what the noes are interested in */ void *v_segvguard; /* e for PAX_SEGVGUARD */ }; #define v_mountedhere v_un.vu_mountedhere @@ -411,15 +412,32 @@ void vref(struct vnode *); #define NULLVP ((struct vnode *)NULL) -static __inline void +/* + * Macro to determine kevent interest on a vnode. + */ +#define VN_KEVENT_INTEREST(vp, n) \ + ((vp)->v_klist_interest != 0) + +static inline void VN_KNOTE(struct vnode *vp, long hint) { - - mutex_enter(vp->v_interlock); - KNOTE(&vp->v_klist, hint); - mutex_exit(vp->v_interlock); + /* + * Testing for klist interest unlocked is fine here, as registering + * interest in vnode events is inherently racy with respect to other + * system activity anyway. Having knotes attached to vnodes is + * actually incredibly rare, so we want to void having to take locks, + * etc. in what is the overwhelmingly common case. + */ + if (__predict_false(VN_KEVENT_INTEREST(vp, hint))) { + mutex_enter(vp->v_interlock); + knote(&vp->v_klist, hint); + mutex_exit(vp->v_interlock); + } } +void vn_knote_attach(struct vnode *, struct knote *); +void vn_knote_detach(struct vnode *, struct knote *); + /* * Global vnode data. */ diff --git a/sys/ufs/chfs/chfs_vnops.c b/sys/ufs/chfs/chfs_vnops.c index a9d7f33600a..a25297a21ef 100644 --- a/sys/ufs/chfs/chfs_vnops.c +++ b/sys/ufs/chfs/chfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: chfs_vnops.c,v 1.45 2021/07/18 23:56:14 dholland Exp $ */ +/* $NetBSD: chfs_vnops.c,v 1.46 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -206,7 +206,6 @@ chfs_create(void *v) return error; } - VN_KNOTE(ap->a_dvp, NOTE_WRITE); return 0; } /* --------------------------------------------------------------------- */ @@ -773,7 +772,6 @@ chfs_write(void *v) off_t osize, origoff, oldoff, preallocoff, endallocoff, nsize; int blkoffset, error, flags, ioflag, resid; int aflag; - int extended=0; vsize_t bytelen; bool async; struct ufsmount *ump; @@ -946,7 +944,6 @@ chfs_write(void *v) if (vp->v_size < newoff) { uvm_vnp_setsize(vp, newoff); - extended = 1; } if (error) @@ -988,8 +985,6 @@ out: ip->mode &= ~ISGID; } } - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); if (error) { (void) UFS_TRUNCATE(vp, osize, ioflag & IO_SYNC, ap->a_cred); uio->uio_offset -= resid - uio->uio_resid; @@ -1038,9 +1033,15 @@ chfs_fsync(void *v) int chfs_remove(void *v) { - struct vnode *dvp = ((struct vop_remove_v2_args *) v)->a_dvp; - struct vnode *vp = ((struct vop_remove_v2_args *) v)->a_vp; - struct componentname *cnp = (((struct vop_remove_v2_args *) v)->a_cnp); + 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 *dvp = ap->a_dvp; + struct vnode *vp = ap->a_vp; + struct componentname *cnp = ap->a_cnp; dbg("remove\n"); KASSERT(VOP_ISLOCKED(dvp)); @@ -1060,6 +1061,9 @@ chfs_remove(void *v) error = chfs_do_unlink(ip, parent, cnp->cn_nameptr, cnp->cn_namelen); + if (error == 0) { + ap->ctx_vp_new_nlink = ip->chvc->nlink; + } out: vput(vp); @@ -1111,12 +1115,21 @@ out: int chfs_rename(void *v) { - struct vnode *fdvp = ((struct vop_rename_args *) v)->a_fdvp; - struct vnode *fvp = ((struct vop_rename_args *) v)->a_fvp; - struct componentname *fcnp = ((struct vop_rename_args *) v)->a_fcnp; - struct vnode *tdvp = ((struct vop_rename_args *) v)->a_tdvp; - struct vnode *tvp = ((struct vop_rename_args *) v)->a_tvp; - struct componentname *tcnp = ((struct vop_rename_args *) v)->a_tcnp; + struct vop_rename_args /* { + const struct vnodeop_desc *a_desc; + struct vnode *a_fdvp; + struct vnode *a_fvp; + struct componentname *a_fcnp; + struct vnode *a_tdvp; + struct vnode *a_tvp; + struct componentname *a_tcnp; + } */ *ap = v; + struct vnode *fdvp = ap->a_fdvp; + struct vnode *fvp = ap->a_fvp; + struct componentname *fcnp = ap->a_fcnp; + struct vnode *tdvp = ap->a_tdvp; + struct vnode *tvp = ap->a_tvp; + struct componentname *tcnp = ap->a_tcnp; struct chfs_inode *oldparent, *old; struct chfs_inode *newparent; @@ -1262,7 +1275,6 @@ chfs_symlink(void *v) err = chfs_makeinode(IFLNK | vap->va_mode, dvp, vpp, cnp, VLNK); if (err) return (err); - VN_KNOTE(dvp, NOTE_WRITE); vp = *vpp; len = strlen(target); ip = VTOI(vp); diff --git a/sys/ufs/ext2fs/ext2fs_readwrite.c b/sys/ufs/ext2fs/ext2fs_readwrite.c index 59dbf53bb05..d1c46bb3875 100644 --- a/sys/ufs/ext2fs/ext2fs_readwrite.c +++ b/sys/ufs/ext2fs/ext2fs_readwrite.c @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_readwrite.c,v 1.77 2020/04/23 21:47:08 ad Exp $ */ +/* $NetBSD: ext2fs_readwrite.c,v 1.78 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 1993 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.77 2020/04/23 21:47:08 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.78 2021/10/20 03:08:19 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -83,7 +83,7 @@ __KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.77 2020/04/23 21:47:08 ad Exp static int ext2fs_post_read_update(struct vnode *, int, int); static int ext2fs_post_write_update(struct vnode *, struct uio *, int, - kauth_cred_t, off_t, int, int, int); + kauth_cred_t, off_t, int, int); /* * Vnode op for reading. @@ -271,7 +271,6 @@ ext2fs_write(void *v) vsize_t bytelen; off_t oldoff = 0; /* XXX */ bool async; - int extended = 0; int advice; ioflag = ap->a_ioflag; @@ -327,7 +326,6 @@ ext2fs_write(void *v) if (vp->v_size < uio->uio_offset) { uvm_vnp_setsize(vp, uio->uio_offset); - extended = 1; } /* @@ -350,7 +348,7 @@ ext2fs_write(void *v) } error = ext2fs_post_write_update(vp, uio, ioflag, ap->a_cred, osize, - resid, extended, error); + resid, error); return error; } @@ -368,7 +366,6 @@ ext2fs_bufwr(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) off_t osize; daddr_t lbn; int resid, blkoffset, xfersize; - int extended = 0; int error; KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); @@ -418,7 +415,6 @@ ext2fs_bufwr(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) if (vp->v_size < uio->uio_offset) { uvm_vnp_setsize(vp, uio->uio_offset); - extended = 1; } if (ioflag & IO_SYNC) @@ -432,13 +428,13 @@ ext2fs_bufwr(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) } error = ext2fs_post_write_update(vp, uio, ioflag, cred, osize, resid, - extended, error); + error); return error; } static int ext2fs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag, - kauth_cred_t cred, off_t osize, int resid, int extended, int oerror) + kauth_cred_t cred, off_t osize, int resid, int oerror) { struct inode *ip = VTOI(vp); int error = oerror; @@ -467,10 +463,6 @@ ext2fs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag, } } - /* If we successfully wrote anything, notify kevent listeners. */ - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); - /* * Update the size on disk: truncate back to original size on * error, or reflect the new size on success. diff --git a/sys/ufs/ext2fs/ext2fs_rename.c b/sys/ufs/ext2fs/ext2fs_rename.c index 44d8d54e1b3..5e6b2cb594f 100644 --- a/sys/ufs/ext2fs/ext2fs_rename.c +++ b/sys/ufs/ext2fs/ext2fs_rename.c @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_rename.c,v 1.11 2016/08/15 18:38:10 jdolecek Exp $ */ +/* $NetBSD: ext2fs_rename.c,v 1.12 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_rename.c,v 1.11 2016/08/15 18:38:10 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_rename.c,v 1.12 2021/10/20 03:08:19 thorpej Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -272,7 +272,7 @@ ext2fs_gro_rename(struct mount *mp, kauth_cred_t cred, 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) { struct ufs_lookup_results *fulr = fde; struct ufs_lookup_results *tulr = tde; @@ -445,6 +445,7 @@ ext2fs_gro_rename(struct mount *mp, kauth_cred_t cred, goto whymustithurtsomuch; #endif } + *tvp_nlinkp = VTOI(tvp)->i_e2fs_nlink; /* * XXX Why is this here, and not above the preceding * conditional? @@ -489,13 +490,6 @@ ext2fs_gro_rename(struct mount *mp, kauth_cred_t cred, if (error) goto whymustithurtsomuch; - /* - * XXX Perhaps this should go at the top, in case the file - * system is modified but incompletely so because of an - * intermediate error. - */ - genfs_rename_knote(fdvp, fvp, tdvp, tvp, - ((tvp != NULL) && (VTOI(tvp)->i_e2fs_nlink == 0))); #if 0 /* XXX */ genfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); #endif @@ -691,7 +685,8 @@ next: */ static int ext2fs_gro_remove(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) { struct ufs_lookup_results *ulr = de; int error; @@ -718,8 +713,7 @@ ext2fs_gro_remove(struct mount *mp, kauth_cred_t cred, VTOI(vp)->i_e2fs_nlink--; VTOI(vp)->i_flag |= IN_CHANGE; - VN_KNOTE(dvp, NOTE_WRITE); - VN_KNOTE(vp, (VTOI(vp)->i_e2fs_nlink? NOTE_LINK : NOTE_DELETE)); + *tvp_nlinkp = VTOI(vp)->i_e2fs_nlink; return 0; } diff --git a/sys/ufs/ext2fs/ext2fs_vnops.c b/sys/ufs/ext2fs/ext2fs_vnops.c index 33b61b3646f..f5ee92ee3f4 100644 --- a/sys/ufs/ext2fs/ext2fs_vnops.c +++ b/sys/ufs/ext2fs/ext2fs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.135 2021/07/18 23:57:15 dholland Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.136 2021/10/20 03:08:19 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.135 2021/07/18 23:57:15 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.136 2021/10/20 03:08:19 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -140,7 +140,6 @@ ext2fs_create(void *v) if (error) return error; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); VOP_UNLOCK(*ap->a_vpp); return 0; } @@ -165,7 +164,6 @@ ext2fs_mknod(void *v) if ((error = ext2fs_makeinode(vap, ap->a_dvp, vpp, ap->a_cnp, 1)) != 0) return error; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; VOP_UNLOCK(*vpp); @@ -453,7 +451,6 @@ ext2fs_setattr(void *v) return EROFS; error = ext2fs_chmod(vp, (int)vap->va_mode, cred, l); } - VN_KNOTE(vp, NOTE_ATTRIB); return error; } @@ -531,10 +528,11 @@ ext2fs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, int ext2fs_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 inode *ip; struct vnode *vp = ap->a_vp; @@ -556,11 +554,10 @@ ext2fs_remove(void *v) if (error == 0) { ip->i_e2fs_nlink--; ip->i_flag |= IN_CHANGE; + ap->ctx_vp_new_nlink = ip->i_e2fs_nlink; } } - VN_KNOTE(vp, NOTE_DELETE); - VN_KNOTE(dvp, NOTE_WRITE); if (dvp == vp) vrele(vp); else @@ -622,8 +619,6 @@ ext2fs_link(void *v) out1: VOP_UNLOCK(vp); out2: - VN_KNOTE(vp, NOTE_LINK); - VN_KNOTE(dvp, NOTE_WRITE); return error; } @@ -748,7 +743,6 @@ bad: ip->i_flag |= IN_CHANGE; vput(tvp); } else { - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); VOP_UNLOCK(tvp); *ap->a_vpp = tvp; } @@ -817,7 +811,6 @@ ext2fs_rmdir(void *v) if (dp->i_e2fs_nlink != EXT2FS_LINK_INF) dp->i_e2fs_nlink--; dp->i_flag |= IN_CHANGE; - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); /* * Truncate inode. The only stuff left @@ -834,7 +827,6 @@ ext2fs_rmdir(void *v) error = ext2fs_truncate(vp, (off_t)0, IO_SYNC, cnp->cn_cred); cache_purge(ITOV(ip)); out: - VN_KNOTE(vp, NOTE_DELETE); vput(vp); return error; } @@ -861,7 +853,6 @@ ext2fs_symlink(void *v) error = ext2fs_makeinode(ap->a_vap, ap->a_dvp, vpp, ap->a_cnp, 1); if (error) return error; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); vp = *vpp; len = strlen(ap->a_target); ip = VTOI(vp); diff --git a/sys/ufs/lfs/lfs_rename.c b/sys/ufs/lfs/lfs_rename.c index f3f3185c4ba..8833a1a323e 100644 --- a/sys/ufs/lfs/lfs_rename.c +++ b/sys/ufs/lfs/lfs_rename.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_rename.c,v 1.24 2020/09/05 16:30:13 riastradh Exp $ */ +/* $NetBSD: lfs_rename.c,v 1.25 2021/10/20 03:08:19 thorpej Exp $ */ /* from NetBSD: ufs_rename.c,v 1.12 2015/03/27 17:27:56 riastradh Exp */ /*- @@ -89,7 +89,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.24 2020/09/05 16:30:13 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.25 2021/10/20 03:08:19 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -477,7 +477,8 @@ next: */ static int ulfs_gro_remove(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) { struct ulfs_lookup_results *ulr = de; int error; @@ -498,13 +499,9 @@ ulfs_gro_remove(struct mount *mp, kauth_cred_t cred, /* XXX ulfs_dirremove decrements vp's link count for us. */ error = ulfs_dirremove(dvp, ulr, VTOI(vp), cnp->cn_flags, 0); - if (error) - goto out1; - VN_KNOTE(dvp, NOTE_WRITE); - VN_KNOTE(vp, (VTOI(vp)->i_nlink? NOTE_LINK : NOTE_DELETE)); + *tvp_nlinkp = VTOI(vp)->i_nlink; -out1: return error; } @@ -732,7 +729,7 @@ ulfs_gro_rename(struct mount *mp, kauth_cred_t cred, 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) { struct lfs *fs; struct ulfs_lookup_results *fulr = fde; @@ -987,13 +984,9 @@ ulfs_gro_rename(struct mount *mp, kauth_cred_t cred, #endif goto arghmybrainhurts; - /* - * XXX Perhaps this should go at the top, in case the file - * system is modified but incompletely so because of an - * intermediate error. - */ - genfs_rename_knote(fdvp, fvp, tdvp, tvp, - ((tvp != NULL) && (VTOI(tvp)->i_nlink == 0))); + if (tvp != NULL) { + *tvp_nlinkp = VTOI(tvp)->i_nlink; + } #if 0 /* XXX */ genfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); #endif @@ -1019,7 +1012,7 @@ lfs_gro_rename(struct mount *mp, kauth_cred_t cred, 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 error; @@ -1054,7 +1047,8 @@ lfs_gro_rename(struct mount *mp, kauth_cred_t cred, error = ulfs_gro_rename(mp, cred, fdvp, fcnp, fde, fvp, - tdvp, tcnp, tde, tvp); + tdvp, tcnp, tde, tvp, + tvp_nlinkp); if (tvp && VTOI(tvp)->i_nlink == 0) lfs_orphan(VTOI(tvp)->i_lfs, VTOI(tvp)->i_number); diff --git a/sys/ufs/lfs/lfs_vnops.c b/sys/ufs/lfs/lfs_vnops.c index 2984b4b97df..630148f721a 100644 --- a/sys/ufs/lfs/lfs_vnops.c +++ b/sys/ufs/lfs/lfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vnops.c,v 1.339 2021/07/18 23:57:15 dholland Exp $ */ +/* $NetBSD: lfs_vnops.c,v 1.340 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -125,7 +125,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.339 2021/07/18 23:57:15 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.340 2021/10/20 03:08:19 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -685,7 +685,6 @@ lfs_symlink(void *v) } KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); - VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); /* @@ -780,7 +779,6 @@ lfs_mknod(void *v) } KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); - VN_KNOTE(dvp, NOTE_WRITE); ip = VTOI(*vpp); ino = ip->i_number; ip->i_state |= IN_ACCESS | IN_CHANGE | IN_UPDATE; @@ -850,7 +848,6 @@ lfs_create(void *v) goto out; } KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); - VN_KNOTE(dvp, NOTE_WRITE); VOP_UNLOCK(*vpp); out: @@ -1002,7 +999,6 @@ lfs_mkdir(void *v) cnp, ip->i_number, LFS_IFTODT(ip->i_mode), bp); bad: if (error == 0) { - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); VOP_UNLOCK(tvp); } else { dp->i_nlink--; @@ -1035,10 +1031,11 @@ out: int lfs_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 *dvp, *vp; struct inode *ip; diff --git a/sys/ufs/lfs/ulfs_readwrite.c b/sys/ufs/lfs/ulfs_readwrite.c index e3fbc5d0505..6e0a0126aaa 100644 --- a/sys/ufs/lfs/ulfs_readwrite.c +++ b/sys/ufs/lfs/ulfs_readwrite.c @@ -1,4 +1,4 @@ -/* $NetBSD: ulfs_readwrite.c,v 1.27 2020/04/23 21:47:09 ad Exp $ */ +/* $NetBSD: ulfs_readwrite.c,v 1.28 2021/10/20 03:08:19 thorpej Exp $ */ /* from NetBSD: ufs_readwrite.c,v 1.120 2015/04/12 22:48:38 riastradh Exp */ /*- @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: ulfs_readwrite.c,v 1.27 2020/04/23 21:47:09 ad Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ulfs_readwrite.c,v 1.28 2021/10/20 03:08:19 thorpej Exp $"); #define FS struct lfs #define I_FS i_lfs @@ -48,7 +48,7 @@ __KERNEL_RCSID(1, "$NetBSD: ulfs_readwrite.c,v 1.27 2020/04/23 21:47:09 ad Exp $ static int ulfs_post_read_update(struct vnode *, int, int); static int ulfs_post_write_update(struct vnode *, struct uio *, int, - kauth_cred_t, off_t, int, int, int); + kauth_cred_t, off_t, int, int); /* * Vnode op for reading. @@ -239,7 +239,6 @@ WRITE(void *v) off_t osize, origoff, oldoff, preallocoff, endallocoff, nsize; int blkoffset, error, flags, ioflag, resid; int aflag; - int extended=0; vsize_t bytelen; bool async; @@ -384,7 +383,6 @@ WRITE(void *v) if (vp->v_size < newoff) { uvm_vnp_setsize(vp, newoff); - extended = 1; } if (error) @@ -406,7 +404,7 @@ WRITE(void *v) out: error = ulfs_post_write_update(vp, uio, ioflag, cred, osize, resid, - extended, error); + error); return (error); } @@ -424,7 +422,6 @@ BUFWR(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) off_t osize; int resid, xfersize, size, blkoffset; daddr_t lbn; - int extended=0; int error; bool need_unreserve = false; @@ -482,7 +479,6 @@ BUFWR(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) ip->i_size = uio->uio_offset + xfersize; DIP_ASSIGN(ip, size, ip->i_size); uvm_vnp_setsize(vp, ip->i_size); - extended = 1; } size = lfs_blksize(fs, ip, lbn) - bp->b_resid; if (xfersize > size) @@ -512,14 +508,14 @@ BUFWR(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) } error = ulfs_post_write_update(vp, uio, ioflag, cred, osize, resid, - extended, error); + error); return (error); } static int ulfs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag, - kauth_cred_t cred, off_t osize, int resid, int extended, int oerror) + kauth_cred_t cred, off_t osize, int resid, int oerror) { struct inode *ip = VTOI(vp); int error = oerror; @@ -552,10 +548,6 @@ ulfs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag, } } - /* If we successfully wrote anything, notify kevent listeners. */ - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); - /* * Update the size on disk: truncate back to original size on * error, or reflect the new size on success. diff --git a/sys/ufs/lfs/ulfs_vnops.c b/sys/ufs/lfs/ulfs_vnops.c index 47c957035c8..ac7b7839fa2 100644 --- a/sys/ufs/lfs/ulfs_vnops.c +++ b/sys/ufs/lfs/ulfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ulfs_vnops.c,v 1.54 2020/09/05 16:30:13 riastradh Exp $ */ +/* $NetBSD: ulfs_vnops.c,v 1.55 2021/10/20 03:08:19 thorpej Exp $ */ /* from NetBSD: ufs_vnops.c,v 1.232 2016/05/19 18:32:03 riastradh Exp */ /*- @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.54 2020/09/05 16:30:13 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.55 2021/10/20 03:08:19 thorpej Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -410,7 +410,6 @@ ulfs_setattr(void *v) } error = ulfs_chmod(vp, (int)vap->va_mode, cred, l); } - VN_KNOTE(vp, NOTE_ATTRIB); out: return (error); } @@ -506,10 +505,11 @@ ulfs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, int ulfs_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, *dvp; struct inode *ip; @@ -535,9 +535,10 @@ ulfs_remove(void *v) else { error = ulfs_dirremove(dvp, ulr, ip, ap->a_cnp->cn_flags, 0); + if (error == 0) { + ap->ctx_vp_new_nlink = ip->i_nlink; + } } - VN_KNOTE(vp, NOTE_DELETE); - VN_KNOTE(dvp, NOTE_WRITE); if (dvp == vp) vrele(vp); else @@ -608,8 +609,6 @@ ulfs_link(void *v) out1: VOP_UNLOCK(vp); out2: - VN_KNOTE(vp, NOTE_LINK); - VN_KNOTE(dvp, NOTE_WRITE); return (error); } @@ -734,7 +733,6 @@ ulfs_rmdir(void *v) if (error) { goto out; } - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); /* * Truncate inode. The only stuff left in the directory is "." and @@ -754,7 +752,6 @@ ulfs_rmdir(void *v) ulfsdirhash_free(ip); #endif out: - VN_KNOTE(vp, NOTE_DELETE); vput(vp); return (error); } diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index 0ad2346ebe3..6e909aa5dc7 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -36,7 +36,7 @@ #if 0 __FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_acl.c 356669 2020-01-13 02:31:51Z mjg $"); #endif -__KERNEL_RCSID(0, "$NetBSD: ufs_acl.c,v 1.2 2021/10/10 23:02:10 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_acl.c,v 1.3 2021/10/20 03:08:19 thorpej Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -425,8 +425,6 @@ ufs_setacl_nfs4_internal(struct vnode *vp, struct acl *aclp, DIP_ASSIGN(ip, mode, ip->i_mode); ip->i_flag |= IN_CHANGE; - VN_KNOTE(vp, NOTE_REVOKE); - error = UFS_UPDATE(vp, NULL, NULL, 0); if (lock) UFS_WAPBL_END(vp->v_mount); @@ -607,7 +605,6 @@ ufs_setacl_posix1e(struct vnode *vp, int type, struct acl *aclp, UFS_WAPBL_END(vp->v_mount); } - VN_KNOTE(vp, NOTE_ATTRIB); return (error); } diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index ec6516274b1..e49f60f7f79 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_extern.h,v 1.87 2021/07/18 23:57:15 dholland Exp $ */ +/* $NetBSD: ufs_extern.h,v 1.88 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -133,9 +133,11 @@ int ufs_gro_remove_check_permitted(struct mount *, kauth_cred_t, struct vnode *, struct vnode *); int ufs_gro_rename(struct mount *, kauth_cred_t, struct vnode *, struct componentname *, void *, struct vnode *, - struct vnode *, struct componentname *, void *, struct vnode *); + struct vnode *, struct componentname *, void *, struct vnode *, + nlink_t *); int ufs_gro_remove(struct mount *, kauth_cred_t, - struct vnode *, struct componentname *, void *, struct vnode *); + struct vnode *, struct componentname *, void *, struct vnode *, + nlink_t *); int ufs_gro_lookup(struct mount *, struct vnode *, struct componentname *, void *, struct vnode **); int ufs_gro_genealogy(struct mount *, kauth_cred_t, diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c index 80413221f76..7d324792187 100644 --- a/sys/ufs/ufs/ufs_readwrite.c +++ b/sys/ufs/ufs/ufs_readwrite.c @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_readwrite.c,v 1.126 2020/04/23 21:47:09 ad Exp $ */ +/* $NetBSD: ufs_readwrite.c,v 1.127 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 1993 @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.126 2020/04/23 21:47:09 ad Exp $"); +__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.127 2021/10/20 03:08:19 thorpej Exp $"); #define FS struct fs #define I_FS i_fs @@ -50,7 +50,7 @@ __KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.126 2020/04/23 21:47:09 ad Exp $ static int ufs_post_read_update(struct vnode *, int, int); static int ufs_post_write_update(struct vnode *, struct uio *, int, - kauth_cred_t, off_t, int, int, int); + kauth_cred_t, off_t, int, int); /* * Vnode op for reading. @@ -245,7 +245,6 @@ WRITE(void *v) off_t osize, origoff, oldoff, preallocoff, endallocoff, nsize; int blkoffset, error, flags, ioflag, resid; int aflag; - int extended=0; vsize_t bytelen; bool async; struct ufsmount *ump; @@ -419,7 +418,6 @@ WRITE(void *v) if (vp->v_size < newoff) { uvm_vnp_setsize(vp, newoff); - extended = 1; } if (error) @@ -448,7 +446,7 @@ WRITE(void *v) out: error = ufs_post_write_update(vp, uio, ioflag, cred, osize, resid, - extended, error); + error); UFS_WAPBL_END(vp->v_mount); return (error); @@ -468,7 +466,6 @@ BUFWR(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) off_t osize; int resid, xfersize, size, blkoffset; daddr_t lbn; - int extended=0; int error; KASSERT(ISSET(ioflag, IO_NODELOCKED)); @@ -520,7 +517,6 @@ BUFWR(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) ip->i_size = uio->uio_offset + xfersize; DIP_ASSIGN(ip, size, ip->i_size); uvm_vnp_setsize(vp, ip->i_size); - extended = 1; } size = ufs_blksize(fs, ip, lbn) - bp->b_resid; if (xfersize > size) @@ -548,14 +544,14 @@ BUFWR(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred) } error = ufs_post_write_update(vp, uio, ioflag, cred, osize, resid, - extended, error); + error); return (error); } static int ufs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag, - kauth_cred_t cred, off_t osize, int resid, int extended, int oerror) + kauth_cred_t cred, off_t osize, int resid, int oerror) { struct inode *ip = VTOI(vp); int error = oerror; @@ -588,10 +584,6 @@ ufs_post_write_update(struct vnode *vp, struct uio *uio, int ioflag, } } - /* If we successfully wrote anything, notify kevent listeners. */ - if (resid > uio->uio_resid) - VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); - /* * Update the size on disk: truncate back to original size on * error, or reflect the new size on success. diff --git a/sys/ufs/ufs/ufs_rename.c b/sys/ufs/ufs/ufs_rename.c index 91e0d98f97e..b9992f99195 100644 --- a/sys/ufs/ufs/ufs_rename.c +++ b/sys/ufs/ufs/ufs_rename.c @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_rename.c,v 1.13 2016/10/28 20:38:12 jdolecek Exp $ */ +/* $NetBSD: ufs_rename.c,v 1.14 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_rename.c,v 1.13 2016/10/28 20:38:12 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_rename.c,v 1.14 2021/10/20 03:08:19 thorpej Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -282,7 +282,7 @@ ufs_gro_rename(struct mount *mp, kauth_cred_t cred, 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) { struct ufs_lookup_results *fulr = fde; struct ufs_lookup_results *tulr = tde; @@ -528,13 +528,9 @@ ufs_gro_rename(struct mount *mp, kauth_cred_t cred, #endif goto arghmybrainhurts; - /* - * XXX Perhaps this should go at the top, in case the file - * system is modified but incompletely so because of an - * intermediate error. - */ - genfs_rename_knote(fdvp, fvp, tdvp, tvp, - ((tvp != NULL) && (VTOI(tvp)->i_nlink == 0))); + if (tvp != NULL) { + *tvp_nlinkp = VTOI(tvp)->i_nlink; + } #if 0 /* XXX */ genfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); #endif @@ -762,7 +758,8 @@ ufs_direct_namlen(const struct direct *ep, const struct vnode *vp) */ int ufs_gro_remove(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) { struct ufs_lookup_results *ulr = de; int error; @@ -783,18 +780,14 @@ ufs_gro_remove(struct mount *mp, kauth_cred_t cred, error = UFS_WAPBL_BEGIN(mp); if (error) - goto out0; + goto out; /* XXX ufs_dirremove decrements vp's link count for us. */ error = ufs_dirremove(dvp, ulr, VTOI(vp), cnp->cn_flags, 0); - if (error) - goto out1; - - VN_KNOTE(dvp, NOTE_WRITE); - VN_KNOTE(vp, (VTOI(vp)->i_nlink? NOTE_LINK : NOTE_DELETE)); + UFS_WAPBL_END(mp); -out1: UFS_WAPBL_END(mp); -out0: + *tvp_nlinkp = VTOI(vp)->i_nlink; +out: return error; } diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index a0e3cd15994..336e8817255 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vnops.c,v 1.259 2020/09/05 16:30:13 riastradh Exp $ */ +/* $NetBSD: ufs_vnops.c,v 1.260 2021/10/20 03:08:19 thorpej Exp $ */ /*- * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.259 2020/09/05 16:30:13 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.260 2021/10/20 03:08:19 thorpej Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -165,7 +165,6 @@ ufs_create(void *v) return (error); } UFS_WAPBL_END(dvp->v_mount); - VN_KNOTE(dvp, NOTE_WRITE); VOP_UNLOCK(*ap->a_vpp); return (0); } @@ -202,7 +201,6 @@ ufs_mknod(void *v) */ if ((error = ufs_makeinode(vap, ap->a_dvp, ulr, vpp, ap->a_cnp)) != 0) goto out; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; UFS_WAPBL_UPDATE(*vpp, NULL, NULL, 0); @@ -672,7 +670,6 @@ ufs_setattr(void *v) error = ufs_chmod(vp, (int)vap->va_mode, cred, l); UFS_WAPBL_END(vp->v_mount); } - VN_KNOTE(vp, NOTE_ATTRIB); out: cache_enter_id(vp, ip->i_mode, ip->i_uid, ip->i_gid, !HAS_ACLS(ip)); return (error); @@ -822,10 +819,11 @@ ufs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, int ufs_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, *dvp; struct inode *ip; @@ -863,10 +861,11 @@ ufs_remove(void *v) error = ufs_dirremove(dvp, ulr, ip, ap->a_cnp->cn_flags, 0); UFS_WAPBL_END(mp); + if (error == 0) { + ap->ctx_vp_new_nlink = ip->i_nlink; + } } } - VN_KNOTE(vp, NOTE_DELETE); - VN_KNOTE(dvp, NOTE_WRITE); #ifdef notyet err: #endif @@ -946,8 +945,6 @@ ufs_link(void *v) out1: VOP_UNLOCK(vp); out2: - VN_KNOTE(vp, NOTE_LINK); - VN_KNOTE(dvp, NOTE_WRITE); return (error); } @@ -1351,7 +1348,6 @@ ufs_mkdir(void *v) pool_cache_put(ufs_direct_cache, newdir); bad: if (error == 0) { - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); VOP_UNLOCK(tvp); UFS_WAPBL_END(dvp->v_mount); } else { @@ -1447,7 +1443,6 @@ ufs_rmdir(void *v) UFS_WAPBL_END(dvp->v_mount); goto out; } - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); /* * Truncate inode. The only stuff left in the directory is "." and @@ -1473,7 +1468,6 @@ ufs_rmdir(void *v) ufsdirhash_free(ip); #endif out: - VN_KNOTE(vp, NOTE_DELETE); vput(vp); return error; err: @@ -1516,7 +1510,6 @@ ufs_symlink(void *v) error = ufs_makeinode(ap->a_vap, ap->a_dvp, ulr, vpp, ap->a_cnp); if (error) goto out; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); vp = *vpp; len = strlen(ap->a_target); ip = VTOI(vp); |
