aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c96
1 files changed, 58 insertions, 38 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d0b991a92327..ff645a961bc8 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1690,8 +1690,8 @@ static int nfs_compare_super(struct super_block *sb, void *data)
1690 return !nfs_compare_fh(&old->fh, &server->fh); 1690 return !nfs_compare_fh(&old->fh, &server->fh);
1691} 1691}
1692 1692
1693static struct super_block *nfs_get_sb(struct file_system_type *fs_type, 1693static int nfs_get_sb(struct file_system_type *fs_type,
1694 int flags, const char *dev_name, void *raw_data) 1694 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1695{ 1695{
1696 int error; 1696 int error;
1697 struct nfs_server *server = NULL; 1697 struct nfs_server *server = NULL;
@@ -1699,14 +1699,14 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1699 struct nfs_fh *root; 1699 struct nfs_fh *root;
1700 struct nfs_mount_data *data = raw_data; 1700 struct nfs_mount_data *data = raw_data;
1701 1701
1702 s = ERR_PTR(-EINVAL); 1702 error = -EINVAL;
1703 if (data == NULL) { 1703 if (data == NULL) {
1704 dprintk("%s: missing data argument\n", __FUNCTION__); 1704 dprintk("%s: missing data argument\n", __FUNCTION__);
1705 goto out_err; 1705 goto out_err_noserver;
1706 } 1706 }
1707 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { 1707 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
1708 dprintk("%s: bad mount version\n", __FUNCTION__); 1708 dprintk("%s: bad mount version\n", __FUNCTION__);
1709 goto out_err; 1709 goto out_err_noserver;
1710 } 1710 }
1711 switch (data->version) { 1711 switch (data->version) {
1712 case 1: 1712 case 1:
@@ -1718,7 +1718,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1718 dprintk("%s: mount structure version %d does not support NFSv3\n", 1718 dprintk("%s: mount structure version %d does not support NFSv3\n",
1719 __FUNCTION__, 1719 __FUNCTION__,
1720 data->version); 1720 data->version);
1721 goto out_err; 1721 goto out_err_noserver;
1722 } 1722 }
1723 data->root.size = NFS2_FHSIZE; 1723 data->root.size = NFS2_FHSIZE;
1724 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); 1724 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
@@ -1727,24 +1727,24 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1727 dprintk("%s: mount structure version %d does not support strong security\n", 1727 dprintk("%s: mount structure version %d does not support strong security\n",
1728 __FUNCTION__, 1728 __FUNCTION__,
1729 data->version); 1729 data->version);
1730 goto out_err; 1730 goto out_err_noserver;
1731 } 1731 }
1732 case 5: 1732 case 5:
1733 memset(data->context, 0, sizeof(data->context)); 1733 memset(data->context, 0, sizeof(data->context));
1734 } 1734 }
1735#ifndef CONFIG_NFS_V3 1735#ifndef CONFIG_NFS_V3
1736 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ 1736 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
1737 s = ERR_PTR(-EPROTONOSUPPORT); 1737 error = -EPROTONOSUPPORT;
1738 if (data->flags & NFS_MOUNT_VER3) { 1738 if (data->flags & NFS_MOUNT_VER3) {
1739 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); 1739 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
1740 goto out_err; 1740 goto out_err_noserver;
1741 } 1741 }
1742#endif /* CONFIG_NFS_V3 */ 1742#endif /* CONFIG_NFS_V3 */
1743 1743
1744 s = ERR_PTR(-ENOMEM); 1744 error = -ENOMEM;
1745 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 1745 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
1746 if (!server) 1746 if (!server)
1747 goto out_err; 1747 goto out_err_noserver;
1748 /* Zero out the NFS state stuff */ 1748 /* Zero out the NFS state stuff */
1749 init_nfsv4_state(server); 1749 init_nfsv4_state(server);
1750 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 1750 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -1754,7 +1754,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1754 root->size = data->root.size; 1754 root->size = data->root.size;
1755 else 1755 else
1756 root->size = NFS2_FHSIZE; 1756 root->size = NFS2_FHSIZE;
1757 s = ERR_PTR(-EINVAL); 1757 error = -EINVAL;
1758 if (root->size > sizeof(root->data)) { 1758 if (root->size > sizeof(root->data)) {
1759 dprintk("%s: invalid root filehandle\n", __FUNCTION__); 1759 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
1760 goto out_err; 1760 goto out_err;
@@ -1770,15 +1770,20 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1770 } 1770 }
1771 1771
1772 /* Fire up rpciod if not yet running */ 1772 /* Fire up rpciod if not yet running */
1773 s = ERR_PTR(rpciod_up()); 1773 error = rpciod_up();
1774 if (IS_ERR(s)) { 1774 if (error < 0) {
1775 dprintk("%s: couldn't start rpciod! Error = %ld\n", 1775 dprintk("%s: couldn't start rpciod! Error = %d\n",
1776 __FUNCTION__, PTR_ERR(s)); 1776 __FUNCTION__, error);
1777 goto out_err; 1777 goto out_err;
1778 } 1778 }
1779 1779
1780 s = sget(fs_type, nfs_compare_super, nfs_set_super, server); 1780 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1781 if (IS_ERR(s) || s->s_root) 1781 if (IS_ERR(s)) {
1782 error = PTR_ERR(s);
1783 goto out_err_rpciod;
1784 }
1785
1786 if (s->s_root)
1782 goto out_rpciod_down; 1787 goto out_rpciod_down;
1783 1788
1784 s->s_flags = flags; 1789 s->s_flags = flags;
@@ -1787,15 +1792,22 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1787 if (error) { 1792 if (error) {
1788 up_write(&s->s_umount); 1793 up_write(&s->s_umount);
1789 deactivate_super(s); 1794 deactivate_super(s);
1790 return ERR_PTR(error); 1795 return error;
1791 } 1796 }
1792 s->s_flags |= MS_ACTIVE; 1797 s->s_flags |= MS_ACTIVE;
1793 return s; 1798 return simple_set_mnt(mnt, s);
1799
1794out_rpciod_down: 1800out_rpciod_down:
1795 rpciod_down(); 1801 rpciod_down();
1802 kfree(server);
1803 return simple_set_mnt(mnt, s);
1804
1805out_err_rpciod:
1806 rpciod_down();
1796out_err: 1807out_err:
1797 kfree(server); 1808 kfree(server);
1798 return s; 1809out_err_noserver:
1810 return error;
1799} 1811}
1800 1812
1801static void nfs_kill_super(struct super_block *s) 1813static void nfs_kill_super(struct super_block *s)
@@ -2032,8 +2044,8 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
2032 return dst; 2044 return dst;
2033} 2045}
2034 2046
2035static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, 2047static int nfs4_get_sb(struct file_system_type *fs_type,
2036 int flags, const char *dev_name, void *raw_data) 2048 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
2037{ 2049{
2038 int error; 2050 int error;
2039 struct nfs_server *server; 2051 struct nfs_server *server;
@@ -2043,16 +2055,16 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
2043 2055
2044 if (data == NULL) { 2056 if (data == NULL) {
2045 dprintk("%s: missing data argument\n", __FUNCTION__); 2057 dprintk("%s: missing data argument\n", __FUNCTION__);
2046 return ERR_PTR(-EINVAL); 2058 return -EINVAL;
2047 } 2059 }
2048 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) { 2060 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
2049 dprintk("%s: bad mount version\n", __FUNCTION__); 2061 dprintk("%s: bad mount version\n", __FUNCTION__);
2050 return ERR_PTR(-EINVAL); 2062 return -EINVAL;
2051 } 2063 }
2052 2064
2053 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 2065 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
2054 if (!server) 2066 if (!server)
2055 return ERR_PTR(-ENOMEM); 2067 return -ENOMEM;
2056 /* Zero out the NFS state stuff */ 2068 /* Zero out the NFS state stuff */
2057 init_nfsv4_state(server); 2069 init_nfsv4_state(server);
2058 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 2070 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -2074,33 +2086,41 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
2074 2086
2075 /* We now require that the mount process passes the remote address */ 2087 /* We now require that the mount process passes the remote address */
2076 if (data->host_addrlen != sizeof(server->addr)) { 2088 if (data->host_addrlen != sizeof(server->addr)) {
2077 s = ERR_PTR(-EINVAL); 2089 error = -EINVAL;
2078 goto out_free; 2090 goto out_free;
2079 } 2091 }
2080 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) { 2092 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {
2081 s = ERR_PTR(-EFAULT); 2093 error = -EFAULT;
2082 goto out_free; 2094 goto out_free;
2083 } 2095 }
2084 if (server->addr.sin_family != AF_INET || 2096 if (server->addr.sin_family != AF_INET ||
2085 server->addr.sin_addr.s_addr == INADDR_ANY) { 2097 server->addr.sin_addr.s_addr == INADDR_ANY) {
2086 dprintk("%s: mount program didn't pass remote IP address!\n", 2098 dprintk("%s: mount program didn't pass remote IP address!\n",
2087 __FUNCTION__); 2099 __FUNCTION__);
2088 s = ERR_PTR(-EINVAL); 2100 error = -EINVAL;
2089 goto out_free; 2101 goto out_free;
2090 } 2102 }
2091 2103
2092 /* Fire up rpciod if not yet running */ 2104 /* Fire up rpciod if not yet running */
2093 s = ERR_PTR(rpciod_up()); 2105 error = rpciod_up();
2094 if (IS_ERR(s)) { 2106 if (error < 0) {
2095 dprintk("%s: couldn't start rpciod! Error = %ld\n", 2107 dprintk("%s: couldn't start rpciod! Error = %d\n",
2096 __FUNCTION__, PTR_ERR(s)); 2108 __FUNCTION__, error);
2097 goto out_free; 2109 goto out_free;
2098 } 2110 }
2099 2111
2100 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); 2112 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
2101 2113 if (IS_ERR(s)) {
2102 if (IS_ERR(s) || s->s_root) 2114 error = PTR_ERR(s);
2103 goto out_free; 2115 goto out_free;
2116 }
2117
2118 if (s->s_root) {
2119 kfree(server->mnt_path);
2120 kfree(server->hostname);
2121 kfree(server);
2122 return simple_set_mnt(mnt, s);
2123 }
2104 2124
2105 s->s_flags = flags; 2125 s->s_flags = flags;
2106 2126
@@ -2108,17 +2128,17 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
2108 if (error) { 2128 if (error) {
2109 up_write(&s->s_umount); 2129 up_write(&s->s_umount);
2110 deactivate_super(s); 2130 deactivate_super(s);
2111 return ERR_PTR(error); 2131 return error;
2112 } 2132 }
2113 s->s_flags |= MS_ACTIVE; 2133 s->s_flags |= MS_ACTIVE;
2114 return s; 2134 return simple_set_mnt(mnt, s);
2115out_err: 2135out_err:
2116 s = (struct super_block *)p; 2136 error = PTR_ERR(p);
2117out_free: 2137out_free:
2118 kfree(server->mnt_path); 2138 kfree(server->mnt_path);
2119 kfree(server->hostname); 2139 kfree(server->hostname);
2120 kfree(server); 2140 kfree(server);
2121 return s; 2141 return error;
2122} 2142}
2123 2143
2124static void nfs4_kill_super(struct super_block *sb) 2144static void nfs4_kill_super(struct super_block *sb)