Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_vnops.c
Show First 20 Lines • Show All 329 Lines • ▼ Show 20 Lines | #ifdef MAC | ||||
if (fmode & O_VERIFY) | if (fmode & O_VERIFY) | ||||
accmode |= VVERIFY; | accmode |= VVERIFY; | ||||
error = mac_vnode_check_open(cred, vp, accmode); | error = mac_vnode_check_open(cred, vp, accmode); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
accmode &= ~(VCREAT | VVERIFY); | accmode &= ~(VCREAT | VVERIFY); | ||||
#endif | #endif | ||||
if ((fmode & O_CREAT) == 0) { | if ((fmode & O_CREAT) == 0 && accmode != 0) { | ||||
if (accmode & VWRITE) { | |||||
error = vn_writechk(vp); | |||||
if (error) | |||||
return (error); | |||||
} | |||||
if (accmode) { | |||||
error = VOP_ACCESS(vp, accmode, cred, td); | error = VOP_ACCESS(vp, accmode, cred, td); | ||||
if (error) | if (error != 0) | ||||
return (error); | return (error); | ||||
} | } | ||||
} | |||||
if (vp->v_type == VFIFO && VOP_ISLOCKED(vp) != LK_EXCLUSIVE) | if (vp->v_type == VFIFO && VOP_ISLOCKED(vp) != LK_EXCLUSIVE) | ||||
vn_lock(vp, LK_UPGRADE | LK_RETRY); | vn_lock(vp, LK_UPGRADE | LK_RETRY); | ||||
if ((error = VOP_OPEN(vp, fmode, cred, td, fp)) != 0) | if ((fmode & FWRITE) != 0) { | ||||
error = VOP_ADD_WRITECOUNT(vp, 1); | |||||
if (error != 0) | |||||
return (error); | return (error); | ||||
CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", | |||||
while ((fmode & (O_EXLOCK | O_SHLOCK)) != 0) { | __func__, vp, vp->v_writecount); | ||||
} | |||||
for (;;) { | |||||
error = VOP_OPEN(vp, fmode, cred, td, fp); | |||||
if (error != 0) | |||||
break; | |||||
if ((fmode & (O_EXLOCK | O_SHLOCK)) == 0) | |||||
break; | |||||
KASSERT(fp != NULL, ("open with flock requires fp")); | KASSERT(fp != NULL, ("open with flock requires fp")); | ||||
if (fp->f_type != DTYPE_NONE && fp->f_type != DTYPE_VNODE) { | if (fp->f_type != DTYPE_NONE && fp->f_type != DTYPE_VNODE) { | ||||
error = EOPNOTSUPP; | error = EOPNOTSUPP; | ||||
break; | break; | ||||
} | } | ||||
lock_flags = VOP_ISLOCKED(vp); | lock_flags = VOP_ISLOCKED(vp); | ||||
VOP_UNLOCK(vp, 0); | VOP_UNLOCK(vp, 0); | ||||
lf.l_whence = SEEK_SET; | lf.l_whence = SEEK_SET; | ||||
lf.l_start = 0; | lf.l_start = 0; | ||||
lf.l_len = 0; | lf.l_len = 0; | ||||
if (fmode & O_EXLOCK) | if (fmode & O_EXLOCK) | ||||
lf.l_type = F_WRLCK; | lf.l_type = F_WRLCK; | ||||
else | else | ||||
lf.l_type = F_RDLCK; | lf.l_type = F_RDLCK; | ||||
type = F_FLOCK; | type = F_FLOCK; | ||||
if ((fmode & FNONBLOCK) == 0) | if ((fmode & FNONBLOCK) == 0) | ||||
type |= F_WAIT; | type |= F_WAIT; | ||||
error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type); | error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type); | ||||
if (error == 0) | if (error == 0) | ||||
fp->f_flag |= FHASLOCK; | fp->f_flag |= FHASLOCK; | ||||
vn_lock(vp, lock_flags | LK_RETRY); | vn_lock(vp, lock_flags | LK_RETRY); | ||||
if (error != 0) | if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0) | ||||
break; | |||||
if ((vp->v_iflag & VI_DOOMED) != 0) { | |||||
error = ENOENT; | error = ENOENT; | ||||
break; | break; | ||||
} | } | ||||
/* | |||||
* Another thread might have used this vnode as an | |||||
* executable while the vnode lock was dropped. | |||||
* Ensure the vnode is still able to be opened for | |||||
* writing after the lock has been obtained. | |||||
*/ | |||||
if ((accmode & VWRITE) != 0) | |||||
error = vn_writechk(vp); | |||||
break; | |||||
} | |||||
if (error != 0) { | if (error != 0) { | ||||
fp->f_flag |= FOPENFAILED; | |||||
fp->f_vnode = vp; | fp->f_vnode = vp; | ||||
if (fp->f_ops == &badfileops) { | if (fp->f_ops == &badfileops) { | ||||
fp->f_type = DTYPE_VNODE; | fp->f_type = DTYPE_VNODE; | ||||
fp->f_ops = &vnops; | fp->f_ops = &vnops; | ||||
} | } | ||||
vref(vp); | vref(vp); | ||||
} else if ((fmode & FWRITE) != 0) { | |||||
VOP_ADD_WRITECOUNT(vp, 1); | |||||
CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", | |||||
__func__, vp, vp->v_writecount); | |||||
} | } | ||||
ASSERT_VOP_LOCKED(vp, "vn_open_vnode"); | ASSERT_VOP_LOCKED(vp, "vn_open_vnode"); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Check for write permissions on the specified vnode. | * Check for write permissions on the specified vnode. | ||||
* Prototype text segments cannot be written. | * Prototype text segments cannot be written. | ||||
* It is racy. | |||||
*/ | */ | ||||
int | int | ||||
vn_writechk(struct vnode *vp) | vn_writechk(struct vnode *vp) | ||||
{ | { | ||||
ASSERT_VOP_LOCKED(vp, "vn_writechk"); | ASSERT_VOP_LOCKED(vp, "vn_writechk"); | ||||
/* | /* | ||||
* If there's shared text associated with | * If there's shared text associated with | ||||
Show All 16 Lines | vn_close1(struct vnode *vp, int flags, struct ucred *file_cred, | ||||
struct mount *mp; | struct mount *mp; | ||||
int error, lock_flags; | int error, lock_flags; | ||||
if (vp->v_type != VFIFO && (flags & FWRITE) == 0 && | if (vp->v_type != VFIFO && (flags & FWRITE) == 0 && | ||||
MNT_EXTENDED_SHARED(vp->v_mount)) | MNT_EXTENDED_SHARED(vp->v_mount)) | ||||
lock_flags = LK_SHARED; | lock_flags = LK_SHARED; | ||||
else | else | ||||
lock_flags = LK_EXCLUSIVE; | lock_flags = LK_EXCLUSIVE; | ||||
error = 0; | |||||
markj: This is a dead store. | |||||
Done Inline ActionsYes, I already removed it in my branch, to reduce the diff. kib: Yes, I already removed it in my branch, to reduce the diff. | |||||
vn_start_write(vp, &mp, V_WAIT); | vn_start_write(vp, &mp, V_WAIT); | ||||
vn_lock(vp, lock_flags | LK_RETRY); | vn_lock(vp, lock_flags | LK_RETRY); | ||||
AUDIT_ARG_VNODE1(vp); | AUDIT_ARG_VNODE1(vp); | ||||
if ((flags & (FWRITE | FOPENFAILED)) == FWRITE) { | if ((flags & FWRITE) != 0) { | ||||
VNASSERT(vp->v_writecount > 0, vp, | VOP_ADD_WRITECOUNT_SUCCEED(vp, -1); | ||||
("vn_close: negative writecount")); | |||||
VOP_ADD_WRITECOUNT(vp, -1); | |||||
CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", | CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", | ||||
__func__, vp, vp->v_writecount); | __func__, vp, vp->v_writecount); | ||||
} | } | ||||
error = VOP_CLOSE(vp, flags, file_cred, td); | error = VOP_CLOSE(vp, flags, file_cred, td); | ||||
if (keep_ref) | if (keep_ref) | ||||
VOP_UNLOCK(vp, 0); | VOP_UNLOCK(vp, 0); | ||||
else | else | ||||
vput(vp); | vput(vp); | ||||
▲ Show 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | if (vp->v_type == VDIR) { | ||||
error = EISDIR; | error = EISDIR; | ||||
goto out; | goto out; | ||||
} | } | ||||
#ifdef MAC | #ifdef MAC | ||||
error = mac_vnode_check_write(active_cred, fp->f_cred, vp); | error = mac_vnode_check_write(active_cred, fp->f_cred, vp); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
#endif | #endif | ||||
error = vn_writechk(vp); | error = VOP_ADD_WRITECOUNT(vp, 1); | ||||
if (error == 0) { | if (error == 0) { | ||||
VATTR_NULL(&vattr); | VATTR_NULL(&vattr); | ||||
vattr.va_size = length; | vattr.va_size = length; | ||||
if ((fp->f_flag & O_FSYNC) != 0) | if ((fp->f_flag & O_FSYNC) != 0) | ||||
vattr.va_vaflags |= VA_SYNC; | vattr.va_vaflags |= VA_SYNC; | ||||
error = VOP_SETATTR(vp, &vattr, fp->f_cred); | error = VOP_SETATTR(vp, &vattr, fp->f_cred); | ||||
VOP_ADD_WRITECOUNT_SUCCEED(vp, -1); | |||||
} | } | ||||
out: | out: | ||||
VOP_UNLOCK(vp, 0); | VOP_UNLOCK(vp, 0); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
out1: | out1: | ||||
vn_rangelock_unlock(vp, rl_cookie); | vn_rangelock_unlock(vp, rl_cookie); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,255 Lines • Show Last 20 Lines |
This is a dead store.