blob: cd52a3062b3d95e8b43871833ee5164d6d899ccd [file] [log] [blame]
From 92b0ddb74ba34dba91878a346c3c6bf396ffb931 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Sun, 19 Jul 2009 08:44:27 -0500
Subject: [PATCH] fs: namespace preemption fix
commit ce5c9d0cfb49aadeac6fe322035c4f73bbc5ef85 in tip.
On RT we cannot loop with preemption disabled here as
mnt_make_readonly() might have been preempted. Instead we block on
vfsmount_lock which is held by mnt_make_readonly(). Works for !RT as
well.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/fs/namespace.c b/fs/namespace.c
index c768f73..962fd96 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -264,8 +264,16 @@ int mnt_want_write(struct vfsmount *mnt)
* incremented count after it has set MNT_WRITE_HOLD.
*/
smp_mb();
- while (mnt->mnt_flags & MNT_WRITE_HOLD)
- cpu_relax();
+ preempt_enable();
+ /*
+ * HACK ALERT. on RT we can not spin here with cpu_relax() and
+ * preemption disabled so we block on the vfsmount lock which is
+ * held by mnt_make_readonly(). Works on !RT as well.
+ */
+ while (mnt->mnt_flags & MNT_WRITE_HOLD) {
+ spin_lock(&vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
+ }
/*
* After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will
* be set to match its requirements. So we must not load that until
@@ -273,12 +281,11 @@ int mnt_want_write(struct vfsmount *mnt)
*/
smp_rmb();
if (__mnt_is_readonly(mnt)) {
+ preempt_disable();
dec_mnt_writers(mnt);
+ preempt_enable();
ret = -EROFS;
- goto out;
}
-out:
- preempt_enable();
return ret;
}
EXPORT_SYMBOL_GPL(mnt_want_write);
--
1.7.1.1