diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 46 |
1 files changed, 18 insertions, 28 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 31aefc8e5fa6..7b0b95371696 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1872,6 +1872,8 @@ out: | |||
1872 | return err; | 1872 | return err; |
1873 | } | 1873 | } |
1874 | 1874 | ||
1875 | static int do_add_mount(struct vfsmount *, struct path *, int); | ||
1876 | |||
1875 | /* | 1877 | /* |
1876 | * create a new mount for userspace and request it to be added into the | 1878 | * create a new mount for userspace and request it to be added into the |
1877 | * namespace's tree | 1879 | * namespace's tree |
@@ -1909,25 +1911,31 @@ int finish_automount(struct vfsmount *m, struct path *path) | |||
1909 | 1911 | ||
1910 | if (m->mnt_sb == path->mnt->mnt_sb && | 1912 | if (m->mnt_sb == path->mnt->mnt_sb && |
1911 | m->mnt_root == path->dentry) { | 1913 | m->mnt_root == path->dentry) { |
1912 | mnt_clear_expiry(m); | 1914 | err = -ELOOP; |
1913 | mntput(m); | 1915 | goto fail; |
1914 | mntput(m); | ||
1915 | return -ELOOP; | ||
1916 | } | 1916 | } |
1917 | 1917 | ||
1918 | 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); |
1919 | if (err) { | 1919 | if (!err) |
1920 | mnt_clear_expiry(m); | 1920 | return 0; |
1921 | mntput(m); | 1921 | fail: |
1922 | mntput(m); | 1922 | /* remove m from any expiration list it may be on */ |
1923 | if (!list_empty(&m->mnt_expire)) { | ||
1924 | down_write(&namespace_sem); | ||
1925 | br_write_lock(vfsmount_lock); | ||
1926 | list_del_init(&m->mnt_expire); | ||
1927 | br_write_unlock(vfsmount_lock); | ||
1928 | up_write(&namespace_sem); | ||
1923 | } | 1929 | } |
1930 | mntput(m); | ||
1931 | mntput(m); | ||
1924 | return err; | 1932 | return err; |
1925 | } | 1933 | } |
1926 | 1934 | ||
1927 | /* | 1935 | /* |
1928 | * add a mount into a namespace's mount tree | 1936 | * add a mount into a namespace's mount tree |
1929 | */ | 1937 | */ |
1930 | int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags) | 1938 | static int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags) |
1931 | { | 1939 | { |
1932 | int err; | 1940 | int err; |
1933 | 1941 | ||
@@ -1954,11 +1962,7 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags) | |||
1954 | goto unlock; | 1962 | goto unlock; |
1955 | 1963 | ||
1956 | newmnt->mnt_flags = mnt_flags; | 1964 | newmnt->mnt_flags = mnt_flags; |
1957 | if ((err = graft_tree(newmnt, path))) | 1965 | err = graft_tree(newmnt, path); |
1958 | goto unlock; | ||
1959 | |||
1960 | up_write(&namespace_sem); | ||
1961 | return 0; | ||
1962 | 1966 | ||
1963 | unlock: | 1967 | unlock: |
1964 | up_write(&namespace_sem); | 1968 | up_write(&namespace_sem); |
@@ -1983,20 +1987,6 @@ void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list) | |||
1983 | EXPORT_SYMBOL(mnt_set_expiry); | 1987 | EXPORT_SYMBOL(mnt_set_expiry); |
1984 | 1988 | ||
1985 | /* | 1989 | /* |
1986 | * Remove a vfsmount from any expiration list it may be on | ||
1987 | */ | ||
1988 | void mnt_clear_expiry(struct vfsmount *mnt) | ||
1989 | { | ||
1990 | if (!list_empty(&mnt->mnt_expire)) { | ||
1991 | down_write(&namespace_sem); | ||
1992 | br_write_lock(vfsmount_lock); | ||
1993 | list_del_init(&mnt->mnt_expire); | ||
1994 | br_write_unlock(vfsmount_lock); | ||
1995 | up_write(&namespace_sem); | ||
1996 | } | ||
1997 | } | ||
1998 | |||
1999 | /* | ||
2000 | * process a list of expirable mountpoints with the intent of discarding any | 1990 | * process a list of expirable mountpoints with the intent of discarding any |
2001 | * mountpoints that aren't in use and haven't been touched since last we came | 1991 | * mountpoints that aren't in use and haven't been touched since last we came |
2002 | * here | 1992 | * here |