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