NFS: Reduce the NFS mount code stack usage.

This appears to fix the Oops reported in
http://bugzilla.kernel.org/show_bug.cgi?id=10826

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

+40 -28
+40 -28
fs/nfs/super.c
··· 1216 1216 { 1217 1217 struct nfs_mount_data *data = (struct nfs_mount_data *)options; 1218 1218 1219 - memset(args, 0, sizeof(*args)); 1220 - 1221 1219 if (data == NULL) 1222 1220 goto out_no_data; 1223 1221 ··· 1583 1585 { 1584 1586 struct nfs_server *server = NULL; 1585 1587 struct super_block *s; 1586 - struct nfs_fh mntfh; 1587 - struct nfs_parsed_mount_data data; 1588 + struct nfs_parsed_mount_data *data; 1589 + struct nfs_fh *mntfh; 1588 1590 struct dentry *mntroot; 1589 1591 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1590 1592 struct nfs_sb_mountdata sb_mntdata = { 1591 1593 .mntflags = flags, 1592 1594 }; 1593 - int error; 1595 + int error = -ENOMEM; 1594 1596 1595 - security_init_mnt_opts(&data.lsm_opts); 1597 + data = kzalloc(sizeof(*data), GFP_KERNEL); 1598 + mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); 1599 + if (data == NULL || mntfh == NULL) 1600 + goto out_free_fh; 1601 + 1602 + security_init_mnt_opts(&data->lsm_opts); 1596 1603 1597 1604 /* Validate the mount data */ 1598 - error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); 1605 + error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); 1599 1606 if (error < 0) 1600 1607 goto out; 1601 1608 1602 1609 /* Get a volume representation */ 1603 - server = nfs_create_server(&data, &mntfh); 1610 + server = nfs_create_server(data, mntfh); 1604 1611 if (IS_ERR(server)) { 1605 1612 error = PTR_ERR(server); 1606 1613 goto out; ··· 1633 1630 1634 1631 if (!s->s_root) { 1635 1632 /* initial superblock/root creation */ 1636 - nfs_fill_super(s, &data); 1633 + nfs_fill_super(s, data); 1637 1634 } 1638 1635 1639 - mntroot = nfs_get_root(s, &mntfh); 1636 + mntroot = nfs_get_root(s, mntfh); 1640 1637 if (IS_ERR(mntroot)) { 1641 1638 error = PTR_ERR(mntroot); 1642 1639 goto error_splat_super; 1643 1640 } 1644 1641 1645 - error = security_sb_set_mnt_opts(s, &data.lsm_opts); 1642 + error = security_sb_set_mnt_opts(s, &data->lsm_opts); 1646 1643 if (error) 1647 1644 goto error_splat_root; 1648 1645 ··· 1652 1649 error = 0; 1653 1650 1654 1651 out: 1655 - kfree(data.nfs_server.hostname); 1656 - kfree(data.mount_server.hostname); 1657 - security_free_mnt_opts(&data.lsm_opts); 1652 + kfree(data->nfs_server.hostname); 1653 + kfree(data->mount_server.hostname); 1654 + security_free_mnt_opts(&data->lsm_opts); 1655 + out_free_fh: 1656 + kfree(mntfh); 1657 + kfree(data); 1658 1658 return error; 1659 1659 1660 1660 out_err_nosb: ··· 1805 1799 struct sockaddr_in *ap; 1806 1800 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; 1807 1801 char *c; 1808 - 1809 - memset(args, 0, sizeof(*args)); 1810 1802 1811 1803 if (data == NULL) 1812 1804 goto out_no_data; ··· 1963 1959 static int nfs4_get_sb(struct file_system_type *fs_type, 1964 1960 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 1965 1961 { 1966 - struct nfs_parsed_mount_data data; 1962 + struct nfs_parsed_mount_data *data; 1967 1963 struct super_block *s; 1968 1964 struct nfs_server *server; 1969 - struct nfs_fh mntfh; 1965 + struct nfs_fh *mntfh; 1970 1966 struct dentry *mntroot; 1971 1967 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1972 1968 struct nfs_sb_mountdata sb_mntdata = { 1973 1969 .mntflags = flags, 1974 1970 }; 1975 - int error; 1971 + int error = -ENOMEM; 1976 1972 1977 - security_init_mnt_opts(&data.lsm_opts); 1973 + data = kzalloc(sizeof(*data), GFP_KERNEL); 1974 + mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); 1975 + if (data == NULL || mntfh == NULL) 1976 + goto out_free_fh; 1977 + 1978 + security_init_mnt_opts(&data->lsm_opts); 1978 1979 1979 1980 /* Validate the mount data */ 1980 - error = nfs4_validate_mount_data(raw_data, &data, dev_name); 1981 + error = nfs4_validate_mount_data(raw_data, data, dev_name); 1981 1982 if (error < 0) 1982 1983 goto out; 1983 1984 1984 1985 /* Get a volume representation */ 1985 - server = nfs4_create_server(&data, &mntfh); 1986 + server = nfs4_create_server(data, mntfh); 1986 1987 if (IS_ERR(server)) { 1987 1988 error = PTR_ERR(server); 1988 1989 goto out; ··· 2018 2009 nfs4_fill_super(s); 2019 2010 } 2020 2011 2021 - mntroot = nfs4_get_root(s, &mntfh); 2012 + mntroot = nfs4_get_root(s, mntfh); 2022 2013 if (IS_ERR(mntroot)) { 2023 2014 error = PTR_ERR(mntroot); 2024 2015 goto error_splat_super; 2025 2016 } 2026 2017 2027 - error = security_sb_set_mnt_opts(s, &data.lsm_opts); 2018 + error = security_sb_set_mnt_opts(s, &data->lsm_opts); 2028 2019 if (error) 2029 2020 goto error_splat_root; 2030 2021 ··· 2034 2025 error = 0; 2035 2026 2036 2027 out: 2037 - kfree(data.client_address); 2038 - kfree(data.nfs_server.export_path); 2039 - kfree(data.nfs_server.hostname); 2040 - security_free_mnt_opts(&data.lsm_opts); 2028 + kfree(data->client_address); 2029 + kfree(data->nfs_server.export_path); 2030 + kfree(data->nfs_server.hostname); 2031 + security_free_mnt_opts(&data->lsm_opts); 2032 + out_free_fh: 2033 + kfree(mntfh); 2034 + kfree(data); 2041 2035 return error; 2042 2036 2043 2037 out_free: