Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157867156
D42642.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D42642.diff
View Options
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -4042,10 +4042,10 @@
}
/*
- * Lock pair of vnodes vp1, vp2, avoiding lock order reversal.
- * vp1_locked indicates whether vp1 is locked; if not, vp1 must be
- * unlocked. Same for vp2 and vp2_locked. One of the vnodes can be
- * NULL.
+ * Lock pair of (possibly same) vnodes vp1, vp2, avoiding lock order
+ * reversal. vp1_locked indicates whether vp1 is locked; if not, vp1
+ * must be unlocked. Same for vp2 and vp2_locked. One of the vnodes
+ * can be NULL.
*
* The function returns with both vnodes exclusively or shared locked,
* according to corresponding lkflags, and guarantees that it does not
@@ -4056,12 +4056,14 @@
*
* Only one of LK_SHARED and LK_EXCLUSIVE must be specified.
* LK_NODDLKTREAT can be optionally passed.
+ *
+ * If vp1 == vp2, only one, most exclusive, lock is obtained on it.
*/
void
vn_lock_pair(struct vnode *vp1, bool vp1_locked, int lkflags1,
struct vnode *vp2, bool vp2_locked, int lkflags2)
{
- int error;
+ int error, locked1;
MPASS(((lkflags1 & LK_SHARED) != 0) ^ ((lkflags1 & LK_EXCLUSIVE) != 0));
MPASS((lkflags1 & ~(LK_SHARED | LK_EXCLUSIVE | LK_NODDLKTREAT)) == 0);
@@ -4071,6 +4073,35 @@
if (vp1 == NULL && vp2 == NULL)
return;
+ if (vp1 == vp2) {
+ MPASS(vp1_locked == vp2_locked);
+
+ /* Select the most exclusive mode for lock. */
+ if ((lkflags1 & LK_TYPE_MASK) != (lkflags2 & LK_TYPE_MASK))
+ lkflags1 = (lkflags1 & ~LK_SHARED) | LK_EXCLUSIVE;
+
+ if (vp1_locked) {
+ ASSERT_VOP_LOCKED(vp1, "vp1");
+
+ /* No need to relock if any lock is exclusive. */
+ if ((vp1->v_vnlock->lock_object.lo_flags &
+ LK_NOSHARE) != 0)
+ return;
+
+ locked1 = VOP_ISLOCKED(vp1);
+ if (((lkflags1 & LK_SHARED) != 0 &&
+ locked1 != LK_EXCLUSIVE) ||
+ ((lkflags1 & LK_EXCLUSIVE) != 0 &&
+ locked1 == LK_EXCLUSIVE))
+ return;
+ VOP_UNLOCK(vp1);
+ }
+
+ ASSERT_VOP_UNLOCKED(vp1, "vp1");
+ vn_lock(vp1, lkflags1 | LK_RETRY);
+ return;
+ }
+
if (vp1 != NULL) {
if ((lkflags1 & LK_SHARED) != 0 &&
(vp1->v_vnlock->lock_object.lo_flags & LK_NOSHARE) != 0)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 26, 11:50 PM (2 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33541330
Default Alt Text
D42642.diff (2 KB)
Attached To
Mode
D42642: vn_lock_pair(): reasonably handle vp1 == vp2 case
Attached
Detach File
Event Timeline
Log In to Comment