aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-01-17 01:41:58 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2011-01-17 01:41:58 -0500
commit15f9a3f3e199647fe0cac19302c5033cf031372d (patch)
tree38a39510439f2913dbdfcfd2de4ffacc8214875d /fs
parent19a167af7c97248ec646552ebc9140bc6aa3552a (diff)
don't drop newmnt on error in do_add_mount()
That gets rid of the kludge in finish_automount() - we need to keep refcount on the vfsmount as-is until we evict it from expiry list. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index bec51e4e0549..31aefc8e5fa6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1880,6 +1880,7 @@ static int do_new_mount(struct path *path, char *type, int flags,
1880 int mnt_flags, char *name, void *data) 1880 int mnt_flags, char *name, void *data)
1881{ 1881{
1882 struct vfsmount *mnt; 1882 struct vfsmount *mnt;
1883 int err;
1883 1884
1884 if (!type) 1885 if (!type)
1885 return -EINVAL; 1886 return -EINVAL;
@@ -1892,7 +1893,10 @@ static int do_new_mount(struct path *path, char *type, int flags,
1892 if (IS_ERR(mnt)) 1893 if (IS_ERR(mnt))
1893 return PTR_ERR(mnt); 1894 return PTR_ERR(mnt);
1894 1895
1895 return do_add_mount(mnt, path, mnt_flags); 1896 err = do_add_mount(mnt, path, mnt_flags);
1897 if (err)
1898 mntput(mnt);
1899 return err;
1896} 1900}
1897 1901
1898int finish_automount(struct vfsmount *m, struct path *path) 1902int finish_automount(struct vfsmount *m, struct path *path)
@@ -1911,26 +1915,17 @@ int finish_automount(struct vfsmount *m, struct path *path)
1911 return -ELOOP; 1915 return -ELOOP;
1912 } 1916 }
1913 1917
1914 /* We need to add the mountpoint to the parent. The filesystem may
1915 * have placed it on an expiry list, and so we need to make sure it
1916 * won't be expired under us if do_add_mount() fails (do_add_mount()
1917 * will eat a reference unconditionally).
1918 */
1919 mntget(m);
1920 err = do_add_mount(m, path, path->mnt->mnt_flags | MNT_SHRINKABLE); 1918 err = do_add_mount(m, path, path->mnt->mnt_flags | MNT_SHRINKABLE);
1921 if (err) { 1919 if (err) {
1922 mnt_clear_expiry(m); 1920 mnt_clear_expiry(m);
1923 mntput(m); 1921 mntput(m);
1924 mntput(m); 1922 mntput(m);
1925 } else {
1926 mntput(m);
1927 } 1923 }
1928 return err; 1924 return err;
1929} 1925}
1930 1926
1931/* 1927/*
1932 * add a mount into a namespace's mount tree 1928 * add a mount into a namespace's mount tree
1933 * - this unconditionally eats one of the caller's references to newmnt.
1934 */ 1929 */
1935int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags) 1930int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1936{ 1931{
@@ -1967,7 +1962,6 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1967 1962
1968unlock: 1963unlock:
1969 up_write(&namespace_sem); 1964 up_write(&namespace_sem);
1970 mntput(newmnt);
1971 return err; 1965 return err;
1972} 1966}
1973 1967