diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2026-03-06 00:18:11 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-03-10 12:44:27 +0000 |
| commit | 92d7808d88f0de979d76446c76c7324731c41302 (patch) | |
| tree | dc33710766a9b6b1c33a3c3fea525945bc8f2b1a | |
| parent | a2b601343bf9261c4ada51e4d4c30c5b9320bb2b (diff) | |
vn_delayed_setsize(): post-commit review' changes
Handle doomed vnodes after LK_RETRY.
Rename the flag from VI_DELAYEDSSZ to VI_DELAYED_SETSIZE.
Change signature of vn_lock_delayed_setsize() to take flatten values
list instead of vop args structure.
__predict_true() for VI_DELAYED_SETSIZE not set.
Minor editings like removing tautological assert, and sorting items.
Noted by: markj
Fixes: 45117ffcd533ddf995f654db60b10899ae8370ec
Reviewed by: markj, rmacklem
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D55681
| -rw-r--r-- | sys/fs/deadfs/dead_vnops.c | 6 | ||||
| -rw-r--r-- | sys/fs/nfsclient/nfs_clport.c | 2 | ||||
| -rw-r--r-- | sys/kern/vfs_vnops.c | 52 | ||||
| -rw-r--r-- | sys/sys/vnode.h | 12 |
4 files changed, 35 insertions, 37 deletions
diff --git a/sys/fs/deadfs/dead_vnops.c b/sys/fs/deadfs/dead_vnops.c index b6d6fa55d221..c793ef2ebf4d 100644 --- a/sys/fs/deadfs/dead_vnops.c +++ b/sys/fs/deadfs/dead_vnops.c @@ -55,6 +55,9 @@ struct vop_vector dead_vnodeops = { .vop_bmap = VOP_EBADF, .vop_close = dead_close, .vop_create = VOP_PANIC, + .vop_delayed_setsize = VOP_NULL, + .vop_fplookup_symlink = VOP_EOPNOTSUPP, + .vop_fplookup_vexec = VOP_EOPNOTSUPP, .vop_getattr = VOP_EBADF, .vop_getwritemount = dead_getwritemount, .vop_inactive = VOP_NULL, @@ -78,9 +81,6 @@ struct vop_vector dead_vnodeops = { .vop_vptocnp = VOP_EBADF, .vop_unset_text = dead_unset_text, .vop_write = dead_write, - .vop_fplookup_vexec = VOP_EOPNOTSUPP, - .vop_fplookup_symlink = VOP_EOPNOTSUPP, - .vop_delayed_setsize = VOP_NULL, }; VFS_VOP_VECTOR_REGISTER(dead_vnodeops); diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 1156e1738703..cf163adc02de 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -646,7 +646,7 @@ ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep) (curthread->td_pflags2 & TDP2_SBPAGES) == 0) setnsize = true; else - vn_delay_setsize(vp); + vn_delayed_setsize(vp); } if (nsizep == NULL) { NFSUNLOCKNODE(np); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 24efdf4ac0d5..ea8f8437b743 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1960,25 +1960,25 @@ _vn_lock_fallback(struct vnode *vp, int flags, const char *file, int line, } static int -vn_lock_delayed_setsize(struct vop_lock1_args *ap) +vn_lock_delayed_setsize(struct vnode *vp, int flags, const char *file, int line) { - struct vnode *vp; + struct vop_lock1_args ap; int error, lktype; bool onfault; - vp = ap->a_vp; - lktype = ap->a_flags & LK_TYPE_MASK; + ASSERT_VOP_LOCKED(vp, "vn_lock_delayed_setsize"); + lktype = flags & LK_TYPE_MASK; if (vp->v_op == &dead_vnodeops) return (0); VI_LOCK(vp); - if ((vp->v_iflag & VI_DELAYEDSSZ) == 0 || (lktype != LK_SHARED && + if ((vp->v_iflag & VI_DELAYED_SETSIZE) == 0 || (lktype != LK_SHARED && lktype != LK_EXCLUSIVE && lktype != LK_UPGRADE && lktype != LK_TRYUPGRADE)) { VI_UNLOCK(vp); return (0); } - onfault = (ap->a_flags & LK_EATTR_MASK) == LK_NOWAIT && - (ap->a_flags & LK_INIT_MASK) == LK_CANRECURSE && + onfault = (flags & LK_EATTR_MASK) == LK_NOWAIT && + (flags & LK_INIT_MASK) == LK_CANRECURSE && (lktype == LK_SHARED || lktype == LK_EXCLUSIVE); if (onfault && vp->v_vnlock->lk_recurse == 0) { /* @@ -1990,35 +1990,38 @@ vn_lock_delayed_setsize(struct vop_lock1_args *ap) VOP_UNLOCK(vp); return (EBUSY); } - if ((ap->a_flags & LK_NOWAIT) != 0 || + if ((flags & LK_NOWAIT) != 0 || (lktype == LK_SHARED && vp->v_vnlock->lk_recurse > 0)) { VI_UNLOCK(vp); return (0); } if (lktype == LK_SHARED) { VOP_UNLOCK(vp); - ap->a_flags &= ~LK_TYPE_MASK; - ap->a_flags |= LK_EXCLUSIVE | LK_INTERLOCK; - error = VOP_LOCK1_APV(&default_vnodeops, ap); + ap.a_gen.a_desc = &vop_lock1_desc; + ap.a_vp = vp; + ap.a_flags = (flags & ~LK_TYPE_MASK) | LK_EXCLUSIVE | + LK_INTERLOCK; + ap.a_file = file; + ap.a_line = line; + error = VOP_LOCK1_APV(&default_vnodeops, &ap); if (error != 0 || vp->v_op == &dead_vnodeops) return (error); if (vp->v_data == NULL) goto downgrade; - MPASS(vp->v_data != NULL); VI_LOCK(vp); - if ((vp->v_iflag & VI_DELAYEDSSZ) == 0) { + if ((vp->v_iflag & VI_DELAYED_SETSIZE) == 0) { VI_UNLOCK(vp); goto downgrade; } } - vp->v_iflag &= ~VI_DELAYEDSSZ; + vn_clear_delayed_setsize_locked(vp); VI_UNLOCK(vp); VOP_DELAYED_SETSIZE(vp); downgrade: if (lktype == LK_SHARED) { - ap->a_flags &= ~(LK_TYPE_MASK | LK_INTERLOCK); - ap->a_flags |= LK_DOWNGRADE; - (void)VOP_LOCK1_APV(&default_vnodeops, ap); + ap.a_flags &= ~(LK_TYPE_MASK | LK_INTERLOCK); + ap.a_flags |= LK_DOWNGRADE; + (void)VOP_LOCK1_APV(&default_vnodeops, &ap); } return (0); } @@ -2026,7 +2029,6 @@ downgrade: int _vn_lock(struct vnode *vp, int flags, const char *file, int line) { - struct vop_lock1_args ap; int error; VNASSERT((flags & LK_TYPE_MASK) != 0, vp, @@ -2034,15 +2036,11 @@ _vn_lock(struct vnode *vp, int flags, const char *file, int line) VNPASS(vp->v_holdcnt > 0, vp); error = VOP_LOCK1(vp, flags, file, line); if (__predict_false(error != 0 || VN_IS_DOOMED(vp))) - return (_vn_lock_fallback(vp, flags, file, line, error)); - if (__predict_false((vp->v_iflag & VI_DELAYEDSSZ) == 0)) - return (0); - ap.a_gen.a_desc = &vop_lock1_desc; - ap.a_vp = vp; - ap.a_flags = flags; - ap.a_file = file; - ap.a_line = line; - return (vn_lock_delayed_setsize(&ap)); + error = _vn_lock_fallback(vp, flags, file, line, error); + if (error != 0 || __predict_true((atomic_load_short(&vp->v_iflag) & + VI_DELAYED_SETSIZE) == 0)) + return (error); + return (vn_lock_delayed_setsize(vp, flags, file, line)); } /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 36e10fd8d8b7..3fd2c770cda1 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -268,7 +268,7 @@ _Static_assert(sizeof(struct vnode) <= 448, "vnode size crosses 448 bytes"); #define VI_DEFINACT 0x0010 /* deferred inactive */ #define VI_FOPENING 0x0020 /* In open, with opening process having the first right to advlock file */ -#define VI_DELAYEDSSZ 0x0040 /* Delayed setsize */ +#define VI_DELAYED_SETSIZE 0x0040 /* Delayed setsize */ #define VV_ROOT 0x0001 /* root of its filesystem */ #define VV_ISTTY 0x0002 /* vnode represents a tty */ @@ -1253,17 +1253,17 @@ vn_get_state(struct vnode *vp) }) static inline void -vn_delay_setsize_locked(struct vnode *vp) +vn_delayed_setsize_locked(struct vnode *vp) { ASSERT_VI_LOCKED(vp, "delayed_setsize"); - vp->v_iflag |= VI_DELAYEDSSZ; + vp->v_iflag |= VI_DELAYED_SETSIZE; } static inline void -vn_delay_setsize(struct vnode *vp) +vn_delayed_setsize(struct vnode *vp) { VI_LOCK(vp); - vn_delay_setsize_locked(vp); + vn_delayed_setsize_locked(vp); VI_UNLOCK(vp); } @@ -1271,7 +1271,7 @@ static inline void vn_clear_delayed_setsize_locked(struct vnode *vp) { ASSERT_VI_LOCKED(vp, "delayed_setsize"); - vp->v_iflag &= ~VI_DELAYEDSSZ; + vp->v_iflag &= ~VI_DELAYED_SETSIZE; } static inline void |
