Skip to content

Commit

Permalink
Fix incomplete __mntput locking
Browse files Browse the repository at this point in the history
Getting this wrong caused

	WARNING: at fs/namespace.c:636 mntput_no_expire+0xac/0xf2()

due to optimistically checking cpu_writer->mnt outside the spinlock.

Here's what we really want:
 * we know that nobody will set cpu_writer->mnt to mnt from now on
 * all changes to that sucker are done under cpu_writer->lock
 * we want the laziest equivalent of
	spin_lock(&cpu_writer->lock);
	if (likely(cpu_writer->mnt != mnt)) {
		spin_unlock(&cpu_writer->lock);
		continue;
	}
	/* do stuff */
  that would make sure we won't miss earlier setting of ->mnt done by
  another CPU.

Anyway, for now we just move the spin_lock() earlier and move the test
into the properly locked region.

Signed-off-by: Al Viro <[email protected]>
Reported-and-tested-by: Li Zefan <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Al Viro authored and torvalds committed Feb 17, 2009
1 parent d2f8d7e commit 1a88b53
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions fs/namespace.c
Original file line number Diff line number Diff line change
@@ -614,9 +614,11 @@ static inline void __mntput(struct vfsmount *mnt)
*/
for_each_possible_cpu(cpu) {
struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu);
if (cpu_writer->mnt != mnt)
continue;
spin_lock(&cpu_writer->lock);
if (cpu_writer->mnt != mnt) {
spin_unlock(&cpu_writer->lock);
continue;
}
atomic_add(cpu_writer->count, &mnt->__mnt_writers);
cpu_writer->count = 0;
/*

0 comments on commit 1a88b53

Please sign in to comment.