From owner-svn-src-head@freebsd.org Sun Jan 17 08:40:53 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EE45FA6AF1B; Sun, 17 Jan 2016 08:40:52 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CB9F71BC5; Sun, 17 Jan 2016 08:40:52 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0H8epOc015238; Sun, 17 Jan 2016 08:40:51 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0H8epU9015236; Sun, 17 Jan 2016 08:40:51 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201601170840.u0H8epU9015236@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Sun, 17 Jan 2016 08:40:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r294205 - in head/sys: kern sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Jan 2016 08:40:53 -0000 Author: kib Date: Sun Jan 17 08:40:51 2016 New Revision: 294205 URL: https://svnweb.freebsd.org/changeset/base/294205 Log: When cleaning up from failed adv locking and checking for write, do not call VOP_CLOSE() manually. Instead, delegate the close to fo_close() performed as part of the fdrop() on the file failed to open. For this, finish constructing file on error, in particular, set f_vnode and f_ops. Forcibly resetting f_ops to badfileops disabled additional cleanups performed by fo_close() for some file types, in this case it was noted that cdevpriv data was corrupted. Since fo_close() call must be enabled for some file types, it makes more sense to enable it for all files opened through vn_open_cred(). In collaboration with: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Modified: head/sys/kern/vfs_vnops.c head/sys/sys/fcntl.h Modified: head/sys/kern/vfs_vnops.c ============================================================================== --- head/sys/kern/vfs_vnops.c Sun Jan 17 08:34:35 2016 (r294204) +++ head/sys/kern/vfs_vnops.c Sun Jan 17 08:40:51 2016 (r294205) @@ -299,10 +299,9 @@ int vn_open_vnode(struct vnode *vp, int fmode, struct ucred *cred, struct thread *td, struct file *fp) { - struct mount *mp; accmode_t accmode; struct flock lf; - int error, have_flock, lock_flags, type; + int error, lock_flags, type; if (vp->v_type == VLNK) return (EMLINK); @@ -365,10 +364,12 @@ vn_open_vnode(struct vnode *vp, int fmod if ((fmode & FNONBLOCK) == 0) type |= F_WAIT; error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type); - have_flock = (error == 0); + if (error == 0) + fp->f_flag |= FHASLOCK; vn_lock(vp, lock_flags | LK_RETRY); if (error == 0 && vp->v_iflag & VI_DOOMED) error = ENOENT; + /* * Another thread might have used this vnode as an * executable while the vnode lock was dropped. @@ -377,34 +378,24 @@ vn_open_vnode(struct vnode *vp, int fmod */ if (error == 0 && accmode & VWRITE) error = vn_writechk(vp); - if (error) { - VOP_UNLOCK(vp, 0); - if (have_flock) { - lf.l_whence = SEEK_SET; - lf.l_start = 0; - lf.l_len = 0; - lf.l_type = F_UNLCK; - (void) VOP_ADVLOCK(vp, fp, F_UNLCK, &lf, - F_FLOCK); + + if (error != 0) { + fp->f_flag |= FOPENFAILED; + fp->f_vnode = vp; + if (fp->f_ops == &badfileops) { + fp->f_type = DTYPE_VNODE; + fp->f_ops = &vnops; } - vn_start_write(vp, &mp, V_WAIT); - vn_lock(vp, lock_flags | LK_RETRY); - (void)VOP_CLOSE(vp, fmode, cred, td); - vn_finished_write(mp); - /* Prevent second close from fdrop()->vn_close(). */ - if (fp != NULL) - fp->f_ops= &badfileops; - return (error); + vref(vp); } - fp->f_flag |= FHASLOCK; } - if (fmode & FWRITE) { + if (error == 0 && fmode & FWRITE) { 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"); - return (0); + return (error); } /* @@ -449,7 +440,7 @@ vn_close(vp, flags, file_cred, td) vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, lock_flags | LK_RETRY); - if (flags & FWRITE) { + if ((flags & (FWRITE | FOPENFAILED)) == FWRITE) { VNASSERT(vp->v_writecount > 0, vp, ("vn_close: negative writecount")); VOP_ADD_WRITECOUNT(vp, -1); Modified: head/sys/sys/fcntl.h ============================================================================== --- head/sys/sys/fcntl.h Sun Jan 17 08:34:35 2016 (r294204) +++ head/sys/sys/fcntl.h Sun Jan 17 08:40:51 2016 (r294205) @@ -142,6 +142,8 @@ typedef __pid_t pid_t; /* Only for devfs d_close() flags. */ #define FLASTCLOSE O_DIRECTORY #define FREVOKE O_VERIFY +/* Only for fo_close() from half-succeeded open */ +#define FOPENFAILED O_TTY_INIT /* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */ #define FFLAGS(oflags) ((oflags) & O_EXEC ? (oflags) : (oflags) + 1)