Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_vnops.c
Show First 20 Lines • Show All 445 Lines • ▼ Show 20 Lines | if (error == 0) { | ||||
CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", | CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", | ||||
__func__, vp, vp->v_writecount); | __func__, vp, vp->v_writecount); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Error from advlock or VOP_ADD_WRITECOUNT() still requires | * Error from advlock or VOP_ADD_WRITECOUNT() still requires | ||||
* calling VOP_CLOSE() to pair with earlier VOP_OPEN(). | * calling VOP_CLOSE() to pair with earlier VOP_OPEN(). | ||||
* Arrange for that by having fdrop() to use vn_closefile(). | |||||
*/ | */ | ||||
if (error != 0) { | if (error != 0) { | ||||
if (fp != NULL) { | |||||
/* | |||||
* Arrange the call by having fdrop() to use | |||||
* vn_closefile(). This is to satisfy | |||||
* filesystems like devfs or tmpfs, which | |||||
* override fo_close(). | |||||
*/ | |||||
fp->f_flag |= FOPENFAILED; | 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 there is no fp, due to kernel-mode open, | |||||
* we can call VOP_CLOSE() now. | |||||
*/ | |||||
if (vp->v_type != VFIFO && (fmode & FWRITE) != 0 && | |||||
!MNT_EXTENDED_SHARED(vp->v_mount) && | |||||
VOP_ISLOCKED(vp) != LK_EXCLUSIVE) | |||||
vn_lock(vp, LK_UPGRADE | LK_RETRY); | |||||
(void)VOP_CLOSE(vp, fmode & (FREAD | FWRITE | FEXEC), | |||||
cred, td); | |||||
} | |||||
} | } | ||||
ASSERT_VOP_LOCKED(vp, "vn_open_vnode"); | ASSERT_VOP_LOCKED(vp, "vn_open_vnode"); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 3,001 Lines • Show Last 20 Lines |