+ if ((fmode & FCREAT) == 0) {
+ if (fmode & FREAD) {
+ if (error = VOP_ACCESS(vp, VREAD, cred, p))
+ goto bad;
+ }
+ if (fmode & (FWRITE|FTRUNC)) {
+ if (vp->v_type == VDIR) {
+ error = EISDIR;
+ goto bad;
+ }
+ if ((error = vn_writechk(vp)) ||
+ (error = VOP_ACCESS(vp, VWRITE, cred, p)))
+ goto bad;
+ }
+ }
+ if (fmode & FTRUNC) {
+ VATTR_NULL(vap);
+ vap->va_size = 0;
+ if (error = VOP_SETATTR(vp, vap, cred, p))
+ goto bad;
+ }
+ VOP_UNLOCK(vp);
+ error = VOP_OPEN(vp, fmode, cred, p);
+ if (error)
+ vrele(vp);
+ return (error);
+
+bad:
+ vput(vp);
+ return (error);