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)                                              \
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to