aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
author\"Talpey, Thomas\ <Thomas.Talpey@netapp.com>2007-09-10 13:44:33 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-09 17:17:28 -0400
commit91ea40b9c6303ddab5c84f078f96b29084b45817 (patch)
treeb7f48effc5adbb1b9c36a7e16ce9133d7152aad9 /fs/nfs/super.c
parent2283f8d6ed21ea2221df4cc329314b93f35351b0 (diff)
NFS: use in-kernel mount argument structure for nfsv4 mounts
The user-visible nfs4_mount_data does not contain sufficient data to describe new mount options, and also is now a legacy structure. Replace it with the internal nfs_parsed_mount_data for nfsv4 in-kernel use. Signed-off-by: Tom Talpey <tmt@netapp.com> Acked-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c146
1 files changed, 66 insertions, 80 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 36a595a63536..63742bbcb1ce 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1514,38 +1514,49 @@ static void nfs4_fill_super(struct super_block *sb)
1514/* 1514/*
1515 * Validate NFSv4 mount options 1515 * Validate NFSv4 mount options
1516 */ 1516 */
1517static int nfs4_validate_mount_data(struct nfs4_mount_data **options, 1517static int nfs4_validate_mount_data(void *options,
1518 const char *dev_name, 1518 struct nfs_parsed_mount_data *args,
1519 struct sockaddr_in *addr, 1519 const char *dev_name)
1520 rpc_authflavor_t *authflavour,
1521 char **hostname,
1522 char **mntpath,
1523 char **ip_addr)
1524{ 1520{
1525 struct nfs4_mount_data *data = *options; 1521 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
1526 char *c; 1522 char *c;
1527 1523
1528 if (data == NULL) 1524 if (data == NULL)
1529 goto out_no_data; 1525 goto out_no_data;
1530 1526
1527 memset(args, 0, sizeof(*args));
1528 args->rsize = NFS_MAX_FILE_IO_SIZE;
1529 args->wsize = NFS_MAX_FILE_IO_SIZE;
1530 args->timeo = 600;
1531 args->retrans = 2;
1532 args->acregmin = 3;
1533 args->acregmax = 60;
1534 args->acdirmin = 30;
1535 args->acdirmax = 60;
1536 args->nfs_server.protocol = IPPROTO_TCP;
1537
1531 switch (data->version) { 1538 switch (data->version) {
1532 case 1: 1539 case 1:
1533 if (data->host_addrlen != sizeof(*addr)) 1540 if (data->host_addrlen != sizeof(args->nfs_server.address))
1534 goto out_no_address; 1541 goto out_no_address;
1535 if (copy_from_user(addr, data->host_addr, sizeof(*addr))) 1542 if (copy_from_user(&args->nfs_server.address,
1543 data->host_addr,
1544 sizeof(&args->nfs_server.address)))
1536 return -EFAULT; 1545 return -EFAULT;
1537 if (addr->sin_port == 0) 1546 if (args->nfs_server.address.sin_port == 0)
1538 addr->sin_port = htons(NFS_PORT); 1547 args->nfs_server.address.sin_port = htons(NFS_PORT);
1539 if (!nfs_verify_server_address((struct sockaddr *) addr)) 1548 if (!nfs_verify_server_address((struct sockaddr *)
1549 &args->nfs_server.address))
1540 goto out_no_address; 1550 goto out_no_address;
1541 1551
1542 switch (data->auth_flavourlen) { 1552 switch (data->auth_flavourlen) {
1543 case 0: 1553 case 0:
1544 *authflavour = RPC_AUTH_UNIX; 1554 args->auth_flavors[0] = RPC_AUTH_UNIX;
1545 break; 1555 break;
1546 case 1: 1556 case 1:
1547 if (copy_from_user(authflavour, data->auth_flavours, 1557 if (copy_from_user(args->auth_flavors,
1548 sizeof(*authflavour))) 1558 data->auth_flavours,
1559 sizeof(args->auth_flavors)))
1549 return -EFAULT; 1560 return -EFAULT;
1550 break; 1561 break;
1551 default: 1562 default:
@@ -1555,75 +1566,57 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
1555 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 1566 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
1556 if (IS_ERR(c)) 1567 if (IS_ERR(c))
1557 return PTR_ERR(c); 1568 return PTR_ERR(c);
1558 *hostname = c; 1569 args->nfs_server.hostname = c;
1559 1570
1560 c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); 1571 c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
1561 if (IS_ERR(c)) 1572 if (IS_ERR(c))
1562 return PTR_ERR(c); 1573 return PTR_ERR(c);
1563 *mntpath = c; 1574 args->nfs_server.export_path = c;
1564 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *mntpath); 1575 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
1565 1576
1566 c = strndup_user(data->client_addr.data, 16); 1577 c = strndup_user(data->client_addr.data, 16);
1567 if (IS_ERR(c)) 1578 if (IS_ERR(c))
1568 return PTR_ERR(c); 1579 return PTR_ERR(c);
1569 *ip_addr = c; 1580 args->client_address = c;
1581
1582 /*
1583 * Translate to nfs_parsed_mount_data, which nfs4_fill_super
1584 * can deal with.
1585 */
1586
1587 args->flags = data->flags & NFS4_MOUNT_FLAGMASK;
1588 args->rsize = data->rsize;
1589 args->wsize = data->wsize;
1590 args->timeo = data->timeo;
1591 args->retrans = data->retrans;
1592 args->acregmin = data->acregmin;
1593 args->acregmax = data->acregmax;
1594 args->acdirmin = data->acdirmin;
1595 args->acdirmax = data->acdirmax;
1596 args->nfs_server.protocol = data->proto;
1570 1597
1571 break; 1598 break;
1572 default: { 1599 default: {
1573 unsigned int len; 1600 unsigned int len;
1574 struct nfs_parsed_mount_data args = { 1601
1575 .rsize = NFS_MAX_FILE_IO_SIZE, 1602 if (nfs_parse_mount_options((char *)options, args) == 0)
1576 .wsize = NFS_MAX_FILE_IO_SIZE,
1577 .timeo = 600,
1578 .retrans = 2,
1579 .acregmin = 3,
1580 .acregmax = 60,
1581 .acdirmin = 30,
1582 .acdirmax = 60,
1583 .nfs_server.protocol = IPPROTO_TCP,
1584 };
1585
1586 if (nfs_parse_mount_options((char *) *options, &args) == 0)
1587 return -EINVAL; 1603 return -EINVAL;
1588 1604
1589 if (!nfs_verify_server_address((struct sockaddr *) 1605 if (!nfs_verify_server_address((struct sockaddr *)
1590 &args.nfs_server.address)) 1606 &args->nfs_server.address))
1591 return -EINVAL; 1607 return -EINVAL;
1592 *addr = args.nfs_server.address;
1593 1608
1594 switch (args.auth_flavor_len) { 1609 switch (args->auth_flavor_len) {
1595 case 0: 1610 case 0:
1596 *authflavour = RPC_AUTH_UNIX; 1611 args->auth_flavors[0] = RPC_AUTH_UNIX;
1597 break; 1612 break;
1598 case 1: 1613 case 1:
1599 *authflavour = (rpc_authflavor_t) args.auth_flavors[0];
1600 break; 1614 break;
1601 default: 1615 default:
1602 goto out_inval_auth; 1616 goto out_inval_auth;
1603 } 1617 }
1604 1618
1605 /* 1619 /*
1606 * Translate to nfs4_mount_data, which nfs4_fill_super
1607 * can deal with.
1608 */
1609 data = kzalloc(sizeof(*data), GFP_KERNEL);
1610 if (data == NULL)
1611 return -ENOMEM;
1612 *options = data;
1613
1614 data->version = 1;
1615 data->flags = args.flags & NFS4_MOUNT_FLAGMASK;
1616 data->rsize = args.rsize;
1617 data->wsize = args.wsize;
1618 data->timeo = args.timeo;
1619 data->retrans = args.retrans;
1620 data->acregmin = args.acregmin;
1621 data->acregmax = args.acregmax;
1622 data->acdirmin = args.acdirmin;
1623 data->acdirmax = args.acdirmax;
1624 data->proto = args.nfs_server.protocol;
1625
1626 /*
1627 * Split "dev_name" into "hostname:mntpath". 1620 * Split "dev_name" into "hostname:mntpath".
1628 */ 1621 */
1629 c = strchr(dev_name, ':'); 1622 c = strchr(dev_name, ':');
@@ -1633,27 +1626,25 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
1633 len = c - dev_name; 1626 len = c - dev_name;
1634 if (len > NFS4_MAXNAMLEN) 1627 if (len > NFS4_MAXNAMLEN)
1635 return -ENAMETOOLONG; 1628 return -ENAMETOOLONG;
1636 *hostname = kzalloc(len, GFP_KERNEL); 1629 args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);
1637 if (*hostname == NULL) 1630 if (args->nfs_server.hostname == NULL)
1638 return -ENOMEM; 1631 return -ENOMEM;
1639 strncpy(*hostname, dev_name, len - 1); 1632 strncpy(args->nfs_server.hostname, dev_name, len - 1);
1640 1633
1641 c++; /* step over the ':' */ 1634 c++; /* step over the ':' */
1642 len = strlen(c); 1635 len = strlen(c);
1643 if (len > NFS4_MAXPATHLEN) 1636 if (len > NFS4_MAXPATHLEN)
1644 return -ENAMETOOLONG; 1637 return -ENAMETOOLONG;
1645 *mntpath = kzalloc(len + 1, GFP_KERNEL); 1638 args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);
1646 if (*mntpath == NULL) 1639 if (args->nfs_server.export_path == NULL)
1647 return -ENOMEM; 1640 return -ENOMEM;
1648 strncpy(*mntpath, c, len); 1641 strncpy(args->nfs_server.export_path, c, len);
1649 1642
1650 dprintk("MNTPATH: %s\n", *mntpath); 1643 dprintk("MNTPATH: %s\n", args->nfs_server.export_path);
1651 1644
1652 if (args.client_address == NULL) 1645 if (args->client_address == NULL)
1653 goto out_no_client_address; 1646 goto out_no_client_address;
1654 1647
1655 *ip_addr = args.client_address;
1656
1657 break; 1648 break;
1658 } 1649 }
1659 } 1650 }
@@ -1684,14 +1675,11 @@ out_no_client_address:
1684static int nfs4_get_sb(struct file_system_type *fs_type, 1675static int nfs4_get_sb(struct file_system_type *fs_type,
1685 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 1676 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1686{ 1677{
1687 struct nfs4_mount_data *data = raw_data; 1678 struct nfs_parsed_mount_data data;
1688 struct super_block *s; 1679 struct super_block *s;
1689 struct nfs_server *server; 1680 struct nfs_server *server;
1690 struct sockaddr_in addr;
1691 rpc_authflavor_t authflavour;
1692 struct nfs_fh mntfh; 1681 struct nfs_fh mntfh;
1693 struct dentry *mntroot; 1682 struct dentry *mntroot;
1694 char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL;
1695 int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1683 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1696 struct nfs_sb_mountdata sb_mntdata = { 1684 struct nfs_sb_mountdata sb_mntdata = {
1697 .mntflags = flags, 1685 .mntflags = flags,
@@ -1699,14 +1687,12 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
1699 int error; 1687 int error;
1700 1688
1701 /* Validate the mount data */ 1689 /* Validate the mount data */
1702 error = nfs4_validate_mount_data(&data, dev_name, &addr, &authflavour, 1690 error = nfs4_validate_mount_data(raw_data, &data, dev_name);
1703 &hostname, &mntpath, &ip_addr);
1704 if (error < 0) 1691 if (error < 0)
1705 goto out; 1692 goto out;
1706 1693
1707 /* Get a volume representation */ 1694 /* Get a volume representation */
1708 server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr, 1695 server = nfs4_create_server(&data, &mntfh);
1709 authflavour, &mntfh);
1710 if (IS_ERR(server)) { 1696 if (IS_ERR(server)) {
1711 error = PTR_ERR(server); 1697 error = PTR_ERR(server);
1712 goto out; 1698 goto out;
@@ -1745,9 +1731,9 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
1745 error = 0; 1731 error = 0;
1746 1732
1747out: 1733out:
1748 kfree(ip_addr); 1734 kfree(data.client_address);
1749 kfree(mntpath); 1735 kfree(data.nfs_server.export_path);
1750 kfree(hostname); 1736 kfree(data.nfs_server.hostname);
1751 return error; 1737 return error;
1752 1738
1753out_free: 1739out_free: