Index: sys/ufs/lfs/lfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v retrieving revision 1.309 diff -p -u -r1.309 lfs_vnops.c --- sys/ufs/lfs/lfs_vnops.c 1 Apr 2017 14:43:00 -0000 1.309 +++ sys/ufs/lfs/lfs_vnops.c 1 Apr 2017 18:02:22 -0000 @@ -407,6 +407,7 @@ lfs_makeinode(struct vattr *vap, struct if (error) goto bad; *vpp = tvp; + KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); return (0); bad: @@ -438,17 +439,20 @@ lfs_fsync(void *v) off_t offhi; } */ *ap = v; struct vnode *vp = ap->a_vp; - int error, wait; + int wait; struct inode *ip = VTOI(vp); struct lfs *fs = ip->i_lfs; + int error = 0; + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); /* If we're mounted read-only, don't try to sync. */ if (fs->lfs_ronly) - return 0; + goto out; /* If a removed vnode is being cleaned, no need to sync here. */ if ((ap->a_flags & FSYNC_RECLAIM) != 0 && ip->i_mode == 0) - return 0; + goto out; /* * Trickle sync simply adds this vnode to the pager list, as if @@ -465,7 +469,7 @@ lfs_fsync(void *v) wakeup(&lfs_writer_daemon); mutex_exit(&lfs_lock); } - return 0; + goto out; } /* @@ -491,7 +495,7 @@ lfs_fsync(void *v) } } while (error == EAGAIN); if (error) - return error; + goto out; if ((ap->a_flags & FSYNC_DATAONLY) == 0) error = lfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0); @@ -504,6 +508,8 @@ lfs_fsync(void *v) if (wait && !VPISEMPTY(vp)) LFS_SET_UINO(ip, IN_MODIFIED); +out: + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); return error; } @@ -517,6 +523,8 @@ lfs_inactive(void *v) struct vnode *a_vp; } */ *ap = v; + KASSERT(VOP_ISLOCKED(ap->a_vp) == LK_EXCLUSIVE); + lfs_unmark_vnode(ap->a_vp); /* @@ -552,8 +560,8 @@ lfs_set_dirop(struct vnode *dvp, struct struct lfs *fs; int error; - KASSERT(VOP_ISLOCKED(dvp)); - KASSERT(vp == NULL || VOP_ISLOCKED(vp)); + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + KASSERT(vp == NULL || VOP_ISLOCKED(vp) == LK_EXCLUSIVE); fs = VTOI(dvp)->i_lfs; @@ -701,6 +709,7 @@ lfs_symlink(void *v) dvp = ap->a_dvp; vpp = ap->a_vpp; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); KASSERT(vpp != NULL); KASSERT(*vpp == NULL); KASSERT(ap->a_vap->va_type == VLNK); @@ -723,6 +732,7 @@ lfs_symlink(void *v) if (error) { goto out; } + KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); @@ -787,9 +797,10 @@ lfs_mknod(void *v) vpp = ap->a_vpp; vap = ap->a_vap; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); KASSERT(vpp != NULL); KASSERT(*vpp == NULL); - + /* XXX should handle this material another way */ ulr = &VTOI(dvp)->i_crap; ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); @@ -816,6 +827,7 @@ lfs_mknod(void *v) *vpp = NULL; return (error); } + KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); VN_KNOTE(dvp, NOTE_WRITE); ip = VTOI(*vpp); @@ -864,6 +876,7 @@ lfs_create(void *v) vpp = ap->a_vpp; vap = ap->a_vap; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); KASSERT(vpp != NULL); KASSERT(*vpp == NULL); @@ -885,6 +898,7 @@ lfs_create(void *v) if (error) { goto out; } + KASSERT(VOP_ISLOCKED(*vpp) == LK_EXCLUSIVE); VN_KNOTE(dvp, NOTE_WRITE); VOP_UNLOCK(*vpp); @@ -927,6 +941,8 @@ lfs_mkdir(void *v) cnp = ap->a_cnp; vap = ap->a_vap; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + dp = VTOI(dvp); ip = NULL; @@ -1078,6 +1094,10 @@ lfs_remove(void *v) dvp = ap->a_dvp; vp = ap->a_vp; + + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + ip = VTOI(vp); if ((error = lfs_set_dirop(dvp, vp)) != 0) { if (dvp == vp) @@ -1118,6 +1138,10 @@ lfs_rmdir(void *v) int error; vp = ap->a_vp; + + KASSERT(VOP_ISLOCKED(ap->a_dvp) == LK_EXCLUSIVE); + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + ip = VTOI(vp); if ((error = lfs_set_dirop(ap->a_dvp, ap->a_vp)) != 0) { if (ap->a_dvp == vp) @@ -1158,6 +1182,8 @@ lfs_link(void *v) dvp = ap->a_dvp; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + fs = VFSTOULFS(dvp->v_mount)->um_lfs; ASSERT_NO_SEGLOCK(fs); if (fs->lfs_ronly) { @@ -1188,9 +1214,14 @@ lfs_getattr(void *v) kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); + struct inode *ip; struct vattr *vap = ap->a_vap; - struct lfs *fs = ip->i_lfs; + struct lfs *fs; + + KASSERT(VOP_ISLOCKED(vp)); + + ip = VTOI(vp); + fs = ip->i_lfs; /* * Copy from inode table @@ -1246,6 +1277,7 @@ lfs_setattr(void *v) } */ *ap = v; struct vnode *vp = ap->a_vp; + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); lfs_check(vp, LFS_UNUSED_LBN, 0); return ulfs_setattr(v); } @@ -1297,8 +1329,13 @@ lfs_close(void *v) kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - struct lfs *fs = ip->i_lfs; + struct inode *ip; + struct lfs *fs; + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + ip = VTOI(vp); + fs = ip->i_lfs; if ((ip->i_number == ULFS_ROOTINO || ip->i_number == LFS_IFILE_INUM) && fs->lfs_stoplwp == curlwp) { @@ -1335,6 +1372,9 @@ lfsspec_close(void *v) struct inode *ip; vp = ap->a_vp; + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + ip = VTOI(vp); if (vp->v_usecount > 1) { LFS_ITIMES(ip, NULL, NULL, NULL); @@ -1359,6 +1399,9 @@ lfsfifo_close(void *v) struct inode *ip; vp = ap->a_vp; + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + ip = VTOI(vp); if (ap->a_vp->v_usecount > 1) { LFS_ITIMES(ip, NULL, NULL, NULL); @@ -1377,10 +1420,13 @@ lfs_reclaim(void *v) struct vnode *a_vp; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - struct lfs *fs = ip->i_lfs; + struct inode *ip; + struct lfs *fs; int error; + ip = VTOI(vp); + fs = ip->i_lfs; + /* * The inode must be freed and updated before being removed * from its hash chain. Other threads trying to gain a hold @@ -2194,9 +2240,14 @@ lfs_openextattr(void *v) kauth_cred_t a_cred; struct proc *a_p; } */ *ap = v; - struct inode *ip = VTOI(ap->a_vp); - struct ulfsmount *ump = ip->i_ump; - //struct lfs *fs = ip->i_lfs; + struct vnode *vp = ap->a_vp; + struct inode *ip; + struct ulfsmount *ump; + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + ip = VTOI(vp); + ump = ip->i_ump; /* Not supported for ULFS1 file systems. */ if (ump->um_fstype == ULFS1) @@ -2215,9 +2266,14 @@ lfs_closeextattr(void *v) kauth_cred_t a_cred; struct proc *a_p; } */ *ap = v; - struct inode *ip = VTOI(ap->a_vp); - struct ulfsmount *ump = ip->i_ump; - //struct lfs *fs = ip->i_lfs; + struct vnode *vp = ap->a_vp; + struct inode *ip; + struct ulfsmount *ump; + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + ip = VTOI(ap->a_vp); + ump = ip->i_ump; /* Not supported for ULFS1 file systems. */ if (ump->um_fstype == ULFS1) @@ -2240,11 +2296,15 @@ lfs_getextattr(void *v) struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - struct ulfsmount *ump = ip->i_ump; - //struct lfs *fs = ip->i_lfs; + struct inode *ip; + struct ulfsmount *ump; int error; + KASSERT(VOP_ISLOCKED(vp)); + + ip = VTOI(vp); + ump = ip->i_ump; + if (ump->um_fstype == ULFS1) { #ifdef LFS_EXTATTR error = ulfs_getextattr(ap); @@ -2270,11 +2330,15 @@ lfs_setextattr(void *v) struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - struct ulfsmount *ump = ip->i_ump; - //struct lfs *fs = ip->i_lfs; + struct inode *ip; + struct ulfsmount *ump; int error; + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + ip = VTOI(vp); + ump = ip->i_ump; + if (ump->um_fstype == ULFS1) { #ifdef LFS_EXTATTR error = ulfs_setextattr(ap); @@ -2300,11 +2364,15 @@ lfs_listextattr(void *v) struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - struct ulfsmount *ump = ip->i_ump; - //struct lfs *fs = ip->i_lfs; + struct inode *ip; + struct ulfsmount *ump; int error; + KASSERT(VOP_ISLOCKED(vp)); + + ip = VTOI(vp); + ump = ip->i_ump; + if (ump->um_fstype == ULFS1) { #ifdef LFS_EXTATTR error = ulfs_listextattr(ap); @@ -2328,11 +2396,15 @@ lfs_deleteextattr(void *v) struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - struct ulfsmount *ump = ip->i_ump; - //struct fs *fs = ip->i_lfs; + struct inode *ip; + struct ulfsmount *ump; int error; + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + ip = VTOI(vp); + ump = ip->i_ump; + if (ump->um_fstype == ULFS1) { #ifdef LFS_EXTATTR error = ulfs_deleteextattr(ap); Index: sys/ufs/lfs/ulfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/ulfs_vnops.c,v retrieving revision 1.46 diff -p -u -r1.46 ulfs_vnops.c --- sys/ufs/lfs/ulfs_vnops.c 30 Mar 2017 09:10:08 -0000 1.46 +++ sys/ufs/lfs/ulfs_vnops.c 1 Apr 2017 18:02:22 -0000 @@ -128,6 +128,8 @@ ulfs_open(void *v) kauth_cred_t a_cred; } */ *ap = v; + KASSERT(VOP_ISLOCKED(ap->a_vp) == LK_EXCLUSIVE); + /* * Files marked append-only must be opened for appending. */ @@ -208,9 +210,12 @@ ulfs_access(void *v) int error; vp = ap->a_vp; - ip = VTOI(vp); mode = ap->a_mode; + KASSERT(VOP_ISLOCKED(vp)); + + ip = VTOI(vp); + error = ulfs_check_possible(vp, ip, mode, ap->a_cred); if (error) return error; @@ -243,13 +248,16 @@ ulfs_setattr(void *v) vap = ap->a_vap; vp = ap->a_vp; - ip = VTOI(vp); - fs = ip->i_lfs; cred = ap->a_cred; l = curlwp; action = KAUTH_VNODE_WRITE_FLAGS; changing_sysflags = false; + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + ip = VTOI(vp); + fs = ip->i_lfs; + /* * Check for unsettable attributes. */ @@ -411,6 +419,8 @@ ulfs_chmod(struct vnode *vp, int mode, k struct inode *ip; int error; + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + ip = VTOI(vp); error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_SECURITY, vp, @@ -440,6 +450,9 @@ ulfs_chown(struct vnode *vp, uid_t uid, gid_t ogid; int64_t change; #endif + + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + ip = VTOI(vp); error = 0; @@ -497,10 +510,14 @@ ulfs_remove(void *v) int error; struct ulfs_lookup_results *ulr; - vp = ap->a_vp; dvp = ap->a_dvp; + vp = ap->a_vp; + + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + KASSERT(dvp->v_mount == vp->v_mount); + ip = VTOI(vp); - KASSERT(dvp->v_mount == vp->v_mount); /* XXX Not stable without lock. */ /* XXX should handle this material another way */ ulr = &VTOI(dvp)->i_crap; @@ -541,9 +558,9 @@ ulfs_link(void *v) int error; struct ulfs_lookup_results *ulr; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); KASSERT(dvp != vp); KASSERT(vp->v_type != VDIR); - KASSERT(dvp->v_mount == vp->v_mount); /* XXX Not stable without lock. */ /* XXX should handle this material another way */ ulr = &VTOI(dvp)->i_crap; @@ -554,6 +571,11 @@ ulfs_link(void *v) VOP_ABORTOP(dvp, cnp); goto out2; } + if (vp->v_mount != dvp->v_mount) { + error = ENOENT; + VOP_ABORTOP(dvp, cnp); + goto out2; + } ip = VTOI(vp); if ((nlink_t)ip->i_nlink >= LINK_MAX) { VOP_ABORTOP(dvp, cnp); @@ -604,6 +626,8 @@ ulfs_whiteout(void *v) struct lfs *fs = ump->um_lfs; struct ulfs_lookup_results *ulr; + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + /* XXX should handle this material another way */ ulr = &VTOI(dvp)->i_crap; ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); @@ -654,11 +678,15 @@ ulfs_rmdir(void *v) int error; struct ulfs_lookup_results *ulr; - vp = ap->a_vp; dvp = ap->a_dvp; + vp = ap->a_vp; cnp = ap->a_cnp; - ip = VTOI(vp); + + KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + dp = VTOI(dvp); + ip = VTOI(vp); /* XXX should handle this material another way */ ulr = &dp->i_crap; @@ -759,6 +787,9 @@ ulfs_readdir(void *v) size_t skipbytes; struct ulfsmount *ump = VFSTOULFS(vp->v_mount); struct lfs *fs = ump->um_lfs; + + KASSERT(VOP_ISLOCKED(vp)); + uio = ap->a_uio; count = uio->uio_resid; rcount = count - ((uio->uio_offset + count) & (fs->um_dirblksiz - 1)); @@ -884,6 +915,8 @@ ulfs_readlink(void *v) struct lfs *fs = ump->um_lfs; int isize; + KASSERT(VOP_ISLOCKED(vp)); + /* * The test against um_maxsymlinklen is off by one; it should * theoretically be <=, not <. However, it cannot be changed @@ -941,6 +974,8 @@ ulfsspec_read(void *v) kauth_cred_t a_cred; } */ *ap = v; + KASSERT(VOP_ISLOCKED(ap->a_vp)); + /* * Set access flag. */ @@ -962,6 +997,8 @@ ulfsspec_write(void *v) kauth_cred_t a_cred; } */ *ap = v; + KASSERT(VOP_ISLOCKED(ap->a_vp) == LK_EXCLUSIVE); + /* * Set update and change flags. */ @@ -983,6 +1020,8 @@ ulfsfifo_read(void *v) kauth_cred_t a_cred; } */ *ap = v; + KASSERT(VOP_ISLOCKED(ap->a_vp)); + /* * Set access flag. */ @@ -1003,6 +1042,8 @@ ulfsfifo_write(void *v) kauth_cred_t a_cred; } */ *ap = v; + KASSERT(VOP_ISLOCKED(ap->a_vp) == LK_EXCLUSIVE); + /* * Set update and change flags. */ @@ -1141,6 +1182,8 @@ ulfs_gop_alloc(struct vnode *vp, off_t o int error, delta, bshift, bsize; UVMHIST_FUNC("ulfs_gop_alloc"); UVMHIST_CALLED(ubchist); + KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + error = 0; bshift = vp->v_mount->mnt_fs_bshift; bsize = 1 << bshift;