svn commit: r240283 - in head/sys: kern sys
Konstantin Belousov
kib at FreeBSD.org
Sun Sep 9 19:11:53 UTC 2012
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 */
More information about the svn-src-head
mailing list