Author: kib
Date: Sun Sep  9 19:11:52 2012
New Revision: 240283
URL: http://svn.freebsd.org/changeset/base/240283

Log:
  Add MNTK_LOOKUP_EXCL_DOTDOT struct mount flag, which specifies to the
  lookup code that dotdot lookups shall override any shared lock
  requests with the exclusive one. The flag is useful for filesystems
  which sometimes need to upgrade shared lock to exclusive inside the
  VOP_LOOKUP or later, which cannot be done safely for dotdot, due to
  dvp also locked and causing LOR.
  
  In collaboration with:            pho
  MFC after:    3 weeks

Modified:
  head/sys/kern/vfs_lookup.c
  head/sys/sys/mount.h

Modified: head/sys/kern/vfs_lookup.c
==============================================================================
--- head/sys/kern/vfs_lookup.c  Sun Sep  9 17:23:57 2012        (r240282)
+++ head/sys/kern/vfs_lookup.c  Sun Sep  9 19:11:52 2012        (r240283)
@@ -406,11 +406,13 @@ namei(struct nameidata *ndp)
 }
 
 static int
-compute_cn_lkflags(struct mount *mp, int lkflags)
+compute_cn_lkflags(struct mount *mp, int lkflags, int cnflags)
 {
 
-       if (mp == NULL || 
-           ((lkflags & LK_SHARED) && !(mp->mnt_kern_flag & 
MNTK_LOOKUP_SHARED))) {
+       if (mp == NULL || ((lkflags & LK_SHARED) &&
+           (!(mp->mnt_kern_flag & MNTK_LOOKUP_SHARED) ||
+           ((cnflags & ISDOTDOT) &&
+           (mp->mnt_kern_flag & MNTK_LOOKUP_EXCL_DOTDOT))))) {
                lkflags &= ~LK_SHARED;
                lkflags |= LK_EXCLUSIVE;
        }
@@ -539,7 +541,8 @@ lookup(struct nameidata *ndp)
        dp = ndp->ni_startdir;
        ndp->ni_startdir = NULLVP;
        vn_lock(dp,
-           compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags | LK_RETRY));
+           compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags | LK_RETRY,
+           cnp->cn_flags));
 
 dirloop:
        /*
@@ -700,7 +703,7 @@ dirloop:
                        VFS_UNLOCK_GIANT(tvfslocked);
                        vn_lock(dp,
                            compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
-                           LK_RETRY));
+                           LK_RETRY, ISDOTDOT));
                }
        }
 
@@ -738,7 +741,8 @@ unionlookup:
        vprint("lookup in", dp);
 #endif
        lkflags_save = cnp->cn_lkflags;
-       cnp->cn_lkflags = compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags);
+       cnp->cn_lkflags = compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags,
+           cnp->cn_flags);
        if ((error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) != 0) {
                cnp->cn_lkflags = lkflags_save;
                KASSERT(ndp->ni_vp == NULL, ("leaf should be empty"));
@@ -757,7 +761,7 @@ unionlookup:
                        VFS_UNLOCK_GIANT(tvfslocked);
                        vn_lock(dp,
                            compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags |
-                           LK_RETRY));
+                           LK_RETRY, cnp->cn_flags));
                        goto unionlookup;
                }
 
@@ -829,8 +833,8 @@ unionlookup:
                dvfslocked = 0;
                vref(vp_crossmp);
                ndp->ni_dvp = vp_crossmp;
-               error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags),
-                   &tdp);
+               error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags,
+                   cnp->cn_flags), &tdp);
                vfs_unbusy(mp);
                if (vn_lock(vp_crossmp, LK_SHARED | LK_NOWAIT))
                        panic("vp_crossmp exclusively locked or reclaimed");

Modified: head/sys/sys/mount.h
==============================================================================
--- head/sys/sys/mount.h        Sun Sep  9 17:23:57 2012        (r240282)
+++ head/sys/sys/mount.h        Sun Sep  9 19:11:52 2012        (r240283)
@@ -373,6 +373,7 @@ void          __mnt_vnode_markerfree(str
 #define        MNTK_NO_IOPF    0x00000100      /* Disallow page faults during 
reads
                                           and writes. Filesystem shall properly
                                           handle i/o state on EFAULT. */
+#define        MNTK_LOOKUP_EXCL_DOTDOT 0x00000800
 #define MNTK_NOASYNC   0x00800000      /* disable async */
 #define MNTK_UNMOUNT   0x01000000      /* unmount in progress */
 #define        MNTK_MWAIT      0x02000000      /* waiting for unmount to 
finish */
_______________________________________________
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