diff options
author | \"Talpey, Thomas\ <Thomas.Talpey@netapp.com> | 2007-09-10 13:44:33 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:17:28 -0400 |
commit | 91ea40b9c6303ddab5c84f078f96b29084b45817 (patch) | |
tree | b7f48effc5adbb1b9c36a7e16ce9133d7152aad9 /fs/nfs/super.c | |
parent | 2283f8d6ed21ea2221df4cc329314b93f35351b0 (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.c | 146 |
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 | */ |
1517 | static int nfs4_validate_mount_data(struct nfs4_mount_data **options, | 1517 | static 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: | |||
1684 | static int nfs4_get_sb(struct file_system_type *fs_type, | 1675 | static 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 | ||
1747 | out: | 1733 | out: |
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 | ||
1753 | out_free: | 1739 | out_free: |