aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:51:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:51:11 -0400
commitf539abece1b7e36fae6add4f9ea29203d40badcb (patch)
tree786c08f3131a1871ece13343c3fa3832930c1408 /fs
parent3f6f7e6d57b8a0ae2810ae7aac70c51b6f2a6304 (diff)
parent24ff6663ccfdaf088dfa7acae489cb11ed4f43c4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: fs: call security_d_instantiate in d_obtain_alias V2 lose 'mounting_here' argument in ->d_manage() don't pass 'mounting_here' flag to follow_down() change the locking order for namespace_sem fix deadlock in pivot_root() vfs: split off vfsmount-related parts of vfs_kern_mount() Some fixes for pstore kill simple_set_mnt()
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs4/root.c6
-rw-r--r--fs/dcache.c3
-rw-r--r--fs/internal.h5
-rw-r--r--fs/namei.c9
-rw-r--r--fs/namespace.c292
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/pstore/inode.c116
-rw-r--r--fs/super.c96
8 files changed, 268 insertions, 261 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 014e7aba3b0..e6f84d26f4c 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -36,7 +36,7 @@ static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
36static int autofs4_dir_open(struct inode *inode, struct file *file); 36static int autofs4_dir_open(struct inode *inode, struct file *file);
37static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); 37static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
38static struct vfsmount *autofs4_d_automount(struct path *); 38static struct vfsmount *autofs4_d_automount(struct path *);
39static int autofs4_d_manage(struct dentry *, bool, bool); 39static int autofs4_d_manage(struct dentry *, bool);
40static void autofs4_dentry_release(struct dentry *); 40static void autofs4_dentry_release(struct dentry *);
41 41
42const struct file_operations autofs4_root_operations = { 42const struct file_operations autofs4_root_operations = {
@@ -446,7 +446,7 @@ done:
446 return NULL; 446 return NULL;
447} 447}
448 448
449int autofs4_d_manage(struct dentry *dentry, bool mounting_here, bool rcu_walk) 449int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
450{ 450{
451 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 451 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
452 452
@@ -454,7 +454,7 @@ int autofs4_d_manage(struct dentry *dentry, bool mounting_here, bool rcu_walk)
454 dentry, dentry->d_name.len, dentry->d_name.name); 454 dentry, dentry->d_name.len, dentry->d_name.name);
455 455
456 /* The daemon never waits. */ 456 /* The daemon never waits. */
457 if (autofs4_oz_mode(sbi) || mounting_here) { 457 if (autofs4_oz_mode(sbi)) {
458 if (!d_mountpoint(dentry)) 458 if (!d_mountpoint(dentry))
459 return -EISDIR; 459 return -EISDIR;
460 return 0; 460 return 0;
diff --git a/fs/dcache.c b/fs/dcache.c
index 8b1f8425549..ad25c4cec7d 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1612,10 +1612,13 @@ struct dentry *d_obtain_alias(struct inode *inode)
1612 __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); 1612 __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first);
1613 spin_unlock(&tmp->d_lock); 1613 spin_unlock(&tmp->d_lock);
1614 spin_unlock(&inode->i_lock); 1614 spin_unlock(&inode->i_lock);
1615 security_d_instantiate(tmp, inode);
1615 1616
1616 return tmp; 1617 return tmp;
1617 1618
1618 out_iput: 1619 out_iput:
1620 if (res && !IS_ERR(res))
1621 security_d_instantiate(res, inode);
1619 iput(inode); 1622 iput(inode);
1620 return res; 1623 return res;
1621} 1624}
diff --git a/fs/internal.h b/fs/internal.h
index f3d15de44b1..17191546d52 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -12,6 +12,7 @@
12#include <linux/lglock.h> 12#include <linux/lglock.h>
13 13
14struct super_block; 14struct super_block;
15struct file_system_type;
15struct linux_binprm; 16struct linux_binprm;
16struct path; 17struct path;
17 18
@@ -61,8 +62,6 @@ extern int check_unsafe_exec(struct linux_binprm *);
61extern int copy_mount_options(const void __user *, unsigned long *); 62extern int copy_mount_options(const void __user *, unsigned long *);
62extern int copy_mount_string(const void __user *, char **); 63extern int copy_mount_string(const void __user *, char **);
63 64
64extern void free_vfsmnt(struct vfsmount *);
65extern struct vfsmount *alloc_vfsmnt(const char *);
66extern unsigned int mnt_get_count(struct vfsmount *mnt); 65extern unsigned int mnt_get_count(struct vfsmount *mnt);
67extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int); 66extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
68extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *, 67extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
@@ -99,6 +98,8 @@ extern struct file *get_empty_filp(void);
99extern int do_remount_sb(struct super_block *, int, void *, int); 98extern int do_remount_sb(struct super_block *, int, void *, int);
100extern void __put_super(struct super_block *sb); 99extern void __put_super(struct super_block *sb);
101extern void put_super(struct super_block *sb); 100extern void put_super(struct super_block *sb);
101extern struct dentry *mount_fs(struct file_system_type *,
102 int, const char *, void *);
102 103
103/* 104/*
104 * open.c 105 * open.c
diff --git a/fs/namei.c b/fs/namei.c
index b912b7abe74..5a9a6c3094d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -933,8 +933,7 @@ static int follow_managed(struct path *path, unsigned flags)
933 if (managed & DCACHE_MANAGE_TRANSIT) { 933 if (managed & DCACHE_MANAGE_TRANSIT) {
934 BUG_ON(!path->dentry->d_op); 934 BUG_ON(!path->dentry->d_op);
935 BUG_ON(!path->dentry->d_op->d_manage); 935 BUG_ON(!path->dentry->d_op->d_manage);
936 ret = path->dentry->d_op->d_manage(path->dentry, 936 ret = path->dentry->d_op->d_manage(path->dentry, false);
937 false, false);
938 if (ret < 0) 937 if (ret < 0)
939 return ret == -EISDIR ? 0 : ret; 938 return ret == -EISDIR ? 0 : ret;
940 } 939 }
@@ -999,7 +998,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
999 struct vfsmount *mounted; 998 struct vfsmount *mounted;
1000 if (unlikely(path->dentry->d_flags & DCACHE_MANAGE_TRANSIT) && 999 if (unlikely(path->dentry->d_flags & DCACHE_MANAGE_TRANSIT) &&
1001 !reverse_transit && 1000 !reverse_transit &&
1002 path->dentry->d_op->d_manage(path->dentry, false, true) < 0) 1001 path->dentry->d_op->d_manage(path->dentry, true) < 0)
1003 return false; 1002 return false;
1004 mounted = __lookup_mnt(path->mnt, path->dentry, 1); 1003 mounted = __lookup_mnt(path->mnt, path->dentry, 1);
1005 if (!mounted) 1004 if (!mounted)
@@ -1065,7 +1064,7 @@ failed:
1065 * Care must be taken as namespace_sem may be held (indicated by mounting_here 1064 * Care must be taken as namespace_sem may be held (indicated by mounting_here
1066 * being true). 1065 * being true).
1067 */ 1066 */
1068int follow_down(struct path *path, bool mounting_here) 1067int follow_down(struct path *path)
1069{ 1068{
1070 unsigned managed; 1069 unsigned managed;
1071 int ret; 1070 int ret;
@@ -1086,7 +1085,7 @@ int follow_down(struct path *path, bool mounting_here)
1086 BUG_ON(!path->dentry->d_op); 1085 BUG_ON(!path->dentry->d_op);
1087 BUG_ON(!path->dentry->d_op->d_manage); 1086 BUG_ON(!path->dentry->d_op->d_manage);
1088 ret = path->dentry->d_op->d_manage( 1087 ret = path->dentry->d_op->d_manage(
1089 path->dentry, mounting_here, false); 1088 path->dentry, false);
1090 if (ret < 0) 1089 if (ret < 0)
1091 return ret == -EISDIR ? 0 : ret; 1090 return ret == -EISDIR ? 0 : ret;
1092 } 1091 }
diff --git a/fs/namespace.c b/fs/namespace.c
index d7513485c1f..9263995bf6a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -196,7 +196,7 @@ unsigned int mnt_get_count(struct vfsmount *mnt)
196#endif 196#endif
197} 197}
198 198
199struct vfsmount *alloc_vfsmnt(const char *name) 199static struct vfsmount *alloc_vfsmnt(const char *name)
200{ 200{
201 struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); 201 struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
202 if (mnt) { 202 if (mnt) {
@@ -466,15 +466,7 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt)
466 br_write_unlock(vfsmount_lock); 466 br_write_unlock(vfsmount_lock);
467} 467}
468 468
469void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) 469static void free_vfsmnt(struct vfsmount *mnt)
470{
471 mnt->mnt_sb = sb;
472 mnt->mnt_root = dget(sb->s_root);
473}
474
475EXPORT_SYMBOL(simple_set_mnt);
476
477void free_vfsmnt(struct vfsmount *mnt)
478{ 470{
479 kfree(mnt->mnt_devname); 471 kfree(mnt->mnt_devname);
480 mnt_free_id(mnt); 472 mnt_free_id(mnt);
@@ -678,6 +670,36 @@ static struct vfsmount *skip_mnt_tree(struct vfsmount *p)
678 return p; 670 return p;
679} 671}
680 672
673struct vfsmount *
674vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
675{
676 struct vfsmount *mnt;
677 struct dentry *root;
678
679 if (!type)
680 return ERR_PTR(-ENODEV);
681
682 mnt = alloc_vfsmnt(name);
683 if (!mnt)
684 return ERR_PTR(-ENOMEM);
685
686 if (flags & MS_KERNMOUNT)
687 mnt->mnt_flags = MNT_INTERNAL;
688
689 root = mount_fs(type, flags, name, data);
690 if (IS_ERR(root)) {
691 free_vfsmnt(mnt);
692 return ERR_CAST(root);
693 }
694
695 mnt->mnt_root = root;
696 mnt->mnt_sb = root->d_sb;
697 mnt->mnt_mountpoint = mnt->mnt_root;
698 mnt->mnt_parent = mnt;
699 return mnt;
700}
701EXPORT_SYMBOL_GPL(vfs_kern_mount);
702
681static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, 703static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
682 int flag) 704 int flag)
683{ 705{
@@ -1641,9 +1663,35 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
1641 return err; 1663 return err;
1642} 1664}
1643 1665
1666static int lock_mount(struct path *path)
1667{
1668 struct vfsmount *mnt;
1669retry:
1670 mutex_lock(&path->dentry->d_inode->i_mutex);
1671 if (unlikely(cant_mount(path->dentry))) {
1672 mutex_unlock(&path->dentry->d_inode->i_mutex);
1673 return -ENOENT;
1674 }
1675 down_write(&namespace_sem);
1676 mnt = lookup_mnt(path);
1677 if (likely(!mnt))
1678 return 0;
1679 up_write(&namespace_sem);
1680 mutex_unlock(&path->dentry->d_inode->i_mutex);
1681 path_put(path);
1682 path->mnt = mnt;
1683 path->dentry = dget(mnt->mnt_root);
1684 goto retry;
1685}
1686
1687static void unlock_mount(struct path *path)
1688{
1689 up_write(&namespace_sem);
1690 mutex_unlock(&path->dentry->d_inode->i_mutex);
1691}
1692
1644static int graft_tree(struct vfsmount *mnt, struct path *path) 1693static int graft_tree(struct vfsmount *mnt, struct path *path)
1645{ 1694{
1646 int err;
1647 if (mnt->mnt_sb->s_flags & MS_NOUSER) 1695 if (mnt->mnt_sb->s_flags & MS_NOUSER)
1648 return -EINVAL; 1696 return -EINVAL;
1649 1697
@@ -1651,16 +1699,10 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
1651 S_ISDIR(mnt->mnt_root->d_inode->i_mode)) 1699 S_ISDIR(mnt->mnt_root->d_inode->i_mode))
1652 return -ENOTDIR; 1700 return -ENOTDIR;
1653 1701
1654 err = -ENOENT; 1702 if (d_unlinked(path->dentry))
1655 mutex_lock(&path->dentry->d_inode->i_mutex); 1703 return -ENOENT;
1656 if (cant_mount(path->dentry))
1657 goto out_unlock;
1658 1704
1659 if (!d_unlinked(path->dentry)) 1705 return attach_recursive_mnt(mnt, path, NULL);
1660 err = attach_recursive_mnt(mnt, path, NULL);
1661out_unlock:
1662 mutex_unlock(&path->dentry->d_inode->i_mutex);
1663 return err;
1664} 1706}
1665 1707
1666/* 1708/*
@@ -1723,6 +1765,7 @@ static int do_change_type(struct path *path, int flag)
1723static int do_loopback(struct path *path, char *old_name, 1765static int do_loopback(struct path *path, char *old_name,
1724 int recurse) 1766 int recurse)
1725{ 1767{
1768 LIST_HEAD(umount_list);
1726 struct path old_path; 1769 struct path old_path;
1727 struct vfsmount *mnt = NULL; 1770 struct vfsmount *mnt = NULL;
1728 int err = mount_is_safe(path); 1771 int err = mount_is_safe(path);
@@ -1734,13 +1777,16 @@ static int do_loopback(struct path *path, char *old_name,
1734 if (err) 1777 if (err)
1735 return err; 1778 return err;
1736 1779
1737 down_write(&namespace_sem); 1780 err = lock_mount(path);
1781 if (err)
1782 goto out;
1783
1738 err = -EINVAL; 1784 err = -EINVAL;
1739 if (IS_MNT_UNBINDABLE(old_path.mnt)) 1785 if (IS_MNT_UNBINDABLE(old_path.mnt))
1740 goto out; 1786 goto out2;
1741 1787
1742 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt)) 1788 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
1743 goto out; 1789 goto out2;
1744 1790
1745 err = -ENOMEM; 1791 err = -ENOMEM;
1746 if (recurse) 1792 if (recurse)
@@ -1749,20 +1795,18 @@ static int do_loopback(struct path *path, char *old_name,
1749 mnt = clone_mnt(old_path.mnt, old_path.dentry, 0); 1795 mnt = clone_mnt(old_path.mnt, old_path.dentry, 0);
1750 1796
1751 if (!mnt) 1797 if (!mnt)
1752 goto out; 1798 goto out2;
1753 1799
1754 err = graft_tree(mnt, path); 1800 err = graft_tree(mnt, path);
1755 if (err) { 1801 if (err) {
1756 LIST_HEAD(umount_list);
1757
1758 br_write_lock(vfsmount_lock); 1802 br_write_lock(vfsmount_lock);
1759 umount_tree(mnt, 0, &umount_list); 1803 umount_tree(mnt, 0, &umount_list);
1760 br_write_unlock(vfsmount_lock); 1804 br_write_unlock(vfsmount_lock);
1761 release_mounts(&umount_list);
1762 } 1805 }
1763 1806out2:
1807 unlock_mount(path);
1808 release_mounts(&umount_list);
1764out: 1809out:
1765 up_write(&namespace_sem);
1766 path_put(&old_path); 1810 path_put(&old_path);
1767 return err; 1811 return err;
1768} 1812}
@@ -1851,18 +1895,12 @@ static int do_move_mount(struct path *path, char *old_name)
1851 if (err) 1895 if (err)
1852 return err; 1896 return err;
1853 1897
1854 down_write(&namespace_sem); 1898 err = lock_mount(path);
1855 err = follow_down(path, true);
1856 if (err < 0) 1899 if (err < 0)
1857 goto out; 1900 goto out;
1858 1901
1859 err = -EINVAL; 1902 err = -EINVAL;
1860 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt)) 1903 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
1861 goto out;
1862
1863 err = -ENOENT;
1864 mutex_lock(&path->dentry->d_inode->i_mutex);
1865 if (cant_mount(path->dentry))
1866 goto out1; 1904 goto out1;
1867 1905
1868 if (d_unlinked(path->dentry)) 1906 if (d_unlinked(path->dentry))
@@ -1904,16 +1942,87 @@ static int do_move_mount(struct path *path, char *old_name)
1904 * automatically */ 1942 * automatically */
1905 list_del_init(&old_path.mnt->mnt_expire); 1943 list_del_init(&old_path.mnt->mnt_expire);
1906out1: 1944out1:
1907 mutex_unlock(&path->dentry->d_inode->i_mutex); 1945 unlock_mount(path);
1908out: 1946out:
1909 up_write(&namespace_sem);
1910 if (!err) 1947 if (!err)
1911 path_put(&parent_path); 1948 path_put(&parent_path);
1912 path_put(&old_path); 1949 path_put(&old_path);
1913 return err; 1950 return err;
1914} 1951}
1915 1952
1916static int do_add_mount(struct vfsmount *, struct path *, int); 1953static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
1954{
1955 int err;
1956 const char *subtype = strchr(fstype, '.');
1957 if (subtype) {
1958 subtype++;
1959 err = -EINVAL;
1960 if (!subtype[0])
1961 goto err;
1962 } else
1963 subtype = "";
1964
1965 mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
1966 err = -ENOMEM;
1967 if (!mnt->mnt_sb->s_subtype)
1968 goto err;
1969 return mnt;
1970
1971 err:
1972 mntput(mnt);
1973 return ERR_PTR(err);
1974}
1975
1976struct vfsmount *
1977do_kern_mount(const char *fstype, int flags, const char *name, void *data)
1978{
1979 struct file_system_type *type = get_fs_type(fstype);
1980 struct vfsmount *mnt;
1981 if (!type)
1982 return ERR_PTR(-ENODEV);
1983 mnt = vfs_kern_mount(type, flags, name, data);
1984 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
1985 !mnt->mnt_sb->s_subtype)
1986 mnt = fs_set_subtype(mnt, fstype);
1987 put_filesystem(type);
1988 return mnt;
1989}
1990EXPORT_SYMBOL_GPL(do_kern_mount);
1991
1992/*
1993 * add a mount into a namespace's mount tree
1994 */
1995static int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1996{
1997 int err;
1998
1999 mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);
2000
2001 err = lock_mount(path);
2002 if (err)
2003 return err;
2004
2005 err = -EINVAL;
2006 if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
2007 goto unlock;
2008
2009 /* Refuse the same filesystem on the same mount point */
2010 err = -EBUSY;
2011 if (path->mnt->mnt_sb == newmnt->mnt_sb &&
2012 path->mnt->mnt_root == path->dentry)
2013 goto unlock;
2014
2015 err = -EINVAL;
2016 if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
2017 goto unlock;
2018
2019 newmnt->mnt_flags = mnt_flags;
2020 err = graft_tree(newmnt, path);
2021
2022unlock:
2023 unlock_mount(path);
2024 return err;
2025}
1917 2026
1918/* 2027/*
1919 * create a new mount for userspace and request it to be added into the 2028 * create a new mount for userspace and request it to be added into the
@@ -1973,43 +2082,6 @@ fail:
1973 return err; 2082 return err;
1974} 2083}
1975 2084
1976/*
1977 * add a mount into a namespace's mount tree
1978 */
1979static int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1980{
1981 int err;
1982
1983 mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);
1984
1985 down_write(&namespace_sem);
1986 /* Something was mounted here while we slept */
1987 err = follow_down(path, true);
1988 if (err < 0)
1989 goto unlock;
1990
1991 err = -EINVAL;
1992 if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
1993 goto unlock;
1994
1995 /* Refuse the same filesystem on the same mount point */
1996 err = -EBUSY;
1997 if (path->mnt->mnt_sb == newmnt->mnt_sb &&
1998 path->mnt->mnt_root == path->dentry)
1999 goto unlock;
2000
2001 err = -EINVAL;
2002 if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
2003 goto unlock;
2004
2005 newmnt->mnt_flags = mnt_flags;
2006 err = graft_tree(newmnt, path);
2007
2008unlock:
2009 up_write(&namespace_sem);
2010 return err;
2011}
2012
2013/** 2085/**
2014 * mnt_set_expiry - Put a mount on an expiration list 2086 * mnt_set_expiry - Put a mount on an expiration list
2015 * @mnt: The mount to list. 2087 * @mnt: The mount to list.
@@ -2510,65 +2582,60 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2510 error = user_path_dir(new_root, &new); 2582 error = user_path_dir(new_root, &new);
2511 if (error) 2583 if (error)
2512 goto out0; 2584 goto out0;
2513 error = -EINVAL;
2514 if (!check_mnt(new.mnt))
2515 goto out1;
2516 2585
2517 error = user_path_dir(put_old, &old); 2586 error = user_path_dir(put_old, &old);
2518 if (error) 2587 if (error)
2519 goto out1; 2588 goto out1;
2520 2589
2521 error = security_sb_pivotroot(&old, &new); 2590 error = security_sb_pivotroot(&old, &new);
2522 if (error) { 2591 if (error)
2523 path_put(&old); 2592 goto out2;
2524 goto out1;
2525 }
2526 2593
2527 get_fs_root(current->fs, &root); 2594 get_fs_root(current->fs, &root);
2528 down_write(&namespace_sem); 2595 error = lock_mount(&old);
2529 mutex_lock(&old.dentry->d_inode->i_mutex); 2596 if (error)
2597 goto out3;
2598
2530 error = -EINVAL; 2599 error = -EINVAL;
2531 if (IS_MNT_SHARED(old.mnt) || 2600 if (IS_MNT_SHARED(old.mnt) ||
2532 IS_MNT_SHARED(new.mnt->mnt_parent) || 2601 IS_MNT_SHARED(new.mnt->mnt_parent) ||
2533 IS_MNT_SHARED(root.mnt->mnt_parent)) 2602 IS_MNT_SHARED(root.mnt->mnt_parent))
2534 goto out2; 2603 goto out4;
2535 if (!check_mnt(root.mnt)) 2604 if (!check_mnt(root.mnt) || !check_mnt(new.mnt))
2536 goto out2; 2605 goto out4;
2537 error = -ENOENT; 2606 error = -ENOENT;
2538 if (cant_mount(old.dentry))
2539 goto out2;
2540 if (d_unlinked(new.dentry)) 2607 if (d_unlinked(new.dentry))
2541 goto out2; 2608 goto out4;
2542 if (d_unlinked(old.dentry)) 2609 if (d_unlinked(old.dentry))
2543 goto out2; 2610 goto out4;
2544 error = -EBUSY; 2611 error = -EBUSY;
2545 if (new.mnt == root.mnt || 2612 if (new.mnt == root.mnt ||
2546 old.mnt == root.mnt) 2613 old.mnt == root.mnt)
2547 goto out2; /* loop, on the same file system */ 2614 goto out4; /* loop, on the same file system */
2548 error = -EINVAL; 2615 error = -EINVAL;
2549 if (root.mnt->mnt_root != root.dentry) 2616 if (root.mnt->mnt_root != root.dentry)
2550 goto out2; /* not a mountpoint */ 2617 goto out4; /* not a mountpoint */
2551 if (root.mnt->mnt_parent == root.mnt) 2618 if (root.mnt->mnt_parent == root.mnt)
2552 goto out2; /* not attached */ 2619 goto out4; /* not attached */
2553 if (new.mnt->mnt_root != new.dentry) 2620 if (new.mnt->mnt_root != new.dentry)
2554 goto out2; /* not a mountpoint */ 2621 goto out4; /* not a mountpoint */
2555 if (new.mnt->mnt_parent == new.mnt) 2622 if (new.mnt->mnt_parent == new.mnt)
2556 goto out2; /* not attached */ 2623 goto out4; /* not attached */
2557 /* make sure we can reach put_old from new_root */ 2624 /* make sure we can reach put_old from new_root */
2558 tmp = old.mnt; 2625 tmp = old.mnt;
2559 br_write_lock(vfsmount_lock);
2560 if (tmp != new.mnt) { 2626 if (tmp != new.mnt) {
2561 for (;;) { 2627 for (;;) {
2562 if (tmp->mnt_parent == tmp) 2628 if (tmp->mnt_parent == tmp)
2563 goto out3; /* already mounted on put_old */ 2629 goto out4; /* already mounted on put_old */
2564 if (tmp->mnt_parent == new.mnt) 2630 if (tmp->mnt_parent == new.mnt)
2565 break; 2631 break;
2566 tmp = tmp->mnt_parent; 2632 tmp = tmp->mnt_parent;
2567 } 2633 }
2568 if (!is_subdir(tmp->mnt_mountpoint, new.dentry)) 2634 if (!is_subdir(tmp->mnt_mountpoint, new.dentry))
2569 goto out3; 2635 goto out4;
2570 } else if (!is_subdir(old.dentry, new.dentry)) 2636 } else if (!is_subdir(old.dentry, new.dentry))
2571 goto out3; 2637 goto out4;
2638 br_write_lock(vfsmount_lock);
2572 detach_mnt(new.mnt, &parent_path); 2639 detach_mnt(new.mnt, &parent_path);
2573 detach_mnt(root.mnt, &root_parent); 2640 detach_mnt(root.mnt, &root_parent);
2574 /* mount old root on put_old */ 2641 /* mount old root on put_old */
@@ -2578,22 +2645,21 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2578 touch_mnt_namespace(current->nsproxy->mnt_ns); 2645 touch_mnt_namespace(current->nsproxy->mnt_ns);
2579 br_write_unlock(vfsmount_lock); 2646 br_write_unlock(vfsmount_lock);
2580 chroot_fs_refs(&root, &new); 2647 chroot_fs_refs(&root, &new);
2581
2582 error = 0; 2648 error = 0;
2583 path_put(&root_parent); 2649out4:
2584 path_put(&parent_path); 2650 unlock_mount(&old);
2585out2: 2651 if (!error) {
2586 mutex_unlock(&old.dentry->d_inode->i_mutex); 2652 path_put(&root_parent);
2587 up_write(&namespace_sem); 2653 path_put(&parent_path);
2654 }
2655out3:
2588 path_put(&root); 2656 path_put(&root);
2657out2:
2589 path_put(&old); 2658 path_put(&old);
2590out1: 2659out1:
2591 path_put(&new); 2660 path_put(&new);
2592out0: 2661out0:
2593 return error; 2662 return error;
2594out3:
2595 br_write_unlock(vfsmount_lock);
2596 goto out2;
2597} 2663}
2598 2664
2599static void __init init_mount_tree(void) 2665static void __init init_mount_tree(void)
@@ -2668,3 +2734,9 @@ void put_mnt_ns(struct mnt_namespace *ns)
2668 kfree(ns); 2734 kfree(ns);
2669} 2735}
2670EXPORT_SYMBOL(put_mnt_ns); 2736EXPORT_SYMBOL(put_mnt_ns);
2737
2738struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
2739{
2740 return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
2741}
2742EXPORT_SYMBOL_GPL(kern_mount_data);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index da1d9701f8e..ff93025ae2f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -87,7 +87,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
87 .dentry = dget(dentry)}; 87 .dentry = dget(dentry)};
88 int err = 0; 88 int err = 0;
89 89
90 err = follow_down(&path, false); 90 err = follow_down(&path);
91 if (err < 0) 91 if (err < 0)
92 goto out; 92 goto out;
93 93
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 549d245d0b4..08342232cb1 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -40,9 +40,29 @@
40struct pstore_private { 40struct pstore_private {
41 u64 id; 41 u64 id;
42 int (*erase)(u64); 42 int (*erase)(u64);
43 ssize_t size;
44 char data[];
43}; 45};
44 46
45#define pstore_get_inode ramfs_get_inode 47static int pstore_file_open(struct inode *inode, struct file *file)
48{
49 file->private_data = inode->i_private;
50 return 0;
51}
52
53static ssize_t pstore_file_read(struct file *file, char __user *userbuf,
54 size_t count, loff_t *ppos)
55{
56 struct pstore_private *ps = file->private_data;
57
58 return simple_read_from_buffer(userbuf, count, ppos, ps->data, ps->size);
59}
60
61static const struct file_operations pstore_file_operations = {
62 .open = pstore_file_open,
63 .read = pstore_file_read,
64 .llseek = default_llseek,
65};
46 66
47/* 67/*
48 * When a file is unlinked from our file system we call the 68 * When a file is unlinked from our file system we call the
@@ -63,6 +83,30 @@ static const struct inode_operations pstore_dir_inode_operations = {
63 .unlink = pstore_unlink, 83 .unlink = pstore_unlink,
64}; 84};
65 85
86static struct inode *pstore_get_inode(struct super_block *sb,
87 const struct inode *dir, int mode, dev_t dev)
88{
89 struct inode *inode = new_inode(sb);
90
91 if (inode) {
92 inode->i_ino = get_next_ino();
93 inode->i_uid = inode->i_gid = 0;
94 inode->i_mode = mode;
95 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
96 switch (mode & S_IFMT) {
97 case S_IFREG:
98 inode->i_fop = &pstore_file_operations;
99 break;
100 case S_IFDIR:
101 inode->i_op = &pstore_dir_inode_operations;
102 inode->i_fop = &simple_dir_operations;
103 inc_nlink(inode);
104 break;
105 }
106 }
107 return inode;
108}
109
66static const struct super_operations pstore_ops = { 110static const struct super_operations pstore_ops = {
67 .statfs = simple_statfs, 111 .statfs = simple_statfs,
68 .drop_inode = generic_delete_inode, 112 .drop_inode = generic_delete_inode,
@@ -70,37 +114,10 @@ static const struct super_operations pstore_ops = {
70}; 114};
71 115
72static struct super_block *pstore_sb; 116static struct super_block *pstore_sb;
73static struct vfsmount *pstore_mnt;
74 117
75int pstore_is_mounted(void) 118int pstore_is_mounted(void)
76{ 119{
77 return pstore_mnt != NULL; 120 return pstore_sb != NULL;
78}
79
80/*
81 * Set up a file structure as if we had opened this file and
82 * write our data to it.
83 */
84static int pstore_writefile(struct inode *inode, struct dentry *dentry,
85 char *data, size_t size)
86{
87 struct file f;
88 ssize_t n;
89 mm_segment_t old_fs = get_fs();
90
91 memset(&f, '0', sizeof f);
92 f.f_mapping = inode->i_mapping;
93 f.f_path.dentry = dentry;
94 f.f_path.mnt = pstore_mnt;
95 f.f_pos = 0;
96 f.f_op = inode->i_fop;
97 set_fs(KERNEL_DS);
98 n = do_sync_write(&f, data, size, &f.f_pos);
99 set_fs(old_fs);
100
101 fsnotify_modify(&f);
102
103 return n == size;
104} 121}
105 122
106/* 123/*
@@ -123,8 +140,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
123 inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0); 140 inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0);
124 if (!inode) 141 if (!inode)
125 goto fail; 142 goto fail;
126 inode->i_uid = inode->i_gid = 0; 143 private = kmalloc(sizeof *private + size, GFP_KERNEL);
127 private = kmalloc(sizeof *private, GFP_KERNEL);
128 if (!private) 144 if (!private)
129 goto fail_alloc; 145 goto fail_alloc;
130 private->id = id; 146 private->id = id;
@@ -152,28 +168,19 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
152 if (IS_ERR(dentry)) 168 if (IS_ERR(dentry))
153 goto fail_lockedalloc; 169 goto fail_lockedalloc;
154 170
155 d_add(dentry, inode); 171 memcpy(private->data, data, size);
156 172 inode->i_size = private->size = size;
157 mutex_unlock(&root->d_inode->i_mutex);
158
159 if (!pstore_writefile(inode, dentry, data, size))
160 goto fail_write;
161 173
162 inode->i_private = private; 174 inode->i_private = private;
163 175
164 if (time.tv_sec) 176 if (time.tv_sec)
165 inode->i_mtime = inode->i_ctime = time; 177 inode->i_mtime = inode->i_ctime = time;
166 178
167 return 0; 179 d_add(dentry, inode);
168 180
169fail_write:
170 kfree(private);
171 inode->i_nlink--;
172 mutex_lock(&root->d_inode->i_mutex);
173 d_delete(dentry);
174 dput(dentry);
175 mutex_unlock(&root->d_inode->i_mutex); 181 mutex_unlock(&root->d_inode->i_mutex);
176 goto fail; 182
183 return 0;
177 184
178fail_lockedalloc: 185fail_lockedalloc:
179 mutex_unlock(&root->d_inode->i_mutex); 186 mutex_unlock(&root->d_inode->i_mutex);
@@ -225,32 +232,21 @@ fail:
225 return err; 232 return err;
226} 233}
227 234
228static int pstore_get_sb(struct file_system_type *fs_type, 235static struct dentry *pstore_mount(struct file_system_type *fs_type,
229 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 236 int flags, const char *dev_name, void *data)
230{ 237{
231 struct dentry *root; 238 return mount_single(fs_type, flags, data, pstore_fill_super);
232
233 root = mount_nodev(fs_type, flags, data, pstore_fill_super);
234 if (IS_ERR(root))
235 return -ENOMEM;
236
237 mnt->mnt_root = root;
238 mnt->mnt_sb = root->d_sb;
239 pstore_mnt = mnt;
240
241 return 0;
242} 239}
243 240
244static void pstore_kill_sb(struct super_block *sb) 241static void pstore_kill_sb(struct super_block *sb)
245{ 242{
246 kill_litter_super(sb); 243 kill_litter_super(sb);
247 pstore_sb = NULL; 244 pstore_sb = NULL;
248 pstore_mnt = NULL;
249} 245}
250 246
251static struct file_system_type pstore_fs_type = { 247static struct file_system_type pstore_fs_type = {
252 .name = "pstore", 248 .name = "pstore",
253 .get_sb = pstore_get_sb, 249 .mount = pstore_mount,
254 .kill_sb = pstore_kill_sb, 250 .kill_sb = pstore_kill_sb,
255}; 251};
256 252
diff --git a/fs/super.c b/fs/super.c
index 4bae0ef6110..e8486490826 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -910,29 +910,18 @@ struct dentry *mount_single(struct file_system_type *fs_type,
910} 910}
911EXPORT_SYMBOL(mount_single); 911EXPORT_SYMBOL(mount_single);
912 912
913struct vfsmount * 913struct dentry *
914vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) 914mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
915{ 915{
916 struct vfsmount *mnt;
917 struct dentry *root; 916 struct dentry *root;
917 struct super_block *sb;
918 char *secdata = NULL; 918 char *secdata = NULL;
919 int error; 919 int error = -ENOMEM;
920
921 if (!type)
922 return ERR_PTR(-ENODEV);
923
924 error = -ENOMEM;
925 mnt = alloc_vfsmnt(name);
926 if (!mnt)
927 goto out;
928
929 if (flags & MS_KERNMOUNT)
930 mnt->mnt_flags = MNT_INTERNAL;
931 920
932 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 921 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
933 secdata = alloc_secdata(); 922 secdata = alloc_secdata();
934 if (!secdata) 923 if (!secdata)
935 goto out_mnt; 924 goto out;
936 925
937 error = security_sb_copy_data(data, secdata); 926 error = security_sb_copy_data(data, secdata);
938 if (error) 927 if (error)
@@ -944,13 +933,12 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
944 error = PTR_ERR(root); 933 error = PTR_ERR(root);
945 goto out_free_secdata; 934 goto out_free_secdata;
946 } 935 }
947 mnt->mnt_root = root; 936 sb = root->d_sb;
948 mnt->mnt_sb = root->d_sb; 937 BUG_ON(!sb);
949 BUG_ON(!mnt->mnt_sb); 938 WARN_ON(!sb->s_bdi);
950 WARN_ON(!mnt->mnt_sb->s_bdi); 939 sb->s_flags |= MS_BORN;
951 mnt->mnt_sb->s_flags |= MS_BORN;
952 940
953 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); 941 error = security_sb_kern_mount(sb, flags, secdata);
954 if (error) 942 if (error)
955 goto out_sb; 943 goto out_sb;
956 944
@@ -961,27 +949,21 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
961 * violate this rule. This warning should be either removed or 949 * violate this rule. This warning should be either removed or
962 * converted to a BUG() in 2.6.34. 950 * converted to a BUG() in 2.6.34.
963 */ 951 */
964 WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " 952 WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
965 "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); 953 "negative value (%lld)\n", type->name, sb->s_maxbytes);
966 954
967 mnt->mnt_mountpoint = mnt->mnt_root; 955 up_write(&sb->s_umount);
968 mnt->mnt_parent = mnt;
969 up_write(&mnt->mnt_sb->s_umount);
970 free_secdata(secdata); 956 free_secdata(secdata);
971 return mnt; 957 return root;
972out_sb: 958out_sb:
973 dput(mnt->mnt_root); 959 dput(root);
974 deactivate_locked_super(mnt->mnt_sb); 960 deactivate_locked_super(sb);
975out_free_secdata: 961out_free_secdata:
976 free_secdata(secdata); 962 free_secdata(secdata);
977out_mnt:
978 free_vfsmnt(mnt);
979out: 963out:
980 return ERR_PTR(error); 964 return ERR_PTR(error);
981} 965}
982 966
983EXPORT_SYMBOL_GPL(vfs_kern_mount);
984
985/** 967/**
986 * freeze_super - lock the filesystem and force it into a consistent state 968 * freeze_super - lock the filesystem and force it into a consistent state
987 * @sb: the super to lock 969 * @sb: the super to lock
@@ -1071,49 +1053,3 @@ out:
1071 return 0; 1053 return 0;
1072} 1054}
1073EXPORT_SYMBOL(thaw_super); 1055EXPORT_SYMBOL(thaw_super);
1074
1075static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
1076{
1077 int err;
1078 const char *subtype = strchr(fstype, '.');
1079 if (subtype) {
1080 subtype++;
1081 err = -EINVAL;
1082 if (!subtype[0])
1083 goto err;
1084 } else
1085 subtype = "";
1086
1087 mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
1088 err = -ENOMEM;
1089 if (!mnt->mnt_sb->s_subtype)
1090 goto err;
1091 return mnt;
1092
1093 err:
1094 mntput(mnt);
1095 return ERR_PTR(err);
1096}
1097
1098struct vfsmount *
1099do_kern_mount(const char *fstype, int flags, const char *name, void *data)
1100{
1101 struct file_system_type *type = get_fs_type(fstype);
1102 struct vfsmount *mnt;
1103 if (!type)
1104 return ERR_PTR(-ENODEV);
1105 mnt = vfs_kern_mount(type, flags, name, data);
1106 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
1107 !mnt->mnt_sb->s_subtype)
1108 mnt = fs_set_subtype(mnt, fstype);
1109 put_filesystem(type);
1110 return mnt;
1111}
1112EXPORT_SYMBOL_GPL(do_kern_mount);
1113
1114struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
1115{
1116 return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
1117}
1118
1119EXPORT_SYMBOL_GPL(kern_mount_data);