aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/nfs/client.c24
-rw-r--r--fs/nfs/internal.h11
-rw-r--r--fs/nfs/super.c146
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 */
910static int nfs4_init_server(struct nfs_server *server, 910static 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 */
942struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, 942struct 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
7struct nfs_string; 7struct nfs_string;
8struct 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);
67extern struct nfs_server *nfs_create_server( 66extern 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 *);
70extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, 69extern 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 *);
77extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, 72extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
78 struct nfs_fh *); 73 struct nfs_fh *);
79extern void nfs_free_server(struct nfs_server *server); 74extern 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 */
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: