diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-07-01 12:13:59 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:48 -0400 |
commit | 8007122520f0a3599bdc4df47358a5d83b2574aa (patch) | |
tree | d2d0def406e081ac32f487b54d2ad347f4f28e81 | |
parent | 136d558ce766967fe3cbf54c3351aba261b5d53b (diff) |
NFS: Add support for mounting NFSv4 file systems with string options
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/super.c | 91 | ||||
-rw-r--r-- | include/linux/nfs4_mount.h | 2 |
2 files changed, 85 insertions, 8 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 757aa3b7e64b..064e69d2fdde 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1541,8 +1541,90 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options, | |||
1541 | *ip_addr = c; | 1541 | *ip_addr = c; |
1542 | 1542 | ||
1543 | break; | 1543 | break; |
1544 | default: | 1544 | default: { |
1545 | goto out_bad_version; | 1545 | unsigned int len; |
1546 | struct nfs_parsed_mount_data args = { | ||
1547 | .rsize = NFS_MAX_FILE_IO_SIZE, | ||
1548 | .wsize = NFS_MAX_FILE_IO_SIZE, | ||
1549 | .timeo = 600, | ||
1550 | .retrans = 2, | ||
1551 | .acregmin = 3, | ||
1552 | .acregmax = 60, | ||
1553 | .acdirmin = 30, | ||
1554 | .acdirmax = 60, | ||
1555 | .nfs_server.protocol = IPPROTO_TCP, | ||
1556 | }; | ||
1557 | |||
1558 | if (nfs_parse_mount_options((char *) *options, &args) == 0) | ||
1559 | return -EINVAL; | ||
1560 | |||
1561 | if (!nfs_verify_server_address((struct sockaddr *) | ||
1562 | &args.nfs_server.address)) | ||
1563 | return -EINVAL; | ||
1564 | *addr = args.nfs_server.address; | ||
1565 | |||
1566 | switch (args.auth_flavor_len) { | ||
1567 | case 0: | ||
1568 | *authflavour = RPC_AUTH_UNIX; | ||
1569 | break; | ||
1570 | case 1: | ||
1571 | *authflavour = (rpc_authflavor_t) args.auth_flavors[0]; | ||
1572 | break; | ||
1573 | default: | ||
1574 | goto out_inval_auth; | ||
1575 | } | ||
1576 | |||
1577 | /* | ||
1578 | * Translate to nfs4_mount_data, which nfs4_fill_super | ||
1579 | * can deal with. | ||
1580 | */ | ||
1581 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
1582 | if (data == NULL) | ||
1583 | return -ENOMEM; | ||
1584 | *options = data; | ||
1585 | |||
1586 | data->version = 1; | ||
1587 | data->flags = args.flags & NFS4_MOUNT_FLAGMASK; | ||
1588 | data->rsize = args.rsize; | ||
1589 | data->wsize = args.wsize; | ||
1590 | data->timeo = args.timeo; | ||
1591 | data->retrans = args.retrans; | ||
1592 | data->acregmin = args.acregmin; | ||
1593 | data->acregmax = args.acregmax; | ||
1594 | data->acdirmin = args.acdirmin; | ||
1595 | data->acdirmax = args.acdirmax; | ||
1596 | data->proto = args.nfs_server.protocol; | ||
1597 | |||
1598 | /* | ||
1599 | * Split "dev_name" into "hostname:mntpath". | ||
1600 | */ | ||
1601 | c = strchr(dev_name, ':'); | ||
1602 | if (c == NULL) | ||
1603 | return -EINVAL; | ||
1604 | /* while calculating len, pretend ':' is '\0' */ | ||
1605 | len = c - dev_name; | ||
1606 | if (len > NFS4_MAXNAMLEN) | ||
1607 | return -EINVAL; | ||
1608 | *hostname = kzalloc(len, GFP_KERNEL); | ||
1609 | if (*hostname == NULL) | ||
1610 | return -ENOMEM; | ||
1611 | strncpy(*hostname, dev_name, len - 1); | ||
1612 | |||
1613 | c++; /* step over the ':' */ | ||
1614 | len = strlen(c); | ||
1615 | if (len > NFS4_MAXPATHLEN) | ||
1616 | return -EINVAL; | ||
1617 | *mntpath = kzalloc(len + 1, GFP_KERNEL); | ||
1618 | if (*mntpath == NULL) | ||
1619 | return -ENOMEM; | ||
1620 | strncpy(*mntpath, c, len); | ||
1621 | |||
1622 | dprintk("MNTPATH: %s\n", *mntpath); | ||
1623 | |||
1624 | *ip_addr = args.client_address; | ||
1625 | |||
1626 | break; | ||
1627 | } | ||
1546 | } | 1628 | } |
1547 | 1629 | ||
1548 | return 0; | 1630 | return 0; |
@@ -1559,11 +1641,6 @@ out_inval_auth: | |||
1559 | out_no_address: | 1641 | out_no_address: |
1560 | dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); | 1642 | dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); |
1561 | return -EINVAL; | 1643 | return -EINVAL; |
1562 | |||
1563 | out_bad_version: | ||
1564 | dfprintk(MOUNT, "NFS4: bad nfs_mount_data version %d\n", | ||
1565 | data->version); | ||
1566 | return -EINVAL; | ||
1567 | } | 1644 | } |
1568 | 1645 | ||
1569 | /* | 1646 | /* |
diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h index 26b4c83f831d..d8d7480e5a47 100644 --- a/include/linux/nfs4_mount.h +++ b/include/linux/nfs4_mount.h | |||
@@ -65,6 +65,6 @@ struct nfs4_mount_data { | |||
65 | #define NFS4_MOUNT_NOCTO 0x0010 /* 1 */ | 65 | #define NFS4_MOUNT_NOCTO 0x0010 /* 1 */ |
66 | #define NFS4_MOUNT_NOAC 0x0020 /* 1 */ | 66 | #define NFS4_MOUNT_NOAC 0x0020 /* 1 */ |
67 | #define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */ | 67 | #define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */ |
68 | #define NFS4_MOUNT_FLAGMASK 0xFFFF | 68 | #define NFS4_MOUNT_FLAGMASK 0x1033 |
69 | 69 | ||
70 | #endif | 70 | #endif |