aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 12:19:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 12:19:15 -0400
commitbf97293eb878df3792d9de7213bd7b82135aea77 (patch)
tree16cb367bd78095b9eb8a54c800fcddfcccb618c7
parent16d70e15295953b19ecf59e943723a181782b856 (diff)
parentb1b3e136948a2bf4915326acb0d825d7d180753f (diff)
Merge tag 'nfs-for-3.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: - Fix NFSv4 recovery so that it doesn't recover lost locks in cases such as lease loss due to a network partition, where doing so may result in data corruption. Add a kernel parameter to control choice of legacy behaviour or not. - Performance improvements when 2 processes are writing to the same file. - Flush data to disk when an RPCSEC_GSS session timeout is imminent. - Implement NFSv4.1 SP4_MACH_CRED state protection to prevent other NFS clients from being able to manipulate our lease and file locking state. - Allow sharing of RPCSEC_GSS caches between different rpc clients. - Fix the broken NFSv4 security auto-negotiation between client and server. - Fix rmdir() to wait for outstanding sillyrename unlinks to complete - Add a tracepoint framework for debugging NFSv4 state recovery issues. - Add tracing to the generic NFS layer. - Add tracing for the SUNRPC socket connection state. - Clean up the rpc_pipefs mount/umount event management. - Merge more patches from Chuck in preparation for NFSv4 migration support" * tag 'nfs-for-3.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (107 commits) NFSv4: use mach cred for SECINFO_NO_NAME w/ integrity NFS: nfs_compare_super shouldn't check the auth flavour unless 'sec=' was set NFSv4: Allow security autonegotiation for submounts NFSv4: Disallow security negotiation for lookups when 'sec=' is specified NFSv4: Fix security auto-negotiation NFS: Clean up nfs_parse_security_flavors() NFS: Clean up the auth flavour array mess NFSv4.1 Use MDS auth flavor for data server connection NFS: Don't check lock owner compatability unless file is locked (part 2) NFS: Don't check lock owner compatibility in writes unless file is locked nfs4: Map NFS4ERR_WRONG_CRED to EPERM nfs4.1: Add SP4_MACH_CRED write and commit support nfs4.1: Add SP4_MACH_CRED stateid support nfs4.1: Add SP4_MACH_CRED secinfo support nfs4.1: Add SP4_MACH_CRED cleanup support nfs4.1: Add state protection handler nfs4.1: Minimal SP4_MACH_CRED implementation SUNRPC: Replace pointer values with task->tk_pid and rpc_clnt->cl_clid SUNRPC: Add an identifier for struct rpc_clnt SUNRPC: Ensure rpc_task->tk_pid is available for tracepoints ...
-rw-r--r--Documentation/kernel-parameters.txt12
-rw-r--r--fs/nfs/Makefile9
-rw-r--r--fs/nfs/callback_proc.c11
-rw-r--r--fs/nfs/client.c6
-rw-r--r--fs/nfs/delegation.c3
-rw-r--r--fs/nfs/dir.c81
-rw-r--r--fs/nfs/file.c20
-rw-r--r--fs/nfs/idmap.c195
-rw-r--r--fs/nfs/inode.c32
-rw-r--r--fs/nfs/internal.h31
-rw-r--r--fs/nfs/nfs3proc.c10
-rw-r--r--fs/nfs/nfs4_fs.h98
-rw-r--r--fs/nfs/nfs4client.c240
-rw-r--r--fs/nfs/nfs4filelayout.c39
-rw-r--r--fs/nfs/nfs4getroot.c4
-rw-r--r--fs/nfs/nfs4namespace.c21
-rw-r--r--fs/nfs/nfs4proc.c793
-rw-r--r--fs/nfs/nfs4session.c86
-rw-r--r--fs/nfs/nfs4session.h37
-rw-r--r--fs/nfs/nfs4state.c174
-rw-r--r--fs/nfs/nfs4super.c2
-rw-r--r--fs/nfs/nfs4trace.c17
-rw-r--r--fs/nfs/nfs4trace.h1148
-rw-r--r--fs/nfs/nfs4xdr.c214
-rw-r--r--fs/nfs/nfstrace.c9
-rw-r--r--fs/nfs/nfstrace.h729
-rw-r--r--fs/nfs/pagelist.c22
-rw-r--r--fs/nfs/pnfs.c3
-rw-r--r--fs/nfs/proc.c6
-rw-r--r--fs/nfs/read.c7
-rw-r--r--fs/nfs/super.c99
-rw-r--r--fs/nfs/unlink.c38
-rw-r--r--fs/nfs/write.c57
-rw-r--r--include/linux/nfs_fs.h1
-rw-r--r--include/linux/nfs_fs_sb.h13
-rw-r--r--include/linux/nfs_xdr.h25
-rw-r--r--include/linux/sunrpc/auth.h28
-rw-r--r--include/linux/sunrpc/clnt.h6
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h39
-rw-r--r--include/linux/sunrpc/sched.h2
-rw-r--r--include/trace/events/sunrpc.h181
-rw-r--r--net/sunrpc/auth.c27
-rw-r--r--net/sunrpc/auth_generic.c82
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c442
-rw-r--r--net/sunrpc/auth_null.c6
-rw-r--r--net/sunrpc/auth_unix.c6
-rw-r--r--net/sunrpc/clnt.c157
-rw-r--r--net/sunrpc/rpc_pipe.c193
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/stats.c2
-rw-r--r--net/sunrpc/xprtsock.c13
51 files changed, 4504 insertions, 974 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 479eeaf44024..1a036cd972fb 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1898,6 +1898,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1898 will be sent. 1898 will be sent.
1899 The default is to send the implementation identification 1899 The default is to send the implementation identification
1900 information. 1900 information.
1901
1902 nfs.recover_lost_locks =
1903 [NFSv4] Attempt to recover locks that were lost due
1904 to a lease timeout on the server. Please note that
1905 doing this risks data corruption, since there are
1906 no guarantees that the file will remain unchanged
1907 after the locks are lost.
1908 If you want to enable the kernel legacy behaviour of
1909 attempting to recover these locks, then set this
1910 parameter to '1'.
1911 The default parameter value of '0' causes the kernel
1912 not to attempt recovery of lost locks.
1901 1913
1902 nfsd.nfs4_disable_idmapping= 1914 nfsd.nfs4_disable_idmapping=
1903 [NFSv4] When set to the default of '1', the NFSv4 1915 [NFSv4] When set to the default of '1', the NFSv4
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index e0bb048e9576..03192a66c143 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -4,9 +4,10 @@
4 4
5obj-$(CONFIG_NFS_FS) += nfs.o 5obj-$(CONFIG_NFS_FS) += nfs.o
6 6
7CFLAGS_nfstrace.o += -I$(src)
7nfs-y := client.o dir.o file.o getroot.o inode.o super.o \ 8nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
8 direct.o pagelist.o read.o symlink.o unlink.o \ 9 direct.o pagelist.o read.o symlink.o unlink.o \
9 write.o namespace.o mount_clnt.o 10 write.o namespace.o mount_clnt.o nfstrace.o
10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o 11nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
11nfs-$(CONFIG_SYSCTL) += sysctl.o 12nfs-$(CONFIG_SYSCTL) += sysctl.o
12nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o 13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
@@ -19,12 +20,14 @@ nfsv3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
19nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o 20nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
20 21
21obj-$(CONFIG_NFS_V4) += nfsv4.o 22obj-$(CONFIG_NFS_V4) += nfsv4.o
23CFLAGS_nfs4trace.o += -I$(src)
22nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ 24nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
23 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ 25 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
24 nfs4namespace.o nfs4getroot.o nfs4client.o dns_resolve.o 26 nfs4namespace.o nfs4getroot.o nfs4client.o nfs4session.o \
27 dns_resolve.o nfs4trace.o
25nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o 28nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
26nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o 29nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
27nfsv4-$(CONFIG_NFS_V4_1) += nfs4session.o pnfs.o pnfs_dev.o 30nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
28 31
29obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o 32obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
30nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o 33nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index e6ebc4c38c81..ae2e87b95453 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -15,6 +15,7 @@
15#include "internal.h" 15#include "internal.h"
16#include "pnfs.h" 16#include "pnfs.h"
17#include "nfs4session.h" 17#include "nfs4session.h"
18#include "nfs4trace.h"
18 19
19#ifdef NFS_DEBUG 20#ifdef NFS_DEBUG
20#define NFSDBG_FACILITY NFSDBG_CALLBACK 21#define NFSDBG_FACILITY NFSDBG_CALLBACK
@@ -93,6 +94,7 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy,
93 default: 94 default:
94 res = htonl(NFS4ERR_RESOURCE); 95 res = htonl(NFS4ERR_RESOURCE);
95 } 96 }
97 trace_nfs4_recall_delegation(inode, -ntohl(res));
96 iput(inode); 98 iput(inode);
97out: 99out:
98 dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); 100 dprintk("%s: exit with status = %d\n", __func__, ntohl(res));
@@ -301,14 +303,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
301{ 303{
302 struct nfs4_slot *slot; 304 struct nfs4_slot *slot;
303 305
304 dprintk("%s enter. slotid %d seqid %d\n", 306 dprintk("%s enter. slotid %u seqid %u\n",
305 __func__, args->csa_slotid, args->csa_sequenceid); 307 __func__, args->csa_slotid, args->csa_sequenceid);
306 308
307 if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS) 309 if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS)
308 return htonl(NFS4ERR_BADSLOT); 310 return htonl(NFS4ERR_BADSLOT);
309 311
310 slot = tbl->slots + args->csa_slotid; 312 slot = tbl->slots + args->csa_slotid;
311 dprintk("%s slot table seqid: %d\n", __func__, slot->seq_nr); 313 dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr);
312 314
313 /* Normal */ 315 /* Normal */
314 if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { 316 if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
@@ -318,7 +320,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
318 320
319 /* Replay */ 321 /* Replay */
320 if (args->csa_sequenceid == slot->seq_nr) { 322 if (args->csa_sequenceid == slot->seq_nr) {
321 dprintk("%s seqid %d is a replay\n", 323 dprintk("%s seqid %u is a replay\n",
322 __func__, args->csa_sequenceid); 324 __func__, args->csa_sequenceid);
323 /* Signal process_op to set this error on next op */ 325 /* Signal process_op to set this error on next op */
324 if (args->csa_cachethis == 0) 326 if (args->csa_cachethis == 0)
@@ -462,6 +464,7 @@ out:
462 } else 464 } else
463 res->csr_status = status; 465 res->csr_status = status;
464 466
467 trace_nfs4_cb_sequence(args, res, status);
465 dprintk("%s: exit with status = %d res->csr_status %d\n", __func__, 468 dprintk("%s: exit with status = %d res->csr_status %d\n", __func__,
466 ntohl(status), ntohl(res->csr_status)); 469 ntohl(status), ntohl(res->csr_status));
467 return status; 470 return status;
@@ -518,7 +521,7 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,
518 if (!cps->clp) /* set in cb_sequence */ 521 if (!cps->clp) /* set in cb_sequence */
519 goto out; 522 goto out;
520 523
521 dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target highest slotid %d\n", 524 dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target highest slotid %u\n",
522 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR), 525 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR),
523 args->crsa_target_highest_slotid); 526 args->crsa_target_highest_slotid);
524 527
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 340b1eff0267..2dceee4db076 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -501,8 +501,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
501 &nn->nfs_client_list); 501 &nn->nfs_client_list);
502 spin_unlock(&nn->nfs_client_lock); 502 spin_unlock(&nn->nfs_client_lock);
503 new->cl_flags = cl_init->init_flags; 503 new->cl_flags = cl_init->init_flags;
504 return rpc_ops->init_client(new, timeparms, ip_addr, 504 return rpc_ops->init_client(new, timeparms, ip_addr);
505 authflavour);
506 } 505 }
507 506
508 spin_unlock(&nn->nfs_client_lock); 507 spin_unlock(&nn->nfs_client_lock);
@@ -694,13 +693,12 @@ EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
694 * @clp: nfs_client to initialise 693 * @clp: nfs_client to initialise
695 * @timeparms: timeout parameters for underlying RPC transport 694 * @timeparms: timeout parameters for underlying RPC transport
696 * @ip_addr: IP presentation address (not used) 695 * @ip_addr: IP presentation address (not used)
697 * @authflavor: authentication flavor for underlying RPC transport
698 * 696 *
699 * Returns pointer to an NFS client, or an ERR_PTR value. 697 * Returns pointer to an NFS client, or an ERR_PTR value.
700 */ 698 */
701struct nfs_client *nfs_init_client(struct nfs_client *clp, 699struct nfs_client *nfs_init_client(struct nfs_client *clp,
702 const struct rpc_timeout *timeparms, 700 const struct rpc_timeout *timeparms,
703 const char *ip_addr, rpc_authflavor_t authflavour) 701 const char *ip_addr)
704{ 702{
705 int error; 703 int error;
706 704
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 7ec4814e298d..ef792f29f831 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -20,6 +20,7 @@
20#include "nfs4_fs.h" 20#include "nfs4_fs.h"
21#include "delegation.h" 21#include "delegation.h"
22#include "internal.h" 22#include "internal.h"
23#include "nfs4trace.h"
23 24
24static void nfs_free_delegation(struct nfs_delegation *delegation) 25static void nfs_free_delegation(struct nfs_delegation *delegation)
25{ 26{
@@ -160,6 +161,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
160 spin_unlock(&delegation->lock); 161 spin_unlock(&delegation->lock);
161 put_rpccred(oldcred); 162 put_rpccred(oldcred);
162 rcu_read_unlock(); 163 rcu_read_unlock();
164 trace_nfs4_reclaim_delegation(inode, res->delegation_type);
163 } else { 165 } else {
164 /* We appear to have raced with a delegation return. */ 166 /* We appear to have raced with a delegation return. */
165 spin_unlock(&delegation->lock); 167 spin_unlock(&delegation->lock);
@@ -344,6 +346,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
344 spin_lock(&inode->i_lock); 346 spin_lock(&inode->i_lock);
345 nfsi->cache_validity |= NFS_INO_REVAL_FORCED; 347 nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
346 spin_unlock(&inode->i_lock); 348 spin_unlock(&inode->i_lock);
349 trace_nfs4_set_delegation(inode, res->delegation_type);
347 350
348out: 351out:
349 spin_unlock(&clp->cl_lock); 352 spin_unlock(&clp->cl_lock);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7468735d299e..e79bc6ce828e 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -43,6 +43,8 @@
43#include "internal.h" 43#include "internal.h"
44#include "fscache.h" 44#include "fscache.h"
45 45
46#include "nfstrace.h"
47
46/* #define NFS_DEBUG_VERBOSE 1 */ 48/* #define NFS_DEBUG_VERBOSE 1 */
47 49
48static int nfs_opendir(struct inode *, struct file *); 50static int nfs_opendir(struct inode *, struct file *);
@@ -1100,7 +1102,9 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1100 if (IS_ERR(label)) 1102 if (IS_ERR(label))
1101 goto out_error; 1103 goto out_error;
1102 1104
1105 trace_nfs_lookup_revalidate_enter(dir, dentry, flags);
1103 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1106 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1107 trace_nfs_lookup_revalidate_exit(dir, dentry, flags, error);
1104 if (error) 1108 if (error)
1105 goto out_bad; 1109 goto out_bad;
1106 if (nfs_compare_fh(NFS_FH(inode), fhandle)) 1110 if (nfs_compare_fh(NFS_FH(inode), fhandle))
@@ -1312,6 +1316,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1312 1316
1313 parent = dentry->d_parent; 1317 parent = dentry->d_parent;
1314 /* Protect against concurrent sillydeletes */ 1318 /* Protect against concurrent sillydeletes */
1319 trace_nfs_lookup_enter(dir, dentry, flags);
1315 nfs_block_sillyrename(parent); 1320 nfs_block_sillyrename(parent);
1316 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1321 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1317 if (error == -ENOENT) 1322 if (error == -ENOENT)
@@ -1338,6 +1343,7 @@ no_entry:
1338 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1343 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1339out_unblock_sillyrename: 1344out_unblock_sillyrename:
1340 nfs_unblock_sillyrename(parent); 1345 nfs_unblock_sillyrename(parent);
1346 trace_nfs_lookup_exit(dir, dentry, flags, error);
1341 nfs4_label_free(label); 1347 nfs4_label_free(label);
1342out: 1348out:
1343 nfs_free_fattr(fattr); 1349 nfs_free_fattr(fattr);
@@ -1392,7 +1398,6 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
1392 nfs_file_set_open_context(file, ctx); 1398 nfs_file_set_open_context(file, ctx);
1393 1399
1394out: 1400out:
1395 put_nfs_open_context(ctx);
1396 return err; 1401 return err;
1397} 1402}
1398 1403
@@ -1404,6 +1409,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1404 struct dentry *res; 1409 struct dentry *res;
1405 struct iattr attr = { .ia_valid = ATTR_OPEN }; 1410 struct iattr attr = { .ia_valid = ATTR_OPEN };
1406 struct inode *inode; 1411 struct inode *inode;
1412 unsigned int lookup_flags = 0;
1407 int err; 1413 int err;
1408 1414
1409 /* Expect a negative dentry */ 1415 /* Expect a negative dentry */
@@ -1412,6 +1418,10 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1412 dfprintk(VFS, "NFS: atomic_open(%s/%ld), %s\n", 1418 dfprintk(VFS, "NFS: atomic_open(%s/%ld), %s\n",
1413 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1419 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
1414 1420
1421 err = nfs_check_flags(open_flags);
1422 if (err)
1423 return err;
1424
1415 /* NFS only supports OPEN on regular files */ 1425 /* NFS only supports OPEN on regular files */
1416 if ((open_flags & O_DIRECTORY)) { 1426 if ((open_flags & O_DIRECTORY)) {
1417 if (!d_unhashed(dentry)) { 1427 if (!d_unhashed(dentry)) {
@@ -1422,6 +1432,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1422 */ 1432 */
1423 return -ENOENT; 1433 return -ENOENT;
1424 } 1434 }
1435 lookup_flags = LOOKUP_OPEN|LOOKUP_DIRECTORY;
1425 goto no_open; 1436 goto no_open;
1426 } 1437 }
1427 1438
@@ -1442,12 +1453,14 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1442 if (IS_ERR(ctx)) 1453 if (IS_ERR(ctx))
1443 goto out; 1454 goto out;
1444 1455
1456 trace_nfs_atomic_open_enter(dir, ctx, open_flags);
1445 nfs_block_sillyrename(dentry->d_parent); 1457 nfs_block_sillyrename(dentry->d_parent);
1446 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); 1458 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
1447 nfs_unblock_sillyrename(dentry->d_parent); 1459 nfs_unblock_sillyrename(dentry->d_parent);
1448 if (IS_ERR(inode)) { 1460 if (IS_ERR(inode)) {
1449 put_nfs_open_context(ctx);
1450 err = PTR_ERR(inode); 1461 err = PTR_ERR(inode);
1462 trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
1463 put_nfs_open_context(ctx);
1451 switch (err) { 1464 switch (err) {
1452 case -ENOENT: 1465 case -ENOENT:
1453 d_drop(dentry); 1466 d_drop(dentry);
@@ -1468,11 +1481,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1468 } 1481 }
1469 1482
1470 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened); 1483 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened);
1484 trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
1485 put_nfs_open_context(ctx);
1471out: 1486out:
1472 return err; 1487 return err;
1473 1488
1474no_open: 1489no_open:
1475 res = nfs_lookup(dir, dentry, 0); 1490 res = nfs_lookup(dir, dentry, lookup_flags);
1476 err = PTR_ERR(res); 1491 err = PTR_ERR(res);
1477 if (IS_ERR(res)) 1492 if (IS_ERR(res))
1478 goto out; 1493 goto out;
@@ -1596,7 +1611,9 @@ int nfs_create(struct inode *dir, struct dentry *dentry,
1596 attr.ia_mode = mode; 1611 attr.ia_mode = mode;
1597 attr.ia_valid = ATTR_MODE; 1612 attr.ia_valid = ATTR_MODE;
1598 1613
1614 trace_nfs_create_enter(dir, dentry, open_flags);
1599 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags); 1615 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
1616 trace_nfs_create_exit(dir, dentry, open_flags, error);
1600 if (error != 0) 1617 if (error != 0)
1601 goto out_err; 1618 goto out_err;
1602 return 0; 1619 return 0;
@@ -1624,7 +1641,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
1624 attr.ia_mode = mode; 1641 attr.ia_mode = mode;
1625 attr.ia_valid = ATTR_MODE; 1642 attr.ia_valid = ATTR_MODE;
1626 1643
1644 trace_nfs_mknod_enter(dir, dentry);
1627 status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); 1645 status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
1646 trace_nfs_mknod_exit(dir, dentry, status);
1628 if (status != 0) 1647 if (status != 0)
1629 goto out_err; 1648 goto out_err;
1630 return 0; 1649 return 0;
@@ -1648,7 +1667,9 @@ int nfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1648 attr.ia_valid = ATTR_MODE; 1667 attr.ia_valid = ATTR_MODE;
1649 attr.ia_mode = mode | S_IFDIR; 1668 attr.ia_mode = mode | S_IFDIR;
1650 1669
1670 trace_nfs_mkdir_enter(dir, dentry);
1651 error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); 1671 error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
1672 trace_nfs_mkdir_exit(dir, dentry, error);
1652 if (error != 0) 1673 if (error != 0)
1653 goto out_err; 1674 goto out_err;
1654 return 0; 1675 return 0;
@@ -1671,12 +1692,21 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1671 dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", 1692 dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
1672 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1693 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
1673 1694
1674 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); 1695 trace_nfs_rmdir_enter(dir, dentry);
1675 /* Ensure the VFS deletes this inode */ 1696 if (dentry->d_inode) {
1676 if (error == 0 && dentry->d_inode != NULL) 1697 nfs_wait_on_sillyrename(dentry);
1677 clear_nlink(dentry->d_inode); 1698 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1678 else if (error == -ENOENT) 1699 /* Ensure the VFS deletes this inode */
1679 nfs_dentry_handle_enoent(dentry); 1700 switch (error) {
1701 case 0:
1702 clear_nlink(dentry->d_inode);
1703 break;
1704 case -ENOENT:
1705 nfs_dentry_handle_enoent(dentry);
1706 }
1707 } else
1708 error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
1709 trace_nfs_rmdir_exit(dir, dentry, error);
1680 1710
1681 return error; 1711 return error;
1682} 1712}
@@ -1704,6 +1734,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1704 goto out; 1734 goto out;
1705 } 1735 }
1706 1736
1737 trace_nfs_remove_enter(dir, dentry);
1707 if (inode != NULL) { 1738 if (inode != NULL) {
1708 NFS_PROTO(inode)->return_delegation(inode); 1739 NFS_PROTO(inode)->return_delegation(inode);
1709 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1740 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
@@ -1713,6 +1744,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1713 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1744 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1714 if (error == -ENOENT) 1745 if (error == -ENOENT)
1715 nfs_dentry_handle_enoent(dentry); 1746 nfs_dentry_handle_enoent(dentry);
1747 trace_nfs_remove_exit(dir, dentry, error);
1716out: 1748out:
1717 return error; 1749 return error;
1718} 1750}
@@ -1730,13 +1762,14 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
1730 dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, 1762 dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id,
1731 dir->i_ino, dentry->d_name.name); 1763 dir->i_ino, dentry->d_name.name);
1732 1764
1765 trace_nfs_unlink_enter(dir, dentry);
1733 spin_lock(&dentry->d_lock); 1766 spin_lock(&dentry->d_lock);
1734 if (d_count(dentry) > 1) { 1767 if (d_count(dentry) > 1) {
1735 spin_unlock(&dentry->d_lock); 1768 spin_unlock(&dentry->d_lock);
1736 /* Start asynchronous writeout of the inode */ 1769 /* Start asynchronous writeout of the inode */
1737 write_inode_now(dentry->d_inode, 0); 1770 write_inode_now(dentry->d_inode, 0);
1738 error = nfs_sillyrename(dir, dentry); 1771 error = nfs_sillyrename(dir, dentry);
1739 return error; 1772 goto out;
1740 } 1773 }
1741 if (!d_unhashed(dentry)) { 1774 if (!d_unhashed(dentry)) {
1742 __d_drop(dentry); 1775 __d_drop(dentry);
@@ -1748,6 +1781,8 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
1748 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1781 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1749 } else if (need_rehash) 1782 } else if (need_rehash)
1750 d_rehash(dentry); 1783 d_rehash(dentry);
1784out:
1785 trace_nfs_unlink_exit(dir, dentry, error);
1751 return error; 1786 return error;
1752} 1787}
1753EXPORT_SYMBOL_GPL(nfs_unlink); 1788EXPORT_SYMBOL_GPL(nfs_unlink);
@@ -1794,7 +1829,9 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1794 memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); 1829 memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
1795 kunmap_atomic(kaddr); 1830 kunmap_atomic(kaddr);
1796 1831
1832 trace_nfs_symlink_enter(dir, dentry);
1797 error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); 1833 error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
1834 trace_nfs_symlink_exit(dir, dentry, error);
1798 if (error != 0) { 1835 if (error != 0) {
1799 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", 1836 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n",
1800 dir->i_sb->s_id, dir->i_ino, 1837 dir->i_sb->s_id, dir->i_ino,
@@ -1829,6 +1866,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1829 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1866 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1830 dentry->d_parent->d_name.name, dentry->d_name.name); 1867 dentry->d_parent->d_name.name, dentry->d_name.name);
1831 1868
1869 trace_nfs_link_enter(inode, dir, dentry);
1832 NFS_PROTO(inode)->return_delegation(inode); 1870 NFS_PROTO(inode)->return_delegation(inode);
1833 1871
1834 d_drop(dentry); 1872 d_drop(dentry);
@@ -1837,6 +1875,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1837 ihold(inode); 1875 ihold(inode);
1838 d_add(dentry, inode); 1876 d_add(dentry, inode);
1839 } 1877 }
1878 trace_nfs_link_exit(inode, dir, dentry, error);
1840 return error; 1879 return error;
1841} 1880}
1842EXPORT_SYMBOL_GPL(nfs_link); 1881EXPORT_SYMBOL_GPL(nfs_link);
@@ -1878,6 +1917,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1878 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, 1917 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
1879 d_count(new_dentry)); 1918 d_count(new_dentry));
1880 1919
1920 trace_nfs_rename_enter(old_dir, old_dentry, new_dir, new_dentry);
1881 /* 1921 /*
1882 * For non-directories, check whether the target is busy and if so, 1922 * For non-directories, check whether the target is busy and if so,
1883 * make a copy of the dentry and then do a silly-rename. If the 1923 * make a copy of the dentry and then do a silly-rename. If the
@@ -1924,6 +1964,8 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1924out: 1964out:
1925 if (rehash) 1965 if (rehash)
1926 d_rehash(rehash); 1966 d_rehash(rehash);
1967 trace_nfs_rename_exit(old_dir, old_dentry,
1968 new_dir, new_dentry, error);
1927 if (!error) { 1969 if (!error) {
1928 if (new_inode != NULL) 1970 if (new_inode != NULL)
1929 nfs_drop_nlink(new_inode); 1971 nfs_drop_nlink(new_inode);
@@ -2173,9 +2215,11 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
2173 struct nfs_access_entry cache; 2215 struct nfs_access_entry cache;
2174 int status; 2216 int status;
2175 2217
2218 trace_nfs_access_enter(inode);
2219
2176 status = nfs_access_get_cached(inode, cred, &cache); 2220 status = nfs_access_get_cached(inode, cred, &cache);
2177 if (status == 0) 2221 if (status == 0)
2178 goto out; 2222 goto out_cached;
2179 2223
2180 /* Be clever: ask server to check for all possible rights */ 2224 /* Be clever: ask server to check for all possible rights */
2181 cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ; 2225 cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
@@ -2188,13 +2232,15 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
2188 if (!S_ISDIR(inode->i_mode)) 2232 if (!S_ISDIR(inode->i_mode))
2189 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); 2233 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
2190 } 2234 }
2191 return status; 2235 goto out;
2192 } 2236 }
2193 nfs_access_add_cache(inode, &cache); 2237 nfs_access_add_cache(inode, &cache);
2238out_cached:
2239 if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
2240 status = -EACCES;
2194out: 2241out:
2195 if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) 2242 trace_nfs_access_exit(inode, status);
2196 return 0; 2243 return status;
2197 return -EACCES;
2198} 2244}
2199 2245
2200static int nfs_open_permission_mask(int openflags) 2246static int nfs_open_permission_mask(int openflags)
@@ -2240,11 +2286,6 @@ int nfs_permission(struct inode *inode, int mask)
2240 case S_IFLNK: 2286 case S_IFLNK:
2241 goto out; 2287 goto out;
2242 case S_IFREG: 2288 case S_IFREG:
2243 /* NFSv4 has atomic_open... */
2244 if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
2245 && (mask & MAY_OPEN)
2246 && !(mask & MAY_EXEC))
2247 goto out;
2248 break; 2289 break;
2249 case S_IFDIR: 2290 case S_IFDIR:
2250 /* 2291 /*
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 94e94bd11aae..1e6bfdbc1aff 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -37,6 +37,8 @@
37#include "iostat.h" 37#include "iostat.h"
38#include "fscache.h" 38#include "fscache.h"
39 39
40#include "nfstrace.h"
41
40#define NFSDBG_FACILITY NFSDBG_FILE 42#define NFSDBG_FACILITY NFSDBG_FILE
41 43
42static const struct vm_operations_struct nfs_file_vm_ops; 44static const struct vm_operations_struct nfs_file_vm_ops;
@@ -294,6 +296,8 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
294 int ret; 296 int ret;
295 struct inode *inode = file_inode(file); 297 struct inode *inode = file_inode(file);
296 298
299 trace_nfs_fsync_enter(inode);
300
297 do { 301 do {
298 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 302 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
299 if (ret != 0) 303 if (ret != 0)
@@ -310,6 +314,7 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
310 end = LLONG_MAX; 314 end = LLONG_MAX;
311 } while (ret == -EAGAIN); 315 } while (ret == -EAGAIN);
312 316
317 trace_nfs_fsync_exit(inode, ret);
313 return ret; 318 return ret;
314} 319}
315 320
@@ -406,6 +411,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
406 struct page *page, void *fsdata) 411 struct page *page, void *fsdata)
407{ 412{
408 unsigned offset = pos & (PAGE_CACHE_SIZE - 1); 413 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
414 struct nfs_open_context *ctx = nfs_file_open_context(file);
409 int status; 415 int status;
410 416
411 dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n", 417 dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n",
@@ -441,6 +447,13 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
441 if (status < 0) 447 if (status < 0)
442 return status; 448 return status;
443 NFS_I(mapping->host)->write_io += copied; 449 NFS_I(mapping->host)->write_io += copied;
450
451 if (nfs_ctx_key_to_expire(ctx)) {
452 status = nfs_wb_all(mapping->host);
453 if (status < 0)
454 return status;
455 }
456
444 return copied; 457 return copied;
445} 458}
446 459
@@ -637,7 +650,8 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
637 if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC)) 650 if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC))
638 return 1; 651 return 1;
639 ctx = nfs_file_open_context(filp); 652 ctx = nfs_file_open_context(filp);
640 if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) 653 if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags) ||
654 nfs_ctx_key_to_expire(ctx))
641 return 1; 655 return 1;
642 return 0; 656 return 0;
643} 657}
@@ -651,6 +665,10 @@ ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
651 ssize_t result; 665 ssize_t result;
652 size_t count = iov_length(iov, nr_segs); 666 size_t count = iov_length(iov, nr_segs);
653 667
668 result = nfs_key_timeout_notify(iocb->ki_filp, inode);
669 if (result)
670 return result;
671
654 if (iocb->ki_filp->f_flags & O_DIRECT) 672 if (iocb->ki_filp->f_flags & O_DIRECT)
655 return nfs_file_direct_write(iocb, iov, nr_segs, pos, true); 673 return nfs_file_direct_write(iocb, iov, nr_segs, pos, true);
656 674
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index c2c4163d5683..567983d2c0eb 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -49,6 +49,7 @@
49 49
50#include "internal.h" 50#include "internal.h"
51#include "netns.h" 51#include "netns.h"
52#include "nfs4trace.h"
52 53
53#define NFS_UINT_MAXLEN 11 54#define NFS_UINT_MAXLEN 11
54 55
@@ -63,6 +64,7 @@ struct idmap_legacy_upcalldata {
63}; 64};
64 65
65struct idmap { 66struct idmap {
67 struct rpc_pipe_dir_object idmap_pdo;
66 struct rpc_pipe *idmap_pipe; 68 struct rpc_pipe *idmap_pipe;
67 struct idmap_legacy_upcalldata *idmap_upcall_data; 69 struct idmap_legacy_upcalldata *idmap_upcall_data;
68 struct mutex idmap_mutex; 70 struct mutex idmap_mutex;
@@ -310,7 +312,7 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
310 if (ret < 0) 312 if (ret < 0)
311 goto out_up; 313 goto out_up;
312 314
313 payload = rcu_dereference(rkey->payload.data); 315 payload = rcu_dereference(rkey->payload.rcudata);
314 if (IS_ERR_OR_NULL(payload)) { 316 if (IS_ERR_OR_NULL(payload)) {
315 ret = PTR_ERR(payload); 317 ret = PTR_ERR(payload);
316 goto out_up; 318 goto out_up;
@@ -401,16 +403,23 @@ static struct key_type key_type_id_resolver_legacy = {
401 .request_key = nfs_idmap_legacy_upcall, 403 .request_key = nfs_idmap_legacy_upcall,
402}; 404};
403 405
404static void __nfs_idmap_unregister(struct rpc_pipe *pipe) 406static void nfs_idmap_pipe_destroy(struct dentry *dir,
407 struct rpc_pipe_dir_object *pdo)
405{ 408{
406 if (pipe->dentry) 409 struct idmap *idmap = pdo->pdo_data;
410 struct rpc_pipe *pipe = idmap->idmap_pipe;
411
412 if (pipe->dentry) {
407 rpc_unlink(pipe->dentry); 413 rpc_unlink(pipe->dentry);
414 pipe->dentry = NULL;
415 }
408} 416}
409 417
410static int __nfs_idmap_register(struct dentry *dir, 418static int nfs_idmap_pipe_create(struct dentry *dir,
411 struct idmap *idmap, 419 struct rpc_pipe_dir_object *pdo)
412 struct rpc_pipe *pipe)
413{ 420{
421 struct idmap *idmap = pdo->pdo_data;
422 struct rpc_pipe *pipe = idmap->idmap_pipe;
414 struct dentry *dentry; 423 struct dentry *dentry;
415 424
416 dentry = rpc_mkpipe_dentry(dir, "idmap", idmap, pipe); 425 dentry = rpc_mkpipe_dentry(dir, "idmap", idmap, pipe);
@@ -420,36 +429,10 @@ static int __nfs_idmap_register(struct dentry *dir,
420 return 0; 429 return 0;
421} 430}
422 431
423static void nfs_idmap_unregister(struct nfs_client *clp, 432static const struct rpc_pipe_dir_object_ops nfs_idmap_pipe_dir_object_ops = {
424 struct rpc_pipe *pipe) 433 .create = nfs_idmap_pipe_create,
425{ 434 .destroy = nfs_idmap_pipe_destroy,
426 struct net *net = clp->cl_net; 435};
427 struct super_block *pipefs_sb;
428
429 pipefs_sb = rpc_get_sb_net(net);
430 if (pipefs_sb) {
431 __nfs_idmap_unregister(pipe);
432 rpc_put_sb_net(net);
433 }
434}
435
436static int nfs_idmap_register(struct nfs_client *clp,
437 struct idmap *idmap,
438 struct rpc_pipe *pipe)
439{
440 struct net *net = clp->cl_net;
441 struct super_block *pipefs_sb;
442 int err = 0;
443
444 pipefs_sb = rpc_get_sb_net(net);
445 if (pipefs_sb) {
446 if (clp->cl_rpcclient->cl_dentry)
447 err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry,
448 idmap, pipe);
449 rpc_put_sb_net(net);
450 }
451 return err;
452}
453 436
454int 437int
455nfs_idmap_new(struct nfs_client *clp) 438nfs_idmap_new(struct nfs_client *clp)
@@ -462,23 +445,31 @@ nfs_idmap_new(struct nfs_client *clp)
462 if (idmap == NULL) 445 if (idmap == NULL)
463 return -ENOMEM; 446 return -ENOMEM;
464 447
448 rpc_init_pipe_dir_object(&idmap->idmap_pdo,
449 &nfs_idmap_pipe_dir_object_ops,
450 idmap);
451
465 pipe = rpc_mkpipe_data(&idmap_upcall_ops, 0); 452 pipe = rpc_mkpipe_data(&idmap_upcall_ops, 0);
466 if (IS_ERR(pipe)) { 453 if (IS_ERR(pipe)) {
467 error = PTR_ERR(pipe); 454 error = PTR_ERR(pipe);
468 kfree(idmap); 455 goto err;
469 return error;
470 }
471 error = nfs_idmap_register(clp, idmap, pipe);
472 if (error) {
473 rpc_destroy_pipe_data(pipe);
474 kfree(idmap);
475 return error;
476 } 456 }
477 idmap->idmap_pipe = pipe; 457 idmap->idmap_pipe = pipe;
478 mutex_init(&idmap->idmap_mutex); 458 mutex_init(&idmap->idmap_mutex);
479 459
460 error = rpc_add_pipe_dir_object(clp->cl_net,
461 &clp->cl_rpcclient->cl_pipedir_objects,
462 &idmap->idmap_pdo);
463 if (error)
464 goto err_destroy_pipe;
465
480 clp->cl_idmap = idmap; 466 clp->cl_idmap = idmap;
481 return 0; 467 return 0;
468err_destroy_pipe:
469 rpc_destroy_pipe_data(idmap->idmap_pipe);
470err:
471 kfree(idmap);
472 return error;
482} 473}
483 474
484void 475void
@@ -488,130 +479,26 @@ nfs_idmap_delete(struct nfs_client *clp)
488 479
489 if (!idmap) 480 if (!idmap)
490 return; 481 return;
491 nfs_idmap_unregister(clp, idmap->idmap_pipe);
492 rpc_destroy_pipe_data(idmap->idmap_pipe);
493 clp->cl_idmap = NULL; 482 clp->cl_idmap = NULL;
483 rpc_remove_pipe_dir_object(clp->cl_net,
484 &clp->cl_rpcclient->cl_pipedir_objects,
485 &idmap->idmap_pdo);
486 rpc_destroy_pipe_data(idmap->idmap_pipe);
494 kfree(idmap); 487 kfree(idmap);
495} 488}
496 489
497static int __rpc_pipefs_event(struct nfs_client *clp, unsigned long event,
498 struct super_block *sb)
499{
500 int err = 0;
501
502 switch (event) {
503 case RPC_PIPEFS_MOUNT:
504 err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry,
505 clp->cl_idmap,
506 clp->cl_idmap->idmap_pipe);
507 break;
508 case RPC_PIPEFS_UMOUNT:
509 if (clp->cl_idmap->idmap_pipe) {
510 struct dentry *parent;
511
512 parent = clp->cl_idmap->idmap_pipe->dentry->d_parent;
513 __nfs_idmap_unregister(clp->cl_idmap->idmap_pipe);
514 /*
515 * Note: This is a dirty hack. SUNRPC hook has been
516 * called already but simple_rmdir() call for the
517 * directory returned with error because of idmap pipe
518 * inside. Thus now we have to remove this directory
519 * here.
520 */
521 if (rpc_rmdir(parent))
522 printk(KERN_ERR "NFS: %s: failed to remove "
523 "clnt dir!\n", __func__);
524 }
525 break;
526 default:
527 printk(KERN_ERR "NFS: %s: unknown event: %ld\n", __func__,
528 event);
529 return -ENOTSUPP;
530 }
531 return err;
532}
533
534static struct nfs_client *nfs_get_client_for_event(struct net *net, int event)
535{
536 struct nfs_net *nn = net_generic(net, nfs_net_id);
537 struct dentry *cl_dentry;
538 struct nfs_client *clp;
539 int err;
540
541restart:
542 spin_lock(&nn->nfs_client_lock);
543 list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
544 /* Wait for initialisation to finish */
545 if (clp->cl_cons_state == NFS_CS_INITING) {
546 atomic_inc(&clp->cl_count);
547 spin_unlock(&nn->nfs_client_lock);
548 err = nfs_wait_client_init_complete(clp);
549 nfs_put_client(clp);
550 if (err)
551 return NULL;
552 goto restart;
553 }
554 /* Skip nfs_clients that failed to initialise */
555 if (clp->cl_cons_state < 0)
556 continue;
557 smp_rmb();
558 if (clp->rpc_ops != &nfs_v4_clientops)
559 continue;
560 cl_dentry = clp->cl_idmap->idmap_pipe->dentry;
561 if (((event == RPC_PIPEFS_MOUNT) && cl_dentry) ||
562 ((event == RPC_PIPEFS_UMOUNT) && !cl_dentry))
563 continue;
564 atomic_inc(&clp->cl_count);
565 spin_unlock(&nn->nfs_client_lock);
566 return clp;
567 }
568 spin_unlock(&nn->nfs_client_lock);
569 return NULL;
570}
571
572static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
573 void *ptr)
574{
575 struct super_block *sb = ptr;
576 struct nfs_client *clp;
577 int error = 0;
578
579 if (!try_module_get(THIS_MODULE))
580 return 0;
581
582 while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) {
583 error = __rpc_pipefs_event(clp, event, sb);
584 nfs_put_client(clp);
585 if (error)
586 break;
587 }
588 module_put(THIS_MODULE);
589 return error;
590}
591
592#define PIPEFS_NFS_PRIO 1
593
594static struct notifier_block nfs_idmap_block = {
595 .notifier_call = rpc_pipefs_event,
596 .priority = SUNRPC_PIPEFS_NFS_PRIO,
597};
598
599int nfs_idmap_init(void) 490int nfs_idmap_init(void)
600{ 491{
601 int ret; 492 int ret;
602 ret = nfs_idmap_init_keyring(); 493 ret = nfs_idmap_init_keyring();
603 if (ret != 0) 494 if (ret != 0)
604 goto out; 495 goto out;
605 ret = rpc_pipefs_notifier_register(&nfs_idmap_block);
606 if (ret != 0)
607 nfs_idmap_quit_keyring();
608out: 496out:
609 return ret; 497 return ret;
610} 498}
611 499
612void nfs_idmap_quit(void) 500void nfs_idmap_quit(void)
613{ 501{
614 rpc_pipefs_notifier_unregister(&nfs_idmap_block);
615 nfs_idmap_quit_keyring(); 502 nfs_idmap_quit_keyring();
616} 503}
617 504
@@ -849,6 +736,7 @@ int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_
849 if (!uid_valid(*uid)) 736 if (!uid_valid(*uid))
850 ret = -ERANGE; 737 ret = -ERANGE;
851 } 738 }
739 trace_nfs4_map_name_to_uid(name, namelen, id, ret);
852 return ret; 740 return ret;
853} 741}
854 742
@@ -865,6 +753,7 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size
865 if (!gid_valid(*gid)) 753 if (!gid_valid(*gid))
866 ret = -ERANGE; 754 ret = -ERANGE;
867 } 755 }
756 trace_nfs4_map_group_to_gid(name, namelen, id, ret);
868 return ret; 757 return ret;
869} 758}
870 759
@@ -879,6 +768,7 @@ int nfs_map_uid_to_name(const struct nfs_server *server, kuid_t uid, char *buf,
879 ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap); 768 ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap);
880 if (ret < 0) 769 if (ret < 0)
881 ret = nfs_map_numeric_to_string(id, buf, buflen); 770 ret = nfs_map_numeric_to_string(id, buf, buflen);
771 trace_nfs4_map_uid_to_name(buf, ret, id, ret);
882 return ret; 772 return ret;
883} 773}
884int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf, size_t buflen) 774int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf, size_t buflen)
@@ -892,5 +782,6 @@ int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf,
892 ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap); 782 ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap);
893 if (ret < 0) 783 if (ret < 0)
894 ret = nfs_map_numeric_to_string(id, buf, buflen); 784 ret = nfs_map_numeric_to_string(id, buf, buflen);
785 trace_nfs4_map_gid_to_group(buf, ret, id, ret);
895 return ret; 786 return ret;
896} 787}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 941246f2b43d..87e797640828 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -38,7 +38,6 @@
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/compat.h> 39#include <linux/compat.h>
40#include <linux/freezer.h> 40#include <linux/freezer.h>
41#include <linux/crc32.h>
42 41
43#include <asm/uaccess.h> 42#include <asm/uaccess.h>
44 43
@@ -52,6 +51,8 @@
52#include "nfs.h" 51#include "nfs.h"
53#include "netns.h" 52#include "netns.h"
54 53
54#include "nfstrace.h"
55
55#define NFSDBG_FACILITY NFSDBG_VFS 56#define NFSDBG_FACILITY NFSDBG_VFS
56 57
57#define NFS_64_BIT_INODE_NUMBERS_ENABLED 1 58#define NFS_64_BIT_INODE_NUMBERS_ENABLED 1
@@ -503,6 +504,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
503 if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0) 504 if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
504 return 0; 505 return 0;
505 506
507 trace_nfs_setattr_enter(inode);
508
506 /* Write all dirty data */ 509 /* Write all dirty data */
507 if (S_ISREG(inode->i_mode)) { 510 if (S_ISREG(inode->i_mode)) {
508 nfs_inode_dio_wait(inode); 511 nfs_inode_dio_wait(inode);
@@ -522,6 +525,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
522 error = nfs_refresh_inode(inode, fattr); 525 error = nfs_refresh_inode(inode, fattr);
523 nfs_free_fattr(fattr); 526 nfs_free_fattr(fattr);
524out: 527out:
528 trace_nfs_setattr_exit(inode, error);
525 return error; 529 return error;
526} 530}
527EXPORT_SYMBOL_GPL(nfs_setattr); 531EXPORT_SYMBOL_GPL(nfs_setattr);
@@ -591,6 +595,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
591 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; 595 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
592 int err; 596 int err;
593 597
598 trace_nfs_getattr_enter(inode);
594 /* Flush out writes to the server in order to update c/mtime. */ 599 /* Flush out writes to the server in order to update c/mtime. */
595 if (S_ISREG(inode->i_mode)) { 600 if (S_ISREG(inode->i_mode)) {
596 nfs_inode_dio_wait(inode); 601 nfs_inode_dio_wait(inode);
@@ -621,6 +626,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
621 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); 626 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
622 } 627 }
623out: 628out:
629 trace_nfs_getattr_exit(inode, err);
624 return err; 630 return err;
625} 631}
626EXPORT_SYMBOL_GPL(nfs_getattr); 632EXPORT_SYMBOL_GPL(nfs_getattr);
@@ -875,6 +881,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
875 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", 881 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
876 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); 882 inode->i_sb->s_id, (long long)NFS_FILEID(inode));
877 883
884 trace_nfs_revalidate_inode_enter(inode);
885
878 if (is_bad_inode(inode)) 886 if (is_bad_inode(inode))
879 goto out; 887 goto out;
880 if (NFS_STALE(inode)) 888 if (NFS_STALE(inode))
@@ -925,6 +933,7 @@ err_out:
925 nfs4_label_free(label); 933 nfs4_label_free(label);
926out: 934out:
927 nfs_free_fattr(fattr); 935 nfs_free_fattr(fattr);
936 trace_nfs_revalidate_inode_exit(inode, status);
928 return status; 937 return status;
929} 938}
930 939
@@ -981,6 +990,7 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
981 spin_unlock(&inode->i_lock); 990 spin_unlock(&inode->i_lock);
982 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); 991 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
983 nfs_fscache_wait_on_invalidate(inode); 992 nfs_fscache_wait_on_invalidate(inode);
993
984 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", 994 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
985 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); 995 inode->i_sb->s_id, (long long)NFS_FILEID(inode));
986 return 0; 996 return 0;
@@ -1014,8 +1024,12 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
1014 if (ret < 0) 1024 if (ret < 0)
1015 goto out; 1025 goto out;
1016 } 1026 }
1017 if (nfsi->cache_validity & NFS_INO_INVALID_DATA) 1027 if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
1028 trace_nfs_invalidate_mapping_enter(inode);
1018 ret = nfs_invalidate_mapping(inode, mapping); 1029 ret = nfs_invalidate_mapping(inode, mapping);
1030 trace_nfs_invalidate_mapping_exit(inode, ret);
1031 }
1032
1019out: 1033out:
1020 return ret; 1034 return ret;
1021} 1035}
@@ -1195,7 +1209,7 @@ u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh)
1195{ 1209{
1196 /* wireshark uses 32-bit AUTODIN crc and does a bitwise 1210 /* wireshark uses 32-bit AUTODIN crc and does a bitwise
1197 * not on the result */ 1211 * not on the result */
1198 return ~crc32(0xFFFFFFFF, &fh->data[0], fh->size); 1212 return nfs_fhandle_hash(fh);
1199} 1213}
1200 1214
1201/* 1215/*
@@ -1274,9 +1288,17 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n
1274 1288
1275static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr) 1289static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
1276{ 1290{
1291 int ret;
1292
1293 trace_nfs_refresh_inode_enter(inode);
1294
1277 if (nfs_inode_attrs_need_update(inode, fattr)) 1295 if (nfs_inode_attrs_need_update(inode, fattr))
1278 return nfs_update_inode(inode, fattr); 1296 ret = nfs_update_inode(inode, fattr);
1279 return nfs_check_inode_attributes(inode, fattr); 1297 else
1298 ret = nfs_check_inode_attributes(inode, fattr);
1299
1300 trace_nfs_refresh_inode_exit(inode, ret);
1301 return ret;
1280} 1302}
1281 1303
1282/** 1304/**
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 3c8373f90ab3..d388302c005f 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -5,6 +5,7 @@
5#include "nfs4_fs.h" 5#include "nfs4_fs.h"
6#include <linux/mount.h> 6#include <linux/mount.h>
7#include <linux/security.h> 7#include <linux/security.h>
8#include <linux/crc32.h>
8 9
9#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS) 10#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
10 11
@@ -185,6 +186,8 @@ extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
185 int ds_addrlen, int ds_proto, 186 int ds_addrlen, int ds_proto,
186 unsigned int ds_timeo, 187 unsigned int ds_timeo,
187 unsigned int ds_retrans); 188 unsigned int ds_retrans);
189extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
190 struct inode *);
188#ifdef CONFIG_PROC_FS 191#ifdef CONFIG_PROC_FS
189extern int __init nfs_fs_proc_init(void); 192extern int __init nfs_fs_proc_init(void);
190extern void nfs_fs_proc_exit(void); 193extern void nfs_fs_proc_exit(void);
@@ -267,7 +270,7 @@ extern struct rpc_procinfo nfs4_procedures[];
267void nfs_close_context(struct nfs_open_context *ctx, int is_sync); 270void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
268extern struct nfs_client *nfs_init_client(struct nfs_client *clp, 271extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
269 const struct rpc_timeout *timeparms, 272 const struct rpc_timeout *timeparms,
270 const char *ip_addr, rpc_authflavor_t authflavour); 273 const char *ip_addr);
271 274
272/* dir.c */ 275/* dir.c */
273extern int nfs_access_cache_shrinker(struct shrinker *shrink, 276extern int nfs_access_cache_shrinker(struct shrinker *shrink,
@@ -355,7 +358,7 @@ extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
355extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, 358extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
356 const char *); 359 const char *);
357 360
358extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh); 361extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool);
359#endif 362#endif
360 363
361struct nfs_pgio_completion_ops; 364struct nfs_pgio_completion_ops;
@@ -430,6 +433,8 @@ void nfs_request_remove_commit_list(struct nfs_page *req,
430void nfs_init_cinfo(struct nfs_commit_info *cinfo, 433void nfs_init_cinfo(struct nfs_commit_info *cinfo,
431 struct inode *inode, 434 struct inode *inode,
432 struct nfs_direct_req *dreq); 435 struct nfs_direct_req *dreq);
436int nfs_key_timeout_notify(struct file *filp, struct inode *inode);
437bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx);
433 438
434#ifdef CONFIG_MIGRATION 439#ifdef CONFIG_MIGRATION
435extern int nfs_migrate_page(struct address_space *, 440extern int nfs_migrate_page(struct address_space *,
@@ -451,8 +456,7 @@ extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
451extern void __nfs4_read_done_cb(struct nfs_read_data *); 456extern void __nfs4_read_done_cb(struct nfs_read_data *);
452extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, 457extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
453 const struct rpc_timeout *timeparms, 458 const struct rpc_timeout *timeparms,
454 const char *ip_addr, 459 const char *ip_addr);
455 rpc_authflavor_t authflavour);
456extern int nfs40_walk_client_list(struct nfs_client *clp, 460extern int nfs40_walk_client_list(struct nfs_client *clp,
457 struct nfs_client **result, 461 struct nfs_client **result,
458 struct rpc_cred *cred); 462 struct rpc_cred *cred);
@@ -575,3 +579,22 @@ u64 nfs_timespec_to_change_attr(const struct timespec *ts)
575{ 579{
576 return ((u64)ts->tv_sec << 30) + ts->tv_nsec; 580 return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
577} 581}
582
583#ifdef CONFIG_CRC32
584/**
585 * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
586 * @fh - pointer to filehandle
587 *
588 * returns a crc32 hash for the filehandle that is compatible with
589 * the one displayed by "wireshark".
590 */
591static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
592{
593 return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
594}
595#else
596static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
597{
598 return 0;
599}
600#endif
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index f5c84c3efbca..90cb10d7b693 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -336,8 +336,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
336 data->arg.create.createmode = NFS3_CREATE_UNCHECKED; 336 data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
337 if (flags & O_EXCL) { 337 if (flags & O_EXCL) {
338 data->arg.create.createmode = NFS3_CREATE_EXCLUSIVE; 338 data->arg.create.createmode = NFS3_CREATE_EXCLUSIVE;
339 data->arg.create.verifier[0] = jiffies; 339 data->arg.create.verifier[0] = cpu_to_be32(jiffies);
340 data->arg.create.verifier[1] = current->pid; 340 data->arg.create.verifier[1] = cpu_to_be32(current->pid);
341 } 341 }
342 342
343 sattr->ia_mode &= ~current_umask(); 343 sattr->ia_mode &= ~current_umask();
@@ -826,9 +826,10 @@ static void nfs3_proc_read_setup(struct nfs_read_data *data, struct rpc_message
826 msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ]; 826 msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
827} 827}
828 828
829static void nfs3_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 829static int nfs3_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
830{ 830{
831 rpc_call_start(task); 831 rpc_call_start(task);
832 return 0;
832} 833}
833 834
834static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data) 835static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -847,9 +848,10 @@ static void nfs3_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
847 msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE]; 848 msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE];
848} 849}
849 850
850static void nfs3_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 851static int nfs3_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
851{ 852{
852 rpc_call_start(task); 853 rpc_call_start(task);
854 return 0;
853} 855}
854 856
855static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) 857static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ee81e354bce7..f520a1113b38 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -38,17 +38,15 @@ struct nfs4_minor_version_ops {
38 u32 minor_version; 38 u32 minor_version;
39 unsigned init_caps; 39 unsigned init_caps;
40 40
41 int (*call_sync)(struct rpc_clnt *clnt, 41 int (*init_client)(struct nfs_client *);
42 struct nfs_server *server, 42 void (*shutdown_client)(struct nfs_client *);
43 struct rpc_message *msg,
44 struct nfs4_sequence_args *args,
45 struct nfs4_sequence_res *res);
46 bool (*match_stateid)(const nfs4_stateid *, 43 bool (*match_stateid)(const nfs4_stateid *,
47 const nfs4_stateid *); 44 const nfs4_stateid *);
48 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *, 45 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
49 struct nfs_fsinfo *); 46 struct nfs_fsinfo *);
50 int (*free_lock_state)(struct nfs_server *, 47 int (*free_lock_state)(struct nfs_server *,
51 struct nfs4_lock_state *); 48 struct nfs4_lock_state *);
49 const struct rpc_call_ops *call_sync_ops;
52 const struct nfs4_state_recovery_ops *reboot_recovery_ops; 50 const struct nfs4_state_recovery_ops *reboot_recovery_ops;
53 const struct nfs4_state_recovery_ops *nograce_recovery_ops; 51 const struct nfs4_state_recovery_ops *nograce_recovery_ops;
54 const struct nfs4_state_maintenance_ops *state_renewal_ops; 52 const struct nfs4_state_maintenance_ops *state_renewal_ops;
@@ -135,6 +133,7 @@ struct nfs4_lock_state {
135 struct list_head ls_locks; /* Other lock stateids */ 133 struct list_head ls_locks; /* Other lock stateids */
136 struct nfs4_state * ls_state; /* Pointer to open state */ 134 struct nfs4_state * ls_state; /* Pointer to open state */
137#define NFS_LOCK_INITIALIZED 0 135#define NFS_LOCK_INITIALIZED 0
136#define NFS_LOCK_LOST 1
138 unsigned long ls_flags; 137 unsigned long ls_flags;
139 struct nfs_seqid_counter ls_seqid; 138 struct nfs_seqid_counter ls_seqid;
140 nfs4_stateid ls_stateid; 139 nfs4_stateid ls_stateid;
@@ -193,7 +192,6 @@ struct nfs4_state_recovery_ops {
193 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); 192 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
194 int (*recover_lock)(struct nfs4_state *, struct file_lock *); 193 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
195 int (*establish_clid)(struct nfs_client *, struct rpc_cred *); 194 int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
196 struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
197 int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *); 195 int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *);
198 int (*detect_trunking)(struct nfs_client *, struct nfs_client **, 196 int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
199 struct rpc_cred *); 197 struct rpc_cred *);
@@ -223,7 +221,7 @@ struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
223/* nfs4proc.c */ 221/* nfs4proc.c */
224extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); 222extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
225extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); 223extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
226extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 224extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool);
227extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred); 225extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred);
228extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred); 226extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
229extern int nfs4_destroy_clientid(struct nfs_client *clp); 227extern int nfs4_destroy_clientid(struct nfs_client *clp);
@@ -248,9 +246,6 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *ser
248 return server->nfs_client->cl_session; 246 return server->nfs_client->cl_session;
249} 247}
250 248
251extern int nfs4_setup_sequence(const struct nfs_server *server,
252 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
253 struct rpc_task *task);
254extern int nfs41_setup_sequence(struct nfs4_session *session, 249extern int nfs41_setup_sequence(struct nfs4_session *session,
255 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 250 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
256 struct rpc_task *task); 251 struct rpc_task *task);
@@ -273,18 +268,63 @@ is_ds_client(struct nfs_client *clp)
273{ 268{
274 return clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_DS; 269 return clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_DS;
275} 270}
276#else /* CONFIG_NFS_v4_1 */ 271
277static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server) 272static inline bool
273_nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
274 struct rpc_clnt **clntp, struct rpc_message *msg)
278{ 275{
279 return NULL; 276 struct rpc_cred *newcred = NULL;
277 rpc_authflavor_t flavor;
278
279 if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
280 spin_lock(&clp->cl_lock);
281 if (clp->cl_machine_cred != NULL)
282 newcred = get_rpccred(clp->cl_machine_cred);
283 spin_unlock(&clp->cl_lock);
284 if (msg->rpc_cred)
285 put_rpccred(msg->rpc_cred);
286 msg->rpc_cred = newcred;
287
288 flavor = clp->cl_rpcclient->cl_auth->au_flavor;
289 WARN_ON(flavor != RPC_AUTH_GSS_KRB5I &&
290 flavor != RPC_AUTH_GSS_KRB5P);
291 *clntp = clp->cl_rpcclient;
292
293 return true;
294 }
295 return false;
280} 296}
281 297
282static inline int nfs4_setup_sequence(const struct nfs_server *server, 298/*
283 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 299 * Function responsible for determining if an rpc_message should use the
284 struct rpc_task *task) 300 * machine cred under SP4_MACH_CRED and if so switching the credential and
301 * authflavor (using the nfs_client's rpc_clnt which will be krb5i/p).
302 * Should be called before rpc_call_sync/rpc_call_async.
303 */
304static inline void
305nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
306 struct rpc_clnt **clntp, struct rpc_message *msg)
285{ 307{
286 rpc_call_start(task); 308 _nfs4_state_protect(clp, sp4_mode, clntp, msg);
287 return 0; 309}
310
311/*
312 * Special wrapper to nfs4_state_protect for write.
313 * If WRITE can use machine cred but COMMIT cannot, make sure all writes
314 * that use machine cred use NFS_FILE_SYNC.
315 */
316static inline void
317nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
318 struct rpc_message *msg, struct nfs_write_data *wdata)
319{
320 if (_nfs4_state_protect(clp, NFS_SP4_MACH_CRED_WRITE, clntp, msg) &&
321 !test_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags))
322 wdata->args.stable = NFS_FILE_SYNC;
323}
324#else /* CONFIG_NFS_v4_1 */
325static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
326{
327 return NULL;
288} 328}
289 329
290static inline bool 330static inline bool
@@ -298,6 +338,18 @@ is_ds_client(struct nfs_client *clp)
298{ 338{
299 return false; 339 return false;
300} 340}
341
342static inline void
343nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_flags,
344 struct rpc_clnt **clntp, struct rpc_message *msg)
345{
346}
347
348static inline void
349nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
350 struct rpc_message *msg, struct nfs_write_data *wdata)
351{
352}
301#endif /* CONFIG_NFS_V4_1 */ 353#endif /* CONFIG_NFS_V4_1 */
302 354
303extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[]; 355extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
@@ -308,6 +360,10 @@ extern const u32 nfs4_pathconf_bitmap[3];
308extern const u32 nfs4_fsinfo_bitmap[3]; 360extern const u32 nfs4_fsinfo_bitmap[3];
309extern const u32 nfs4_fs_locations_bitmap[3]; 361extern const u32 nfs4_fs_locations_bitmap[3];
310 362
363void nfs40_shutdown_client(struct nfs_client *);
364void nfs41_shutdown_client(struct nfs_client *);
365int nfs40_init_client(struct nfs_client *);
366int nfs41_init_client(struct nfs_client *);
311void nfs4_free_client(struct nfs_client *); 367void nfs4_free_client(struct nfs_client *);
312 368
313struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *); 369struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);
@@ -319,7 +375,7 @@ extern void nfs4_kill_renewd(struct nfs_client *);
319extern void nfs4_renew_state(struct work_struct *); 375extern void nfs4_renew_state(struct work_struct *);
320 376
321/* nfs4state.c */ 377/* nfs4state.c */
322struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp); 378struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp);
323struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp); 379struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
324struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp); 380struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
325int nfs4_discover_server_trunking(struct nfs_client *clp, 381int nfs4_discover_server_trunking(struct nfs_client *clp,
@@ -327,7 +383,6 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
327int nfs40_discover_server_trunking(struct nfs_client *clp, 383int nfs40_discover_server_trunking(struct nfs_client *clp,
328 struct nfs_client **, struct rpc_cred *); 384 struct nfs_client **, struct rpc_cred *);
329#if defined(CONFIG_NFS_V4_1) 385#if defined(CONFIG_NFS_V4_1)
330struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
331int nfs41_discover_server_trunking(struct nfs_client *clp, 386int nfs41_discover_server_trunking(struct nfs_client *clp,
332 struct nfs_client **, struct rpc_cred *); 387 struct nfs_client **, struct rpc_cred *);
333extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); 388extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
@@ -382,6 +437,7 @@ struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct
382extern bool nfs4_disable_idmapping; 437extern bool nfs4_disable_idmapping;
383extern unsigned short max_session_slots; 438extern unsigned short max_session_slots;
384extern unsigned short send_implementation_id; 439extern unsigned short send_implementation_id;
440extern bool recover_lost_locks;
385 441
386#define NFS4_CLIENT_ID_UNIQ_LEN (64) 442#define NFS4_CLIENT_ID_UNIQ_LEN (64)
387extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN]; 443extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN];
@@ -429,6 +485,8 @@ static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
429 485
430#define nfs4_close_state(a, b) do { } while (0) 486#define nfs4_close_state(a, b) do { } while (0)
431#define nfs4_close_sync(a, b) do { } while (0) 487#define nfs4_close_sync(a, b) do { } while (0)
488#define nfs4_state_protect(a, b, c, d) do { } while (0)
489#define nfs4_state_protect_write(a, b, c, d) do { } while (0)
432 490
433#endif /* CONFIG_NFS_V4 */ 491#endif /* CONFIG_NFS_V4 */
434#endif /* __LINUX_FS_NFS_NFS4_FS.H */ 492#endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 90dce91dd5b5..a860ab566d6e 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -41,19 +41,138 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
41} 41}
42 42
43#ifdef CONFIG_NFS_V4_1 43#ifdef CONFIG_NFS_V4_1
44static void nfs4_shutdown_session(struct nfs_client *clp) 44/**
45 * Per auth flavor data server rpc clients
46 */
47struct nfs4_ds_server {
48 struct list_head list; /* ds_clp->cl_ds_clients */
49 struct rpc_clnt *rpc_clnt;
50};
51
52/**
53 * Common lookup case for DS I/O
54 */
55static struct nfs4_ds_server *
56nfs4_find_ds_client(struct nfs_client *ds_clp, rpc_authflavor_t flavor)
57{
58 struct nfs4_ds_server *dss;
59
60 rcu_read_lock();
61 list_for_each_entry_rcu(dss, &ds_clp->cl_ds_clients, list) {
62 if (dss->rpc_clnt->cl_auth->au_flavor != flavor)
63 continue;
64 goto out;
65 }
66 dss = NULL;
67out:
68 rcu_read_unlock();
69 return dss;
70}
71
72static struct nfs4_ds_server *
73nfs4_add_ds_client(struct nfs_client *ds_clp, rpc_authflavor_t flavor,
74 struct nfs4_ds_server *new)
75{
76 struct nfs4_ds_server *dss;
77
78 spin_lock(&ds_clp->cl_lock);
79 list_for_each_entry(dss, &ds_clp->cl_ds_clients, list) {
80 if (dss->rpc_clnt->cl_auth->au_flavor != flavor)
81 continue;
82 goto out;
83 }
84 if (new)
85 list_add_rcu(&new->list, &ds_clp->cl_ds_clients);
86 dss = new;
87out:
88 spin_unlock(&ds_clp->cl_lock); /* need some lock to protect list */
89 return dss;
90}
91
92static struct nfs4_ds_server *
93nfs4_alloc_ds_server(struct nfs_client *ds_clp, rpc_authflavor_t flavor)
94{
95 struct nfs4_ds_server *dss;
96
97 dss = kmalloc(sizeof(*dss), GFP_NOFS);
98 if (dss == NULL)
99 return ERR_PTR(-ENOMEM);
100
101 dss->rpc_clnt = rpc_clone_client_set_auth(ds_clp->cl_rpcclient, flavor);
102 if (IS_ERR(dss->rpc_clnt)) {
103 int err = PTR_ERR(dss->rpc_clnt);
104 kfree (dss);
105 return ERR_PTR(err);
106 }
107 INIT_LIST_HEAD(&dss->list);
108
109 return dss;
110}
111
112static void
113nfs4_free_ds_server(struct nfs4_ds_server *dss)
114{
115 rpc_release_client(dss->rpc_clnt);
116 kfree(dss);
117}
118
119/**
120* Find or create a DS rpc client with th MDS server rpc client auth flavor
121* in the nfs_client cl_ds_clients list.
122*/
123struct rpc_clnt *
124nfs4_find_or_create_ds_client(struct nfs_client *ds_clp, struct inode *inode)
125{
126 struct nfs4_ds_server *dss, *new;
127 rpc_authflavor_t flavor = NFS_SERVER(inode)->client->cl_auth->au_flavor;
128
129 dss = nfs4_find_ds_client(ds_clp, flavor);
130 if (dss != NULL)
131 goto out;
132 new = nfs4_alloc_ds_server(ds_clp, flavor);
133 if (IS_ERR(new))
134 return ERR_CAST(new);
135 dss = nfs4_add_ds_client(ds_clp, flavor, new);
136 if (dss != new)
137 nfs4_free_ds_server(new);
138out:
139 return dss->rpc_clnt;
140}
141EXPORT_SYMBOL_GPL(nfs4_find_or_create_ds_client);
142
143static void
144nfs4_shutdown_ds_clients(struct nfs_client *clp)
145{
146 struct nfs4_ds_server *dss;
147 LIST_HEAD(shutdown_list);
148
149 while (!list_empty(&clp->cl_ds_clients)) {
150 dss = list_entry(clp->cl_ds_clients.next,
151 struct nfs4_ds_server, list);
152 list_del(&dss->list);
153 rpc_shutdown_client(dss->rpc_clnt);
154 kfree (dss);
155 }
156}
157
158void nfs41_shutdown_client(struct nfs_client *clp)
45{ 159{
46 if (nfs4_has_session(clp)) { 160 if (nfs4_has_session(clp)) {
161 nfs4_shutdown_ds_clients(clp);
47 nfs4_destroy_session(clp->cl_session); 162 nfs4_destroy_session(clp->cl_session);
48 nfs4_destroy_clientid(clp); 163 nfs4_destroy_clientid(clp);
49 } 164 }
50 165
51} 166}
52#else /* CONFIG_NFS_V4_1 */ 167#endif /* CONFIG_NFS_V4_1 */
53static void nfs4_shutdown_session(struct nfs_client *clp) 168
169void nfs40_shutdown_client(struct nfs_client *clp)
54{ 170{
171 if (clp->cl_slot_tbl) {
172 nfs4_release_slot_table(clp->cl_slot_tbl);
173 kfree(clp->cl_slot_tbl);
174 }
55} 175}
56#endif /* CONFIG_NFS_V4_1 */
57 176
58struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) 177struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
59{ 178{
@@ -73,6 +192,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
73 192
74 spin_lock_init(&clp->cl_lock); 193 spin_lock_init(&clp->cl_lock);
75 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); 194 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
195 INIT_LIST_HEAD(&clp->cl_ds_clients);
76 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); 196 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
77 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 197 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
78 clp->cl_minorversion = cl_init->minorversion; 198 clp->cl_minorversion = cl_init->minorversion;
@@ -97,7 +217,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
97{ 217{
98 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state)) 218 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
99 nfs4_kill_renewd(clp); 219 nfs4_kill_renewd(clp);
100 nfs4_shutdown_session(clp); 220 clp->cl_mvops->shutdown_client(clp);
101 nfs4_destroy_callback(clp); 221 nfs4_destroy_callback(clp);
102 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) 222 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
103 nfs_idmap_delete(clp); 223 nfs_idmap_delete(clp);
@@ -144,34 +264,77 @@ static int nfs4_init_callback(struct nfs_client *clp)
144 return 0; 264 return 0;
145} 265}
146 266
267/**
268 * nfs40_init_client - nfs_client initialization tasks for NFSv4.0
269 * @clp - nfs_client to initialize
270 *
271 * Returns zero on success, or a negative errno if some error occurred.
272 */
273int nfs40_init_client(struct nfs_client *clp)
274{
275 struct nfs4_slot_table *tbl;
276 int ret;
277
278 tbl = kzalloc(sizeof(*tbl), GFP_NOFS);
279 if (tbl == NULL)
280 return -ENOMEM;
281
282 ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
283 "NFSv4.0 transport Slot table");
284 if (ret) {
285 kfree(tbl);
286 return ret;
287 }
288
289 clp->cl_slot_tbl = tbl;
290 return 0;
291}
292
293#if defined(CONFIG_NFS_V4_1)
294
295/**
296 * nfs41_init_client - nfs_client initialization tasks for NFSv4.1+
297 * @clp - nfs_client to initialize
298 *
299 * Returns zero on success, or a negative errno if some error occurred.
300 */
301int nfs41_init_client(struct nfs_client *clp)
302{
303 struct nfs4_session *session = NULL;
304
305 /*
306 * Create the session and mark it expired.
307 * When a SEQUENCE operation encounters the expired session
308 * it will do session recovery to initialize it.
309 */
310 session = nfs4_alloc_session(clp);
311 if (!session)
312 return -ENOMEM;
313
314 clp->cl_session = session;
315
316 /*
317 * The create session reply races with the server back
318 * channel probe. Mark the client NFS_CS_SESSION_INITING
319 * so that the client back channel can find the
320 * nfs_client struct
321 */
322 nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
323 return 0;
324}
325
326#endif /* CONFIG_NFS_V4_1 */
327
147/* 328/*
148 * Initialize the minor version specific parts of an NFS4 client record 329 * Initialize the minor version specific parts of an NFS4 client record
149 */ 330 */
150static int nfs4_init_client_minor_version(struct nfs_client *clp) 331static int nfs4_init_client_minor_version(struct nfs_client *clp)
151{ 332{
152#if defined(CONFIG_NFS_V4_1) 333 int ret;
153 if (clp->cl_mvops->minor_version) {
154 struct nfs4_session *session = NULL;
155 /*
156 * Create the session and mark it expired.
157 * When a SEQUENCE operation encounters the expired session
158 * it will do session recovery to initialize it.
159 */
160 session = nfs4_alloc_session(clp);
161 if (!session)
162 return -ENOMEM;
163
164 clp->cl_session = session;
165 /*
166 * The create session reply races with the server back
167 * channel probe. Mark the client NFS_CS_SESSION_INITING
168 * so that the client back channel can find the
169 * nfs_client struct
170 */
171 nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
172 }
173#endif /* CONFIG_NFS_V4_1 */
174 334
335 ret = clp->cl_mvops->init_client(clp);
336 if (ret)
337 return ret;
175 return nfs4_init_callback(clp); 338 return nfs4_init_callback(clp);
176} 339}
177 340
@@ -187,8 +350,7 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
187 */ 350 */
188struct nfs_client *nfs4_init_client(struct nfs_client *clp, 351struct nfs_client *nfs4_init_client(struct nfs_client *clp,
189 const struct rpc_timeout *timeparms, 352 const struct rpc_timeout *timeparms,
190 const char *ip_addr, 353 const char *ip_addr)
191 rpc_authflavor_t authflavour)
192{ 354{
193 char buf[INET6_ADDRSTRLEN + 1]; 355 char buf[INET6_ADDRSTRLEN + 1];
194 struct nfs_client *old; 356 struct nfs_client *old;
@@ -723,7 +885,7 @@ static void nfs4_session_set_rwsize(struct nfs_server *server)
723} 885}
724 886
725static int nfs4_server_common_setup(struct nfs_server *server, 887static int nfs4_server_common_setup(struct nfs_server *server,
726 struct nfs_fh *mntfh) 888 struct nfs_fh *mntfh, bool auth_probe)
727{ 889{
728 struct nfs_fattr *fattr; 890 struct nfs_fattr *fattr;
729 int error; 891 int error;
@@ -755,7 +917,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
755 917
756 918
757 /* Probe the root fh to retrieve its FSID and filehandle */ 919 /* Probe the root fh to retrieve its FSID and filehandle */
758 error = nfs4_get_rootfh(server, mntfh); 920 error = nfs4_get_rootfh(server, mntfh, auth_probe);
759 if (error < 0) 921 if (error < 0)
760 goto out; 922 goto out;
761 923
@@ -787,6 +949,7 @@ out:
787static int nfs4_init_server(struct nfs_server *server, 949static int nfs4_init_server(struct nfs_server *server,
788 const struct nfs_parsed_mount_data *data) 950 const struct nfs_parsed_mount_data *data)
789{ 951{
952 rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX;
790 struct rpc_timeout timeparms; 953 struct rpc_timeout timeparms;
791 int error; 954 int error;
792 955
@@ -799,13 +962,16 @@ static int nfs4_init_server(struct nfs_server *server,
799 server->flags = data->flags; 962 server->flags = data->flags;
800 server->options = data->options; 963 server->options = data->options;
801 964
965 if (data->auth_flavor_len >= 1)
966 pseudoflavor = data->auth_flavors[0];
967
802 /* Get a client record */ 968 /* Get a client record */
803 error = nfs4_set_client(server, 969 error = nfs4_set_client(server,
804 data->nfs_server.hostname, 970 data->nfs_server.hostname,
805 (const struct sockaddr *)&data->nfs_server.address, 971 (const struct sockaddr *)&data->nfs_server.address,
806 data->nfs_server.addrlen, 972 data->nfs_server.addrlen,
807 data->client_address, 973 data->client_address,
808 data->auth_flavors[0], 974 pseudoflavor,
809 data->nfs_server.protocol, 975 data->nfs_server.protocol,
810 &timeparms, 976 &timeparms,
811 data->minorversion, 977 data->minorversion,
@@ -825,7 +991,7 @@ static int nfs4_init_server(struct nfs_server *server,
825 991
826 server->port = data->nfs_server.port; 992 server->port = data->nfs_server.port;
827 993
828 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 994 error = nfs_init_server_rpcclient(server, &timeparms, pseudoflavor);
829 995
830error: 996error:
831 /* Done */ 997 /* Done */
@@ -843,6 +1009,7 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
843 struct nfs_subversion *nfs_mod) 1009 struct nfs_subversion *nfs_mod)
844{ 1010{
845 struct nfs_server *server; 1011 struct nfs_server *server;
1012 bool auth_probe;
846 int error; 1013 int error;
847 1014
848 dprintk("--> nfs4_create_server()\n"); 1015 dprintk("--> nfs4_create_server()\n");
@@ -851,12 +1018,14 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
851 if (!server) 1018 if (!server)
852 return ERR_PTR(-ENOMEM); 1019 return ERR_PTR(-ENOMEM);
853 1020
1021 auth_probe = mount_info->parsed->auth_flavor_len < 1;
1022
854 /* set up the general RPC client */ 1023 /* set up the general RPC client */
855 error = nfs4_init_server(server, mount_info->parsed); 1024 error = nfs4_init_server(server, mount_info->parsed);
856 if (error < 0) 1025 if (error < 0)
857 goto error; 1026 goto error;
858 1027
859 error = nfs4_server_common_setup(server, mount_info->mntfh); 1028 error = nfs4_server_common_setup(server, mount_info->mntfh, auth_probe);
860 if (error < 0) 1029 if (error < 0)
861 goto error; 1030 goto error;
862 1031
@@ -909,7 +1078,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
909 if (error < 0) 1078 if (error < 0)
910 goto error; 1079 goto error;
911 1080
912 error = nfs4_server_common_setup(server, mntfh); 1081 error = nfs4_server_common_setup(server, mntfh,
1082 !(parent_server->flags & NFS_MOUNT_SECFLAVOUR));
913 if (error < 0) 1083 if (error < 0)
914 goto error; 1084 goto error;
915 1085
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 17ed87ef9de8..b86464ba25e1 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -39,6 +39,7 @@
39#include "internal.h" 39#include "internal.h"
40#include "delegation.h" 40#include "delegation.h"
41#include "nfs4filelayout.h" 41#include "nfs4filelayout.h"
42#include "nfs4trace.h"
42 43
43#define NFSDBG_FACILITY NFSDBG_PNFS_LD 44#define NFSDBG_FACILITY NFSDBG_PNFS_LD
44 45
@@ -247,6 +248,7 @@ static int filelayout_read_done_cb(struct rpc_task *task,
247 struct nfs_pgio_header *hdr = data->header; 248 struct nfs_pgio_header *hdr = data->header;
248 int err; 249 int err;
249 250
251 trace_nfs4_pnfs_read(data, task->tk_status);
250 err = filelayout_async_handle_error(task, data->args.context->state, 252 err = filelayout_async_handle_error(task, data->args.context->state,
251 data->ds_clp, hdr->lseg); 253 data->ds_clp, hdr->lseg);
252 254
@@ -363,6 +365,7 @@ static int filelayout_write_done_cb(struct rpc_task *task,
363 struct nfs_pgio_header *hdr = data->header; 365 struct nfs_pgio_header *hdr = data->header;
364 int err; 366 int err;
365 367
368 trace_nfs4_pnfs_write(data, task->tk_status);
366 err = filelayout_async_handle_error(task, data->args.context->state, 369 err = filelayout_async_handle_error(task, data->args.context->state,
367 data->ds_clp, hdr->lseg); 370 data->ds_clp, hdr->lseg);
368 371
@@ -395,6 +398,7 @@ static int filelayout_commit_done_cb(struct rpc_task *task,
395{ 398{
396 int err; 399 int err;
397 400
401 trace_nfs4_pnfs_commit_ds(data, task->tk_status);
398 err = filelayout_async_handle_error(task, NULL, data->ds_clp, 402 err = filelayout_async_handle_error(task, NULL, data->ds_clp,
399 data->lseg); 403 data->lseg);
400 404
@@ -524,6 +528,7 @@ filelayout_read_pagelist(struct nfs_read_data *data)
524 struct nfs_pgio_header *hdr = data->header; 528 struct nfs_pgio_header *hdr = data->header;
525 struct pnfs_layout_segment *lseg = hdr->lseg; 529 struct pnfs_layout_segment *lseg = hdr->lseg;
526 struct nfs4_pnfs_ds *ds; 530 struct nfs4_pnfs_ds *ds;
531 struct rpc_clnt *ds_clnt;
527 loff_t offset = data->args.offset; 532 loff_t offset = data->args.offset;
528 u32 j, idx; 533 u32 j, idx;
529 struct nfs_fh *fh; 534 struct nfs_fh *fh;
@@ -538,6 +543,11 @@ filelayout_read_pagelist(struct nfs_read_data *data)
538 ds = nfs4_fl_prepare_ds(lseg, idx); 543 ds = nfs4_fl_prepare_ds(lseg, idx);
539 if (!ds) 544 if (!ds)
540 return PNFS_NOT_ATTEMPTED; 545 return PNFS_NOT_ATTEMPTED;
546
547 ds_clnt = nfs4_find_or_create_ds_client(ds->ds_clp, hdr->inode);
548 if (IS_ERR(ds_clnt))
549 return PNFS_NOT_ATTEMPTED;
550
541 dprintk("%s USE DS: %s cl_count %d\n", __func__, 551 dprintk("%s USE DS: %s cl_count %d\n", __func__,
542 ds->ds_remotestr, atomic_read(&ds->ds_clp->cl_count)); 552 ds->ds_remotestr, atomic_read(&ds->ds_clp->cl_count));
543 553
@@ -552,7 +562,7 @@ filelayout_read_pagelist(struct nfs_read_data *data)
552 data->mds_offset = offset; 562 data->mds_offset = offset;
553 563
554 /* Perform an asynchronous read to ds */ 564 /* Perform an asynchronous read to ds */
555 nfs_initiate_read(ds->ds_clp->cl_rpcclient, data, 565 nfs_initiate_read(ds_clnt, data,
556 &filelayout_read_call_ops, RPC_TASK_SOFTCONN); 566 &filelayout_read_call_ops, RPC_TASK_SOFTCONN);
557 return PNFS_ATTEMPTED; 567 return PNFS_ATTEMPTED;
558} 568}
@@ -564,6 +574,7 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
564 struct nfs_pgio_header *hdr = data->header; 574 struct nfs_pgio_header *hdr = data->header;
565 struct pnfs_layout_segment *lseg = hdr->lseg; 575 struct pnfs_layout_segment *lseg = hdr->lseg;
566 struct nfs4_pnfs_ds *ds; 576 struct nfs4_pnfs_ds *ds;
577 struct rpc_clnt *ds_clnt;
567 loff_t offset = data->args.offset; 578 loff_t offset = data->args.offset;
568 u32 j, idx; 579 u32 j, idx;
569 struct nfs_fh *fh; 580 struct nfs_fh *fh;
@@ -574,6 +585,11 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
574 ds = nfs4_fl_prepare_ds(lseg, idx); 585 ds = nfs4_fl_prepare_ds(lseg, idx);
575 if (!ds) 586 if (!ds)
576 return PNFS_NOT_ATTEMPTED; 587 return PNFS_NOT_ATTEMPTED;
588
589 ds_clnt = nfs4_find_or_create_ds_client(ds->ds_clp, hdr->inode);
590 if (IS_ERR(ds_clnt))
591 return PNFS_NOT_ATTEMPTED;
592
577 dprintk("%s ino %lu sync %d req %Zu@%llu DS: %s cl_count %d\n", 593 dprintk("%s ino %lu sync %d req %Zu@%llu DS: %s cl_count %d\n",
578 __func__, hdr->inode->i_ino, sync, (size_t) data->args.count, 594 __func__, hdr->inode->i_ino, sync, (size_t) data->args.count,
579 offset, ds->ds_remotestr, atomic_read(&ds->ds_clp->cl_count)); 595 offset, ds->ds_remotestr, atomic_read(&ds->ds_clp->cl_count));
@@ -591,7 +607,7 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
591 data->args.offset = filelayout_get_dserver_offset(lseg, offset); 607 data->args.offset = filelayout_get_dserver_offset(lseg, offset);
592 608
593 /* Perform an asynchronous write */ 609 /* Perform an asynchronous write */
594 nfs_initiate_write(ds->ds_clp->cl_rpcclient, data, 610 nfs_initiate_write(ds_clnt, data,
595 &filelayout_write_call_ops, sync, 611 &filelayout_write_call_ops, sync,
596 RPC_TASK_SOFTCONN); 612 RPC_TASK_SOFTCONN);
597 return PNFS_ATTEMPTED; 613 return PNFS_ATTEMPTED;
@@ -1101,16 +1117,19 @@ static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
1101{ 1117{
1102 struct pnfs_layout_segment *lseg = data->lseg; 1118 struct pnfs_layout_segment *lseg = data->lseg;
1103 struct nfs4_pnfs_ds *ds; 1119 struct nfs4_pnfs_ds *ds;
1120 struct rpc_clnt *ds_clnt;
1104 u32 idx; 1121 u32 idx;
1105 struct nfs_fh *fh; 1122 struct nfs_fh *fh;
1106 1123
1107 idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); 1124 idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
1108 ds = nfs4_fl_prepare_ds(lseg, idx); 1125 ds = nfs4_fl_prepare_ds(lseg, idx);
1109 if (!ds) { 1126 if (!ds)
1110 prepare_to_resend_writes(data); 1127 goto out_err;
1111 filelayout_commit_release(data); 1128
1112 return -EAGAIN; 1129 ds_clnt = nfs4_find_or_create_ds_client(ds->ds_clp, data->inode);
1113 } 1130 if (IS_ERR(ds_clnt))
1131 goto out_err;
1132
1114 dprintk("%s ino %lu, how %d cl_count %d\n", __func__, 1133 dprintk("%s ino %lu, how %d cl_count %d\n", __func__,
1115 data->inode->i_ino, how, atomic_read(&ds->ds_clp->cl_count)); 1134 data->inode->i_ino, how, atomic_read(&ds->ds_clp->cl_count));
1116 data->commit_done_cb = filelayout_commit_done_cb; 1135 data->commit_done_cb = filelayout_commit_done_cb;
@@ -1119,9 +1138,13 @@ static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
1119 fh = select_ds_fh_from_commit(lseg, data->ds_commit_index); 1138 fh = select_ds_fh_from_commit(lseg, data->ds_commit_index);
1120 if (fh) 1139 if (fh)
1121 data->args.fh = fh; 1140 data->args.fh = fh;
1122 return nfs_initiate_commit(ds->ds_clp->cl_rpcclient, data, 1141 return nfs_initiate_commit(ds_clnt, data,
1123 &filelayout_commit_call_ops, how, 1142 &filelayout_commit_call_ops, how,
1124 RPC_TASK_SOFTCONN); 1143 RPC_TASK_SOFTCONN);
1144out_err:
1145 prepare_to_resend_writes(data);
1146 filelayout_commit_release(data);
1147 return -EAGAIN;
1125} 1148}
1126 1149
1127static int 1150static int
diff --git a/fs/nfs/nfs4getroot.c b/fs/nfs/nfs4getroot.c
index 549462e5b9b0..c0b3a16b4a00 100644
--- a/fs/nfs/nfs4getroot.c
+++ b/fs/nfs/nfs4getroot.c
@@ -9,7 +9,7 @@
9 9
10#define NFSDBG_FACILITY NFSDBG_CLIENT 10#define NFSDBG_FACILITY NFSDBG_CLIENT
11 11
12int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) 12int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool auth_probe)
13{ 13{
14 struct nfs_fsinfo fsinfo; 14 struct nfs_fsinfo fsinfo;
15 int ret = -ENOMEM; 15 int ret = -ENOMEM;
@@ -21,7 +21,7 @@ int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh)
21 goto out; 21 goto out;
22 22
23 /* Start by getting the root filehandle from the server */ 23 /* Start by getting the root filehandle from the server */
24 ret = nfs4_proc_get_rootfh(server, mntfh, &fsinfo); 24 ret = nfs4_proc_get_rootfh(server, mntfh, &fsinfo, auth_probe);
25 if (ret < 0) { 25 if (ret < 0) {
26 dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret); 26 dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret);
27 goto out; 27 goto out;
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index cdb0b41a4810..2288cd3c9278 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -11,6 +11,7 @@
11#include <linux/mount.h> 11#include <linux/mount.h>
12#include <linux/namei.h> 12#include <linux/namei.h>
13#include <linux/nfs_fs.h> 13#include <linux/nfs_fs.h>
14#include <linux/nfs_mount.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include <linux/string.h> 16#include <linux/string.h>
16#include <linux/sunrpc/clnt.h> 17#include <linux/sunrpc/clnt.h>
@@ -369,21 +370,33 @@ out:
369struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry, 370struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry,
370 struct nfs_fh *fh, struct nfs_fattr *fattr) 371 struct nfs_fh *fh, struct nfs_fattr *fattr)
371{ 372{
373 rpc_authflavor_t flavor = server->client->cl_auth->au_flavor;
372 struct dentry *parent = dget_parent(dentry); 374 struct dentry *parent = dget_parent(dentry);
375 struct inode *dir = parent->d_inode;
376 struct qstr *name = &dentry->d_name;
373 struct rpc_clnt *client; 377 struct rpc_clnt *client;
374 struct vfsmount *mnt; 378 struct vfsmount *mnt;
375 379
376 /* Look it up again to get its attributes and sec flavor */ 380 /* Look it up again to get its attributes and sec flavor */
377 client = nfs4_proc_lookup_mountpoint(parent->d_inode, &dentry->d_name, fh, fattr); 381 client = nfs4_proc_lookup_mountpoint(dir, name, fh, fattr);
378 dput(parent); 382 dput(parent);
379 if (IS_ERR(client)) 383 if (IS_ERR(client))
380 return ERR_CAST(client); 384 return ERR_CAST(client);
381 385
382 if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) 386 if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
383 mnt = nfs_do_refmount(client, dentry); 387 mnt = nfs_do_refmount(client, dentry);
384 else 388 goto out;
385 mnt = nfs_do_submount(dentry, fh, fattr, client->cl_auth->au_flavor); 389 }
386 390
391 if (client->cl_auth->au_flavor != flavor)
392 flavor = client->cl_auth->au_flavor;
393 else if (!(server->flags & NFS_MOUNT_SECFLAVOUR)) {
394 rpc_authflavor_t new = nfs4_negotiate_security(dir, name);
395 if ((int)new >= 0)
396 flavor = new;
397 }
398 mnt = nfs_do_submount(dentry, fh, fattr, flavor);
399out:
387 rpc_shutdown_client(client); 400 rpc_shutdown_client(client);
388 return mnt; 401 return mnt;
389} 402}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 108a774095f7..39b6cf2d1683 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -66,6 +66,8 @@
66#include "nfs4session.h" 66#include "nfs4session.h"
67#include "fscache.h" 67#include "fscache.h"
68 68
69#include "nfs4trace.h"
70
69#define NFSDBG_FACILITY NFSDBG_PROC 71#define NFSDBG_FACILITY NFSDBG_PROC
70 72
71#define NFS4_POLL_RETRY_MIN (HZ/10) 73#define NFS4_POLL_RETRY_MIN (HZ/10)
@@ -150,6 +152,7 @@ static int nfs4_map_errors(int err)
150 case -NFS4ERR_RECALLCONFLICT: 152 case -NFS4ERR_RECALLCONFLICT:
151 return -EREMOTEIO; 153 return -EREMOTEIO;
152 case -NFS4ERR_WRONGSEC: 154 case -NFS4ERR_WRONGSEC:
155 case -NFS4ERR_WRONG_CRED:
153 return -EPERM; 156 return -EPERM;
154 case -NFS4ERR_BADOWNER: 157 case -NFS4ERR_BADOWNER:
155 case -NFS4ERR_BADNAME: 158 case -NFS4ERR_BADNAME:
@@ -433,6 +436,20 @@ wait_on_recovery:
433 return ret; 436 return ret;
434} 437}
435 438
439/*
440 * Return 'true' if 'clp' is using an rpc_client that is integrity protected
441 * or 'false' otherwise.
442 */
443static bool _nfs4_is_integrity_protected(struct nfs_client *clp)
444{
445 rpc_authflavor_t flavor = clp->cl_rpcclient->cl_auth->au_flavor;
446
447 if (flavor == RPC_AUTH_GSS_KRB5I ||
448 flavor == RPC_AUTH_GSS_KRB5P)
449 return true;
450
451 return false;
452}
436 453
437static void do_renew_lease(struct nfs_client *clp, unsigned long timestamp) 454static void do_renew_lease(struct nfs_client *clp, unsigned long timestamp)
438{ 455{
@@ -447,6 +464,88 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
447 do_renew_lease(server->nfs_client, timestamp); 464 do_renew_lease(server->nfs_client, timestamp);
448} 465}
449 466
467struct nfs4_call_sync_data {
468 const struct nfs_server *seq_server;
469 struct nfs4_sequence_args *seq_args;
470 struct nfs4_sequence_res *seq_res;
471};
472
473static void nfs4_init_sequence(struct nfs4_sequence_args *args,
474 struct nfs4_sequence_res *res, int cache_reply)
475{
476 args->sa_slot = NULL;
477 args->sa_cache_this = cache_reply;
478 args->sa_privileged = 0;
479
480 res->sr_slot = NULL;
481}
482
483static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
484{
485 args->sa_privileged = 1;
486}
487
488static int nfs40_setup_sequence(const struct nfs_server *server,
489 struct nfs4_sequence_args *args,
490 struct nfs4_sequence_res *res,
491 struct rpc_task *task)
492{
493 struct nfs4_slot_table *tbl = server->nfs_client->cl_slot_tbl;
494 struct nfs4_slot *slot;
495
496 /* slot already allocated? */
497 if (res->sr_slot != NULL)
498 goto out_start;
499
500 spin_lock(&tbl->slot_tbl_lock);
501 if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
502 goto out_sleep;
503
504 slot = nfs4_alloc_slot(tbl);
505 if (IS_ERR(slot)) {
506 if (slot == ERR_PTR(-ENOMEM))
507 task->tk_timeout = HZ >> 2;
508 goto out_sleep;
509 }
510 spin_unlock(&tbl->slot_tbl_lock);
511
512 args->sa_slot = slot;
513 res->sr_slot = slot;
514
515out_start:
516 rpc_call_start(task);
517 return 0;
518
519out_sleep:
520 if (args->sa_privileged)
521 rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
522 NULL, RPC_PRIORITY_PRIVILEGED);
523 else
524 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
525 spin_unlock(&tbl->slot_tbl_lock);
526 return -EAGAIN;
527}
528
529static int nfs40_sequence_done(struct rpc_task *task,
530 struct nfs4_sequence_res *res)
531{
532 struct nfs4_slot *slot = res->sr_slot;
533 struct nfs4_slot_table *tbl;
534
535 if (!RPC_WAS_SENT(task))
536 goto out;
537
538 tbl = slot->table;
539 spin_lock(&tbl->slot_tbl_lock);
540 if (!nfs41_wake_and_assign_slot(tbl, slot))
541 nfs4_free_slot(tbl, slot);
542 spin_unlock(&tbl->slot_tbl_lock);
543
544 res->sr_slot = NULL;
545out:
546 return 1;
547}
548
450#if defined(CONFIG_NFS_V4_1) 549#if defined(CONFIG_NFS_V4_1)
451 550
452static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) 551static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
@@ -506,6 +605,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
506 interrupted = true; 605 interrupted = true;
507 } 606 }
508 607
608 trace_nfs4_sequence_done(session, res);
509 /* Check the SEQUENCE operation status */ 609 /* Check the SEQUENCE operation status */
510 switch (res->sr_status) { 610 switch (res->sr_status) {
511 case 0: 611 case 0:
@@ -591,25 +691,11 @@ static int nfs4_sequence_done(struct rpc_task *task,
591{ 691{
592 if (res->sr_slot == NULL) 692 if (res->sr_slot == NULL)
593 return 1; 693 return 1;
694 if (!res->sr_slot->table->session)
695 return nfs40_sequence_done(task, res);
594 return nfs41_sequence_done(task, res); 696 return nfs41_sequence_done(task, res);
595} 697}
596 698
597static void nfs41_init_sequence(struct nfs4_sequence_args *args,
598 struct nfs4_sequence_res *res, int cache_reply)
599{
600 args->sa_slot = NULL;
601 args->sa_cache_this = 0;
602 args->sa_privileged = 0;
603 if (cache_reply)
604 args->sa_cache_this = 1;
605 res->sr_slot = NULL;
606}
607
608static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
609{
610 args->sa_privileged = 1;
611}
612
613int nfs41_setup_sequence(struct nfs4_session *session, 699int nfs41_setup_sequence(struct nfs4_session *session,
614 struct nfs4_sequence_args *args, 700 struct nfs4_sequence_args *args,
615 struct nfs4_sequence_res *res, 701 struct nfs4_sequence_res *res,
@@ -647,7 +733,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
647 733
648 args->sa_slot = slot; 734 args->sa_slot = slot;
649 735
650 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, 736 dprintk("<-- %s slotid=%u seqid=%u\n", __func__,
651 slot->slot_nr, slot->seq_nr); 737 slot->slot_nr, slot->seq_nr);
652 738
653 res->sr_slot = slot; 739 res->sr_slot = slot;
@@ -658,6 +744,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
658 * set to 1 if an rpc level failure occurs. 744 * set to 1 if an rpc level failure occurs.
659 */ 745 */
660 res->sr_status = 1; 746 res->sr_status = 1;
747 trace_nfs4_setup_sequence(session, args);
661out_success: 748out_success:
662 rpc_call_start(task); 749 rpc_call_start(task);
663 return 0; 750 return 0;
@@ -673,38 +760,30 @@ out_sleep:
673} 760}
674EXPORT_SYMBOL_GPL(nfs41_setup_sequence); 761EXPORT_SYMBOL_GPL(nfs41_setup_sequence);
675 762
676int nfs4_setup_sequence(const struct nfs_server *server, 763static int nfs4_setup_sequence(const struct nfs_server *server,
677 struct nfs4_sequence_args *args, 764 struct nfs4_sequence_args *args,
678 struct nfs4_sequence_res *res, 765 struct nfs4_sequence_res *res,
679 struct rpc_task *task) 766 struct rpc_task *task)
680{ 767{
681 struct nfs4_session *session = nfs4_get_session(server); 768 struct nfs4_session *session = nfs4_get_session(server);
682 int ret = 0; 769 int ret = 0;
683 770
684 if (session == NULL) { 771 if (!session)
685 rpc_call_start(task); 772 return nfs40_setup_sequence(server, args, res, task);
686 goto out;
687 }
688 773
689 dprintk("--> %s clp %p session %p sr_slot %d\n", 774 dprintk("--> %s clp %p session %p sr_slot %u\n",
690 __func__, session->clp, session, res->sr_slot ? 775 __func__, session->clp, session, res->sr_slot ?
691 res->sr_slot->slot_nr : -1); 776 res->sr_slot->slot_nr : NFS4_NO_SLOT);
692 777
693 ret = nfs41_setup_sequence(session, args, res, task); 778 ret = nfs41_setup_sequence(session, args, res, task);
694out: 779
695 dprintk("<-- %s status=%d\n", __func__, ret); 780 dprintk("<-- %s status=%d\n", __func__, ret);
696 return ret; 781 return ret;
697} 782}
698 783
699struct nfs41_call_sync_data {
700 const struct nfs_server *seq_server;
701 struct nfs4_sequence_args *seq_args;
702 struct nfs4_sequence_res *seq_res;
703};
704
705static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata) 784static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
706{ 785{
707 struct nfs41_call_sync_data *data = calldata; 786 struct nfs4_call_sync_data *data = calldata;
708 struct nfs4_session *session = nfs4_get_session(data->seq_server); 787 struct nfs4_session *session = nfs4_get_session(data->seq_server);
709 788
710 dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server); 789 dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);
@@ -714,7 +793,7 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
714 793
715static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 794static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
716{ 795{
717 struct nfs41_call_sync_data *data = calldata; 796 struct nfs4_call_sync_data *data = calldata;
718 797
719 nfs41_sequence_done(task, data->seq_res); 798 nfs41_sequence_done(task, data->seq_res);
720} 799}
@@ -724,6 +803,42 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {
724 .rpc_call_done = nfs41_call_sync_done, 803 .rpc_call_done = nfs41_call_sync_done,
725}; 804};
726 805
806#else /* !CONFIG_NFS_V4_1 */
807
808static int nfs4_setup_sequence(const struct nfs_server *server,
809 struct nfs4_sequence_args *args,
810 struct nfs4_sequence_res *res,
811 struct rpc_task *task)
812{
813 return nfs40_setup_sequence(server, args, res, task);
814}
815
816static int nfs4_sequence_done(struct rpc_task *task,
817 struct nfs4_sequence_res *res)
818{
819 return nfs40_sequence_done(task, res);
820}
821
822#endif /* !CONFIG_NFS_V4_1 */
823
824static void nfs40_call_sync_prepare(struct rpc_task *task, void *calldata)
825{
826 struct nfs4_call_sync_data *data = calldata;
827 nfs4_setup_sequence(data->seq_server,
828 data->seq_args, data->seq_res, task);
829}
830
831static void nfs40_call_sync_done(struct rpc_task *task, void *calldata)
832{
833 struct nfs4_call_sync_data *data = calldata;
834 nfs4_sequence_done(task, data->seq_res);
835}
836
837static const struct rpc_call_ops nfs40_call_sync_ops = {
838 .rpc_call_prepare = nfs40_call_sync_prepare,
839 .rpc_call_done = nfs40_call_sync_done,
840};
841
727static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, 842static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
728 struct nfs_server *server, 843 struct nfs_server *server,
729 struct rpc_message *msg, 844 struct rpc_message *msg,
@@ -732,7 +847,8 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
732{ 847{
733 int ret; 848 int ret;
734 struct rpc_task *task; 849 struct rpc_task *task;
735 struct nfs41_call_sync_data data = { 850 struct nfs_client *clp = server->nfs_client;
851 struct nfs4_call_sync_data data = {
736 .seq_server = server, 852 .seq_server = server,
737 .seq_args = args, 853 .seq_args = args,
738 .seq_res = res, 854 .seq_res = res,
@@ -740,7 +856,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
740 struct rpc_task_setup task_setup = { 856 struct rpc_task_setup task_setup = {
741 .rpc_client = clnt, 857 .rpc_client = clnt,
742 .rpc_message = msg, 858 .rpc_message = msg,
743 .callback_ops = &nfs41_call_sync_ops, 859 .callback_ops = clp->cl_mvops->call_sync_ops,
744 .callback_data = &data 860 .callback_data = &data
745 }; 861 };
746 862
@@ -754,35 +870,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
754 return ret; 870 return ret;
755} 871}
756 872
757#else
758static
759void nfs41_init_sequence(struct nfs4_sequence_args *args,
760 struct nfs4_sequence_res *res, int cache_reply)
761{
762}
763
764static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
765{
766}
767
768
769static int nfs4_sequence_done(struct rpc_task *task,
770 struct nfs4_sequence_res *res)
771{
772 return 1;
773}
774#endif /* CONFIG_NFS_V4_1 */
775
776static
777int _nfs4_call_sync(struct rpc_clnt *clnt,
778 struct nfs_server *server,
779 struct rpc_message *msg,
780 struct nfs4_sequence_args *args,
781 struct nfs4_sequence_res *res)
782{
783 return rpc_call_sync(clnt, msg, 0);
784}
785
786static 873static
787int nfs4_call_sync(struct rpc_clnt *clnt, 874int nfs4_call_sync(struct rpc_clnt *clnt,
788 struct nfs_server *server, 875 struct nfs_server *server,
@@ -791,9 +878,8 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
791 struct nfs4_sequence_res *res, 878 struct nfs4_sequence_res *res,
792 int cache_reply) 879 int cache_reply)
793{ 880{
794 nfs41_init_sequence(args, res, cache_reply); 881 nfs4_init_sequence(args, res, cache_reply);
795 return server->nfs_client->cl_mvops->call_sync(clnt, server, msg, 882 return nfs4_call_sync_sequence(clnt, server, msg, args, res);
796 args, res);
797} 883}
798 884
799static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 885static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
@@ -933,7 +1019,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
933 p->o_arg.fh = NFS_FH(dentry->d_inode); 1019 p->o_arg.fh = NFS_FH(dentry->d_inode);
934 } 1020 }
935 if (attrs != NULL && attrs->ia_valid != 0) { 1021 if (attrs != NULL && attrs->ia_valid != 0) {
936 __be32 verf[2]; 1022 __u32 verf[2];
937 1023
938 p->o_arg.u.attrs = &p->attrs; 1024 p->o_arg.u.attrs = &p->attrs;
939 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 1025 memcpy(&p->attrs, attrs, sizeof(p->attrs));
@@ -1103,7 +1189,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
1103 goto no_delegation; 1189 goto no_delegation;
1104 1190
1105 spin_lock(&deleg_cur->lock); 1191 spin_lock(&deleg_cur->lock);
1106 if (nfsi->delegation != deleg_cur || 1192 if (rcu_dereference(nfsi->delegation) != deleg_cur ||
1107 test_bit(NFS_DELEGATION_RETURNING, &deleg_cur->flags) || 1193 test_bit(NFS_DELEGATION_RETURNING, &deleg_cur->flags) ||
1108 (deleg_cur->type & fmode) != fmode) 1194 (deleg_cur->type & fmode) != fmode)
1109 goto no_delegation_unlock; 1195 goto no_delegation_unlock;
@@ -1440,6 +1526,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1440 int err; 1526 int err;
1441 do { 1527 do {
1442 err = _nfs4_do_open_reclaim(ctx, state); 1528 err = _nfs4_do_open_reclaim(ctx, state);
1529 trace_nfs4_open_reclaim(ctx, 0, err);
1443 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception)) 1530 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
1444 continue; 1531 continue;
1445 if (err != -NFS4ERR_DELAY) 1532 if (err != -NFS4ERR_DELAY)
@@ -1524,10 +1611,20 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1524 return nfs4_handle_delegation_recall_error(server, state, stateid, err); 1611 return nfs4_handle_delegation_recall_error(server, state, stateid, err);
1525} 1612}
1526 1613
1614static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
1615{
1616 struct nfs4_opendata *data = calldata;
1617
1618 nfs40_setup_sequence(data->o_arg.server, &data->o_arg.seq_args,
1619 &data->o_res.seq_res, task);
1620}
1621
1527static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) 1622static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
1528{ 1623{
1529 struct nfs4_opendata *data = calldata; 1624 struct nfs4_opendata *data = calldata;
1530 1625
1626 nfs40_sequence_done(task, &data->o_res.seq_res);
1627
1531 data->rpc_status = task->tk_status; 1628 data->rpc_status = task->tk_status;
1532 if (data->rpc_status == 0) { 1629 if (data->rpc_status == 0) {
1533 nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid); 1630 nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid);
@@ -1556,6 +1653,7 @@ out_free:
1556} 1653}
1557 1654
1558static const struct rpc_call_ops nfs4_open_confirm_ops = { 1655static const struct rpc_call_ops nfs4_open_confirm_ops = {
1656 .rpc_call_prepare = nfs4_open_confirm_prepare,
1559 .rpc_call_done = nfs4_open_confirm_done, 1657 .rpc_call_done = nfs4_open_confirm_done,
1560 .rpc_release = nfs4_open_confirm_release, 1658 .rpc_release = nfs4_open_confirm_release,
1561}; 1659};
@@ -1583,6 +1681,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
1583 }; 1681 };
1584 int status; 1682 int status;
1585 1683
1684 nfs4_init_sequence(&data->o_arg.seq_args, &data->o_res.seq_res, 1);
1586 kref_get(&data->kref); 1685 kref_get(&data->kref);
1587 data->rpc_done = 0; 1686 data->rpc_done = 0;
1588 data->rpc_status = 0; 1687 data->rpc_status = 0;
@@ -1742,7 +1841,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1742 }; 1841 };
1743 int status; 1842 int status;
1744 1843
1745 nfs41_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1); 1844 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);
1746 kref_get(&data->kref); 1845 kref_get(&data->kref);
1747 data->rpc_done = 0; 1846 data->rpc_done = 0;
1748 data->rpc_status = 0; 1847 data->rpc_status = 0;
@@ -1895,6 +1994,7 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state
1895 1994
1896 do { 1995 do {
1897 err = _nfs4_open_expired(ctx, state); 1996 err = _nfs4_open_expired(ctx, state);
1997 trace_nfs4_open_expired(ctx, 0, err);
1898 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception)) 1998 if (nfs4_clear_cap_atomic_open_v1(server, err, &exception))
1899 continue; 1999 continue;
1900 switch (err) { 2000 switch (err) {
@@ -1944,6 +2044,7 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
1944 cred = get_rpccred(delegation->cred); 2044 cred = get_rpccred(delegation->cred);
1945 rcu_read_unlock(); 2045 rcu_read_unlock();
1946 status = nfs41_test_stateid(server, stateid, cred); 2046 status = nfs41_test_stateid(server, stateid, cred);
2047 trace_nfs4_test_delegation_stateid(state, NULL, status);
1947 } else 2048 } else
1948 rcu_read_unlock(); 2049 rcu_read_unlock();
1949 2050
@@ -1986,6 +2087,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
1986 return -NFS4ERR_BAD_STATEID; 2087 return -NFS4ERR_BAD_STATEID;
1987 2088
1988 status = nfs41_test_stateid(server, stateid, cred); 2089 status = nfs41_test_stateid(server, stateid, cred);
2090 trace_nfs4_test_open_stateid(state, NULL, status);
1989 if (status != NFS_OK) { 2091 if (status != NFS_OK) {
1990 /* Free the stateid unless the server explicitly 2092 /* Free the stateid unless the server explicitly
1991 * informs us the stateid is unrecognized. */ 2093 * informs us the stateid is unrecognized. */
@@ -2197,6 +2299,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
2197 do { 2299 do {
2198 status = _nfs4_do_open(dir, ctx, flags, sattr, label); 2300 status = _nfs4_do_open(dir, ctx, flags, sattr, label);
2199 res = ctx->state; 2301 res = ctx->state;
2302 trace_nfs4_open_file(ctx, flags, status);
2200 if (status == 0) 2303 if (status == 0)
2201 break; 2304 break;
2202 /* NOTE: BAD_SEQID means the server and client disagree about the 2305 /* NOTE: BAD_SEQID means the server and client disagree about the
@@ -2310,6 +2413,7 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2310 int err; 2413 int err;
2311 do { 2414 do {
2312 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel); 2415 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel);
2416 trace_nfs4_setattr(inode, err);
2313 switch (err) { 2417 switch (err) {
2314 case -NFS4ERR_OPENMODE: 2418 case -NFS4ERR_OPENMODE:
2315 if (!(sattr->ia_valid & ATTR_SIZE)) { 2419 if (!(sattr->ia_valid & ATTR_SIZE)) {
@@ -2387,6 +2491,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2387 dprintk("%s: begin!\n", __func__); 2491 dprintk("%s: begin!\n", __func__);
2388 if (!nfs4_sequence_done(task, &calldata->res.seq_res)) 2492 if (!nfs4_sequence_done(task, &calldata->res.seq_res))
2389 return; 2493 return;
2494 trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);
2390 /* hmm. we are done with the inode, and in the process of freeing 2495 /* hmm. we are done with the inode, and in the process of freeing
2391 * the state_owner. we keep this around to process errors 2496 * the state_owner. we keep this around to process errors
2392 */ 2497 */
@@ -2511,10 +2616,13 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
2511 }; 2616 };
2512 int status = -ENOMEM; 2617 int status = -ENOMEM;
2513 2618
2619 nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP,
2620 &task_setup_data.rpc_client, &msg);
2621
2514 calldata = kzalloc(sizeof(*calldata), gfp_mask); 2622 calldata = kzalloc(sizeof(*calldata), gfp_mask);
2515 if (calldata == NULL) 2623 if (calldata == NULL)
2516 goto out; 2624 goto out;
2517 nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 1); 2625 nfs4_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 1);
2518 calldata->inode = state->inode; 2626 calldata->inode = state->inode;
2519 calldata->state = state; 2627 calldata->state = state;
2520 calldata->arg.fh = NFS_FH(state->inode); 2628 calldata->arg.fh = NFS_FH(state->inode);
@@ -2690,6 +2798,7 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2690 int err; 2798 int err;
2691 do { 2799 do {
2692 err = _nfs4_lookup_root(server, fhandle, info); 2800 err = _nfs4_lookup_root(server, fhandle, info);
2801 trace_nfs4_lookup_root(server, fhandle, info->fattr, err);
2693 switch (err) { 2802 switch (err) {
2694 case 0: 2803 case 0:
2695 case -NFS4ERR_WRONGSEC: 2804 case -NFS4ERR_WRONGSEC:
@@ -2705,10 +2814,13 @@ out:
2705static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, 2814static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2706 struct nfs_fsinfo *info, rpc_authflavor_t flavor) 2815 struct nfs_fsinfo *info, rpc_authflavor_t flavor)
2707{ 2816{
2817 struct rpc_auth_create_args auth_args = {
2818 .pseudoflavor = flavor,
2819 };
2708 struct rpc_auth *auth; 2820 struct rpc_auth *auth;
2709 int ret; 2821 int ret;
2710 2822
2711 auth = rpcauth_create(flavor, server->client); 2823 auth = rpcauth_create(&auth_args, server->client);
2712 if (IS_ERR(auth)) { 2824 if (IS_ERR(auth)) {
2713 ret = -EACCES; 2825 ret = -EACCES;
2714 goto out; 2826 goto out;
@@ -2772,18 +2884,27 @@ static int nfs4_do_find_root_sec(struct nfs_server *server,
2772 * @server: initialized nfs_server handle 2884 * @server: initialized nfs_server handle
2773 * @fhandle: we fill in the pseudo-fs root file handle 2885 * @fhandle: we fill in the pseudo-fs root file handle
2774 * @info: we fill in an FSINFO struct 2886 * @info: we fill in an FSINFO struct
2887 * @auth_probe: probe the auth flavours
2775 * 2888 *
2776 * Returns zero on success, or a negative errno. 2889 * Returns zero on success, or a negative errno.
2777 */ 2890 */
2778int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, 2891int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
2779 struct nfs_fsinfo *info) 2892 struct nfs_fsinfo *info,
2893 bool auth_probe)
2780{ 2894{
2781 int status; 2895 int status;
2782 2896
2783 status = nfs4_lookup_root(server, fhandle, info); 2897 switch (auth_probe) {
2784 if ((status == -NFS4ERR_WRONGSEC) && 2898 case false:
2785 !(server->flags & NFS_MOUNT_SECFLAVOUR)) 2899 status = nfs4_lookup_root(server, fhandle, info);
2900 if (status != -NFS4ERR_WRONGSEC)
2901 break;
2902 /* Did user force a 'sec=' mount option? */
2903 if (server->flags & NFS_MOUNT_SECFLAVOUR)
2904 break;
2905 default:
2786 status = nfs4_do_find_root_sec(server, fhandle, info); 2906 status = nfs4_do_find_root_sec(server, fhandle, info);
2907 }
2787 2908
2788 if (status == 0) 2909 if (status == 0)
2789 status = nfs4_server_capabilities(server, fhandle); 2910 status = nfs4_server_capabilities(server, fhandle);
@@ -2899,8 +3020,9 @@ static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2899 struct nfs4_exception exception = { }; 3020 struct nfs4_exception exception = { };
2900 int err; 3021 int err;
2901 do { 3022 do {
2902 err = nfs4_handle_exception(server, 3023 err = _nfs4_proc_getattr(server, fhandle, fattr, label);
2903 _nfs4_proc_getattr(server, fhandle, fattr, label), 3024 trace_nfs4_getattr(server, fhandle, fattr, err);
3025 err = nfs4_handle_exception(server, err,
2904 &exception); 3026 &exception);
2905 } while (exception.retry); 3027 } while (exception.retry);
2906 return err; 3028 return err;
@@ -2940,10 +3062,10 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2940 3062
2941 /* Deal with open(O_TRUNC) */ 3063 /* Deal with open(O_TRUNC) */
2942 if (sattr->ia_valid & ATTR_OPEN) 3064 if (sattr->ia_valid & ATTR_OPEN)
2943 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); 3065 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME);
2944 3066
2945 /* Optimization: if the end result is no change, don't RPC */ 3067 /* Optimization: if the end result is no change, don't RPC */
2946 if ((sattr->ia_valid & ~(ATTR_FILE)) == 0) 3068 if ((sattr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
2947 return 0; 3069 return 0;
2948 3070
2949 /* Search for an existing open(O_WRITE) file */ 3071 /* Search for an existing open(O_WRITE) file */
@@ -3020,6 +3142,7 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
3020 int err; 3142 int err;
3021 do { 3143 do {
3022 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label); 3144 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label);
3145 trace_nfs4_lookup(dir, name, err);
3023 switch (err) { 3146 switch (err) {
3024 case -NFS4ERR_BADNAME: 3147 case -NFS4ERR_BADNAME:
3025 err = -ENOENT; 3148 err = -ENOENT;
@@ -3031,7 +3154,9 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
3031 err = -EPERM; 3154 err = -EPERM;
3032 if (client != *clnt) 3155 if (client != *clnt)
3033 goto out; 3156 goto out;
3034 3157 /* No security negotiation if the user specified 'sec=' */
3158 if (NFS_SERVER(dir)->flags & NFS_MOUNT_SECFLAVOUR)
3159 goto out;
3035 client = nfs4_create_sec_client(client, dir, name); 3160 client = nfs4_create_sec_client(client, dir, name);
3036 if (IS_ERR(client)) 3161 if (IS_ERR(client))
3037 return PTR_ERR(client); 3162 return PTR_ERR(client);
@@ -3134,8 +3259,9 @@ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
3134 struct nfs4_exception exception = { }; 3259 struct nfs4_exception exception = { };
3135 int err; 3260 int err;
3136 do { 3261 do {
3137 err = nfs4_handle_exception(NFS_SERVER(inode), 3262 err = _nfs4_proc_access(inode, entry);
3138 _nfs4_proc_access(inode, entry), 3263 trace_nfs4_access(inode, err);
3264 err = nfs4_handle_exception(NFS_SERVER(inode), err,
3139 &exception); 3265 &exception);
3140 } while (exception.retry); 3266 } while (exception.retry);
3141 return err; 3267 return err;
@@ -3188,8 +3314,9 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
3188 struct nfs4_exception exception = { }; 3314 struct nfs4_exception exception = { };
3189 int err; 3315 int err;
3190 do { 3316 do {
3191 err = nfs4_handle_exception(NFS_SERVER(inode), 3317 err = _nfs4_proc_readlink(inode, page, pgbase, pglen);
3192 _nfs4_proc_readlink(inode, page, pgbase, pglen), 3318 trace_nfs4_readlink(inode, err);
3319 err = nfs4_handle_exception(NFS_SERVER(inode), err,
3193 &exception); 3320 &exception);
3194 } while (exception.retry); 3321 } while (exception.retry);
3195 return err; 3322 return err;
@@ -3253,8 +3380,9 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
3253 struct nfs4_exception exception = { }; 3380 struct nfs4_exception exception = { };
3254 int err; 3381 int err;
3255 do { 3382 do {
3256 err = nfs4_handle_exception(NFS_SERVER(dir), 3383 err = _nfs4_proc_remove(dir, name);
3257 _nfs4_proc_remove(dir, name), 3384 trace_nfs4_remove(dir, name, err);
3385 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3258 &exception); 3386 &exception);
3259 } while (exception.retry); 3387 } while (exception.retry);
3260 return err; 3388 return err;
@@ -3268,7 +3396,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
3268 3396
3269 res->server = server; 3397 res->server = server;
3270 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; 3398 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
3271 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1); 3399 nfs4_init_sequence(&args->seq_args, &res->seq_res, 1);
3272 3400
3273 nfs_fattr_init(res->dir_attr); 3401 nfs_fattr_init(res->dir_attr);
3274} 3402}
@@ -3283,7 +3411,8 @@ static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlin
3283 3411
3284static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) 3412static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
3285{ 3413{
3286 struct nfs_removeres *res = task->tk_msg.rpc_resp; 3414 struct nfs_unlinkdata *data = task->tk_calldata;
3415 struct nfs_removeres *res = &data->res;
3287 3416
3288 if (!nfs4_sequence_done(task, &res->seq_res)) 3417 if (!nfs4_sequence_done(task, &res->seq_res))
3289 return 0; 3418 return 0;
@@ -3301,7 +3430,7 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
3301 3430
3302 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME]; 3431 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
3303 res->server = server; 3432 res->server = server;
3304 nfs41_init_sequence(&arg->seq_args, &res->seq_res, 1); 3433 nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1);
3305} 3434}
3306 3435
3307static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data) 3436static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
@@ -3315,7 +3444,8 @@ static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renam
3315static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, 3444static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
3316 struct inode *new_dir) 3445 struct inode *new_dir)
3317{ 3446{
3318 struct nfs_renameres *res = task->tk_msg.rpc_resp; 3447 struct nfs_renamedata *data = task->tk_calldata;
3448 struct nfs_renameres *res = &data->res;
3319 3449
3320 if (!nfs4_sequence_done(task, &res->seq_res)) 3450 if (!nfs4_sequence_done(task, &res->seq_res))
3321 return 0; 3451 return 0;
@@ -3361,9 +3491,10 @@ static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
3361 struct nfs4_exception exception = { }; 3491 struct nfs4_exception exception = { };
3362 int err; 3492 int err;
3363 do { 3493 do {
3364 err = nfs4_handle_exception(NFS_SERVER(old_dir), 3494 err = _nfs4_proc_rename(old_dir, old_name,
3365 _nfs4_proc_rename(old_dir, old_name, 3495 new_dir, new_name);
3366 new_dir, new_name), 3496 trace_nfs4_rename(old_dir, old_name, new_dir, new_name, err);
3497 err = nfs4_handle_exception(NFS_SERVER(old_dir), err,
3367 &exception); 3498 &exception);
3368 } while (exception.retry); 3499 } while (exception.retry);
3369 return err; 3500 return err;
@@ -3525,9 +3656,9 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
3525 label = nfs4_label_init_security(dir, dentry, sattr, &l); 3656 label = nfs4_label_init_security(dir, dentry, sattr, &l);
3526 3657
3527 do { 3658 do {
3528 err = nfs4_handle_exception(NFS_SERVER(dir), 3659 err = _nfs4_proc_symlink(dir, dentry, page, len, sattr, label);
3529 _nfs4_proc_symlink(dir, dentry, page, 3660 trace_nfs4_symlink(dir, &dentry->d_name, err);
3530 len, sattr, label), 3661 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3531 &exception); 3662 &exception);
3532 } while (exception.retry); 3663 } while (exception.retry);
3533 3664
@@ -3564,8 +3695,9 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
3564 3695
3565 sattr->ia_mode &= ~current_umask(); 3696 sattr->ia_mode &= ~current_umask();
3566 do { 3697 do {
3567 err = nfs4_handle_exception(NFS_SERVER(dir), 3698 err = _nfs4_proc_mkdir(dir, dentry, sattr, label);
3568 _nfs4_proc_mkdir(dir, dentry, sattr, label), 3699 trace_nfs4_mkdir(dir, &dentry->d_name, err);
3700 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3569 &exception); 3701 &exception);
3570 } while (exception.retry); 3702 } while (exception.retry);
3571 nfs4_label_release_security(label); 3703 nfs4_label_release_security(label);
@@ -3618,9 +3750,10 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
3618 struct nfs4_exception exception = { }; 3750 struct nfs4_exception exception = { };
3619 int err; 3751 int err;
3620 do { 3752 do {
3621 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), 3753 err = _nfs4_proc_readdir(dentry, cred, cookie,
3622 _nfs4_proc_readdir(dentry, cred, cookie, 3754 pages, count, plus);
3623 pages, count, plus), 3755 trace_nfs4_readdir(dentry->d_inode, err);
3756 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), err,
3624 &exception); 3757 &exception);
3625 } while (exception.retry); 3758 } while (exception.retry);
3626 return err; 3759 return err;
@@ -3672,8 +3805,9 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3672 3805
3673 sattr->ia_mode &= ~current_umask(); 3806 sattr->ia_mode &= ~current_umask();
3674 do { 3807 do {
3675 err = nfs4_handle_exception(NFS_SERVER(dir), 3808 err = _nfs4_proc_mknod(dir, dentry, sattr, label, rdev);
3676 _nfs4_proc_mknod(dir, dentry, sattr, label, rdev), 3809 trace_nfs4_mknod(dir, &dentry->d_name, err);
3810 err = nfs4_handle_exception(NFS_SERVER(dir), err,
3677 &exception); 3811 &exception);
3678 } while (exception.retry); 3812 } while (exception.retry);
3679 3813
@@ -3741,6 +3875,7 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
3741 3875
3742 do { 3876 do {
3743 err = _nfs4_do_fsinfo(server, fhandle, fsinfo); 3877 err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
3878 trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err);
3744 if (err == 0) { 3879 if (err == 0) {
3745 struct nfs_client *clp = server->nfs_client; 3880 struct nfs_client *clp = server->nfs_client;
3746 3881
@@ -3859,6 +3994,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3859{ 3994{
3860 struct nfs_server *server = NFS_SERVER(data->header->inode); 3995 struct nfs_server *server = NFS_SERVER(data->header->inode);
3861 3996
3997 trace_nfs4_read(data, task->tk_status);
3862 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3998 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
3863 rpc_restart_call_prepare(task); 3999 rpc_restart_call_prepare(task);
3864 return -EAGAIN; 4000 return -EAGAIN;
@@ -3902,24 +4038,29 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
3902 data->timestamp = jiffies; 4038 data->timestamp = jiffies;
3903 data->read_done_cb = nfs4_read_done_cb; 4039 data->read_done_cb = nfs4_read_done_cb;
3904 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; 4040 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
3905 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 0); 4041 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
3906} 4042}
3907 4043
3908static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 4044static int nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
3909{ 4045{
3910 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), 4046 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3911 &data->args.seq_args, 4047 &data->args.seq_args,
3912 &data->res.seq_res, 4048 &data->res.seq_res,
3913 task)) 4049 task))
3914 return; 4050 return 0;
3915 nfs4_set_rw_stateid(&data->args.stateid, data->args.context, 4051 if (nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
3916 data->args.lock_context, FMODE_READ); 4052 data->args.lock_context, FMODE_READ) == -EIO)
4053 return -EIO;
4054 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
4055 return -EIO;
4056 return 0;
3917} 4057}
3918 4058
3919static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) 4059static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
3920{ 4060{
3921 struct inode *inode = data->header->inode; 4061 struct inode *inode = data->header->inode;
3922 4062
4063 trace_nfs4_write(data, task->tk_status);
3923 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 4064 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3924 rpc_restart_call_prepare(task); 4065 rpc_restart_call_prepare(task);
3925 return -EAGAIN; 4066 return -EAGAIN;
@@ -3985,18 +4126,22 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
3985 data->timestamp = jiffies; 4126 data->timestamp = jiffies;
3986 4127
3987 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; 4128 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
3988 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4129 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
3989} 4130}
3990 4131
3991static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 4132static int nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
3992{ 4133{
3993 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), 4134 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3994 &data->args.seq_args, 4135 &data->args.seq_args,
3995 &data->res.seq_res, 4136 &data->res.seq_res,
3996 task)) 4137 task))
3997 return; 4138 return 0;
3998 nfs4_set_rw_stateid(&data->args.stateid, data->args.context, 4139 if (nfs4_set_rw_stateid(&data->args.stateid, data->args.context,
3999 data->args.lock_context, FMODE_WRITE); 4140 data->args.lock_context, FMODE_WRITE) == -EIO)
4141 return -EIO;
4142 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags)))
4143 return -EIO;
4144 return 0;
4000} 4145}
4001 4146
4002static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) 4147static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
@@ -4011,6 +4156,7 @@ static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *da
4011{ 4156{
4012 struct inode *inode = data->inode; 4157 struct inode *inode = data->inode;
4013 4158
4159 trace_nfs4_commit(data, task->tk_status);
4014 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 4160 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
4015 rpc_restart_call_prepare(task); 4161 rpc_restart_call_prepare(task);
4016 return -EAGAIN; 4162 return -EAGAIN;
@@ -4033,7 +4179,7 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess
4033 data->commit_done_cb = nfs4_commit_done_cb; 4179 data->commit_done_cb = nfs4_commit_done_cb;
4034 data->res.server = server; 4180 data->res.server = server;
4035 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; 4181 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
4036 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4182 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
4037} 4183}
4038 4184
4039struct nfs4_renewdata { 4185struct nfs4_renewdata {
@@ -4062,6 +4208,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata)
4062 struct nfs_client *clp = data->client; 4208 struct nfs_client *clp = data->client;
4063 unsigned long timestamp = data->timestamp; 4209 unsigned long timestamp = data->timestamp;
4064 4210
4211 trace_nfs4_renew_async(clp, task->tk_status);
4065 if (task->tk_status < 0) { 4212 if (task->tk_status < 0) {
4066 /* Unless we're shutting down, schedule state recovery! */ 4213 /* Unless we're shutting down, schedule state recovery! */
4067 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0) 4214 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0)
@@ -4319,6 +4466,7 @@ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bufl
4319 ssize_t ret; 4466 ssize_t ret;
4320 do { 4467 do {
4321 ret = __nfs4_get_acl_uncached(inode, buf, buflen); 4468 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
4469 trace_nfs4_get_acl(inode, ret);
4322 if (ret >= 0) 4470 if (ret >= 0)
4323 break; 4471 break;
4324 ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); 4472 ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception);
@@ -4398,8 +4546,9 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
4398 struct nfs4_exception exception = { }; 4546 struct nfs4_exception exception = { };
4399 int err; 4547 int err;
4400 do { 4548 do {
4401 err = nfs4_handle_exception(NFS_SERVER(inode), 4549 err = __nfs4_proc_set_acl(inode, buf, buflen);
4402 __nfs4_proc_set_acl(inode, buf, buflen), 4550 trace_nfs4_set_acl(inode, err);
4551 err = nfs4_handle_exception(NFS_SERVER(inode), err,
4403 &exception); 4552 &exception);
4404 } while (exception.retry); 4553 } while (exception.retry);
4405 return err; 4554 return err;
@@ -4452,8 +4601,9 @@ static int nfs4_get_security_label(struct inode *inode, void *buf,
4452 return -EOPNOTSUPP; 4601 return -EOPNOTSUPP;
4453 4602
4454 do { 4603 do {
4455 err = nfs4_handle_exception(NFS_SERVER(inode), 4604 err = _nfs4_get_security_label(inode, buf, buflen);
4456 _nfs4_get_security_label(inode, buf, buflen), 4605 trace_nfs4_get_security_label(inode, err);
4606 err = nfs4_handle_exception(NFS_SERVER(inode), err,
4457 &exception); 4607 &exception);
4458 } while (exception.retry); 4608 } while (exception.retry);
4459 return err; 4609 return err;
@@ -4505,9 +4655,10 @@ static int nfs4_do_set_security_label(struct inode *inode,
4505 int err; 4655 int err;
4506 4656
4507 do { 4657 do {
4508 err = nfs4_handle_exception(NFS_SERVER(inode), 4658 err = _nfs4_do_set_security_label(inode, ilabel,
4509 _nfs4_do_set_security_label(inode, ilabel, 4659 fattr, olabel);
4510 fattr, olabel), 4660 trace_nfs4_set_security_label(inode, err);
4661 err = nfs4_handle_exception(NFS_SERVER(inode), err,
4511 &exception); 4662 &exception);
4512 } while (exception.retry); 4663 } while (exception.retry);
4513 return err; 4664 return err;
@@ -4630,11 +4781,11 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp,
4630 /* An impossible timestamp guarantees this value 4781 /* An impossible timestamp guarantees this value
4631 * will never match a generated boot time. */ 4782 * will never match a generated boot time. */
4632 verf[0] = 0; 4783 verf[0] = 0;
4633 verf[1] = (__be32)(NSEC_PER_SEC + 1); 4784 verf[1] = cpu_to_be32(NSEC_PER_SEC + 1);
4634 } else { 4785 } else {
4635 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); 4786 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
4636 verf[0] = (__be32)nn->boot_time.tv_sec; 4787 verf[0] = cpu_to_be32(nn->boot_time.tv_sec);
4637 verf[1] = (__be32)nn->boot_time.tv_nsec; 4788 verf[1] = cpu_to_be32(nn->boot_time.tv_nsec);
4638 } 4789 }
4639 memcpy(bootverf->data, verf, sizeof(bootverf->data)); 4790 memcpy(bootverf->data, verf, sizeof(bootverf->data));
4640} 4791}
@@ -4660,10 +4811,14 @@ static unsigned int
4660nfs4_init_uniform_client_string(const struct nfs_client *clp, 4811nfs4_init_uniform_client_string(const struct nfs_client *clp,
4661 char *buf, size_t len) 4812 char *buf, size_t len)
4662{ 4813{
4663 char *nodename = clp->cl_rpcclient->cl_nodename; 4814 const char *nodename = clp->cl_rpcclient->cl_nodename;
4664 4815
4665 if (nfs4_client_id_uniquifier[0] != '\0') 4816 if (nfs4_client_id_uniquifier[0] != '\0')
4666 nodename = nfs4_client_id_uniquifier; 4817 return scnprintf(buf, len, "Linux NFSv%u.%u %s/%s",
4818 clp->rpc_ops->version,
4819 clp->cl_minorversion,
4820 nfs4_client_id_uniquifier,
4821 nodename);
4667 return scnprintf(buf, len, "Linux NFSv%u.%u %s", 4822 return scnprintf(buf, len, "Linux NFSv%u.%u %s",
4668 clp->rpc_ops->version, clp->cl_minorversion, 4823 clp->rpc_ops->version, clp->cl_minorversion,
4669 nodename); 4824 nodename);
@@ -4724,6 +4879,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
4724 clp->cl_rpcclient->cl_auth->au_ops->au_name, 4879 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4725 setclientid.sc_name_len, setclientid.sc_name); 4880 setclientid.sc_name_len, setclientid.sc_name);
4726 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4881 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4882 trace_nfs4_setclientid(clp, status);
4727 dprintk("NFS reply setclientid: %d\n", status); 4883 dprintk("NFS reply setclientid: %d\n", status);
4728 return status; 4884 return status;
4729} 4885}
@@ -4751,6 +4907,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
4751 clp->cl_rpcclient->cl_auth->au_ops->au_name, 4907 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4752 clp->cl_clientid); 4908 clp->cl_clientid);
4753 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4909 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4910 trace_nfs4_setclientid_confirm(clp, status);
4754 dprintk("NFS reply setclientid_confirm: %d\n", status); 4911 dprintk("NFS reply setclientid_confirm: %d\n", status);
4755 return status; 4912 return status;
4756} 4913}
@@ -4772,6 +4929,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
4772 if (!nfs4_sequence_done(task, &data->res.seq_res)) 4929 if (!nfs4_sequence_done(task, &data->res.seq_res))
4773 return; 4930 return;
4774 4931
4932 trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
4775 switch (task->tk_status) { 4933 switch (task->tk_status) {
4776 case -NFS4ERR_STALE_STATEID: 4934 case -NFS4ERR_STALE_STATEID:
4777 case -NFS4ERR_EXPIRED: 4935 case -NFS4ERR_EXPIRED:
@@ -4793,7 +4951,6 @@ static void nfs4_delegreturn_release(void *calldata)
4793 kfree(calldata); 4951 kfree(calldata);
4794} 4952}
4795 4953
4796#if defined(CONFIG_NFS_V4_1)
4797static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data) 4954static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
4798{ 4955{
4799 struct nfs4_delegreturndata *d_data; 4956 struct nfs4_delegreturndata *d_data;
@@ -4805,12 +4962,9 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
4805 &d_data->res.seq_res, 4962 &d_data->res.seq_res,
4806 task); 4963 task);
4807} 4964}
4808#endif /* CONFIG_NFS_V4_1 */
4809 4965
4810static const struct rpc_call_ops nfs4_delegreturn_ops = { 4966static const struct rpc_call_ops nfs4_delegreturn_ops = {
4811#if defined(CONFIG_NFS_V4_1)
4812 .rpc_call_prepare = nfs4_delegreturn_prepare, 4967 .rpc_call_prepare = nfs4_delegreturn_prepare,
4813#endif /* CONFIG_NFS_V4_1 */
4814 .rpc_call_done = nfs4_delegreturn_done, 4968 .rpc_call_done = nfs4_delegreturn_done,
4815 .rpc_release = nfs4_delegreturn_release, 4969 .rpc_release = nfs4_delegreturn_release,
4816}; 4970};
@@ -4835,7 +4989,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
4835 data = kzalloc(sizeof(*data), GFP_NOFS); 4989 data = kzalloc(sizeof(*data), GFP_NOFS);
4836 if (data == NULL) 4990 if (data == NULL)
4837 return -ENOMEM; 4991 return -ENOMEM;
4838 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4992 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
4839 data->args.fhandle = &data->fh; 4993 data->args.fhandle = &data->fh;
4840 data->args.stateid = &data->stateid; 4994 data->args.stateid = &data->stateid;
4841 data->args.bitmask = server->cache_consistency_bitmask; 4995 data->args.bitmask = server->cache_consistency_bitmask;
@@ -4875,6 +5029,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
4875 int err; 5029 int err;
4876 do { 5030 do {
4877 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync); 5031 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
5032 trace_nfs4_delegreturn(inode, err);
4878 switch (err) { 5033 switch (err) {
4879 case -NFS4ERR_STALE_STATEID: 5034 case -NFS4ERR_STALE_STATEID:
4880 case -NFS4ERR_EXPIRED: 5035 case -NFS4ERR_EXPIRED:
@@ -4949,8 +5104,9 @@ static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *
4949 int err; 5104 int err;
4950 5105
4951 do { 5106 do {
4952 err = nfs4_handle_exception(NFS_SERVER(state->inode), 5107 err = _nfs4_proc_getlk(state, cmd, request);
4953 _nfs4_proc_getlk(state, cmd, request), 5108 trace_nfs4_get_lock(request, state, cmd, err);
5109 err = nfs4_handle_exception(NFS_SERVER(state->inode), err,
4954 &exception); 5110 &exception);
4955 } while (exception.retry); 5111 } while (exception.retry);
4956 return err; 5112 return err;
@@ -5087,6 +5243,9 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
5087 .flags = RPC_TASK_ASYNC, 5243 .flags = RPC_TASK_ASYNC,
5088 }; 5244 };
5089 5245
5246 nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client,
5247 NFS_SP4_MACH_CRED_CLEANUP, &task_setup_data.rpc_client, &msg);
5248
5090 /* Ensure this is an unlock - when canceling a lock, the 5249 /* Ensure this is an unlock - when canceling a lock, the
5091 * canceled lock is passed in, and it won't be an unlock. 5250 * canceled lock is passed in, and it won't be an unlock.
5092 */ 5251 */
@@ -5098,7 +5257,7 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
5098 return ERR_PTR(-ENOMEM); 5257 return ERR_PTR(-ENOMEM);
5099 } 5258 }
5100 5259
5101 nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1); 5260 nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
5102 msg.rpc_argp = &data->arg; 5261 msg.rpc_argp = &data->arg;
5103 msg.rpc_resp = &data->res; 5262 msg.rpc_resp = &data->res;
5104 task_setup_data.callback_data = data; 5263 task_setup_data.callback_data = data;
@@ -5148,6 +5307,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
5148 rpc_put_task(task); 5307 rpc_put_task(task);
5149out: 5308out:
5150 request->fl_flags = fl_flags; 5309 request->fl_flags = fl_flags;
5310 trace_nfs4_unlock(request, state, F_SETLK, status);
5151 return status; 5311 return status;
5152} 5312}
5153 5313
@@ -5333,7 +5493,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
5333 return -ENOMEM; 5493 return -ENOMEM;
5334 if (IS_SETLKW(cmd)) 5494 if (IS_SETLKW(cmd))
5335 data->arg.block = 1; 5495 data->arg.block = 1;
5336 nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1); 5496 nfs4_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
5337 msg.rpc_argp = &data->arg; 5497 msg.rpc_argp = &data->arg;
5338 msg.rpc_resp = &data->res; 5498 msg.rpc_resp = &data->res;
5339 task_setup_data.callback_data = data; 5499 task_setup_data.callback_data = data;
@@ -5371,6 +5531,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
5371 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 5531 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
5372 return 0; 5532 return 0;
5373 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); 5533 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
5534 trace_nfs4_lock_reclaim(request, state, F_SETLK, err);
5374 if (err != -NFS4ERR_DELAY) 5535 if (err != -NFS4ERR_DELAY)
5375 break; 5536 break;
5376 nfs4_handle_exception(server, err, &exception); 5537 nfs4_handle_exception(server, err, &exception);
@@ -5389,10 +5550,15 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
5389 err = nfs4_set_lock_state(state, request); 5550 err = nfs4_set_lock_state(state, request);
5390 if (err != 0) 5551 if (err != 0)
5391 return err; 5552 return err;
5553 if (!recover_lost_locks) {
5554 set_bit(NFS_LOCK_LOST, &request->fl_u.nfs4_fl.owner->ls_flags);
5555 return 0;
5556 }
5392 do { 5557 do {
5393 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 5558 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
5394 return 0; 5559 return 0;
5395 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED); 5560 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
5561 trace_nfs4_lock_expired(request, state, F_SETLK, err);
5396 switch (err) { 5562 switch (err) {
5397 default: 5563 default:
5398 goto out; 5564 goto out;
@@ -5428,6 +5594,7 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
5428 status = nfs41_test_stateid(server, 5594 status = nfs41_test_stateid(server,
5429 &lsp->ls_stateid, 5595 &lsp->ls_stateid,
5430 cred); 5596 cred);
5597 trace_nfs4_test_lock_stateid(state, lsp, status);
5431 if (status != NFS_OK) { 5598 if (status != NFS_OK) {
5432 /* Free the stateid unless the server 5599 /* Free the stateid unless the server
5433 * informs us the stateid is unrecognized. */ 5600 * informs us the stateid is unrecognized. */
@@ -5515,6 +5682,7 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *
5515 5682
5516 do { 5683 do {
5517 err = _nfs4_proc_setlk(state, cmd, request); 5684 err = _nfs4_proc_setlk(state, cmd, request);
5685 trace_nfs4_set_lock(request, state, cmd, err);
5518 if (err == -NFS4ERR_DENIED) 5686 if (err == -NFS4ERR_DENIED)
5519 err = -EAGAIN; 5687 err = -EAGAIN;
5520 err = nfs4_handle_exception(NFS_SERVER(state->inode), 5688 err = nfs4_handle_exception(NFS_SERVER(state->inode),
@@ -5597,8 +5765,23 @@ struct nfs_release_lockowner_data {
5597 struct nfs4_lock_state *lsp; 5765 struct nfs4_lock_state *lsp;
5598 struct nfs_server *server; 5766 struct nfs_server *server;
5599 struct nfs_release_lockowner_args args; 5767 struct nfs_release_lockowner_args args;
5768 struct nfs4_sequence_args seq_args;
5769 struct nfs4_sequence_res seq_res;
5600}; 5770};
5601 5771
5772static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata)
5773{
5774 struct nfs_release_lockowner_data *data = calldata;
5775 nfs40_setup_sequence(data->server,
5776 &data->seq_args, &data->seq_res, task);
5777}
5778
5779static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata)
5780{
5781 struct nfs_release_lockowner_data *data = calldata;
5782 nfs40_sequence_done(task, &data->seq_res);
5783}
5784
5602static void nfs4_release_lockowner_release(void *calldata) 5785static void nfs4_release_lockowner_release(void *calldata)
5603{ 5786{
5604 struct nfs_release_lockowner_data *data = calldata; 5787 struct nfs_release_lockowner_data *data = calldata;
@@ -5607,6 +5790,8 @@ static void nfs4_release_lockowner_release(void *calldata)
5607} 5790}
5608 5791
5609static const struct rpc_call_ops nfs4_release_lockowner_ops = { 5792static const struct rpc_call_ops nfs4_release_lockowner_ops = {
5793 .rpc_call_prepare = nfs4_release_lockowner_prepare,
5794 .rpc_call_done = nfs4_release_lockowner_done,
5610 .rpc_release = nfs4_release_lockowner_release, 5795 .rpc_release = nfs4_release_lockowner_release,
5611}; 5796};
5612 5797
@@ -5619,14 +5804,17 @@ static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_st
5619 5804
5620 if (server->nfs_client->cl_mvops->minor_version != 0) 5805 if (server->nfs_client->cl_mvops->minor_version != 0)
5621 return -EINVAL; 5806 return -EINVAL;
5807
5622 data = kmalloc(sizeof(*data), GFP_NOFS); 5808 data = kmalloc(sizeof(*data), GFP_NOFS);
5623 if (!data) 5809 if (!data)
5624 return -ENOMEM; 5810 return -ENOMEM;
5811 nfs4_init_sequence(&data->seq_args, &data->seq_res, 0);
5625 data->lsp = lsp; 5812 data->lsp = lsp;
5626 data->server = server; 5813 data->server = server;
5627 data->args.lock_owner.clientid = server->nfs_client->cl_clientid; 5814 data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
5628 data->args.lock_owner.id = lsp->ls_seqid.owner_id; 5815 data->args.lock_owner.id = lsp->ls_seqid.owner_id;
5629 data->args.lock_owner.s_dev = server->s_dev; 5816 data->args.lock_owner.s_dev = server->s_dev;
5817
5630 msg.rpc_argp = &data->args; 5818 msg.rpc_argp = &data->args;
5631 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); 5819 rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data);
5632 return 0; 5820 return 0;
@@ -5781,14 +5969,23 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
5781 struct nfs4_exception exception = { }; 5969 struct nfs4_exception exception = { };
5782 int err; 5970 int err;
5783 do { 5971 do {
5784 err = nfs4_handle_exception(NFS_SERVER(dir), 5972 err = _nfs4_proc_fs_locations(client, dir, name,
5785 _nfs4_proc_fs_locations(client, dir, name, fs_locations, page), 5973 fs_locations, page);
5974 trace_nfs4_get_fs_locations(dir, name, err);
5975 err = nfs4_handle_exception(NFS_SERVER(dir), err,
5786 &exception); 5976 &exception);
5787 } while (exception.retry); 5977 } while (exception.retry);
5788 return err; 5978 return err;
5789} 5979}
5790 5980
5791static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors) 5981/**
5982 * If 'use_integrity' is true and the state managment nfs_client
5983 * cl_rpcclient is using krb5i/p, use the integrity protected cl_rpcclient
5984 * and the machine credential as per RFC3530bis and RFC5661 Security
5985 * Considerations sections. Otherwise, just use the user cred with the
5986 * filesystem's rpc_client.
5987 */
5988static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors, bool use_integrity)
5792{ 5989{
5793 int status; 5990 int status;
5794 struct nfs4_secinfo_arg args = { 5991 struct nfs4_secinfo_arg args = {
@@ -5803,10 +6000,25 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
5803 .rpc_argp = &args, 6000 .rpc_argp = &args,
5804 .rpc_resp = &res, 6001 .rpc_resp = &res,
5805 }; 6002 };
6003 struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
6004
6005 if (use_integrity) {
6006 clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
6007 msg.rpc_cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client);
6008 }
5806 6009
5807 dprintk("NFS call secinfo %s\n", name->name); 6010 dprintk("NFS call secinfo %s\n", name->name);
5808 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); 6011
6012 nfs4_state_protect(NFS_SERVER(dir)->nfs_client,
6013 NFS_SP4_MACH_CRED_SECINFO, &clnt, &msg);
6014
6015 status = nfs4_call_sync(clnt, NFS_SERVER(dir), &msg, &args.seq_args,
6016 &res.seq_res, 0);
5809 dprintk("NFS reply secinfo: %d\n", status); 6017 dprintk("NFS reply secinfo: %d\n", status);
6018
6019 if (msg.rpc_cred)
6020 put_rpccred(msg.rpc_cred);
6021
5810 return status; 6022 return status;
5811} 6023}
5812 6024
@@ -5816,8 +6028,23 @@ int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name,
5816 struct nfs4_exception exception = { }; 6028 struct nfs4_exception exception = { };
5817 int err; 6029 int err;
5818 do { 6030 do {
5819 err = nfs4_handle_exception(NFS_SERVER(dir), 6031 err = -NFS4ERR_WRONGSEC;
5820 _nfs4_proc_secinfo(dir, name, flavors), 6032
6033 /* try to use integrity protection with machine cred */
6034 if (_nfs4_is_integrity_protected(NFS_SERVER(dir)->nfs_client))
6035 err = _nfs4_proc_secinfo(dir, name, flavors, true);
6036
6037 /*
6038 * if unable to use integrity protection, or SECINFO with
6039 * integrity protection returns NFS4ERR_WRONGSEC (which is
6040 * disallowed by spec, but exists in deployed servers) use
6041 * the current filesystem's rpc_client and the user cred.
6042 */
6043 if (err == -NFS4ERR_WRONGSEC)
6044 err = _nfs4_proc_secinfo(dir, name, flavors, false);
6045
6046 trace_nfs4_secinfo(dir, name, err);
6047 err = nfs4_handle_exception(NFS_SERVER(dir), err,
5821 &exception); 6048 &exception);
5822 } while (exception.retry); 6049 } while (exception.retry);
5823 return err; 6050 return err;
@@ -5881,6 +6108,7 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred
5881 } 6108 }
5882 6109
5883 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6110 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6111 trace_nfs4_bind_conn_to_session(clp, status);
5884 if (status == 0) { 6112 if (status == 0) {
5885 if (memcmp(res.session->sess_id.data, 6113 if (memcmp(res.session->sess_id.data,
5886 clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) { 6114 clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) {
@@ -5909,16 +6137,124 @@ out:
5909} 6137}
5910 6138
5911/* 6139/*
5912 * nfs4_proc_exchange_id() 6140 * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map
6141 * and operations we'd like to see to enable certain features in the allow map
6142 */
6143static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
6144 .how = SP4_MACH_CRED,
6145 .enforce.u.words = {
6146 [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
6147 1 << (OP_EXCHANGE_ID - 32) |
6148 1 << (OP_CREATE_SESSION - 32) |
6149 1 << (OP_DESTROY_SESSION - 32) |
6150 1 << (OP_DESTROY_CLIENTID - 32)
6151 },
6152 .allow.u.words = {
6153 [0] = 1 << (OP_CLOSE) |
6154 1 << (OP_LOCKU),
6155 [1] = 1 << (OP_SECINFO - 32) |
6156 1 << (OP_SECINFO_NO_NAME - 32) |
6157 1 << (OP_TEST_STATEID - 32) |
6158 1 << (OP_FREE_STATEID - 32)
6159 }
6160};
6161
6162/*
6163 * Select the state protection mode for client `clp' given the server results
6164 * from exchange_id in `sp'.
5913 * 6165 *
5914 * Returns zero, a negative errno, or a negative NFS4ERR status code. 6166 * Returns 0 on success, negative errno otherwise.
6167 */
6168static int nfs4_sp4_select_mode(struct nfs_client *clp,
6169 struct nfs41_state_protection *sp)
6170{
6171 static const u32 supported_enforce[NFS4_OP_MAP_NUM_WORDS] = {
6172 [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
6173 1 << (OP_EXCHANGE_ID - 32) |
6174 1 << (OP_CREATE_SESSION - 32) |
6175 1 << (OP_DESTROY_SESSION - 32) |
6176 1 << (OP_DESTROY_CLIENTID - 32)
6177 };
6178 unsigned int i;
6179
6180 if (sp->how == SP4_MACH_CRED) {
6181 /* Print state protect result */
6182 dfprintk(MOUNT, "Server SP4_MACH_CRED support:\n");
6183 for (i = 0; i <= LAST_NFS4_OP; i++) {
6184 if (test_bit(i, sp->enforce.u.longs))
6185 dfprintk(MOUNT, " enforce op %d\n", i);
6186 if (test_bit(i, sp->allow.u.longs))
6187 dfprintk(MOUNT, " allow op %d\n", i);
6188 }
6189
6190 /* make sure nothing is on enforce list that isn't supported */
6191 for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++) {
6192 if (sp->enforce.u.words[i] & ~supported_enforce[i]) {
6193 dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
6194 return -EINVAL;
6195 }
6196 }
6197
6198 /*
6199 * Minimal mode - state operations are allowed to use machine
6200 * credential. Note this already happens by default, so the
6201 * client doesn't have to do anything more than the negotiation.
6202 *
6203 * NOTE: we don't care if EXCHANGE_ID is in the list -
6204 * we're already using the machine cred for exchange_id
6205 * and will never use a different cred.
6206 */
6207 if (test_bit(OP_BIND_CONN_TO_SESSION, sp->enforce.u.longs) &&
6208 test_bit(OP_CREATE_SESSION, sp->enforce.u.longs) &&
6209 test_bit(OP_DESTROY_SESSION, sp->enforce.u.longs) &&
6210 test_bit(OP_DESTROY_CLIENTID, sp->enforce.u.longs)) {
6211 dfprintk(MOUNT, "sp4_mach_cred:\n");
6212 dfprintk(MOUNT, " minimal mode enabled\n");
6213 set_bit(NFS_SP4_MACH_CRED_MINIMAL, &clp->cl_sp4_flags);
6214 } else {
6215 dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
6216 return -EINVAL;
6217 }
6218
6219 if (test_bit(OP_CLOSE, sp->allow.u.longs) &&
6220 test_bit(OP_LOCKU, sp->allow.u.longs)) {
6221 dfprintk(MOUNT, " cleanup mode enabled\n");
6222 set_bit(NFS_SP4_MACH_CRED_CLEANUP, &clp->cl_sp4_flags);
6223 }
6224
6225 if (test_bit(OP_SECINFO, sp->allow.u.longs) &&
6226 test_bit(OP_SECINFO_NO_NAME, sp->allow.u.longs)) {
6227 dfprintk(MOUNT, " secinfo mode enabled\n");
6228 set_bit(NFS_SP4_MACH_CRED_SECINFO, &clp->cl_sp4_flags);
6229 }
6230
6231 if (test_bit(OP_TEST_STATEID, sp->allow.u.longs) &&
6232 test_bit(OP_FREE_STATEID, sp->allow.u.longs)) {
6233 dfprintk(MOUNT, " stateid mode enabled\n");
6234 set_bit(NFS_SP4_MACH_CRED_STATEID, &clp->cl_sp4_flags);
6235 }
6236
6237 if (test_bit(OP_WRITE, sp->allow.u.longs)) {
6238 dfprintk(MOUNT, " write mode enabled\n");
6239 set_bit(NFS_SP4_MACH_CRED_WRITE, &clp->cl_sp4_flags);
6240 }
6241
6242 if (test_bit(OP_COMMIT, sp->allow.u.longs)) {
6243 dfprintk(MOUNT, " commit mode enabled\n");
6244 set_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags);
6245 }
6246 }
6247
6248 return 0;
6249}
6250
6251/*
6252 * _nfs4_proc_exchange_id()
5915 * 6253 *
5916 * Since the clientid has expired, all compounds using sessions 6254 * Wrapper for EXCHANGE_ID operation.
5917 * associated with the stale clientid will be returning
5918 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
5919 * be in some phase of session reset.
5920 */ 6255 */
5921int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) 6256static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
6257 u32 sp4_how)
5922{ 6258{
5923 nfs4_verifier verifier; 6259 nfs4_verifier verifier;
5924 struct nfs41_exchange_id_args args = { 6260 struct nfs41_exchange_id_args args = {
@@ -5965,10 +6301,30 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5965 goto out_server_scope; 6301 goto out_server_scope;
5966 } 6302 }
5967 6303
6304 switch (sp4_how) {
6305 case SP4_NONE:
6306 args.state_protect.how = SP4_NONE;
6307 break;
6308
6309 case SP4_MACH_CRED:
6310 args.state_protect = nfs4_sp4_mach_cred_request;
6311 break;
6312
6313 default:
6314 /* unsupported! */
6315 WARN_ON_ONCE(1);
6316 status = -EINVAL;
6317 goto out_server_scope;
6318 }
6319
5968 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6320 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6321 trace_nfs4_exchange_id(clp, status);
5969 if (status == 0) 6322 if (status == 0)
5970 status = nfs4_check_cl_exchange_flags(res.flags); 6323 status = nfs4_check_cl_exchange_flags(res.flags);
5971 6324
6325 if (status == 0)
6326 status = nfs4_sp4_select_mode(clp, &res.state_protect);
6327
5972 if (status == 0) { 6328 if (status == 0) {
5973 clp->cl_clientid = res.clientid; 6329 clp->cl_clientid = res.clientid;
5974 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R); 6330 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
@@ -6015,6 +6371,35 @@ out:
6015 return status; 6371 return status;
6016} 6372}
6017 6373
6374/*
6375 * nfs4_proc_exchange_id()
6376 *
6377 * Returns zero, a negative errno, or a negative NFS4ERR status code.
6378 *
6379 * Since the clientid has expired, all compounds using sessions
6380 * associated with the stale clientid will be returning
6381 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
6382 * be in some phase of session reset.
6383 *
6384 * Will attempt to negotiate SP4_MACH_CRED if krb5i / krb5p auth is used.
6385 */
6386int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
6387{
6388 rpc_authflavor_t authflavor = clp->cl_rpcclient->cl_auth->au_flavor;
6389 int status;
6390
6391 /* try SP4_MACH_CRED if krb5i/p */
6392 if (authflavor == RPC_AUTH_GSS_KRB5I ||
6393 authflavor == RPC_AUTH_GSS_KRB5P) {
6394 status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED);
6395 if (!status)
6396 return 0;
6397 }
6398
6399 /* try SP4_NONE */
6400 return _nfs4_proc_exchange_id(clp, cred, SP4_NONE);
6401}
6402
6018static int _nfs4_proc_destroy_clientid(struct nfs_client *clp, 6403static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
6019 struct rpc_cred *cred) 6404 struct rpc_cred *cred)
6020{ 6405{
@@ -6026,6 +6411,7 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
6026 int status; 6411 int status;
6027 6412
6028 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6413 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6414 trace_nfs4_destroy_clientid(clp, status);
6029 if (status) 6415 if (status)
6030 dprintk("NFS: Got error %d from the server %s on " 6416 dprintk("NFS: Got error %d from the server %s on "
6031 "DESTROY_CLIENTID.", status, clp->cl_hostname); 6417 "DESTROY_CLIENTID.", status, clp->cl_hostname);
@@ -6063,7 +6449,7 @@ int nfs4_destroy_clientid(struct nfs_client *clp)
6063 goto out; 6449 goto out;
6064 if (clp->cl_preserve_clid) 6450 if (clp->cl_preserve_clid)
6065 goto out; 6451 goto out;
6066 cred = nfs4_get_exchange_id_cred(clp); 6452 cred = nfs4_get_clid_cred(clp);
6067 ret = nfs4_proc_destroy_clientid(clp, cred); 6453 ret = nfs4_proc_destroy_clientid(clp, cred);
6068 if (cred) 6454 if (cred)
6069 put_rpccred(cred); 6455 put_rpccred(cred);
@@ -6155,7 +6541,7 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
6155 }; 6541 };
6156 int status; 6542 int status;
6157 6543
6158 nfs41_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0); 6544 nfs4_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0);
6159 nfs4_set_sequence_privileged(&args.la_seq_args); 6545 nfs4_set_sequence_privileged(&args.la_seq_args);
6160 dprintk("--> %s\n", __func__); 6546 dprintk("--> %s\n", __func__);
6161 task = rpc_run_task(&task_setup); 6547 task = rpc_run_task(&task_setup);
@@ -6289,6 +6675,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
6289 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN); 6675 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
6290 6676
6291 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6677 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6678 trace_nfs4_create_session(clp, status);
6292 6679
6293 if (!status) { 6680 if (!status) {
6294 /* Verify the session's negotiated channel_attrs values */ 6681 /* Verify the session's negotiated channel_attrs values */
@@ -6352,6 +6739,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
6352 return status; 6739 return status;
6353 6740
6354 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6741 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
6742 trace_nfs4_destroy_session(session->clp, status);
6355 6743
6356 if (status) 6744 if (status)
6357 dprintk("NFS: Got error %d from the server on DESTROY_SESSION. " 6745 dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
@@ -6401,6 +6789,7 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
6401 if (!nfs41_sequence_done(task, task->tk_msg.rpc_resp)) 6789 if (!nfs41_sequence_done(task, task->tk_msg.rpc_resp))
6402 return; 6790 return;
6403 6791
6792 trace_nfs4_sequence(clp, task->tk_status);
6404 if (task->tk_status < 0) { 6793 if (task->tk_status < 0) {
6405 dprintk("%s ERROR %d\n", __func__, task->tk_status); 6794 dprintk("%s ERROR %d\n", __func__, task->tk_status);
6406 if (atomic_read(&clp->cl_count) == 1) 6795 if (atomic_read(&clp->cl_count) == 1)
@@ -6458,7 +6847,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
6458 nfs_put_client(clp); 6847 nfs_put_client(clp);
6459 return ERR_PTR(-ENOMEM); 6848 return ERR_PTR(-ENOMEM);
6460 } 6849 }
6461 nfs41_init_sequence(&calldata->args, &calldata->res, 0); 6850 nfs4_init_sequence(&calldata->args, &calldata->res, 0);
6462 if (is_privileged) 6851 if (is_privileged)
6463 nfs4_set_sequence_privileged(&calldata->args); 6852 nfs4_set_sequence_privileged(&calldata->args);
6464 msg.rpc_argp = &calldata->args; 6853 msg.rpc_argp = &calldata->args;
@@ -6553,6 +6942,7 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
6553 if (!nfs41_sequence_done(task, res)) 6942 if (!nfs41_sequence_done(task, res))
6554 return; 6943 return;
6555 6944
6945 trace_nfs4_reclaim_complete(clp, task->tk_status);
6556 if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) { 6946 if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) {
6557 rpc_restart_call_prepare(task); 6947 rpc_restart_call_prepare(task);
6558 return; 6948 return;
@@ -6600,7 +6990,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
6600 calldata->clp = clp; 6990 calldata->clp = clp;
6601 calldata->arg.one_fs = 0; 6991 calldata->arg.one_fs = 0;
6602 6992
6603 nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0); 6993 nfs4_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0);
6604 nfs4_set_sequence_privileged(&calldata->arg.seq_args); 6994 nfs4_set_sequence_privileged(&calldata->arg.seq_args);
6605 msg.rpc_argp = &calldata->arg; 6995 msg.rpc_argp = &calldata->arg;
6606 msg.rpc_resp = &calldata->res; 6996 msg.rpc_resp = &calldata->res;
@@ -6791,7 +7181,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6791 7181
6792 lgp->res.layoutp = &lgp->args.layout; 7182 lgp->res.layoutp = &lgp->args.layout;
6793 lgp->res.seq_res.sr_slot = NULL; 7183 lgp->res.seq_res.sr_slot = NULL;
6794 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 7184 nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
6795 7185
6796 /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ 7186 /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
6797 pnfs_get_layout_hdr(NFS_I(inode)->layout); 7187 pnfs_get_layout_hdr(NFS_I(inode)->layout);
@@ -6802,6 +7192,10 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6802 status = nfs4_wait_for_completion_rpc_task(task); 7192 status = nfs4_wait_for_completion_rpc_task(task);
6803 if (status == 0) 7193 if (status == 0)
6804 status = task->tk_status; 7194 status = task->tk_status;
7195 trace_nfs4_layoutget(lgp->args.ctx,
7196 &lgp->args.range,
7197 &lgp->res.range,
7198 status);
6805 /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ 7199 /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
6806 if (status == 0 && lgp->res.layoutp->len) 7200 if (status == 0 && lgp->res.layoutp->len)
6807 lseg = pnfs_layout_process(lgp); 7201 lseg = pnfs_layout_process(lgp);
@@ -6874,7 +7268,7 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
6874 .rpc_cred = lrp->cred, 7268 .rpc_cred = lrp->cred,
6875 }; 7269 };
6876 struct rpc_task_setup task_setup_data = { 7270 struct rpc_task_setup task_setup_data = {
6877 .rpc_client = lrp->clp->cl_rpcclient, 7271 .rpc_client = NFS_SERVER(lrp->args.inode)->client,
6878 .rpc_message = &msg, 7272 .rpc_message = &msg,
6879 .callback_ops = &nfs4_layoutreturn_call_ops, 7273 .callback_ops = &nfs4_layoutreturn_call_ops,
6880 .callback_data = lrp, 7274 .callback_data = lrp,
@@ -6882,11 +7276,12 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
6882 int status; 7276 int status;
6883 7277
6884 dprintk("--> %s\n", __func__); 7278 dprintk("--> %s\n", __func__);
6885 nfs41_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1); 7279 nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1);
6886 task = rpc_run_task(&task_setup_data); 7280 task = rpc_run_task(&task_setup_data);
6887 if (IS_ERR(task)) 7281 if (IS_ERR(task))
6888 return PTR_ERR(task); 7282 return PTR_ERR(task);
6889 status = task->tk_status; 7283 status = task->tk_status;
7284 trace_nfs4_layoutreturn(lrp->args.inode, status);
6890 dprintk("<-- %s status=%d\n", __func__, status); 7285 dprintk("<-- %s status=%d\n", __func__, status);
6891 rpc_put_task(task); 7286 rpc_put_task(task);
6892 return status; 7287 return status;
@@ -7063,7 +7458,7 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
7063 data->args.lastbytewritten, 7458 data->args.lastbytewritten,
7064 data->args.inode->i_ino); 7459 data->args.inode->i_ino);
7065 7460
7066 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 7461 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
7067 task = rpc_run_task(&task_setup_data); 7462 task = rpc_run_task(&task_setup_data);
7068 if (IS_ERR(task)) 7463 if (IS_ERR(task))
7069 return PTR_ERR(task); 7464 return PTR_ERR(task);
@@ -7073,15 +7468,21 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
7073 if (status != 0) 7468 if (status != 0)
7074 goto out; 7469 goto out;
7075 status = task->tk_status; 7470 status = task->tk_status;
7471 trace_nfs4_layoutcommit(data->args.inode, status);
7076out: 7472out:
7077 dprintk("%s: status %d\n", __func__, status); 7473 dprintk("%s: status %d\n", __func__, status);
7078 rpc_put_task(task); 7474 rpc_put_task(task);
7079 return status; 7475 return status;
7080} 7476}
7081 7477
7478/**
7479 * Use the state managment nfs_client cl_rpcclient, which uses krb5i (if
7480 * possible) as per RFC3530bis and RFC5661 Security Considerations sections
7481 */
7082static int 7482static int
7083_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, 7483_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7084 struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors) 7484 struct nfs_fsinfo *info,
7485 struct nfs4_secinfo_flavors *flavors, bool use_integrity)
7085{ 7486{
7086 struct nfs41_secinfo_no_name_args args = { 7487 struct nfs41_secinfo_no_name_args args = {
7087 .style = SECINFO_STYLE_CURRENT_FH, 7488 .style = SECINFO_STYLE_CURRENT_FH,
@@ -7094,7 +7495,23 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7094 .rpc_argp = &args, 7495 .rpc_argp = &args,
7095 .rpc_resp = &res, 7496 .rpc_resp = &res,
7096 }; 7497 };
7097 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 7498 struct rpc_clnt *clnt = server->client;
7499 int status;
7500
7501 if (use_integrity) {
7502 clnt = server->nfs_client->cl_rpcclient;
7503 msg.rpc_cred = nfs4_get_clid_cred(server->nfs_client);
7504 }
7505
7506 dprintk("--> %s\n", __func__);
7507 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
7508 &res.seq_res, 0);
7509 dprintk("<-- %s status=%d\n", __func__, status);
7510
7511 if (msg.rpc_cred)
7512 put_rpccred(msg.rpc_cred);
7513
7514 return status;
7098} 7515}
7099 7516
7100static int 7517static int
@@ -7104,7 +7521,24 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7104 struct nfs4_exception exception = { }; 7521 struct nfs4_exception exception = { };
7105 int err; 7522 int err;
7106 do { 7523 do {
7107 err = _nfs41_proc_secinfo_no_name(server, fhandle, info, flavors); 7524 /* first try using integrity protection */
7525 err = -NFS4ERR_WRONGSEC;
7526
7527 /* try to use integrity protection with machine cred */
7528 if (_nfs4_is_integrity_protected(server->nfs_client))
7529 err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
7530 flavors, true);
7531
7532 /*
7533 * if unable to use integrity protection, or SECINFO with
7534 * integrity protection returns NFS4ERR_WRONGSEC (which is
7535 * disallowed by spec, but exists in deployed servers) use
7536 * the current filesystem's rpc_client and the user cred.
7537 */
7538 if (err == -NFS4ERR_WRONGSEC)
7539 err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
7540 flavors, false);
7541
7108 switch (err) { 7542 switch (err) {
7109 case 0: 7543 case 0:
7110 case -NFS4ERR_WRONGSEC: 7544 case -NFS4ERR_WRONGSEC:
@@ -7174,11 +7608,15 @@ static int _nfs41_test_stateid(struct nfs_server *server,
7174 .rpc_resp = &res, 7608 .rpc_resp = &res,
7175 .rpc_cred = cred, 7609 .rpc_cred = cred,
7176 }; 7610 };
7611 struct rpc_clnt *rpc_client = server->client;
7612
7613 nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
7614 &rpc_client, &msg);
7177 7615
7178 dprintk("NFS call test_stateid %p\n", stateid); 7616 dprintk("NFS call test_stateid %p\n", stateid);
7179 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 7617 nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
7180 nfs4_set_sequence_privileged(&args.seq_args); 7618 nfs4_set_sequence_privileged(&args.seq_args);
7181 status = nfs4_call_sync_sequence(server->client, server, &msg, 7619 status = nfs4_call_sync_sequence(rpc_client, server, &msg,
7182 &args.seq_args, &res.seq_res); 7620 &args.seq_args, &res.seq_res);
7183 if (status != NFS_OK) { 7621 if (status != NFS_OK) {
7184 dprintk("NFS reply test_stateid: failed, %d\n", status); 7622 dprintk("NFS reply test_stateid: failed, %d\n", status);
@@ -7247,7 +7685,7 @@ static void nfs41_free_stateid_release(void *calldata)
7247 kfree(calldata); 7685 kfree(calldata);
7248} 7686}
7249 7687
7250const struct rpc_call_ops nfs41_free_stateid_ops = { 7688static const struct rpc_call_ops nfs41_free_stateid_ops = {
7251 .rpc_call_prepare = nfs41_free_stateid_prepare, 7689 .rpc_call_prepare = nfs41_free_stateid_prepare,
7252 .rpc_call_done = nfs41_free_stateid_done, 7690 .rpc_call_done = nfs41_free_stateid_done,
7253 .rpc_release = nfs41_free_stateid_release, 7691 .rpc_release = nfs41_free_stateid_release,
@@ -7270,6 +7708,9 @@ static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
7270 }; 7708 };
7271 struct nfs_free_stateid_data *data; 7709 struct nfs_free_stateid_data *data;
7272 7710
7711 nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
7712 &task_setup.rpc_client, &msg);
7713
7273 dprintk("NFS call free_stateid %p\n", stateid); 7714 dprintk("NFS call free_stateid %p\n", stateid);
7274 data = kmalloc(sizeof(*data), GFP_NOFS); 7715 data = kmalloc(sizeof(*data), GFP_NOFS);
7275 if (!data) 7716 if (!data)
@@ -7281,7 +7722,7 @@ static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
7281 7722
7282 msg.rpc_argp = &data->args; 7723 msg.rpc_argp = &data->args;
7283 msg.rpc_resp = &data->res; 7724 msg.rpc_resp = &data->res;
7284 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 0); 7725 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
7285 if (privileged) 7726 if (privileged)
7286 nfs4_set_sequence_privileged(&data->args.seq_args); 7727 nfs4_set_sequence_privileged(&data->args.seq_args);
7287 7728
@@ -7357,7 +7798,6 @@ static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
7357 .recover_open = nfs4_open_reclaim, 7798 .recover_open = nfs4_open_reclaim,
7358 .recover_lock = nfs4_lock_reclaim, 7799 .recover_lock = nfs4_lock_reclaim,
7359 .establish_clid = nfs4_init_clientid, 7800 .establish_clid = nfs4_init_clientid,
7360 .get_clid_cred = nfs4_get_setclientid_cred,
7361 .detect_trunking = nfs40_discover_server_trunking, 7801 .detect_trunking = nfs40_discover_server_trunking,
7362}; 7802};
7363 7803
@@ -7368,7 +7808,6 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
7368 .recover_open = nfs4_open_reclaim, 7808 .recover_open = nfs4_open_reclaim,
7369 .recover_lock = nfs4_lock_reclaim, 7809 .recover_lock = nfs4_lock_reclaim,
7370 .establish_clid = nfs41_init_clientid, 7810 .establish_clid = nfs41_init_clientid,
7371 .get_clid_cred = nfs4_get_exchange_id_cred,
7372 .reclaim_complete = nfs41_proc_reclaim_complete, 7811 .reclaim_complete = nfs41_proc_reclaim_complete,
7373 .detect_trunking = nfs41_discover_server_trunking, 7812 .detect_trunking = nfs41_discover_server_trunking,
7374}; 7813};
@@ -7380,7 +7819,6 @@ static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
7380 .recover_open = nfs4_open_expired, 7819 .recover_open = nfs4_open_expired,
7381 .recover_lock = nfs4_lock_expired, 7820 .recover_lock = nfs4_lock_expired,
7382 .establish_clid = nfs4_init_clientid, 7821 .establish_clid = nfs4_init_clientid,
7383 .get_clid_cred = nfs4_get_setclientid_cred,
7384}; 7822};
7385 7823
7386#if defined(CONFIG_NFS_V4_1) 7824#if defined(CONFIG_NFS_V4_1)
@@ -7390,7 +7828,6 @@ static const struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
7390 .recover_open = nfs41_open_expired, 7828 .recover_open = nfs41_open_expired,
7391 .recover_lock = nfs41_lock_expired, 7829 .recover_lock = nfs41_lock_expired,
7392 .establish_clid = nfs41_init_clientid, 7830 .establish_clid = nfs41_init_clientid,
7393 .get_clid_cred = nfs4_get_exchange_id_cred,
7394}; 7831};
7395#endif /* CONFIG_NFS_V4_1 */ 7832#endif /* CONFIG_NFS_V4_1 */
7396 7833
@@ -7414,10 +7851,12 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
7414 | NFS_CAP_ATOMIC_OPEN 7851 | NFS_CAP_ATOMIC_OPEN
7415 | NFS_CAP_CHANGE_ATTR 7852 | NFS_CAP_CHANGE_ATTR
7416 | NFS_CAP_POSIX_LOCK, 7853 | NFS_CAP_POSIX_LOCK,
7417 .call_sync = _nfs4_call_sync, 7854 .init_client = nfs40_init_client,
7855 .shutdown_client = nfs40_shutdown_client,
7418 .match_stateid = nfs4_match_stateid, 7856 .match_stateid = nfs4_match_stateid,
7419 .find_root_sec = nfs4_find_root_sec, 7857 .find_root_sec = nfs4_find_root_sec,
7420 .free_lock_state = nfs4_release_lockowner, 7858 .free_lock_state = nfs4_release_lockowner,
7859 .call_sync_ops = &nfs40_call_sync_ops,
7421 .reboot_recovery_ops = &nfs40_reboot_recovery_ops, 7860 .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
7422 .nograce_recovery_ops = &nfs40_nograce_recovery_ops, 7861 .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
7423 .state_renewal_ops = &nfs40_state_renewal_ops, 7862 .state_renewal_ops = &nfs40_state_renewal_ops,
@@ -7432,10 +7871,12 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
7432 | NFS_CAP_POSIX_LOCK 7871 | NFS_CAP_POSIX_LOCK
7433 | NFS_CAP_STATEID_NFSV41 7872 | NFS_CAP_STATEID_NFSV41
7434 | NFS_CAP_ATOMIC_OPEN_V1, 7873 | NFS_CAP_ATOMIC_OPEN_V1,
7435 .call_sync = nfs4_call_sync_sequence, 7874 .init_client = nfs41_init_client,
7875 .shutdown_client = nfs41_shutdown_client,
7436 .match_stateid = nfs41_match_stateid, 7876 .match_stateid = nfs41_match_stateid,
7437 .find_root_sec = nfs41_find_root_sec, 7877 .find_root_sec = nfs41_find_root_sec,
7438 .free_lock_state = nfs41_free_lock_state, 7878 .free_lock_state = nfs41_free_lock_state,
7879 .call_sync_ops = &nfs41_call_sync_ops,
7439 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7880 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
7440 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7881 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
7441 .state_renewal_ops = &nfs41_state_renewal_ops, 7882 .state_renewal_ops = &nfs41_state_renewal_ops,
@@ -7451,10 +7892,12 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
7451 | NFS_CAP_POSIX_LOCK 7892 | NFS_CAP_POSIX_LOCK
7452 | NFS_CAP_STATEID_NFSV41 7893 | NFS_CAP_STATEID_NFSV41
7453 | NFS_CAP_ATOMIC_OPEN_V1, 7894 | NFS_CAP_ATOMIC_OPEN_V1,
7454 .call_sync = nfs4_call_sync_sequence, 7895 .init_client = nfs41_init_client,
7896 .shutdown_client = nfs41_shutdown_client,
7455 .match_stateid = nfs41_match_stateid, 7897 .match_stateid = nfs41_match_stateid,
7456 .find_root_sec = nfs41_find_root_sec, 7898 .find_root_sec = nfs41_find_root_sec,
7457 .free_lock_state = nfs41_free_lock_state, 7899 .free_lock_state = nfs41_free_lock_state,
7900 .call_sync_ops = &nfs41_call_sync_ops,
7458 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7901 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
7459 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7902 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
7460 .state_renewal_ops = &nfs41_state_renewal_ops, 7903 .state_renewal_ops = &nfs41_state_renewal_ops,
@@ -7471,7 +7914,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
7471#endif 7914#endif
7472}; 7915};
7473 7916
7474const struct inode_operations nfs4_dir_inode_operations = { 7917static const struct inode_operations nfs4_dir_inode_operations = {
7475 .create = nfs_create, 7918 .create = nfs_create,
7476 .lookup = nfs_lookup, 7919 .lookup = nfs_lookup,
7477 .atomic_open = nfs_atomic_open, 7920 .atomic_open = nfs_atomic_open,
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
index 36e21cb29d65..cf883c7ae053 100644
--- a/fs/nfs/nfs4session.c
+++ b/fs/nfs/nfs4session.c
@@ -23,6 +23,14 @@
23 23
24#define NFSDBG_FACILITY NFSDBG_STATE 24#define NFSDBG_FACILITY NFSDBG_STATE
25 25
26static void nfs4_init_slot_table(struct nfs4_slot_table *tbl, const char *queue)
27{
28 tbl->highest_used_slotid = NFS4_NO_SLOT;
29 spin_lock_init(&tbl->slot_tbl_lock);
30 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, queue);
31 init_completion(&tbl->complete);
32}
33
26/* 34/*
27 * nfs4_shrink_slot_table - free retired slots from the slot table 35 * nfs4_shrink_slot_table - free retired slots from the slot table
28 */ 36 */
@@ -44,6 +52,17 @@ static void nfs4_shrink_slot_table(struct nfs4_slot_table *tbl, u32 newsize)
44 } 52 }
45} 53}
46 54
55/**
56 * nfs4_slot_tbl_drain_complete - wake waiters when drain is complete
57 * @tbl - controlling slot table
58 *
59 */
60void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl)
61{
62 if (nfs4_slot_tbl_draining(tbl))
63 complete(&tbl->complete);
64}
65
47/* 66/*
48 * nfs4_free_slot - free a slot and efficiently update slot table. 67 * nfs4_free_slot - free a slot and efficiently update slot table.
49 * 68 *
@@ -76,7 +95,7 @@ void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
76 nfs4_slot_tbl_drain_complete(tbl); 95 nfs4_slot_tbl_drain_complete(tbl);
77 } 96 }
78 } 97 }
79 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__, 98 dprintk("%s: slotid %u highest_used_slotid %u\n", __func__,
80 slotid, tbl->highest_used_slotid); 99 slotid, tbl->highest_used_slotid);
81} 100}
82 101
@@ -146,9 +165,9 @@ struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)
146 ret->generation = tbl->generation; 165 ret->generation = tbl->generation;
147 166
148out: 167out:
149 dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", 168 dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n",
150 __func__, tbl->used_slots[0], tbl->highest_used_slotid, 169 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
151 !IS_ERR(ret) ? ret->slot_nr : -1); 170 !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT);
152 return ret; 171 return ret;
153} 172}
154 173
@@ -191,7 +210,7 @@ static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl,
191{ 210{
192 int ret; 211 int ret;
193 212
194 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__, 213 dprintk("--> %s: max_reqs=%u, tbl->max_slots %u\n", __func__,
195 max_reqs, tbl->max_slots); 214 max_reqs, tbl->max_slots);
196 215
197 if (max_reqs > NFS4_MAX_SLOT_TABLE) 216 if (max_reqs > NFS4_MAX_SLOT_TABLE)
@@ -205,18 +224,36 @@ static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl,
205 nfs4_reset_slot_table(tbl, max_reqs - 1, ivalue); 224 nfs4_reset_slot_table(tbl, max_reqs - 1, ivalue);
206 spin_unlock(&tbl->slot_tbl_lock); 225 spin_unlock(&tbl->slot_tbl_lock);
207 226
208 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 227 dprintk("%s: tbl=%p slots=%p max_slots=%u\n", __func__,
209 tbl, tbl->slots, tbl->max_slots); 228 tbl, tbl->slots, tbl->max_slots);
210out: 229out:
211 dprintk("<-- %s: return %d\n", __func__, ret); 230 dprintk("<-- %s: return %d\n", __func__, ret);
212 return ret; 231 return ret;
213} 232}
214 233
215/* Destroy the slot table */ 234/**
216static void nfs4_destroy_slot_tables(struct nfs4_session *session) 235 * nfs4_release_slot_table - release resources attached to a slot table
236 * @tbl: slot table to shut down
237 *
238 */
239void nfs4_release_slot_table(struct nfs4_slot_table *tbl)
240{
241 nfs4_shrink_slot_table(tbl, 0);
242}
243
244/**
245 * nfs4_setup_slot_table - prepare a stand-alone slot table for use
246 * @tbl: slot table to set up
247 * @max_reqs: maximum number of requests allowed
248 * @queue: name to give RPC wait queue
249 *
250 * Returns zero on success, or a negative errno.
251 */
252int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, unsigned int max_reqs,
253 const char *queue)
217{ 254{
218 nfs4_shrink_slot_table(&session->fc_slot_table, 0); 255 nfs4_init_slot_table(tbl, queue);
219 nfs4_shrink_slot_table(&session->bc_slot_table, 0); 256 return nfs4_realloc_slot_table(tbl, max_reqs, 0);
220} 257}
221 258
222static bool nfs41_assign_slot(struct rpc_task *task, void *pslot) 259static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
@@ -273,6 +310,8 @@ void nfs41_wake_slot_table(struct nfs4_slot_table *tbl)
273 } 310 }
274} 311}
275 312
313#if defined(CONFIG_NFS_V4_1)
314
276static void nfs41_set_max_slotid_locked(struct nfs4_slot_table *tbl, 315static void nfs41_set_max_slotid_locked(struct nfs4_slot_table *tbl,
277 u32 target_highest_slotid) 316 u32 target_highest_slotid)
278{ 317{
@@ -383,6 +422,12 @@ void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
383 spin_unlock(&tbl->slot_tbl_lock); 422 spin_unlock(&tbl->slot_tbl_lock);
384} 423}
385 424
425static void nfs4_destroy_session_slot_tables(struct nfs4_session *session)
426{
427 nfs4_release_slot_table(&session->fc_slot_table);
428 nfs4_release_slot_table(&session->bc_slot_table);
429}
430
386/* 431/*
387 * Initialize or reset the forechannel and backchannel tables 432 * Initialize or reset the forechannel and backchannel tables
388 */ 433 */
@@ -405,31 +450,20 @@ int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
405 if (status && tbl->slots == NULL) 450 if (status && tbl->slots == NULL)
406 /* Fore and back channel share a connection so get 451 /* Fore and back channel share a connection so get
407 * both slot tables or neither */ 452 * both slot tables or neither */
408 nfs4_destroy_slot_tables(ses); 453 nfs4_destroy_session_slot_tables(ses);
409 return status; 454 return status;
410} 455}
411 456
412struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) 457struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
413{ 458{
414 struct nfs4_session *session; 459 struct nfs4_session *session;
415 struct nfs4_slot_table *tbl;
416 460
417 session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); 461 session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
418 if (!session) 462 if (!session)
419 return NULL; 463 return NULL;
420 464
421 tbl = &session->fc_slot_table; 465 nfs4_init_slot_table(&session->fc_slot_table, "ForeChannel Slot table");
422 tbl->highest_used_slotid = NFS4_NO_SLOT; 466 nfs4_init_slot_table(&session->bc_slot_table, "BackChannel Slot table");
423 spin_lock_init(&tbl->slot_tbl_lock);
424 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
425 init_completion(&tbl->complete);
426
427 tbl = &session->bc_slot_table;
428 tbl->highest_used_slotid = NFS4_NO_SLOT;
429 spin_lock_init(&tbl->slot_tbl_lock);
430 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
431 init_completion(&tbl->complete);
432
433 session->session_state = 1<<NFS4_SESSION_INITING; 467 session->session_state = 1<<NFS4_SESSION_INITING;
434 468
435 session->clp = clp; 469 session->clp = clp;
@@ -441,7 +475,7 @@ void nfs4_destroy_session(struct nfs4_session *session)
441 struct rpc_xprt *xprt; 475 struct rpc_xprt *xprt;
442 struct rpc_cred *cred; 476 struct rpc_cred *cred;
443 477
444 cred = nfs4_get_exchange_id_cred(session->clp); 478 cred = nfs4_get_clid_cred(session->clp);
445 nfs4_proc_destroy_session(session, cred); 479 nfs4_proc_destroy_session(session, cred);
446 if (cred) 480 if (cred)
447 put_rpccred(cred); 481 put_rpccred(cred);
@@ -452,7 +486,7 @@ void nfs4_destroy_session(struct nfs4_session *session)
452 dprintk("%s Destroy backchannel for xprt %p\n", 486 dprintk("%s Destroy backchannel for xprt %p\n",
453 __func__, xprt); 487 __func__, xprt);
454 xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS); 488 xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
455 nfs4_destroy_slot_tables(session); 489 nfs4_destroy_session_slot_tables(session);
456 kfree(session); 490 kfree(session);
457} 491}
458 492
@@ -513,4 +547,4 @@ int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time)
513} 547}
514EXPORT_SYMBOL_GPL(nfs4_init_ds_session); 548EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
515 549
516 550#endif /* defined(CONFIG_NFS_V4_1) */
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index 3a153d82b90c..232306100651 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -8,7 +8,7 @@
8#define __LINUX_FS_NFS_NFS4SESSION_H 8#define __LINUX_FS_NFS_NFS4SESSION_H
9 9
10/* maximum number of slots to use */ 10/* maximum number of slots to use */
11#define NFS4_DEF_SLOT_TABLE_SIZE (16U) 11#define NFS4_DEF_SLOT_TABLE_SIZE (64U)
12#define NFS4_MAX_SLOT_TABLE (1024U) 12#define NFS4_MAX_SLOT_TABLE (1024U)
13#define NFS4_NO_SLOT ((u32)-1) 13#define NFS4_NO_SLOT ((u32)-1)
14 14
@@ -72,10 +72,22 @@ enum nfs4_session_state {
72 NFS4_SESSION_INITING, 72 NFS4_SESSION_INITING,
73}; 73};
74 74
75#if defined(CONFIG_NFS_V4_1) 75extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl,
76 unsigned int max_reqs, const char *queue);
77extern void nfs4_release_slot_table(struct nfs4_slot_table *tbl);
76extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); 78extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl);
77extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); 79extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot);
80extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl);
81bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
82 struct nfs4_slot *slot);
83void nfs41_wake_slot_table(struct nfs4_slot_table *tbl);
84
85static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl)
86{
87 return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
88}
78 89
90#if defined(CONFIG_NFS_V4_1)
79extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, 91extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
80 u32 target_highest_slotid); 92 u32 target_highest_slotid);
81extern void nfs41_update_target_slotid(struct nfs4_slot_table *tbl, 93extern void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
@@ -89,17 +101,6 @@ extern void nfs4_destroy_session(struct nfs4_session *session);
89extern int nfs4_init_session(struct nfs_client *clp); 101extern int nfs4_init_session(struct nfs_client *clp);
90extern int nfs4_init_ds_session(struct nfs_client *, unsigned long); 102extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
91 103
92extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl);
93
94static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl)
95{
96 return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
97}
98
99bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
100 struct nfs4_slot *slot);
101void nfs41_wake_slot_table(struct nfs4_slot_table *tbl);
102
103/* 104/*
104 * Determine if sessions are in use. 105 * Determine if sessions are in use.
105 */ 106 */
@@ -117,6 +118,16 @@ static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
117 return 0; 118 return 0;
118} 119}
119 120
121#ifdef CONFIG_CRC32
122/*
123 * nfs_session_id_hash - calculate the crc32 hash for the session id
124 * @session - pointer to session
125 */
126#define nfs_session_id_hash(sess_id) \
127 (~crc32_le(0xFFFFFFFF, &(sess_id)->data[0], sizeof((sess_id)->data)))
128#else
129#define nfs_session_id_hash(session) (0)
130#endif
120#else /* defined(CONFIG_NFS_V4_1) */ 131#else /* defined(CONFIG_NFS_V4_1) */
121 132
122static inline int nfs4_init_session(struct nfs_client *clp) 133static inline int nfs4_init_session(struct nfs_client *clp)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e22862f13564..cc14cbb78b73 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -154,6 +154,19 @@ struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
154 return cred; 154 return cred;
155} 155}
156 156
157static void nfs4_root_machine_cred(struct nfs_client *clp)
158{
159 struct rpc_cred *cred, *new;
160
161 new = rpc_lookup_machine_cred(NULL);
162 spin_lock(&clp->cl_lock);
163 cred = clp->cl_machine_cred;
164 clp->cl_machine_cred = new;
165 spin_unlock(&clp->cl_lock);
166 if (cred != NULL)
167 put_rpccred(cred);
168}
169
157static struct rpc_cred * 170static struct rpc_cred *
158nfs4_get_renew_cred_server_locked(struct nfs_server *server) 171nfs4_get_renew_cred_server_locked(struct nfs_server *server)
159{ 172{
@@ -202,32 +215,6 @@ out:
202 return cred; 215 return cred;
203} 216}
204 217
205#if defined(CONFIG_NFS_V4_1)
206
207static int nfs41_setup_state_renewal(struct nfs_client *clp)
208{
209 int status;
210 struct nfs_fsinfo fsinfo;
211
212 if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) {
213 nfs4_schedule_state_renewal(clp);
214 return 0;
215 }
216
217 status = nfs4_proc_get_lease_time(clp, &fsinfo);
218 if (status == 0) {
219 /* Update lease time and schedule renewal */
220 spin_lock(&clp->cl_lock);
221 clp->cl_lease_time = fsinfo.lease_time * HZ;
222 clp->cl_last_renewal = jiffies;
223 spin_unlock(&clp->cl_lock);
224
225 nfs4_schedule_state_renewal(clp);
226 }
227
228 return status;
229}
230
231static void nfs4_end_drain_slot_table(struct nfs4_slot_table *tbl) 218static void nfs4_end_drain_slot_table(struct nfs4_slot_table *tbl)
232{ 219{
233 if (test_and_clear_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { 220 if (test_and_clear_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
@@ -241,20 +228,18 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
241{ 228{
242 struct nfs4_session *ses = clp->cl_session; 229 struct nfs4_session *ses = clp->cl_session;
243 230
231 if (clp->cl_slot_tbl) {
232 nfs4_end_drain_slot_table(clp->cl_slot_tbl);
233 return;
234 }
235
244 if (ses != NULL) { 236 if (ses != NULL) {
245 nfs4_end_drain_slot_table(&ses->bc_slot_table); 237 nfs4_end_drain_slot_table(&ses->bc_slot_table);
246 nfs4_end_drain_slot_table(&ses->fc_slot_table); 238 nfs4_end_drain_slot_table(&ses->fc_slot_table);
247 } 239 }
248} 240}
249 241
250/* 242#if defined(CONFIG_NFS_V4_1)
251 * Signal state manager thread if session fore channel is drained
252 */
253void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl)
254{
255 if (nfs4_slot_tbl_draining(tbl))
256 complete(&tbl->complete);
257}
258 243
259static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl) 244static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl)
260{ 245{
@@ -274,6 +259,9 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
274 struct nfs4_session *ses = clp->cl_session; 259 struct nfs4_session *ses = clp->cl_session;
275 int ret = 0; 260 int ret = 0;
276 261
262 if (clp->cl_slot_tbl)
263 return nfs4_drain_slot_tbl(clp->cl_slot_tbl);
264
277 /* back channel */ 265 /* back channel */
278 ret = nfs4_drain_slot_tbl(&ses->bc_slot_table); 266 ret = nfs4_drain_slot_tbl(&ses->bc_slot_table);
279 if (ret) 267 if (ret)
@@ -282,6 +270,30 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
282 return nfs4_drain_slot_tbl(&ses->fc_slot_table); 270 return nfs4_drain_slot_tbl(&ses->fc_slot_table);
283} 271}
284 272
273static int nfs41_setup_state_renewal(struct nfs_client *clp)
274{
275 int status;
276 struct nfs_fsinfo fsinfo;
277
278 if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) {
279 nfs4_schedule_state_renewal(clp);
280 return 0;
281 }
282
283 status = nfs4_proc_get_lease_time(clp, &fsinfo);
284 if (status == 0) {
285 /* Update lease time and schedule renewal */
286 spin_lock(&clp->cl_lock);
287 clp->cl_lease_time = fsinfo.lease_time * HZ;
288 clp->cl_last_renewal = jiffies;
289 spin_unlock(&clp->cl_lock);
290
291 nfs4_schedule_state_renewal(clp);
292 }
293
294 return status;
295}
296
285static void nfs41_finish_session_reset(struct nfs_client *clp) 297static void nfs41_finish_session_reset(struct nfs_client *clp)
286{ 298{
287 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 299 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
@@ -339,62 +351,21 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
339 return nfs41_walk_client_list(clp, result, cred); 351 return nfs41_walk_client_list(clp, result, cred);
340} 352}
341 353
342struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
343{
344 struct rpc_cred *cred;
345
346 spin_lock(&clp->cl_lock);
347 cred = nfs4_get_machine_cred_locked(clp);
348 spin_unlock(&clp->cl_lock);
349 return cred;
350}
351
352#endif /* CONFIG_NFS_V4_1 */ 354#endif /* CONFIG_NFS_V4_1 */
353 355
354static struct rpc_cred *
355nfs4_get_setclientid_cred_server(struct nfs_server *server)
356{
357 struct nfs_client *clp = server->nfs_client;
358 struct rpc_cred *cred = NULL;
359 struct nfs4_state_owner *sp;
360 struct rb_node *pos;
361
362 spin_lock(&clp->cl_lock);
363 pos = rb_first(&server->state_owners);
364 if (pos != NULL) {
365 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
366 cred = get_rpccred(sp->so_cred);
367 }
368 spin_unlock(&clp->cl_lock);
369 return cred;
370}
371
372/** 356/**
373 * nfs4_get_setclientid_cred - Acquire credential for a setclientid operation 357 * nfs4_get_clid_cred - Acquire credential for a setclientid operation
374 * @clp: client state handle 358 * @clp: client state handle
375 * 359 *
376 * Returns an rpc_cred with reference count bumped, or NULL. 360 * Returns an rpc_cred with reference count bumped, or NULL.
377 */ 361 */
378struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) 362struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp)
379{ 363{
380 struct nfs_server *server;
381 struct rpc_cred *cred; 364 struct rpc_cred *cred;
382 365
383 spin_lock(&clp->cl_lock); 366 spin_lock(&clp->cl_lock);
384 cred = nfs4_get_machine_cred_locked(clp); 367 cred = nfs4_get_machine_cred_locked(clp);
385 spin_unlock(&clp->cl_lock); 368 spin_unlock(&clp->cl_lock);
386 if (cred != NULL)
387 goto out;
388
389 rcu_read_lock();
390 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
391 cred = nfs4_get_setclientid_cred_server(server);
392 if (cred != NULL)
393 break;
394 }
395 rcu_read_unlock();
396
397out:
398 return cred; 369 return cred;
399} 370}
400 371
@@ -998,7 +969,9 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
998 fl_pid = lockowner->l_pid; 969 fl_pid = lockowner->l_pid;
999 spin_lock(&state->state_lock); 970 spin_lock(&state->state_lock);
1000 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); 971 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
1001 if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { 972 if (lsp && test_bit(NFS_LOCK_LOST, &lsp->ls_flags))
973 ret = -EIO;
974 else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
1002 nfs4_stateid_copy(dst, &lsp->ls_stateid); 975 nfs4_stateid_copy(dst, &lsp->ls_stateid);
1003 ret = 0; 976 ret = 0;
1004 smp_rmb(); 977 smp_rmb();
@@ -1038,11 +1011,17 @@ static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
1038int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, 1011int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
1039 fmode_t fmode, const struct nfs_lockowner *lockowner) 1012 fmode_t fmode, const struct nfs_lockowner *lockowner)
1040{ 1013{
1041 int ret = 0; 1014 int ret = nfs4_copy_lock_stateid(dst, state, lockowner);
1015 if (ret == -EIO)
1016 /* A lost lock - don't even consider delegations */
1017 goto out;
1042 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) 1018 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
1043 goto out; 1019 goto out;
1044 ret = nfs4_copy_lock_stateid(dst, state, lockowner);
1045 if (ret != -ENOENT) 1020 if (ret != -ENOENT)
1021 /* nfs4_copy_delegation_stateid() didn't over-write
1022 * dst, so it still has the lock stateid which we now
1023 * choose to use.
1024 */
1046 goto out; 1025 goto out;
1047 ret = nfs4_copy_open_stateid(dst, state); 1026 ret = nfs4_copy_open_stateid(dst, state);
1048out: 1027out:
@@ -1443,14 +1422,16 @@ restart:
1443 if (status >= 0) { 1422 if (status >= 0) {
1444 status = nfs4_reclaim_locks(state, ops); 1423 status = nfs4_reclaim_locks(state, ops);
1445 if (status >= 0) { 1424 if (status >= 0) {
1446 spin_lock(&state->state_lock); 1425 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) {
1447 list_for_each_entry(lock, &state->lock_states, ls_locks) { 1426 spin_lock(&state->state_lock);
1448 if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags)) 1427 list_for_each_entry(lock, &state->lock_states, ls_locks) {
1449 pr_warn_ratelimited("NFS: " 1428 if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
1450 "%s: Lock reclaim " 1429 pr_warn_ratelimited("NFS: "
1451 "failed!\n", __func__); 1430 "%s: Lock reclaim "
1431 "failed!\n", __func__);
1432 }
1433 spin_unlock(&state->state_lock);
1452 } 1434 }
1453 spin_unlock(&state->state_lock);
1454 nfs4_put_open_state(state); 1435 nfs4_put_open_state(state);
1455 spin_lock(&sp->so_lock); 1436 spin_lock(&sp->so_lock);
1456 goto restart; 1437 goto restart;
@@ -1618,7 +1599,7 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1618 if (!nfs4_state_clear_reclaim_reboot(clp)) 1599 if (!nfs4_state_clear_reclaim_reboot(clp))
1619 return; 1600 return;
1620 ops = clp->cl_mvops->reboot_recovery_ops; 1601 ops = clp->cl_mvops->reboot_recovery_ops;
1621 cred = ops->get_clid_cred(clp); 1602 cred = nfs4_get_clid_cred(clp);
1622 nfs4_reclaim_complete(clp, ops, cred); 1603 nfs4_reclaim_complete(clp, ops, cred);
1623 put_rpccred(cred); 1604 put_rpccred(cred);
1624} 1605}
@@ -1732,7 +1713,7 @@ static int nfs4_check_lease(struct nfs_client *clp)
1732 cred = ops->get_state_renewal_cred_locked(clp); 1713 cred = ops->get_state_renewal_cred_locked(clp);
1733 spin_unlock(&clp->cl_lock); 1714 spin_unlock(&clp->cl_lock);
1734 if (cred == NULL) { 1715 if (cred == NULL) {
1735 cred = nfs4_get_setclientid_cred(clp); 1716 cred = nfs4_get_clid_cred(clp);
1736 status = -ENOKEY; 1717 status = -ENOKEY;
1737 if (cred == NULL) 1718 if (cred == NULL)
1738 goto out; 1719 goto out;
@@ -1804,7 +1785,7 @@ static int nfs4_establish_lease(struct nfs_client *clp)
1804 clp->cl_mvops->reboot_recovery_ops; 1785 clp->cl_mvops->reboot_recovery_ops;
1805 int status; 1786 int status;
1806 1787
1807 cred = ops->get_clid_cred(clp); 1788 cred = nfs4_get_clid_cred(clp);
1808 if (cred == NULL) 1789 if (cred == NULL)
1809 return -ENOENT; 1790 return -ENOENT;
1810 status = ops->establish_clid(clp, cred); 1791 status = ops->establish_clid(clp, cred);
@@ -1878,7 +1859,7 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
1878 mutex_lock(&nfs_clid_init_mutex); 1859 mutex_lock(&nfs_clid_init_mutex);
1879again: 1860again:
1880 status = -ENOENT; 1861 status = -ENOENT;
1881 cred = ops->get_clid_cred(clp); 1862 cred = nfs4_get_clid_cred(clp);
1882 if (cred == NULL) 1863 if (cred == NULL)
1883 goto out_unlock; 1864 goto out_unlock;
1884 1865
@@ -1896,7 +1877,11 @@ again:
1896 __func__, status); 1877 __func__, status);
1897 goto again; 1878 goto again;
1898 case -EACCES: 1879 case -EACCES:
1899 if (i++) 1880 if (i++ == 0) {
1881 nfs4_root_machine_cred(clp);
1882 goto again;
1883 }
1884 if (i > 2)
1900 break; 1885 break;
1901 case -NFS4ERR_CLID_INUSE: 1886 case -NFS4ERR_CLID_INUSE:
1902 case -NFS4ERR_WRONGSEC: 1887 case -NFS4ERR_WRONGSEC:
@@ -2052,7 +2037,7 @@ static int nfs4_reset_session(struct nfs_client *clp)
2052 if (!nfs4_has_session(clp)) 2037 if (!nfs4_has_session(clp))
2053 return 0; 2038 return 0;
2054 nfs4_begin_drain_session(clp); 2039 nfs4_begin_drain_session(clp);
2055 cred = nfs4_get_exchange_id_cred(clp); 2040 cred = nfs4_get_clid_cred(clp);
2056 status = nfs4_proc_destroy_session(clp->cl_session, cred); 2041 status = nfs4_proc_destroy_session(clp->cl_session, cred);
2057 switch (status) { 2042 switch (status) {
2058 case 0: 2043 case 0:
@@ -2095,7 +2080,7 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
2095 if (!nfs4_has_session(clp)) 2080 if (!nfs4_has_session(clp))
2096 return 0; 2081 return 0;
2097 nfs4_begin_drain_session(clp); 2082 nfs4_begin_drain_session(clp);
2098 cred = nfs4_get_exchange_id_cred(clp); 2083 cred = nfs4_get_clid_cred(clp);
2099 ret = nfs4_proc_bind_conn_to_session(clp, cred); 2084 ret = nfs4_proc_bind_conn_to_session(clp, cred);
2100 if (cred) 2085 if (cred)
2101 put_rpccred(cred); 2086 put_rpccred(cred);
@@ -2116,7 +2101,6 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
2116} 2101}
2117#else /* CONFIG_NFS_V4_1 */ 2102#else /* CONFIG_NFS_V4_1 */
2118static int nfs4_reset_session(struct nfs_client *clp) { return 0; } 2103static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
2119static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
2120 2104
2121static int nfs4_bind_conn_to_session(struct nfs_client *clp) 2105static int nfs4_bind_conn_to_session(struct nfs_client *clp)
2122{ 2106{
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 5dbe2d269210..e26acdd1a645 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -253,8 +253,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
253 253
254 dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 254 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
255 255
256 if (data->auth_flavors[0] == RPC_AUTH_MAXFLAVOR)
257 data->auth_flavors[0] = RPC_AUTH_UNIX;
258 export_path = data->nfs_server.export_path; 256 export_path = data->nfs_server.export_path;
259 data->nfs_server.export_path = "/"; 257 data->nfs_server.export_path = "/";
260 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 258 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
diff --git a/fs/nfs/nfs4trace.c b/fs/nfs/nfs4trace.c
new file mode 100644
index 000000000000..d774335cc8bc
--- /dev/null
+++ b/fs/nfs/nfs4trace.c
@@ -0,0 +1,17 @@
1/*
2 * Copyright (c) 2013 Trond Myklebust <Trond.Myklebust@netapp.com>
3 */
4#include <linux/nfs_fs.h>
5#include "nfs4_fs.h"
6#include "internal.h"
7#include "nfs4session.h"
8#include "callback.h"
9
10#define CREATE_TRACE_POINTS
11#include "nfs4trace.h"
12
13#ifdef CONFIG_NFS_V4_1
14EXPORT_TRACEPOINT_SYMBOL_GPL(nfs4_pnfs_read);
15EXPORT_TRACEPOINT_SYMBOL_GPL(nfs4_pnfs_write);
16EXPORT_TRACEPOINT_SYMBOL_GPL(nfs4_pnfs_commit_ds);
17#endif
diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
new file mode 100644
index 000000000000..849cf146db30
--- /dev/null
+++ b/fs/nfs/nfs4trace.h
@@ -0,0 +1,1148 @@
1/*
2 * Copyright (c) 2013 Trond Myklebust <Trond.Myklebust@netapp.com>
3 */
4#undef TRACE_SYSTEM
5#define TRACE_SYSTEM nfs4
6
7#if !defined(_TRACE_NFS4_H) || defined(TRACE_HEADER_MULTI_READ)
8#define _TRACE_NFS4_H
9
10#include <linux/tracepoint.h>
11
12#define show_nfsv4_errors(error) \
13 __print_symbolic(error, \
14 { NFS4_OK, "OK" }, \
15 /* Mapped by nfs4_stat_to_errno() */ \
16 { -EPERM, "EPERM" }, \
17 { -ENOENT, "ENOENT" }, \
18 { -EIO, "EIO" }, \
19 { -ENXIO, "ENXIO" }, \
20 { -EACCES, "EACCES" }, \
21 { -EEXIST, "EEXIST" }, \
22 { -EXDEV, "EXDEV" }, \
23 { -ENOTDIR, "ENOTDIR" }, \
24 { -EISDIR, "EISDIR" }, \
25 { -EFBIG, "EFBIG" }, \
26 { -ENOSPC, "ENOSPC" }, \
27 { -EROFS, "EROFS" }, \
28 { -EMLINK, "EMLINK" }, \
29 { -ENAMETOOLONG, "ENAMETOOLONG" }, \
30 { -ENOTEMPTY, "ENOTEMPTY" }, \
31 { -EDQUOT, "EDQUOT" }, \
32 { -ESTALE, "ESTALE" }, \
33 { -EBADHANDLE, "EBADHANDLE" }, \
34 { -EBADCOOKIE, "EBADCOOKIE" }, \
35 { -ENOTSUPP, "ENOTSUPP" }, \
36 { -ETOOSMALL, "ETOOSMALL" }, \
37 { -EREMOTEIO, "EREMOTEIO" }, \
38 { -EBADTYPE, "EBADTYPE" }, \
39 { -EAGAIN, "EAGAIN" }, \
40 { -ELOOP, "ELOOP" }, \
41 { -EOPNOTSUPP, "EOPNOTSUPP" }, \
42 { -EDEADLK, "EDEADLK" }, \
43 /* RPC errors */ \
44 { -ENOMEM, "ENOMEM" }, \
45 { -EKEYEXPIRED, "EKEYEXPIRED" }, \
46 { -ETIMEDOUT, "ETIMEDOUT" }, \
47 { -ERESTARTSYS, "ERESTARTSYS" }, \
48 { -ECONNREFUSED, "ECONNREFUSED" }, \
49 { -ECONNRESET, "ECONNRESET" }, \
50 { -ENETUNREACH, "ENETUNREACH" }, \
51 { -EHOSTUNREACH, "EHOSTUNREACH" }, \
52 { -EHOSTDOWN, "EHOSTDOWN" }, \
53 { -EPIPE, "EPIPE" }, \
54 { -EPFNOSUPPORT, "EPFNOSUPPORT" }, \
55 { -EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \
56 /* NFSv4 native errors */ \
57 { -NFS4ERR_ACCESS, "ACCESS" }, \
58 { -NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \
59 { -NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \
60 { -NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \
61 { -NFS4ERR_BADCHAR, "BADCHAR" }, \
62 { -NFS4ERR_BADHANDLE, "BADHANDLE" }, \
63 { -NFS4ERR_BADIOMODE, "BADIOMODE" }, \
64 { -NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \
65 { -NFS4ERR_BADLABEL, "BADLABEL" }, \
66 { -NFS4ERR_BADNAME, "BADNAME" }, \
67 { -NFS4ERR_BADOWNER, "BADOWNER" }, \
68 { -NFS4ERR_BADSESSION, "BADSESSION" }, \
69 { -NFS4ERR_BADSLOT, "BADSLOT" }, \
70 { -NFS4ERR_BADTYPE, "BADTYPE" }, \
71 { -NFS4ERR_BADXDR, "BADXDR" }, \
72 { -NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \
73 { -NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \
74 { -NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \
75 { -NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \
76 { -NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \
77 { -NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \
78 { -NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
79 { -NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \
80 { -NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \
81 { -NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \
82 { -NFS4ERR_CONN_NOT_BOUND_TO_SESSION, \
83 "CONN_NOT_BOUND_TO_SESSION" }, \
84 { -NFS4ERR_DEADLOCK, "DEADLOCK" }, \
85 { -NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \
86 { -NFS4ERR_DELAY, "DELAY" }, \
87 { -NFS4ERR_DELEG_ALREADY_WANTED, \
88 "DELEG_ALREADY_WANTED" }, \
89 { -NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \
90 { -NFS4ERR_DENIED, "DENIED" }, \
91 { -NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \
92 { -NFS4ERR_DQUOT, "DQUOT" }, \
93 { -NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \
94 { -NFS4ERR_EXIST, "EXIST" }, \
95 { -NFS4ERR_EXPIRED, "EXPIRED" }, \
96 { -NFS4ERR_FBIG, "FBIG" }, \
97 { -NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \
98 { -NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \
99 { -NFS4ERR_GRACE, "GRACE" }, \
100 { -NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \
101 { -NFS4ERR_INVAL, "INVAL" }, \
102 { -NFS4ERR_IO, "IO" }, \
103 { -NFS4ERR_ISDIR, "ISDIR" }, \
104 { -NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \
105 { -NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \
106 { -NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \
107 { -NFS4ERR_LOCKED, "LOCKED" }, \
108 { -NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \
109 { -NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \
110 { -NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \
111 { -NFS4ERR_MLINK, "MLINK" }, \
112 { -NFS4ERR_MOVED, "MOVED" }, \
113 { -NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \
114 { -NFS4ERR_NOENT, "NOENT" }, \
115 { -NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \
116 { -NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \
117 { -NFS4ERR_NOSPC, "NOSPC" }, \
118 { -NFS4ERR_NOTDIR, "NOTDIR" }, \
119 { -NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \
120 { -NFS4ERR_NOTSUPP, "NOTSUPP" }, \
121 { -NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \
122 { -NFS4ERR_NOT_SAME, "NOT_SAME" }, \
123 { -NFS4ERR_NO_GRACE, "NO_GRACE" }, \
124 { -NFS4ERR_NXIO, "NXIO" }, \
125 { -NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \
126 { -NFS4ERR_OPENMODE, "OPENMODE" }, \
127 { -NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \
128 { -NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \
129 { -NFS4ERR_PERM, "PERM" }, \
130 { -NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \
131 { -NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \
132 { -NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \
133 { -NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \
134 { -NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \
135 { -NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \
136 { -NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \
137 { -NFS4ERR_REP_TOO_BIG_TO_CACHE, \
138 "REP_TOO_BIG_TO_CACHE" }, \
139 { -NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \
140 { -NFS4ERR_RESOURCE, "RESOURCE" }, \
141 { -NFS4ERR_RESTOREFH, "RESTOREFH" }, \
142 { -NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \
143 { -NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \
144 { -NFS4ERR_ROFS, "ROFS" }, \
145 { -NFS4ERR_SAME, "SAME" }, \
146 { -NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \
147 { -NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \
148 { -NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \
149 { -NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \
150 { -NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \
151 { -NFS4ERR_STALE, "STALE" }, \
152 { -NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \
153 { -NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \
154 { -NFS4ERR_SYMLINK, "SYMLINK" }, \
155 { -NFS4ERR_TOOSMALL, "TOOSMALL" }, \
156 { -NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \
157 { -NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \
158 { -NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \
159 { -NFS4ERR_WRONGSEC, "WRONGSEC" }, \
160 { -NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \
161 { -NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \
162 { -NFS4ERR_XDEV, "XDEV" })
163
164#define show_open_flags(flags) \
165 __print_flags(flags, "|", \
166 { O_CREAT, "O_CREAT" }, \
167 { O_EXCL, "O_EXCL" }, \
168 { O_TRUNC, "O_TRUNC" }, \
169 { O_DIRECT, "O_DIRECT" })
170
171#define show_fmode_flags(mode) \
172 __print_flags(mode, "|", \
173 { ((__force unsigned long)FMODE_READ), "READ" }, \
174 { ((__force unsigned long)FMODE_WRITE), "WRITE" }, \
175 { ((__force unsigned long)FMODE_EXEC), "EXEC" })
176
177#define show_nfs_fattr_flags(valid) \
178 __print_flags((unsigned long)valid, "|", \
179 { NFS_ATTR_FATTR_TYPE, "TYPE" }, \
180 { NFS_ATTR_FATTR_MODE, "MODE" }, \
181 { NFS_ATTR_FATTR_NLINK, "NLINK" }, \
182 { NFS_ATTR_FATTR_OWNER, "OWNER" }, \
183 { NFS_ATTR_FATTR_GROUP, "GROUP" }, \
184 { NFS_ATTR_FATTR_RDEV, "RDEV" }, \
185 { NFS_ATTR_FATTR_SIZE, "SIZE" }, \
186 { NFS_ATTR_FATTR_FSID, "FSID" }, \
187 { NFS_ATTR_FATTR_FILEID, "FILEID" }, \
188 { NFS_ATTR_FATTR_ATIME, "ATIME" }, \
189 { NFS_ATTR_FATTR_MTIME, "MTIME" }, \
190 { NFS_ATTR_FATTR_CTIME, "CTIME" }, \
191 { NFS_ATTR_FATTR_CHANGE, "CHANGE" }, \
192 { NFS_ATTR_FATTR_OWNER_NAME, "OWNER_NAME" }, \
193 { NFS_ATTR_FATTR_GROUP_NAME, "GROUP_NAME" })
194
195DECLARE_EVENT_CLASS(nfs4_clientid_event,
196 TP_PROTO(
197 const struct nfs_client *clp,
198 int error
199 ),
200
201 TP_ARGS(clp, error),
202
203 TP_STRUCT__entry(
204 __string(dstaddr,
205 rpc_peeraddr2str(clp->cl_rpcclient,
206 RPC_DISPLAY_ADDR))
207 __field(int, error)
208 ),
209
210 TP_fast_assign(
211 __entry->error = error;
212 __assign_str(dstaddr,
213 rpc_peeraddr2str(clp->cl_rpcclient,
214 RPC_DISPLAY_ADDR));
215 ),
216
217 TP_printk(
218 "error=%d (%s) dstaddr=%s",
219 __entry->error,
220 show_nfsv4_errors(__entry->error),
221 __get_str(dstaddr)
222 )
223);
224#define DEFINE_NFS4_CLIENTID_EVENT(name) \
225 DEFINE_EVENT(nfs4_clientid_event, name, \
226 TP_PROTO( \
227 const struct nfs_client *clp, \
228 int error \
229 ), \
230 TP_ARGS(clp, error))
231DEFINE_NFS4_CLIENTID_EVENT(nfs4_setclientid);
232DEFINE_NFS4_CLIENTID_EVENT(nfs4_setclientid_confirm);
233DEFINE_NFS4_CLIENTID_EVENT(nfs4_renew);
234DEFINE_NFS4_CLIENTID_EVENT(nfs4_renew_async);
235#ifdef CONFIG_NFS_V4_1
236DEFINE_NFS4_CLIENTID_EVENT(nfs4_exchange_id);
237DEFINE_NFS4_CLIENTID_EVENT(nfs4_create_session);
238DEFINE_NFS4_CLIENTID_EVENT(nfs4_destroy_session);
239DEFINE_NFS4_CLIENTID_EVENT(nfs4_destroy_clientid);
240DEFINE_NFS4_CLIENTID_EVENT(nfs4_bind_conn_to_session);
241DEFINE_NFS4_CLIENTID_EVENT(nfs4_sequence);
242DEFINE_NFS4_CLIENTID_EVENT(nfs4_reclaim_complete);
243
244TRACE_EVENT(nfs4_setup_sequence,
245 TP_PROTO(
246 const struct nfs4_session *session,
247 const struct nfs4_sequence_args *args
248 ),
249 TP_ARGS(session, args),
250
251 TP_STRUCT__entry(
252 __field(unsigned int, session)
253 __field(unsigned int, slot_nr)
254 __field(unsigned int, seq_nr)
255 __field(unsigned int, highest_used_slotid)
256 ),
257
258 TP_fast_assign(
259 const struct nfs4_slot *sa_slot = args->sa_slot;
260 __entry->session = nfs_session_id_hash(&session->sess_id);
261 __entry->slot_nr = sa_slot->slot_nr;
262 __entry->seq_nr = sa_slot->seq_nr;
263 __entry->highest_used_slotid =
264 sa_slot->table->highest_used_slotid;
265 ),
266 TP_printk(
267 "session=0x%08x slot_nr=%u seq_nr=%u "
268 "highest_used_slotid=%u",
269 __entry->session,
270 __entry->slot_nr,
271 __entry->seq_nr,
272 __entry->highest_used_slotid
273 )
274);
275
276#define show_nfs4_sequence_status_flags(status) \
277 __print_flags((unsigned long)status, "|", \
278 { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
279 { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, \
280 "CB_GSS_CONTEXTS_EXPIRING" }, \
281 { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, \
282 "CB_GSS_CONTEXTS_EXPIRED" }, \
283 { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, \
284 "EXPIRED_ALL_STATE_REVOKED" }, \
285 { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, \
286 "EXPIRED_SOME_STATE_REVOKED" }, \
287 { SEQ4_STATUS_ADMIN_STATE_REVOKED, \
288 "ADMIN_STATE_REVOKED" }, \
289 { SEQ4_STATUS_RECALLABLE_STATE_REVOKED, \
290 "RECALLABLE_STATE_REVOKED" }, \
291 { SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \
292 { SEQ4_STATUS_RESTART_RECLAIM_NEEDED, \
293 "RESTART_RECLAIM_NEEDED" }, \
294 { SEQ4_STATUS_CB_PATH_DOWN_SESSION, \
295 "CB_PATH_DOWN_SESSION" }, \
296 { SEQ4_STATUS_BACKCHANNEL_FAULT, \
297 "BACKCHANNEL_FAULT" })
298
299TRACE_EVENT(nfs4_sequence_done,
300 TP_PROTO(
301 const struct nfs4_session *session,
302 const struct nfs4_sequence_res *res
303 ),
304 TP_ARGS(session, res),
305
306 TP_STRUCT__entry(
307 __field(unsigned int, session)
308 __field(unsigned int, slot_nr)
309 __field(unsigned int, seq_nr)
310 __field(unsigned int, highest_slotid)
311 __field(unsigned int, target_highest_slotid)
312 __field(unsigned int, status_flags)
313 __field(int, error)
314 ),
315
316 TP_fast_assign(
317 const struct nfs4_slot *sr_slot = res->sr_slot;
318 __entry->session = nfs_session_id_hash(&session->sess_id);
319 __entry->slot_nr = sr_slot->slot_nr;
320 __entry->seq_nr = sr_slot->seq_nr;
321 __entry->highest_slotid = res->sr_highest_slotid;
322 __entry->target_highest_slotid =
323 res->sr_target_highest_slotid;
324 __entry->error = res->sr_status;
325 ),
326 TP_printk(
327 "error=%d (%s) session=0x%08x slot_nr=%u seq_nr=%u "
328 "highest_slotid=%u target_highest_slotid=%u "
329 "status_flags=%u (%s)",
330 __entry->error,
331 show_nfsv4_errors(__entry->error),
332 __entry->session,
333 __entry->slot_nr,
334 __entry->seq_nr,
335 __entry->highest_slotid,
336 __entry->target_highest_slotid,
337 __entry->status_flags,
338 show_nfs4_sequence_status_flags(__entry->status_flags)
339 )
340);
341
342struct cb_sequenceargs;
343struct cb_sequenceres;
344
345TRACE_EVENT(nfs4_cb_sequence,
346 TP_PROTO(
347 const struct cb_sequenceargs *args,
348 const struct cb_sequenceres *res,
349 __be32 status
350 ),
351 TP_ARGS(args, res, status),
352
353 TP_STRUCT__entry(
354 __field(unsigned int, session)
355 __field(unsigned int, slot_nr)
356 __field(unsigned int, seq_nr)
357 __field(unsigned int, highest_slotid)
358 __field(unsigned int, cachethis)
359 __field(int, error)
360 ),
361
362 TP_fast_assign(
363 __entry->session = nfs_session_id_hash(&args->csa_sessionid);
364 __entry->slot_nr = args->csa_slotid;
365 __entry->seq_nr = args->csa_sequenceid;
366 __entry->highest_slotid = args->csa_highestslotid;
367 __entry->cachethis = args->csa_cachethis;
368 __entry->error = -be32_to_cpu(status);
369 ),
370
371 TP_printk(
372 "error=%d (%s) session=0x%08x slot_nr=%u seq_nr=%u "
373 "highest_slotid=%u",
374 __entry->error,
375 show_nfsv4_errors(__entry->error),
376 __entry->session,
377 __entry->slot_nr,
378 __entry->seq_nr,
379 __entry->highest_slotid
380 )
381);
382#endif /* CONFIG_NFS_V4_1 */
383
384DECLARE_EVENT_CLASS(nfs4_open_event,
385 TP_PROTO(
386 const struct nfs_open_context *ctx,
387 int flags,
388 int error
389 ),
390
391 TP_ARGS(ctx, flags, error),
392
393 TP_STRUCT__entry(
394 __field(int, error)
395 __field(unsigned int, flags)
396 __field(unsigned int, fmode)
397 __field(dev_t, dev)
398 __field(u32, fhandle)
399 __field(u64, fileid)
400 __field(u64, dir)
401 __string(name, ctx->dentry->d_name.name)
402 ),
403
404 TP_fast_assign(
405 const struct nfs4_state *state = ctx->state;
406 const struct inode *inode = NULL;
407
408 __entry->error = error;
409 __entry->flags = flags;
410 __entry->fmode = (__force unsigned int)ctx->mode;
411 __entry->dev = ctx->dentry->d_sb->s_dev;
412 if (!IS_ERR(state))
413 inode = state->inode;
414 if (inode != NULL) {
415 __entry->fileid = NFS_FILEID(inode);
416 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
417 } else {
418 __entry->fileid = 0;
419 __entry->fhandle = 0;
420 }
421 __entry->dir = NFS_FILEID(ctx->dentry->d_parent->d_inode);
422 __assign_str(name, ctx->dentry->d_name.name);
423 ),
424
425 TP_printk(
426 "error=%d (%s) flags=%d (%s) fmode=%s "
427 "fileid=%02x:%02x:%llu fhandle=0x%08x "
428 "name=%02x:%02x:%llu/%s",
429 __entry->error,
430 show_nfsv4_errors(__entry->error),
431 __entry->flags,
432 show_open_flags(__entry->flags),
433 show_fmode_flags(__entry->fmode),
434 MAJOR(__entry->dev), MINOR(__entry->dev),
435 (unsigned long long)__entry->fileid,
436 __entry->fhandle,
437 MAJOR(__entry->dev), MINOR(__entry->dev),
438 (unsigned long long)__entry->dir,
439 __get_str(name)
440 )
441);
442
443#define DEFINE_NFS4_OPEN_EVENT(name) \
444 DEFINE_EVENT(nfs4_open_event, name, \
445 TP_PROTO( \
446 const struct nfs_open_context *ctx, \
447 int flags, \
448 int error \
449 ), \
450 TP_ARGS(ctx, flags, error))
451DEFINE_NFS4_OPEN_EVENT(nfs4_open_reclaim);
452DEFINE_NFS4_OPEN_EVENT(nfs4_open_expired);
453DEFINE_NFS4_OPEN_EVENT(nfs4_open_file);
454
455TRACE_EVENT(nfs4_close,
456 TP_PROTO(
457 const struct nfs4_state *state,
458 const struct nfs_closeargs *args,
459 const struct nfs_closeres *res,
460 int error
461 ),
462
463 TP_ARGS(state, args, res, error),
464
465 TP_STRUCT__entry(
466 __field(dev_t, dev)
467 __field(u32, fhandle)
468 __field(u64, fileid)
469 __field(unsigned int, fmode)
470 __field(int, error)
471 ),
472
473 TP_fast_assign(
474 const struct inode *inode = state->inode;
475
476 __entry->dev = inode->i_sb->s_dev;
477 __entry->fileid = NFS_FILEID(inode);
478 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
479 __entry->fmode = (__force unsigned int)state->state;
480 __entry->error = error;
481 ),
482
483 TP_printk(
484 "error=%d (%s) fmode=%s fileid=%02x:%02x:%llu "
485 "fhandle=0x%08x",
486 __entry->error,
487 show_nfsv4_errors(__entry->error),
488 __entry->fmode ? show_fmode_flags(__entry->fmode) :
489 "closed",
490 MAJOR(__entry->dev), MINOR(__entry->dev),
491 (unsigned long long)__entry->fileid,
492 __entry->fhandle
493 )
494);
495
496#define show_lock_cmd(type) \
497 __print_symbolic((int)type, \
498 { F_GETLK, "GETLK" }, \
499 { F_SETLK, "SETLK" }, \
500 { F_SETLKW, "SETLKW" })
501#define show_lock_type(type) \
502 __print_symbolic((int)type, \
503 { F_RDLCK, "RDLCK" }, \
504 { F_WRLCK, "WRLCK" }, \
505 { F_UNLCK, "UNLCK" })
506
507DECLARE_EVENT_CLASS(nfs4_lock_event,
508 TP_PROTO(
509 const struct file_lock *request,
510 const struct nfs4_state *state,
511 int cmd,
512 int error
513 ),
514
515 TP_ARGS(request, state, cmd, error),
516
517 TP_STRUCT__entry(
518 __field(int, error)
519 __field(int, cmd)
520 __field(char, type)
521 __field(loff_t, start)
522 __field(loff_t, end)
523 __field(dev_t, dev)
524 __field(u32, fhandle)
525 __field(u64, fileid)
526 ),
527
528 TP_fast_assign(
529 const struct inode *inode = state->inode;
530
531 __entry->error = error;
532 __entry->cmd = cmd;
533 __entry->type = request->fl_type;
534 __entry->start = request->fl_start;
535 __entry->end = request->fl_end;
536 __entry->dev = inode->i_sb->s_dev;
537 __entry->fileid = NFS_FILEID(inode);
538 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
539 ),
540
541 TP_printk(
542 "error=%d (%s) cmd=%s:%s range=%lld:%lld "
543 "fileid=%02x:%02x:%llu fhandle=0x%08x",
544 __entry->error,
545 show_nfsv4_errors(__entry->error),
546 show_lock_cmd(__entry->cmd),
547 show_lock_type(__entry->type),
548 (long long)__entry->start,
549 (long long)__entry->end,
550 MAJOR(__entry->dev), MINOR(__entry->dev),
551 (unsigned long long)__entry->fileid,
552 __entry->fhandle
553 )
554);
555
556#define DEFINE_NFS4_LOCK_EVENT(name) \
557 DEFINE_EVENT(nfs4_lock_event, name, \
558 TP_PROTO( \
559 const struct file_lock *request, \
560 const struct nfs4_state *state, \
561 int cmd, \
562 int error \
563 ), \
564 TP_ARGS(request, state, cmd, error))
565DEFINE_NFS4_LOCK_EVENT(nfs4_get_lock);
566DEFINE_NFS4_LOCK_EVENT(nfs4_set_lock);
567DEFINE_NFS4_LOCK_EVENT(nfs4_lock_reclaim);
568DEFINE_NFS4_LOCK_EVENT(nfs4_lock_expired);
569DEFINE_NFS4_LOCK_EVENT(nfs4_unlock);
570
571DECLARE_EVENT_CLASS(nfs4_set_delegation_event,
572 TP_PROTO(
573 const struct inode *inode,
574 fmode_t fmode
575 ),
576
577 TP_ARGS(inode, fmode),
578
579 TP_STRUCT__entry(
580 __field(dev_t, dev)
581 __field(u32, fhandle)
582 __field(u64, fileid)
583 __field(unsigned int, fmode)
584 ),
585
586 TP_fast_assign(
587 __entry->dev = inode->i_sb->s_dev;
588 __entry->fileid = NFS_FILEID(inode);
589 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
590 __entry->fmode = (__force unsigned int)fmode;
591 ),
592
593 TP_printk(
594 "fmode=%s fileid=%02x:%02x:%llu fhandle=0x%08x",
595 show_fmode_flags(__entry->fmode),
596 MAJOR(__entry->dev), MINOR(__entry->dev),
597 (unsigned long long)__entry->fileid,
598 __entry->fhandle
599 )
600);
601#define DEFINE_NFS4_SET_DELEGATION_EVENT(name) \
602 DEFINE_EVENT(nfs4_set_delegation_event, name, \
603 TP_PROTO( \
604 const struct inode *inode, \
605 fmode_t fmode \
606 ), \
607 TP_ARGS(inode, fmode))
608DEFINE_NFS4_SET_DELEGATION_EVENT(nfs4_set_delegation);
609DEFINE_NFS4_SET_DELEGATION_EVENT(nfs4_reclaim_delegation);
610
611TRACE_EVENT(nfs4_delegreturn_exit,
612 TP_PROTO(
613 const struct nfs4_delegreturnargs *args,
614 const struct nfs4_delegreturnres *res,
615 int error
616 ),
617
618 TP_ARGS(args, res, error),
619
620 TP_STRUCT__entry(
621 __field(dev_t, dev)
622 __field(u32, fhandle)
623 __field(int, error)
624 ),
625
626 TP_fast_assign(
627 __entry->dev = res->server->s_dev;
628 __entry->fhandle = nfs_fhandle_hash(args->fhandle);
629 __entry->error = error;
630 ),
631
632 TP_printk(
633 "error=%d (%s) dev=%02x:%02x fhandle=0x%08x",
634 __entry->error,
635 show_nfsv4_errors(__entry->error),
636 MAJOR(__entry->dev), MINOR(__entry->dev),
637 __entry->fhandle
638 )
639);
640
641#ifdef CONFIG_NFS_V4_1
642DECLARE_EVENT_CLASS(nfs4_test_stateid_event,
643 TP_PROTO(
644 const struct nfs4_state *state,
645 const struct nfs4_lock_state *lsp,
646 int error
647 ),
648
649 TP_ARGS(state, lsp, error),
650
651 TP_STRUCT__entry(
652 __field(int, error)
653 __field(dev_t, dev)
654 __field(u32, fhandle)
655 __field(u64, fileid)
656 ),
657
658 TP_fast_assign(
659 const struct inode *inode = state->inode;
660
661 __entry->error = error;
662 __entry->dev = inode->i_sb->s_dev;
663 __entry->fileid = NFS_FILEID(inode);
664 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
665 ),
666
667 TP_printk(
668 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x",
669 __entry->error,
670 show_nfsv4_errors(__entry->error),
671 MAJOR(__entry->dev), MINOR(__entry->dev),
672 (unsigned long long)__entry->fileid,
673 __entry->fhandle
674 )
675);
676
677#define DEFINE_NFS4_TEST_STATEID_EVENT(name) \
678 DEFINE_EVENT(nfs4_test_stateid_event, name, \
679 TP_PROTO( \
680 const struct nfs4_state *state, \
681 const struct nfs4_lock_state *lsp, \
682 int error \
683 ), \
684 TP_ARGS(state, lsp, error))
685DEFINE_NFS4_TEST_STATEID_EVENT(nfs4_test_delegation_stateid);
686DEFINE_NFS4_TEST_STATEID_EVENT(nfs4_test_open_stateid);
687DEFINE_NFS4_TEST_STATEID_EVENT(nfs4_test_lock_stateid);
688#endif /* CONFIG_NFS_V4_1 */
689
690DECLARE_EVENT_CLASS(nfs4_lookup_event,
691 TP_PROTO(
692 const struct inode *dir,
693 const struct qstr *name,
694 int error
695 ),
696
697 TP_ARGS(dir, name, error),
698
699 TP_STRUCT__entry(
700 __field(dev_t, dev)
701 __field(int, error)
702 __field(u64, dir)
703 __string(name, name->name)
704 ),
705
706 TP_fast_assign(
707 __entry->dev = dir->i_sb->s_dev;
708 __entry->dir = NFS_FILEID(dir);
709 __entry->error = error;
710 __assign_str(name, name->name);
711 ),
712
713 TP_printk(
714 "error=%d (%s) name=%02x:%02x:%llu/%s",
715 __entry->error,
716 show_nfsv4_errors(__entry->error),
717 MAJOR(__entry->dev), MINOR(__entry->dev),
718 (unsigned long long)__entry->dir,
719 __get_str(name)
720 )
721);
722
723#define DEFINE_NFS4_LOOKUP_EVENT(name) \
724 DEFINE_EVENT(nfs4_lookup_event, name, \
725 TP_PROTO( \
726 const struct inode *dir, \
727 const struct qstr *name, \
728 int error \
729 ), \
730 TP_ARGS(dir, name, error))
731
732DEFINE_NFS4_LOOKUP_EVENT(nfs4_lookup);
733DEFINE_NFS4_LOOKUP_EVENT(nfs4_symlink);
734DEFINE_NFS4_LOOKUP_EVENT(nfs4_mkdir);
735DEFINE_NFS4_LOOKUP_EVENT(nfs4_mknod);
736DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove);
737DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
738DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
739
740TRACE_EVENT(nfs4_rename,
741 TP_PROTO(
742 const struct inode *olddir,
743 const struct qstr *oldname,
744 const struct inode *newdir,
745 const struct qstr *newname,
746 int error
747 ),
748
749 TP_ARGS(olddir, oldname, newdir, newname, error),
750
751 TP_STRUCT__entry(
752 __field(dev_t, dev)
753 __field(int, error)
754 __field(u64, olddir)
755 __string(oldname, oldname->name)
756 __field(u64, newdir)
757 __string(newname, newname->name)
758 ),
759
760 TP_fast_assign(
761 __entry->dev = olddir->i_sb->s_dev;
762 __entry->olddir = NFS_FILEID(olddir);
763 __entry->newdir = NFS_FILEID(newdir);
764 __entry->error = error;
765 __assign_str(oldname, oldname->name);
766 __assign_str(newname, newname->name);
767 ),
768
769 TP_printk(
770 "error=%d (%s) oldname=%02x:%02x:%llu/%s "
771 "newname=%02x:%02x:%llu/%s",
772 __entry->error,
773 show_nfsv4_errors(__entry->error),
774 MAJOR(__entry->dev), MINOR(__entry->dev),
775 (unsigned long long)__entry->olddir,
776 __get_str(oldname),
777 MAJOR(__entry->dev), MINOR(__entry->dev),
778 (unsigned long long)__entry->newdir,
779 __get_str(newname)
780 )
781);
782
783DECLARE_EVENT_CLASS(nfs4_inode_event,
784 TP_PROTO(
785 const struct inode *inode,
786 int error
787 ),
788
789 TP_ARGS(inode, error),
790
791 TP_STRUCT__entry(
792 __field(dev_t, dev)
793 __field(u32, fhandle)
794 __field(u64, fileid)
795 __field(int, error)
796 ),
797
798 TP_fast_assign(
799 __entry->dev = inode->i_sb->s_dev;
800 __entry->fileid = NFS_FILEID(inode);
801 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
802 __entry->error = error;
803 ),
804
805 TP_printk(
806 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x",
807 __entry->error,
808 show_nfsv4_errors(__entry->error),
809 MAJOR(__entry->dev), MINOR(__entry->dev),
810 (unsigned long long)__entry->fileid,
811 __entry->fhandle
812 )
813);
814
815#define DEFINE_NFS4_INODE_EVENT(name) \
816 DEFINE_EVENT(nfs4_inode_event, name, \
817 TP_PROTO( \
818 const struct inode *inode, \
819 int error \
820 ), \
821 TP_ARGS(inode, error))
822
823DEFINE_NFS4_INODE_EVENT(nfs4_setattr);
824DEFINE_NFS4_INODE_EVENT(nfs4_access);
825DEFINE_NFS4_INODE_EVENT(nfs4_readlink);
826DEFINE_NFS4_INODE_EVENT(nfs4_readdir);
827DEFINE_NFS4_INODE_EVENT(nfs4_get_acl);
828DEFINE_NFS4_INODE_EVENT(nfs4_set_acl);
829#ifdef CONFIG_NFS_V4_SECURITY_LABEL
830DEFINE_NFS4_INODE_EVENT(nfs4_get_security_label);
831DEFINE_NFS4_INODE_EVENT(nfs4_set_security_label);
832#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
833DEFINE_NFS4_INODE_EVENT(nfs4_recall_delegation);
834DEFINE_NFS4_INODE_EVENT(nfs4_delegreturn);
835
836DECLARE_EVENT_CLASS(nfs4_getattr_event,
837 TP_PROTO(
838 const struct nfs_server *server,
839 const struct nfs_fh *fhandle,
840 const struct nfs_fattr *fattr,
841 int error
842 ),
843
844 TP_ARGS(server, fhandle, fattr, error),
845
846 TP_STRUCT__entry(
847 __field(dev_t, dev)
848 __field(u32, fhandle)
849 __field(u64, fileid)
850 __field(unsigned int, valid)
851 __field(int, error)
852 ),
853
854 TP_fast_assign(
855 __entry->dev = server->s_dev;
856 __entry->valid = fattr->valid;
857 __entry->fhandle = nfs_fhandle_hash(fhandle);
858 __entry->fileid = (fattr->valid & NFS_ATTR_FATTR_FILEID) ? fattr->fileid : 0;
859 __entry->error = error;
860 ),
861
862 TP_printk(
863 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
864 "valid=%s",
865 __entry->error,
866 show_nfsv4_errors(__entry->error),
867 MAJOR(__entry->dev), MINOR(__entry->dev),
868 (unsigned long long)__entry->fileid,
869 __entry->fhandle,
870 show_nfs_fattr_flags(__entry->valid)
871 )
872);
873
874#define DEFINE_NFS4_GETATTR_EVENT(name) \
875 DEFINE_EVENT(nfs4_getattr_event, name, \
876 TP_PROTO( \
877 const struct nfs_server *server, \
878 const struct nfs_fh *fhandle, \
879 const struct nfs_fattr *fattr, \
880 int error \
881 ), \
882 TP_ARGS(server, fhandle, fattr, error))
883DEFINE_NFS4_GETATTR_EVENT(nfs4_getattr);
884DEFINE_NFS4_GETATTR_EVENT(nfs4_lookup_root);
885DEFINE_NFS4_GETATTR_EVENT(nfs4_fsinfo);
886
887DECLARE_EVENT_CLASS(nfs4_idmap_event,
888 TP_PROTO(
889 const char *name,
890 int len,
891 u32 id,
892 int error
893 ),
894
895 TP_ARGS(name, len, id, error),
896
897 TP_STRUCT__entry(
898 __field(int, error)
899 __field(u32, id)
900 __dynamic_array(char, name, len > 0 ? len + 1 : 1)
901 ),
902
903 TP_fast_assign(
904 if (len < 0)
905 len = 0;
906 __entry->error = error < 0 ? error : 0;
907 __entry->id = id;
908 memcpy(__get_dynamic_array(name), name, len);
909 ((char *)__get_dynamic_array(name))[len] = 0;
910 ),
911
912 TP_printk(
913 "error=%d id=%u name=%s",
914 __entry->error,
915 __entry->id,
916 __get_str(name)
917 )
918);
919#define DEFINE_NFS4_IDMAP_EVENT(name) \
920 DEFINE_EVENT(nfs4_idmap_event, name, \
921 TP_PROTO( \
922 const char *name, \
923 int len, \
924 u32 id, \
925 int error \
926 ), \
927 TP_ARGS(name, len, id, error))
928DEFINE_NFS4_IDMAP_EVENT(nfs4_map_name_to_uid);
929DEFINE_NFS4_IDMAP_EVENT(nfs4_map_group_to_gid);
930DEFINE_NFS4_IDMAP_EVENT(nfs4_map_uid_to_name);
931DEFINE_NFS4_IDMAP_EVENT(nfs4_map_gid_to_group);
932
933DECLARE_EVENT_CLASS(nfs4_read_event,
934 TP_PROTO(
935 const struct nfs_read_data *data,
936 int error
937 ),
938
939 TP_ARGS(data, error),
940
941 TP_STRUCT__entry(
942 __field(dev_t, dev)
943 __field(u32, fhandle)
944 __field(u64, fileid)
945 __field(loff_t, offset)
946 __field(size_t, count)
947 __field(int, error)
948 ),
949
950 TP_fast_assign(
951 const struct inode *inode = data->header->inode;
952 __entry->dev = inode->i_sb->s_dev;
953 __entry->fileid = NFS_FILEID(inode);
954 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
955 __entry->offset = data->args.offset;
956 __entry->count = data->args.count;
957 __entry->error = error;
958 ),
959
960 TP_printk(
961 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
962 "offset=%lld count=%zu",
963 __entry->error,
964 show_nfsv4_errors(__entry->error),
965 MAJOR(__entry->dev), MINOR(__entry->dev),
966 (unsigned long long)__entry->fileid,
967 __entry->fhandle,
968 (long long)__entry->offset,
969 __entry->count
970 )
971);
972#define DEFINE_NFS4_READ_EVENT(name) \
973 DEFINE_EVENT(nfs4_read_event, name, \
974 TP_PROTO( \
975 const struct nfs_read_data *data, \
976 int error \
977 ), \
978 TP_ARGS(data, error))
979DEFINE_NFS4_READ_EVENT(nfs4_read);
980#ifdef CONFIG_NFS_V4_1
981DEFINE_NFS4_READ_EVENT(nfs4_pnfs_read);
982#endif /* CONFIG_NFS_V4_1 */
983
984DECLARE_EVENT_CLASS(nfs4_write_event,
985 TP_PROTO(
986 const struct nfs_write_data *data,
987 int error
988 ),
989
990 TP_ARGS(data, error),
991
992 TP_STRUCT__entry(
993 __field(dev_t, dev)
994 __field(u32, fhandle)
995 __field(u64, fileid)
996 __field(loff_t, offset)
997 __field(size_t, count)
998 __field(int, error)
999 ),
1000
1001 TP_fast_assign(
1002 const struct inode *inode = data->header->inode;
1003 __entry->dev = inode->i_sb->s_dev;
1004 __entry->fileid = NFS_FILEID(inode);
1005 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
1006 __entry->offset = data->args.offset;
1007 __entry->count = data->args.count;
1008 __entry->error = error;
1009 ),
1010
1011 TP_printk(
1012 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
1013 "offset=%lld count=%zu",
1014 __entry->error,
1015 show_nfsv4_errors(__entry->error),
1016 MAJOR(__entry->dev), MINOR(__entry->dev),
1017 (unsigned long long)__entry->fileid,
1018 __entry->fhandle,
1019 (long long)__entry->offset,
1020 __entry->count
1021 )
1022);
1023
1024#define DEFINE_NFS4_WRITE_EVENT(name) \
1025 DEFINE_EVENT(nfs4_write_event, name, \
1026 TP_PROTO( \
1027 const struct nfs_write_data *data, \
1028 int error \
1029 ), \
1030 TP_ARGS(data, error))
1031DEFINE_NFS4_WRITE_EVENT(nfs4_write);
1032#ifdef CONFIG_NFS_V4_1
1033DEFINE_NFS4_WRITE_EVENT(nfs4_pnfs_write);
1034#endif /* CONFIG_NFS_V4_1 */
1035
1036DECLARE_EVENT_CLASS(nfs4_commit_event,
1037 TP_PROTO(
1038 const struct nfs_commit_data *data,
1039 int error
1040 ),
1041
1042 TP_ARGS(data, error),
1043
1044 TP_STRUCT__entry(
1045 __field(dev_t, dev)
1046 __field(u32, fhandle)
1047 __field(u64, fileid)
1048 __field(loff_t, offset)
1049 __field(size_t, count)
1050 __field(int, error)
1051 ),
1052
1053 TP_fast_assign(
1054 const struct inode *inode = data->inode;
1055 __entry->dev = inode->i_sb->s_dev;
1056 __entry->fileid = NFS_FILEID(inode);
1057 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
1058 __entry->offset = data->args.offset;
1059 __entry->count = data->args.count;
1060 __entry->error = error;
1061 ),
1062
1063 TP_printk(
1064 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
1065 "offset=%lld count=%zu",
1066 __entry->error,
1067 show_nfsv4_errors(__entry->error),
1068 MAJOR(__entry->dev), MINOR(__entry->dev),
1069 (unsigned long long)__entry->fileid,
1070 __entry->fhandle,
1071 (long long)__entry->offset,
1072 __entry->count
1073 )
1074);
1075#define DEFINE_NFS4_COMMIT_EVENT(name) \
1076 DEFINE_EVENT(nfs4_commit_event, name, \
1077 TP_PROTO( \
1078 const struct nfs_commit_data *data, \
1079 int error \
1080 ), \
1081 TP_ARGS(data, error))
1082DEFINE_NFS4_COMMIT_EVENT(nfs4_commit);
1083#ifdef CONFIG_NFS_V4_1
1084DEFINE_NFS4_COMMIT_EVENT(nfs4_pnfs_commit_ds);
1085
1086#define show_pnfs_iomode(iomode) \
1087 __print_symbolic(iomode, \
1088 { IOMODE_READ, "READ" }, \
1089 { IOMODE_RW, "RW" }, \
1090 { IOMODE_ANY, "ANY" })
1091
1092TRACE_EVENT(nfs4_layoutget,
1093 TP_PROTO(
1094 const struct nfs_open_context *ctx,
1095 const struct pnfs_layout_range *args,
1096 const struct pnfs_layout_range *res,
1097 int error
1098 ),
1099
1100 TP_ARGS(ctx, args, res, error),
1101
1102 TP_STRUCT__entry(
1103 __field(dev_t, dev)
1104 __field(u32, fhandle)
1105 __field(u64, fileid)
1106 __field(u32, iomode)
1107 __field(u64, offset)
1108 __field(u64, count)
1109 __field(int, error)
1110 ),
1111
1112 TP_fast_assign(
1113 const struct inode *inode = ctx->dentry->d_inode;
1114 __entry->dev = inode->i_sb->s_dev;
1115 __entry->fileid = NFS_FILEID(inode);
1116 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
1117 __entry->iomode = args->iomode;
1118 __entry->offset = args->offset;
1119 __entry->count = args->length;
1120 __entry->error = error;
1121 ),
1122
1123 TP_printk(
1124 "error=%d (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
1125 "iomode=%s offset=%llu count=%llu",
1126 __entry->error,
1127 show_nfsv4_errors(__entry->error),
1128 MAJOR(__entry->dev), MINOR(__entry->dev),
1129 (unsigned long long)__entry->fileid,
1130 __entry->fhandle,
1131 show_pnfs_iomode(__entry->iomode),
1132 (unsigned long long)__entry->offset,
1133 (unsigned long long)__entry->count
1134 )
1135);
1136
1137DEFINE_NFS4_INODE_EVENT(nfs4_layoutcommit);
1138DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn);
1139
1140#endif /* CONFIG_NFS_V4_1 */
1141
1142#endif /* _TRACE_NFS4_H */
1143
1144#undef TRACE_INCLUDE_PATH
1145#define TRACE_INCLUDE_PATH .
1146#define TRACE_INCLUDE_FILE nfs4trace
1147/* This part must be outside protection */
1148#include <trace/define_trace.h>
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3850b018815f..fbdad9e1719f 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -294,7 +294,9 @@ static int nfs4_stat_to_errno(int);
294 XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \ 294 XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
295 1 /* flags */ + \ 295 1 /* flags */ + \
296 1 /* spa_how */ + \ 296 1 /* spa_how */ + \
297 0 /* SP4_NONE (for now) */ + \ 297 /* max is SP4_MACH_CRED (for now) */ + \
298 1 + NFS4_OP_MAP_NUM_WORDS + \
299 1 + NFS4_OP_MAP_NUM_WORDS + \
298 1 /* implementation id array of size 1 */ + \ 300 1 /* implementation id array of size 1 */ + \
299 1 /* nii_domain */ + \ 301 1 /* nii_domain */ + \
300 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 302 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
@@ -306,7 +308,9 @@ static int nfs4_stat_to_errno(int);
306 1 /* eir_sequenceid */ + \ 308 1 /* eir_sequenceid */ + \
307 1 /* eir_flags */ + \ 309 1 /* eir_flags */ + \
308 1 /* spr_how */ + \ 310 1 /* spr_how */ + \
309 0 /* SP4_NONE (for now) */ + \ 311 /* max is SP4_MACH_CRED (for now) */ + \
312 1 + NFS4_OP_MAP_NUM_WORDS + \
313 1 + NFS4_OP_MAP_NUM_WORDS + \
310 2 /* eir_server_owner.so_minor_id */ + \ 314 2 /* eir_server_owner.so_minor_id */ + \
311 /* eir_server_owner.so_major_id<> */ \ 315 /* eir_server_owner.so_major_id<> */ \
312 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \ 316 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
@@ -997,12 +1001,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
997 int owner_namelen = 0; 1001 int owner_namelen = 0;
998 int owner_grouplen = 0; 1002 int owner_grouplen = 0;
999 __be32 *p; 1003 __be32 *p;
1000 __be32 *q; 1004 unsigned i;
1001 int len; 1005 uint32_t len = 0;
1002 uint32_t bmval_len = 2; 1006 uint32_t bmval_len;
1003 uint32_t bmval0 = 0; 1007 uint32_t bmval[3] = { 0 };
1004 uint32_t bmval1 = 0;
1005 uint32_t bmval2 = 0;
1006 1008
1007 /* 1009 /*
1008 * We reserve enough space to write the entire attribute buffer at once. 1010 * We reserve enough space to write the entire attribute buffer at once.
@@ -1011,13 +1013,14 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1011 * = 40 bytes, plus any contribution from variable-length fields 1013 * = 40 bytes, plus any contribution from variable-length fields
1012 * such as owner/group. 1014 * such as owner/group.
1013 */ 1015 */
1014 len = 8; 1016 if (iap->ia_valid & ATTR_SIZE) {
1015 1017 bmval[0] |= FATTR4_WORD0_SIZE;
1016 /* Sigh */
1017 if (iap->ia_valid & ATTR_SIZE)
1018 len += 8; 1018 len += 8;
1019 if (iap->ia_valid & ATTR_MODE) 1019 }
1020 if (iap->ia_valid & ATTR_MODE) {
1021 bmval[1] |= FATTR4_WORD1_MODE;
1020 len += 4; 1022 len += 4;
1023 }
1021 if (iap->ia_valid & ATTR_UID) { 1024 if (iap->ia_valid & ATTR_UID) {
1022 owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); 1025 owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ);
1023 if (owner_namelen < 0) { 1026 if (owner_namelen < 0) {
@@ -1028,6 +1031,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1028 owner_namelen = sizeof("nobody") - 1; 1031 owner_namelen = sizeof("nobody") - 1;
1029 /* goto out; */ 1032 /* goto out; */
1030 } 1033 }
1034 bmval[1] |= FATTR4_WORD1_OWNER;
1031 len += 4 + (XDR_QUADLEN(owner_namelen) << 2); 1035 len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
1032 } 1036 }
1033 if (iap->ia_valid & ATTR_GID) { 1037 if (iap->ia_valid & ATTR_GID) {
@@ -1039,92 +1043,73 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1039 owner_grouplen = sizeof("nobody") - 1; 1043 owner_grouplen = sizeof("nobody") - 1;
1040 /* goto out; */ 1044 /* goto out; */
1041 } 1045 }
1046 bmval[1] |= FATTR4_WORD1_OWNER_GROUP;
1042 len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); 1047 len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
1043 } 1048 }
1044 if (iap->ia_valid & ATTR_ATIME_SET) 1049 if (iap->ia_valid & ATTR_ATIME_SET) {
1050 bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
1045 len += 16; 1051 len += 16;
1046 else if (iap->ia_valid & ATTR_ATIME) 1052 } else if (iap->ia_valid & ATTR_ATIME) {
1053 bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
1047 len += 4; 1054 len += 4;
1048 if (iap->ia_valid & ATTR_MTIME_SET) 1055 }
1056 if (iap->ia_valid & ATTR_MTIME_SET) {
1057 bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
1049 len += 16; 1058 len += 16;
1050 else if (iap->ia_valid & ATTR_MTIME) 1059 } else if (iap->ia_valid & ATTR_MTIME) {
1060 bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
1051 len += 4; 1061 len += 4;
1062 }
1052 if (label) { 1063 if (label) {
1053 len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); 1064 len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
1054 bmval_len = 3; 1065 bmval[2] |= FATTR4_WORD2_SECURITY_LABEL;
1055 } 1066 }
1056 1067
1057 len += bmval_len << 2; 1068 if (bmval[2] != 0)
1058 p = reserve_space(xdr, len); 1069 bmval_len = 3;
1070 else if (bmval[1] != 0)
1071 bmval_len = 2;
1072 else
1073 bmval_len = 1;
1074
1075 p = reserve_space(xdr, 4 + (bmval_len << 2) + 4 + len);
1059 1076
1060 /*
1061 * We write the bitmap length now, but leave the bitmap and the attribute
1062 * buffer length to be backfilled at the end of this routine.
1063 */
1064 *p++ = cpu_to_be32(bmval_len); 1077 *p++ = cpu_to_be32(bmval_len);
1065 q = p; 1078 for (i = 0; i < bmval_len; i++)
1066 /* Skip bitmap entries + attrlen */ 1079 *p++ = cpu_to_be32(bmval[i]);
1067 p += bmval_len + 1; 1080 *p++ = cpu_to_be32(len);
1068 1081
1069 if (iap->ia_valid & ATTR_SIZE) { 1082 if (bmval[0] & FATTR4_WORD0_SIZE)
1070 bmval0 |= FATTR4_WORD0_SIZE;
1071 p = xdr_encode_hyper(p, iap->ia_size); 1083 p = xdr_encode_hyper(p, iap->ia_size);
1072 } 1084 if (bmval[1] & FATTR4_WORD1_MODE)
1073 if (iap->ia_valid & ATTR_MODE) {
1074 bmval1 |= FATTR4_WORD1_MODE;
1075 *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); 1085 *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
1076 } 1086 if (bmval[1] & FATTR4_WORD1_OWNER)
1077 if (iap->ia_valid & ATTR_UID) {
1078 bmval1 |= FATTR4_WORD1_OWNER;
1079 p = xdr_encode_opaque(p, owner_name, owner_namelen); 1087 p = xdr_encode_opaque(p, owner_name, owner_namelen);
1080 } 1088 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP)
1081 if (iap->ia_valid & ATTR_GID) {
1082 bmval1 |= FATTR4_WORD1_OWNER_GROUP;
1083 p = xdr_encode_opaque(p, owner_group, owner_grouplen); 1089 p = xdr_encode_opaque(p, owner_group, owner_grouplen);
1090 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
1091 if (iap->ia_valid & ATTR_ATIME_SET) {
1092 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1093 p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec);
1094 *p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
1095 } else
1096 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1084 } 1097 }
1085 if (iap->ia_valid & ATTR_ATIME_SET) { 1098 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
1086 bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; 1099 if (iap->ia_valid & ATTR_MTIME_SET) {
1087 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); 1100 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1088 p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec); 1101 p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec);
1089 *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); 1102 *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
1090 } 1103 } else
1091 else if (iap->ia_valid & ATTR_ATIME) { 1104 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1092 bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
1093 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1094 }
1095 if (iap->ia_valid & ATTR_MTIME_SET) {
1096 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
1097 *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
1098 p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec);
1099 *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
1100 }
1101 else if (iap->ia_valid & ATTR_MTIME) {
1102 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
1103 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1104 } 1105 }
1105 if (label) { 1106 if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
1106 bmval2 |= FATTR4_WORD2_SECURITY_LABEL;
1107 *p++ = cpu_to_be32(label->lfs); 1107 *p++ = cpu_to_be32(label->lfs);
1108 *p++ = cpu_to_be32(label->pi); 1108 *p++ = cpu_to_be32(label->pi);
1109 *p++ = cpu_to_be32(label->len); 1109 *p++ = cpu_to_be32(label->len);
1110 p = xdr_encode_opaque_fixed(p, label->label, label->len); 1110 p = xdr_encode_opaque_fixed(p, label->label, label->len);
1111 } 1111 }
1112 1112
1113 /*
1114 * Now we backfill the bitmap and the attribute buffer length.
1115 */
1116 if (len != ((char *)p - (char *)q) + 4) {
1117 printk(KERN_ERR "NFS: Attr length error, %u != %Zu\n",
1118 len, ((char *)p - (char *)q) + 4);
1119 BUG();
1120 }
1121 *q++ = htonl(bmval0);
1122 *q++ = htonl(bmval1);
1123 if (bmval_len == 3)
1124 *q++ = htonl(bmval2);
1125 len = (char *)p - (char *)(q + 1);
1126 *q = htonl(len);
1127
1128/* out: */ 1113/* out: */
1129} 1114}
1130 1115
@@ -1745,6 +1730,14 @@ static void encode_bind_conn_to_session(struct xdr_stream *xdr,
1745 *p = 0; /* use_conn_in_rdma_mode = False */ 1730 *p = 0; /* use_conn_in_rdma_mode = False */
1746} 1731}
1747 1732
1733static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
1734{
1735 unsigned int i;
1736 encode_uint32(xdr, NFS4_OP_MAP_NUM_WORDS);
1737 for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++)
1738 encode_uint32(xdr, op_map->u.words[i]);
1739}
1740
1748static void encode_exchange_id(struct xdr_stream *xdr, 1741static void encode_exchange_id(struct xdr_stream *xdr,
1749 struct nfs41_exchange_id_args *args, 1742 struct nfs41_exchange_id_args *args,
1750 struct compound_hdr *hdr) 1743 struct compound_hdr *hdr)
@@ -1758,9 +1751,20 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1758 1751
1759 encode_string(xdr, args->id_len, args->id); 1752 encode_string(xdr, args->id_len, args->id);
1760 1753
1761 p = reserve_space(xdr, 12); 1754 encode_uint32(xdr, args->flags);
1762 *p++ = cpu_to_be32(args->flags); 1755 encode_uint32(xdr, args->state_protect.how);
1763 *p++ = cpu_to_be32(0); /* zero length state_protect4_a */ 1756
1757 switch (args->state_protect.how) {
1758 case SP4_NONE:
1759 break;
1760 case SP4_MACH_CRED:
1761 encode_op_map(xdr, &args->state_protect.enforce);
1762 encode_op_map(xdr, &args->state_protect.allow);
1763 break;
1764 default:
1765 WARN_ON_ONCE(1);
1766 break;
1767 }
1764 1768
1765 if (send_implementation_id && 1769 if (send_implementation_id &&
1766 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 && 1770 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
@@ -1771,7 +1775,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1771 utsname()->version, utsname()->machine); 1775 utsname()->version, utsname()->machine);
1772 1776
1773 if (len > 0) { 1777 if (len > 0) {
1774 *p = cpu_to_be32(1); /* implementation id array length=1 */ 1778 encode_uint32(xdr, 1); /* implementation id array length=1 */
1775 1779
1776 encode_string(xdr, 1780 encode_string(xdr,
1777 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1, 1781 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1,
@@ -1782,7 +1786,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1782 p = xdr_encode_hyper(p, 0); 1786 p = xdr_encode_hyper(p, 0);
1783 *p = cpu_to_be32(0); 1787 *p = cpu_to_be32(0);
1784 } else 1788 } else
1785 *p = cpu_to_be32(0); /* implementation id array length=0 */ 1789 encode_uint32(xdr, 0); /* implementation id array length=0 */
1786} 1790}
1787 1791
1788static void encode_create_session(struct xdr_stream *xdr, 1792static void encode_create_session(struct xdr_stream *xdr,
@@ -1835,7 +1839,7 @@ static void encode_create_session(struct xdr_stream *xdr,
1835 *p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */ 1839 *p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */
1836 1840
1837 /* authsys_parms rfc1831 */ 1841 /* authsys_parms rfc1831 */
1838 *p++ = (__be32)nn->boot_time.tv_nsec; /* stamp */ 1842 *p++ = cpu_to_be32(nn->boot_time.tv_nsec); /* stamp */
1839 p = xdr_encode_opaque(p, machine_name, len); 1843 p = xdr_encode_opaque(p, machine_name, len);
1840 *p++ = cpu_to_be32(0); /* UID */ 1844 *p++ = cpu_to_be32(0); /* UID */
1841 *p++ = cpu_to_be32(0); /* GID */ 1845 *p++ = cpu_to_be32(0); /* GID */
@@ -1877,11 +1881,10 @@ static void encode_sequence(struct xdr_stream *xdr,
1877 struct nfs4_slot *slot = args->sa_slot; 1881 struct nfs4_slot *slot = args->sa_slot;
1878 __be32 *p; 1882 __be32 *p;
1879 1883
1880 if (slot == NULL)
1881 return;
1882
1883 tp = slot->table; 1884 tp = slot->table;
1884 session = tp->session; 1885 session = tp->session;
1886 if (!session)
1887 return;
1885 1888
1886 encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr); 1889 encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr);
1887 1890
@@ -2062,9 +2065,9 @@ static void encode_free_stateid(struct xdr_stream *xdr,
2062static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args) 2065static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
2063{ 2066{
2064#if defined(CONFIG_NFS_V4_1) 2067#if defined(CONFIG_NFS_V4_1)
2065 2068 struct nfs4_session *session = args->sa_slot->table->session;
2066 if (args->sa_slot) 2069 if (session)
2067 return args->sa_slot->table->session->clp->cl_mvops->minor_version; 2070 return session->clp->cl_mvops->minor_version;
2068#endif /* CONFIG_NFS_V4_1 */ 2071#endif /* CONFIG_NFS_V4_1 */
2069 return 0; 2072 return 0;
2070} 2073}
@@ -4649,7 +4652,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4649static int decode_first_pnfs_layout_type(struct xdr_stream *xdr, 4652static int decode_first_pnfs_layout_type(struct xdr_stream *xdr,
4650 uint32_t *layouttype) 4653 uint32_t *layouttype)
4651{ 4654{
4652 uint32_t *p; 4655 __be32 *p;
4653 int num; 4656 int num;
4654 4657
4655 p = xdr_inline_decode(xdr, 4); 4658 p = xdr_inline_decode(xdr, 4);
@@ -5394,6 +5397,23 @@ static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_re
5394 return decode_secinfo_common(xdr, res); 5397 return decode_secinfo_common(xdr, res);
5395} 5398}
5396 5399
5400static int decode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
5401{
5402 __be32 *p;
5403 uint32_t bitmap_words;
5404 unsigned int i;
5405
5406 p = xdr_inline_decode(xdr, 4);
5407 bitmap_words = be32_to_cpup(p++);
5408 if (bitmap_words > NFS4_OP_MAP_NUM_WORDS)
5409 return -EIO;
5410 p = xdr_inline_decode(xdr, 4 * bitmap_words);
5411 for (i = 0; i < bitmap_words; i++)
5412 op_map->u.words[i] = be32_to_cpup(p++);
5413
5414 return 0;
5415}
5416
5397static int decode_exchange_id(struct xdr_stream *xdr, 5417static int decode_exchange_id(struct xdr_stream *xdr,
5398 struct nfs41_exchange_id_res *res) 5418 struct nfs41_exchange_id_res *res)
5399{ 5419{
@@ -5417,10 +5437,22 @@ static int decode_exchange_id(struct xdr_stream *xdr,
5417 res->seqid = be32_to_cpup(p++); 5437 res->seqid = be32_to_cpup(p++);
5418 res->flags = be32_to_cpup(p++); 5438 res->flags = be32_to_cpup(p++);
5419 5439
5420 /* We ask for SP4_NONE */ 5440 res->state_protect.how = be32_to_cpup(p);
5421 dummy = be32_to_cpup(p); 5441 switch (res->state_protect.how) {
5422 if (dummy != SP4_NONE) 5442 case SP4_NONE:
5443 break;
5444 case SP4_MACH_CRED:
5445 status = decode_op_map(xdr, &res->state_protect.enforce);
5446 if (status)
5447 return status;
5448 status = decode_op_map(xdr, &res->state_protect.allow);
5449 if (status)
5450 return status;
5451 break;
5452 default:
5453 WARN_ON_ONCE(1);
5423 return -EIO; 5454 return -EIO;
5455 }
5424 5456
5425 /* server_owner4.so_minor_id */ 5457 /* server_owner4.so_minor_id */
5426 p = xdr_inline_decode(xdr, 8); 5458 p = xdr_inline_decode(xdr, 8);
@@ -5614,6 +5646,8 @@ static int decode_sequence(struct xdr_stream *xdr,
5614 5646
5615 if (res->sr_slot == NULL) 5647 if (res->sr_slot == NULL)
5616 return 0; 5648 return 0;
5649 if (!res->sr_slot->table->session)
5650 return 0;
5617 5651
5618 status = decode_op_hdr(xdr, OP_SEQUENCE); 5652 status = decode_op_hdr(xdr, OP_SEQUENCE);
5619 if (!status) 5653 if (!status)
diff --git a/fs/nfs/nfstrace.c b/fs/nfs/nfstrace.c
new file mode 100644
index 000000000000..4eb0aead69b6
--- /dev/null
+++ b/fs/nfs/nfstrace.c
@@ -0,0 +1,9 @@
1/*
2 * Copyright (c) 2013 Trond Myklebust <Trond.Myklebust@netapp.com>
3 */
4#include <linux/nfs_fs.h>
5#include <linux/namei.h>
6#include "internal.h"
7
8#define CREATE_TRACE_POINTS
9#include "nfstrace.h"
diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h
new file mode 100644
index 000000000000..89fe741e58b1
--- /dev/null
+++ b/fs/nfs/nfstrace.h
@@ -0,0 +1,729 @@
1/*
2 * Copyright (c) 2013 Trond Myklebust <Trond.Myklebust@netapp.com>
3 */
4#undef TRACE_SYSTEM
5#define TRACE_SYSTEM nfs
6
7#if !defined(_TRACE_NFS_H) || defined(TRACE_HEADER_MULTI_READ)
8#define _TRACE_NFS_H
9
10#include <linux/tracepoint.h>
11
12#define nfs_show_file_type(ftype) \
13 __print_symbolic(ftype, \
14 { DT_UNKNOWN, "UNKNOWN" }, \
15 { DT_FIFO, "FIFO" }, \
16 { DT_CHR, "CHR" }, \
17 { DT_DIR, "DIR" }, \
18 { DT_BLK, "BLK" }, \
19 { DT_REG, "REG" }, \
20 { DT_LNK, "LNK" }, \
21 { DT_SOCK, "SOCK" }, \
22 { DT_WHT, "WHT" })
23
24#define nfs_show_cache_validity(v) \
25 __print_flags(v, "|", \
26 { NFS_INO_INVALID_ATTR, "INVALID_ATTR" }, \
27 { NFS_INO_INVALID_DATA, "INVALID_DATA" }, \
28 { NFS_INO_INVALID_ATIME, "INVALID_ATIME" }, \
29 { NFS_INO_INVALID_ACCESS, "INVALID_ACCESS" }, \
30 { NFS_INO_INVALID_ACL, "INVALID_ACL" }, \
31 { NFS_INO_REVAL_PAGECACHE, "REVAL_PAGECACHE" }, \
32 { NFS_INO_REVAL_FORCED, "REVAL_FORCED" }, \
33 { NFS_INO_INVALID_LABEL, "INVALID_LABEL" })
34
35#define nfs_show_nfsi_flags(v) \
36 __print_flags(v, "|", \
37 { 1 << NFS_INO_ADVISE_RDPLUS, "ADVISE_RDPLUS" }, \
38 { 1 << NFS_INO_STALE, "STALE" }, \
39 { 1 << NFS_INO_FLUSHING, "FLUSHING" }, \
40 { 1 << NFS_INO_FSCACHE, "FSCACHE" }, \
41 { 1 << NFS_INO_COMMIT, "COMMIT" }, \
42 { 1 << NFS_INO_LAYOUTCOMMIT, "NEED_LAYOUTCOMMIT" }, \
43 { 1 << NFS_INO_LAYOUTCOMMITTING, "LAYOUTCOMMIT" })
44
45DECLARE_EVENT_CLASS(nfs_inode_event,
46 TP_PROTO(
47 const struct inode *inode
48 ),
49
50 TP_ARGS(inode),
51
52 TP_STRUCT__entry(
53 __field(dev_t, dev)
54 __field(u32, fhandle)
55 __field(u64, fileid)
56 __field(u64, version)
57 ),
58
59 TP_fast_assign(
60 const struct nfs_inode *nfsi = NFS_I(inode);
61 __entry->dev = inode->i_sb->s_dev;
62 __entry->fileid = nfsi->fileid;
63 __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
64 __entry->version = inode->i_version;
65 ),
66
67 TP_printk(
68 "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu ",
69 MAJOR(__entry->dev), MINOR(__entry->dev),
70 (unsigned long long)__entry->fileid,
71 __entry->fhandle,
72 (unsigned long long)__entry->version
73 )
74);
75
76DECLARE_EVENT_CLASS(nfs_inode_event_done,
77 TP_PROTO(
78 const struct inode *inode,
79 int error
80 ),
81
82 TP_ARGS(inode, error),
83
84 TP_STRUCT__entry(
85 __field(int, error)
86 __field(dev_t, dev)
87 __field(u32, fhandle)
88 __field(unsigned char, type)
89 __field(u64, fileid)
90 __field(u64, version)
91 __field(loff_t, size)
92 __field(unsigned long, nfsi_flags)
93 __field(unsigned long, cache_validity)
94 ),
95
96 TP_fast_assign(
97 const struct nfs_inode *nfsi = NFS_I(inode);
98 __entry->error = error;
99 __entry->dev = inode->i_sb->s_dev;
100 __entry->fileid = nfsi->fileid;
101 __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
102 __entry->type = nfs_umode_to_dtype(inode->i_mode);
103 __entry->version = inode->i_version;
104 __entry->size = i_size_read(inode);
105 __entry->nfsi_flags = nfsi->flags;
106 __entry->cache_validity = nfsi->cache_validity;
107 ),
108
109 TP_printk(
110 "error=%d fileid=%02x:%02x:%llu fhandle=0x%08x "
111 "type=%u (%s) version=%llu size=%lld "
112 "cache_validity=%lu (%s) nfs_flags=%ld (%s)",
113 __entry->error,
114 MAJOR(__entry->dev), MINOR(__entry->dev),
115 (unsigned long long)__entry->fileid,
116 __entry->fhandle,
117 __entry->type,
118 nfs_show_file_type(__entry->type),
119 (unsigned long long)__entry->version,
120 (long long)__entry->size,
121 __entry->cache_validity,
122 nfs_show_cache_validity(__entry->cache_validity),
123 __entry->nfsi_flags,
124 nfs_show_nfsi_flags(__entry->nfsi_flags)
125 )
126);
127
128#define DEFINE_NFS_INODE_EVENT(name) \
129 DEFINE_EVENT(nfs_inode_event, name, \
130 TP_PROTO( \
131 const struct inode *inode \
132 ), \
133 TP_ARGS(inode))
134#define DEFINE_NFS_INODE_EVENT_DONE(name) \
135 DEFINE_EVENT(nfs_inode_event_done, name, \
136 TP_PROTO( \
137 const struct inode *inode, \
138 int error \
139 ), \
140 TP_ARGS(inode, error))
141DEFINE_NFS_INODE_EVENT(nfs_refresh_inode_enter);
142DEFINE_NFS_INODE_EVENT_DONE(nfs_refresh_inode_exit);
143DEFINE_NFS_INODE_EVENT(nfs_revalidate_inode_enter);
144DEFINE_NFS_INODE_EVENT_DONE(nfs_revalidate_inode_exit);
145DEFINE_NFS_INODE_EVENT(nfs_invalidate_mapping_enter);
146DEFINE_NFS_INODE_EVENT_DONE(nfs_invalidate_mapping_exit);
147DEFINE_NFS_INODE_EVENT(nfs_getattr_enter);
148DEFINE_NFS_INODE_EVENT_DONE(nfs_getattr_exit);
149DEFINE_NFS_INODE_EVENT(nfs_setattr_enter);
150DEFINE_NFS_INODE_EVENT_DONE(nfs_setattr_exit);
151DEFINE_NFS_INODE_EVENT(nfs_writeback_page_enter);
152DEFINE_NFS_INODE_EVENT_DONE(nfs_writeback_page_exit);
153DEFINE_NFS_INODE_EVENT(nfs_writeback_inode_enter);
154DEFINE_NFS_INODE_EVENT_DONE(nfs_writeback_inode_exit);
155DEFINE_NFS_INODE_EVENT(nfs_fsync_enter);
156DEFINE_NFS_INODE_EVENT_DONE(nfs_fsync_exit);
157DEFINE_NFS_INODE_EVENT(nfs_access_enter);
158DEFINE_NFS_INODE_EVENT_DONE(nfs_access_exit);
159
160#define show_lookup_flags(flags) \
161 __print_flags((unsigned long)flags, "|", \
162 { LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \
163 { LOOKUP_DIRECTORY, "DIRECTORY" }, \
164 { LOOKUP_OPEN, "OPEN" }, \
165 { LOOKUP_CREATE, "CREATE" }, \
166 { LOOKUP_EXCL, "EXCL" })
167
168DECLARE_EVENT_CLASS(nfs_lookup_event,
169 TP_PROTO(
170 const struct inode *dir,
171 const struct dentry *dentry,
172 unsigned int flags
173 ),
174
175 TP_ARGS(dir, dentry, flags),
176
177 TP_STRUCT__entry(
178 __field(unsigned int, flags)
179 __field(dev_t, dev)
180 __field(u64, dir)
181 __string(name, dentry->d_name.name)
182 ),
183
184 TP_fast_assign(
185 __entry->dev = dir->i_sb->s_dev;
186 __entry->dir = NFS_FILEID(dir);
187 __entry->flags = flags;
188 __assign_str(name, dentry->d_name.name);
189 ),
190
191 TP_printk(
192 "flags=%u (%s) name=%02x:%02x:%llu/%s",
193 __entry->flags,
194 show_lookup_flags(__entry->flags),
195 MAJOR(__entry->dev), MINOR(__entry->dev),
196 (unsigned long long)__entry->dir,
197 __get_str(name)
198 )
199);
200
201#define DEFINE_NFS_LOOKUP_EVENT(name) \
202 DEFINE_EVENT(nfs_lookup_event, name, \
203 TP_PROTO( \
204 const struct inode *dir, \
205 const struct dentry *dentry, \
206 unsigned int flags \
207 ), \
208 TP_ARGS(dir, dentry, flags))
209
210DECLARE_EVENT_CLASS(nfs_lookup_event_done,
211 TP_PROTO(
212 const struct inode *dir,
213 const struct dentry *dentry,
214 unsigned int flags,
215 int error
216 ),
217
218 TP_ARGS(dir, dentry, flags, error),
219
220 TP_STRUCT__entry(
221 __field(int, error)
222 __field(unsigned int, flags)
223 __field(dev_t, dev)
224 __field(u64, dir)
225 __string(name, dentry->d_name.name)
226 ),
227
228 TP_fast_assign(
229 __entry->dev = dir->i_sb->s_dev;
230 __entry->dir = NFS_FILEID(dir);
231 __entry->error = error;
232 __entry->flags = flags;
233 __assign_str(name, dentry->d_name.name);
234 ),
235
236 TP_printk(
237 "error=%d flags=%u (%s) name=%02x:%02x:%llu/%s",
238 __entry->error,
239 __entry->flags,
240 show_lookup_flags(__entry->flags),
241 MAJOR(__entry->dev), MINOR(__entry->dev),
242 (unsigned long long)__entry->dir,
243 __get_str(name)
244 )
245);
246
247#define DEFINE_NFS_LOOKUP_EVENT_DONE(name) \
248 DEFINE_EVENT(nfs_lookup_event_done, name, \
249 TP_PROTO( \
250 const struct inode *dir, \
251 const struct dentry *dentry, \
252 unsigned int flags, \
253 int error \
254 ), \
255 TP_ARGS(dir, dentry, flags, error))
256
257DEFINE_NFS_LOOKUP_EVENT(nfs_lookup_enter);
258DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_exit);
259DEFINE_NFS_LOOKUP_EVENT(nfs_lookup_revalidate_enter);
260DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_revalidate_exit);
261
262#define show_open_flags(flags) \
263 __print_flags((unsigned long)flags, "|", \
264 { O_CREAT, "O_CREAT" }, \
265 { O_EXCL, "O_EXCL" }, \
266 { O_TRUNC, "O_TRUNC" }, \
267 { O_APPEND, "O_APPEND" }, \
268 { O_DSYNC, "O_DSYNC" }, \
269 { O_DIRECT, "O_DIRECT" }, \
270 { O_DIRECTORY, "O_DIRECTORY" })
271
272#define show_fmode_flags(mode) \
273 __print_flags(mode, "|", \
274 { ((__force unsigned long)FMODE_READ), "READ" }, \
275 { ((__force unsigned long)FMODE_WRITE), "WRITE" }, \
276 { ((__force unsigned long)FMODE_EXEC), "EXEC" })
277
278TRACE_EVENT(nfs_atomic_open_enter,
279 TP_PROTO(
280 const struct inode *dir,
281 const struct nfs_open_context *ctx,
282 unsigned int flags
283 ),
284
285 TP_ARGS(dir, ctx, flags),
286
287 TP_STRUCT__entry(
288 __field(unsigned int, flags)
289 __field(unsigned int, fmode)
290 __field(dev_t, dev)
291 __field(u64, dir)
292 __string(name, ctx->dentry->d_name.name)
293 ),
294
295 TP_fast_assign(
296 __entry->dev = dir->i_sb->s_dev;
297 __entry->dir = NFS_FILEID(dir);
298 __entry->flags = flags;
299 __entry->fmode = (__force unsigned int)ctx->mode;
300 __assign_str(name, ctx->dentry->d_name.name);
301 ),
302
303 TP_printk(
304 "flags=%u (%s) fmode=%s name=%02x:%02x:%llu/%s",
305 __entry->flags,
306 show_open_flags(__entry->flags),
307 show_fmode_flags(__entry->fmode),
308 MAJOR(__entry->dev), MINOR(__entry->dev),
309 (unsigned long long)__entry->dir,
310 __get_str(name)
311 )
312);
313
314TRACE_EVENT(nfs_atomic_open_exit,
315 TP_PROTO(
316 const struct inode *dir,
317 const struct nfs_open_context *ctx,
318 unsigned int flags,
319 int error
320 ),
321
322 TP_ARGS(dir, ctx, flags, error),
323
324 TP_STRUCT__entry(
325 __field(int, error)
326 __field(unsigned int, flags)
327 __field(unsigned int, fmode)
328 __field(dev_t, dev)
329 __field(u64, dir)
330 __string(name, ctx->dentry->d_name.name)
331 ),
332
333 TP_fast_assign(
334 __entry->error = error;
335 __entry->dev = dir->i_sb->s_dev;
336 __entry->dir = NFS_FILEID(dir);
337 __entry->flags = flags;
338 __entry->fmode = (__force unsigned int)ctx->mode;
339 __assign_str(name, ctx->dentry->d_name.name);
340 ),
341
342 TP_printk(
343 "error=%d flags=%u (%s) fmode=%s "
344 "name=%02x:%02x:%llu/%s",
345 __entry->error,
346 __entry->flags,
347 show_open_flags(__entry->flags),
348 show_fmode_flags(__entry->fmode),
349 MAJOR(__entry->dev), MINOR(__entry->dev),
350 (unsigned long long)__entry->dir,
351 __get_str(name)
352 )
353);
354
355TRACE_EVENT(nfs_create_enter,
356 TP_PROTO(
357 const struct inode *dir,
358 const struct dentry *dentry,
359 unsigned int flags
360 ),
361
362 TP_ARGS(dir, dentry, flags),
363
364 TP_STRUCT__entry(
365 __field(unsigned int, flags)
366 __field(dev_t, dev)
367 __field(u64, dir)
368 __string(name, dentry->d_name.name)
369 ),
370
371 TP_fast_assign(
372 __entry->dev = dir->i_sb->s_dev;
373 __entry->dir = NFS_FILEID(dir);
374 __entry->flags = flags;
375 __assign_str(name, dentry->d_name.name);
376 ),
377
378 TP_printk(
379 "flags=%u (%s) name=%02x:%02x:%llu/%s",
380 __entry->flags,
381 show_open_flags(__entry->flags),
382 MAJOR(__entry->dev), MINOR(__entry->dev),
383 (unsigned long long)__entry->dir,
384 __get_str(name)
385 )
386);
387
388TRACE_EVENT(nfs_create_exit,
389 TP_PROTO(
390 const struct inode *dir,
391 const struct dentry *dentry,
392 unsigned int flags,
393 int error
394 ),
395
396 TP_ARGS(dir, dentry, flags, error),
397
398 TP_STRUCT__entry(
399 __field(int, error)
400 __field(unsigned int, flags)
401 __field(dev_t, dev)
402 __field(u64, dir)
403 __string(name, dentry->d_name.name)
404 ),
405
406 TP_fast_assign(
407 __entry->error = error;
408 __entry->dev = dir->i_sb->s_dev;
409 __entry->dir = NFS_FILEID(dir);
410 __entry->flags = flags;
411 __assign_str(name, dentry->d_name.name);
412 ),
413
414 TP_printk(
415 "error=%d flags=%u (%s) name=%02x:%02x:%llu/%s",
416 __entry->error,
417 __entry->flags,
418 show_open_flags(__entry->flags),
419 MAJOR(__entry->dev), MINOR(__entry->dev),
420 (unsigned long long)__entry->dir,
421 __get_str(name)
422 )
423);
424
425DECLARE_EVENT_CLASS(nfs_directory_event,
426 TP_PROTO(
427 const struct inode *dir,
428 const struct dentry *dentry
429 ),
430
431 TP_ARGS(dir, dentry),
432
433 TP_STRUCT__entry(
434 __field(dev_t, dev)
435 __field(u64, dir)
436 __string(name, dentry->d_name.name)
437 ),
438
439 TP_fast_assign(
440 __entry->dev = dir->i_sb->s_dev;
441 __entry->dir = NFS_FILEID(dir);
442 __assign_str(name, dentry->d_name.name);
443 ),
444
445 TP_printk(
446 "name=%02x:%02x:%llu/%s",
447 MAJOR(__entry->dev), MINOR(__entry->dev),
448 (unsigned long long)__entry->dir,
449 __get_str(name)
450 )
451);
452
453#define DEFINE_NFS_DIRECTORY_EVENT(name) \
454 DEFINE_EVENT(nfs_directory_event, name, \
455 TP_PROTO( \
456 const struct inode *dir, \
457 const struct dentry *dentry \
458 ), \
459 TP_ARGS(dir, dentry))
460
461DECLARE_EVENT_CLASS(nfs_directory_event_done,
462 TP_PROTO(
463 const struct inode *dir,
464 const struct dentry *dentry,
465 int error
466 ),
467
468 TP_ARGS(dir, dentry, error),
469
470 TP_STRUCT__entry(
471 __field(int, error)
472 __field(dev_t, dev)
473 __field(u64, dir)
474 __string(name, dentry->d_name.name)
475 ),
476
477 TP_fast_assign(
478 __entry->dev = dir->i_sb->s_dev;
479 __entry->dir = NFS_FILEID(dir);
480 __entry->error = error;
481 __assign_str(name, dentry->d_name.name);
482 ),
483
484 TP_printk(
485 "error=%d name=%02x:%02x:%llu/%s",
486 __entry->error,
487 MAJOR(__entry->dev), MINOR(__entry->dev),
488 (unsigned long long)__entry->dir,
489 __get_str(name)
490 )
491);
492
493#define DEFINE_NFS_DIRECTORY_EVENT_DONE(name) \
494 DEFINE_EVENT(nfs_directory_event_done, name, \
495 TP_PROTO( \
496 const struct inode *dir, \
497 const struct dentry *dentry, \
498 int error \
499 ), \
500 TP_ARGS(dir, dentry, error))
501
502DEFINE_NFS_DIRECTORY_EVENT(nfs_mknod_enter);
503DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_mknod_exit);
504DEFINE_NFS_DIRECTORY_EVENT(nfs_mkdir_enter);
505DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_mkdir_exit);
506DEFINE_NFS_DIRECTORY_EVENT(nfs_rmdir_enter);
507DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_rmdir_exit);
508DEFINE_NFS_DIRECTORY_EVENT(nfs_remove_enter);
509DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_remove_exit);
510DEFINE_NFS_DIRECTORY_EVENT(nfs_unlink_enter);
511DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_unlink_exit);
512DEFINE_NFS_DIRECTORY_EVENT(nfs_symlink_enter);
513DEFINE_NFS_DIRECTORY_EVENT_DONE(nfs_symlink_exit);
514
515TRACE_EVENT(nfs_link_enter,
516 TP_PROTO(
517 const struct inode *inode,
518 const struct inode *dir,
519 const struct dentry *dentry
520 ),
521
522 TP_ARGS(inode, dir, dentry),
523
524 TP_STRUCT__entry(
525 __field(dev_t, dev)
526 __field(u64, fileid)
527 __field(u64, dir)
528 __string(name, dentry->d_name.name)
529 ),
530
531 TP_fast_assign(
532 __entry->dev = inode->i_sb->s_dev;
533 __entry->fileid = NFS_FILEID(inode);
534 __entry->dir = NFS_FILEID(dir);
535 __assign_str(name, dentry->d_name.name);
536 ),
537
538 TP_printk(
539 "fileid=%02x:%02x:%llu name=%02x:%02x:%llu/%s",
540 MAJOR(__entry->dev), MINOR(__entry->dev),
541 __entry->fileid,
542 MAJOR(__entry->dev), MINOR(__entry->dev),
543 (unsigned long long)__entry->dir,
544 __get_str(name)
545 )
546);
547
548TRACE_EVENT(nfs_link_exit,
549 TP_PROTO(
550 const struct inode *inode,
551 const struct inode *dir,
552 const struct dentry *dentry,
553 int error
554 ),
555
556 TP_ARGS(inode, dir, dentry, error),
557
558 TP_STRUCT__entry(
559 __field(int, error)
560 __field(dev_t, dev)
561 __field(u64, fileid)
562 __field(u64, dir)
563 __string(name, dentry->d_name.name)
564 ),
565
566 TP_fast_assign(
567 __entry->dev = inode->i_sb->s_dev;
568 __entry->fileid = NFS_FILEID(inode);
569 __entry->dir = NFS_FILEID(dir);
570 __entry->error = error;
571 __assign_str(name, dentry->d_name.name);
572 ),
573
574 TP_printk(
575 "error=%d fileid=%02x:%02x:%llu name=%02x:%02x:%llu/%s",
576 __entry->error,
577 MAJOR(__entry->dev), MINOR(__entry->dev),
578 __entry->fileid,
579 MAJOR(__entry->dev), MINOR(__entry->dev),
580 (unsigned long long)__entry->dir,
581 __get_str(name)
582 )
583);
584
585DECLARE_EVENT_CLASS(nfs_rename_event,
586 TP_PROTO(
587 const struct inode *old_dir,
588 const struct dentry *old_dentry,
589 const struct inode *new_dir,
590 const struct dentry *new_dentry
591 ),
592
593 TP_ARGS(old_dir, old_dentry, new_dir, new_dentry),
594
595 TP_STRUCT__entry(
596 __field(dev_t, dev)
597 __field(u64, old_dir)
598 __field(u64, new_dir)
599 __string(old_name, old_dentry->d_name.name)
600 __string(new_name, new_dentry->d_name.name)
601 ),
602
603 TP_fast_assign(
604 __entry->dev = old_dir->i_sb->s_dev;
605 __entry->old_dir = NFS_FILEID(old_dir);
606 __entry->new_dir = NFS_FILEID(new_dir);
607 __assign_str(old_name, old_dentry->d_name.name);
608 __assign_str(new_name, new_dentry->d_name.name);
609 ),
610
611 TP_printk(
612 "old_name=%02x:%02x:%llu/%s new_name=%02x:%02x:%llu/%s",
613 MAJOR(__entry->dev), MINOR(__entry->dev),
614 (unsigned long long)__entry->old_dir,
615 __get_str(old_name),
616 MAJOR(__entry->dev), MINOR(__entry->dev),
617 (unsigned long long)__entry->new_dir,
618 __get_str(new_name)
619 )
620);
621#define DEFINE_NFS_RENAME_EVENT(name) \
622 DEFINE_EVENT(nfs_rename_event, name, \
623 TP_PROTO( \
624 const struct inode *old_dir, \
625 const struct dentry *old_dentry, \
626 const struct inode *new_dir, \
627 const struct dentry *new_dentry \
628 ), \
629 TP_ARGS(old_dir, old_dentry, new_dir, new_dentry))
630
631DECLARE_EVENT_CLASS(nfs_rename_event_done,
632 TP_PROTO(
633 const struct inode *old_dir,
634 const struct dentry *old_dentry,
635 const struct inode *new_dir,
636 const struct dentry *new_dentry,
637 int error
638 ),
639
640 TP_ARGS(old_dir, old_dentry, new_dir, new_dentry, error),
641
642 TP_STRUCT__entry(
643 __field(dev_t, dev)
644 __field(int, error)
645 __field(u64, old_dir)
646 __string(old_name, old_dentry->d_name.name)
647 __field(u64, new_dir)
648 __string(new_name, new_dentry->d_name.name)
649 ),
650
651 TP_fast_assign(
652 __entry->dev = old_dir->i_sb->s_dev;
653 __entry->old_dir = NFS_FILEID(old_dir);
654 __entry->new_dir = NFS_FILEID(new_dir);
655 __entry->error = error;
656 __assign_str(old_name, old_dentry->d_name.name);
657 __assign_str(new_name, new_dentry->d_name.name);
658 ),
659
660 TP_printk(
661 "error=%d old_name=%02x:%02x:%llu/%s "
662 "new_name=%02x:%02x:%llu/%s",
663 __entry->error,
664 MAJOR(__entry->dev), MINOR(__entry->dev),
665 (unsigned long long)__entry->old_dir,
666 __get_str(old_name),
667 MAJOR(__entry->dev), MINOR(__entry->dev),
668 (unsigned long long)__entry->new_dir,
669 __get_str(new_name)
670 )
671);
672#define DEFINE_NFS_RENAME_EVENT_DONE(name) \
673 DEFINE_EVENT(nfs_rename_event_done, name, \
674 TP_PROTO( \
675 const struct inode *old_dir, \
676 const struct dentry *old_dentry, \
677 const struct inode *new_dir, \
678 const struct dentry *new_dentry, \
679 int error \
680 ), \
681 TP_ARGS(old_dir, old_dentry, new_dir, \
682 new_dentry, error))
683
684DEFINE_NFS_RENAME_EVENT(nfs_rename_enter);
685DEFINE_NFS_RENAME_EVENT_DONE(nfs_rename_exit);
686
687DEFINE_NFS_RENAME_EVENT_DONE(nfs_sillyrename_rename);
688
689TRACE_EVENT(nfs_sillyrename_unlink,
690 TP_PROTO(
691 const struct nfs_unlinkdata *data,
692 int error
693 ),
694
695 TP_ARGS(data, error),
696
697 TP_STRUCT__entry(
698 __field(dev_t, dev)
699 __field(int, error)
700 __field(u64, dir)
701 __dynamic_array(char, name, data->args.name.len + 1)
702 ),
703
704 TP_fast_assign(
705 struct inode *dir = data->dir;
706 size_t len = data->args.name.len;
707 __entry->dev = dir->i_sb->s_dev;
708 __entry->dir = NFS_FILEID(dir);
709 __entry->error = error;
710 memcpy(__get_dynamic_array(name),
711 data->args.name.name, len);
712 ((char *)__get_dynamic_array(name))[len] = 0;
713 ),
714
715 TP_printk(
716 "error=%d name=%02x:%02x:%llu/%s",
717 __entry->error,
718 MAJOR(__entry->dev), MINOR(__entry->dev),
719 (unsigned long long)__entry->dir,
720 __get_str(name)
721 )
722);
723#endif /* _TRACE_NFS_H */
724
725#undef TRACE_INCLUDE_PATH
726#define TRACE_INCLUDE_PATH .
727#define TRACE_INCLUDE_FILE nfstrace
728/* This part must be outside protection */
729#include <trace/define_trace.h>
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 29cfb7ade121..2ffebf2081ce 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -328,6 +328,19 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
328} 328}
329EXPORT_SYMBOL_GPL(nfs_pageio_init); 329EXPORT_SYMBOL_GPL(nfs_pageio_init);
330 330
331static bool nfs_match_open_context(const struct nfs_open_context *ctx1,
332 const struct nfs_open_context *ctx2)
333{
334 return ctx1->cred == ctx2->cred && ctx1->state == ctx2->state;
335}
336
337static bool nfs_match_lock_context(const struct nfs_lock_context *l1,
338 const struct nfs_lock_context *l2)
339{
340 return l1->lockowner.l_owner == l2->lockowner.l_owner
341 && l1->lockowner.l_pid == l2->lockowner.l_pid;
342}
343
331/** 344/**
332 * nfs_can_coalesce_requests - test two requests for compatibility 345 * nfs_can_coalesce_requests - test two requests for compatibility
333 * @prev: pointer to nfs_page 346 * @prev: pointer to nfs_page
@@ -343,13 +356,10 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
343 struct nfs_page *req, 356 struct nfs_page *req,
344 struct nfs_pageio_descriptor *pgio) 357 struct nfs_pageio_descriptor *pgio)
345{ 358{
346 if (req->wb_context->cred != prev->wb_context->cred) 359 if (!nfs_match_open_context(req->wb_context, prev->wb_context))
347 return false;
348 if (req->wb_lock_context->lockowner.l_owner != prev->wb_lock_context->lockowner.l_owner)
349 return false;
350 if (req->wb_lock_context->lockowner.l_pid != prev->wb_lock_context->lockowner.l_pid)
351 return false; 360 return false;
352 if (req->wb_context->state != prev->wb_context->state) 361 if (req->wb_context->dentry->d_inode->i_flock != NULL &&
362 !nfs_match_lock_context(req->wb_lock_context, prev->wb_lock_context))
353 return false; 363 return false;
354 if (req->wb_pgbase != 0) 364 if (req->wb_pgbase != 0)
355 return false; 365 return false;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 3a3a79d6bf15..d75d938d36cb 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -33,6 +33,7 @@
33#include "internal.h" 33#include "internal.h"
34#include "pnfs.h" 34#include "pnfs.h"
35#include "iostat.h" 35#include "iostat.h"
36#include "nfs4trace.h"
36 37
37#define NFSDBG_FACILITY NFSDBG_PNFS 38#define NFSDBG_FACILITY NFSDBG_PNFS
38#define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ) 39#define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ)
@@ -1526,6 +1527,7 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
1526{ 1527{
1527 struct nfs_pgio_header *hdr = data->header; 1528 struct nfs_pgio_header *hdr = data->header;
1528 1529
1530 trace_nfs4_pnfs_write(data, hdr->pnfs_error);
1529 if (!hdr->pnfs_error) { 1531 if (!hdr->pnfs_error) {
1530 pnfs_set_layoutcommit(data); 1532 pnfs_set_layoutcommit(data);
1531 hdr->mds_ops->rpc_call_done(&data->task, data); 1533 hdr->mds_ops->rpc_call_done(&data->task, data);
@@ -1680,6 +1682,7 @@ void pnfs_ld_read_done(struct nfs_read_data *data)
1680{ 1682{
1681 struct nfs_pgio_header *hdr = data->header; 1683 struct nfs_pgio_header *hdr = data->header;
1682 1684
1685 trace_nfs4_pnfs_read(data, hdr->pnfs_error);
1683 if (likely(!hdr->pnfs_error)) { 1686 if (likely(!hdr->pnfs_error)) {
1684 __nfs4_read_done_cb(data); 1687 __nfs4_read_done_cb(data);
1685 hdr->mds_ops->rpc_call_done(&data->task, data); 1688 hdr->mds_ops->rpc_call_done(&data->task, data);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index c041c41f7a52..a8f57c728df5 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -623,9 +623,10 @@ static void nfs_proc_read_setup(struct nfs_read_data *data, struct rpc_message *
623 msg->rpc_proc = &nfs_procedures[NFSPROC_READ]; 623 msg->rpc_proc = &nfs_procedures[NFSPROC_READ];
624} 624}
625 625
626static void nfs_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 626static int nfs_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
627{ 627{
628 rpc_call_start(task); 628 rpc_call_start(task);
629 return 0;
629} 630}
630 631
631static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) 632static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -644,9 +645,10 @@ static void nfs_proc_write_setup(struct nfs_write_data *data, struct rpc_message
644 msg->rpc_proc = &nfs_procedures[NFSPROC_WRITE]; 645 msg->rpc_proc = &nfs_procedures[NFSPROC_WRITE];
645} 646}
646 647
647static void nfs_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 648static int nfs_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
648{ 649{
649 rpc_call_start(task); 650 rpc_call_start(task);
651 return 0;
650} 652}
651 653
652static void nfs_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) 654static void nfs_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 70a26c651f09..31db5c366b81 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -513,9 +513,10 @@ static void nfs_readpage_release_common(void *calldata)
513void nfs_read_prepare(struct rpc_task *task, void *calldata) 513void nfs_read_prepare(struct rpc_task *task, void *calldata)
514{ 514{
515 struct nfs_read_data *data = calldata; 515 struct nfs_read_data *data = calldata;
516 NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data); 516 int err;
517 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags))) 517 err = NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data);
518 rpc_exit(task, -EIO); 518 if (err)
519 rpc_exit(task, err);
519} 520}
520 521
521static const struct rpc_call_ops nfs_read_common_ops = { 522static const struct rpc_call_ops nfs_read_common_ops = {
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f6db66d8f647..5793f24613c8 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -923,7 +923,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
923 data->nfs_server.port = NFS_UNSPEC_PORT; 923 data->nfs_server.port = NFS_UNSPEC_PORT;
924 data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 924 data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
925 data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR; 925 data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR;
926 data->auth_flavor_len = 1; 926 data->auth_flavor_len = 0;
927 data->minorversion = 0; 927 data->minorversion = 0;
928 data->need_mount = true; 928 data->need_mount = true;
929 data->net = current->nsproxy->net_ns; 929 data->net = current->nsproxy->net_ns;
@@ -1018,6 +1018,13 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
1018 } 1018 }
1019} 1019}
1020 1020
1021static void nfs_set_auth_parsed_mount_data(struct nfs_parsed_mount_data *data,
1022 rpc_authflavor_t pseudoflavor)
1023{
1024 data->auth_flavors[0] = pseudoflavor;
1025 data->auth_flavor_len = 1;
1026}
1027
1021/* 1028/*
1022 * Parse the value of the 'sec=' option. 1029 * Parse the value of the 'sec=' option.
1023 */ 1030 */
@@ -1025,49 +1032,50 @@ static int nfs_parse_security_flavors(char *value,
1025 struct nfs_parsed_mount_data *mnt) 1032 struct nfs_parsed_mount_data *mnt)
1026{ 1033{
1027 substring_t args[MAX_OPT_ARGS]; 1034 substring_t args[MAX_OPT_ARGS];
1035 rpc_authflavor_t pseudoflavor;
1028 1036
1029 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); 1037 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value);
1030 1038
1031 switch (match_token(value, nfs_secflavor_tokens, args)) { 1039 switch (match_token(value, nfs_secflavor_tokens, args)) {
1032 case Opt_sec_none: 1040 case Opt_sec_none:
1033 mnt->auth_flavors[0] = RPC_AUTH_NULL; 1041 pseudoflavor = RPC_AUTH_NULL;
1034 break; 1042 break;
1035 case Opt_sec_sys: 1043 case Opt_sec_sys:
1036 mnt->auth_flavors[0] = RPC_AUTH_UNIX; 1044 pseudoflavor = RPC_AUTH_UNIX;
1037 break; 1045 break;
1038 case Opt_sec_krb5: 1046 case Opt_sec_krb5:
1039 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; 1047 pseudoflavor = RPC_AUTH_GSS_KRB5;
1040 break; 1048 break;
1041 case Opt_sec_krb5i: 1049 case Opt_sec_krb5i:
1042 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; 1050 pseudoflavor = RPC_AUTH_GSS_KRB5I;
1043 break; 1051 break;
1044 case Opt_sec_krb5p: 1052 case Opt_sec_krb5p:
1045 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; 1053 pseudoflavor = RPC_AUTH_GSS_KRB5P;
1046 break; 1054 break;
1047 case Opt_sec_lkey: 1055 case Opt_sec_lkey:
1048 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; 1056 pseudoflavor = RPC_AUTH_GSS_LKEY;
1049 break; 1057 break;
1050 case Opt_sec_lkeyi: 1058 case Opt_sec_lkeyi:
1051 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; 1059 pseudoflavor = RPC_AUTH_GSS_LKEYI;
1052 break; 1060 break;
1053 case Opt_sec_lkeyp: 1061 case Opt_sec_lkeyp:
1054 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; 1062 pseudoflavor = RPC_AUTH_GSS_LKEYP;
1055 break; 1063 break;
1056 case Opt_sec_spkm: 1064 case Opt_sec_spkm:
1057 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; 1065 pseudoflavor = RPC_AUTH_GSS_SPKM;
1058 break; 1066 break;
1059 case Opt_sec_spkmi: 1067 case Opt_sec_spkmi:
1060 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; 1068 pseudoflavor = RPC_AUTH_GSS_SPKMI;
1061 break; 1069 break;
1062 case Opt_sec_spkmp: 1070 case Opt_sec_spkmp:
1063 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; 1071 pseudoflavor = RPC_AUTH_GSS_SPKMP;
1064 break; 1072 break;
1065 default: 1073 default:
1066 return 0; 1074 return 0;
1067 } 1075 }
1068 1076
1069 mnt->flags |= NFS_MOUNT_SECFLAVOUR; 1077 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
1070 mnt->auth_flavor_len = 1; 1078 nfs_set_auth_parsed_mount_data(mnt, pseudoflavor);
1071 return 1; 1079 return 1;
1072} 1080}
1073 1081
@@ -1729,7 +1737,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1729 * Was a sec= authflavor specified in the options? First, verify 1737 * Was a sec= authflavor specified in the options? First, verify
1730 * whether the server supports it, and then just try to use it if so. 1738 * whether the server supports it, and then just try to use it if so.
1731 */ 1739 */
1732 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) { 1740 if (args->auth_flavor_len > 0) {
1733 status = nfs_verify_authflavor(args, authlist, authlist_len); 1741 status = nfs_verify_authflavor(args, authlist, authlist_len);
1734 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]); 1742 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
1735 if (status) 1743 if (status)
@@ -1760,7 +1768,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1760 /* Fallthrough */ 1768 /* Fallthrough */
1761 } 1769 }
1762 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor); 1770 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
1763 args->auth_flavors[0] = flavor; 1771 nfs_set_auth_parsed_mount_data(args, flavor);
1764 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1772 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1765 if (!IS_ERR(server)) 1773 if (!IS_ERR(server))
1766 return server; 1774 return server;
@@ -1776,7 +1784,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1776 1784
1777 /* Last chance! Try AUTH_UNIX */ 1785 /* Last chance! Try AUTH_UNIX */
1778 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX); 1786 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
1779 args->auth_flavors[0] = RPC_AUTH_UNIX; 1787 nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
1780 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1788 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1781} 1789}
1782 1790
@@ -1893,6 +1901,7 @@ static int nfs23_validate_mount_data(void *options,
1893{ 1901{
1894 struct nfs_mount_data *data = (struct nfs_mount_data *)options; 1902 struct nfs_mount_data *data = (struct nfs_mount_data *)options;
1895 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 1903 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
1904 int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
1896 1905
1897 if (data == NULL) 1906 if (data == NULL)
1898 goto out_no_data; 1907 goto out_no_data;
@@ -1908,6 +1917,8 @@ static int nfs23_validate_mount_data(void *options,
1908 goto out_no_v3; 1917 goto out_no_v3;
1909 data->root.size = NFS2_FHSIZE; 1918 data->root.size = NFS2_FHSIZE;
1910 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); 1919 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1920 /* Turn off security negotiation */
1921 extra_flags |= NFS_MOUNT_SECFLAVOUR;
1911 case 4: 1922 case 4:
1912 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1923 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1913 goto out_no_sec; 1924 goto out_no_sec;
@@ -1935,7 +1946,7 @@ static int nfs23_validate_mount_data(void *options,
1935 * can deal with. 1946 * can deal with.
1936 */ 1947 */
1937 args->flags = data->flags & NFS_MOUNT_FLAGMASK; 1948 args->flags = data->flags & NFS_MOUNT_FLAGMASK;
1938 args->flags |= NFS_MOUNT_LEGACY_INTERFACE; 1949 args->flags |= extra_flags;
1939 args->rsize = data->rsize; 1950 args->rsize = data->rsize;
1940 args->wsize = data->wsize; 1951 args->wsize = data->wsize;
1941 args->timeo = data->timeo; 1952 args->timeo = data->timeo;
@@ -1959,9 +1970,10 @@ static int nfs23_validate_mount_data(void *options,
1959 args->namlen = data->namlen; 1970 args->namlen = data->namlen;
1960 args->bsize = data->bsize; 1971 args->bsize = data->bsize;
1961 1972
1962 args->auth_flavors[0] = RPC_AUTH_UNIX;
1963 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1973 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1964 args->auth_flavors[0] = data->pseudoflavor; 1974 nfs_set_auth_parsed_mount_data(args, data->pseudoflavor);
1975 else
1976 nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
1965 if (!args->nfs_server.hostname) 1977 if (!args->nfs_server.hostname)
1966 goto out_nomem; 1978 goto out_nomem;
1967 1979
@@ -2084,6 +2096,8 @@ static int nfs_validate_text_mount_data(void *options,
2084 max_namelen = NFS4_MAXNAMLEN; 2096 max_namelen = NFS4_MAXNAMLEN;
2085 max_pathlen = NFS4_MAXPATHLEN; 2097 max_pathlen = NFS4_MAXPATHLEN;
2086 nfs_validate_transport_protocol(args); 2098 nfs_validate_transport_protocol(args);
2099 if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP)
2100 goto out_invalid_transport_udp;
2087 nfs4_validate_mount_flags(args); 2101 nfs4_validate_mount_flags(args);
2088#else 2102#else
2089 goto out_v4_not_compiled; 2103 goto out_v4_not_compiled;
@@ -2106,6 +2120,10 @@ static int nfs_validate_text_mount_data(void *options,
2106out_v4_not_compiled: 2120out_v4_not_compiled:
2107 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 2121 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
2108 return -EPROTONOSUPPORT; 2122 return -EPROTONOSUPPORT;
2123#else
2124out_invalid_transport_udp:
2125 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n");
2126 return -EINVAL;
2109#endif /* !CONFIG_NFS_V4 */ 2127#endif /* !CONFIG_NFS_V4 */
2110 2128
2111out_no_address: 2129out_no_address:
@@ -2170,7 +2188,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
2170 data->rsize = nfss->rsize; 2188 data->rsize = nfss->rsize;
2171 data->wsize = nfss->wsize; 2189 data->wsize = nfss->wsize;
2172 data->retrans = nfss->client->cl_timeout->to_retries; 2190 data->retrans = nfss->client->cl_timeout->to_retries;
2173 data->auth_flavors[0] = nfss->client->cl_auth->au_flavor; 2191 nfs_set_auth_parsed_mount_data(data, nfss->client->cl_auth->au_flavor);
2174 data->acregmin = nfss->acregmin / HZ; 2192 data->acregmin = nfss->acregmin / HZ;
2175 data->acregmax = nfss->acregmax / HZ; 2193 data->acregmax = nfss->acregmax / HZ;
2176 data->acdirmin = nfss->acdirmin / HZ; 2194 data->acdirmin = nfss->acdirmin / HZ;
@@ -2277,6 +2295,18 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2277 nfs_initialise_sb(sb); 2295 nfs_initialise_sb(sb);
2278} 2296}
2279 2297
2298#define NFS_MOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \
2299 | NFS_MOUNT_SECURE \
2300 | NFS_MOUNT_TCP \
2301 | NFS_MOUNT_VER3 \
2302 | NFS_MOUNT_KERBEROS \
2303 | NFS_MOUNT_NONLM \
2304 | NFS_MOUNT_BROKEN_SUID \
2305 | NFS_MOUNT_STRICTLOCK \
2306 | NFS_MOUNT_UNSHARED \
2307 | NFS_MOUNT_NORESVPORT \
2308 | NFS_MOUNT_LEGACY_INTERFACE)
2309
2280static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags) 2310static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
2281{ 2311{
2282 const struct nfs_server *a = s->s_fs_info; 2312 const struct nfs_server *a = s->s_fs_info;
@@ -2287,7 +2317,7 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
2287 goto Ebusy; 2317 goto Ebusy;
2288 if (a->nfs_client != b->nfs_client) 2318 if (a->nfs_client != b->nfs_client)
2289 goto Ebusy; 2319 goto Ebusy;
2290 if (a->flags != b->flags) 2320 if ((a->flags ^ b->flags) & NFS_MOUNT_CMP_FLAGMASK)
2291 goto Ebusy; 2321 goto Ebusy;
2292 if (a->wsize != b->wsize) 2322 if (a->wsize != b->wsize)
2293 goto Ebusy; 2323 goto Ebusy;
@@ -2301,7 +2331,8 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
2301 goto Ebusy; 2331 goto Ebusy;
2302 if (a->acdirmax != b->acdirmax) 2332 if (a->acdirmax != b->acdirmax)
2303 goto Ebusy; 2333 goto Ebusy;
2304 if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor) 2334 if (b->flags & NFS_MOUNT_SECFLAVOUR &&
2335 clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
2305 goto Ebusy; 2336 goto Ebusy;
2306 return 1; 2337 return 1;
2307Ebusy: 2338Ebusy:
@@ -2673,15 +2704,17 @@ static int nfs4_validate_mount_data(void *options,
2673 goto out_no_address; 2704 goto out_no_address;
2674 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 2705 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
2675 2706
2676 args->auth_flavors[0] = RPC_AUTH_UNIX;
2677 if (data->auth_flavourlen) { 2707 if (data->auth_flavourlen) {
2708 rpc_authflavor_t pseudoflavor;
2678 if (data->auth_flavourlen > 1) 2709 if (data->auth_flavourlen > 1)
2679 goto out_inval_auth; 2710 goto out_inval_auth;
2680 if (copy_from_user(&args->auth_flavors[0], 2711 if (copy_from_user(&pseudoflavor,
2681 data->auth_flavours, 2712 data->auth_flavours,
2682 sizeof(args->auth_flavors[0]))) 2713 sizeof(pseudoflavor)))
2683 return -EFAULT; 2714 return -EFAULT;
2684 } 2715 nfs_set_auth_parsed_mount_data(args, pseudoflavor);
2716 } else
2717 nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
2685 2718
2686 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 2719 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
2687 if (IS_ERR(c)) 2720 if (IS_ERR(c))
@@ -2715,6 +2748,8 @@ static int nfs4_validate_mount_data(void *options,
2715 args->acdirmax = data->acdirmax; 2748 args->acdirmax = data->acdirmax;
2716 args->nfs_server.protocol = data->proto; 2749 args->nfs_server.protocol = data->proto;
2717 nfs_validate_transport_protocol(args); 2750 nfs_validate_transport_protocol(args);
2751 if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP)
2752 goto out_invalid_transport_udp;
2718 2753
2719 break; 2754 break;
2720 default: 2755 default:
@@ -2735,6 +2770,10 @@ out_inval_auth:
2735out_no_address: 2770out_no_address:
2736 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 2771 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
2737 return -EINVAL; 2772 return -EINVAL;
2773
2774out_invalid_transport_udp:
2775 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n");
2776 return -EINVAL;
2738} 2777}
2739 2778
2740/* 2779/*
@@ -2750,6 +2789,7 @@ bool nfs4_disable_idmapping = true;
2750unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE; 2789unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
2751unsigned short send_implementation_id = 1; 2790unsigned short send_implementation_id = 1;
2752char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = ""; 2791char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
2792bool recover_lost_locks = false;
2753 2793
2754EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport); 2794EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
2755EXPORT_SYMBOL_GPL(nfs_callback_tcpport); 2795EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
@@ -2758,6 +2798,7 @@ EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
2758EXPORT_SYMBOL_GPL(max_session_slots); 2798EXPORT_SYMBOL_GPL(max_session_slots);
2759EXPORT_SYMBOL_GPL(send_implementation_id); 2799EXPORT_SYMBOL_GPL(send_implementation_id);
2760EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier); 2800EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
2801EXPORT_SYMBOL_GPL(recover_lost_locks);
2761 2802
2762#define NFS_CALLBACK_MAXPORTNR (65535U) 2803#define NFS_CALLBACK_MAXPORTNR (65535U)
2763 2804
@@ -2795,4 +2836,10 @@ MODULE_PARM_DESC(send_implementation_id,
2795 "Send implementation ID with NFSv4.1 exchange_id"); 2836 "Send implementation ID with NFSv4.1 exchange_id");
2796MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string"); 2837MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
2797 2838
2839module_param(recover_lost_locks, bool, 0644);
2840MODULE_PARM_DESC(recover_lost_locks,
2841 "If the server reports that a lock might be lost, "
2842 "try to recover it risking data corruption.");
2843
2844
2798#endif /* CONFIG_NFS_V4 */ 2845#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 60395ad3a2e4..bb939edd4c99 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -20,6 +20,8 @@
20#include "iostat.h" 20#include "iostat.h"
21#include "delegation.h" 21#include "delegation.h"
22 22
23#include "nfstrace.h"
24
23/** 25/**
24 * nfs_free_unlinkdata - release data from a sillydelete operation. 26 * nfs_free_unlinkdata - release data from a sillydelete operation.
25 * @data: pointer to unlink structure. 27 * @data: pointer to unlink structure.
@@ -77,6 +79,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
77 struct nfs_unlinkdata *data = calldata; 79 struct nfs_unlinkdata *data = calldata;
78 struct inode *dir = data->dir; 80 struct inode *dir = data->dir;
79 81
82 trace_nfs_sillyrename_unlink(data, task->tk_status);
80 if (!NFS_PROTO(dir)->unlink_done(task, dir)) 83 if (!NFS_PROTO(dir)->unlink_done(task, dir))
81 rpc_restart_call_prepare(task); 84 rpc_restart_call_prepare(task);
82} 85}
@@ -204,6 +207,13 @@ out_free:
204 return ret; 207 return ret;
205} 208}
206 209
210void nfs_wait_on_sillyrename(struct dentry *dentry)
211{
212 struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
213
214 wait_event(nfsi->waitqueue, atomic_read(&nfsi->silly_count) <= 1);
215}
216
207void nfs_block_sillyrename(struct dentry *dentry) 217void nfs_block_sillyrename(struct dentry *dentry)
208{ 218{
209 struct nfs_inode *nfsi = NFS_I(dentry->d_inode); 219 struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
@@ -336,6 +346,8 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
336 struct inode *new_dir = data->new_dir; 346 struct inode *new_dir = data->new_dir;
337 struct dentry *old_dentry = data->old_dentry; 347 struct dentry *old_dentry = data->old_dentry;
338 348
349 trace_nfs_sillyrename_rename(old_dir, old_dentry,
350 new_dir, data->new_dentry, task->tk_status);
339 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { 351 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
340 rpc_restart_call_prepare(task); 352 rpc_restart_call_prepare(task);
341 return; 353 return;
@@ -444,6 +456,14 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
444 return rpc_run_task(&task_setup_data); 456 return rpc_run_task(&task_setup_data);
445} 457}
446 458
459#define SILLYNAME_PREFIX ".nfs"
460#define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
461#define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
462#define SILLYNAME_COUNTER_LEN ((unsigned)sizeof(unsigned int) << 1)
463#define SILLYNAME_LEN (SILLYNAME_PREFIX_LEN + \
464 SILLYNAME_FILEID_LEN + \
465 SILLYNAME_COUNTER_LEN)
466
447/** 467/**
448 * nfs_sillyrename - Perform a silly-rename of a dentry 468 * nfs_sillyrename - Perform a silly-rename of a dentry
449 * @dir: inode of directory that contains dentry 469 * @dir: inode of directory that contains dentry
@@ -469,10 +489,8 @@ int
469nfs_sillyrename(struct inode *dir, struct dentry *dentry) 489nfs_sillyrename(struct inode *dir, struct dentry *dentry)
470{ 490{
471 static unsigned int sillycounter; 491 static unsigned int sillycounter;
472 const int fileidsize = sizeof(NFS_FILEID(dentry->d_inode))*2; 492 unsigned char silly[SILLYNAME_LEN + 1];
473 const int countersize = sizeof(sillycounter)*2; 493 unsigned long long fileid;
474 const int slen = sizeof(".nfs")+fileidsize+countersize-1;
475 char silly[slen+1];
476 struct dentry *sdentry; 494 struct dentry *sdentry;
477 struct rpc_task *task; 495 struct rpc_task *task;
478 int error = -EIO; 496 int error = -EIO;
@@ -489,20 +507,20 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
489 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) 507 if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
490 goto out; 508 goto out;
491 509
492 sprintf(silly, ".nfs%*.*Lx", 510 fileid = NFS_FILEID(dentry->d_inode);
493 fileidsize, fileidsize,
494 (unsigned long long)NFS_FILEID(dentry->d_inode));
495 511
496 /* Return delegation in anticipation of the rename */ 512 /* Return delegation in anticipation of the rename */
497 NFS_PROTO(dentry->d_inode)->return_delegation(dentry->d_inode); 513 NFS_PROTO(dentry->d_inode)->return_delegation(dentry->d_inode);
498 514
499 sdentry = NULL; 515 sdentry = NULL;
500 do { 516 do {
501 char *suffix = silly + slen - countersize; 517 int slen;
502
503 dput(sdentry); 518 dput(sdentry);
504 sillycounter++; 519 sillycounter++;
505 sprintf(suffix, "%*.*x", countersize, countersize, sillycounter); 520 slen = scnprintf(silly, sizeof(silly),
521 SILLYNAME_PREFIX "%0*llx%0*x",
522 SILLYNAME_FILEID_LEN, fileid,
523 SILLYNAME_COUNTER_LEN, sillycounter);
506 524
507 dfprintk(VFS, "NFS: trying to rename %s to %s\n", 525 dfprintk(VFS, "NFS: trying to rename %s to %s\n",
508 dentry->d_name.name, silly); 526 dentry->d_name.name, silly);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f1bdb7254776..ac1dc331ba31 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -31,6 +31,8 @@
31#include "fscache.h" 31#include "fscache.h"
32#include "pnfs.h" 32#include "pnfs.h"
33 33
34#include "nfstrace.h"
35
34#define NFSDBG_FACILITY NFSDBG_PAGECACHE 36#define NFSDBG_FACILITY NFSDBG_PAGECACHE
35 37
36#define MIN_POOL_WRITE (32) 38#define MIN_POOL_WRITE (32)
@@ -861,7 +863,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
861 return 0; 863 return 0;
862 l_ctx = req->wb_lock_context; 864 l_ctx = req->wb_lock_context;
863 do_flush = req->wb_page != page || req->wb_context != ctx; 865 do_flush = req->wb_page != page || req->wb_context != ctx;
864 if (l_ctx) { 866 if (l_ctx && ctx->dentry->d_inode->i_flock != NULL) {
865 do_flush |= l_ctx->lockowner.l_owner != current->files 867 do_flush |= l_ctx->lockowner.l_owner != current->files
866 || l_ctx->lockowner.l_pid != current->tgid; 868 || l_ctx->lockowner.l_pid != current->tgid;
867 } 869 }
@@ -874,6 +876,33 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
874} 876}
875 877
876/* 878/*
879 * Avoid buffered writes when a open context credential's key would
880 * expire soon.
881 *
882 * Returns -EACCES if the key will expire within RPC_KEY_EXPIRE_FAIL.
883 *
884 * Return 0 and set a credential flag which triggers the inode to flush
885 * and performs NFS_FILE_SYNC writes if the key will expired within
886 * RPC_KEY_EXPIRE_TIMEO.
887 */
888int
889nfs_key_timeout_notify(struct file *filp, struct inode *inode)
890{
891 struct nfs_open_context *ctx = nfs_file_open_context(filp);
892 struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
893
894 return rpcauth_key_timeout_notify(auth, ctx->cred);
895}
896
897/*
898 * Test if the open context credential key is marked to expire soon.
899 */
900bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx)
901{
902 return rpcauth_cred_key_to_expire(ctx->cred);
903}
904
905/*
877 * If the page cache is marked as unsafe or invalid, then we can't rely on 906 * If the page cache is marked as unsafe or invalid, then we can't rely on
878 * the PageUptodate() flag. In this case, we will need to turn off 907 * the PageUptodate() flag. In this case, we will need to turn off
879 * write optimisations that depend on the page contents being correct. 908 * write optimisations that depend on the page contents being correct.
@@ -993,6 +1022,9 @@ int nfs_initiate_write(struct rpc_clnt *clnt,
993 data->args.count, 1022 data->args.count,
994 (unsigned long long)data->args.offset); 1023 (unsigned long long)data->args.offset);
995 1024
1025 nfs4_state_protect_write(NFS_SERVER(inode)->nfs_client,
1026 &task_setup_data.rpc_client, &msg, data);
1027
996 task = rpc_run_task(&task_setup_data); 1028 task = rpc_run_task(&task_setup_data);
997 if (IS_ERR(task)) { 1029 if (IS_ERR(task)) {
998 ret = PTR_ERR(task); 1030 ret = PTR_ERR(task);
@@ -1265,9 +1297,10 @@ EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds);
1265void nfs_write_prepare(struct rpc_task *task, void *calldata) 1297void nfs_write_prepare(struct rpc_task *task, void *calldata)
1266{ 1298{
1267 struct nfs_write_data *data = calldata; 1299 struct nfs_write_data *data = calldata;
1268 NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data); 1300 int err;
1269 if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags))) 1301 err = NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data);
1270 rpc_exit(task, -EIO); 1302 if (err)
1303 rpc_exit(task, err);
1271} 1304}
1272 1305
1273void nfs_commit_prepare(struct rpc_task *task, void *calldata) 1306void nfs_commit_prepare(struct rpc_task *task, void *calldata)
@@ -1458,6 +1491,9 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
1458 1491
1459 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 1492 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
1460 1493
1494 nfs4_state_protect(NFS_SERVER(data->inode)->nfs_client,
1495 NFS_SP4_MACH_CRED_COMMIT, &task_setup_data.rpc_client, &msg);
1496
1461 task = rpc_run_task(&task_setup_data); 1497 task = rpc_run_task(&task_setup_data);
1462 if (IS_ERR(task)) 1498 if (IS_ERR(task))
1463 return PTR_ERR(task); 1499 return PTR_ERR(task);
@@ -1732,8 +1768,14 @@ int nfs_wb_all(struct inode *inode)
1732 .range_start = 0, 1768 .range_start = 0,
1733 .range_end = LLONG_MAX, 1769 .range_end = LLONG_MAX,
1734 }; 1770 };
1771 int ret;
1735 1772
1736 return sync_inode(inode, &wbc); 1773 trace_nfs_writeback_inode_enter(inode);
1774
1775 ret = sync_inode(inode, &wbc);
1776
1777 trace_nfs_writeback_inode_exit(inode, ret);
1778 return ret;
1737} 1779}
1738EXPORT_SYMBOL_GPL(nfs_wb_all); 1780EXPORT_SYMBOL_GPL(nfs_wb_all);
1739 1781
@@ -1781,6 +1823,8 @@ int nfs_wb_page(struct inode *inode, struct page *page)
1781 }; 1823 };
1782 int ret; 1824 int ret;
1783 1825
1826 trace_nfs_writeback_page_enter(inode);
1827
1784 for (;;) { 1828 for (;;) {
1785 wait_on_page_writeback(page); 1829 wait_on_page_writeback(page);
1786 if (clear_page_dirty_for_io(page)) { 1830 if (clear_page_dirty_for_io(page)) {
@@ -1789,14 +1833,15 @@ int nfs_wb_page(struct inode *inode, struct page *page)
1789 goto out_error; 1833 goto out_error;
1790 continue; 1834 continue;
1791 } 1835 }
1836 ret = 0;
1792 if (!PagePrivate(page)) 1837 if (!PagePrivate(page))
1793 break; 1838 break;
1794 ret = nfs_commit_inode(inode, FLUSH_SYNC); 1839 ret = nfs_commit_inode(inode, FLUSH_SYNC);
1795 if (ret < 0) 1840 if (ret < 0)
1796 goto out_error; 1841 goto out_error;
1797 } 1842 }
1798 return 0;
1799out_error: 1843out_error:
1844 trace_nfs_writeback_page_exit(inode, ret);
1800 return ret; 1845 return ret;
1801} 1846}
1802 1847
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 7125cef74164..3ea4cde8701c 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -524,6 +524,7 @@ static inline void nfs4_label_free(void *label) {}
524 * linux/fs/nfs/unlink.c 524 * linux/fs/nfs/unlink.c
525 */ 525 */
526extern void nfs_complete_unlink(struct dentry *dentry, struct inode *); 526extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
527extern void nfs_wait_on_sillyrename(struct dentry *dentry);
527extern void nfs_block_sillyrename(struct dentry *dentry); 528extern void nfs_block_sillyrename(struct dentry *dentry);
528extern void nfs_unblock_sillyrename(struct dentry *dentry); 529extern void nfs_unblock_sillyrename(struct dentry *dentry);
529extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry); 530extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index d2212432c456..b8cedced50c9 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -56,6 +56,7 @@ struct nfs_client {
56 struct rpc_cred *cl_machine_cred; 56 struct rpc_cred *cl_machine_cred;
57 57
58#if IS_ENABLED(CONFIG_NFS_V4) 58#if IS_ENABLED(CONFIG_NFS_V4)
59 struct list_head cl_ds_clients; /* auth flavor data servers */
59 u64 cl_clientid; /* constant */ 60 u64 cl_clientid; /* constant */
60 nfs4_verifier cl_confirm; /* Clientid verifier */ 61 nfs4_verifier cl_confirm; /* Clientid verifier */
61 unsigned long cl_state; 62 unsigned long cl_state;
@@ -78,6 +79,9 @@ struct nfs_client {
78 u32 cl_cb_ident; /* v4.0 callback identifier */ 79 u32 cl_cb_ident; /* v4.0 callback identifier */
79 const struct nfs4_minor_version_ops *cl_mvops; 80 const struct nfs4_minor_version_ops *cl_mvops;
80 81
82 /* NFSv4.0 transport blocking */
83 struct nfs4_slot_table *cl_slot_tbl;
84
81 /* The sequence id to use for the next CREATE_SESSION */ 85 /* The sequence id to use for the next CREATE_SESSION */
82 u32 cl_seqid; 86 u32 cl_seqid;
83 /* The flags used for obtaining the clientid during EXCHANGE_ID */ 87 /* The flags used for obtaining the clientid during EXCHANGE_ID */
@@ -87,6 +91,15 @@ struct nfs_client {
87 struct nfs41_server_owner *cl_serverowner; 91 struct nfs41_server_owner *cl_serverowner;
88 struct nfs41_server_scope *cl_serverscope; 92 struct nfs41_server_scope *cl_serverscope;
89 struct nfs41_impl_id *cl_implid; 93 struct nfs41_impl_id *cl_implid;
94 /* nfs 4.1+ state protection modes: */
95 unsigned long cl_sp4_flags;
96#define NFS_SP4_MACH_CRED_MINIMAL 1 /* Minimal sp4_mach_cred - state ops
97 * must use machine cred */
98#define NFS_SP4_MACH_CRED_CLEANUP 2 /* CLOSE and LOCKU */
99#define NFS_SP4_MACH_CRED_SECINFO 3 /* SECINFO and SECINFO_NO_NAME */
100#define NFS_SP4_MACH_CRED_STATEID 4 /* TEST_STATEID and FREE_STATEID */
101#define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */
102#define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */
90#endif /* CONFIG_NFS_V4 */ 103#endif /* CONFIG_NFS_V4 */
91 104
92#ifdef CONFIG_NFS_FSCACHE 105#ifdef CONFIG_NFS_FSCACHE
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 8651574a305b..01fd84b566f7 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1107,6 +1107,23 @@ struct pnfs_ds_commit_info {
1107 struct pnfs_commit_bucket *buckets; 1107 struct pnfs_commit_bucket *buckets;
1108}; 1108};
1109 1109
1110#define NFS4_OP_MAP_NUM_LONGS \
1111 DIV_ROUND_UP(LAST_NFS4_OP, 8 * sizeof(unsigned long))
1112#define NFS4_OP_MAP_NUM_WORDS \
1113 (NFS4_OP_MAP_NUM_LONGS * sizeof(unsigned long) / sizeof(u32))
1114struct nfs4_op_map {
1115 union {
1116 unsigned long longs[NFS4_OP_MAP_NUM_LONGS];
1117 u32 words[NFS4_OP_MAP_NUM_WORDS];
1118 } u;
1119};
1120
1121struct nfs41_state_protection {
1122 u32 how;
1123 struct nfs4_op_map enforce;
1124 struct nfs4_op_map allow;
1125};
1126
1110#define NFS4_EXCHANGE_ID_LEN (48) 1127#define NFS4_EXCHANGE_ID_LEN (48)
1111struct nfs41_exchange_id_args { 1128struct nfs41_exchange_id_args {
1112 struct nfs_client *client; 1129 struct nfs_client *client;
@@ -1114,6 +1131,7 @@ struct nfs41_exchange_id_args {
1114 unsigned int id_len; 1131 unsigned int id_len;
1115 char id[NFS4_EXCHANGE_ID_LEN]; 1132 char id[NFS4_EXCHANGE_ID_LEN];
1116 u32 flags; 1133 u32 flags;
1134 struct nfs41_state_protection state_protect;
1117}; 1135};
1118 1136
1119struct nfs41_server_owner { 1137struct nfs41_server_owner {
@@ -1146,6 +1164,7 @@ struct nfs41_exchange_id_res {
1146 struct nfs41_server_owner *server_owner; 1164 struct nfs41_server_owner *server_owner;
1147 struct nfs41_server_scope *server_scope; 1165 struct nfs41_server_scope *server_scope;
1148 struct nfs41_impl_id *impl_id; 1166 struct nfs41_impl_id *impl_id;
1167 struct nfs41_state_protection state_protect;
1149}; 1168};
1150 1169
1151struct nfs41_create_session_args { 1170struct nfs41_create_session_args {
@@ -1419,12 +1438,12 @@ struct nfs_rpc_ops {
1419 void (*read_setup) (struct nfs_read_data *, struct rpc_message *); 1438 void (*read_setup) (struct nfs_read_data *, struct rpc_message *);
1420 void (*read_pageio_init)(struct nfs_pageio_descriptor *, struct inode *, 1439 void (*read_pageio_init)(struct nfs_pageio_descriptor *, struct inode *,
1421 const struct nfs_pgio_completion_ops *); 1440 const struct nfs_pgio_completion_ops *);
1422 void (*read_rpc_prepare)(struct rpc_task *, struct nfs_read_data *); 1441 int (*read_rpc_prepare)(struct rpc_task *, struct nfs_read_data *);
1423 int (*read_done) (struct rpc_task *, struct nfs_read_data *); 1442 int (*read_done) (struct rpc_task *, struct nfs_read_data *);
1424 void (*write_setup) (struct nfs_write_data *, struct rpc_message *); 1443 void (*write_setup) (struct nfs_write_data *, struct rpc_message *);
1425 void (*write_pageio_init)(struct nfs_pageio_descriptor *, struct inode *, int, 1444 void (*write_pageio_init)(struct nfs_pageio_descriptor *, struct inode *, int,
1426 const struct nfs_pgio_completion_ops *); 1445 const struct nfs_pgio_completion_ops *);
1427 void (*write_rpc_prepare)(struct rpc_task *, struct nfs_write_data *); 1446 int (*write_rpc_prepare)(struct rpc_task *, struct nfs_write_data *);
1428 int (*write_done) (struct rpc_task *, struct nfs_write_data *); 1447 int (*write_done) (struct rpc_task *, struct nfs_write_data *);
1429 void (*commit_setup) (struct nfs_commit_data *, struct rpc_message *); 1448 void (*commit_setup) (struct nfs_commit_data *, struct rpc_message *);
1430 void (*commit_rpc_prepare)(struct rpc_task *, struct nfs_commit_data *); 1449 void (*commit_rpc_prepare)(struct rpc_task *, struct nfs_commit_data *);
@@ -1442,7 +1461,7 @@ struct nfs_rpc_ops {
1442 struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *); 1461 struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *);
1443 struct nfs_client * 1462 struct nfs_client *
1444 (*init_client) (struct nfs_client *, const struct rpc_timeout *, 1463 (*init_client) (struct nfs_client *, const struct rpc_timeout *,
1445 const char *, rpc_authflavor_t); 1464 const char *);
1446 void (*free_client) (struct nfs_client *); 1465 void (*free_client) (struct nfs_client *);
1447 struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *); 1466 struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *);
1448 struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, 1467 struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 0dd00f4f6810..790be1472792 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -24,12 +24,21 @@
24 24
25struct rpcsec_gss_info; 25struct rpcsec_gss_info;
26 26
27/* auth_cred ac_flags bits */
28enum {
29 RPC_CRED_NO_CRKEY_TIMEOUT = 0, /* underlying cred has no key timeout */
30 RPC_CRED_KEY_EXPIRE_SOON = 1, /* underlying cred key will expire soon */
31 RPC_CRED_NOTIFY_TIMEOUT = 2, /* nofity generic cred when underlying
32 key will expire soon */
33};
34
27/* Work around the lack of a VFS credential */ 35/* Work around the lack of a VFS credential */
28struct auth_cred { 36struct auth_cred {
29 kuid_t uid; 37 kuid_t uid;
30 kgid_t gid; 38 kgid_t gid;
31 struct group_info *group_info; 39 struct group_info *group_info;
32 const char *principal; 40 const char *principal;
41 unsigned long ac_flags;
33 unsigned char machine_cred : 1; 42 unsigned char machine_cred : 1;
34}; 43};
35 44
@@ -87,6 +96,11 @@ struct rpc_auth {
87 /* per-flavor data */ 96 /* per-flavor data */
88}; 97};
89 98
99struct rpc_auth_create_args {
100 rpc_authflavor_t pseudoflavor;
101 const char *target_name;
102};
103
90/* Flags for rpcauth_lookupcred() */ 104/* Flags for rpcauth_lookupcred() */
91#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ 105#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */
92 106
@@ -97,17 +111,17 @@ struct rpc_authops {
97 struct module *owner; 111 struct module *owner;
98 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */ 112 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */
99 char * au_name; 113 char * au_name;
100 struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t); 114 struct rpc_auth * (*create)(struct rpc_auth_create_args *, struct rpc_clnt *);
101 void (*destroy)(struct rpc_auth *); 115 void (*destroy)(struct rpc_auth *);
102 116
103 struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); 117 struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
104 struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int); 118 struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int);
105 int (*pipes_create)(struct rpc_auth *);
106 void (*pipes_destroy)(struct rpc_auth *);
107 int (*list_pseudoflavors)(rpc_authflavor_t *, int); 119 int (*list_pseudoflavors)(rpc_authflavor_t *, int);
108 rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *); 120 rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *);
109 int (*flavor2info)(rpc_authflavor_t, 121 int (*flavor2info)(rpc_authflavor_t,
110 struct rpcsec_gss_info *); 122 struct rpcsec_gss_info *);
123 int (*key_timeout)(struct rpc_auth *,
124 struct rpc_cred *);
111}; 125};
112 126
113struct rpc_credops { 127struct rpc_credops {
@@ -124,6 +138,8 @@ struct rpc_credops {
124 void *, __be32 *, void *); 138 void *, __be32 *, void *);
125 int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t, 139 int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
126 void *, __be32 *, void *); 140 void *, __be32 *, void *);
141 int (*crkey_timeout)(struct rpc_cred *);
142 bool (*crkey_to_expire)(struct rpc_cred *);
127}; 143};
128 144
129extern const struct rpc_authops authunix_ops; 145extern const struct rpc_authops authunix_ops;
@@ -140,7 +156,8 @@ struct rpc_cred * rpc_lookup_cred(void);
140struct rpc_cred * rpc_lookup_machine_cred(const char *service_name); 156struct rpc_cred * rpc_lookup_machine_cred(const char *service_name);
141int rpcauth_register(const struct rpc_authops *); 157int rpcauth_register(const struct rpc_authops *);
142int rpcauth_unregister(const struct rpc_authops *); 158int rpcauth_unregister(const struct rpc_authops *);
143struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); 159struct rpc_auth * rpcauth_create(struct rpc_auth_create_args *,
160 struct rpc_clnt *);
144void rpcauth_release(struct rpc_auth *); 161void rpcauth_release(struct rpc_auth *);
145rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t, 162rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t,
146 struct rpcsec_gss_info *); 163 struct rpcsec_gss_info *);
@@ -162,6 +179,9 @@ int rpcauth_uptodatecred(struct rpc_task *);
162int rpcauth_init_credcache(struct rpc_auth *); 179int rpcauth_init_credcache(struct rpc_auth *);
163void rpcauth_destroy_credcache(struct rpc_auth *); 180void rpcauth_destroy_credcache(struct rpc_auth *);
164void rpcauth_clear_credcache(struct rpc_cred_cache *); 181void rpcauth_clear_credcache(struct rpc_cred_cache *);
182int rpcauth_key_timeout_notify(struct rpc_auth *,
183 struct rpc_cred *);
184bool rpcauth_cred_key_to_expire(struct rpc_cred *);
165 185
166static inline 186static inline
167struct rpc_cred * get_rpccred(struct rpc_cred *cred) 187struct rpc_cred * get_rpccred(struct rpc_cred *cred)
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index bfe11be81f6f..6740801aa71a 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -21,6 +21,7 @@
21#include <linux/sunrpc/stats.h> 21#include <linux/sunrpc/stats.h>
22#include <linux/sunrpc/xdr.h> 22#include <linux/sunrpc/xdr.h>
23#include <linux/sunrpc/timer.h> 23#include <linux/sunrpc/timer.h>
24#include <linux/sunrpc/rpc_pipe_fs.h>
24#include <asm/signal.h> 25#include <asm/signal.h>
25#include <linux/path.h> 26#include <linux/path.h>
26#include <net/ipv6.h> 27#include <net/ipv6.h>
@@ -32,6 +33,7 @@ struct rpc_inode;
32 */ 33 */
33struct rpc_clnt { 34struct rpc_clnt {
34 atomic_t cl_count; /* Number of references */ 35 atomic_t cl_count; /* Number of references */
36 unsigned int cl_clid; /* client id */
35 struct list_head cl_clients; /* Global list of clients */ 37 struct list_head cl_clients; /* Global list of clients */
36 struct list_head cl_tasks; /* List of tasks */ 38 struct list_head cl_tasks; /* List of tasks */
37 spinlock_t cl_lock; /* spinlock */ 39 spinlock_t cl_lock; /* spinlock */
@@ -41,7 +43,6 @@ struct rpc_clnt {
41 cl_vers, /* RPC version number */ 43 cl_vers, /* RPC version number */
42 cl_maxproc; /* max procedure number */ 44 cl_maxproc; /* max procedure number */
43 45
44 const char * cl_protname; /* protocol name */
45 struct rpc_auth * cl_auth; /* authenticator */ 46 struct rpc_auth * cl_auth; /* authenticator */
46 struct rpc_stat * cl_stats; /* per-program statistics */ 47 struct rpc_stat * cl_stats; /* per-program statistics */
47 struct rpc_iostats * cl_metrics; /* per-client statistics */ 48 struct rpc_iostats * cl_metrics; /* per-client statistics */
@@ -56,12 +57,11 @@ struct rpc_clnt {
56 57
57 int cl_nodelen; /* nodename length */ 58 int cl_nodelen; /* nodename length */
58 char cl_nodename[UNX_MAXNODENAME]; 59 char cl_nodename[UNX_MAXNODENAME];
59 struct dentry * cl_dentry; 60 struct rpc_pipe_dir_head cl_pipedir_objects;
60 struct rpc_clnt * cl_parent; /* Points to parent of clones */ 61 struct rpc_clnt * cl_parent; /* Points to parent of clones */
61 struct rpc_rtt cl_rtt_default; 62 struct rpc_rtt cl_rtt_default;
62 struct rpc_timeout cl_timeout_default; 63 struct rpc_timeout cl_timeout_default;
63 const struct rpc_program *cl_program; 64 const struct rpc_program *cl_program;
64 char *cl_principal; /* target to authenticate to */
65}; 65};
66 66
67/* 67/*
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index aa5b582cc471..a353e0300b54 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -5,6 +5,26 @@
5 5
6#include <linux/workqueue.h> 6#include <linux/workqueue.h>
7 7
8struct rpc_pipe_dir_head {
9 struct list_head pdh_entries;
10 struct dentry *pdh_dentry;
11};
12
13struct rpc_pipe_dir_object_ops;
14struct rpc_pipe_dir_object {
15 struct list_head pdo_head;
16 const struct rpc_pipe_dir_object_ops *pdo_ops;
17
18 void *pdo_data;
19};
20
21struct rpc_pipe_dir_object_ops {
22 int (*create)(struct dentry *dir,
23 struct rpc_pipe_dir_object *pdo);
24 void (*destroy)(struct dentry *dir,
25 struct rpc_pipe_dir_object *pdo);
26};
27
8struct rpc_pipe_msg { 28struct rpc_pipe_msg {
9 struct list_head list; 29 struct list_head list;
10 void *data; 30 void *data;
@@ -74,7 +94,24 @@ extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
74 94
75struct rpc_clnt; 95struct rpc_clnt;
76extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *); 96extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
77extern int rpc_remove_client_dir(struct dentry *); 97extern int rpc_remove_client_dir(struct rpc_clnt *);
98
99extern void rpc_init_pipe_dir_head(struct rpc_pipe_dir_head *pdh);
100extern void rpc_init_pipe_dir_object(struct rpc_pipe_dir_object *pdo,
101 const struct rpc_pipe_dir_object_ops *pdo_ops,
102 void *pdo_data);
103extern int rpc_add_pipe_dir_object(struct net *net,
104 struct rpc_pipe_dir_head *pdh,
105 struct rpc_pipe_dir_object *pdo);
106extern void rpc_remove_pipe_dir_object(struct net *net,
107 struct rpc_pipe_dir_head *pdh,
108 struct rpc_pipe_dir_object *pdo);
109extern struct rpc_pipe_dir_object *rpc_find_or_alloc_pipe_dir_object(
110 struct net *net,
111 struct rpc_pipe_dir_head *pdh,
112 int (*match)(struct rpc_pipe_dir_object *, void *),
113 struct rpc_pipe_dir_object *(*alloc)(void *),
114 void *data);
78 115
79struct cache_detail; 116struct cache_detail;
80extern struct dentry *rpc_create_cache_dir(struct dentry *, 117extern struct dentry *rpc_create_cache_dir(struct dentry *,
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 1821445708d6..096ee58be11a 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -79,7 +79,7 @@ struct rpc_task {
79 unsigned short tk_flags; /* misc flags */ 79 unsigned short tk_flags; /* misc flags */
80 unsigned short tk_timeouts; /* maj timeouts */ 80 unsigned short tk_timeouts; /* maj timeouts */
81 81
82#ifdef RPC_DEBUG 82#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
83 unsigned short tk_pid; /* debugging aid */ 83 unsigned short tk_pid; /* debugging aid */
84#endif 84#endif
85 unsigned char tk_priority : 2,/* Task priority */ 85 unsigned char tk_priority : 2,/* Task priority */
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 43be87d5dd58..d51d16c7afd8 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -6,6 +6,8 @@
6 6
7#include <linux/sunrpc/sched.h> 7#include <linux/sunrpc/sched.h>
8#include <linux/sunrpc/clnt.h> 8#include <linux/sunrpc/clnt.h>
9#include <net/tcp_states.h>
10#include <linux/net.h>
9#include <linux/tracepoint.h> 11#include <linux/tracepoint.h>
10 12
11DECLARE_EVENT_CLASS(rpc_task_status, 13DECLARE_EVENT_CLASS(rpc_task_status,
@@ -15,18 +17,20 @@ DECLARE_EVENT_CLASS(rpc_task_status,
15 TP_ARGS(task), 17 TP_ARGS(task),
16 18
17 TP_STRUCT__entry( 19 TP_STRUCT__entry(
18 __field(const struct rpc_task *, task) 20 __field(unsigned int, task_id)
19 __field(const struct rpc_clnt *, clnt) 21 __field(unsigned int, client_id)
20 __field(int, status) 22 __field(int, status)
21 ), 23 ),
22 24
23 TP_fast_assign( 25 TP_fast_assign(
24 __entry->task = task; 26 __entry->task_id = task->tk_pid;
25 __entry->clnt = task->tk_client; 27 __entry->client_id = task->tk_client->cl_clid;
26 __entry->status = task->tk_status; 28 __entry->status = task->tk_status;
27 ), 29 ),
28 30
29 TP_printk("task:%p@%p, status %d",__entry->task, __entry->clnt, __entry->status) 31 TP_printk("task:%u@%u, status %d",
32 __entry->task_id, __entry->client_id,
33 __entry->status)
30); 34);
31 35
32DEFINE_EVENT(rpc_task_status, rpc_call_status, 36DEFINE_EVENT(rpc_task_status, rpc_call_status,
@@ -47,18 +51,20 @@ TRACE_EVENT(rpc_connect_status,
47 TP_ARGS(task, status), 51 TP_ARGS(task, status),
48 52
49 TP_STRUCT__entry( 53 TP_STRUCT__entry(
50 __field(const struct rpc_task *, task) 54 __field(unsigned int, task_id)
51 __field(const struct rpc_clnt *, clnt) 55 __field(unsigned int, client_id)
52 __field(int, status) 56 __field(int, status)
53 ), 57 ),
54 58
55 TP_fast_assign( 59 TP_fast_assign(
56 __entry->task = task; 60 __entry->task_id = task->tk_pid;
57 __entry->clnt = task->tk_client; 61 __entry->client_id = task->tk_client->cl_clid;
58 __entry->status = status; 62 __entry->status = status;
59 ), 63 ),
60 64
61 TP_printk("task:%p@%p, status %d",__entry->task, __entry->clnt, __entry->status) 65 TP_printk("task:%u@%u, status %d",
66 __entry->task_id, __entry->client_id,
67 __entry->status)
62); 68);
63 69
64DECLARE_EVENT_CLASS(rpc_task_running, 70DECLARE_EVENT_CLASS(rpc_task_running,
@@ -68,8 +74,8 @@ DECLARE_EVENT_CLASS(rpc_task_running,
68 TP_ARGS(clnt, task, action), 74 TP_ARGS(clnt, task, action),
69 75
70 TP_STRUCT__entry( 76 TP_STRUCT__entry(
71 __field(const struct rpc_clnt *, clnt) 77 __field(unsigned int, task_id)
72 __field(const struct rpc_task *, task) 78 __field(unsigned int, client_id)
73 __field(const void *, action) 79 __field(const void *, action)
74 __field(unsigned long, runstate) 80 __field(unsigned long, runstate)
75 __field(int, status) 81 __field(int, status)
@@ -77,17 +83,16 @@ DECLARE_EVENT_CLASS(rpc_task_running,
77 ), 83 ),
78 84
79 TP_fast_assign( 85 TP_fast_assign(
80 __entry->clnt = clnt; 86 __entry->client_id = clnt->cl_clid;
81 __entry->task = task; 87 __entry->task_id = task->tk_pid;
82 __entry->action = action; 88 __entry->action = action;
83 __entry->runstate = task->tk_runstate; 89 __entry->runstate = task->tk_runstate;
84 __entry->status = task->tk_status; 90 __entry->status = task->tk_status;
85 __entry->flags = task->tk_flags; 91 __entry->flags = task->tk_flags;
86 ), 92 ),
87 93
88 TP_printk("task:%p@%p flags=%4.4x state=%4.4lx status=%d action=%pf", 94 TP_printk("task:%u@%u flags=%4.4x state=%4.4lx status=%d action=%pf",
89 __entry->task, 95 __entry->task_id, __entry->client_id,
90 __entry->clnt,
91 __entry->flags, 96 __entry->flags,
92 __entry->runstate, 97 __entry->runstate,
93 __entry->status, 98 __entry->status,
@@ -126,8 +131,8 @@ DECLARE_EVENT_CLASS(rpc_task_queued,
126 TP_ARGS(clnt, task, q), 131 TP_ARGS(clnt, task, q),
127 132
128 TP_STRUCT__entry( 133 TP_STRUCT__entry(
129 __field(const struct rpc_clnt *, clnt) 134 __field(unsigned int, task_id)
130 __field(const struct rpc_task *, task) 135 __field(unsigned int, client_id)
131 __field(unsigned long, timeout) 136 __field(unsigned long, timeout)
132 __field(unsigned long, runstate) 137 __field(unsigned long, runstate)
133 __field(int, status) 138 __field(int, status)
@@ -136,8 +141,8 @@ DECLARE_EVENT_CLASS(rpc_task_queued,
136 ), 141 ),
137 142
138 TP_fast_assign( 143 TP_fast_assign(
139 __entry->clnt = clnt; 144 __entry->client_id = clnt->cl_clid;
140 __entry->task = task; 145 __entry->task_id = task->tk_pid;
141 __entry->timeout = task->tk_timeout; 146 __entry->timeout = task->tk_timeout;
142 __entry->runstate = task->tk_runstate; 147 __entry->runstate = task->tk_runstate;
143 __entry->status = task->tk_status; 148 __entry->status = task->tk_status;
@@ -145,9 +150,8 @@ DECLARE_EVENT_CLASS(rpc_task_queued,
145 __assign_str(q_name, rpc_qname(q)); 150 __assign_str(q_name, rpc_qname(q));
146 ), 151 ),
147 152
148 TP_printk("task:%p@%p flags=%4.4x state=%4.4lx status=%d timeout=%lu queue=%s", 153 TP_printk("task:%u@%u flags=%4.4x state=%4.4lx status=%d timeout=%lu queue=%s",
149 __entry->task, 154 __entry->task_id, __entry->client_id,
150 __entry->clnt,
151 __entry->flags, 155 __entry->flags,
152 __entry->runstate, 156 __entry->runstate,
153 __entry->status, 157 __entry->status,
@@ -172,6 +176,135 @@ DEFINE_EVENT(rpc_task_queued, rpc_task_wakeup,
172 176
173); 177);
174 178
179#define rpc_show_socket_state(state) \
180 __print_symbolic(state, \
181 { SS_FREE, "FREE" }, \
182 { SS_UNCONNECTED, "UNCONNECTED" }, \
183 { SS_CONNECTING, "CONNECTING," }, \
184 { SS_CONNECTED, "CONNECTED," }, \
185 { SS_DISCONNECTING, "DISCONNECTING" })
186
187#define rpc_show_sock_state(state) \
188 __print_symbolic(state, \
189 { TCP_ESTABLISHED, "ESTABLISHED" }, \
190 { TCP_SYN_SENT, "SYN_SENT" }, \
191 { TCP_SYN_RECV, "SYN_RECV" }, \
192 { TCP_FIN_WAIT1, "FIN_WAIT1" }, \
193 { TCP_FIN_WAIT2, "FIN_WAIT2" }, \
194 { TCP_TIME_WAIT, "TIME_WAIT" }, \
195 { TCP_CLOSE, "CLOSE" }, \
196 { TCP_CLOSE_WAIT, "CLOSE_WAIT" }, \
197 { TCP_LAST_ACK, "LAST_ACK" }, \
198 { TCP_LISTEN, "LISTEN" }, \
199 { TCP_CLOSING, "CLOSING" })
200
201DECLARE_EVENT_CLASS(xs_socket_event,
202
203 TP_PROTO(
204 struct rpc_xprt *xprt,
205 struct socket *socket
206 ),
207
208 TP_ARGS(xprt, socket),
209
210 TP_STRUCT__entry(
211 __field(unsigned int, socket_state)
212 __field(unsigned int, sock_state)
213 __field(unsigned long long, ino)
214 __string(dstaddr,
215 xprt->address_strings[RPC_DISPLAY_ADDR])
216 __string(dstport,
217 xprt->address_strings[RPC_DISPLAY_PORT])
218 ),
219
220 TP_fast_assign(
221 struct inode *inode = SOCK_INODE(socket);
222 __entry->socket_state = socket->state;
223 __entry->sock_state = socket->sk->sk_state;
224 __entry->ino = (unsigned long long)inode->i_ino;
225 __assign_str(dstaddr,
226 xprt->address_strings[RPC_DISPLAY_ADDR]);
227 __assign_str(dstport,
228 xprt->address_strings[RPC_DISPLAY_PORT]);
229 ),
230
231 TP_printk(
232 "socket:[%llu] dstaddr=%s/%s "
233 "state=%u (%s) sk_state=%u (%s)",
234 __entry->ino, __get_str(dstaddr), __get_str(dstport),
235 __entry->socket_state,
236 rpc_show_socket_state(__entry->socket_state),
237 __entry->sock_state,
238 rpc_show_sock_state(__entry->sock_state)
239 )
240);
241#define DEFINE_RPC_SOCKET_EVENT(name) \
242 DEFINE_EVENT(xs_socket_event, name, \
243 TP_PROTO( \
244 struct rpc_xprt *xprt, \
245 struct socket *socket \
246 ), \
247 TP_ARGS(xprt, socket))
248
249DECLARE_EVENT_CLASS(xs_socket_event_done,
250
251 TP_PROTO(
252 struct rpc_xprt *xprt,
253 struct socket *socket,
254 int error
255 ),
256
257 TP_ARGS(xprt, socket, error),
258
259 TP_STRUCT__entry(
260 __field(int, error)
261 __field(unsigned int, socket_state)
262 __field(unsigned int, sock_state)
263 __field(unsigned long long, ino)
264 __string(dstaddr,
265 xprt->address_strings[RPC_DISPLAY_ADDR])
266 __string(dstport,
267 xprt->address_strings[RPC_DISPLAY_PORT])
268 ),
269
270 TP_fast_assign(
271 struct inode *inode = SOCK_INODE(socket);
272 __entry->socket_state = socket->state;
273 __entry->sock_state = socket->sk->sk_state;
274 __entry->ino = (unsigned long long)inode->i_ino;
275 __entry->error = error;
276 __assign_str(dstaddr,
277 xprt->address_strings[RPC_DISPLAY_ADDR]);
278 __assign_str(dstport,
279 xprt->address_strings[RPC_DISPLAY_PORT]);
280 ),
281
282 TP_printk(
283 "error=%d socket:[%llu] dstaddr=%s/%s "
284 "state=%u (%s) sk_state=%u (%s)",
285 __entry->error,
286 __entry->ino, __get_str(dstaddr), __get_str(dstport),
287 __entry->socket_state,
288 rpc_show_socket_state(__entry->socket_state),
289 __entry->sock_state,
290 rpc_show_sock_state(__entry->sock_state)
291 )
292);
293#define DEFINE_RPC_SOCKET_EVENT_DONE(name) \
294 DEFINE_EVENT(xs_socket_event_done, name, \
295 TP_PROTO( \
296 struct rpc_xprt *xprt, \
297 struct socket *socket, \
298 int error \
299 ), \
300 TP_ARGS(xprt, socket, error))
301
302DEFINE_RPC_SOCKET_EVENT(rpc_socket_state_change);
303DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_connect);
304DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_reset_connection);
305DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
306DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
307
175#endif /* _TRACE_SUNRPC_H */ 308#endif /* _TRACE_SUNRPC_H */
176 309
177#include <trace/define_trace.h> 310#include <trace/define_trace.h>
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index ed2fdd210c0b..415159061cd0 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -250,11 +250,11 @@ rpcauth_list_flavors(rpc_authflavor_t *array, int size)
250EXPORT_SYMBOL_GPL(rpcauth_list_flavors); 250EXPORT_SYMBOL_GPL(rpcauth_list_flavors);
251 251
252struct rpc_auth * 252struct rpc_auth *
253rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) 253rpcauth_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
254{ 254{
255 struct rpc_auth *auth; 255 struct rpc_auth *auth;
256 const struct rpc_authops *ops; 256 const struct rpc_authops *ops;
257 u32 flavor = pseudoflavor_to_flavor(pseudoflavor); 257 u32 flavor = pseudoflavor_to_flavor(args->pseudoflavor);
258 258
259 auth = ERR_PTR(-EINVAL); 259 auth = ERR_PTR(-EINVAL);
260 if (flavor >= RPC_AUTH_MAXFLAVOR) 260 if (flavor >= RPC_AUTH_MAXFLAVOR)
@@ -269,7 +269,7 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
269 goto out; 269 goto out;
270 } 270 }
271 spin_unlock(&rpc_authflavor_lock); 271 spin_unlock(&rpc_authflavor_lock);
272 auth = ops->create(clnt, pseudoflavor); 272 auth = ops->create(args, clnt);
273 module_put(ops->owner); 273 module_put(ops->owner);
274 if (IS_ERR(auth)) 274 if (IS_ERR(auth))
275 return auth; 275 return auth;
@@ -343,6 +343,27 @@ out_nocache:
343EXPORT_SYMBOL_GPL(rpcauth_init_credcache); 343EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
344 344
345/* 345/*
346 * Setup a credential key lifetime timeout notification
347 */
348int
349rpcauth_key_timeout_notify(struct rpc_auth *auth, struct rpc_cred *cred)
350{
351 if (!cred->cr_auth->au_ops->key_timeout)
352 return 0;
353 return cred->cr_auth->au_ops->key_timeout(auth, cred);
354}
355EXPORT_SYMBOL_GPL(rpcauth_key_timeout_notify);
356
357bool
358rpcauth_cred_key_to_expire(struct rpc_cred *cred)
359{
360 if (!cred->cr_ops->crkey_to_expire)
361 return false;
362 return cred->cr_ops->crkey_to_expire(cred);
363}
364EXPORT_SYMBOL_GPL(rpcauth_cred_key_to_expire);
365
366/*
346 * Destroy a list of credentials 367 * Destroy a list of credentials
347 */ 368 */
348static inline 369static inline
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index b6badafc6494..f6d84be49050 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -89,6 +89,7 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
89 gcred->acred.uid = acred->uid; 89 gcred->acred.uid = acred->uid;
90 gcred->acred.gid = acred->gid; 90 gcred->acred.gid = acred->gid;
91 gcred->acred.group_info = acred->group_info; 91 gcred->acred.group_info = acred->group_info;
92 gcred->acred.ac_flags = 0;
92 if (gcred->acred.group_info != NULL) 93 if (gcred->acred.group_info != NULL)
93 get_group_info(gcred->acred.group_info); 94 get_group_info(gcred->acred.group_info);
94 gcred->acred.machine_cred = acred->machine_cred; 95 gcred->acred.machine_cred = acred->machine_cred;
@@ -182,11 +183,78 @@ void rpc_destroy_generic_auth(void)
182 rpcauth_destroy_credcache(&generic_auth); 183 rpcauth_destroy_credcache(&generic_auth);
183} 184}
184 185
186/*
187 * Test the the current time (now) against the underlying credential key expiry
188 * minus a timeout and setup notification.
189 *
190 * The normal case:
191 * If 'now' is before the key expiry minus RPC_KEY_EXPIRE_TIMEO, set
192 * the RPC_CRED_NOTIFY_TIMEOUT flag to setup the underlying credential
193 * rpc_credops crmatch routine to notify this generic cred when it's key
194 * expiration is within RPC_KEY_EXPIRE_TIMEO, and return 0.
195 *
196 * The error case:
197 * If the underlying cred lookup fails, return -EACCES.
198 *
199 * The 'almost' error case:
200 * If 'now' is within key expiry minus RPC_KEY_EXPIRE_TIMEO, but not within
201 * key expiry minus RPC_KEY_EXPIRE_FAIL, set the RPC_CRED_EXPIRE_SOON bit
202 * on the acred ac_flags and return 0.
203 */
204static int
205generic_key_timeout(struct rpc_auth *auth, struct rpc_cred *cred)
206{
207 struct auth_cred *acred = &container_of(cred, struct generic_cred,
208 gc_base)->acred;
209 struct rpc_cred *tcred;
210 int ret = 0;
211
212
213 /* Fast track for non crkey_timeout (no key) underlying credentials */
214 if (test_bit(RPC_CRED_NO_CRKEY_TIMEOUT, &acred->ac_flags))
215 return 0;
216
217 /* Fast track for the normal case */
218 if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags))
219 return 0;
220
221 /* lookup_cred either returns a valid referenced rpc_cred, or PTR_ERR */
222 tcred = auth->au_ops->lookup_cred(auth, acred, 0);
223 if (IS_ERR(tcred))
224 return -EACCES;
225
226 if (!tcred->cr_ops->crkey_timeout) {
227 set_bit(RPC_CRED_NO_CRKEY_TIMEOUT, &acred->ac_flags);
228 ret = 0;
229 goto out_put;
230 }
231
232 /* Test for the almost error case */
233 ret = tcred->cr_ops->crkey_timeout(tcred);
234 if (ret != 0) {
235 set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
236 ret = 0;
237 } else {
238 /* In case underlying cred key has been reset */
239 if (test_and_clear_bit(RPC_CRED_KEY_EXPIRE_SOON,
240 &acred->ac_flags))
241 dprintk("RPC: UID %d Credential key reset\n",
242 tcred->cr_uid);
243 /* set up fasttrack for the normal case */
244 set_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
245 }
246
247out_put:
248 put_rpccred(tcred);
249 return ret;
250}
251
185static const struct rpc_authops generic_auth_ops = { 252static const struct rpc_authops generic_auth_ops = {
186 .owner = THIS_MODULE, 253 .owner = THIS_MODULE,
187 .au_name = "Generic", 254 .au_name = "Generic",
188 .lookup_cred = generic_lookup_cred, 255 .lookup_cred = generic_lookup_cred,
189 .crcreate = generic_create_cred, 256 .crcreate = generic_create_cred,
257 .key_timeout = generic_key_timeout,
190}; 258};
191 259
192static struct rpc_auth generic_auth = { 260static struct rpc_auth generic_auth = {
@@ -194,9 +262,23 @@ static struct rpc_auth generic_auth = {
194 .au_count = ATOMIC_INIT(0), 262 .au_count = ATOMIC_INIT(0),
195}; 263};
196 264
265static bool generic_key_to_expire(struct rpc_cred *cred)
266{
267 struct auth_cred *acred = &container_of(cred, struct generic_cred,
268 gc_base)->acred;
269 bool ret;
270
271 get_rpccred(cred);
272 ret = test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
273 put_rpccred(cred);
274
275 return ret;
276}
277
197static const struct rpc_credops generic_credops = { 278static const struct rpc_credops generic_credops = {
198 .cr_name = "Generic cred", 279 .cr_name = "Generic cred",
199 .crdestroy = generic_destroy_cred, 280 .crdestroy = generic_destroy_cred,
200 .crbind = generic_bind_cred, 281 .crbind = generic_bind_cred,
201 .crmatch = generic_match, 282 .crmatch = generic_match,
283 .crkey_to_expire = generic_key_to_expire,
202}; 284};
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index fc2f78d6a9b4..30eb502135bb 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -51,6 +51,7 @@
51#include <linux/sunrpc/rpc_pipe_fs.h> 51#include <linux/sunrpc/rpc_pipe_fs.h>
52#include <linux/sunrpc/gss_api.h> 52#include <linux/sunrpc/gss_api.h>
53#include <asm/uaccess.h> 53#include <asm/uaccess.h>
54#include <linux/hashtable.h>
54 55
55#include "../netns.h" 56#include "../netns.h"
56 57
@@ -62,6 +63,9 @@ static const struct rpc_credops gss_nullops;
62#define GSS_RETRY_EXPIRED 5 63#define GSS_RETRY_EXPIRED 5
63static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED; 64static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
64 65
66#define GSS_KEY_EXPIRE_TIMEO 240
67static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
68
65#ifdef RPC_DEBUG 69#ifdef RPC_DEBUG
66# define RPCDBG_FACILITY RPCDBG_AUTH 70# define RPCDBG_FACILITY RPCDBG_AUTH
67#endif 71#endif
@@ -71,19 +75,33 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
71 * using integrity (two 4-byte integers): */ 75 * using integrity (two 4-byte integers): */
72#define GSS_VERF_SLACK 100 76#define GSS_VERF_SLACK 100
73 77
78static DEFINE_HASHTABLE(gss_auth_hash_table, 16);
79static DEFINE_SPINLOCK(gss_auth_hash_lock);
80
81struct gss_pipe {
82 struct rpc_pipe_dir_object pdo;
83 struct rpc_pipe *pipe;
84 struct rpc_clnt *clnt;
85 const char *name;
86 struct kref kref;
87};
88
74struct gss_auth { 89struct gss_auth {
75 struct kref kref; 90 struct kref kref;
91 struct hlist_node hash;
76 struct rpc_auth rpc_auth; 92 struct rpc_auth rpc_auth;
77 struct gss_api_mech *mech; 93 struct gss_api_mech *mech;
78 enum rpc_gss_svc service; 94 enum rpc_gss_svc service;
79 struct rpc_clnt *client; 95 struct rpc_clnt *client;
96 struct net *net;
80 /* 97 /*
81 * There are two upcall pipes; dentry[1], named "gssd", is used 98 * There are two upcall pipes; dentry[1], named "gssd", is used
82 * for the new text-based upcall; dentry[0] is named after the 99 * for the new text-based upcall; dentry[0] is named after the
83 * mechanism (for example, "krb5") and exists for 100 * mechanism (for example, "krb5") and exists for
84 * backwards-compatibility with older gssd's. 101 * backwards-compatibility with older gssd's.
85 */ 102 */
86 struct rpc_pipe *pipe[2]; 103 struct gss_pipe *gss_pipe[2];
104 const char *target_name;
87}; 105};
88 106
89/* pipe_version >= 0 if and only if someone has a pipe open. */ 107/* pipe_version >= 0 if and only if someone has a pipe open. */
@@ -294,7 +312,7 @@ static void put_pipe_version(struct net *net)
294static void 312static void
295gss_release_msg(struct gss_upcall_msg *gss_msg) 313gss_release_msg(struct gss_upcall_msg *gss_msg)
296{ 314{
297 struct net *net = rpc_net_ns(gss_msg->auth->client); 315 struct net *net = gss_msg->auth->net;
298 if (!atomic_dec_and_test(&gss_msg->count)) 316 if (!atomic_dec_and_test(&gss_msg->count))
299 return; 317 return;
300 put_pipe_version(net); 318 put_pipe_version(net);
@@ -406,8 +424,8 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
406} 424}
407 425
408static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, 426static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
409 struct rpc_clnt *clnt, 427 const char *service_name,
410 const char *service_name) 428 const char *target_name)
411{ 429{
412 struct gss_api_mech *mech = gss_msg->auth->mech; 430 struct gss_api_mech *mech = gss_msg->auth->mech;
413 char *p = gss_msg->databuf; 431 char *p = gss_msg->databuf;
@@ -417,8 +435,8 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
417 mech->gm_name, 435 mech->gm_name,
418 from_kuid(&init_user_ns, gss_msg->uid)); 436 from_kuid(&init_user_ns, gss_msg->uid));
419 p += gss_msg->msg.len; 437 p += gss_msg->msg.len;
420 if (clnt->cl_principal) { 438 if (target_name) {
421 len = sprintf(p, "target=%s ", clnt->cl_principal); 439 len = sprintf(p, "target=%s ", target_name);
422 p += len; 440 p += len;
423 gss_msg->msg.len += len; 441 gss_msg->msg.len += len;
424 } 442 }
@@ -439,21 +457,8 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
439 BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN); 457 BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN);
440} 458}
441 459
442static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
443 struct rpc_clnt *clnt,
444 const char *service_name)
445{
446 struct net *net = rpc_net_ns(clnt);
447 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
448
449 if (sn->pipe_version == 0)
450 gss_encode_v0_msg(gss_msg);
451 else /* pipe_version == 1 */
452 gss_encode_v1_msg(gss_msg, clnt, service_name);
453}
454
455static struct gss_upcall_msg * 460static struct gss_upcall_msg *
456gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, 461gss_alloc_msg(struct gss_auth *gss_auth,
457 kuid_t uid, const char *service_name) 462 kuid_t uid, const char *service_name)
458{ 463{
459 struct gss_upcall_msg *gss_msg; 464 struct gss_upcall_msg *gss_msg;
@@ -462,31 +467,36 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
462 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); 467 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
463 if (gss_msg == NULL) 468 if (gss_msg == NULL)
464 return ERR_PTR(-ENOMEM); 469 return ERR_PTR(-ENOMEM);
465 vers = get_pipe_version(rpc_net_ns(clnt)); 470 vers = get_pipe_version(gss_auth->net);
466 if (vers < 0) { 471 if (vers < 0) {
467 kfree(gss_msg); 472 kfree(gss_msg);
468 return ERR_PTR(vers); 473 return ERR_PTR(vers);
469 } 474 }
470 gss_msg->pipe = gss_auth->pipe[vers]; 475 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe;
471 INIT_LIST_HEAD(&gss_msg->list); 476 INIT_LIST_HEAD(&gss_msg->list);
472 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); 477 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
473 init_waitqueue_head(&gss_msg->waitqueue); 478 init_waitqueue_head(&gss_msg->waitqueue);
474 atomic_set(&gss_msg->count, 1); 479 atomic_set(&gss_msg->count, 1);
475 gss_msg->uid = uid; 480 gss_msg->uid = uid;
476 gss_msg->auth = gss_auth; 481 gss_msg->auth = gss_auth;
477 gss_encode_msg(gss_msg, clnt, service_name); 482 switch (vers) {
483 case 0:
484 gss_encode_v0_msg(gss_msg);
485 default:
486 gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
487 };
478 return gss_msg; 488 return gss_msg;
479} 489}
480 490
481static struct gss_upcall_msg * 491static struct gss_upcall_msg *
482gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cred *cred) 492gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
483{ 493{
484 struct gss_cred *gss_cred = container_of(cred, 494 struct gss_cred *gss_cred = container_of(cred,
485 struct gss_cred, gc_base); 495 struct gss_cred, gc_base);
486 struct gss_upcall_msg *gss_new, *gss_msg; 496 struct gss_upcall_msg *gss_new, *gss_msg;
487 kuid_t uid = cred->cr_uid; 497 kuid_t uid = cred->cr_uid;
488 498
489 gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal); 499 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal);
490 if (IS_ERR(gss_new)) 500 if (IS_ERR(gss_new))
491 return gss_new; 501 return gss_new;
492 gss_msg = gss_add_msg(gss_new); 502 gss_msg = gss_add_msg(gss_new);
@@ -527,7 +537,7 @@ gss_refresh_upcall(struct rpc_task *task)
527 537
528 dprintk("RPC: %5u %s for uid %u\n", 538 dprintk("RPC: %5u %s for uid %u\n",
529 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid)); 539 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
530 gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); 540 gss_msg = gss_setup_upcall(gss_auth, cred);
531 if (PTR_ERR(gss_msg) == -EAGAIN) { 541 if (PTR_ERR(gss_msg) == -EAGAIN) {
532 /* XXX: warning on the first, under the assumption we 542 /* XXX: warning on the first, under the assumption we
533 * shouldn't normally hit this case on a refresh. */ 543 * shouldn't normally hit this case on a refresh. */
@@ -566,7 +576,7 @@ out:
566static inline int 576static inline int
567gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 577gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
568{ 578{
569 struct net *net = rpc_net_ns(gss_auth->client); 579 struct net *net = gss_auth->net;
570 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 580 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
571 struct rpc_pipe *pipe; 581 struct rpc_pipe *pipe;
572 struct rpc_cred *cred = &gss_cred->gc_base; 582 struct rpc_cred *cred = &gss_cred->gc_base;
@@ -583,7 +593,7 @@ retry:
583 timeout = 15 * HZ; 593 timeout = 15 * HZ;
584 if (!sn->gssd_running) 594 if (!sn->gssd_running)
585 timeout = HZ >> 2; 595 timeout = HZ >> 2;
586 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 596 gss_msg = gss_setup_upcall(gss_auth, cred);
587 if (PTR_ERR(gss_msg) == -EAGAIN) { 597 if (PTR_ERR(gss_msg) == -EAGAIN) {
588 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 598 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
589 sn->pipe_version >= 0, timeout); 599 sn->pipe_version >= 0, timeout);
@@ -797,83 +807,153 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
797 } 807 }
798} 808}
799 809
800static void gss_pipes_dentries_destroy(struct rpc_auth *auth) 810static void gss_pipe_dentry_destroy(struct dentry *dir,
811 struct rpc_pipe_dir_object *pdo)
801{ 812{
802 struct gss_auth *gss_auth; 813 struct gss_pipe *gss_pipe = pdo->pdo_data;
814 struct rpc_pipe *pipe = gss_pipe->pipe;
803 815
804 gss_auth = container_of(auth, struct gss_auth, rpc_auth); 816 if (pipe->dentry != NULL) {
805 if (gss_auth->pipe[0]->dentry) 817 rpc_unlink(pipe->dentry);
806 rpc_unlink(gss_auth->pipe[0]->dentry); 818 pipe->dentry = NULL;
807 if (gss_auth->pipe[1]->dentry) 819 }
808 rpc_unlink(gss_auth->pipe[1]->dentry);
809} 820}
810 821
811static int gss_pipes_dentries_create(struct rpc_auth *auth) 822static int gss_pipe_dentry_create(struct dentry *dir,
823 struct rpc_pipe_dir_object *pdo)
812{ 824{
813 int err; 825 struct gss_pipe *p = pdo->pdo_data;
814 struct gss_auth *gss_auth; 826 struct dentry *dentry;
815 struct rpc_clnt *clnt;
816 827
817 gss_auth = container_of(auth, struct gss_auth, rpc_auth); 828 dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe);
818 clnt = gss_auth->client; 829 if (IS_ERR(dentry))
819 830 return PTR_ERR(dentry);
820 gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, 831 p->pipe->dentry = dentry;
821 "gssd",
822 clnt, gss_auth->pipe[1]);
823 if (IS_ERR(gss_auth->pipe[1]->dentry))
824 return PTR_ERR(gss_auth->pipe[1]->dentry);
825 gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
826 gss_auth->mech->gm_name,
827 clnt, gss_auth->pipe[0]);
828 if (IS_ERR(gss_auth->pipe[0]->dentry)) {
829 err = PTR_ERR(gss_auth->pipe[0]->dentry);
830 goto err_unlink_pipe_1;
831 }
832 return 0; 832 return 0;
833}
833 834
834err_unlink_pipe_1: 835static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = {
835 rpc_unlink(gss_auth->pipe[1]->dentry); 836 .create = gss_pipe_dentry_create,
836 return err; 837 .destroy = gss_pipe_dentry_destroy,
838};
839
840static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt,
841 const char *name,
842 const struct rpc_pipe_ops *upcall_ops)
843{
844 struct gss_pipe *p;
845 int err = -ENOMEM;
846
847 p = kmalloc(sizeof(*p), GFP_KERNEL);
848 if (p == NULL)
849 goto err;
850 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
851 if (IS_ERR(p->pipe)) {
852 err = PTR_ERR(p->pipe);
853 goto err_free_gss_pipe;
854 }
855 p->name = name;
856 p->clnt = clnt;
857 kref_init(&p->kref);
858 rpc_init_pipe_dir_object(&p->pdo,
859 &gss_pipe_dir_object_ops,
860 p);
861 return p;
862err_free_gss_pipe:
863 kfree(p);
864err:
865 return ERR_PTR(err);
866}
867
868struct gss_alloc_pdo {
869 struct rpc_clnt *clnt;
870 const char *name;
871 const struct rpc_pipe_ops *upcall_ops;
872};
873
874static int gss_pipe_match_pdo(struct rpc_pipe_dir_object *pdo, void *data)
875{
876 struct gss_pipe *gss_pipe;
877 struct gss_alloc_pdo *args = data;
878
879 if (pdo->pdo_ops != &gss_pipe_dir_object_ops)
880 return 0;
881 gss_pipe = container_of(pdo, struct gss_pipe, pdo);
882 if (strcmp(gss_pipe->name, args->name) != 0)
883 return 0;
884 if (!kref_get_unless_zero(&gss_pipe->kref))
885 return 0;
886 return 1;
837} 887}
838 888
839static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt, 889static struct rpc_pipe_dir_object *gss_pipe_alloc_pdo(void *data)
840 struct rpc_auth *auth) 890{
891 struct gss_pipe *gss_pipe;
892 struct gss_alloc_pdo *args = data;
893
894 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops);
895 if (!IS_ERR(gss_pipe))
896 return &gss_pipe->pdo;
897 return NULL;
898}
899
900static struct gss_pipe *gss_pipe_get(struct rpc_clnt *clnt,
901 const char *name,
902 const struct rpc_pipe_ops *upcall_ops)
841{ 903{
842 struct net *net = rpc_net_ns(clnt); 904 struct net *net = rpc_net_ns(clnt);
843 struct super_block *sb; 905 struct rpc_pipe_dir_object *pdo;
906 struct gss_alloc_pdo args = {
907 .clnt = clnt,
908 .name = name,
909 .upcall_ops = upcall_ops,
910 };
844 911
845 sb = rpc_get_sb_net(net); 912 pdo = rpc_find_or_alloc_pipe_dir_object(net,
846 if (sb) { 913 &clnt->cl_pipedir_objects,
847 if (clnt->cl_dentry) 914 gss_pipe_match_pdo,
848 gss_pipes_dentries_destroy(auth); 915 gss_pipe_alloc_pdo,
849 rpc_put_sb_net(net); 916 &args);
850 } 917 if (pdo != NULL)
918 return container_of(pdo, struct gss_pipe, pdo);
919 return ERR_PTR(-ENOMEM);
851} 920}
852 921
853static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt, 922static void __gss_pipe_free(struct gss_pipe *p)
854 struct rpc_auth *auth)
855{ 923{
924 struct rpc_clnt *clnt = p->clnt;
856 struct net *net = rpc_net_ns(clnt); 925 struct net *net = rpc_net_ns(clnt);
857 struct super_block *sb;
858 int err = 0;
859 926
860 sb = rpc_get_sb_net(net); 927 rpc_remove_pipe_dir_object(net,
861 if (sb) { 928 &clnt->cl_pipedir_objects,
862 if (clnt->cl_dentry) 929 &p->pdo);
863 err = gss_pipes_dentries_create(auth); 930 rpc_destroy_pipe_data(p->pipe);
864 rpc_put_sb_net(net); 931 kfree(p);
865 } 932}
866 return err; 933
934static void __gss_pipe_release(struct kref *kref)
935{
936 struct gss_pipe *p = container_of(kref, struct gss_pipe, kref);
937
938 __gss_pipe_free(p);
939}
940
941static void gss_pipe_free(struct gss_pipe *p)
942{
943 if (p != NULL)
944 kref_put(&p->kref, __gss_pipe_release);
867} 945}
868 946
869/* 947/*
870 * NOTE: we have the opportunity to use different 948 * NOTE: we have the opportunity to use different
871 * parameters based on the input flavor (which must be a pseudoflavor) 949 * parameters based on the input flavor (which must be a pseudoflavor)
872 */ 950 */
873static struct rpc_auth * 951static struct gss_auth *
874gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) 952gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
875{ 953{
954 rpc_authflavor_t flavor = args->pseudoflavor;
876 struct gss_auth *gss_auth; 955 struct gss_auth *gss_auth;
956 struct gss_pipe *gss_pipe;
877 struct rpc_auth * auth; 957 struct rpc_auth * auth;
878 int err = -ENOMEM; /* XXX? */ 958 int err = -ENOMEM; /* XXX? */
879 959
@@ -883,12 +963,20 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
883 return ERR_PTR(err); 963 return ERR_PTR(err);
884 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) 964 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
885 goto out_dec; 965 goto out_dec;
966 INIT_HLIST_NODE(&gss_auth->hash);
967 gss_auth->target_name = NULL;
968 if (args->target_name) {
969 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL);
970 if (gss_auth->target_name == NULL)
971 goto err_free;
972 }
886 gss_auth->client = clnt; 973 gss_auth->client = clnt;
974 gss_auth->net = get_net(rpc_net_ns(clnt));
887 err = -EINVAL; 975 err = -EINVAL;
888 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); 976 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
889 if (!gss_auth->mech) { 977 if (!gss_auth->mech) {
890 dprintk("RPC: Pseudoflavor %d not found!\n", flavor); 978 dprintk("RPC: Pseudoflavor %d not found!\n", flavor);
891 goto err_free; 979 goto err_put_net;
892 } 980 }
893 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); 981 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
894 if (gss_auth->service == 0) 982 if (gss_auth->service == 0)
@@ -901,42 +989,41 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
901 atomic_set(&auth->au_count, 1); 989 atomic_set(&auth->au_count, 1);
902 kref_init(&gss_auth->kref); 990 kref_init(&gss_auth->kref);
903 991
992 err = rpcauth_init_credcache(auth);
993 if (err)
994 goto err_put_mech;
904 /* 995 /*
905 * Note: if we created the old pipe first, then someone who 996 * Note: if we created the old pipe first, then someone who
906 * examined the directory at the right moment might conclude 997 * examined the directory at the right moment might conclude
907 * that we supported only the old pipe. So we instead create 998 * that we supported only the old pipe. So we instead create
908 * the new pipe first. 999 * the new pipe first.
909 */ 1000 */
910 gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1, 1001 gss_pipe = gss_pipe_get(clnt, "gssd", &gss_upcall_ops_v1);
911 RPC_PIPE_WAIT_FOR_OPEN); 1002 if (IS_ERR(gss_pipe)) {
912 if (IS_ERR(gss_auth->pipe[1])) { 1003 err = PTR_ERR(gss_pipe);
913 err = PTR_ERR(gss_auth->pipe[1]); 1004 goto err_destroy_credcache;
914 goto err_put_mech;
915 } 1005 }
1006 gss_auth->gss_pipe[1] = gss_pipe;
916 1007
917 gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0, 1008 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name,
918 RPC_PIPE_WAIT_FOR_OPEN); 1009 &gss_upcall_ops_v0);
919 if (IS_ERR(gss_auth->pipe[0])) { 1010 if (IS_ERR(gss_pipe)) {
920 err = PTR_ERR(gss_auth->pipe[0]); 1011 err = PTR_ERR(gss_pipe);
921 goto err_destroy_pipe_1; 1012 goto err_destroy_pipe_1;
922 } 1013 }
923 err = gss_pipes_dentries_create_net(clnt, auth); 1014 gss_auth->gss_pipe[0] = gss_pipe;
924 if (err)
925 goto err_destroy_pipe_0;
926 err = rpcauth_init_credcache(auth);
927 if (err)
928 goto err_unlink_pipes;
929 1015
930 return auth; 1016 return gss_auth;
931err_unlink_pipes:
932 gss_pipes_dentries_destroy_net(clnt, auth);
933err_destroy_pipe_0:
934 rpc_destroy_pipe_data(gss_auth->pipe[0]);
935err_destroy_pipe_1: 1017err_destroy_pipe_1:
936 rpc_destroy_pipe_data(gss_auth->pipe[1]); 1018 gss_pipe_free(gss_auth->gss_pipe[1]);
1019err_destroy_credcache:
1020 rpcauth_destroy_credcache(auth);
937err_put_mech: 1021err_put_mech:
938 gss_mech_put(gss_auth->mech); 1022 gss_mech_put(gss_auth->mech);
1023err_put_net:
1024 put_net(gss_auth->net);
939err_free: 1025err_free:
1026 kfree(gss_auth->target_name);
940 kfree(gss_auth); 1027 kfree(gss_auth);
941out_dec: 1028out_dec:
942 module_put(THIS_MODULE); 1029 module_put(THIS_MODULE);
@@ -946,10 +1033,11 @@ out_dec:
946static void 1033static void
947gss_free(struct gss_auth *gss_auth) 1034gss_free(struct gss_auth *gss_auth)
948{ 1035{
949 gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth); 1036 gss_pipe_free(gss_auth->gss_pipe[0]);
950 rpc_destroy_pipe_data(gss_auth->pipe[0]); 1037 gss_pipe_free(gss_auth->gss_pipe[1]);
951 rpc_destroy_pipe_data(gss_auth->pipe[1]);
952 gss_mech_put(gss_auth->mech); 1038 gss_mech_put(gss_auth->mech);
1039 put_net(gss_auth->net);
1040 kfree(gss_auth->target_name);
953 1041
954 kfree(gss_auth); 1042 kfree(gss_auth);
955 module_put(THIS_MODULE); 1043 module_put(THIS_MODULE);
@@ -966,17 +1054,101 @@ gss_free_callback(struct kref *kref)
966static void 1054static void
967gss_destroy(struct rpc_auth *auth) 1055gss_destroy(struct rpc_auth *auth)
968{ 1056{
969 struct gss_auth *gss_auth; 1057 struct gss_auth *gss_auth = container_of(auth,
1058 struct gss_auth, rpc_auth);
970 1059
971 dprintk("RPC: destroying GSS authenticator %p flavor %d\n", 1060 dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
972 auth, auth->au_flavor); 1061 auth, auth->au_flavor);
973 1062
1063 if (hash_hashed(&gss_auth->hash)) {
1064 spin_lock(&gss_auth_hash_lock);
1065 hash_del(&gss_auth->hash);
1066 spin_unlock(&gss_auth_hash_lock);
1067 }
1068
1069 gss_pipe_free(gss_auth->gss_pipe[0]);
1070 gss_auth->gss_pipe[0] = NULL;
1071 gss_pipe_free(gss_auth->gss_pipe[1]);
1072 gss_auth->gss_pipe[1] = NULL;
974 rpcauth_destroy_credcache(auth); 1073 rpcauth_destroy_credcache(auth);
975 1074
976 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
977 kref_put(&gss_auth->kref, gss_free_callback); 1075 kref_put(&gss_auth->kref, gss_free_callback);
978} 1076}
979 1077
1078static struct gss_auth *
1079gss_auth_find_or_add_hashed(struct rpc_auth_create_args *args,
1080 struct rpc_clnt *clnt,
1081 struct gss_auth *new)
1082{
1083 struct gss_auth *gss_auth;
1084 unsigned long hashval = (unsigned long)clnt;
1085
1086 spin_lock(&gss_auth_hash_lock);
1087 hash_for_each_possible(gss_auth_hash_table,
1088 gss_auth,
1089 hash,
1090 hashval) {
1091 if (gss_auth->rpc_auth.au_flavor != args->pseudoflavor)
1092 continue;
1093 if (gss_auth->target_name != args->target_name) {
1094 if (gss_auth->target_name == NULL)
1095 continue;
1096 if (args->target_name == NULL)
1097 continue;
1098 if (strcmp(gss_auth->target_name, args->target_name))
1099 continue;
1100 }
1101 if (!atomic_inc_not_zero(&gss_auth->rpc_auth.au_count))
1102 continue;
1103 goto out;
1104 }
1105 if (new)
1106 hash_add(gss_auth_hash_table, &new->hash, hashval);
1107 gss_auth = new;
1108out:
1109 spin_unlock(&gss_auth_hash_lock);
1110 return gss_auth;
1111}
1112
1113static struct gss_auth *
1114gss_create_hashed(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1115{
1116 struct gss_auth *gss_auth;
1117 struct gss_auth *new;
1118
1119 gss_auth = gss_auth_find_or_add_hashed(args, clnt, NULL);
1120 if (gss_auth != NULL)
1121 goto out;
1122 new = gss_create_new(args, clnt);
1123 if (IS_ERR(new))
1124 return new;
1125 gss_auth = gss_auth_find_or_add_hashed(args, clnt, new);
1126 if (gss_auth != new)
1127 gss_destroy(&new->rpc_auth);
1128out:
1129 return gss_auth;
1130}
1131
1132static struct rpc_auth *
1133gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1134{
1135 struct gss_auth *gss_auth;
1136 struct rpc_xprt *xprt = rcu_access_pointer(clnt->cl_xprt);
1137
1138 while (clnt != clnt->cl_parent) {
1139 struct rpc_clnt *parent = clnt->cl_parent;
1140 /* Find the original parent for this transport */
1141 if (rcu_access_pointer(parent->cl_xprt) != xprt)
1142 break;
1143 clnt = parent;
1144 }
1145
1146 gss_auth = gss_create_hashed(args, clnt);
1147 if (IS_ERR(gss_auth))
1148 return ERR_CAST(gss_auth);
1149 return &gss_auth->rpc_auth;
1150}
1151
980/* 1152/*
981 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call 1153 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
982 * to the server with the GSS control procedure field set to 1154 * to the server with the GSS control procedure field set to
@@ -1126,10 +1298,32 @@ gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
1126 return err; 1298 return err;
1127} 1299}
1128 1300
1301/*
1302 * Returns -EACCES if GSS context is NULL or will expire within the
1303 * timeout (miliseconds)
1304 */
1305static int
1306gss_key_timeout(struct rpc_cred *rc)
1307{
1308 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1309 unsigned long now = jiffies;
1310 unsigned long expire;
1311
1312 if (gss_cred->gc_ctx == NULL)
1313 return -EACCES;
1314
1315 expire = gss_cred->gc_ctx->gc_expiry - (gss_key_expire_timeo * HZ);
1316
1317 if (time_after(now, expire))
1318 return -EACCES;
1319 return 0;
1320}
1321
1129static int 1322static int
1130gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) 1323gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
1131{ 1324{
1132 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 1325 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1326 int ret;
1133 1327
1134 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) 1328 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
1135 goto out; 1329 goto out;
@@ -1142,11 +1336,26 @@ out:
1142 if (acred->principal != NULL) { 1336 if (acred->principal != NULL) {
1143 if (gss_cred->gc_principal == NULL) 1337 if (gss_cred->gc_principal == NULL)
1144 return 0; 1338 return 0;
1145 return strcmp(acred->principal, gss_cred->gc_principal) == 0; 1339 ret = strcmp(acred->principal, gss_cred->gc_principal) == 0;
1340 goto check_expire;
1146 } 1341 }
1147 if (gss_cred->gc_principal != NULL) 1342 if (gss_cred->gc_principal != NULL)
1148 return 0; 1343 return 0;
1149 return uid_eq(rc->cr_uid, acred->uid); 1344 ret = uid_eq(rc->cr_uid, acred->uid);
1345
1346check_expire:
1347 if (ret == 0)
1348 return ret;
1349
1350 /* Notify acred users of GSS context expiration timeout */
1351 if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags) &&
1352 (gss_key_timeout(rc) != 0)) {
1353 /* test will now be done from generic cred */
1354 test_and_clear_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
1355 /* tell NFS layer that key will expire soon */
1356 set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
1357 }
1358 return ret;
1150} 1359}
1151 1360
1152/* 1361/*
@@ -1292,6 +1501,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
1292 struct xdr_netobj mic; 1501 struct xdr_netobj mic;
1293 u32 flav,len; 1502 u32 flav,len;
1294 u32 maj_stat; 1503 u32 maj_stat;
1504 __be32 *ret = ERR_PTR(-EIO);
1295 1505
1296 dprintk("RPC: %5u %s\n", task->tk_pid, __func__); 1506 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1297 1507
@@ -1307,6 +1517,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
1307 mic.data = (u8 *)p; 1517 mic.data = (u8 *)p;
1308 mic.len = len; 1518 mic.len = len;
1309 1519
1520 ret = ERR_PTR(-EACCES);
1310 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 1521 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1311 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1522 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1312 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1523 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
@@ -1324,8 +1535,9 @@ gss_validate(struct rpc_task *task, __be32 *p)
1324 return p + XDR_QUADLEN(len); 1535 return p + XDR_QUADLEN(len);
1325out_bad: 1536out_bad:
1326 gss_put_ctx(ctx); 1537 gss_put_ctx(ctx);
1327 dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__); 1538 dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
1328 return NULL; 1539 PTR_ERR(ret));
1540 return ret;
1329} 1541}
1330 1542
1331static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, 1543static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
@@ -1657,8 +1869,6 @@ static const struct rpc_authops authgss_ops = {
1657 .destroy = gss_destroy, 1869 .destroy = gss_destroy,
1658 .lookup_cred = gss_lookup_cred, 1870 .lookup_cred = gss_lookup_cred,
1659 .crcreate = gss_create_cred, 1871 .crcreate = gss_create_cred,
1660 .pipes_create = gss_pipes_dentries_create,
1661 .pipes_destroy = gss_pipes_dentries_destroy,
1662 .list_pseudoflavors = gss_mech_list_pseudoflavors, 1872 .list_pseudoflavors = gss_mech_list_pseudoflavors,
1663 .info2flavor = gss_mech_info2flavor, 1873 .info2flavor = gss_mech_info2flavor,
1664 .flavor2info = gss_mech_flavor2info, 1874 .flavor2info = gss_mech_flavor2info,
@@ -1675,6 +1885,7 @@ static const struct rpc_credops gss_credops = {
1675 .crvalidate = gss_validate, 1885 .crvalidate = gss_validate,
1676 .crwrap_req = gss_wrap_req, 1886 .crwrap_req = gss_wrap_req,
1677 .crunwrap_resp = gss_unwrap_resp, 1887 .crunwrap_resp = gss_unwrap_resp,
1888 .crkey_timeout = gss_key_timeout,
1678}; 1889};
1679 1890
1680static const struct rpc_credops gss_nullops = { 1891static const struct rpc_credops gss_nullops = {
@@ -1762,5 +1973,12 @@ module_param_named(expired_cred_retry_delay,
1762MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until " 1973MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until "
1763 "the RPC engine retries an expired credential"); 1974 "the RPC engine retries an expired credential");
1764 1975
1976module_param_named(key_expire_timeo,
1977 gss_key_expire_timeo,
1978 uint, 0644);
1979MODULE_PARM_DESC(key_expire_timeo, "Time (in seconds) at the end of a "
1980 "credential keys lifetime where the NFS layer cleans up "
1981 "prior to key expiration");
1982
1765module_init(init_rpcsec_gss) 1983module_init(init_rpcsec_gss)
1766module_exit(exit_rpcsec_gss) 1984module_exit(exit_rpcsec_gss)
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index a5c36c01707b..f0ebe07978a2 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -18,7 +18,7 @@ static struct rpc_auth null_auth;
18static struct rpc_cred null_cred; 18static struct rpc_cred null_cred;
19 19
20static struct rpc_auth * 20static struct rpc_auth *
21nul_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) 21nul_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
22{ 22{
23 atomic_inc(&null_auth.au_count); 23 atomic_inc(&null_auth.au_count);
24 return &null_auth; 24 return &null_auth;
@@ -88,13 +88,13 @@ nul_validate(struct rpc_task *task, __be32 *p)
88 flavor = ntohl(*p++); 88 flavor = ntohl(*p++);
89 if (flavor != RPC_AUTH_NULL) { 89 if (flavor != RPC_AUTH_NULL) {
90 printk("RPC: bad verf flavor: %u\n", flavor); 90 printk("RPC: bad verf flavor: %u\n", flavor);
91 return NULL; 91 return ERR_PTR(-EIO);
92 } 92 }
93 93
94 size = ntohl(*p++); 94 size = ntohl(*p++);
95 if (size != 0) { 95 if (size != 0) {
96 printk("RPC: bad verf size: %u\n", size); 96 printk("RPC: bad verf size: %u\n", size);
97 return NULL; 97 return ERR_PTR(-EIO);
98 } 98 }
99 99
100 return p; 100 return p;
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index dc37021fc3e5..d5d692366294 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -33,7 +33,7 @@ static struct rpc_auth unix_auth;
33static const struct rpc_credops unix_credops; 33static const struct rpc_credops unix_credops;
34 34
35static struct rpc_auth * 35static struct rpc_auth *
36unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) 36unx_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
37{ 37{
38 dprintk("RPC: creating UNIX authenticator for client %p\n", 38 dprintk("RPC: creating UNIX authenticator for client %p\n",
39 clnt); 39 clnt);
@@ -192,13 +192,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
192 flavor != RPC_AUTH_UNIX && 192 flavor != RPC_AUTH_UNIX &&
193 flavor != RPC_AUTH_SHORT) { 193 flavor != RPC_AUTH_SHORT) {
194 printk("RPC: bad verf flavor: %u\n", flavor); 194 printk("RPC: bad verf flavor: %u\n", flavor);
195 return NULL; 195 return ERR_PTR(-EIO);
196 } 196 }
197 197
198 size = ntohl(*p++); 198 size = ntohl(*p++);
199 if (size > RPC_MAX_AUTH_SIZE) { 199 if (size > RPC_MAX_AUTH_SIZE) {
200 printk("RPC: giant verf size: %u\n", size); 200 printk("RPC: giant verf size: %u\n", size);
201 return NULL; 201 return ERR_PTR(-EIO);
202 } 202 }
203 task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2; 203 task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
204 p += (size >> 2); 204 p += (size >> 2);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index ecbc4e3d83ad..77479606a971 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -102,12 +102,7 @@ static void rpc_unregister_client(struct rpc_clnt *clnt)
102 102
103static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) 103static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
104{ 104{
105 if (clnt->cl_dentry) { 105 rpc_remove_client_dir(clnt);
106 if (clnt->cl_auth && clnt->cl_auth->au_ops->pipes_destroy)
107 clnt->cl_auth->au_ops->pipes_destroy(clnt->cl_auth);
108 rpc_remove_client_dir(clnt->cl_dentry);
109 }
110 clnt->cl_dentry = NULL;
111} 106}
112 107
113static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) 108static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
@@ -123,10 +118,10 @@ static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
123} 118}
124 119
125static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb, 120static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
126 struct rpc_clnt *clnt, 121 struct rpc_clnt *clnt)
127 const char *dir_name)
128{ 122{
129 static uint32_t clntid; 123 static uint32_t clntid;
124 const char *dir_name = clnt->cl_program->pipe_dir_name;
130 char name[15]; 125 char name[15];
131 struct dentry *dir, *dentry; 126 struct dentry *dir, *dentry;
132 127
@@ -153,28 +148,35 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
153} 148}
154 149
155static int 150static int
156rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name, 151rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt)
157 struct super_block *pipefs_sb)
158{ 152{
159 struct dentry *dentry; 153 struct dentry *dentry;
160 154
161 clnt->cl_dentry = NULL; 155 if (clnt->cl_program->pipe_dir_name != NULL) {
162 if (dir_name == NULL) 156 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt);
163 return 0; 157 if (IS_ERR(dentry))
164 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name); 158 return PTR_ERR(dentry);
165 if (IS_ERR(dentry)) 159 }
166 return PTR_ERR(dentry);
167 clnt->cl_dentry = dentry;
168 return 0; 160 return 0;
169} 161}
170 162
171static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) 163static int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
172{ 164{
173 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || 165 if (clnt->cl_program->pipe_dir_name == NULL)
174 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
175 return 1;
176 if ((event == RPC_PIPEFS_MOUNT) && atomic_read(&clnt->cl_count) == 0)
177 return 1; 166 return 1;
167
168 switch (event) {
169 case RPC_PIPEFS_MOUNT:
170 if (clnt->cl_pipedir_objects.pdh_dentry != NULL)
171 return 1;
172 if (atomic_read(&clnt->cl_count) == 0)
173 return 1;
174 break;
175 case RPC_PIPEFS_UMOUNT:
176 if (clnt->cl_pipedir_objects.pdh_dentry == NULL)
177 return 1;
178 break;
179 }
178 return 0; 180 return 0;
179} 181}
180 182
@@ -186,18 +188,11 @@ static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event,
186 188
187 switch (event) { 189 switch (event) {
188 case RPC_PIPEFS_MOUNT: 190 case RPC_PIPEFS_MOUNT:
189 dentry = rpc_setup_pipedir_sb(sb, clnt, 191 dentry = rpc_setup_pipedir_sb(sb, clnt);
190 clnt->cl_program->pipe_dir_name);
191 if (!dentry) 192 if (!dentry)
192 return -ENOENT; 193 return -ENOENT;
193 if (IS_ERR(dentry)) 194 if (IS_ERR(dentry))
194 return PTR_ERR(dentry); 195 return PTR_ERR(dentry);
195 clnt->cl_dentry = dentry;
196 if (clnt->cl_auth->au_ops->pipes_create) {
197 err = clnt->cl_auth->au_ops->pipes_create(clnt->cl_auth);
198 if (err)
199 __rpc_clnt_remove_pipedir(clnt);
200 }
201 break; 196 break;
202 case RPC_PIPEFS_UMOUNT: 197 case RPC_PIPEFS_UMOUNT:
203 __rpc_clnt_remove_pipedir(clnt); 198 __rpc_clnt_remove_pipedir(clnt);
@@ -230,8 +225,6 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
230 225
231 spin_lock(&sn->rpc_client_lock); 226 spin_lock(&sn->rpc_client_lock);
232 list_for_each_entry(clnt, &sn->all_clients, cl_clients) { 227 list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
233 if (clnt->cl_program->pipe_dir_name == NULL)
234 continue;
235 if (rpc_clnt_skip_event(clnt, event)) 228 if (rpc_clnt_skip_event(clnt, event))
236 continue; 229 continue;
237 spin_unlock(&sn->rpc_client_lock); 230 spin_unlock(&sn->rpc_client_lock);
@@ -282,7 +275,10 @@ static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
282static int rpc_client_register(const struct rpc_create_args *args, 275static int rpc_client_register(const struct rpc_create_args *args,
283 struct rpc_clnt *clnt) 276 struct rpc_clnt *clnt)
284{ 277{
285 const struct rpc_program *program = args->program; 278 struct rpc_auth_create_args auth_args = {
279 .pseudoflavor = args->authflavor,
280 .target_name = args->client_name,
281 };
286 struct rpc_auth *auth; 282 struct rpc_auth *auth;
287 struct net *net = rpc_net_ns(clnt); 283 struct net *net = rpc_net_ns(clnt);
288 struct super_block *pipefs_sb; 284 struct super_block *pipefs_sb;
@@ -290,7 +286,7 @@ static int rpc_client_register(const struct rpc_create_args *args,
290 286
291 pipefs_sb = rpc_get_sb_net(net); 287 pipefs_sb = rpc_get_sb_net(net);
292 if (pipefs_sb) { 288 if (pipefs_sb) {
293 err = rpc_setup_pipedir(clnt, program->pipe_dir_name, pipefs_sb); 289 err = rpc_setup_pipedir(pipefs_sb, clnt);
294 if (err) 290 if (err)
295 goto out; 291 goto out;
296 } 292 }
@@ -299,7 +295,7 @@ static int rpc_client_register(const struct rpc_create_args *args,
299 if (pipefs_sb) 295 if (pipefs_sb)
300 rpc_put_sb_net(net); 296 rpc_put_sb_net(net);
301 297
302 auth = rpcauth_create(args->authflavor, clnt); 298 auth = rpcauth_create(&auth_args, clnt);
303 if (IS_ERR(auth)) { 299 if (IS_ERR(auth)) {
304 dprintk("RPC: Couldn't create auth handle (flavor %u)\n", 300 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
305 args->authflavor); 301 args->authflavor);
@@ -317,7 +313,27 @@ out:
317 return err; 313 return err;
318} 314}
319 315
320static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) 316static DEFINE_IDA(rpc_clids);
317
318static int rpc_alloc_clid(struct rpc_clnt *clnt)
319{
320 int clid;
321
322 clid = ida_simple_get(&rpc_clids, 0, 0, GFP_KERNEL);
323 if (clid < 0)
324 return clid;
325 clnt->cl_clid = clid;
326 return 0;
327}
328
329static void rpc_free_clid(struct rpc_clnt *clnt)
330{
331 ida_simple_remove(&rpc_clids, clnt->cl_clid);
332}
333
334static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
335 struct rpc_xprt *xprt,
336 struct rpc_clnt *parent)
321{ 337{
322 const struct rpc_program *program = args->program; 338 const struct rpc_program *program = args->program;
323 const struct rpc_version *version; 339 const struct rpc_version *version;
@@ -343,16 +359,20 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
343 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); 359 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
344 if (!clnt) 360 if (!clnt)
345 goto out_err; 361 goto out_err;
346 clnt->cl_parent = clnt; 362 clnt->cl_parent = parent ? : clnt;
363
364 err = rpc_alloc_clid(clnt);
365 if (err)
366 goto out_no_clid;
347 367
348 rcu_assign_pointer(clnt->cl_xprt, xprt); 368 rcu_assign_pointer(clnt->cl_xprt, xprt);
349 clnt->cl_procinfo = version->procs; 369 clnt->cl_procinfo = version->procs;
350 clnt->cl_maxproc = version->nrprocs; 370 clnt->cl_maxproc = version->nrprocs;
351 clnt->cl_protname = program->name;
352 clnt->cl_prog = args->prognumber ? : program->number; 371 clnt->cl_prog = args->prognumber ? : program->number;
353 clnt->cl_vers = version->number; 372 clnt->cl_vers = version->number;
354 clnt->cl_stats = program->stats; 373 clnt->cl_stats = program->stats;
355 clnt->cl_metrics = rpc_alloc_iostats(clnt); 374 clnt->cl_metrics = rpc_alloc_iostats(clnt);
375 rpc_init_pipe_dir_head(&clnt->cl_pipedir_objects);
356 err = -ENOMEM; 376 err = -ENOMEM;
357 if (clnt->cl_metrics == NULL) 377 if (clnt->cl_metrics == NULL)
358 goto out_no_stats; 378 goto out_no_stats;
@@ -372,12 +392,6 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
372 392
373 clnt->cl_rtt = &clnt->cl_rtt_default; 393 clnt->cl_rtt = &clnt->cl_rtt_default;
374 rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); 394 rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
375 clnt->cl_principal = NULL;
376 if (args->client_name) {
377 clnt->cl_principal = kstrdup(args->client_name, GFP_KERNEL);
378 if (!clnt->cl_principal)
379 goto out_no_principal;
380 }
381 395
382 atomic_set(&clnt->cl_count, 1); 396 atomic_set(&clnt->cl_count, 1);
383 397
@@ -387,13 +401,15 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
387 err = rpc_client_register(args, clnt); 401 err = rpc_client_register(args, clnt);
388 if (err) 402 if (err)
389 goto out_no_path; 403 goto out_no_path;
404 if (parent)
405 atomic_inc(&parent->cl_count);
390 return clnt; 406 return clnt;
391 407
392out_no_path: 408out_no_path:
393 kfree(clnt->cl_principal);
394out_no_principal:
395 rpc_free_iostats(clnt->cl_metrics); 409 rpc_free_iostats(clnt->cl_metrics);
396out_no_stats: 410out_no_stats:
411 rpc_free_clid(clnt);
412out_no_clid:
397 kfree(clnt); 413 kfree(clnt);
398out_err: 414out_err:
399 rpciod_down(); 415 rpciod_down();
@@ -479,7 +495,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
479 if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) 495 if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
480 xprt->resvport = 0; 496 xprt->resvport = 0;
481 497
482 clnt = rpc_new_client(args, xprt); 498 clnt = rpc_new_client(args, xprt, NULL);
483 if (IS_ERR(clnt)) 499 if (IS_ERR(clnt))
484 return clnt; 500 return clnt;
485 501
@@ -526,15 +542,12 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
526 goto out_err; 542 goto out_err;
527 args->servername = xprt->servername; 543 args->servername = xprt->servername;
528 544
529 new = rpc_new_client(args, xprt); 545 new = rpc_new_client(args, xprt, clnt);
530 if (IS_ERR(new)) { 546 if (IS_ERR(new)) {
531 err = PTR_ERR(new); 547 err = PTR_ERR(new);
532 goto out_err; 548 goto out_err;
533 } 549 }
534 550
535 atomic_inc(&clnt->cl_count);
536 new->cl_parent = clnt;
537
538 /* Turn off autobind on clones */ 551 /* Turn off autobind on clones */
539 new->cl_autobind = 0; 552 new->cl_autobind = 0;
540 new->cl_softrtry = clnt->cl_softrtry; 553 new->cl_softrtry = clnt->cl_softrtry;
@@ -561,7 +574,6 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
561 .prognumber = clnt->cl_prog, 574 .prognumber = clnt->cl_prog,
562 .version = clnt->cl_vers, 575 .version = clnt->cl_vers,
563 .authflavor = clnt->cl_auth->au_flavor, 576 .authflavor = clnt->cl_auth->au_flavor,
564 .client_name = clnt->cl_principal,
565 }; 577 };
566 return __rpc_clone_client(&args, clnt); 578 return __rpc_clone_client(&args, clnt);
567} 579}
@@ -583,7 +595,6 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
583 .prognumber = clnt->cl_prog, 595 .prognumber = clnt->cl_prog,
584 .version = clnt->cl_vers, 596 .version = clnt->cl_vers,
585 .authflavor = flavor, 597 .authflavor = flavor,
586 .client_name = clnt->cl_principal,
587 }; 598 };
588 return __rpc_clone_client(&args, clnt); 599 return __rpc_clone_client(&args, clnt);
589} 600}
@@ -629,7 +640,7 @@ void rpc_shutdown_client(struct rpc_clnt *clnt)
629 might_sleep(); 640 might_sleep();
630 641
631 dprintk_rcu("RPC: shutting down %s client for %s\n", 642 dprintk_rcu("RPC: shutting down %s client for %s\n",
632 clnt->cl_protname, 643 clnt->cl_program->name,
633 rcu_dereference(clnt->cl_xprt)->servername); 644 rcu_dereference(clnt->cl_xprt)->servername);
634 645
635 while (!list_empty(&clnt->cl_tasks)) { 646 while (!list_empty(&clnt->cl_tasks)) {
@@ -649,17 +660,17 @@ static void
649rpc_free_client(struct rpc_clnt *clnt) 660rpc_free_client(struct rpc_clnt *clnt)
650{ 661{
651 dprintk_rcu("RPC: destroying %s client for %s\n", 662 dprintk_rcu("RPC: destroying %s client for %s\n",
652 clnt->cl_protname, 663 clnt->cl_program->name,
653 rcu_dereference(clnt->cl_xprt)->servername); 664 rcu_dereference(clnt->cl_xprt)->servername);
654 if (clnt->cl_parent != clnt) 665 if (clnt->cl_parent != clnt)
655 rpc_release_client(clnt->cl_parent); 666 rpc_release_client(clnt->cl_parent);
656 rpc_clnt_remove_pipedir(clnt); 667 rpc_clnt_remove_pipedir(clnt);
657 rpc_unregister_client(clnt); 668 rpc_unregister_client(clnt);
658 rpc_free_iostats(clnt->cl_metrics); 669 rpc_free_iostats(clnt->cl_metrics);
659 kfree(clnt->cl_principal);
660 clnt->cl_metrics = NULL; 670 clnt->cl_metrics = NULL;
661 xprt_put(rcu_dereference_raw(clnt->cl_xprt)); 671 xprt_put(rcu_dereference_raw(clnt->cl_xprt));
662 rpciod_down(); 672 rpciod_down();
673 rpc_free_clid(clnt);
663 kfree(clnt); 674 kfree(clnt);
664} 675}
665 676
@@ -720,7 +731,6 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
720 .prognumber = program->number, 731 .prognumber = program->number,
721 .version = vers, 732 .version = vers,
722 .authflavor = old->cl_auth->au_flavor, 733 .authflavor = old->cl_auth->au_flavor,
723 .client_name = old->cl_principal,
724 }; 734 };
725 struct rpc_clnt *clnt; 735 struct rpc_clnt *clnt;
726 int err; 736 int err;
@@ -1299,7 +1309,7 @@ call_start(struct rpc_task *task)
1299 struct rpc_clnt *clnt = task->tk_client; 1309 struct rpc_clnt *clnt = task->tk_client;
1300 1310
1301 dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid, 1311 dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid,
1302 clnt->cl_protname, clnt->cl_vers, 1312 clnt->cl_program->name, clnt->cl_vers,
1303 rpc_proc_name(task), 1313 rpc_proc_name(task),
1304 (RPC_IS_ASYNC(task) ? "async" : "sync")); 1314 (RPC_IS_ASYNC(task) ? "async" : "sync"));
1305 1315
@@ -1423,9 +1433,9 @@ call_refreshresult(struct rpc_task *task)
1423 return; 1433 return;
1424 case -ETIMEDOUT: 1434 case -ETIMEDOUT:
1425 rpc_delay(task, 3*HZ); 1435 rpc_delay(task, 3*HZ);
1426 case -EKEYEXPIRED:
1427 case -EAGAIN: 1436 case -EAGAIN:
1428 status = -EACCES; 1437 status = -EACCES;
1438 case -EKEYEXPIRED:
1429 if (!task->tk_cred_retry) 1439 if (!task->tk_cred_retry)
1430 break; 1440 break;
1431 task->tk_cred_retry--; 1441 task->tk_cred_retry--;
@@ -1912,7 +1922,7 @@ call_status(struct rpc_task *task)
1912 default: 1922 default:
1913 if (clnt->cl_chatty) 1923 if (clnt->cl_chatty)
1914 printk("%s: RPC call returned error %d\n", 1924 printk("%s: RPC call returned error %d\n",
1915 clnt->cl_protname, -status); 1925 clnt->cl_program->name, -status);
1916 rpc_exit(task, status); 1926 rpc_exit(task, status);
1917 } 1927 }
1918} 1928}
@@ -1943,7 +1953,7 @@ call_timeout(struct rpc_task *task)
1943 if (clnt->cl_chatty) { 1953 if (clnt->cl_chatty) {
1944 rcu_read_lock(); 1954 rcu_read_lock();
1945 printk(KERN_NOTICE "%s: server %s not responding, timed out\n", 1955 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
1946 clnt->cl_protname, 1956 clnt->cl_program->name,
1947 rcu_dereference(clnt->cl_xprt)->servername); 1957 rcu_dereference(clnt->cl_xprt)->servername);
1948 rcu_read_unlock(); 1958 rcu_read_unlock();
1949 } 1959 }
@@ -1959,7 +1969,7 @@ call_timeout(struct rpc_task *task)
1959 if (clnt->cl_chatty) { 1969 if (clnt->cl_chatty) {
1960 rcu_read_lock(); 1970 rcu_read_lock();
1961 printk(KERN_NOTICE "%s: server %s not responding, still trying\n", 1971 printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
1962 clnt->cl_protname, 1972 clnt->cl_program->name,
1963 rcu_dereference(clnt->cl_xprt)->servername); 1973 rcu_dereference(clnt->cl_xprt)->servername);
1964 rcu_read_unlock(); 1974 rcu_read_unlock();
1965 } 1975 }
@@ -1994,7 +2004,7 @@ call_decode(struct rpc_task *task)
1994 if (clnt->cl_chatty) { 2004 if (clnt->cl_chatty) {
1995 rcu_read_lock(); 2005 rcu_read_lock();
1996 printk(KERN_NOTICE "%s: server %s OK\n", 2006 printk(KERN_NOTICE "%s: server %s OK\n",
1997 clnt->cl_protname, 2007 clnt->cl_program->name,
1998 rcu_dereference(clnt->cl_xprt)->servername); 2008 rcu_dereference(clnt->cl_xprt)->servername);
1999 rcu_read_unlock(); 2009 rcu_read_unlock();
2000 } 2010 }
@@ -2019,7 +2029,7 @@ call_decode(struct rpc_task *task)
2019 goto out_retry; 2029 goto out_retry;
2020 } 2030 }
2021 dprintk("RPC: %s: too small RPC reply size (%d bytes)\n", 2031 dprintk("RPC: %s: too small RPC reply size (%d bytes)\n",
2022 clnt->cl_protname, task->tk_status); 2032 clnt->cl_program->name, task->tk_status);
2023 task->tk_action = call_timeout; 2033 task->tk_action = call_timeout;
2024 goto out_retry; 2034 goto out_retry;
2025 } 2035 }
@@ -2091,7 +2101,8 @@ rpc_verify_header(struct rpc_task *task)
2091 dprintk("RPC: %5u %s: XDR representation not a multiple of" 2101 dprintk("RPC: %5u %s: XDR representation not a multiple of"
2092 " 4 bytes: 0x%x\n", task->tk_pid, __func__, 2102 " 4 bytes: 0x%x\n", task->tk_pid, __func__,
2093 task->tk_rqstp->rq_rcv_buf.len); 2103 task->tk_rqstp->rq_rcv_buf.len);
2094 goto out_eio; 2104 error = -EIO;
2105 goto out_err;
2095 } 2106 }
2096 if ((len -= 3) < 0) 2107 if ((len -= 3) < 0)
2097 goto out_overflow; 2108 goto out_overflow;
@@ -2100,6 +2111,7 @@ rpc_verify_header(struct rpc_task *task)
2100 if ((n = ntohl(*p++)) != RPC_REPLY) { 2111 if ((n = ntohl(*p++)) != RPC_REPLY) {
2101 dprintk("RPC: %5u %s: not an RPC reply: %x\n", 2112 dprintk("RPC: %5u %s: not an RPC reply: %x\n",
2102 task->tk_pid, __func__, n); 2113 task->tk_pid, __func__, n);
2114 error = -EIO;
2103 goto out_garbage; 2115 goto out_garbage;
2104 } 2116 }
2105 2117
@@ -2118,7 +2130,8 @@ rpc_verify_header(struct rpc_task *task)
2118 dprintk("RPC: %5u %s: RPC call rejected, " 2130 dprintk("RPC: %5u %s: RPC call rejected, "
2119 "unknown error: %x\n", 2131 "unknown error: %x\n",
2120 task->tk_pid, __func__, n); 2132 task->tk_pid, __func__, n);
2121 goto out_eio; 2133 error = -EIO;
2134 goto out_err;
2122 } 2135 }
2123 if (--len < 0) 2136 if (--len < 0)
2124 goto out_overflow; 2137 goto out_overflow;
@@ -2163,9 +2176,11 @@ rpc_verify_header(struct rpc_task *task)
2163 task->tk_pid, __func__, n); 2176 task->tk_pid, __func__, n);
2164 goto out_err; 2177 goto out_err;
2165 } 2178 }
2166 if (!(p = rpcauth_checkverf(task, p))) { 2179 p = rpcauth_checkverf(task, p);
2167 dprintk("RPC: %5u %s: auth check failed\n", 2180 if (IS_ERR(p)) {
2168 task->tk_pid, __func__); 2181 error = PTR_ERR(p);
2182 dprintk("RPC: %5u %s: auth check failed with %d\n",
2183 task->tk_pid, __func__, error);
2169 goto out_garbage; /* bad verifier, retry */ 2184 goto out_garbage; /* bad verifier, retry */
2170 } 2185 }
2171 len = p - (__be32 *)iov->iov_base - 1; 2186 len = p - (__be32 *)iov->iov_base - 1;
@@ -2218,8 +2233,6 @@ out_garbage:
2218out_retry: 2233out_retry:
2219 return ERR_PTR(-EAGAIN); 2234 return ERR_PTR(-EAGAIN);
2220 } 2235 }
2221out_eio:
2222 error = -EIO;
2223out_err: 2236out_err:
2224 rpc_exit(task, error); 2237 rpc_exit(task, error);
2225 dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid, 2238 dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,
@@ -2291,7 +2304,7 @@ static void rpc_show_task(const struct rpc_clnt *clnt,
2291 printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n", 2304 printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n",
2292 task->tk_pid, task->tk_flags, task->tk_status, 2305 task->tk_pid, task->tk_flags, task->tk_status,
2293 clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, 2306 clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops,
2294 clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), 2307 clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
2295 task->tk_action, rpc_waitq); 2308 task->tk_action, rpc_waitq);
2296} 2309}
2297 2310
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 406859cc68aa..f94567b45bb3 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -409,7 +409,7 @@ rpc_show_info(struct seq_file *m, void *v)
409 rcu_read_lock(); 409 rcu_read_lock();
410 seq_printf(m, "RPC server: %s\n", 410 seq_printf(m, "RPC server: %s\n",
411 rcu_dereference(clnt->cl_xprt)->servername); 411 rcu_dereference(clnt->cl_xprt)->servername);
412 seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname, 412 seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_program->name,
413 clnt->cl_prog, clnt->cl_vers); 413 clnt->cl_prog, clnt->cl_vers);
414 seq_printf(m, "address: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); 414 seq_printf(m, "address: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR));
415 seq_printf(m, "protocol: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PROTO)); 415 seq_printf(m, "protocol: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PROTO));
@@ -480,23 +480,6 @@ static const struct dentry_operations rpc_dentry_operations = {
480 .d_delete = rpc_delete_dentry, 480 .d_delete = rpc_delete_dentry,
481}; 481};
482 482
483/*
484 * Lookup the data. This is trivial - if the dentry didn't already
485 * exist, we know it is negative.
486 */
487static struct dentry *
488rpc_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
489{
490 if (dentry->d_name.len > NAME_MAX)
491 return ERR_PTR(-ENAMETOOLONG);
492 d_add(dentry, NULL);
493 return NULL;
494}
495
496static const struct inode_operations rpc_dir_inode_operations = {
497 .lookup = rpc_lookup,
498};
499
500static struct inode * 483static struct inode *
501rpc_get_inode(struct super_block *sb, umode_t mode) 484rpc_get_inode(struct super_block *sb, umode_t mode)
502{ 485{
@@ -509,7 +492,7 @@ rpc_get_inode(struct super_block *sb, umode_t mode)
509 switch (mode & S_IFMT) { 492 switch (mode & S_IFMT) {
510 case S_IFDIR: 493 case S_IFDIR:
511 inode->i_fop = &simple_dir_operations; 494 inode->i_fop = &simple_dir_operations;
512 inode->i_op = &rpc_dir_inode_operations; 495 inode->i_op = &simple_dir_inode_operations;
513 inc_nlink(inode); 496 inc_nlink(inode);
514 default: 497 default:
515 break; 498 break;
@@ -901,6 +884,159 @@ rpc_unlink(struct dentry *dentry)
901} 884}
902EXPORT_SYMBOL_GPL(rpc_unlink); 885EXPORT_SYMBOL_GPL(rpc_unlink);
903 886
887/**
888 * rpc_init_pipe_dir_head - initialise a struct rpc_pipe_dir_head
889 * @pdh: pointer to struct rpc_pipe_dir_head
890 */
891void rpc_init_pipe_dir_head(struct rpc_pipe_dir_head *pdh)
892{
893 INIT_LIST_HEAD(&pdh->pdh_entries);
894 pdh->pdh_dentry = NULL;
895}
896EXPORT_SYMBOL_GPL(rpc_init_pipe_dir_head);
897
898/**
899 * rpc_init_pipe_dir_object - initialise a struct rpc_pipe_dir_object
900 * @pdo: pointer to struct rpc_pipe_dir_object
901 * @pdo_ops: pointer to const struct rpc_pipe_dir_object_ops
902 * @pdo_data: pointer to caller-defined data
903 */
904void rpc_init_pipe_dir_object(struct rpc_pipe_dir_object *pdo,
905 const struct rpc_pipe_dir_object_ops *pdo_ops,
906 void *pdo_data)
907{
908 INIT_LIST_HEAD(&pdo->pdo_head);
909 pdo->pdo_ops = pdo_ops;
910 pdo->pdo_data = pdo_data;
911}
912EXPORT_SYMBOL_GPL(rpc_init_pipe_dir_object);
913
914static int
915rpc_add_pipe_dir_object_locked(struct net *net,
916 struct rpc_pipe_dir_head *pdh,
917 struct rpc_pipe_dir_object *pdo)
918{
919 int ret = 0;
920
921 if (pdh->pdh_dentry)
922 ret = pdo->pdo_ops->create(pdh->pdh_dentry, pdo);
923 if (ret == 0)
924 list_add_tail(&pdo->pdo_head, &pdh->pdh_entries);
925 return ret;
926}
927
928static void
929rpc_remove_pipe_dir_object_locked(struct net *net,
930 struct rpc_pipe_dir_head *pdh,
931 struct rpc_pipe_dir_object *pdo)
932{
933 if (pdh->pdh_dentry)
934 pdo->pdo_ops->destroy(pdh->pdh_dentry, pdo);
935 list_del_init(&pdo->pdo_head);
936}
937
938/**
939 * rpc_add_pipe_dir_object - associate a rpc_pipe_dir_object to a directory
940 * @net: pointer to struct net
941 * @pdh: pointer to struct rpc_pipe_dir_head
942 * @pdo: pointer to struct rpc_pipe_dir_object
943 *
944 */
945int
946rpc_add_pipe_dir_object(struct net *net,
947 struct rpc_pipe_dir_head *pdh,
948 struct rpc_pipe_dir_object *pdo)
949{
950 int ret = 0;
951
952 if (list_empty(&pdo->pdo_head)) {
953 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
954
955 mutex_lock(&sn->pipefs_sb_lock);
956 ret = rpc_add_pipe_dir_object_locked(net, pdh, pdo);
957 mutex_unlock(&sn->pipefs_sb_lock);
958 }
959 return ret;
960}
961EXPORT_SYMBOL_GPL(rpc_add_pipe_dir_object);
962
963/**
964 * rpc_remove_pipe_dir_object - remove a rpc_pipe_dir_object from a directory
965 * @net: pointer to struct net
966 * @pdh: pointer to struct rpc_pipe_dir_head
967 * @pdo: pointer to struct rpc_pipe_dir_object
968 *
969 */
970void
971rpc_remove_pipe_dir_object(struct net *net,
972 struct rpc_pipe_dir_head *pdh,
973 struct rpc_pipe_dir_object *pdo)
974{
975 if (!list_empty(&pdo->pdo_head)) {
976 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
977
978 mutex_lock(&sn->pipefs_sb_lock);
979 rpc_remove_pipe_dir_object_locked(net, pdh, pdo);
980 mutex_unlock(&sn->pipefs_sb_lock);
981 }
982}
983EXPORT_SYMBOL_GPL(rpc_remove_pipe_dir_object);
984
985/**
986 * rpc_find_or_alloc_pipe_dir_object
987 * @net: pointer to struct net
988 * @pdh: pointer to struct rpc_pipe_dir_head
989 * @match: match struct rpc_pipe_dir_object to data
990 * @alloc: allocate a new struct rpc_pipe_dir_object
991 * @data: user defined data for match() and alloc()
992 *
993 */
994struct rpc_pipe_dir_object *
995rpc_find_or_alloc_pipe_dir_object(struct net *net,
996 struct rpc_pipe_dir_head *pdh,
997 int (*match)(struct rpc_pipe_dir_object *, void *),
998 struct rpc_pipe_dir_object *(*alloc)(void *),
999 void *data)
1000{
1001 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1002 struct rpc_pipe_dir_object *pdo;
1003
1004 mutex_lock(&sn->pipefs_sb_lock);
1005 list_for_each_entry(pdo, &pdh->pdh_entries, pdo_head) {
1006 if (!match(pdo, data))
1007 continue;
1008 goto out;
1009 }
1010 pdo = alloc(data);
1011 if (!pdo)
1012 goto out;
1013 rpc_add_pipe_dir_object_locked(net, pdh, pdo);
1014out:
1015 mutex_unlock(&sn->pipefs_sb_lock);
1016 return pdo;
1017}
1018EXPORT_SYMBOL_GPL(rpc_find_or_alloc_pipe_dir_object);
1019
1020static void
1021rpc_create_pipe_dir_objects(struct rpc_pipe_dir_head *pdh)
1022{
1023 struct rpc_pipe_dir_object *pdo;
1024 struct dentry *dir = pdh->pdh_dentry;
1025
1026 list_for_each_entry(pdo, &pdh->pdh_entries, pdo_head)
1027 pdo->pdo_ops->create(dir, pdo);
1028}
1029
1030static void
1031rpc_destroy_pipe_dir_objects(struct rpc_pipe_dir_head *pdh)
1032{
1033 struct rpc_pipe_dir_object *pdo;
1034 struct dentry *dir = pdh->pdh_dentry;
1035
1036 list_for_each_entry(pdo, &pdh->pdh_entries, pdo_head)
1037 pdo->pdo_ops->destroy(dir, pdo);
1038}
1039
904enum { 1040enum {
905 RPCAUTH_info, 1041 RPCAUTH_info,
906 RPCAUTH_EOF 1042 RPCAUTH_EOF
@@ -941,16 +1077,29 @@ struct dentry *rpc_create_client_dir(struct dentry *dentry,
941 const char *name, 1077 const char *name,
942 struct rpc_clnt *rpc_client) 1078 struct rpc_clnt *rpc_client)
943{ 1079{
944 return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, NULL, 1080 struct dentry *ret;
1081
1082 ret = rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, NULL,
945 rpc_clntdir_populate, rpc_client); 1083 rpc_clntdir_populate, rpc_client);
1084 if (!IS_ERR(ret)) {
1085 rpc_client->cl_pipedir_objects.pdh_dentry = ret;
1086 rpc_create_pipe_dir_objects(&rpc_client->cl_pipedir_objects);
1087 }
1088 return ret;
946} 1089}
947 1090
948/** 1091/**
949 * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir() 1092 * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir()
950 * @dentry: dentry for the pipe 1093 * @rpc_client: rpc_client for the pipe
951 */ 1094 */
952int rpc_remove_client_dir(struct dentry *dentry) 1095int rpc_remove_client_dir(struct rpc_clnt *rpc_client)
953{ 1096{
1097 struct dentry *dentry = rpc_client->cl_pipedir_objects.pdh_dentry;
1098
1099 if (dentry == NULL)
1100 return 0;
1101 rpc_destroy_pipe_dir_objects(&rpc_client->cl_pipedir_objects);
1102 rpc_client->cl_pipedir_objects.pdh_dentry = NULL;
954 return rpc_rmdir_depopulate(dentry, rpc_clntdir_depopulate); 1103 return rpc_rmdir_depopulate(dentry, rpc_clntdir_depopulate);
955} 1104}
956 1105
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 93a7a4e94d80..ff3cc4bf4b24 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(void *word)
258 return 0; 258 return 0;
259} 259}
260 260
261#ifdef RPC_DEBUG 261#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
262static void rpc_task_set_debuginfo(struct rpc_task *task) 262static void rpc_task_set_debuginfo(struct rpc_task *task)
263{ 263{
264 static atomic_t rpc_pid; 264 static atomic_t rpc_pid;
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 21b75cb08c03..54530490944e 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -188,7 +188,7 @@ void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
188 188
189 seq_printf(seq, "\tRPC iostats version: %s ", RPC_IOSTATS_VERS); 189 seq_printf(seq, "\tRPC iostats version: %s ", RPC_IOSTATS_VERS);
190 seq_printf(seq, "p/v: %u/%u (%s)\n", 190 seq_printf(seq, "p/v: %u/%u (%s)\n",
191 clnt->cl_prog, clnt->cl_vers, clnt->cl_protname); 191 clnt->cl_prog, clnt->cl_vers, clnt->cl_program->name);
192 192
193 rcu_read_lock(); 193 rcu_read_lock();
194 xprt = rcu_dereference(clnt->cl_xprt); 194 xprt = rcu_dereference(clnt->cl_xprt);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index d6656d7768f4..ee03d35677d9 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -47,6 +47,8 @@
47#include <net/udp.h> 47#include <net/udp.h>
48#include <net/tcp.h> 48#include <net/tcp.h>
49 49
50#include <trace/events/sunrpc.h>
51
50#include "sunrpc.h" 52#include "sunrpc.h"
51 53
52static void xs_close(struct rpc_xprt *xprt); 54static void xs_close(struct rpc_xprt *xprt);
@@ -665,8 +667,10 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
665 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 667 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
666 struct socket *sock = transport->sock; 668 struct socket *sock = transport->sock;
667 669
668 if (sock != NULL) 670 if (sock != NULL) {
669 kernel_sock_shutdown(sock, SHUT_WR); 671 kernel_sock_shutdown(sock, SHUT_WR);
672 trace_rpc_socket_shutdown(xprt, sock);
673 }
670} 674}
671 675
672/** 676/**
@@ -811,6 +815,7 @@ static void xs_reset_transport(struct sock_xprt *transport)
811 815
812 sk->sk_no_check = 0; 816 sk->sk_no_check = 0;
813 817
818 trace_rpc_socket_close(&transport->xprt, sock);
814 sock_release(sock); 819 sock_release(sock);
815} 820}
816 821
@@ -1492,6 +1497,7 @@ static void xs_tcp_state_change(struct sock *sk)
1492 sock_flag(sk, SOCK_ZAPPED), 1497 sock_flag(sk, SOCK_ZAPPED),
1493 sk->sk_shutdown); 1498 sk->sk_shutdown);
1494 1499
1500 trace_rpc_socket_state_change(xprt, sk->sk_socket);
1495 switch (sk->sk_state) { 1501 switch (sk->sk_state) {
1496 case TCP_ESTABLISHED: 1502 case TCP_ESTABLISHED:
1497 spin_lock(&xprt->transport_lock); 1503 spin_lock(&xprt->transport_lock);
@@ -1896,6 +1902,7 @@ static int xs_local_setup_socket(struct sock_xprt *transport)
1896 xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); 1902 xprt, xprt->address_strings[RPC_DISPLAY_ADDR]);
1897 1903
1898 status = xs_local_finish_connecting(xprt, sock); 1904 status = xs_local_finish_connecting(xprt, sock);
1905 trace_rpc_socket_connect(xprt, sock, status);
1899 switch (status) { 1906 switch (status) {
1900 case 0: 1907 case 0:
1901 dprintk("RPC: xprt %p connected to %s\n", 1908 dprintk("RPC: xprt %p connected to %s\n",
@@ -2039,6 +2046,7 @@ static void xs_udp_setup_socket(struct work_struct *work)
2039 xprt->address_strings[RPC_DISPLAY_PORT]); 2046 xprt->address_strings[RPC_DISPLAY_PORT]);
2040 2047
2041 xs_udp_finish_connecting(xprt, sock); 2048 xs_udp_finish_connecting(xprt, sock);
2049 trace_rpc_socket_connect(xprt, sock, 0);
2042 status = 0; 2050 status = 0;
2043out: 2051out:
2044 xprt_clear_connecting(xprt); 2052 xprt_clear_connecting(xprt);
@@ -2064,6 +2072,8 @@ static void xs_abort_connection(struct sock_xprt *transport)
2064 memset(&any, 0, sizeof(any)); 2072 memset(&any, 0, sizeof(any));
2065 any.sa_family = AF_UNSPEC; 2073 any.sa_family = AF_UNSPEC;
2066 result = kernel_connect(transport->sock, &any, sizeof(any), 0); 2074 result = kernel_connect(transport->sock, &any, sizeof(any), 0);
2075 trace_rpc_socket_reset_connection(&transport->xprt,
2076 transport->sock, result);
2067 if (!result) 2077 if (!result)
2068 xs_sock_reset_connection_flags(&transport->xprt); 2078 xs_sock_reset_connection_flags(&transport->xprt);
2069 dprintk("RPC: AF_UNSPEC connect return code %d\n", result); 2079 dprintk("RPC: AF_UNSPEC connect return code %d\n", result);
@@ -2194,6 +2204,7 @@ static void xs_tcp_setup_socket(struct work_struct *work)
2194 xprt->address_strings[RPC_DISPLAY_PORT]); 2204 xprt->address_strings[RPC_DISPLAY_PORT]);
2195 2205
2196 status = xs_tcp_finish_connecting(xprt, sock); 2206 status = xs_tcp_finish_connecting(xprt, sock);
2207 trace_rpc_socket_connect(xprt, sock, status);
2197 dprintk("RPC: %p connect status %d connected %d sock state %d\n", 2208 dprintk("RPC: %p connect status %d connected %d sock state %d\n",
2198 xprt, -status, xprt_connected(xprt), 2209 xprt, -status, xprt_connected(xprt),
2199 sock->sk->sk_state); 2210 sock->sk->sk_state);