--- kernel/bsd/vfs/vfs_vnops.c 2018/04/24 18:26:06 1.1 +++ kernel/bsd/vfs/vfs_vnops.c 2018/04/24 18:31:25 1.1.1.2 @@ -148,11 +148,21 @@ vn_open(ndp, fmode, cmode) goto bad; } if ((fmode & O_CREAT) == 0) { - if (fmode & FREAD) { - if (error = VOP_ACCESS(vp, VREAD, cred, p)) + if (fmode & FREAD && fmode & (FWRITE | O_TRUNC)) { + int err = 0; + if (vp->v_type == VDIR) + err = EISDIR; + else + err = vn_writechk(vp); + if (err && !(error = VOP_ACCESS(vp, VREAD, cred, p))) + error = err; + if (error || (error = VOP_ACCESS(vp, VREAD|VWRITE, + cred, p))) goto bad; - } - if (fmode & (FWRITE | O_TRUNC)) { + } else if (fmode & FREAD) { + if ((error = VOP_ACCESS(vp, VREAD, cred, p))) + goto bad; + } else if (fmode & (FWRITE | O_TRUNC)) { if (vp->v_type == VDIR) { error = EISDIR; goto bad; @@ -191,7 +201,8 @@ vn_open(ndp, fmode, cmode) #endif /* MACH_NBC */ if (fmode & FWRITE) - vp->v_writecount++; + if (++vp->v_writecount <= 0) + panic("vn_open: v_writecount"); return (0); bad: vput(vp);