aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-09-28 13:02:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-09-28 13:02:53 -0400
commit7596824e6626c62557b9eb6411ee74fec68b8ff9 (patch)
tree4a906422538887be858b9cbdf848d68f8db6c116 /fs
parent97956605d8f2a0d17706cbd338a6cfe8de1920e9 (diff)
parentc5aa1e554a20fb3542c62688ae46049c9225a965 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "A couple of fixes; one for automount/lazy umount race, another a classic "we don't protect the refcount transition to zero with the lock that protects looking for object in hash" kind of crap in lockd." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: close the race in nlmsvc_free_block() do_add_mount()/umount -l races
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/svclock.c3
-rw-r--r--fs/namespace.c10
2 files changed, 9 insertions, 4 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index fb1a2bedbe9..8d80c990dff 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -289,7 +289,6 @@ static void nlmsvc_free_block(struct kref *kref)
289 dprintk("lockd: freeing block %p...\n", block); 289 dprintk("lockd: freeing block %p...\n", block);
290 290
291 /* Remove block from file's list of blocks */ 291 /* Remove block from file's list of blocks */
292 mutex_lock(&file->f_mutex);
293 list_del_init(&block->b_flist); 292 list_del_init(&block->b_flist);
294 mutex_unlock(&file->f_mutex); 293 mutex_unlock(&file->f_mutex);
295 294
@@ -303,7 +302,7 @@ static void nlmsvc_free_block(struct kref *kref)
303static void nlmsvc_release_block(struct nlm_block *block) 302static void nlmsvc_release_block(struct nlm_block *block)
304{ 303{
305 if (block != NULL) 304 if (block != NULL)
306 kref_put(&block->b_count, nlmsvc_free_block); 305 kref_put_mutex(&block->b_count, nlmsvc_free_block, &block->b_file->f_mutex);
307} 306}
308 307
309/* 308/*
diff --git a/fs/namespace.c b/fs/namespace.c
index 4d31f73e256..7bdf7907413 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1886,8 +1886,14 @@ static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags)
1886 return err; 1886 return err;
1887 1887
1888 err = -EINVAL; 1888 err = -EINVAL;
1889 if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(real_mount(path->mnt))) 1889 if (unlikely(!check_mnt(real_mount(path->mnt)))) {
1890 goto unlock; 1890 /* that's acceptable only for automounts done in private ns */
1891 if (!(mnt_flags & MNT_SHRINKABLE))
1892 goto unlock;
1893 /* ... and for those we'd better have mountpoint still alive */
1894 if (!real_mount(path->mnt)->mnt_ns)
1895 goto unlock;
1896 }
1891 1897
1892 /* Refuse the same filesystem on the same mount point */ 1898 /* Refuse the same filesystem on the same mount point */
1893 err = -EBUSY; 1899 err = -EBUSY;