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 | |
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>
-rw-r--r-- | fs/nfs/client.c | 24 | ||||
-rw-r--r-- | fs/nfs/internal.h | 11 | ||||
-rw-r--r-- | fs/nfs/super.c | 146 |
3 files changed, 81 insertions, 100 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index f51eabff3cd0..2edcbca1a161 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -908,7 +908,7 @@ error: | |||
908 | * Create a version 4 volume record | 908 | * Create a version 4 volume record |
909 | */ | 909 | */ |
910 | static int nfs4_init_server(struct nfs_server *server, | 910 | static int nfs4_init_server(struct nfs_server *server, |
911 | const struct nfs4_mount_data *data, rpc_authflavor_t authflavour) | 911 | const struct nfs_parsed_mount_data *data) |
912 | { | 912 | { |
913 | int error; | 913 | int error; |
914 | 914 | ||
@@ -928,7 +928,7 @@ static int nfs4_init_server(struct nfs_server *server, | |||
928 | server->acdirmin = data->acdirmin * HZ; | 928 | server->acdirmin = data->acdirmin * HZ; |
929 | server->acdirmax = data->acdirmax * HZ; | 929 | server->acdirmax = data->acdirmax * HZ; |
930 | 930 | ||
931 | error = nfs_init_server_rpcclient(server, authflavour); | 931 | error = nfs_init_server_rpcclient(server, data->auth_flavors[0]); |
932 | 932 | ||
933 | /* Done */ | 933 | /* Done */ |
934 | dprintk("<-- nfs4_init_server() = %d\n", error); | 934 | dprintk("<-- nfs4_init_server() = %d\n", error); |
@@ -939,12 +939,7 @@ static int nfs4_init_server(struct nfs_server *server, | |||
939 | * Create a version 4 volume record | 939 | * Create a version 4 volume record |
940 | * - keyed on server and FSID | 940 | * - keyed on server and FSID |
941 | */ | 941 | */ |
942 | struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, | 942 | struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, |
943 | const char *hostname, | ||
944 | const struct sockaddr_in *addr, | ||
945 | const char *mntpath, | ||
946 | const char *ip_addr, | ||
947 | rpc_authflavor_t authflavour, | ||
948 | struct nfs_fh *mntfh) | 943 | struct nfs_fh *mntfh) |
949 | { | 944 | { |
950 | struct nfs_fattr fattr; | 945 | struct nfs_fattr fattr; |
@@ -958,13 +953,18 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, | |||
958 | return ERR_PTR(-ENOMEM); | 953 | return ERR_PTR(-ENOMEM); |
959 | 954 | ||
960 | /* Get a client record */ | 955 | /* Get a client record */ |
961 | error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour, | 956 | error = nfs4_set_client(server, |
962 | data->proto, data->timeo, data->retrans); | 957 | data->nfs_server.hostname, |
958 | &data->nfs_server.address, | ||
959 | data->client_address, | ||
960 | data->auth_flavors[0], | ||
961 | data->nfs_server.protocol, | ||
962 | data->timeo, data->retrans); | ||
963 | if (error < 0) | 963 | if (error < 0) |
964 | goto error; | 964 | goto error; |
965 | 965 | ||
966 | /* set up the general RPC client */ | 966 | /* set up the general RPC client */ |
967 | error = nfs4_init_server(server, data, authflavour); | 967 | error = nfs4_init_server(server, data); |
968 | if (error < 0) | 968 | if (error < 0) |
969 | goto error; | 969 | goto error; |
970 | 970 | ||
@@ -973,7 +973,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, | |||
973 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | 973 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); |
974 | 974 | ||
975 | /* Probe the root fh to retrieve its FSID */ | 975 | /* Probe the root fh to retrieve its FSID */ |
976 | error = nfs4_path_walk(server, mntfh, mntpath); | 976 | error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); |
977 | if (error < 0) | 977 | if (error < 0) |
978 | goto error; | 978 | goto error; |
979 | 979 | ||
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index d28e54e4dee4..f3acf48412be 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/mount.h> | 5 | #include <linux/mount.h> |
6 | 6 | ||
7 | struct nfs_string; | 7 | struct nfs_string; |
8 | struct nfs4_mount_data; | ||
9 | 8 | ||
10 | /* Maximum number of readahead requests | 9 | /* Maximum number of readahead requests |
11 | * FIXME: this should really be a sysctl so that users may tune it to suit | 10 | * FIXME: this should really be a sysctl so that users may tune it to suit |
@@ -67,13 +66,9 @@ extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); | |||
67 | extern struct nfs_server *nfs_create_server( | 66 | extern struct nfs_server *nfs_create_server( |
68 | const struct nfs_parsed_mount_data *, | 67 | const struct nfs_parsed_mount_data *, |
69 | struct nfs_fh *); | 68 | struct nfs_fh *); |
70 | extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, | 69 | extern struct nfs_server *nfs4_create_server( |
71 | const char *, | 70 | const struct nfs_parsed_mount_data *, |
72 | const struct sockaddr_in *, | 71 | struct nfs_fh *); |
73 | const char *, | ||
74 | const char *, | ||
75 | rpc_authflavor_t, | ||
76 | struct nfs_fh *); | ||
77 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, | 72 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, |
78 | struct nfs_fh *); | 73 | struct nfs_fh *); |
79 | extern void nfs_free_server(struct nfs_server *server); | 74 | extern void nfs_free_server(struct nfs_server *server); |
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: |