From owner-svn-src-head@FreeBSD.ORG Sat Nov 9 20:30:15 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 0A6C67A8; Sat, 9 Nov 2013 20:30:15 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id DC0CB2184; Sat, 9 Nov 2013 20:30:14 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rA9KUEJN027206; Sat, 9 Nov 2013 20:30:14 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rA9KUEtl027202; Sat, 9 Nov 2013 20:30:14 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201311092030.rA9KUEtl027202@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 9 Nov 2013 20:30:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r257898 - 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.14 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: Sat, 09 Nov 2013 20:30:15 -0000 Author: kib Date: Sat Nov 9 20:30:13 2013 New Revision: 257898 URL: http://svnweb.freebsd.org/changeset/base/257898 Log: Both vn_close() and VFS_PROLOGUE() evaluate vp->v_mount twice, without holding the vnode lock; vp->v_mount is checked first for NULL equiality, and then dereferenced if not NULL. If vnode is reclaimed meantime, second dereference would still give NULL. Change VFS_PROLOGUE() to evaluate the mp once, convert MNTK_SHARED_WRITES and MNTK_EXTENDED_SHARED tests into inline functions. Reviewed by: alc Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Modified: head/sys/kern/vfs_lookup.c head/sys/kern/vfs_vnops.c head/sys/sys/mount.h Modified: head/sys/kern/vfs_lookup.c ============================================================================== --- head/sys/kern/vfs_lookup.c Sat Nov 9 20:11:21 2013 (r257897) +++ head/sys/kern/vfs_lookup.c Sat Nov 9 20:30:13 2013 (r257898) @@ -424,13 +424,8 @@ needs_exclusive_leaf(struct mount *mp, i * extended shared operations, then use a shared lock for the * leaf node, otherwise use an exclusive lock. */ - if (flags & ISOPEN) { - if (mp != NULL && - (mp->mnt_kern_flag & MNTK_EXTENDED_SHARED)) - return (0); - else - return (1); - } + if ((flags & ISOPEN) != 0) + return (!MNT_EXTENDED_SHARED(mp)); /* * Lookup requests outside of open() that specify LOCKSHARED Modified: head/sys/kern/vfs_vnops.c ============================================================================== --- head/sys/kern/vfs_vnops.c Sat Nov 9 20:11:21 2013 (r257897) +++ head/sys/kern/vfs_vnops.c Sat Nov 9 20:30:13 2013 (r257898) @@ -360,8 +360,8 @@ vn_close(vp, flags, file_cred, td) struct mount *mp; int error, lock_flags; - if (vp->v_type != VFIFO && !(flags & FWRITE) && vp->v_mount != NULL && - vp->v_mount->mnt_kern_flag & MNTK_EXTENDED_SHARED) + if (vp->v_type != VFIFO && (flags & FWRITE) == 0 && + MNT_EXTENDED_SHARED(vp->v_mount)) lock_flags = LK_SHARED; else lock_flags = LK_EXCLUSIVE; Modified: head/sys/sys/mount.h ============================================================================== --- head/sys/sys/mount.h Sat Nov 9 20:11:21 2013 (r257897) +++ head/sys/sys/mount.h Sat Nov 9 20:30:13 2013 (r257898) @@ -362,8 +362,19 @@ void __mnt_vnode_markerfree_act #define MNTK_LOOKUP_SHARED 0x40000000 /* FS supports shared lock lookups */ #define MNTK_NOKNOTE 0x80000000 /* Don't send KNOTEs from VOP hooks */ -#define MNT_SHARED_WRITES(mp) (((mp) != NULL) && \ - ((mp)->mnt_kern_flag & MNTK_SHARED_WRITES)) +static inline int +MNT_SHARED_WRITES(struct mount *mp) +{ + + return (mp != NULL && (mp->mnt_kern_flag & MNTK_SHARED_WRITES) != 0); +} + +static inline int +MNT_EXTENDED_SHARED(struct mount *mp) +{ + + return (mp != NULL && (mp->mnt_kern_flag & MNTK_EXTENDED_SHARED) != 0); +} /* * Sysctl CTL_VFS definitions. @@ -636,10 +647,12 @@ struct vfsops { vfs_statfs_t __vfs_statfs; #define VFS_PROLOGUE(MP) do { \ + struct mount *mp__; \ int _enable_stops; \ \ - _enable_stops = ((MP) != NULL && \ - ((MP)->mnt_vfc->vfc_flags & VFCF_SBDRY) && sigdeferstop()) + mp__ = (MP); \ + _enable_stops = (mp__ != NULL && \ + (mp__->mnt_vfc->vfc_flags & VFCF_SBDRY) && sigdeferstop()) #define VFS_EPILOGUE(MP) \ if (_enable_stops) \