diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 11:53:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 11:53:47 -0400 |
commit | f63d395d47f37a4fe771e6d4b1db9d2cdae5ffc5 (patch) | |
tree | 3448a14ae965802adb963762cadeb9989ce4caa2 /fs/nfs/inode.c | |
parent | 643ac9fc5429e85b8b7f534544b80bcc4f34c367 (diff) | |
parent | 5a7c9eec9fde1da0e3adf0a4ddb64ff2a324a492 (diff) |
Merge tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates for Linux 3.4 from Trond Myklebust:
"New features include:
- Add NFS client support for containers.
This should enable most of the necessary functionality, including
lockd support, and support for rpc.statd, NFSv4 idmapper and
RPCSEC_GSS upcalls into the correct network namespace from which
the mount system call was issued.
- NFSv4 idmapper scalability improvements
Base the idmapper cache on the keyring interface to allow
concurrent access to idmapper entries. Start the process of
migrating users from the single-threaded daemon-based approach to
the multi-threaded request-key based approach.
- NFSv4.1 implementation id.
Allows the NFSv4.1 client and server to mutually identify each
other for logging and debugging purposes.
- Support the 'vers=4.1' mount option for mounting NFSv4.1 instead of
having to use the more counterintuitive 'vers=4,minorversion=1'.
- SUNRPC tracepoints.
Start the process of adding tracepoints in order to improve
debugging of the RPC layer.
- pNFS object layout support for autologin.
Important bugfixes include:
- Fix a bug in rpc_wake_up/rpc_wake_up_status that caused them to
fail to wake up all tasks when applied to priority waitqueues.
- Ensure that we handle read delegations correctly, when we try to
truncate a file.
- A number of fixes for NFSv4 state manager loops (mostly to do with
delegation recovery)."
* tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (224 commits)
NFS: fix sb->s_id in nfs debug prints
xprtrdma: Remove assumption that each segment is <= PAGE_SIZE
xprtrdma: The transport should not bug-check when a dup reply is received
pnfs-obj: autologin: Add support for protocol autologin
NFS: Remove nfs4_setup_sequence from generic rename code
NFS: Remove nfs4_setup_sequence from generic unlink code
NFS: Remove nfs4_setup_sequence from generic read code
NFS: Remove nfs4_setup_sequence from generic write code
NFS: Fix more NFS debug related build warnings
SUNRPC/LOCKD: Fix build warnings when CONFIG_SUNRPC_DEBUG is undefined
nfs: non void functions must return a value
SUNRPC: Kill compiler warning when RPC_DEBUG is unset
SUNRPC/NFS: Add Kbuild dependencies for NFS_DEBUG/RPC_DEBUG
NFS: Use cond_resched_lock() to reduce latencies in the commit scans
NFSv4: It is not safe to dereference lsp->ls_state in release_lockowner
NFS: ncommit count is being double decremented
SUNRPC: We must not use list_for_each_entry_safe() in rpc_wake_up()
Try using machine credentials for RENEW calls
NFSv4.1: Fix a few issues in filelayout_commit_pagelist
NFSv4.1: Clean ups and bugfixes for the pNFS read/writeback/commit code
...
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 119 |
1 files changed, 106 insertions, 13 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index f649fba8c38..7bb4d13c1cd 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/compat.h> | 40 | #include <linux/compat.h> |
41 | #include <linux/freezer.h> | 41 | #include <linux/freezer.h> |
42 | #include <linux/crc32.h> | ||
42 | 43 | ||
43 | #include <asm/system.h> | 44 | #include <asm/system.h> |
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -51,6 +52,7 @@ | |||
51 | #include "fscache.h" | 52 | #include "fscache.h" |
52 | #include "dns_resolve.h" | 53 | #include "dns_resolve.h" |
53 | #include "pnfs.h" | 54 | #include "pnfs.h" |
55 | #include "netns.h" | ||
54 | 56 | ||
55 | #define NFSDBG_FACILITY NFSDBG_VFS | 57 | #define NFSDBG_FACILITY NFSDBG_VFS |
56 | 58 | ||
@@ -388,9 +390,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
388 | unlock_new_inode(inode); | 390 | unlock_new_inode(inode); |
389 | } else | 391 | } else |
390 | nfs_refresh_inode(inode, fattr); | 392 | nfs_refresh_inode(inode, fattr); |
391 | dprintk("NFS: nfs_fhget(%s/%Ld ct=%d)\n", | 393 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", |
392 | inode->i_sb->s_id, | 394 | inode->i_sb->s_id, |
393 | (long long)NFS_FILEID(inode), | 395 | (long long)NFS_FILEID(inode), |
396 | nfs_display_fhandle_hash(fh), | ||
394 | atomic_read(&inode->i_count)); | 397 | atomic_read(&inode->i_count)); |
395 | 398 | ||
396 | out: | 399 | out: |
@@ -401,7 +404,7 @@ out_no_inode: | |||
401 | goto out; | 404 | goto out; |
402 | } | 405 | } |
403 | 406 | ||
404 | #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE) | 407 | #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN) |
405 | 408 | ||
406 | int | 409 | int |
407 | nfs_setattr(struct dentry *dentry, struct iattr *attr) | 410 | nfs_setattr(struct dentry *dentry, struct iattr *attr) |
@@ -423,7 +426,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
423 | 426 | ||
424 | /* Optimization: if the end result is no change, don't RPC */ | 427 | /* Optimization: if the end result is no change, don't RPC */ |
425 | attr->ia_valid &= NFS_VALID_ATTRS; | 428 | attr->ia_valid &= NFS_VALID_ATTRS; |
426 | if ((attr->ia_valid & ~ATTR_FILE) == 0) | 429 | if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0) |
427 | return 0; | 430 | return 0; |
428 | 431 | ||
429 | /* Write all dirty data */ | 432 | /* Write all dirty data */ |
@@ -1044,6 +1047,67 @@ struct nfs_fh *nfs_alloc_fhandle(void) | |||
1044 | return fh; | 1047 | return fh; |
1045 | } | 1048 | } |
1046 | 1049 | ||
1050 | #ifdef NFS_DEBUG | ||
1051 | /* | ||
1052 | * _nfs_display_fhandle_hash - calculate the crc32 hash for the filehandle | ||
1053 | * in the same way that wireshark does | ||
1054 | * | ||
1055 | * @fh: file handle | ||
1056 | * | ||
1057 | * For debugging only. | ||
1058 | */ | ||
1059 | u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh) | ||
1060 | { | ||
1061 | /* wireshark uses 32-bit AUTODIN crc and does a bitwise | ||
1062 | * not on the result */ | ||
1063 | return ~crc32(0xFFFFFFFF, &fh->data[0], fh->size); | ||
1064 | } | ||
1065 | |||
1066 | /* | ||
1067 | * _nfs_display_fhandle - display an NFS file handle on the console | ||
1068 | * | ||
1069 | * @fh: file handle to display | ||
1070 | * @caption: display caption | ||
1071 | * | ||
1072 | * For debugging only. | ||
1073 | */ | ||
1074 | void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption) | ||
1075 | { | ||
1076 | unsigned short i; | ||
1077 | |||
1078 | if (fh == NULL || fh->size == 0) { | ||
1079 | printk(KERN_DEFAULT "%s at %p is empty\n", caption, fh); | ||
1080 | return; | ||
1081 | } | ||
1082 | |||
1083 | printk(KERN_DEFAULT "%s at %p is %u bytes, crc: 0x%08x:\n", | ||
1084 | caption, fh, fh->size, _nfs_display_fhandle_hash(fh)); | ||
1085 | for (i = 0; i < fh->size; i += 16) { | ||
1086 | __be32 *pos = (__be32 *)&fh->data[i]; | ||
1087 | |||
1088 | switch ((fh->size - i - 1) >> 2) { | ||
1089 | case 0: | ||
1090 | printk(KERN_DEFAULT " %08x\n", | ||
1091 | be32_to_cpup(pos)); | ||
1092 | break; | ||
1093 | case 1: | ||
1094 | printk(KERN_DEFAULT " %08x %08x\n", | ||
1095 | be32_to_cpup(pos), be32_to_cpup(pos + 1)); | ||
1096 | break; | ||
1097 | case 2: | ||
1098 | printk(KERN_DEFAULT " %08x %08x %08x\n", | ||
1099 | be32_to_cpup(pos), be32_to_cpup(pos + 1), | ||
1100 | be32_to_cpup(pos + 2)); | ||
1101 | break; | ||
1102 | default: | ||
1103 | printk(KERN_DEFAULT " %08x %08x %08x %08x\n", | ||
1104 | be32_to_cpup(pos), be32_to_cpup(pos + 1), | ||
1105 | be32_to_cpup(pos + 2), be32_to_cpup(pos + 3)); | ||
1106 | } | ||
1107 | } | ||
1108 | } | ||
1109 | #endif | ||
1110 | |||
1047 | /** | 1111 | /** |
1048 | * nfs_inode_attrs_need_update - check if the inode attributes need updating | 1112 | * nfs_inode_attrs_need_update - check if the inode attributes need updating |
1049 | * @inode - pointer to inode | 1113 | * @inode - pointer to inode |
@@ -1211,8 +1275,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1211 | unsigned long now = jiffies; | 1275 | unsigned long now = jiffies; |
1212 | unsigned long save_cache_validity; | 1276 | unsigned long save_cache_validity; |
1213 | 1277 | ||
1214 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1278 | dfprintk(VFS, "NFS: %s(%s/%ld fh_crc=0x%08x ct=%d info=0x%x)\n", |
1215 | __func__, inode->i_sb->s_id, inode->i_ino, | 1279 | __func__, inode->i_sb->s_id, inode->i_ino, |
1280 | nfs_display_fhandle_hash(NFS_FH(inode)), | ||
1216 | atomic_read(&inode->i_count), fattr->valid); | 1281 | atomic_read(&inode->i_count), fattr->valid); |
1217 | 1282 | ||
1218 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) | 1283 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) |
@@ -1406,7 +1471,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1406 | /* | 1471 | /* |
1407 | * Big trouble! The inode has become a different object. | 1472 | * Big trouble! The inode has become a different object. |
1408 | */ | 1473 | */ |
1409 | printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", | 1474 | printk(KERN_DEBUG "NFS: %s: inode %ld mode changed, %07o to %07o\n", |
1410 | __func__, inode->i_ino, inode->i_mode, fattr->mode); | 1475 | __func__, inode->i_ino, inode->i_mode, fattr->mode); |
1411 | out_err: | 1476 | out_err: |
1412 | /* | 1477 | /* |
@@ -1495,7 +1560,7 @@ static void init_once(void *foo) | |||
1495 | INIT_LIST_HEAD(&nfsi->open_files); | 1560 | INIT_LIST_HEAD(&nfsi->open_files); |
1496 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); | 1561 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); |
1497 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); | 1562 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); |
1498 | INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); | 1563 | INIT_LIST_HEAD(&nfsi->commit_list); |
1499 | nfsi->npages = 0; | 1564 | nfsi->npages = 0; |
1500 | nfsi->ncommit = 0; | 1565 | nfsi->ncommit = 0; |
1501 | atomic_set(&nfsi->silly_count, 1); | 1566 | atomic_set(&nfsi->silly_count, 1); |
@@ -1552,6 +1617,28 @@ static void nfsiod_stop(void) | |||
1552 | destroy_workqueue(wq); | 1617 | destroy_workqueue(wq); |
1553 | } | 1618 | } |
1554 | 1619 | ||
1620 | int nfs_net_id; | ||
1621 | EXPORT_SYMBOL_GPL(nfs_net_id); | ||
1622 | |||
1623 | static int nfs_net_init(struct net *net) | ||
1624 | { | ||
1625 | nfs_clients_init(net); | ||
1626 | return nfs_dns_resolver_cache_init(net); | ||
1627 | } | ||
1628 | |||
1629 | static void nfs_net_exit(struct net *net) | ||
1630 | { | ||
1631 | nfs_dns_resolver_cache_destroy(net); | ||
1632 | nfs_cleanup_cb_ident_idr(net); | ||
1633 | } | ||
1634 | |||
1635 | static struct pernet_operations nfs_net_ops = { | ||
1636 | .init = nfs_net_init, | ||
1637 | .exit = nfs_net_exit, | ||
1638 | .id = &nfs_net_id, | ||
1639 | .size = sizeof(struct nfs_net), | ||
1640 | }; | ||
1641 | |||
1555 | /* | 1642 | /* |
1556 | * Initialize NFS | 1643 | * Initialize NFS |
1557 | */ | 1644 | */ |
@@ -1561,10 +1648,14 @@ static int __init init_nfs_fs(void) | |||
1561 | 1648 | ||
1562 | err = nfs_idmap_init(); | 1649 | err = nfs_idmap_init(); |
1563 | if (err < 0) | 1650 | if (err < 0) |
1564 | goto out9; | 1651 | goto out10; |
1565 | 1652 | ||
1566 | err = nfs_dns_resolver_init(); | 1653 | err = nfs_dns_resolver_init(); |
1567 | if (err < 0) | 1654 | if (err < 0) |
1655 | goto out9; | ||
1656 | |||
1657 | err = register_pernet_subsys(&nfs_net_ops); | ||
1658 | if (err < 0) | ||
1568 | goto out8; | 1659 | goto out8; |
1569 | 1660 | ||
1570 | err = nfs_fscache_register(); | 1661 | err = nfs_fscache_register(); |
@@ -1600,14 +1691,14 @@ static int __init init_nfs_fs(void) | |||
1600 | goto out0; | 1691 | goto out0; |
1601 | 1692 | ||
1602 | #ifdef CONFIG_PROC_FS | 1693 | #ifdef CONFIG_PROC_FS |
1603 | rpc_proc_register(&nfs_rpcstat); | 1694 | rpc_proc_register(&init_net, &nfs_rpcstat); |
1604 | #endif | 1695 | #endif |
1605 | if ((err = register_nfs_fs()) != 0) | 1696 | if ((err = register_nfs_fs()) != 0) |
1606 | goto out; | 1697 | goto out; |
1607 | return 0; | 1698 | return 0; |
1608 | out: | 1699 | out: |
1609 | #ifdef CONFIG_PROC_FS | 1700 | #ifdef CONFIG_PROC_FS |
1610 | rpc_proc_unregister("nfs"); | 1701 | rpc_proc_unregister(&init_net, "nfs"); |
1611 | #endif | 1702 | #endif |
1612 | nfs_destroy_directcache(); | 1703 | nfs_destroy_directcache(); |
1613 | out0: | 1704 | out0: |
@@ -1625,10 +1716,12 @@ out5: | |||
1625 | out6: | 1716 | out6: |
1626 | nfs_fscache_unregister(); | 1717 | nfs_fscache_unregister(); |
1627 | out7: | 1718 | out7: |
1628 | nfs_dns_resolver_destroy(); | 1719 | unregister_pernet_subsys(&nfs_net_ops); |
1629 | out8: | 1720 | out8: |
1630 | nfs_idmap_quit(); | 1721 | nfs_dns_resolver_destroy(); |
1631 | out9: | 1722 | out9: |
1723 | nfs_idmap_quit(); | ||
1724 | out10: | ||
1632 | return err; | 1725 | return err; |
1633 | } | 1726 | } |
1634 | 1727 | ||
@@ -1640,12 +1733,12 @@ static void __exit exit_nfs_fs(void) | |||
1640 | nfs_destroy_inodecache(); | 1733 | nfs_destroy_inodecache(); |
1641 | nfs_destroy_nfspagecache(); | 1734 | nfs_destroy_nfspagecache(); |
1642 | nfs_fscache_unregister(); | 1735 | nfs_fscache_unregister(); |
1736 | unregister_pernet_subsys(&nfs_net_ops); | ||
1643 | nfs_dns_resolver_destroy(); | 1737 | nfs_dns_resolver_destroy(); |
1644 | nfs_idmap_quit(); | 1738 | nfs_idmap_quit(); |
1645 | #ifdef CONFIG_PROC_FS | 1739 | #ifdef CONFIG_PROC_FS |
1646 | rpc_proc_unregister("nfs"); | 1740 | rpc_proc_unregister(&init_net, "nfs"); |
1647 | #endif | 1741 | #endif |
1648 | nfs_cleanup_cb_ident_idr(); | ||
1649 | unregister_nfs_fs(); | 1742 | unregister_nfs_fs(); |
1650 | nfs_fs_proc_exit(); | 1743 | nfs_fs_proc_exit(); |
1651 | nfsiod_stop(); | 1744 | nfsiod_stop(); |