aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/inode.c179
1 files changed, 105 insertions, 74 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index ea784969fb85..32ddcf69e9ac 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -366,13 +366,15 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
366 xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, 366 xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
367 &server->addr, &timeparms); 367 &server->addr, &timeparms);
368 if (IS_ERR(xprt)) { 368 if (IS_ERR(xprt)) {
369 printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); 369 dprintk("%s: cannot create RPC transport. Error = %ld\n",
370 __FUNCTION__, PTR_ERR(xprt));
370 return (struct rpc_clnt *)xprt; 371 return (struct rpc_clnt *)xprt;
371 } 372 }
372 clnt = rpc_create_client(xprt, server->hostname, &nfs_program, 373 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
373 server->rpc_ops->version, data->pseudoflavor); 374 server->rpc_ops->version, data->pseudoflavor);
374 if (IS_ERR(clnt)) { 375 if (IS_ERR(clnt)) {
375 printk(KERN_WARNING "NFS: cannot create RPC client.\n"); 376 dprintk("%s: cannot create RPC client. Error = %ld\n",
377 __FUNCTION__, PTR_ERR(xprt));
376 goto out_fail; 378 goto out_fail;
377 } 379 }
378 380
@@ -426,21 +428,16 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
426 428
427 /* Check NFS protocol revision and initialize RPC op vector 429 /* Check NFS protocol revision and initialize RPC op vector
428 * and file handle pool. */ 430 * and file handle pool. */
429 if (server->flags & NFS_MOUNT_VER3) {
430#ifdef CONFIG_NFS_V3 431#ifdef CONFIG_NFS_V3
432 if (server->flags & NFS_MOUNT_VER3) {
431 server->rpc_ops = &nfs_v3_clientops; 433 server->rpc_ops = &nfs_v3_clientops;
432 server->caps |= NFS_CAP_READDIRPLUS; 434 server->caps |= NFS_CAP_READDIRPLUS;
433 if (data->version < 4) {
434 printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n");
435 return -EIO;
436 }
437#else
438 printk(KERN_NOTICE "NFS: NFSv3 not supported.\n");
439 return -EIO;
440#endif
441 } else { 435 } else {
442 server->rpc_ops = &nfs_v2_clientops; 436 server->rpc_ops = &nfs_v2_clientops;
443 } 437 }
438#else
439 server->rpc_ops = &nfs_v2_clientops;
440#endif
444 441
445 /* Fill in pseudoflavor for mount version < 5 */ 442 /* Fill in pseudoflavor for mount version < 5 */
446 if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) 443 if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
@@ -1384,74 +1381,94 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1384 int flags, const char *dev_name, void *raw_data) 1381 int flags, const char *dev_name, void *raw_data)
1385{ 1382{
1386 int error; 1383 int error;
1387 struct nfs_server *server; 1384 struct nfs_server *server = NULL;
1388 struct super_block *s; 1385 struct super_block *s;
1389 struct nfs_fh *root; 1386 struct nfs_fh *root;
1390 struct nfs_mount_data *data = raw_data; 1387 struct nfs_mount_data *data = raw_data;
1391 1388
1392 if (!data) { 1389 s = ERR_PTR(-EINVAL);
1393 printk("nfs_read_super: missing data argument\n"); 1390 if (data == NULL) {
1394 return ERR_PTR(-EINVAL); 1391 dprintk("%s: missing data argument\n", __FUNCTION__);
1392 goto out_err;
1393 }
1394 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
1395 dprintk("%s: bad mount version\n", __FUNCTION__);
1396 goto out_err;
1395 } 1397 }
1398 switch (data->version) {
1399 case 1:
1400 data->namlen = 0;
1401 case 2:
1402 data->bsize = 0;
1403 case 3:
1404 if (data->flags & NFS_MOUNT_VER3) {
1405 dprintk("%s: mount structure version %d does not support NFSv3\n",
1406 __FUNCTION__,
1407 data->version);
1408 goto out_err;
1409 }
1410 data->root.size = NFS2_FHSIZE;
1411 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1412 case 4:
1413 if (data->flags & NFS_MOUNT_SECFLAVOUR) {
1414 dprintk("%s: mount structure version %d does not support strong security\n",
1415 __FUNCTION__,
1416 data->version);
1417 goto out_err;
1418 }
1419 case 5:
1420 memset(data->context, 0, sizeof(data->context));
1421 }
1422#ifndef CONFIG_NFS_V3
1423 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
1424 s = ERR_PTR(-EPROTONOSUPPORT);
1425 if (data->flags & NFS_MOUNT_VER3) {
1426 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
1427 goto out_err;
1428 }
1429#endif /* CONFIG_NFS_V3 */
1396 1430
1431 s = ERR_PTR(-ENOMEM);
1397 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); 1432 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
1398 if (!server) 1433 if (!server)
1399 return ERR_PTR(-ENOMEM); 1434 goto out_err;
1400 memset(server, 0, sizeof(struct nfs_server)); 1435 memset(server, 0, sizeof(struct nfs_server));
1401 /* Zero out the NFS state stuff */ 1436 /* Zero out the NFS state stuff */
1402 init_nfsv4_state(server); 1437 init_nfsv4_state(server);
1403 1438
1404 if (data->version != NFS_MOUNT_VERSION) {
1405 printk("nfs warning: mount version %s than kernel\n",
1406 data->version < NFS_MOUNT_VERSION ? "older" : "newer");
1407 if (data->version < 2)
1408 data->namlen = 0;
1409 if (data->version < 3)
1410 data->bsize = 0;
1411 if (data->version < 4) {
1412 data->flags &= ~NFS_MOUNT_VER3;
1413 data->root.size = NFS2_FHSIZE;
1414 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1415 }
1416 if (data->version < 5)
1417 data->flags &= ~NFS_MOUNT_SECFLAVOUR;
1418 }
1419
1420 root = &server->fh; 1439 root = &server->fh;
1421 if (data->flags & NFS_MOUNT_VER3) 1440 if (data->flags & NFS_MOUNT_VER3)
1422 root->size = data->root.size; 1441 root->size = data->root.size;
1423 else 1442 else
1424 root->size = NFS2_FHSIZE; 1443 root->size = NFS2_FHSIZE;
1444 s = ERR_PTR(-EINVAL);
1425 if (root->size > sizeof(root->data)) { 1445 if (root->size > sizeof(root->data)) {
1426 printk("nfs_get_sb: invalid root filehandle\n"); 1446 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
1427 kfree(server); 1447 goto out_err;
1428 return ERR_PTR(-EINVAL);
1429 } 1448 }
1430 memcpy(root->data, data->root.data, root->size); 1449 memcpy(root->data, data->root.data, root->size);
1431 1450
1432 /* We now require that the mount process passes the remote address */ 1451 /* We now require that the mount process passes the remote address */
1433 memcpy(&server->addr, &data->addr, sizeof(server->addr)); 1452 memcpy(&server->addr, &data->addr, sizeof(server->addr));
1434 if (server->addr.sin_addr.s_addr == INADDR_ANY) { 1453 if (server->addr.sin_addr.s_addr == INADDR_ANY) {
1435 printk("NFS: mount program didn't pass remote address!\n"); 1454 dprintk("%s: mount program didn't pass remote address!\n",
1436 kfree(server); 1455 __FUNCTION__);
1437 return ERR_PTR(-EINVAL); 1456 goto out_err;
1438 } 1457 }
1439 1458
1440 s = sget(fs_type, nfs_compare_super, nfs_set_super, server); 1459 /* Fire up rpciod if not yet running */
1441 1460 s = ERR_PTR(rpciod_up());
1442 if (IS_ERR(s) || s->s_root) { 1461 if (IS_ERR(s)) {
1443 kfree(server); 1462 dprintk("%s: couldn't start rpciod! Error = %ld\n",
1444 return s; 1463 __FUNCTION__, PTR_ERR(s));
1464 goto out_err;
1445 } 1465 }
1446 1466
1447 s->s_flags = flags; 1467 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1468 if (IS_ERR(s) || s->s_root)
1469 goto out_rpciod_down;
1448 1470
1449 /* Fire up rpciod if not yet running */ 1471 s->s_flags = flags;
1450 if (rpciod_up() != 0) {
1451 printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
1452 kfree(server);
1453 return ERR_PTR(-EIO);
1454 }
1455 1472
1456 error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); 1473 error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
1457 if (error) { 1474 if (error) {
@@ -1461,6 +1478,11 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1461 } 1478 }
1462 s->s_flags |= MS_ACTIVE; 1479 s->s_flags |= MS_ACTIVE;
1463 return s; 1480 return s;
1481out_rpciod_down:
1482 rpciod_down();
1483out_err:
1484 kfree(server);
1485 return s;
1464} 1486}
1465 1487
1466static void nfs_kill_super(struct super_block *s) 1488static void nfs_kill_super(struct super_block *s)
@@ -1593,15 +1615,19 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1593 1615
1594 clp = nfs4_get_client(&server->addr.sin_addr); 1616 clp = nfs4_get_client(&server->addr.sin_addr);
1595 if (!clp) { 1617 if (!clp) {
1596 printk(KERN_WARNING "NFS: failed to create NFS4 client.\n"); 1618 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
1597 return -EIO; 1619 return -EIO;
1598 } 1620 }
1599 1621
1600 /* Now create transport and client */ 1622 /* Now create transport and client */
1601 authflavour = RPC_AUTH_UNIX; 1623 authflavour = RPC_AUTH_UNIX;
1602 if (data->auth_flavourlen != 0) { 1624 if (data->auth_flavourlen != 0) {
1603 if (data->auth_flavourlen > 1) 1625 if (data->auth_flavourlen != 1) {
1604 printk(KERN_INFO "NFS: cannot yet deal with multiple auth flavours.\n"); 1626 dprintk("%s: Invalid number of RPC auth flavours %d.\n",
1627 __FUNCTION__, data->auth_flavourlen);
1628 err = -EINVAL;
1629 goto out_fail;
1630 }
1605 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) { 1631 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
1606 err = -EFAULT; 1632 err = -EFAULT;
1607 goto out_fail; 1633 goto out_fail;
@@ -1613,16 +1639,18 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1613 xprt = xprt_create_proto(proto, &server->addr, &timeparms); 1639 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
1614 if (IS_ERR(xprt)) { 1640 if (IS_ERR(xprt)) {
1615 up_write(&clp->cl_sem); 1641 up_write(&clp->cl_sem);
1616 printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
1617 err = PTR_ERR(xprt); 1642 err = PTR_ERR(xprt);
1643 dprintk("%s: cannot create RPC transport. Error = %d\n",
1644 __FUNCTION__, err);
1618 goto out_fail; 1645 goto out_fail;
1619 } 1646 }
1620 clnt = rpc_create_client(xprt, server->hostname, &nfs_program, 1647 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
1621 server->rpc_ops->version, authflavour); 1648 server->rpc_ops->version, authflavour);
1622 if (IS_ERR(clnt)) { 1649 if (IS_ERR(clnt)) {
1623 up_write(&clp->cl_sem); 1650 up_write(&clp->cl_sem);
1624 printk(KERN_WARNING "NFS: cannot create RPC client.\n");
1625 err = PTR_ERR(clnt); 1651 err = PTR_ERR(clnt);
1652 dprintk("%s: cannot create RPC client. Error = %d\n",
1653 __FUNCTION__, err);
1626 goto out_fail; 1654 goto out_fail;
1627 } 1655 }
1628 clnt->cl_intr = 1; 1656 clnt->cl_intr = 1;
@@ -1654,20 +1682,22 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1654 clp = NULL; 1682 clp = NULL;
1655 1683
1656 if (IS_ERR(clnt)) { 1684 if (IS_ERR(clnt)) {
1657 printk(KERN_WARNING "NFS: cannot create RPC client.\n"); 1685 err = PTR_ERR(clnt);
1658 return PTR_ERR(clnt); 1686 dprintk("%s: cannot create RPC client. Error = %d\n",
1687 __FUNCTION__, err);
1688 return err;
1659 } 1689 }
1660 1690
1661 server->client = clnt; 1691 server->client = clnt;
1662 1692
1663 if (server->nfs4_state->cl_idmap == NULL) { 1693 if (server->nfs4_state->cl_idmap == NULL) {
1664 printk(KERN_WARNING "NFS: failed to create idmapper.\n"); 1694 dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
1665 return -ENOMEM; 1695 return -ENOMEM;
1666 } 1696 }
1667 1697
1668 if (clnt->cl_auth->au_flavor != authflavour) { 1698 if (clnt->cl_auth->au_flavor != authflavour) {
1669 if (rpcauth_create(authflavour, clnt) == NULL) { 1699 if (rpcauth_create(authflavour, clnt) == NULL) {
1670 printk(KERN_WARNING "NFS: couldn't create credcache!\n"); 1700 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
1671 return -ENOMEM; 1701 return -ENOMEM;
1672 } 1702 }
1673 } 1703 }
@@ -1728,8 +1758,12 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1728 struct nfs4_mount_data *data = raw_data; 1758 struct nfs4_mount_data *data = raw_data;
1729 void *p; 1759 void *p;
1730 1760
1731 if (!data) { 1761 if (data == NULL) {
1732 printk("nfs_read_super: missing data argument\n"); 1762 dprintk("%s: missing data argument\n", __FUNCTION__);
1763 return ERR_PTR(-EINVAL);
1764 }
1765 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
1766 dprintk("%s: bad mount version\n", __FUNCTION__);
1733 return ERR_PTR(-EINVAL); 1767 return ERR_PTR(-EINVAL);
1734 } 1768 }
1735 1769
@@ -1740,11 +1774,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1740 /* Zero out the NFS state stuff */ 1774 /* Zero out the NFS state stuff */
1741 init_nfsv4_state(server); 1775 init_nfsv4_state(server);
1742 1776
1743 if (data->version != NFS4_MOUNT_VERSION) {
1744 printk("nfs warning: mount version %s than kernel\n",
1745 data->version < NFS4_MOUNT_VERSION ? "older" : "newer");
1746 }
1747
1748 p = nfs_copy_user_string(NULL, &data->hostname, 256); 1777 p = nfs_copy_user_string(NULL, &data->hostname, 256);
1749 if (IS_ERR(p)) 1778 if (IS_ERR(p))
1750 goto out_err; 1779 goto out_err;
@@ -1771,11 +1800,20 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1771 } 1800 }
1772 if (server->addr.sin_family != AF_INET || 1801 if (server->addr.sin_family != AF_INET ||
1773 server->addr.sin_addr.s_addr == INADDR_ANY) { 1802 server->addr.sin_addr.s_addr == INADDR_ANY) {
1774 printk("NFS: mount program didn't pass remote IP address!\n"); 1803 dprintk("%s: mount program didn't pass remote IP address!\n",
1804 __FUNCTION__);
1775 s = ERR_PTR(-EINVAL); 1805 s = ERR_PTR(-EINVAL);
1776 goto out_free; 1806 goto out_free;
1777 } 1807 }
1778 1808
1809 /* Fire up rpciod if not yet running */
1810 s = ERR_PTR(rpciod_up());
1811 if (IS_ERR(s)) {
1812 dprintk("%s: couldn't start rpciod! Error = %ld\n",
1813 __FUNCTION__, PTR_ERR(s));
1814 goto out_free;
1815 }
1816
1779 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); 1817 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
1780 1818
1781 if (IS_ERR(s) || s->s_root) 1819 if (IS_ERR(s) || s->s_root)
@@ -1783,13 +1821,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1783 1821
1784 s->s_flags = flags; 1822 s->s_flags = flags;
1785 1823
1786 /* Fire up rpciod if not yet running */
1787 if (rpciod_up() != 0) {
1788 printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
1789 s = ERR_PTR(-EIO);
1790 goto out_free;
1791 }
1792
1793 error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); 1824 error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
1794 if (error) { 1825 if (error) {
1795 up_write(&s->s_umount); 1826 up_write(&s->s_umount);