aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 17:04:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 17:04:11 -0500
commit982197277c85018cc6eb77f1d3bef17933b0c5fd (patch)
tree805fcef9ec7c1e83867b89332fd37f751594fae3
parent40889e8d9fc6355980cf2bc94ef4356c10dec4ec (diff)
parent24ffb93872f7363a01ad639e3c8a9889b46c3f0a (diff)
Merge branch 'for-3.8' of git://linux-nfs.org/~bfields/linux
Pull nfsd update from Bruce Fields: "Included this time: - more nfsd containerization work from Stanislav Kinsbursky: we're not quite there yet, but should be by 3.9. - NFSv4.1 progress: implementation of basic backchannel security negotiation and the mandatory BACKCHANNEL_CTL operation. See http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues for remaining TODO's - Fixes for some bugs that could be triggered by unusual compounds. Our xdr code wasn't designed with v4 compounds in mind, and it shows. A more thorough rewrite is still a todo. - If you've ever seen "RPC: multiple fragments per record not supported" logged while using some sort of odd userland NFS client, that should now be fixed. - Further work from Jeff Layton on our mechanism for storing information about NFSv4 clients across reboots. - Further work from Bryan Schumaker on his fault-injection mechanism (which allows us to discard selective NFSv4 state, to excercise rarely-taken recovery code paths in the client.) - The usual mix of miscellaneous bugs and cleanup. Thanks to everyone who tested or contributed this cycle." * 'for-3.8' of git://linux-nfs.org/~bfields/linux: (111 commits) nfsd4: don't leave freed stateid hashed nfsd4: free_stateid can use the current stateid nfsd4: cleanup: replace rq_resused count by rq_next_page pointer nfsd: warn on odd reply state in nfsd_vfs_read nfsd4: fix oops on unusual readlike compound nfsd4: disable zero-copy on non-final read ops svcrpc: fix some printks NFSD: Correct the size calculation in fault_inject_write NFSD: Pass correct buffer size to rpc_ntop nfsd: pass proper net to nfsd_destroy() from NFSd kthreads nfsd: simplify service shutdown nfsd: replace boolean nfsd_up flag by users counter nfsd: simplify NFSv4 state init and shutdown nfsd: introduce helpers for generic resources init and shutdown nfsd: make NFSd service structure allocated per net nfsd: make NFSd service boot time per-net nfsd: per-net NFSd up flag introduced nfsd: move per-net startup code to separated function nfsd: pass net to __write_ports() and down nfsd: pass net to nfsd_set_nrthreads() ...
-rw-r--r--Documentation/filesystems/nfs/nfs41-server.txt20
-rw-r--r--fs/exportfs/expfs.c4
-rw-r--r--fs/fhandle.c2
-rw-r--r--fs/nfsd/fault_inject.c113
-rw-r--r--fs/nfsd/fault_inject.h28
-rw-r--r--fs/nfsd/netns.h66
-rw-r--r--fs/nfsd/nfs2acl.c2
-rw-r--r--fs/nfsd/nfs3acl.c2
-rw-r--r--fs/nfsd/nfs3proc.c6
-rw-r--r--fs/nfsd/nfs3xdr.c47
-rw-r--r--fs/nfsd/nfs4callback.c69
-rw-r--r--fs/nfsd/nfs4proc.c74
-rw-r--r--fs/nfsd/nfs4recover.c561
-rw-r--r--fs/nfsd/nfs4state.c1015
-rw-r--r--fs/nfsd/nfs4xdr.c324
-rw-r--r--fs/nfsd/nfsctl.c100
-rw-r--r--fs/nfsd/nfsd.h36
-rw-r--r--fs/nfsd/nfsfh.c4
-rw-r--r--fs/nfsd/nfssvc.c203
-rw-r--r--fs/nfsd/nfsxdr.c11
-rw-r--r--fs/nfsd/state.h64
-rw-r--r--fs/nfsd/vfs.c53
-rw-r--r--fs/nfsd/xdr4.h15
-rw-r--r--include/linux/exportfs.h5
-rw-r--r--include/linux/sunrpc/cache.h6
-rw-r--r--include/linux/sunrpc/svc.h6
-rw-r--r--include/linux/sunrpc/svcsock.h21
-rw-r--r--net/sunrpc/rpcb_clnt.c1
-rw-r--r--net/sunrpc/svc.c8
-rw-r--r--net/sunrpc/svcsock.c98
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c10
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c4
32 files changed, 1911 insertions, 1067 deletions
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt
index 092fad92a3f0..01c2db769791 100644
--- a/Documentation/filesystems/nfs/nfs41-server.txt
+++ b/Documentation/filesystems/nfs/nfs41-server.txt
@@ -39,21 +39,10 @@ interoperability problems with future clients. Known issues:
39 from a linux client are possible, but we aren't really 39 from a linux client are possible, but we aren't really
40 conformant with the spec (for example, we don't use kerberos 40 conformant with the spec (for example, we don't use kerberos
41 on the backchannel correctly). 41 on the backchannel correctly).
42 - Incomplete backchannel support: incomplete backchannel gss
43 support and no support for BACKCHANNEL_CTL mean that
44 callbacks (hence delegations and layouts) may not be
45 available and clients confused by the incomplete
46 implementation may fail.
47 - We do not support SSV, which provides security for shared 42 - We do not support SSV, which provides security for shared
48 client-server state (thus preventing unauthorized tampering 43 client-server state (thus preventing unauthorized tampering
49 with locks and opens, for example). It is mandatory for 44 with locks and opens, for example). It is mandatory for
50 servers to support this, though no clients use it yet. 45 servers to support this, though no clients use it yet.
51 - Mandatory operations which we do not support, such as
52 DESTROY_CLIENTID, are not currently used by clients, but will be
53 (and the spec recommends their uses in common cases), and
54 clients should not be expected to know how to recover from the
55 case where they are not supported. This will eventually cause
56 interoperability failures.
57 46
58In addition, some limitations are inherited from the current NFSv4 47In addition, some limitations are inherited from the current NFSv4
59implementation: 48implementation:
@@ -89,7 +78,7 @@ Operations
89 | | MNI | or OPT) | | 78 | | MNI | or OPT) | |
90 +----------------------+------------+--------------+----------------+ 79 +----------------------+------------+--------------+----------------+
91 | ACCESS | REQ | | Section 18.1 | 80 | ACCESS | REQ | | Section 18.1 |
92NS | BACKCHANNEL_CTL | REQ | | Section 18.33 | 81I | BACKCHANNEL_CTL | REQ | | Section 18.33 |
93I | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | 82I | BIND_CONN_TO_SESSION | REQ | | Section 18.34 |
94 | CLOSE | REQ | | Section 18.2 | 83 | CLOSE | REQ | | Section 18.2 |
95 | COMMIT | REQ | | Section 18.3 | 84 | COMMIT | REQ | | Section 18.3 |
@@ -99,7 +88,7 @@ NS*| DELEGPURGE | OPT | FDELG (REQ) | Section 18.5 |
99 | DELEGRETURN | OPT | FDELG, | Section 18.6 | 88 | DELEGRETURN | OPT | FDELG, | Section 18.6 |
100 | | | DDELG, pNFS | | 89 | | | DDELG, pNFS | |
101 | | | (REQ) | | 90 | | | (REQ) | |
102NS | DESTROY_CLIENTID | REQ | | Section 18.50 | 91I | DESTROY_CLIENTID | REQ | | Section 18.50 |
103I | DESTROY_SESSION | REQ | | Section 18.37 | 92I | DESTROY_SESSION | REQ | | Section 18.37 |
104I | EXCHANGE_ID | REQ | | Section 18.35 | 93I | EXCHANGE_ID | REQ | | Section 18.35 |
105I | FREE_STATEID | REQ | | Section 18.38 | 94I | FREE_STATEID | REQ | | Section 18.38 |
@@ -192,7 +181,6 @@ EXCHANGE_ID:
192 181
193CREATE_SESSION: 182CREATE_SESSION:
194* backchannel attributes are ignored 183* backchannel attributes are ignored
195* backchannel security parameters are ignored
196 184
197SEQUENCE: 185SEQUENCE:
198* no support for dynamic slot table renegotiation (optional) 186* no support for dynamic slot table renegotiation (optional)
@@ -202,7 +190,7 @@ Nonstandard compound limitations:
202 ca_maxrequestsize request and a ca_maxresponsesize reply, so we may 190 ca_maxrequestsize request and a ca_maxresponsesize reply, so we may
203 fail to live up to the promise we made in CREATE_SESSION fore channel 191 fail to live up to the promise we made in CREATE_SESSION fore channel
204 negotiation. 192 negotiation.
205* No more than one IO operation (read, write, readdir) allowed per 193* No more than one read-like operation allowed per compound; encoding
206 compound. 194 replies that cross page boundaries (except for read data) not handled.
207 195
208See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues. 196See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues.
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 606bb074c501..5df4bb4aab14 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -322,10 +322,10 @@ static int export_encode_fh(struct inode *inode, struct fid *fid,
322 322
323 if (parent && (len < 4)) { 323 if (parent && (len < 4)) {
324 *max_len = 4; 324 *max_len = 4;
325 return 255; 325 return FILEID_INVALID;
326 } else if (len < 2) { 326 } else if (len < 2) {
327 *max_len = 2; 327 *max_len = 2;
328 return 255; 328 return FILEID_INVALID;
329 } 329 }
330 330
331 len = 2; 331 len = 2;
diff --git a/fs/fhandle.c b/fs/fhandle.c
index cccdc874bb55..999ff5c3cab0 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -52,7 +52,7 @@ static long do_sys_name_to_handle(struct path *path,
52 handle_bytes = handle_dwords * sizeof(u32); 52 handle_bytes = handle_dwords * sizeof(u32);
53 handle->handle_bytes = handle_bytes; 53 handle->handle_bytes = handle_bytes;
54 if ((handle->handle_bytes > f_handle.handle_bytes) || 54 if ((handle->handle_bytes > f_handle.handle_bytes) ||
55 (retval == 255) || (retval == -ENOSPC)) { 55 (retval == FILEID_INVALID) || (retval == -ENOSPC)) {
56 /* As per old exportfs_encode_fh documentation 56 /* As per old exportfs_encode_fh documentation
57 * we could return ENOSPC to indicate overflow 57 * we could return ENOSPC to indicate overflow
58 * But file system returned 255 always. So handle 58 * But file system returned 255 always. So handle
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index e6c38159622f..e761ee95617f 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -8,61 +8,144 @@
8#include <linux/fs.h> 8#include <linux/fs.h>
9#include <linux/debugfs.h> 9#include <linux/debugfs.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/nsproxy.h>
12#include <linux/sunrpc/clnt.h>
13#include <asm/uaccess.h>
11 14
12#include "state.h" 15#include "state.h"
13#include "fault_inject.h" 16#include "netns.h"
14 17
15struct nfsd_fault_inject_op { 18struct nfsd_fault_inject_op {
16 char *file; 19 char *file;
17 void (*func)(u64); 20 u64 (*forget)(struct nfs4_client *, u64);
21 u64 (*print)(struct nfs4_client *, u64);
18}; 22};
19 23
20static struct nfsd_fault_inject_op inject_ops[] = { 24static struct nfsd_fault_inject_op inject_ops[] = {
21 { 25 {
22 .file = "forget_clients", 26 .file = "forget_clients",
23 .func = nfsd_forget_clients, 27 .forget = nfsd_forget_client,
28 .print = nfsd_print_client,
24 }, 29 },
25 { 30 {
26 .file = "forget_locks", 31 .file = "forget_locks",
27 .func = nfsd_forget_locks, 32 .forget = nfsd_forget_client_locks,
33 .print = nfsd_print_client_locks,
28 }, 34 },
29 { 35 {
30 .file = "forget_openowners", 36 .file = "forget_openowners",
31 .func = nfsd_forget_openowners, 37 .forget = nfsd_forget_client_openowners,
38 .print = nfsd_print_client_openowners,
32 }, 39 },
33 { 40 {
34 .file = "forget_delegations", 41 .file = "forget_delegations",
35 .func = nfsd_forget_delegations, 42 .forget = nfsd_forget_client_delegations,
43 .print = nfsd_print_client_delegations,
36 }, 44 },
37 { 45 {
38 .file = "recall_delegations", 46 .file = "recall_delegations",
39 .func = nfsd_recall_delegations, 47 .forget = nfsd_recall_client_delegations,
48 .print = nfsd_print_client_delegations,
40 }, 49 },
41}; 50};
42 51
43static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op); 52static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op);
44static struct dentry *debug_dir; 53static struct dentry *debug_dir;
45 54
46static int nfsd_inject_set(void *op_ptr, u64 val) 55static void nfsd_inject_set(struct nfsd_fault_inject_op *op, u64 val)
47{ 56{
48 struct nfsd_fault_inject_op *op = op_ptr; 57 u64 count = 0;
49 58
50 if (val == 0) 59 if (val == 0)
51 printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file); 60 printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file);
52 else 61 else
53 printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val); 62 printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val);
54 63
55 op->func(val); 64 nfs4_lock_state();
56 return 0; 65 count = nfsd_for_n_state(val, op->forget);
66 nfs4_unlock_state();
67 printk(KERN_INFO "NFSD: %s: found %llu", op->file, count);
57} 68}
58 69
59static int nfsd_inject_get(void *data, u64 *val) 70static void nfsd_inject_set_client(struct nfsd_fault_inject_op *op,
71 struct sockaddr_storage *addr,
72 size_t addr_size)
60{ 73{
61 *val = 0; 74 char buf[INET6_ADDRSTRLEN];
62 return 0; 75 struct nfs4_client *clp;
76 u64 count;
77
78 nfs4_lock_state();
79 clp = nfsd_find_client(addr, addr_size);
80 if (clp) {
81 count = op->forget(clp, 0);
82 rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
83 printk(KERN_INFO "NFSD [%s]: Client %s had %llu state object(s)\n", op->file, buf, count);
84 }
85 nfs4_unlock_state();
86}
87
88static void nfsd_inject_get(struct nfsd_fault_inject_op *op, u64 *val)
89{
90 nfs4_lock_state();
91 *val = nfsd_for_n_state(0, op->print);
92 nfs4_unlock_state();
63} 93}
64 94
65DEFINE_SIMPLE_ATTRIBUTE(fops_nfsd, nfsd_inject_get, nfsd_inject_set, "%llu\n"); 95static ssize_t fault_inject_read(struct file *file, char __user *buf,
96 size_t len, loff_t *ppos)
97{
98 static u64 val;
99 char read_buf[25];
100 size_t size, ret;
101 loff_t pos = *ppos;
102
103 if (!pos)
104 nfsd_inject_get(file->f_dentry->d_inode->i_private, &val);
105 size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val);
106
107 if (pos < 0)
108 return -EINVAL;
109 if (pos >= size || !len)
110 return 0;
111 if (len > size - pos)
112 len = size - pos;
113 ret = copy_to_user(buf, read_buf + pos, len);
114 if (ret == len)
115 return -EFAULT;
116 len -= ret;
117 *ppos = pos + len;
118 return len;
119}
120
121static ssize_t fault_inject_write(struct file *file, const char __user *buf,
122 size_t len, loff_t *ppos)
123{
124 char write_buf[INET6_ADDRSTRLEN];
125 size_t size = min(sizeof(write_buf) - 1, len);
126 struct net *net = current->nsproxy->net_ns;
127 struct sockaddr_storage sa;
128 u64 val;
129
130 if (copy_from_user(write_buf, buf, size))
131 return -EFAULT;
132 write_buf[size] = '\0';
133
134 size = rpc_pton(net, write_buf, size, (struct sockaddr *)&sa, sizeof(sa));
135 if (size > 0)
136 nfsd_inject_set_client(file->f_dentry->d_inode->i_private, &sa, size);
137 else {
138 val = simple_strtoll(write_buf, NULL, 0);
139 nfsd_inject_set(file->f_dentry->d_inode->i_private, val);
140 }
141 return len; /* on success, claim we got the whole input */
142}
143
144static const struct file_operations fops_nfsd = {
145 .owner = THIS_MODULE,
146 .read = fault_inject_read,
147 .write = fault_inject_write,
148};
66 149
67void nfsd_fault_inject_cleanup(void) 150void nfsd_fault_inject_cleanup(void)
68{ 151{
diff --git a/fs/nfsd/fault_inject.h b/fs/nfsd/fault_inject.h
deleted file mode 100644
index 90bd0570956c..000000000000
--- a/fs/nfsd/fault_inject.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (c) 2011 Bryan Schumaker <bjschuma@netapp.com>
3 *
4 * Function definitions for fault injection
5 */
6
7#ifndef LINUX_NFSD_FAULT_INJECT_H
8#define LINUX_NFSD_FAULT_INJECT_H
9
10#ifdef CONFIG_NFSD_FAULT_INJECTION
11int nfsd_fault_inject_init(void);
12void nfsd_fault_inject_cleanup(void);
13void nfsd_forget_clients(u64);
14void nfsd_forget_locks(u64);
15void nfsd_forget_openowners(u64);
16void nfsd_forget_delegations(u64);
17void nfsd_recall_delegations(u64);
18#else /* CONFIG_NFSD_FAULT_INJECTION */
19static inline int nfsd_fault_inject_init(void) { return 0; }
20static inline void nfsd_fault_inject_cleanup(void) {}
21static inline void nfsd_forget_clients(u64 num) {}
22static inline void nfsd_forget_locks(u64 num) {}
23static inline void nfsd_forget_openowners(u64 num) {}
24static inline void nfsd_forget_delegations(u64 num) {}
25static inline void nfsd_recall_delegations(u64 num) {}
26#endif /* CONFIG_NFSD_FAULT_INJECTION */
27
28#endif /* LINUX_NFSD_FAULT_INJECT_H */
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 65c2431ea32f..1051bebff1b0 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -24,7 +24,18 @@
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/netns/generic.h> 25#include <net/netns/generic.h>
26 26
27/* Hash tables for nfs4_clientid state */
28#define CLIENT_HASH_BITS 4
29#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
30#define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
31
32#define LOCKOWNER_INO_HASH_BITS 8
33#define LOCKOWNER_INO_HASH_SIZE (1 << LOCKOWNER_INO_HASH_BITS)
34
35#define SESSION_HASH_SIZE 512
36
27struct cld_net; 37struct cld_net;
38struct nfsd4_client_tracking_ops;
28 39
29struct nfsd_net { 40struct nfsd_net {
30 struct cld_net *cld_net; 41 struct cld_net *cld_net;
@@ -38,7 +49,62 @@ struct nfsd_net {
38 struct lock_manager nfsd4_manager; 49 struct lock_manager nfsd4_manager;
39 bool grace_ended; 50 bool grace_ended;
40 time_t boot_time; 51 time_t boot_time;
52
53 /*
54 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
55 * used in reboot/reset lease grace period processing
56 *
57 * conf_id_hashtbl[], and conf_name_tree hold confirmed
58 * setclientid_confirmed info.
59 *
60 * unconf_str_hastbl[] and unconf_name_tree hold unconfirmed
61 * setclientid info.
62 */
63 struct list_head *reclaim_str_hashtbl;
64 int reclaim_str_hashtbl_size;
65 struct list_head *conf_id_hashtbl;
66 struct rb_root conf_name_tree;
67 struct list_head *unconf_id_hashtbl;
68 struct rb_root unconf_name_tree;
69 struct list_head *ownerstr_hashtbl;
70 struct list_head *lockowner_ino_hashtbl;
71 struct list_head *sessionid_hashtbl;
72 /*
73 * client_lru holds client queue ordered by nfs4_client.cl_time
74 * for lease renewal.
75 *
76 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
77 * for last close replay.
78 *
79 * All of the above fields are protected by the client_mutex.
80 */
81 struct list_head client_lru;
82 struct list_head close_lru;
83
84 struct delayed_work laundromat_work;
85
86 /* client_lock protects the client lru list and session hash table */
87 spinlock_t client_lock;
88
89 struct file *rec_file;
90 bool in_grace;
91 struct nfsd4_client_tracking_ops *client_tracking_ops;
92
93 time_t nfsd4_lease;
94 time_t nfsd4_grace;
95
96 bool nfsd_net_up;
97
98 /*
99 * Time of server startup
100 */
101 struct timeval nfssvc_boot;
102
103 struct svc_serv *nfsd_serv;
41}; 104};
42 105
106/* Simple check to find out if a given net was properly initialized */
107#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
108
43extern int nfsd_net_id; 109extern int nfsd_net_id;
44#endif /* __NFSD_NETNS_H__ */ 110#endif /* __NFSD_NETNS_H__ */
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index b314888825d5..9170861c804a 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -253,7 +253,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
253 (resp->mask & NFS_ACL) ? resp->acl_access : NULL, 253 (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
254 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); 254 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
255 while (w > 0) { 255 while (w > 0) {
256 if (!rqstp->rq_respages[rqstp->rq_resused++]) 256 if (!*(rqstp->rq_next_page++))
257 return 0; 257 return 0;
258 w -= PAGE_SIZE; 258 w -= PAGE_SIZE;
259 } 259 }
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index a596e9d987e4..9cbc1a841f87 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -184,7 +184,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
184 (resp->mask & NFS_ACL) ? resp->acl_access : NULL, 184 (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
185 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); 185 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
186 while (w > 0) { 186 while (w > 0) {
187 if (!rqstp->rq_respages[rqstp->rq_resused++]) 187 if (!*(rqstp->rq_next_page++))
188 return 0; 188 return 0;
189 w -= PAGE_SIZE; 189 w -= PAGE_SIZE;
190 } 190 }
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 97d90d1c8608..1fc02dfdc5c4 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -460,7 +460,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
460 __be32 nfserr; 460 __be32 nfserr;
461 int count = 0; 461 int count = 0;
462 loff_t offset; 462 loff_t offset;
463 int i; 463 struct page **p;
464 caddr_t page_addr = NULL; 464 caddr_t page_addr = NULL;
465 465
466 dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n", 466 dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n",
@@ -484,8 +484,8 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
484 &resp->common, 484 &resp->common,
485 nfs3svc_encode_entry_plus); 485 nfs3svc_encode_entry_plus);
486 memcpy(resp->verf, argp->verf, 8); 486 memcpy(resp->verf, argp->verf, 8);
487 for (i=1; i<rqstp->rq_resused ; i++) { 487 for (p = rqstp->rq_respages + 1; p < rqstp->rq_next_page; p++) {
488 page_addr = page_address(rqstp->rq_respages[i]); 488 page_addr = page_address(*p);
489 489
490 if (((caddr_t)resp->buffer >= page_addr) && 490 if (((caddr_t)resp->buffer >= page_addr) &&
491 ((caddr_t)resp->buffer < page_addr + PAGE_SIZE)) { 491 ((caddr_t)resp->buffer < page_addr + PAGE_SIZE)) {
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 43f46cd9edea..324c0baf7cda 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -7,8 +7,10 @@
7 */ 7 */
8 8
9#include <linux/namei.h> 9#include <linux/namei.h>
10#include <linux/sunrpc/svc_xprt.h>
10#include "xdr3.h" 11#include "xdr3.h"
11#include "auth.h" 12#include "auth.h"
13#include "netns.h"
12 14
13#define NFSDDBG_FACILITY NFSDDBG_XDR 15#define NFSDDBG_FACILITY NFSDDBG_XDR
14 16
@@ -323,7 +325,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
323 struct nfsd3_readargs *args) 325 struct nfsd3_readargs *args)
324{ 326{
325 unsigned int len; 327 unsigned int len;
326 int v,pn; 328 int v;
327 u32 max_blocksize = svc_max_payload(rqstp); 329 u32 max_blocksize = svc_max_payload(rqstp);
328 330
329 if (!(p = decode_fh(p, &args->fh))) 331 if (!(p = decode_fh(p, &args->fh)))
@@ -338,8 +340,9 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
338 /* set up the kvec */ 340 /* set up the kvec */
339 v=0; 341 v=0;
340 while (len > 0) { 342 while (len > 0) {
341 pn = rqstp->rq_resused++; 343 struct page *p = *(rqstp->rq_next_page++);
342 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]); 344
345 rqstp->rq_vec[v].iov_base = page_address(p);
343 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE; 346 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
344 len -= rqstp->rq_vec[v].iov_len; 347 len -= rqstp->rq_vec[v].iov_len;
345 v++; 348 v++;
@@ -461,8 +464,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
461 len = ntohl(*p++); 464 len = ntohl(*p++);
462 if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE) 465 if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
463 return 0; 466 return 0;
464 args->tname = new = 467 args->tname = new = page_address(*(rqstp->rq_next_page++));
465 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
466 args->tlen = len; 468 args->tlen = len;
467 /* first copy and check from the first page */ 469 /* first copy and check from the first page */
468 old = (char*)p; 470 old = (char*)p;
@@ -533,8 +535,7 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
533{ 535{
534 if (!(p = decode_fh(p, &args->fh))) 536 if (!(p = decode_fh(p, &args->fh)))
535 return 0; 537 return 0;
536 args->buffer = 538 args->buffer = page_address(*(rqstp->rq_next_page++));
537 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
538 539
539 return xdr_argsize_check(rqstp, p); 540 return xdr_argsize_check(rqstp, p);
540} 541}
@@ -565,8 +566,7 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
565 if (args->count > PAGE_SIZE) 566 if (args->count > PAGE_SIZE)
566 args->count = PAGE_SIZE; 567 args->count = PAGE_SIZE;
567 568
568 args->buffer = 569 args->buffer = page_address(*(rqstp->rq_next_page++));
569 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
570 570
571 return xdr_argsize_check(rqstp, p); 571 return xdr_argsize_check(rqstp, p);
572} 572}
@@ -575,7 +575,7 @@ int
575nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, 575nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
576 struct nfsd3_readdirargs *args) 576 struct nfsd3_readdirargs *args)
577{ 577{
578 int len, pn; 578 int len;
579 u32 max_blocksize = svc_max_payload(rqstp); 579 u32 max_blocksize = svc_max_payload(rqstp);
580 580
581 if (!(p = decode_fh(p, &args->fh))) 581 if (!(p = decode_fh(p, &args->fh)))
@@ -590,9 +590,9 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
590 args->count = len; 590 args->count = len;
591 591
592 while (len > 0) { 592 while (len > 0) {
593 pn = rqstp->rq_resused++; 593 struct page *p = *(rqstp->rq_next_page++);
594 if (!args->buffer) 594 if (!args->buffer)
595 args->buffer = page_address(rqstp->rq_respages[pn]); 595 args->buffer = page_address(p);
596 len -= PAGE_SIZE; 596 len -= PAGE_SIZE;
597 } 597 }
598 598
@@ -720,12 +720,14 @@ int
720nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p, 720nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p,
721 struct nfsd3_writeres *resp) 721 struct nfsd3_writeres *resp)
722{ 722{
723 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
724
723 p = encode_wcc_data(rqstp, p, &resp->fh); 725 p = encode_wcc_data(rqstp, p, &resp->fh);
724 if (resp->status == 0) { 726 if (resp->status == 0) {
725 *p++ = htonl(resp->count); 727 *p++ = htonl(resp->count);
726 *p++ = htonl(resp->committed); 728 *p++ = htonl(resp->committed);
727 *p++ = htonl(nfssvc_boot.tv_sec); 729 *p++ = htonl(nn->nfssvc_boot.tv_sec);
728 *p++ = htonl(nfssvc_boot.tv_usec); 730 *p++ = htonl(nn->nfssvc_boot.tv_usec);
729 } 731 }
730 return xdr_ressize_check(rqstp, p); 732 return xdr_ressize_check(rqstp, p);
731} 733}
@@ -876,7 +878,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
876 common); 878 common);
877 __be32 *p = cd->buffer; 879 __be32 *p = cd->buffer;
878 caddr_t curr_page_addr = NULL; 880 caddr_t curr_page_addr = NULL;
879 int pn; /* current page number */ 881 struct page ** page;
880 int slen; /* string (name) length */ 882 int slen; /* string (name) length */
881 int elen; /* estimated entry length in words */ 883 int elen; /* estimated entry length in words */
882 int num_entry_words = 0; /* actual number of words */ 884 int num_entry_words = 0; /* actual number of words */
@@ -913,8 +915,9 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
913 } 915 }
914 916
915 /* determine which page in rq_respages[] we are currently filling */ 917 /* determine which page in rq_respages[] we are currently filling */
916 for (pn=1; pn < cd->rqstp->rq_resused; pn++) { 918 for (page = cd->rqstp->rq_respages + 1;
917 curr_page_addr = page_address(cd->rqstp->rq_respages[pn]); 919 page < cd->rqstp->rq_next_page; page++) {
920 curr_page_addr = page_address(*page);
918 921
919 if (((caddr_t)cd->buffer >= curr_page_addr) && 922 if (((caddr_t)cd->buffer >= curr_page_addr) &&
920 ((caddr_t)cd->buffer < curr_page_addr + PAGE_SIZE)) 923 ((caddr_t)cd->buffer < curr_page_addr + PAGE_SIZE))
@@ -929,14 +932,14 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
929 if (plus) 932 if (plus)
930 p = encode_entryplus_baggage(cd, p, name, namlen); 933 p = encode_entryplus_baggage(cd, p, name, namlen);
931 num_entry_words = p - cd->buffer; 934 num_entry_words = p - cd->buffer;
932 } else if (cd->rqstp->rq_respages[pn+1] != NULL) { 935 } else if (*(page+1) != NULL) {
933 /* temporarily encode entry into next page, then move back to 936 /* temporarily encode entry into next page, then move back to
934 * current and next page in rq_respages[] */ 937 * current and next page in rq_respages[] */
935 __be32 *p1, *tmp; 938 __be32 *p1, *tmp;
936 int len1, len2; 939 int len1, len2;
937 940
938 /* grab next page for temporary storage of entry */ 941 /* grab next page for temporary storage of entry */
939 p1 = tmp = page_address(cd->rqstp->rq_respages[pn+1]); 942 p1 = tmp = page_address(*(page+1));
940 943
941 p1 = encode_entry_baggage(cd, p1, name, namlen, ino); 944 p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
942 945
@@ -1082,11 +1085,13 @@ int
1082nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p, 1085nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p,
1083 struct nfsd3_commitres *resp) 1086 struct nfsd3_commitres *resp)
1084{ 1087{
1088 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1089
1085 p = encode_wcc_data(rqstp, p, &resp->fh); 1090 p = encode_wcc_data(rqstp, p, &resp->fh);
1086 /* Write verifier */ 1091 /* Write verifier */
1087 if (resp->status == 0) { 1092 if (resp->status == 0) {
1088 *p++ = htonl(nfssvc_boot.tv_sec); 1093 *p++ = htonl(nn->nfssvc_boot.tv_sec);
1089 *p++ = htonl(nfssvc_boot.tv_usec); 1094 *p++ = htonl(nn->nfssvc_boot.tv_usec);
1090 } 1095 }
1091 return xdr_ressize_check(rqstp, p); 1096 return xdr_ressize_check(rqstp, p);
1092} 1097}
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index bdf29c96e4cd..99bc85ff0217 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -36,6 +36,7 @@
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include "nfsd.h" 37#include "nfsd.h"
38#include "state.h" 38#include "state.h"
39#include "netns.h"
39 40
40#define NFSDDBG_FACILITY NFSDDBG_PROC 41#define NFSDDBG_FACILITY NFSDDBG_PROC
41 42
@@ -625,20 +626,46 @@ static const struct rpc_program cb_program = {
625 .pipe_dir_name = "nfsd4_cb", 626 .pipe_dir_name = "nfsd4_cb",
626}; 627};
627 628
628static int max_cb_time(void) 629static int max_cb_time(struct net *net)
629{ 630{
630 return max(nfsd4_lease/10, (time_t)1) * HZ; 631 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
632 return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
631} 633}
632 634
635static struct rpc_cred *callback_cred;
636
637int set_callback_cred(void)
638{
639 if (callback_cred)
640 return 0;
641 callback_cred = rpc_lookup_machine_cred("nfs");
642 if (!callback_cred)
643 return -ENOMEM;
644 return 0;
645}
646
647static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
648{
649 if (clp->cl_minorversion == 0) {
650 return get_rpccred(callback_cred);
651 } else {
652 struct rpc_auth *auth = client->cl_auth;
653 struct auth_cred acred = {};
654
655 acred.uid = ses->se_cb_sec.uid;
656 acred.gid = ses->se_cb_sec.gid;
657 return auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
658 }
659}
633 660
634static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) 661static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
635{ 662{
636 struct rpc_timeout timeparms = { 663 struct rpc_timeout timeparms = {
637 .to_initval = max_cb_time(), 664 .to_initval = max_cb_time(clp->net),
638 .to_retries = 0, 665 .to_retries = 0,
639 }; 666 };
640 struct rpc_create_args args = { 667 struct rpc_create_args args = {
641 .net = &init_net, 668 .net = clp->net,
642 .address = (struct sockaddr *) &conn->cb_addr, 669 .address = (struct sockaddr *) &conn->cb_addr,
643 .addrsize = conn->cb_addrlen, 670 .addrsize = conn->cb_addrlen,
644 .saddress = (struct sockaddr *) &conn->cb_saddr, 671 .saddress = (struct sockaddr *) &conn->cb_saddr,
@@ -648,6 +675,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
648 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), 675 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
649 }; 676 };
650 struct rpc_clnt *client; 677 struct rpc_clnt *client;
678 struct rpc_cred *cred;
651 679
652 if (clp->cl_minorversion == 0) { 680 if (clp->cl_minorversion == 0) {
653 if (!clp->cl_cred.cr_principal && 681 if (!clp->cl_cred.cr_principal &&
@@ -666,7 +694,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
666 args.bc_xprt = conn->cb_xprt; 694 args.bc_xprt = conn->cb_xprt;
667 args.prognumber = clp->cl_cb_session->se_cb_prog; 695 args.prognumber = clp->cl_cb_session->se_cb_prog;
668 args.protocol = XPRT_TRANSPORT_BC_TCP; 696 args.protocol = XPRT_TRANSPORT_BC_TCP;
669 args.authflavor = RPC_AUTH_UNIX; 697 args.authflavor = ses->se_cb_sec.flavor;
670 } 698 }
671 /* Create RPC client */ 699 /* Create RPC client */
672 client = rpc_create(&args); 700 client = rpc_create(&args);
@@ -675,9 +703,14 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
675 PTR_ERR(client)); 703 PTR_ERR(client));
676 return PTR_ERR(client); 704 return PTR_ERR(client);
677 } 705 }
706 cred = get_backchannel_cred(clp, client, ses);
707 if (IS_ERR(cred)) {
708 rpc_shutdown_client(client);
709 return PTR_ERR(cred);
710 }
678 clp->cl_cb_client = client; 711 clp->cl_cb_client = client;
712 clp->cl_cb_cred = cred;
679 return 0; 713 return 0;
680
681} 714}
682 715
683static void warn_no_callback_path(struct nfs4_client *clp, int reason) 716static void warn_no_callback_path(struct nfs4_client *clp, int reason)
@@ -714,18 +747,6 @@ static const struct rpc_call_ops nfsd4_cb_probe_ops = {
714 .rpc_call_done = nfsd4_cb_probe_done, 747 .rpc_call_done = nfsd4_cb_probe_done,
715}; 748};
716 749
717static struct rpc_cred *callback_cred;
718
719int set_callback_cred(void)
720{
721 if (callback_cred)
722 return 0;
723 callback_cred = rpc_lookup_machine_cred("nfs");
724 if (!callback_cred)
725 return -ENOMEM;
726 return 0;
727}
728
729static struct workqueue_struct *callback_wq; 750static struct workqueue_struct *callback_wq;
730 751
731static void run_nfsd4_cb(struct nfsd4_callback *cb) 752static void run_nfsd4_cb(struct nfsd4_callback *cb)
@@ -743,7 +764,6 @@ static void do_probe_callback(struct nfs4_client *clp)
743 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL]; 764 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL];
744 cb->cb_msg.rpc_argp = NULL; 765 cb->cb_msg.rpc_argp = NULL;
745 cb->cb_msg.rpc_resp = NULL; 766 cb->cb_msg.rpc_resp = NULL;
746 cb->cb_msg.rpc_cred = callback_cred;
747 767
748 cb->cb_ops = &nfsd4_cb_probe_ops; 768 cb->cb_ops = &nfsd4_cb_probe_ops;
749 769
@@ -962,6 +982,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
962 if (clp->cl_cb_client) { 982 if (clp->cl_cb_client) {
963 rpc_shutdown_client(clp->cl_cb_client); 983 rpc_shutdown_client(clp->cl_cb_client);
964 clp->cl_cb_client = NULL; 984 clp->cl_cb_client = NULL;
985 put_rpccred(clp->cl_cb_cred);
986 clp->cl_cb_cred = NULL;
965 } 987 }
966 if (clp->cl_cb_conn.cb_xprt) { 988 if (clp->cl_cb_conn.cb_xprt) {
967 svc_xprt_put(clp->cl_cb_conn.cb_xprt); 989 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
@@ -995,7 +1017,7 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
995 run_nfsd4_cb(cb); 1017 run_nfsd4_cb(cb);
996} 1018}
997 1019
998void nfsd4_do_callback_rpc(struct work_struct *w) 1020static void nfsd4_do_callback_rpc(struct work_struct *w)
999{ 1021{
1000 struct nfsd4_callback *cb = container_of(w, struct nfsd4_callback, cb_work); 1022 struct nfsd4_callback *cb = container_of(w, struct nfsd4_callback, cb_work);
1001 struct nfs4_client *clp = cb->cb_clp; 1023 struct nfs4_client *clp = cb->cb_clp;
@@ -1010,10 +1032,16 @@ void nfsd4_do_callback_rpc(struct work_struct *w)
1010 nfsd4_release_cb(cb); 1032 nfsd4_release_cb(cb);
1011 return; 1033 return;
1012 } 1034 }
1035 cb->cb_msg.rpc_cred = clp->cl_cb_cred;
1013 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN, 1036 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
1014 cb->cb_ops, cb); 1037 cb->cb_ops, cb);
1015} 1038}
1016 1039
1040void nfsd4_init_callback(struct nfsd4_callback *cb)
1041{
1042 INIT_WORK(&cb->cb_work, nfsd4_do_callback_rpc);
1043}
1044
1017void nfsd4_cb_recall(struct nfs4_delegation *dp) 1045void nfsd4_cb_recall(struct nfs4_delegation *dp)
1018{ 1046{
1019 struct nfsd4_callback *cb = &dp->dl_recall; 1047 struct nfsd4_callback *cb = &dp->dl_recall;
@@ -1025,7 +1053,6 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp)
1025 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL]; 1053 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
1026 cb->cb_msg.rpc_argp = cb; 1054 cb->cb_msg.rpc_argp = cb;
1027 cb->cb_msg.rpc_resp = cb; 1055 cb->cb_msg.rpc_resp = cb;
1028 cb->cb_msg.rpc_cred = callback_cred;
1029 1056
1030 cb->cb_ops = &nfsd4_cb_recall_ops; 1057 cb->cb_ops = &nfsd4_cb_recall_ops;
1031 1058
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 6c9a4b291dba..9d1c5dba2bbb 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -40,6 +40,7 @@
40#include "xdr4.h" 40#include "xdr4.h"
41#include "vfs.h" 41#include "vfs.h"
42#include "current_stateid.h" 42#include "current_stateid.h"
43#include "netns.h"
43 44
44#define NFSDDBG_FACILITY NFSDDBG_PROC 45#define NFSDDBG_FACILITY NFSDDBG_PROC
45 46
@@ -194,6 +195,7 @@ static __be32
194do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 195do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
195{ 196{
196 struct svc_fh *resfh; 197 struct svc_fh *resfh;
198 int accmode;
197 __be32 status; 199 __be32 status;
198 200
199 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); 201 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
@@ -253,9 +255,10 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
253 /* set reply cache */ 255 /* set reply cache */
254 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 256 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
255 &resfh->fh_handle); 257 &resfh->fh_handle);
256 if (!open->op_created) 258 accmode = NFSD_MAY_NOP;
257 status = do_open_permission(rqstp, resfh, open, 259 if (open->op_created)
258 NFSD_MAY_NOP); 260 accmode |= NFSD_MAY_OWNER_OVERRIDE;
261 status = do_open_permission(rqstp, resfh, open, accmode);
259 set_change_info(&open->op_cinfo, current_fh); 262 set_change_info(&open->op_cinfo, current_fh);
260 fh_dup2(current_fh, resfh); 263 fh_dup2(current_fh, resfh);
261out: 264out:
@@ -304,6 +307,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
304{ 307{
305 __be32 status; 308 __be32 status;
306 struct nfsd4_compoundres *resp; 309 struct nfsd4_compoundres *resp;
310 struct net *net = SVC_NET(rqstp);
311 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
307 312
308 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n", 313 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
309 (int)open->op_fname.len, open->op_fname.data, 314 (int)open->op_fname.len, open->op_fname.data,
@@ -331,7 +336,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
331 336
332 /* check seqid for replay. set nfs4_owner */ 337 /* check seqid for replay. set nfs4_owner */
333 resp = rqstp->rq_resp; 338 resp = rqstp->rq_resp;
334 status = nfsd4_process_open1(&resp->cstate, open); 339 status = nfsd4_process_open1(&resp->cstate, open, nn);
335 if (status == nfserr_replay_me) { 340 if (status == nfserr_replay_me) {
336 struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay; 341 struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay;
337 fh_put(&cstate->current_fh); 342 fh_put(&cstate->current_fh);
@@ -354,10 +359,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
354 /* Openowner is now set, so sequence id will get bumped. Now we need 359 /* Openowner is now set, so sequence id will get bumped. Now we need
355 * these checks before we do any creates: */ 360 * these checks before we do any creates: */
356 status = nfserr_grace; 361 status = nfserr_grace;
357 if (locks_in_grace(SVC_NET(rqstp)) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 362 if (locks_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
358 goto out; 363 goto out;
359 status = nfserr_no_grace; 364 status = nfserr_no_grace;
360 if (!locks_in_grace(SVC_NET(rqstp)) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 365 if (!locks_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
361 goto out; 366 goto out;
362 367
363 switch (open->op_claim_type) { 368 switch (open->op_claim_type) {
@@ -370,7 +375,9 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
370 break; 375 break;
371 case NFS4_OPEN_CLAIM_PREVIOUS: 376 case NFS4_OPEN_CLAIM_PREVIOUS:
372 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 377 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
373 status = nfs4_check_open_reclaim(&open->op_clientid, cstate->minorversion); 378 status = nfs4_check_open_reclaim(&open->op_clientid,
379 cstate->minorversion,
380 nn);
374 if (status) 381 if (status)
375 goto out; 382 goto out;
376 case NFS4_OPEN_CLAIM_FH: 383 case NFS4_OPEN_CLAIM_FH:
@@ -490,12 +497,13 @@ nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
490 &access->ac_supported); 497 &access->ac_supported);
491} 498}
492 499
493static void gen_boot_verifier(nfs4_verifier *verifier) 500static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net)
494{ 501{
495 __be32 verf[2]; 502 __be32 verf[2];
503 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
496 504
497 verf[0] = (__be32)nfssvc_boot.tv_sec; 505 verf[0] = (__be32)nn->nfssvc_boot.tv_sec;
498 verf[1] = (__be32)nfssvc_boot.tv_usec; 506 verf[1] = (__be32)nn->nfssvc_boot.tv_usec;
499 memcpy(verifier->data, verf, sizeof(verifier->data)); 507 memcpy(verifier->data, verf, sizeof(verifier->data));
500} 508}
501 509
@@ -503,7 +511,7 @@ static __be32
503nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 511nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
504 struct nfsd4_commit *commit) 512 struct nfsd4_commit *commit)
505{ 513{
506 gen_boot_verifier(&commit->co_verf); 514 gen_boot_verifier(&commit->co_verf, SVC_NET(rqstp));
507 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 515 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
508 commit->co_count); 516 commit->co_count);
509} 517}
@@ -684,6 +692,17 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
684 if (read->rd_offset >= OFFSET_MAX) 692 if (read->rd_offset >= OFFSET_MAX)
685 return nfserr_inval; 693 return nfserr_inval;
686 694
695 /*
696 * If we do a zero copy read, then a client will see read data
697 * that reflects the state of the file *after* performing the
698 * following compound.
699 *
700 * To ensure proper ordering, we therefore turn off zero copy if
701 * the client wants us to do more in this compound:
702 */
703 if (!nfsd4_last_compound_op(rqstp))
704 rqstp->rq_splice_ok = false;
705
687 nfs4_lock_state(); 706 nfs4_lock_state();
688 /* check stateid */ 707 /* check stateid */
689 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), 708 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
@@ -876,6 +895,24 @@ out:
876 return status; 895 return status;
877} 896}
878 897
898static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
899{
900 int i = 1;
901 int buflen = write->wr_buflen;
902
903 vec[0].iov_base = write->wr_head.iov_base;
904 vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
905 buflen -= vec[0].iov_len;
906
907 while (buflen) {
908 vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
909 vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
910 buflen -= vec[i].iov_len;
911 i++;
912 }
913 return i;
914}
915
879static __be32 916static __be32
880nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 917nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
881 struct nfsd4_write *write) 918 struct nfsd4_write *write)
@@ -884,6 +921,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
884 struct file *filp = NULL; 921 struct file *filp = NULL;
885 __be32 status = nfs_ok; 922 __be32 status = nfs_ok;
886 unsigned long cnt; 923 unsigned long cnt;
924 int nvecs;
887 925
888 /* no need to check permission - this will be done in nfsd_write() */ 926 /* no need to check permission - this will be done in nfsd_write() */
889 927
@@ -904,10 +942,13 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
904 942
905 cnt = write->wr_buflen; 943 cnt = write->wr_buflen;
906 write->wr_how_written = write->wr_stable_how; 944 write->wr_how_written = write->wr_stable_how;
907 gen_boot_verifier(&write->wr_verifier); 945 gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
946
947 nvecs = fill_in_write_vector(rqstp->rq_vec, write);
948 WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
908 949
909 status = nfsd_write(rqstp, &cstate->current_fh, filp, 950 status = nfsd_write(rqstp, &cstate->current_fh, filp,
910 write->wr_offset, rqstp->rq_vec, write->wr_vlen, 951 write->wr_offset, rqstp->rq_vec, nvecs,
911 &cnt, &write->wr_how_written); 952 &cnt, &write->wr_how_written);
912 if (filp) 953 if (filp)
913 fput(filp); 954 fput(filp);
@@ -1666,6 +1707,12 @@ static struct nfsd4_operation nfsd4_ops[] = {
1666 .op_name = "OP_EXCHANGE_ID", 1707 .op_name = "OP_EXCHANGE_ID",
1667 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize, 1708 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize,
1668 }, 1709 },
1710 [OP_BACKCHANNEL_CTL] = {
1711 .op_func = (nfsd4op_func)nfsd4_backchannel_ctl,
1712 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1713 .op_name = "OP_BACKCHANNEL_CTL",
1714 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1715 },
1669 [OP_BIND_CONN_TO_SESSION] = { 1716 [OP_BIND_CONN_TO_SESSION] = {
1670 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, 1717 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
1671 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1718 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
@@ -1719,6 +1766,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1719 .op_func = (nfsd4op_func)nfsd4_free_stateid, 1766 .op_func = (nfsd4op_func)nfsd4_free_stateid,
1720 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, 1767 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1721 .op_name = "OP_FREE_STATEID", 1768 .op_name = "OP_FREE_STATEID",
1769 .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
1722 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1770 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1723 }, 1771 },
1724}; 1772};
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 43295d45cc2b..ba6fdd4a0455 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -58,13 +58,11 @@ struct nfsd4_client_tracking_ops {
58 void (*create)(struct nfs4_client *); 58 void (*create)(struct nfs4_client *);
59 void (*remove)(struct nfs4_client *); 59 void (*remove)(struct nfs4_client *);
60 int (*check)(struct nfs4_client *); 60 int (*check)(struct nfs4_client *);
61 void (*grace_done)(struct net *, time_t); 61 void (*grace_done)(struct nfsd_net *, time_t);
62}; 62};
63 63
64/* Globals */ 64/* Globals */
65static struct file *rec_file;
66static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; 65static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
67static struct nfsd4_client_tracking_ops *client_tracking_ops;
68 66
69static int 67static int
70nfs4_save_creds(const struct cred **original_creds) 68nfs4_save_creds(const struct cred **original_creds)
@@ -102,33 +100,39 @@ md5_to_hex(char *out, char *md5)
102 *out = '\0'; 100 *out = '\0';
103} 101}
104 102
105__be32 103static int
106nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) 104nfs4_make_rec_clidname(char *dname, const struct xdr_netobj *clname)
107{ 105{
108 struct xdr_netobj cksum; 106 struct xdr_netobj cksum;
109 struct hash_desc desc; 107 struct hash_desc desc;
110 struct scatterlist sg; 108 struct scatterlist sg;
111 __be32 status = nfserr_jukebox; 109 int status;
112 110
113 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 111 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
114 clname->len, clname->data); 112 clname->len, clname->data);
115 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; 113 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
116 desc.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC); 114 desc.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
117 if (IS_ERR(desc.tfm)) 115 if (IS_ERR(desc.tfm)) {
116 status = PTR_ERR(desc.tfm);
118 goto out_no_tfm; 117 goto out_no_tfm;
118 }
119
119 cksum.len = crypto_hash_digestsize(desc.tfm); 120 cksum.len = crypto_hash_digestsize(desc.tfm);
120 cksum.data = kmalloc(cksum.len, GFP_KERNEL); 121 cksum.data = kmalloc(cksum.len, GFP_KERNEL);
121 if (cksum.data == NULL) 122 if (cksum.data == NULL) {
123 status = -ENOMEM;
122 goto out; 124 goto out;
125 }
123 126
124 sg_init_one(&sg, clname->data, clname->len); 127 sg_init_one(&sg, clname->data, clname->len);
125 128
126 if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data)) 129 status = crypto_hash_digest(&desc, &sg, sg.length, cksum.data);
130 if (status)
127 goto out; 131 goto out;
128 132
129 md5_to_hex(dname, cksum.data); 133 md5_to_hex(dname, cksum.data);
130 134
131 status = nfs_ok; 135 status = 0;
132out: 136out:
133 kfree(cksum.data); 137 kfree(cksum.data);
134 crypto_free_hash(desc.tfm); 138 crypto_free_hash(desc.tfm);
@@ -136,29 +140,61 @@ out_no_tfm:
136 return status; 140 return status;
137} 141}
138 142
143/*
144 * If we had an error generating the recdir name for the legacy tracker
145 * then warn the admin. If the error doesn't appear to be transient,
146 * then disable recovery tracking.
147 */
148static void
149legacy_recdir_name_error(int error)
150{
151 printk(KERN_ERR "NFSD: unable to generate recoverydir "
152 "name (%d).\n", error);
153
154 /*
155 * if the algorithm just doesn't exist, then disable the recovery
156 * tracker altogether. The crypto libs will generally return this if
157 * FIPS is enabled as well.
158 */
159 if (error == -ENOENT) {
160 printk(KERN_ERR "NFSD: disabling legacy clientid tracking. "
161 "Reboot recovery will not function correctly!\n");
162
163 /* the argument is ignored by the legacy exit function */
164 nfsd4_client_tracking_exit(NULL);
165 }
166}
167
139static void 168static void
140nfsd4_create_clid_dir(struct nfs4_client *clp) 169nfsd4_create_clid_dir(struct nfs4_client *clp)
141{ 170{
142 const struct cred *original_cred; 171 const struct cred *original_cred;
143 char *dname = clp->cl_recdir; 172 char dname[HEXDIR_LEN];
144 struct dentry *dir, *dentry; 173 struct dentry *dir, *dentry;
174 struct nfs4_client_reclaim *crp;
145 int status; 175 int status;
176 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
146 177
147 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); 178 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
148 179
149 if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 180 if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
150 return; 181 return;
151 if (!rec_file) 182 if (!nn->rec_file)
152 return; 183 return;
184
185 status = nfs4_make_rec_clidname(dname, &clp->cl_name);
186 if (status)
187 return legacy_recdir_name_error(status);
188
153 status = nfs4_save_creds(&original_cred); 189 status = nfs4_save_creds(&original_cred);
154 if (status < 0) 190 if (status < 0)
155 return; 191 return;
156 192
157 status = mnt_want_write_file(rec_file); 193 status = mnt_want_write_file(nn->rec_file);
158 if (status) 194 if (status)
159 return; 195 return;
160 196
161 dir = rec_file->f_path.dentry; 197 dir = nn->rec_file->f_path.dentry;
162 /* lock the parent */ 198 /* lock the parent */
163 mutex_lock(&dir->d_inode->i_mutex); 199 mutex_lock(&dir->d_inode->i_mutex);
164 200
@@ -182,18 +218,24 @@ out_put:
182 dput(dentry); 218 dput(dentry);
183out_unlock: 219out_unlock:
184 mutex_unlock(&dir->d_inode->i_mutex); 220 mutex_unlock(&dir->d_inode->i_mutex);
185 if (status == 0) 221 if (status == 0) {
186 vfs_fsync(rec_file, 0); 222 if (nn->in_grace) {
187 else 223 crp = nfs4_client_to_reclaim(dname, nn);
224 if (crp)
225 crp->cr_clp = clp;
226 }
227 vfs_fsync(nn->rec_file, 0);
228 } else {
188 printk(KERN_ERR "NFSD: failed to write recovery record" 229 printk(KERN_ERR "NFSD: failed to write recovery record"
189 " (err %d); please check that %s exists" 230 " (err %d); please check that %s exists"
190 " and is writeable", status, 231 " and is writeable", status,
191 user_recovery_dirname); 232 user_recovery_dirname);
192 mnt_drop_write_file(rec_file); 233 }
234 mnt_drop_write_file(nn->rec_file);
193 nfs4_reset_creds(original_cred); 235 nfs4_reset_creds(original_cred);
194} 236}
195 237
196typedef int (recdir_func)(struct dentry *, struct dentry *); 238typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *);
197 239
198struct name_list { 240struct name_list {
199 char name[HEXDIR_LEN]; 241 char name[HEXDIR_LEN];
@@ -219,10 +261,10 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
219} 261}
220 262
221static int 263static int
222nfsd4_list_rec_dir(recdir_func *f) 264nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
223{ 265{
224 const struct cred *original_cred; 266 const struct cred *original_cred;
225 struct dentry *dir = rec_file->f_path.dentry; 267 struct dentry *dir = nn->rec_file->f_path.dentry;
226 LIST_HEAD(names); 268 LIST_HEAD(names);
227 int status; 269 int status;
228 270
@@ -230,13 +272,13 @@ nfsd4_list_rec_dir(recdir_func *f)
230 if (status < 0) 272 if (status < 0)
231 return status; 273 return status;
232 274
233 status = vfs_llseek(rec_file, 0, SEEK_SET); 275 status = vfs_llseek(nn->rec_file, 0, SEEK_SET);
234 if (status < 0) { 276 if (status < 0) {
235 nfs4_reset_creds(original_cred); 277 nfs4_reset_creds(original_cred);
236 return status; 278 return status;
237 } 279 }
238 280
239 status = vfs_readdir(rec_file, nfsd4_build_namelist, &names); 281 status = vfs_readdir(nn->rec_file, nfsd4_build_namelist, &names);
240 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); 282 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
241 while (!list_empty(&names)) { 283 while (!list_empty(&names)) {
242 struct name_list *entry; 284 struct name_list *entry;
@@ -248,7 +290,7 @@ nfsd4_list_rec_dir(recdir_func *f)
248 status = PTR_ERR(dentry); 290 status = PTR_ERR(dentry);
249 break; 291 break;
250 } 292 }
251 status = f(dir, dentry); 293 status = f(dir, dentry, nn);
252 dput(dentry); 294 dput(dentry);
253 } 295 }
254 list_del(&entry->list); 296 list_del(&entry->list);
@@ -260,14 +302,14 @@ nfsd4_list_rec_dir(recdir_func *f)
260} 302}
261 303
262static int 304static int
263nfsd4_unlink_clid_dir(char *name, int namlen) 305nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
264{ 306{
265 struct dentry *dir, *dentry; 307 struct dentry *dir, *dentry;
266 int status; 308 int status;
267 309
268 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); 310 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
269 311
270 dir = rec_file->f_path.dentry; 312 dir = nn->rec_file->f_path.dentry;
271 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); 313 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
272 dentry = lookup_one_len(name, dir, namlen); 314 dentry = lookup_one_len(name, dir, namlen);
273 if (IS_ERR(dentry)) { 315 if (IS_ERR(dentry)) {
@@ -289,37 +331,52 @@ static void
289nfsd4_remove_clid_dir(struct nfs4_client *clp) 331nfsd4_remove_clid_dir(struct nfs4_client *clp)
290{ 332{
291 const struct cred *original_cred; 333 const struct cred *original_cred;
334 struct nfs4_client_reclaim *crp;
335 char dname[HEXDIR_LEN];
292 int status; 336 int status;
337 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
293 338
294 if (!rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 339 if (!nn->rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
295 return; 340 return;
296 341
297 status = mnt_want_write_file(rec_file); 342 status = nfs4_make_rec_clidname(dname, &clp->cl_name);
343 if (status)
344 return legacy_recdir_name_error(status);
345
346 status = mnt_want_write_file(nn->rec_file);
298 if (status) 347 if (status)
299 goto out; 348 goto out;
300 clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); 349 clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
301 350
302 status = nfs4_save_creds(&original_cred); 351 status = nfs4_save_creds(&original_cred);
303 if (status < 0) 352 if (status < 0)
304 goto out; 353 goto out_drop_write;
305 354
306 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); 355 status = nfsd4_unlink_clid_dir(dname, HEXDIR_LEN-1, nn);
307 nfs4_reset_creds(original_cred); 356 nfs4_reset_creds(original_cred);
308 if (status == 0) 357 if (status == 0) {
309 vfs_fsync(rec_file, 0); 358 vfs_fsync(nn->rec_file, 0);
310 mnt_drop_write_file(rec_file); 359 if (nn->in_grace) {
360 /* remove reclaim record */
361 crp = nfsd4_find_reclaim_client(dname, nn);
362 if (crp)
363 nfs4_remove_reclaim_record(crp, nn);
364 }
365 }
366out_drop_write:
367 mnt_drop_write_file(nn->rec_file);
311out: 368out:
312 if (status) 369 if (status)
313 printk("NFSD: Failed to remove expired client state directory" 370 printk("NFSD: Failed to remove expired client state directory"
314 " %.*s\n", HEXDIR_LEN, clp->cl_recdir); 371 " %.*s\n", HEXDIR_LEN, dname);
315} 372}
316 373
317static int 374static int
318purge_old(struct dentry *parent, struct dentry *child) 375purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
319{ 376{
320 int status; 377 int status;
321 378
322 if (nfs4_has_reclaimed_state(child->d_name.name, false)) 379 if (nfs4_has_reclaimed_state(child->d_name.name, nn))
323 return 0; 380 return 0;
324 381
325 status = vfs_rmdir(parent->d_inode, child); 382 status = vfs_rmdir(parent->d_inode, child);
@@ -331,27 +388,29 @@ purge_old(struct dentry *parent, struct dentry *child)
331} 388}
332 389
333static void 390static void
334nfsd4_recdir_purge_old(struct net *net, time_t boot_time) 391nfsd4_recdir_purge_old(struct nfsd_net *nn, time_t boot_time)
335{ 392{
336 int status; 393 int status;
337 394
338 if (!rec_file) 395 nn->in_grace = false;
396 if (!nn->rec_file)
339 return; 397 return;
340 status = mnt_want_write_file(rec_file); 398 status = mnt_want_write_file(nn->rec_file);
341 if (status) 399 if (status)
342 goto out; 400 goto out;
343 status = nfsd4_list_rec_dir(purge_old); 401 status = nfsd4_list_rec_dir(purge_old, nn);
344 if (status == 0) 402 if (status == 0)
345 vfs_fsync(rec_file, 0); 403 vfs_fsync(nn->rec_file, 0);
346 mnt_drop_write_file(rec_file); 404 mnt_drop_write_file(nn->rec_file);
347out: 405out:
406 nfs4_release_reclaim(nn);
348 if (status) 407 if (status)
349 printk("nfsd4: failed to purge old clients from recovery" 408 printk("nfsd4: failed to purge old clients from recovery"
350 " directory %s\n", rec_file->f_path.dentry->d_name.name); 409 " directory %s\n", nn->rec_file->f_path.dentry->d_name.name);
351} 410}
352 411
353static int 412static int
354load_recdir(struct dentry *parent, struct dentry *child) 413load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
355{ 414{
356 if (child->d_name.len != HEXDIR_LEN - 1) { 415 if (child->d_name.len != HEXDIR_LEN - 1) {
357 printk("nfsd4: illegal name %s in recovery directory\n", 416 printk("nfsd4: illegal name %s in recovery directory\n",
@@ -359,21 +418,22 @@ load_recdir(struct dentry *parent, struct dentry *child)
359 /* Keep trying; maybe the others are OK: */ 418 /* Keep trying; maybe the others are OK: */
360 return 0; 419 return 0;
361 } 420 }
362 nfs4_client_to_reclaim(child->d_name.name); 421 nfs4_client_to_reclaim(child->d_name.name, nn);
363 return 0; 422 return 0;
364} 423}
365 424
366static int 425static int
367nfsd4_recdir_load(void) { 426nfsd4_recdir_load(struct net *net) {
368 int status; 427 int status;
428 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
369 429
370 if (!rec_file) 430 if (!nn->rec_file)
371 return 0; 431 return 0;
372 432
373 status = nfsd4_list_rec_dir(load_recdir); 433 status = nfsd4_list_rec_dir(load_recdir, nn);
374 if (status) 434 if (status)
375 printk("nfsd4: failed loading clients from recovery" 435 printk("nfsd4: failed loading clients from recovery"
376 " directory %s\n", rec_file->f_path.dentry->d_name.name); 436 " directory %s\n", nn->rec_file->f_path.dentry->d_name.name);
377 return status; 437 return status;
378} 438}
379 439
@@ -382,15 +442,16 @@ nfsd4_recdir_load(void) {
382 */ 442 */
383 443
384static int 444static int
385nfsd4_init_recdir(void) 445nfsd4_init_recdir(struct net *net)
386{ 446{
447 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
387 const struct cred *original_cred; 448 const struct cred *original_cred;
388 int status; 449 int status;
389 450
390 printk("NFSD: Using %s as the NFSv4 state recovery directory\n", 451 printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
391 user_recovery_dirname); 452 user_recovery_dirname);
392 453
393 BUG_ON(rec_file); 454 BUG_ON(nn->rec_file);
394 455
395 status = nfs4_save_creds(&original_cred); 456 status = nfs4_save_creds(&original_cred);
396 if (status < 0) { 457 if (status < 0) {
@@ -400,23 +461,65 @@ nfsd4_init_recdir(void)
400 return status; 461 return status;
401 } 462 }
402 463
403 rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0); 464 nn->rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0);
404 if (IS_ERR(rec_file)) { 465 if (IS_ERR(nn->rec_file)) {
405 printk("NFSD: unable to find recovery directory %s\n", 466 printk("NFSD: unable to find recovery directory %s\n",
406 user_recovery_dirname); 467 user_recovery_dirname);
407 status = PTR_ERR(rec_file); 468 status = PTR_ERR(nn->rec_file);
408 rec_file = NULL; 469 nn->rec_file = NULL;
409 } 470 }
410 471
411 nfs4_reset_creds(original_cred); 472 nfs4_reset_creds(original_cred);
473 if (!status)
474 nn->in_grace = true;
412 return status; 475 return status;
413} 476}
414 477
478
479static int
480nfs4_legacy_state_init(struct net *net)
481{
482 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
483 int i;
484
485 nn->reclaim_str_hashtbl = kmalloc(sizeof(struct list_head) *
486 CLIENT_HASH_SIZE, GFP_KERNEL);
487 if (!nn->reclaim_str_hashtbl)
488 return -ENOMEM;
489
490 for (i = 0; i < CLIENT_HASH_SIZE; i++)
491 INIT_LIST_HEAD(&nn->reclaim_str_hashtbl[i]);
492 nn->reclaim_str_hashtbl_size = 0;
493
494 return 0;
495}
496
497static void
498nfs4_legacy_state_shutdown(struct net *net)
499{
500 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
501
502 kfree(nn->reclaim_str_hashtbl);
503}
504
415static int 505static int
416nfsd4_load_reboot_recovery_data(struct net *net) 506nfsd4_load_reboot_recovery_data(struct net *net)
417{ 507{
418 int status; 508 int status;
419 509
510 status = nfsd4_init_recdir(net);
511 if (!status)
512 status = nfsd4_recdir_load(net);
513 if (status)
514 printk(KERN_ERR "NFSD: Failure reading reboot recovery data\n");
515 return status;
516}
517
518static int
519nfsd4_legacy_tracking_init(struct net *net)
520{
521 int status;
522
420 /* XXX: The legacy code won't work in a container */ 523 /* XXX: The legacy code won't work in a container */
421 if (net != &init_net) { 524 if (net != &init_net) {
422 WARN(1, KERN_ERR "NFSD: attempt to initialize legacy client " 525 WARN(1, KERN_ERR "NFSD: attempt to initialize legacy client "
@@ -424,30 +527,37 @@ nfsd4_load_reboot_recovery_data(struct net *net)
424 return -EINVAL; 527 return -EINVAL;
425 } 528 }
426 529
427 nfs4_lock_state(); 530 status = nfs4_legacy_state_init(net);
428 status = nfsd4_init_recdir();
429 if (!status)
430 status = nfsd4_recdir_load();
431 nfs4_unlock_state();
432 if (status) 531 if (status)
433 printk(KERN_ERR "NFSD: Failure reading reboot recovery data\n"); 532 return status;
533
534 status = nfsd4_load_reboot_recovery_data(net);
535 if (status)
536 goto err;
537 return 0;
538
539err:
540 nfs4_legacy_state_shutdown(net);
434 return status; 541 return status;
435} 542}
436 543
437static void 544static void
438nfsd4_shutdown_recdir(void) 545nfsd4_shutdown_recdir(struct nfsd_net *nn)
439{ 546{
440 if (!rec_file) 547 if (!nn->rec_file)
441 return; 548 return;
442 fput(rec_file); 549 fput(nn->rec_file);
443 rec_file = NULL; 550 nn->rec_file = NULL;
444} 551}
445 552
446static void 553static void
447nfsd4_legacy_tracking_exit(struct net *net) 554nfsd4_legacy_tracking_exit(struct net *net)
448{ 555{
449 nfs4_release_reclaim(); 556 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
450 nfsd4_shutdown_recdir(); 557
558 nfs4_release_reclaim(nn);
559 nfsd4_shutdown_recdir(nn);
560 nfs4_legacy_state_shutdown(net);
451} 561}
452 562
453/* 563/*
@@ -480,13 +590,26 @@ nfs4_recoverydir(void)
480static int 590static int
481nfsd4_check_legacy_client(struct nfs4_client *clp) 591nfsd4_check_legacy_client(struct nfs4_client *clp)
482{ 592{
593 int status;
594 char dname[HEXDIR_LEN];
595 struct nfs4_client_reclaim *crp;
596 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
597
483 /* did we already find that this client is stable? */ 598 /* did we already find that this client is stable? */
484 if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 599 if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
485 return 0; 600 return 0;
486 601
602 status = nfs4_make_rec_clidname(dname, &clp->cl_name);
603 if (status) {
604 legacy_recdir_name_error(status);
605 return status;
606 }
607
487 /* look for it in the reclaim hashtable otherwise */ 608 /* look for it in the reclaim hashtable otherwise */
488 if (nfsd4_find_reclaim_client(clp)) { 609 crp = nfsd4_find_reclaim_client(dname, nn);
610 if (crp) {
489 set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); 611 set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
612 crp->cr_clp = clp;
490 return 0; 613 return 0;
491 } 614 }
492 615
@@ -494,7 +617,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
494} 617}
495 618
496static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = { 619static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
497 .init = nfsd4_load_reboot_recovery_data, 620 .init = nfsd4_legacy_tracking_init,
498 .exit = nfsd4_legacy_tracking_exit, 621 .exit = nfsd4_legacy_tracking_exit,
499 .create = nfsd4_create_clid_dir, 622 .create = nfsd4_create_clid_dir,
500 .remove = nfsd4_remove_clid_dir, 623 .remove = nfsd4_remove_clid_dir,
@@ -785,8 +908,7 @@ nfsd4_cld_create(struct nfs4_client *clp)
785{ 908{
786 int ret; 909 int ret;
787 struct cld_upcall *cup; 910 struct cld_upcall *cup;
788 /* FIXME: determine net from clp */ 911 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
789 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
790 struct cld_net *cn = nn->cld_net; 912 struct cld_net *cn = nn->cld_net;
791 913
792 /* Don't upcall if it's already stored */ 914 /* Don't upcall if it's already stored */
@@ -823,8 +945,7 @@ nfsd4_cld_remove(struct nfs4_client *clp)
823{ 945{
824 int ret; 946 int ret;
825 struct cld_upcall *cup; 947 struct cld_upcall *cup;
826 /* FIXME: determine net from clp */ 948 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
827 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
828 struct cld_net *cn = nn->cld_net; 949 struct cld_net *cn = nn->cld_net;
829 950
830 /* Don't upcall if it's already removed */ 951 /* Don't upcall if it's already removed */
@@ -861,8 +982,7 @@ nfsd4_cld_check(struct nfs4_client *clp)
861{ 982{
862 int ret; 983 int ret;
863 struct cld_upcall *cup; 984 struct cld_upcall *cup;
864 /* FIXME: determine net from clp */ 985 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
865 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
866 struct cld_net *cn = nn->cld_net; 986 struct cld_net *cn = nn->cld_net;
867 987
868 /* Don't upcall if one was already stored during this grace pd */ 988 /* Don't upcall if one was already stored during this grace pd */
@@ -892,11 +1012,10 @@ nfsd4_cld_check(struct nfs4_client *clp)
892} 1012}
893 1013
894static void 1014static void
895nfsd4_cld_grace_done(struct net *net, time_t boot_time) 1015nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
896{ 1016{
897 int ret; 1017 int ret;
898 struct cld_upcall *cup; 1018 struct cld_upcall *cup;
899 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
900 struct cld_net *cn = nn->cld_net; 1019 struct cld_net *cn = nn->cld_net;
901 1020
902 cup = alloc_cld_upcall(cn); 1021 cup = alloc_cld_upcall(cn);
@@ -926,28 +1045,261 @@ static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
926 .grace_done = nfsd4_cld_grace_done, 1045 .grace_done = nfsd4_cld_grace_done,
927}; 1046};
928 1047
1048/* upcall via usermodehelper */
1049static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
1050module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
1051 S_IRUGO|S_IWUSR);
1052MODULE_PARM_DESC(cltrack_prog, "Path to the nfsdcltrack upcall program");
1053
1054static bool cltrack_legacy_disable;
1055module_param(cltrack_legacy_disable, bool, S_IRUGO|S_IWUSR);
1056MODULE_PARM_DESC(cltrack_legacy_disable,
1057 "Disable legacy recoverydir conversion. Default: false");
1058
1059#define LEGACY_TOPDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_TOPDIR="
1060#define LEGACY_RECDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_RECDIR="
1061
1062static char *
1063nfsd4_cltrack_legacy_topdir(void)
1064{
1065 int copied;
1066 size_t len;
1067 char *result;
1068
1069 if (cltrack_legacy_disable)
1070 return NULL;
1071
1072 len = strlen(LEGACY_TOPDIR_ENV_PREFIX) +
1073 strlen(nfs4_recoverydir()) + 1;
1074
1075 result = kmalloc(len, GFP_KERNEL);
1076 if (!result)
1077 return result;
1078
1079 copied = snprintf(result, len, LEGACY_TOPDIR_ENV_PREFIX "%s",
1080 nfs4_recoverydir());
1081 if (copied >= len) {
1082 /* just return nothing if output was truncated */
1083 kfree(result);
1084 return NULL;
1085 }
1086
1087 return result;
1088}
1089
1090static char *
1091nfsd4_cltrack_legacy_recdir(const struct xdr_netobj *name)
1092{
1093 int copied;
1094 size_t len;
1095 char *result;
1096
1097 if (cltrack_legacy_disable)
1098 return NULL;
1099
1100 /* +1 is for '/' between "topdir" and "recdir" */
1101 len = strlen(LEGACY_RECDIR_ENV_PREFIX) +
1102 strlen(nfs4_recoverydir()) + 1 + HEXDIR_LEN;
1103
1104 result = kmalloc(len, GFP_KERNEL);
1105 if (!result)
1106 return result;
1107
1108 copied = snprintf(result, len, LEGACY_RECDIR_ENV_PREFIX "%s/",
1109 nfs4_recoverydir());
1110 if (copied > (len - HEXDIR_LEN)) {
1111 /* just return nothing if output will be truncated */
1112 kfree(result);
1113 return NULL;
1114 }
1115
1116 copied = nfs4_make_rec_clidname(result + copied, name);
1117 if (copied) {
1118 kfree(result);
1119 return NULL;
1120 }
1121
1122 return result;
1123}
1124
1125static int
1126nfsd4_umh_cltrack_upcall(char *cmd, char *arg, char *legacy)
1127{
1128 char *envp[2];
1129 char *argv[4];
1130 int ret;
1131
1132 if (unlikely(!cltrack_prog[0])) {
1133 dprintk("%s: cltrack_prog is disabled\n", __func__);
1134 return -EACCES;
1135 }
1136
1137 dprintk("%s: cmd: %s\n", __func__, cmd);
1138 dprintk("%s: arg: %s\n", __func__, arg ? arg : "(null)");
1139 dprintk("%s: legacy: %s\n", __func__, legacy ? legacy : "(null)");
1140
1141 envp[0] = legacy;
1142 envp[1] = NULL;
1143
1144 argv[0] = (char *)cltrack_prog;
1145 argv[1] = cmd;
1146 argv[2] = arg;
1147 argv[3] = NULL;
1148
1149 ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
1150 /*
1151 * Disable the upcall mechanism if we're getting an ENOENT or EACCES
1152 * error. The admin can re-enable it on the fly by using sysfs
1153 * once the problem has been fixed.
1154 */
1155 if (ret == -ENOENT || ret == -EACCES) {
1156 dprintk("NFSD: %s was not found or isn't executable (%d). "
1157 "Setting cltrack_prog to blank string!",
1158 cltrack_prog, ret);
1159 cltrack_prog[0] = '\0';
1160 }
1161 dprintk("%s: %s return value: %d\n", __func__, cltrack_prog, ret);
1162
1163 return ret;
1164}
1165
1166static char *
1167bin_to_hex_dup(const unsigned char *src, int srclen)
1168{
1169 int i;
1170 char *buf, *hex;
1171
1172 /* +1 for terminating NULL */
1173 buf = kmalloc((srclen * 2) + 1, GFP_KERNEL);
1174 if (!buf)
1175 return buf;
1176
1177 hex = buf;
1178 for (i = 0; i < srclen; i++) {
1179 sprintf(hex, "%2.2x", *src++);
1180 hex += 2;
1181 }
1182 return buf;
1183}
1184
1185static int
1186nfsd4_umh_cltrack_init(struct net __attribute__((unused)) *net)
1187{
1188 return nfsd4_umh_cltrack_upcall("init", NULL, NULL);
1189}
1190
1191static void
1192nfsd4_umh_cltrack_create(struct nfs4_client *clp)
1193{
1194 char *hexid;
1195
1196 hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1197 if (!hexid) {
1198 dprintk("%s: can't allocate memory for upcall!\n", __func__);
1199 return;
1200 }
1201 nfsd4_umh_cltrack_upcall("create", hexid, NULL);
1202 kfree(hexid);
1203}
1204
1205static void
1206nfsd4_umh_cltrack_remove(struct nfs4_client *clp)
1207{
1208 char *hexid;
1209
1210 hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1211 if (!hexid) {
1212 dprintk("%s: can't allocate memory for upcall!\n", __func__);
1213 return;
1214 }
1215 nfsd4_umh_cltrack_upcall("remove", hexid, NULL);
1216 kfree(hexid);
1217}
1218
1219static int
1220nfsd4_umh_cltrack_check(struct nfs4_client *clp)
1221{
1222 int ret;
1223 char *hexid, *legacy;
1224
1225 hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1226 if (!hexid) {
1227 dprintk("%s: can't allocate memory for upcall!\n", __func__);
1228 return -ENOMEM;
1229 }
1230 legacy = nfsd4_cltrack_legacy_recdir(&clp->cl_name);
1231 ret = nfsd4_umh_cltrack_upcall("check", hexid, legacy);
1232 kfree(legacy);
1233 kfree(hexid);
1234 return ret;
1235}
1236
1237static void
1238nfsd4_umh_cltrack_grace_done(struct nfsd_net __attribute__((unused)) *nn,
1239 time_t boot_time)
1240{
1241 char *legacy;
1242 char timestr[22]; /* FIXME: better way to determine max size? */
1243
1244 sprintf(timestr, "%ld", boot_time);
1245 legacy = nfsd4_cltrack_legacy_topdir();
1246 nfsd4_umh_cltrack_upcall("gracedone", timestr, legacy);
1247 kfree(legacy);
1248}
1249
1250static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {
1251 .init = nfsd4_umh_cltrack_init,
1252 .exit = NULL,
1253 .create = nfsd4_umh_cltrack_create,
1254 .remove = nfsd4_umh_cltrack_remove,
1255 .check = nfsd4_umh_cltrack_check,
1256 .grace_done = nfsd4_umh_cltrack_grace_done,
1257};
1258
929int 1259int
930nfsd4_client_tracking_init(struct net *net) 1260nfsd4_client_tracking_init(struct net *net)
931{ 1261{
932 int status; 1262 int status;
933 struct path path; 1263 struct path path;
1264 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
934 1265
935 if (!client_tracking_ops) { 1266 /* just run the init if it the method is already decided */
936 client_tracking_ops = &nfsd4_cld_tracking_ops; 1267 if (nn->client_tracking_ops)
937 status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path); 1268 goto do_init;
938 if (!status) { 1269
939 if (S_ISDIR(path.dentry->d_inode->i_mode)) 1270 /*
940 client_tracking_ops = 1271 * First, try a UMH upcall. It should succeed or fail quickly, so
941 &nfsd4_legacy_tracking_ops; 1272 * there's little harm in trying that first.
942 path_put(&path); 1273 */
943 } 1274 nn->client_tracking_ops = &nfsd4_umh_tracking_ops;
1275 status = nn->client_tracking_ops->init(net);
1276 if (!status)
1277 return status;
1278
1279 /*
1280 * See if the recoverydir exists and is a directory. If it is,
1281 * then use the legacy ops.
1282 */
1283 nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
1284 status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
1285 if (!status) {
1286 status = S_ISDIR(path.dentry->d_inode->i_mode);
1287 path_put(&path);
1288 if (status)
1289 goto do_init;
944 } 1290 }
945 1291
946 status = client_tracking_ops->init(net); 1292 /* Finally, try to use nfsdcld */
1293 nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
1294 printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
1295 "removed in 3.10. Please transition to using "
1296 "nfsdcltrack.\n");
1297do_init:
1298 status = nn->client_tracking_ops->init(net);
947 if (status) { 1299 if (status) {
948 printk(KERN_WARNING "NFSD: Unable to initialize client " 1300 printk(KERN_WARNING "NFSD: Unable to initialize client "
949 "recovery tracking! (%d)\n", status); 1301 "recovery tracking! (%d)\n", status);
950 client_tracking_ops = NULL; 1302 nn->client_tracking_ops = NULL;
951 } 1303 }
952 return status; 1304 return status;
953} 1305}
@@ -955,40 +1307,49 @@ nfsd4_client_tracking_init(struct net *net)
955void 1307void
956nfsd4_client_tracking_exit(struct net *net) 1308nfsd4_client_tracking_exit(struct net *net)
957{ 1309{
958 if (client_tracking_ops) { 1310 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
959 client_tracking_ops->exit(net); 1311
960 client_tracking_ops = NULL; 1312 if (nn->client_tracking_ops) {
1313 if (nn->client_tracking_ops->exit)
1314 nn->client_tracking_ops->exit(net);
1315 nn->client_tracking_ops = NULL;
961 } 1316 }
962} 1317}
963 1318
964void 1319void
965nfsd4_client_record_create(struct nfs4_client *clp) 1320nfsd4_client_record_create(struct nfs4_client *clp)
966{ 1321{
967 if (client_tracking_ops) 1322 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
968 client_tracking_ops->create(clp); 1323
1324 if (nn->client_tracking_ops)
1325 nn->client_tracking_ops->create(clp);
969} 1326}
970 1327
971void 1328void
972nfsd4_client_record_remove(struct nfs4_client *clp) 1329nfsd4_client_record_remove(struct nfs4_client *clp)
973{ 1330{
974 if (client_tracking_ops) 1331 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
975 client_tracking_ops->remove(clp); 1332
1333 if (nn->client_tracking_ops)
1334 nn->client_tracking_ops->remove(clp);
976} 1335}
977 1336
978int 1337int
979nfsd4_client_record_check(struct nfs4_client *clp) 1338nfsd4_client_record_check(struct nfs4_client *clp)
980{ 1339{
981 if (client_tracking_ops) 1340 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
982 return client_tracking_ops->check(clp); 1341
1342 if (nn->client_tracking_ops)
1343 return nn->client_tracking_ops->check(clp);
983 1344
984 return -EOPNOTSUPP; 1345 return -EOPNOTSUPP;
985} 1346}
986 1347
987void 1348void
988nfsd4_record_grace_done(struct net *net, time_t boot_time) 1349nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
989{ 1350{
990 if (client_tracking_ops) 1351 if (nn->client_tracking_ops)
991 client_tracking_ops->grace_done(net, boot_time); 1352 nn->client_tracking_ops->grace_done(nn, boot_time);
992} 1353}
993 1354
994static int 1355static int
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d0237f872cc4..ac8ed96c4199 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -44,16 +44,11 @@
44#include "xdr4.h" 44#include "xdr4.h"
45#include "vfs.h" 45#include "vfs.h"
46#include "current_stateid.h" 46#include "current_stateid.h"
47#include "fault_inject.h"
48 47
49#include "netns.h" 48#include "netns.h"
50 49
51#define NFSDDBG_FACILITY NFSDDBG_PROC 50#define NFSDDBG_FACILITY NFSDDBG_PROC
52 51
53/* Globals */
54time_t nfsd4_lease = 90; /* default lease time */
55time_t nfsd4_grace = 90;
56
57#define all_ones {{~0,~0},~0} 52#define all_ones {{~0,~0},~0}
58static const stateid_t one_stateid = { 53static const stateid_t one_stateid = {
59 .si_generation = ~0, 54 .si_generation = ~0,
@@ -176,8 +171,6 @@ static unsigned int ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
176 return ret & OWNER_HASH_MASK; 171 return ret & OWNER_HASH_MASK;
177} 172}
178 173
179static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
180
181/* hash table for nfs4_file */ 174/* hash table for nfs4_file */
182#define FILE_HASH_BITS 8 175#define FILE_HASH_BITS 8
183#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) 176#define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
@@ -192,7 +185,7 @@ static struct list_head file_hashtbl[FILE_HASH_SIZE];
192 185
193static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag) 186static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag)
194{ 187{
195 BUG_ON(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR])); 188 WARN_ON_ONCE(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR]));
196 atomic_inc(&fp->fi_access[oflag]); 189 atomic_inc(&fp->fi_access[oflag]);
197} 190}
198 191
@@ -251,7 +244,7 @@ static inline int get_new_stid(struct nfs4_stid *stid)
251 * preallocations that can exist at a time, but the state lock 244 * preallocations that can exist at a time, but the state lock
252 * prevents anyone from using ours before we get here: 245 * prevents anyone from using ours before we get here:
253 */ 246 */
254 BUG_ON(error); 247 WARN_ON_ONCE(error);
255 /* 248 /*
256 * It shouldn't be a problem to reuse an opaque stateid value. 249 * It shouldn't be a problem to reuse an opaque stateid value.
257 * I don't think it is for 4.1. But with 4.0 I worry that, for 250 * I don't think it is for 4.1. But with 4.0 I worry that, for
@@ -340,7 +333,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
340 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); 333 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
341 dp->dl_time = 0; 334 dp->dl_time = 0;
342 atomic_set(&dp->dl_count, 1); 335 atomic_set(&dp->dl_count, 1);
343 INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc); 336 nfsd4_init_callback(&dp->dl_recall);
344 return dp; 337 return dp;
345} 338}
346 339
@@ -390,14 +383,6 @@ unhash_delegation(struct nfs4_delegation *dp)
390 * SETCLIENTID state 383 * SETCLIENTID state
391 */ 384 */
392 385
393/* client_lock protects the client lru list and session hash table */
394static DEFINE_SPINLOCK(client_lock);
395
396/* Hash tables for nfs4_clientid state */
397#define CLIENT_HASH_BITS 4
398#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
399#define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
400
401static unsigned int clientid_hashval(u32 id) 386static unsigned int clientid_hashval(u32 id)
402{ 387{
403 return id & CLIENT_HASH_MASK; 388 return id & CLIENT_HASH_MASK;
@@ -409,31 +394,6 @@ static unsigned int clientstr_hashval(const char *name)
409} 394}
410 395
411/* 396/*
412 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
413 * used in reboot/reset lease grace period processing
414 *
415 * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
416 * setclientid_confirmed info.
417 *
418 * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed
419 * setclientid info.
420 *
421 * client_lru holds client queue ordered by nfs4_client.cl_time
422 * for lease renewal.
423 *
424 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
425 * for last close replay.
426 */
427static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
428static int reclaim_str_hashtbl_size = 0;
429static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
430static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
431static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
432static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
433static struct list_head client_lru;
434static struct list_head close_lru;
435
436/*
437 * We store the NONE, READ, WRITE, and BOTH bits separately in the 397 * We store the NONE, READ, WRITE, and BOTH bits separately in the
438 * st_{access,deny}_bmap field of the stateid, in order to track not 398 * st_{access,deny}_bmap field of the stateid, in order to track not
439 * only what share bits are currently in force, but also what 399 * only what share bits are currently in force, but also what
@@ -526,7 +486,8 @@ static int nfs4_access_to_omode(u32 access)
526 case NFS4_SHARE_ACCESS_BOTH: 486 case NFS4_SHARE_ACCESS_BOTH:
527 return O_RDWR; 487 return O_RDWR;
528 } 488 }
529 BUG(); 489 WARN_ON_ONCE(1);
490 return O_RDONLY;
530} 491}
531 492
532/* release all access and file references for a given stateid */ 493/* release all access and file references for a given stateid */
@@ -652,9 +613,6 @@ static void release_openowner(struct nfs4_openowner *oo)
652 nfs4_free_openowner(oo); 613 nfs4_free_openowner(oo);
653} 614}
654 615
655#define SESSION_HASH_SIZE 512
656static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
657
658static inline int 616static inline int
659hash_sessionid(struct nfs4_sessionid *sessionid) 617hash_sessionid(struct nfs4_sessionid *sessionid)
660{ 618{
@@ -785,9 +743,12 @@ out_free:
785 return NULL; 743 return NULL;
786} 744}
787 745
788static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4_channel_attrs *req, int numslots, int slotsize) 746static void init_forechannel_attrs(struct nfsd4_channel_attrs *new,
747 struct nfsd4_channel_attrs *req,
748 int numslots, int slotsize,
749 struct nfsd_net *nn)
789{ 750{
790 u32 maxrpc = nfsd_serv->sv_max_mesg; 751 u32 maxrpc = nn->nfsd_serv->sv_max_mesg;
791 752
792 new->maxreqs = numslots; 753 new->maxreqs = numslots;
793 new->maxresp_cached = min_t(u32, req->maxresp_cached, 754 new->maxresp_cached = min_t(u32, req->maxresp_cached,
@@ -906,21 +867,27 @@ static void __free_session(struct nfsd4_session *ses)
906static void free_session(struct kref *kref) 867static void free_session(struct kref *kref)
907{ 868{
908 struct nfsd4_session *ses; 869 struct nfsd4_session *ses;
870 struct nfsd_net *nn;
909 871
910 lockdep_assert_held(&client_lock);
911 ses = container_of(kref, struct nfsd4_session, se_ref); 872 ses = container_of(kref, struct nfsd4_session, se_ref);
873 nn = net_generic(ses->se_client->net, nfsd_net_id);
874
875 lockdep_assert_held(&nn->client_lock);
912 nfsd4_del_conns(ses); 876 nfsd4_del_conns(ses);
913 __free_session(ses); 877 __free_session(ses);
914} 878}
915 879
916void nfsd4_put_session(struct nfsd4_session *ses) 880void nfsd4_put_session(struct nfsd4_session *ses)
917{ 881{
918 spin_lock(&client_lock); 882 struct nfsd_net *nn = net_generic(ses->se_client->net, nfsd_net_id);
883
884 spin_lock(&nn->client_lock);
919 nfsd4_put_session_locked(ses); 885 nfsd4_put_session_locked(ses);
920 spin_unlock(&client_lock); 886 spin_unlock(&nn->client_lock);
921} 887}
922 888
923static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan) 889static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan,
890 struct nfsd_net *nn)
924{ 891{
925 struct nfsd4_session *new; 892 struct nfsd4_session *new;
926 int numslots, slotsize; 893 int numslots, slotsize;
@@ -941,13 +908,14 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan)
941 nfsd4_put_drc_mem(slotsize, fchan->maxreqs); 908 nfsd4_put_drc_mem(slotsize, fchan->maxreqs);
942 return NULL; 909 return NULL;
943 } 910 }
944 init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize); 911 init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize, nn);
945 return new; 912 return new;
946} 913}
947 914
948static struct nfsd4_session *init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses) 915static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses)
949{ 916{
950 int idx; 917 int idx;
918 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
951 919
952 new->se_client = clp; 920 new->se_client = clp;
953 gen_sessionid(new); 921 gen_sessionid(new);
@@ -957,14 +925,15 @@ static struct nfsd4_session *init_session(struct svc_rqst *rqstp, struct nfsd4_s
957 new->se_cb_seq_nr = 1; 925 new->se_cb_seq_nr = 1;
958 new->se_flags = cses->flags; 926 new->se_flags = cses->flags;
959 new->se_cb_prog = cses->callback_prog; 927 new->se_cb_prog = cses->callback_prog;
928 new->se_cb_sec = cses->cb_sec;
960 kref_init(&new->se_ref); 929 kref_init(&new->se_ref);
961 idx = hash_sessionid(&new->se_sessionid); 930 idx = hash_sessionid(&new->se_sessionid);
962 spin_lock(&client_lock); 931 spin_lock(&nn->client_lock);
963 list_add(&new->se_hash, &sessionid_hashtbl[idx]); 932 list_add(&new->se_hash, &nn->sessionid_hashtbl[idx]);
964 spin_lock(&clp->cl_lock); 933 spin_lock(&clp->cl_lock);
965 list_add(&new->se_perclnt, &clp->cl_sessions); 934 list_add(&new->se_perclnt, &clp->cl_sessions);
966 spin_unlock(&clp->cl_lock); 935 spin_unlock(&clp->cl_lock);
967 spin_unlock(&client_lock); 936 spin_unlock(&nn->client_lock);
968 937
969 if (cses->flags & SESSION4_BACK_CHAN) { 938 if (cses->flags & SESSION4_BACK_CHAN) {
970 struct sockaddr *sa = svc_addr(rqstp); 939 struct sockaddr *sa = svc_addr(rqstp);
@@ -978,20 +947,20 @@ static struct nfsd4_session *init_session(struct svc_rqst *rqstp, struct nfsd4_s
978 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa); 947 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
979 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa); 948 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
980 } 949 }
981 return new;
982} 950}
983 951
984/* caller must hold client_lock */ 952/* caller must hold client_lock */
985static struct nfsd4_session * 953static struct nfsd4_session *
986find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid) 954find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid, struct net *net)
987{ 955{
988 struct nfsd4_session *elem; 956 struct nfsd4_session *elem;
989 int idx; 957 int idx;
958 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
990 959
991 dump_sessionid(__func__, sessionid); 960 dump_sessionid(__func__, sessionid);
992 idx = hash_sessionid(sessionid); 961 idx = hash_sessionid(sessionid);
993 /* Search in the appropriate list */ 962 /* Search in the appropriate list */
994 list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) { 963 list_for_each_entry(elem, &nn->sessionid_hashtbl[idx], se_hash) {
995 if (!memcmp(elem->se_sessionid.data, sessionid->data, 964 if (!memcmp(elem->se_sessionid.data, sessionid->data,
996 NFS4_MAX_SESSIONID_LEN)) { 965 NFS4_MAX_SESSIONID_LEN)) {
997 return elem; 966 return elem;
@@ -1016,6 +985,8 @@ unhash_session(struct nfsd4_session *ses)
1016static inline void 985static inline void
1017renew_client_locked(struct nfs4_client *clp) 986renew_client_locked(struct nfs4_client *clp)
1018{ 987{
988 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
989
1019 if (is_client_expired(clp)) { 990 if (is_client_expired(clp)) {
1020 WARN_ON(1); 991 WARN_ON(1);
1021 printk("%s: client (clientid %08x/%08x) already expired\n", 992 printk("%s: client (clientid %08x/%08x) already expired\n",
@@ -1028,16 +999,18 @@ renew_client_locked(struct nfs4_client *clp)
1028 dprintk("renewing client (clientid %08x/%08x)\n", 999 dprintk("renewing client (clientid %08x/%08x)\n",
1029 clp->cl_clientid.cl_boot, 1000 clp->cl_clientid.cl_boot,
1030 clp->cl_clientid.cl_id); 1001 clp->cl_clientid.cl_id);
1031 list_move_tail(&clp->cl_lru, &client_lru); 1002 list_move_tail(&clp->cl_lru, &nn->client_lru);
1032 clp->cl_time = get_seconds(); 1003 clp->cl_time = get_seconds();
1033} 1004}
1034 1005
1035static inline void 1006static inline void
1036renew_client(struct nfs4_client *clp) 1007renew_client(struct nfs4_client *clp)
1037{ 1008{
1038 spin_lock(&client_lock); 1009 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1010
1011 spin_lock(&nn->client_lock);
1039 renew_client_locked(clp); 1012 renew_client_locked(clp);
1040 spin_unlock(&client_lock); 1013 spin_unlock(&nn->client_lock);
1041} 1014}
1042 1015
1043/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */ 1016/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
@@ -1075,7 +1048,9 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1075static inline void 1048static inline void
1076free_client(struct nfs4_client *clp) 1049free_client(struct nfs4_client *clp)
1077{ 1050{
1078 lockdep_assert_held(&client_lock); 1051 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1052
1053 lockdep_assert_held(&nn->client_lock);
1079 while (!list_empty(&clp->cl_sessions)) { 1054 while (!list_empty(&clp->cl_sessions)) {
1080 struct nfsd4_session *ses; 1055 struct nfsd4_session *ses;
1081 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session, 1056 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
@@ -1092,15 +1067,16 @@ void
1092release_session_client(struct nfsd4_session *session) 1067release_session_client(struct nfsd4_session *session)
1093{ 1068{
1094 struct nfs4_client *clp = session->se_client; 1069 struct nfs4_client *clp = session->se_client;
1070 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1095 1071
1096 if (!atomic_dec_and_lock(&clp->cl_refcount, &client_lock)) 1072 if (!atomic_dec_and_lock(&clp->cl_refcount, &nn->client_lock))
1097 return; 1073 return;
1098 if (is_client_expired(clp)) { 1074 if (is_client_expired(clp)) {
1099 free_client(clp); 1075 free_client(clp);
1100 session->se_client = NULL; 1076 session->se_client = NULL;
1101 } else 1077 } else
1102 renew_client_locked(clp); 1078 renew_client_locked(clp);
1103 spin_unlock(&client_lock); 1079 spin_unlock(&nn->client_lock);
1104} 1080}
1105 1081
1106/* must be called under the client_lock */ 1082/* must be called under the client_lock */
@@ -1123,6 +1099,7 @@ destroy_client(struct nfs4_client *clp)
1123 struct nfs4_openowner *oo; 1099 struct nfs4_openowner *oo;
1124 struct nfs4_delegation *dp; 1100 struct nfs4_delegation *dp;
1125 struct list_head reaplist; 1101 struct list_head reaplist;
1102 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1126 1103
1127 INIT_LIST_HEAD(&reaplist); 1104 INIT_LIST_HEAD(&reaplist);
1128 spin_lock(&recall_lock); 1105 spin_lock(&recall_lock);
@@ -1144,12 +1121,15 @@ destroy_client(struct nfs4_client *clp)
1144 if (clp->cl_cb_conn.cb_xprt) 1121 if (clp->cl_cb_conn.cb_xprt)
1145 svc_xprt_put(clp->cl_cb_conn.cb_xprt); 1122 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1146 list_del(&clp->cl_idhash); 1123 list_del(&clp->cl_idhash);
1147 list_del(&clp->cl_strhash); 1124 if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
1148 spin_lock(&client_lock); 1125 rb_erase(&clp->cl_namenode, &nn->conf_name_tree);
1126 else
1127 rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1128 spin_lock(&nn->client_lock);
1149 unhash_client_locked(clp); 1129 unhash_client_locked(clp);
1150 if (atomic_read(&clp->cl_refcount) == 0) 1130 if (atomic_read(&clp->cl_refcount) == 0)
1151 free_client(clp); 1131 free_client(clp);
1152 spin_unlock(&client_lock); 1132 spin_unlock(&nn->client_lock);
1153} 1133}
1154 1134
1155static void expire_client(struct nfs4_client *clp) 1135static void expire_client(struct nfs4_client *clp)
@@ -1187,6 +1167,17 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1187 return 0; 1167 return 0;
1188} 1168}
1189 1169
1170static long long
1171compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2)
1172{
1173 long long res;
1174
1175 res = o1->len - o2->len;
1176 if (res)
1177 return res;
1178 return (long long)memcmp(o1->data, o2->data, o1->len);
1179}
1180
1190static int same_name(const char *n1, const char *n2) 1181static int same_name(const char *n1, const char *n2)
1191{ 1182{
1192 return 0 == memcmp(n1, n2, HEXDIR_LEN); 1183 return 0 == memcmp(n1, n2, HEXDIR_LEN);
@@ -1247,10 +1238,9 @@ same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1247 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal); 1238 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
1248} 1239}
1249 1240
1250static void gen_clid(struct nfs4_client *clp) 1241static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
1251{ 1242{
1252 static u32 current_clientid = 1; 1243 static u32 current_clientid = 1;
1253 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
1254 1244
1255 clp->cl_clientid.cl_boot = nn->boot_time; 1245 clp->cl_clientid.cl_boot = nn->boot_time;
1256 clp->cl_clientid.cl_id = current_clientid++; 1246 clp->cl_clientid.cl_id = current_clientid++;
@@ -1283,12 +1273,14 @@ static struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, stateid_t
1283 return NULL; 1273 return NULL;
1284} 1274}
1285 1275
1286static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, 1276static struct nfs4_client *create_client(struct xdr_netobj name,
1287 struct svc_rqst *rqstp, nfs4_verifier *verf) 1277 struct svc_rqst *rqstp, nfs4_verifier *verf)
1288{ 1278{
1289 struct nfs4_client *clp; 1279 struct nfs4_client *clp;
1290 struct sockaddr *sa = svc_addr(rqstp); 1280 struct sockaddr *sa = svc_addr(rqstp);
1291 int ret; 1281 int ret;
1282 struct net *net = SVC_NET(rqstp);
1283 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1292 1284
1293 clp = alloc_client(name); 1285 clp = alloc_client(name);
1294 if (clp == NULL) 1286 if (clp == NULL)
@@ -1297,23 +1289,21 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1297 INIT_LIST_HEAD(&clp->cl_sessions); 1289 INIT_LIST_HEAD(&clp->cl_sessions);
1298 ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); 1290 ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
1299 if (ret) { 1291 if (ret) {
1300 spin_lock(&client_lock); 1292 spin_lock(&nn->client_lock);
1301 free_client(clp); 1293 free_client(clp);
1302 spin_unlock(&client_lock); 1294 spin_unlock(&nn->client_lock);
1303 return NULL; 1295 return NULL;
1304 } 1296 }
1305 idr_init(&clp->cl_stateids); 1297 idr_init(&clp->cl_stateids);
1306 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
1307 atomic_set(&clp->cl_refcount, 0); 1298 atomic_set(&clp->cl_refcount, 0);
1308 clp->cl_cb_state = NFSD4_CB_UNKNOWN; 1299 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
1309 INIT_LIST_HEAD(&clp->cl_idhash); 1300 INIT_LIST_HEAD(&clp->cl_idhash);
1310 INIT_LIST_HEAD(&clp->cl_strhash);
1311 INIT_LIST_HEAD(&clp->cl_openowners); 1301 INIT_LIST_HEAD(&clp->cl_openowners);
1312 INIT_LIST_HEAD(&clp->cl_delegations); 1302 INIT_LIST_HEAD(&clp->cl_delegations);
1313 INIT_LIST_HEAD(&clp->cl_lru); 1303 INIT_LIST_HEAD(&clp->cl_lru);
1314 INIT_LIST_HEAD(&clp->cl_callbacks); 1304 INIT_LIST_HEAD(&clp->cl_callbacks);
1315 spin_lock_init(&clp->cl_lock); 1305 spin_lock_init(&clp->cl_lock);
1316 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); 1306 nfsd4_init_callback(&clp->cl_cb_null);
1317 clp->cl_time = get_seconds(); 1307 clp->cl_time = get_seconds();
1318 clear_bit(0, &clp->cl_cb_slot_busy); 1308 clear_bit(0, &clp->cl_cb_slot_busy);
1319 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 1309 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
@@ -1321,17 +1311,60 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1321 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); 1311 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
1322 gen_confirm(clp); 1312 gen_confirm(clp);
1323 clp->cl_cb_session = NULL; 1313 clp->cl_cb_session = NULL;
1314 clp->net = net;
1324 return clp; 1315 return clp;
1325} 1316}
1326 1317
1327static void 1318static void
1328add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) 1319add_clp_to_name_tree(struct nfs4_client *new_clp, struct rb_root *root)
1320{
1321 struct rb_node **new = &(root->rb_node), *parent = NULL;
1322 struct nfs4_client *clp;
1323
1324 while (*new) {
1325 clp = rb_entry(*new, struct nfs4_client, cl_namenode);
1326 parent = *new;
1327
1328 if (compare_blob(&clp->cl_name, &new_clp->cl_name) > 0)
1329 new = &((*new)->rb_left);
1330 else
1331 new = &((*new)->rb_right);
1332 }
1333
1334 rb_link_node(&new_clp->cl_namenode, parent, new);
1335 rb_insert_color(&new_clp->cl_namenode, root);
1336}
1337
1338static struct nfs4_client *
1339find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root)
1340{
1341 long long cmp;
1342 struct rb_node *node = root->rb_node;
1343 struct nfs4_client *clp;
1344
1345 while (node) {
1346 clp = rb_entry(node, struct nfs4_client, cl_namenode);
1347 cmp = compare_blob(&clp->cl_name, name);
1348 if (cmp > 0)
1349 node = node->rb_left;
1350 else if (cmp < 0)
1351 node = node->rb_right;
1352 else
1353 return clp;
1354 }
1355 return NULL;
1356}
1357
1358static void
1359add_to_unconfirmed(struct nfs4_client *clp)
1329{ 1360{
1330 unsigned int idhashval; 1361 unsigned int idhashval;
1362 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1331 1363
1332 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]); 1364 clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
1365 add_clp_to_name_tree(clp, &nn->unconf_name_tree);
1333 idhashval = clientid_hashval(clp->cl_clientid.cl_id); 1366 idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1334 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]); 1367 list_add(&clp->cl_idhash, &nn->unconf_id_hashtbl[idhashval]);
1335 renew_client(clp); 1368 renew_client(clp);
1336} 1369}
1337 1370
@@ -1339,22 +1372,23 @@ static void
1339move_to_confirmed(struct nfs4_client *clp) 1372move_to_confirmed(struct nfs4_client *clp)
1340{ 1373{
1341 unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id); 1374 unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
1342 unsigned int strhashval; 1375 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1343 1376
1344 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); 1377 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
1345 list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); 1378 list_move(&clp->cl_idhash, &nn->conf_id_hashtbl[idhashval]);
1346 strhashval = clientstr_hashval(clp->cl_recdir); 1379 rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
1347 list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); 1380 add_clp_to_name_tree(clp, &nn->conf_name_tree);
1381 set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
1348 renew_client(clp); 1382 renew_client(clp);
1349} 1383}
1350 1384
1351static struct nfs4_client * 1385static struct nfs4_client *
1352find_confirmed_client(clientid_t *clid, bool sessions) 1386find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
1353{ 1387{
1354 struct nfs4_client *clp; 1388 struct nfs4_client *clp;
1355 unsigned int idhashval = clientid_hashval(clid->cl_id); 1389 unsigned int idhashval = clientid_hashval(clid->cl_id);
1356 1390
1357 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) { 1391 list_for_each_entry(clp, &nn->conf_id_hashtbl[idhashval], cl_idhash) {
1358 if (same_clid(&clp->cl_clientid, clid)) { 1392 if (same_clid(&clp->cl_clientid, clid)) {
1359 if ((bool)clp->cl_minorversion != sessions) 1393 if ((bool)clp->cl_minorversion != sessions)
1360 return NULL; 1394 return NULL;
@@ -1366,12 +1400,12 @@ find_confirmed_client(clientid_t *clid, bool sessions)
1366} 1400}
1367 1401
1368static struct nfs4_client * 1402static struct nfs4_client *
1369find_unconfirmed_client(clientid_t *clid, bool sessions) 1403find_unconfirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
1370{ 1404{
1371 struct nfs4_client *clp; 1405 struct nfs4_client *clp;
1372 unsigned int idhashval = clientid_hashval(clid->cl_id); 1406 unsigned int idhashval = clientid_hashval(clid->cl_id);
1373 1407
1374 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) { 1408 list_for_each_entry(clp, &nn->unconf_id_hashtbl[idhashval], cl_idhash) {
1375 if (same_clid(&clp->cl_clientid, clid)) { 1409 if (same_clid(&clp->cl_clientid, clid)) {
1376 if ((bool)clp->cl_minorversion != sessions) 1410 if ((bool)clp->cl_minorversion != sessions)
1377 return NULL; 1411 return NULL;
@@ -1387,27 +1421,15 @@ static bool clp_used_exchangeid(struct nfs4_client *clp)
1387} 1421}
1388 1422
1389static struct nfs4_client * 1423static struct nfs4_client *
1390find_confirmed_client_by_str(const char *dname, unsigned int hashval) 1424find_confirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1391{ 1425{
1392 struct nfs4_client *clp; 1426 return find_clp_in_name_tree(name, &nn->conf_name_tree);
1393
1394 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
1395 if (same_name(clp->cl_recdir, dname))
1396 return clp;
1397 }
1398 return NULL;
1399} 1427}
1400 1428
1401static struct nfs4_client * 1429static struct nfs4_client *
1402find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) 1430find_unconfirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
1403{ 1431{
1404 struct nfs4_client *clp; 1432 return find_clp_in_name_tree(name, &nn->unconf_name_tree);
1405
1406 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
1407 if (same_name(clp->cl_recdir, dname))
1408 return clp;
1409 }
1410 return NULL;
1411} 1433}
1412 1434
1413static void 1435static void
@@ -1428,7 +1450,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r
1428 else 1450 else
1429 goto out_err; 1451 goto out_err;
1430 1452
1431 conn->cb_addrlen = rpc_uaddr2sockaddr(&init_net, se->se_callback_addr_val, 1453 conn->cb_addrlen = rpc_uaddr2sockaddr(clp->net, se->se_callback_addr_val,
1432 se->se_callback_addr_len, 1454 se->se_callback_addr_len,
1433 (struct sockaddr *)&conn->cb_addr, 1455 (struct sockaddr *)&conn->cb_addr,
1434 sizeof(conn->cb_addr)); 1456 sizeof(conn->cb_addr));
@@ -1572,12 +1594,11 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1572{ 1594{
1573 struct nfs4_client *unconf, *conf, *new; 1595 struct nfs4_client *unconf, *conf, *new;
1574 __be32 status; 1596 __be32 status;
1575 unsigned int strhashval;
1576 char dname[HEXDIR_LEN];
1577 char addr_str[INET6_ADDRSTRLEN]; 1597 char addr_str[INET6_ADDRSTRLEN];
1578 nfs4_verifier verf = exid->verifier; 1598 nfs4_verifier verf = exid->verifier;
1579 struct sockaddr *sa = svc_addr(rqstp); 1599 struct sockaddr *sa = svc_addr(rqstp);
1580 bool update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A; 1600 bool update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A;
1601 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1581 1602
1582 rpc_ntop(sa, addr_str, sizeof(addr_str)); 1603 rpc_ntop(sa, addr_str, sizeof(addr_str));
1583 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p " 1604 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
@@ -1592,24 +1613,16 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1592 switch (exid->spa_how) { 1613 switch (exid->spa_how) {
1593 case SP4_NONE: 1614 case SP4_NONE:
1594 break; 1615 break;
1616 default: /* checked by xdr code */
1617 WARN_ON_ONCE(1);
1595 case SP4_SSV: 1618 case SP4_SSV:
1596 return nfserr_serverfault;
1597 default:
1598 BUG(); /* checked by xdr code */
1599 case SP4_MACH_CRED: 1619 case SP4_MACH_CRED:
1600 return nfserr_serverfault; /* no excuse :-/ */ 1620 return nfserr_serverfault; /* no excuse :-/ */
1601 } 1621 }
1602 1622
1603 status = nfs4_make_rec_clidname(dname, &exid->clname);
1604
1605 if (status)
1606 return status;
1607
1608 strhashval = clientstr_hashval(dname);
1609
1610 /* Cases below refer to rfc 5661 section 18.35.4: */ 1623 /* Cases below refer to rfc 5661 section 18.35.4: */
1611 nfs4_lock_state(); 1624 nfs4_lock_state();
1612 conf = find_confirmed_client_by_str(dname, strhashval); 1625 conf = find_confirmed_client_by_name(&exid->clname, nn);
1613 if (conf) { 1626 if (conf) {
1614 bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred); 1627 bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
1615 bool verfs_match = same_verf(&verf, &conf->cl_verifier); 1628 bool verfs_match = same_verf(&verf, &conf->cl_verifier);
@@ -1654,21 +1667,21 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1654 goto out; 1667 goto out;
1655 } 1668 }
1656 1669
1657 unconf = find_unconfirmed_client_by_str(dname, strhashval); 1670 unconf = find_unconfirmed_client_by_name(&exid->clname, nn);
1658 if (unconf) /* case 4, possible retry or client restart */ 1671 if (unconf) /* case 4, possible retry or client restart */
1659 expire_client(unconf); 1672 expire_client(unconf);
1660 1673
1661 /* case 1 (normal case) */ 1674 /* case 1 (normal case) */
1662out_new: 1675out_new:
1663 new = create_client(exid->clname, dname, rqstp, &verf); 1676 new = create_client(exid->clname, rqstp, &verf);
1664 if (new == NULL) { 1677 if (new == NULL) {
1665 status = nfserr_jukebox; 1678 status = nfserr_jukebox;
1666 goto out; 1679 goto out;
1667 } 1680 }
1668 new->cl_minorversion = 1; 1681 new->cl_minorversion = 1;
1669 1682
1670 gen_clid(new); 1683 gen_clid(new, nn);
1671 add_to_unconfirmed(new, strhashval); 1684 add_to_unconfirmed(new);
1672out_copy: 1685out_copy:
1673 exid->clientid.cl_boot = new->cl_clientid.cl_boot; 1686 exid->clientid.cl_boot = new->cl_clientid.cl_boot;
1674 exid->clientid.cl_id = new->cl_clientid.cl_id; 1687 exid->clientid.cl_id = new->cl_clientid.cl_id;
@@ -1761,12 +1774,13 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1761 struct nfsd4_conn *conn; 1774 struct nfsd4_conn *conn;
1762 struct nfsd4_clid_slot *cs_slot = NULL; 1775 struct nfsd4_clid_slot *cs_slot = NULL;
1763 __be32 status = 0; 1776 __be32 status = 0;
1777 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1764 1778
1765 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1779 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
1766 return nfserr_inval; 1780 return nfserr_inval;
1767 if (check_forechannel_attrs(cr_ses->fore_channel)) 1781 if (check_forechannel_attrs(cr_ses->fore_channel))
1768 return nfserr_toosmall; 1782 return nfserr_toosmall;
1769 new = alloc_session(&cr_ses->fore_channel); 1783 new = alloc_session(&cr_ses->fore_channel, nn);
1770 if (!new) 1784 if (!new)
1771 return nfserr_jukebox; 1785 return nfserr_jukebox;
1772 status = nfserr_jukebox; 1786 status = nfserr_jukebox;
@@ -1775,8 +1789,8 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1775 goto out_free_session; 1789 goto out_free_session;
1776 1790
1777 nfs4_lock_state(); 1791 nfs4_lock_state();
1778 unconf = find_unconfirmed_client(&cr_ses->clientid, true); 1792 unconf = find_unconfirmed_client(&cr_ses->clientid, true, nn);
1779 conf = find_confirmed_client(&cr_ses->clientid, true); 1793 conf = find_confirmed_client(&cr_ses->clientid, true, nn);
1780 1794
1781 if (conf) { 1795 if (conf) {
1782 cs_slot = &conf->cl_cs_slot; 1796 cs_slot = &conf->cl_cs_slot;
@@ -1789,7 +1803,6 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1789 goto out_free_conn; 1803 goto out_free_conn;
1790 } 1804 }
1791 } else if (unconf) { 1805 } else if (unconf) {
1792 unsigned int hash;
1793 struct nfs4_client *old; 1806 struct nfs4_client *old;
1794 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) || 1807 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
1795 !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) { 1808 !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
@@ -1803,8 +1816,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1803 status = nfserr_seq_misordered; 1816 status = nfserr_seq_misordered;
1804 goto out_free_conn; 1817 goto out_free_conn;
1805 } 1818 }
1806 hash = clientstr_hashval(unconf->cl_recdir); 1819 old = find_confirmed_client_by_name(&unconf->cl_name, nn);
1807 old = find_confirmed_client_by_str(unconf->cl_recdir, hash);
1808 if (old) 1820 if (old)
1809 expire_client(old); 1821 expire_client(old);
1810 move_to_confirmed(unconf); 1822 move_to_confirmed(unconf);
@@ -1843,14 +1855,6 @@ out_free_session:
1843 goto out; 1855 goto out;
1844} 1856}
1845 1857
1846static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
1847{
1848 struct nfsd4_compoundres *resp = rqstp->rq_resp;
1849 struct nfsd4_compoundargs *argp = rqstp->rq_argp;
1850
1851 return argp->opcnt == resp->opcnt;
1852}
1853
1854static __be32 nfsd4_map_bcts_dir(u32 *dir) 1858static __be32 nfsd4_map_bcts_dir(u32 *dir)
1855{ 1859{
1856 switch (*dir) { 1860 switch (*dir) {
@@ -1865,24 +1869,40 @@ static __be32 nfsd4_map_bcts_dir(u32 *dir)
1865 return nfserr_inval; 1869 return nfserr_inval;
1866} 1870}
1867 1871
1872__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_backchannel_ctl *bc)
1873{
1874 struct nfsd4_session *session = cstate->session;
1875 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1876
1877 spin_lock(&nn->client_lock);
1878 session->se_cb_prog = bc->bc_cb_program;
1879 session->se_cb_sec = bc->bc_cb_sec;
1880 spin_unlock(&nn->client_lock);
1881
1882 nfsd4_probe_callback(session->se_client);
1883
1884 return nfs_ok;
1885}
1886
1868__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, 1887__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1869 struct nfsd4_compound_state *cstate, 1888 struct nfsd4_compound_state *cstate,
1870 struct nfsd4_bind_conn_to_session *bcts) 1889 struct nfsd4_bind_conn_to_session *bcts)
1871{ 1890{
1872 __be32 status; 1891 __be32 status;
1873 struct nfsd4_conn *conn; 1892 struct nfsd4_conn *conn;
1893 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1874 1894
1875 if (!nfsd4_last_compound_op(rqstp)) 1895 if (!nfsd4_last_compound_op(rqstp))
1876 return nfserr_not_only_op; 1896 return nfserr_not_only_op;
1877 spin_lock(&client_lock); 1897 spin_lock(&nn->client_lock);
1878 cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid); 1898 cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid, SVC_NET(rqstp));
1879 /* Sorta weird: we only need the refcnt'ing because new_conn acquires 1899 /* Sorta weird: we only need the refcnt'ing because new_conn acquires
1880 * client_lock iself: */ 1900 * client_lock iself: */
1881 if (cstate->session) { 1901 if (cstate->session) {
1882 nfsd4_get_session(cstate->session); 1902 nfsd4_get_session(cstate->session);
1883 atomic_inc(&cstate->session->se_client->cl_refcount); 1903 atomic_inc(&cstate->session->se_client->cl_refcount);
1884 } 1904 }
1885 spin_unlock(&client_lock); 1905 spin_unlock(&nn->client_lock);
1886 if (!cstate->session) 1906 if (!cstate->session)
1887 return nfserr_badsession; 1907 return nfserr_badsession;
1888 1908
@@ -1910,6 +1930,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
1910{ 1930{
1911 struct nfsd4_session *ses; 1931 struct nfsd4_session *ses;
1912 __be32 status = nfserr_badsession; 1932 __be32 status = nfserr_badsession;
1933 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id);
1913 1934
1914 /* Notes: 1935 /* Notes:
1915 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid 1936 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid
@@ -1923,24 +1944,24 @@ nfsd4_destroy_session(struct svc_rqst *r,
1923 return nfserr_not_only_op; 1944 return nfserr_not_only_op;
1924 } 1945 }
1925 dump_sessionid(__func__, &sessionid->sessionid); 1946 dump_sessionid(__func__, &sessionid->sessionid);
1926 spin_lock(&client_lock); 1947 spin_lock(&nn->client_lock);
1927 ses = find_in_sessionid_hashtbl(&sessionid->sessionid); 1948 ses = find_in_sessionid_hashtbl(&sessionid->sessionid, SVC_NET(r));
1928 if (!ses) { 1949 if (!ses) {
1929 spin_unlock(&client_lock); 1950 spin_unlock(&nn->client_lock);
1930 goto out; 1951 goto out;
1931 } 1952 }
1932 1953
1933 unhash_session(ses); 1954 unhash_session(ses);
1934 spin_unlock(&client_lock); 1955 spin_unlock(&nn->client_lock);
1935 1956
1936 nfs4_lock_state(); 1957 nfs4_lock_state();
1937 nfsd4_probe_callback_sync(ses->se_client); 1958 nfsd4_probe_callback_sync(ses->se_client);
1938 nfs4_unlock_state(); 1959 nfs4_unlock_state();
1939 1960
1940 spin_lock(&client_lock); 1961 spin_lock(&nn->client_lock);
1941 nfsd4_del_conns(ses); 1962 nfsd4_del_conns(ses);
1942 nfsd4_put_session_locked(ses); 1963 nfsd4_put_session_locked(ses);
1943 spin_unlock(&client_lock); 1964 spin_unlock(&nn->client_lock);
1944 status = nfs_ok; 1965 status = nfs_ok;
1945out: 1966out:
1946 dprintk("%s returns %d\n", __func__, ntohl(status)); 1967 dprintk("%s returns %d\n", __func__, ntohl(status));
@@ -2006,6 +2027,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2006 struct nfsd4_slot *slot; 2027 struct nfsd4_slot *slot;
2007 struct nfsd4_conn *conn; 2028 struct nfsd4_conn *conn;
2008 __be32 status; 2029 __be32 status;
2030 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2009 2031
2010 if (resp->opcnt != 1) 2032 if (resp->opcnt != 1)
2011 return nfserr_sequence_pos; 2033 return nfserr_sequence_pos;
@@ -2018,9 +2040,9 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2018 if (!conn) 2040 if (!conn)
2019 return nfserr_jukebox; 2041 return nfserr_jukebox;
2020 2042
2021 spin_lock(&client_lock); 2043 spin_lock(&nn->client_lock);
2022 status = nfserr_badsession; 2044 status = nfserr_badsession;
2023 session = find_in_sessionid_hashtbl(&seq->sessionid); 2045 session = find_in_sessionid_hashtbl(&seq->sessionid, SVC_NET(rqstp));
2024 if (!session) 2046 if (!session)
2025 goto out; 2047 goto out;
2026 2048
@@ -2094,7 +2116,7 @@ out:
2094 } 2116 }
2095 } 2117 }
2096 kfree(conn); 2118 kfree(conn);
2097 spin_unlock(&client_lock); 2119 spin_unlock(&nn->client_lock);
2098 dprintk("%s: return %d\n", __func__, ntohl(status)); 2120 dprintk("%s: return %d\n", __func__, ntohl(status));
2099 return status; 2121 return status;
2100} 2122}
@@ -2104,10 +2126,11 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
2104{ 2126{
2105 struct nfs4_client *conf, *unconf, *clp; 2127 struct nfs4_client *conf, *unconf, *clp;
2106 __be32 status = 0; 2128 __be32 status = 0;
2129 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2107 2130
2108 nfs4_lock_state(); 2131 nfs4_lock_state();
2109 unconf = find_unconfirmed_client(&dc->clientid, true); 2132 unconf = find_unconfirmed_client(&dc->clientid, true, nn);
2110 conf = find_confirmed_client(&dc->clientid, true); 2133 conf = find_confirmed_client(&dc->clientid, true, nn);
2111 2134
2112 if (conf) { 2135 if (conf) {
2113 clp = conf; 2136 clp = conf;
@@ -2181,20 +2204,13 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2181{ 2204{
2182 struct xdr_netobj clname = setclid->se_name; 2205 struct xdr_netobj clname = setclid->se_name;
2183 nfs4_verifier clverifier = setclid->se_verf; 2206 nfs4_verifier clverifier = setclid->se_verf;
2184 unsigned int strhashval;
2185 struct nfs4_client *conf, *unconf, *new; 2207 struct nfs4_client *conf, *unconf, *new;
2186 __be32 status; 2208 __be32 status;
2187 char dname[HEXDIR_LEN]; 2209 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2188
2189 status = nfs4_make_rec_clidname(dname, &clname);
2190 if (status)
2191 return status;
2192
2193 strhashval = clientstr_hashval(dname);
2194 2210
2195 /* Cases below refer to rfc 3530 section 14.2.33: */ 2211 /* Cases below refer to rfc 3530 section 14.2.33: */
2196 nfs4_lock_state(); 2212 nfs4_lock_state();
2197 conf = find_confirmed_client_by_str(dname, strhashval); 2213 conf = find_confirmed_client_by_name(&clname, nn);
2198 if (conf) { 2214 if (conf) {
2199 /* case 0: */ 2215 /* case 0: */
2200 status = nfserr_clid_inuse; 2216 status = nfserr_clid_inuse;
@@ -2209,21 +2225,21 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2209 goto out; 2225 goto out;
2210 } 2226 }
2211 } 2227 }
2212 unconf = find_unconfirmed_client_by_str(dname, strhashval); 2228 unconf = find_unconfirmed_client_by_name(&clname, nn);
2213 if (unconf) 2229 if (unconf)
2214 expire_client(unconf); 2230 expire_client(unconf);
2215 status = nfserr_jukebox; 2231 status = nfserr_jukebox;
2216 new = create_client(clname, dname, rqstp, &clverifier); 2232 new = create_client(clname, rqstp, &clverifier);
2217 if (new == NULL) 2233 if (new == NULL)
2218 goto out; 2234 goto out;
2219 if (conf && same_verf(&conf->cl_verifier, &clverifier)) 2235 if (conf && same_verf(&conf->cl_verifier, &clverifier))
2220 /* case 1: probable callback update */ 2236 /* case 1: probable callback update */
2221 copy_clid(new, conf); 2237 copy_clid(new, conf);
2222 else /* case 4 (new client) or cases 2, 3 (client reboot): */ 2238 else /* case 4 (new client) or cases 2, 3 (client reboot): */
2223 gen_clid(new); 2239 gen_clid(new, nn);
2224 new->cl_minorversion = 0; 2240 new->cl_minorversion = 0;
2225 gen_callback(new, setclid, rqstp); 2241 gen_callback(new, setclid, rqstp);
2226 add_to_unconfirmed(new, strhashval); 2242 add_to_unconfirmed(new);
2227 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; 2243 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
2228 setclid->se_clientid.cl_id = new->cl_clientid.cl_id; 2244 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
2229 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data)); 2245 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
@@ -2243,14 +2259,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
2243 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 2259 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
2244 clientid_t * clid = &setclientid_confirm->sc_clientid; 2260 clientid_t * clid = &setclientid_confirm->sc_clientid;
2245 __be32 status; 2261 __be32 status;
2246 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 2262 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2247 2263
2248 if (STALE_CLIENTID(clid, nn)) 2264 if (STALE_CLIENTID(clid, nn))
2249 return nfserr_stale_clientid; 2265 return nfserr_stale_clientid;
2250 nfs4_lock_state(); 2266 nfs4_lock_state();
2251 2267
2252 conf = find_confirmed_client(clid, false); 2268 conf = find_confirmed_client(clid, false, nn);
2253 unconf = find_unconfirmed_client(clid, false); 2269 unconf = find_unconfirmed_client(clid, false, nn);
2254 /* 2270 /*
2255 * We try hard to give out unique clientid's, so if we get an 2271 * We try hard to give out unique clientid's, so if we get an
2256 * attempt to confirm the same clientid with a different cred, 2272 * attempt to confirm the same clientid with a different cred,
@@ -2276,9 +2292,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
2276 nfsd4_probe_callback(conf); 2292 nfsd4_probe_callback(conf);
2277 expire_client(unconf); 2293 expire_client(unconf);
2278 } else { /* case 3: normal case; new or rebooted client */ 2294 } else { /* case 3: normal case; new or rebooted client */
2279 unsigned int hash = clientstr_hashval(unconf->cl_recdir); 2295 conf = find_confirmed_client_by_name(&unconf->cl_name, nn);
2280
2281 conf = find_confirmed_client_by_str(unconf->cl_recdir, hash);
2282 if (conf) 2296 if (conf)
2283 expire_client(conf); 2297 expire_client(conf);
2284 move_to_confirmed(unconf); 2298 move_to_confirmed(unconf);
@@ -2340,7 +2354,7 @@ nfsd4_init_slabs(void)
2340 if (openowner_slab == NULL) 2354 if (openowner_slab == NULL)
2341 goto out_nomem; 2355 goto out_nomem;
2342 lockowner_slab = kmem_cache_create("nfsd4_lockowners", 2356 lockowner_slab = kmem_cache_create("nfsd4_lockowners",
2343 sizeof(struct nfs4_openowner), 0, 0, NULL); 2357 sizeof(struct nfs4_lockowner), 0, 0, NULL);
2344 if (lockowner_slab == NULL) 2358 if (lockowner_slab == NULL)
2345 goto out_nomem; 2359 goto out_nomem;
2346 file_slab = kmem_cache_create("nfsd4_files", 2360 file_slab = kmem_cache_create("nfsd4_files",
@@ -2404,7 +2418,9 @@ static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj
2404 2418
2405static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval) 2419static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
2406{ 2420{
2407 list_add(&oo->oo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); 2421 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
2422
2423 list_add(&oo->oo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]);
2408 list_add(&oo->oo_perclient, &clp->cl_openowners); 2424 list_add(&oo->oo_perclient, &clp->cl_openowners);
2409} 2425}
2410 2426
@@ -2444,11 +2460,13 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
2444} 2460}
2445 2461
2446static void 2462static void
2447move_to_close_lru(struct nfs4_openowner *oo) 2463move_to_close_lru(struct nfs4_openowner *oo, struct net *net)
2448{ 2464{
2465 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2466
2449 dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo); 2467 dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo);
2450 2468
2451 list_move_tail(&oo->oo_close_lru, &close_lru); 2469 list_move_tail(&oo->oo_close_lru, &nn->close_lru);
2452 oo->oo_time = get_seconds(); 2470 oo->oo_time = get_seconds();
2453} 2471}
2454 2472
@@ -2462,13 +2480,14 @@ same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
2462} 2480}
2463 2481
2464static struct nfs4_openowner * 2482static struct nfs4_openowner *
2465find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, bool sessions) 2483find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
2484 bool sessions, struct nfsd_net *nn)
2466{ 2485{
2467 struct nfs4_stateowner *so; 2486 struct nfs4_stateowner *so;
2468 struct nfs4_openowner *oo; 2487 struct nfs4_openowner *oo;
2469 struct nfs4_client *clp; 2488 struct nfs4_client *clp;
2470 2489
2471 list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) { 2490 list_for_each_entry(so, &nn->ownerstr_hashtbl[hashval], so_strhash) {
2472 if (!so->so_is_open_owner) 2491 if (!so->so_is_open_owner)
2473 continue; 2492 continue;
2474 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) { 2493 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) {
@@ -2555,9 +2574,14 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
2555 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; 2574 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
2556 struct nfs4_delegation *dp; 2575 struct nfs4_delegation *dp;
2557 2576
2558 BUG_ON(!fp); 2577 if (!fp) {
2559 /* We assume break_lease is only called once per lease: */ 2578 WARN(1, "(%p)->fl_owner NULL\n", fl);
2560 BUG_ON(fp->fi_had_conflict); 2579 return;
2580 }
2581 if (fp->fi_had_conflict) {
2582 WARN(1, "duplicate break on %p\n", fp);
2583 return;
2584 }
2561 /* 2585 /*
2562 * We don't want the locks code to timeout the lease for us; 2586 * We don't want the locks code to timeout the lease for us;
2563 * we'll remove it ourself if a delegation isn't returned 2587 * we'll remove it ourself if a delegation isn't returned
@@ -2599,14 +2623,13 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4
2599 2623
2600__be32 2624__be32
2601nfsd4_process_open1(struct nfsd4_compound_state *cstate, 2625nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2602 struct nfsd4_open *open) 2626 struct nfsd4_open *open, struct nfsd_net *nn)
2603{ 2627{
2604 clientid_t *clientid = &open->op_clientid; 2628 clientid_t *clientid = &open->op_clientid;
2605 struct nfs4_client *clp = NULL; 2629 struct nfs4_client *clp = NULL;
2606 unsigned int strhashval; 2630 unsigned int strhashval;
2607 struct nfs4_openowner *oo = NULL; 2631 struct nfs4_openowner *oo = NULL;
2608 __be32 status; 2632 __be32 status;
2609 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
2610 2633
2611 if (STALE_CLIENTID(&open->op_clientid, nn)) 2634 if (STALE_CLIENTID(&open->op_clientid, nn))
2612 return nfserr_stale_clientid; 2635 return nfserr_stale_clientid;
@@ -2619,10 +2642,11 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2619 return nfserr_jukebox; 2642 return nfserr_jukebox;
2620 2643
2621 strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner); 2644 strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner);
2622 oo = find_openstateowner_str(strhashval, open, cstate->minorversion); 2645 oo = find_openstateowner_str(strhashval, open, cstate->minorversion, nn);
2623 open->op_openowner = oo; 2646 open->op_openowner = oo;
2624 if (!oo) { 2647 if (!oo) {
2625 clp = find_confirmed_client(clientid, cstate->minorversion); 2648 clp = find_confirmed_client(clientid, cstate->minorversion,
2649 nn);
2626 if (clp == NULL) 2650 if (clp == NULL)
2627 return nfserr_expired; 2651 return nfserr_expired;
2628 goto new_owner; 2652 goto new_owner;
@@ -2891,7 +2915,7 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
2891 open->op_why_no_deleg = WND4_CANCELLED; 2915 open->op_why_no_deleg = WND4_CANCELLED;
2892 break; 2916 break;
2893 case NFS4_SHARE_WANT_NO_DELEG: 2917 case NFS4_SHARE_WANT_NO_DELEG:
2894 BUG(); /* not supposed to get here */ 2918 WARN_ON_ONCE(1);
2895 } 2919 }
2896 } 2920 }
2897} 2921}
@@ -2959,6 +2983,7 @@ out:
2959 } 2983 }
2960 return; 2984 return;
2961out_free: 2985out_free:
2986 unhash_stid(&dp->dl_stid);
2962 nfs4_put_delegation(dp); 2987 nfs4_put_delegation(dp);
2963out_no_deleg: 2988out_no_deleg:
2964 flag = NFS4_OPEN_DELEGATE_NONE; 2989 flag = NFS4_OPEN_DELEGATE_NONE;
@@ -3104,27 +3129,32 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status)
3104 free_generic_stateid(open->op_stp); 3129 free_generic_stateid(open->op_stp);
3105} 3130}
3106 3131
3132static __be32 lookup_clientid(clientid_t *clid, bool session, struct nfsd_net *nn, struct nfs4_client **clp)
3133{
3134 struct nfs4_client *found;
3135
3136 if (STALE_CLIENTID(clid, nn))
3137 return nfserr_stale_clientid;
3138 found = find_confirmed_client(clid, session, nn);
3139 if (clp)
3140 *clp = found;
3141 return found ? nfs_ok : nfserr_expired;
3142}
3143
3107__be32 3144__be32
3108nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3145nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3109 clientid_t *clid) 3146 clientid_t *clid)
3110{ 3147{
3111 struct nfs4_client *clp; 3148 struct nfs4_client *clp;
3112 __be32 status; 3149 __be32 status;
3113 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 3150 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3114 3151
3115 nfs4_lock_state(); 3152 nfs4_lock_state();
3116 dprintk("process_renew(%08x/%08x): starting\n", 3153 dprintk("process_renew(%08x/%08x): starting\n",
3117 clid->cl_boot, clid->cl_id); 3154 clid->cl_boot, clid->cl_id);
3118 status = nfserr_stale_clientid; 3155 status = lookup_clientid(clid, cstate->minorversion, nn, &clp);
3119 if (STALE_CLIENTID(clid, nn)) 3156 if (status)
3120 goto out;
3121 clp = find_confirmed_client(clid, cstate->minorversion);
3122 status = nfserr_expired;
3123 if (clp == NULL) {
3124 /* We assume the client took too long to RENEW. */
3125 dprintk("nfsd4_renew: clientid not found!\n");
3126 goto out; 3157 goto out;
3127 }
3128 status = nfserr_cb_path_down; 3158 status = nfserr_cb_path_down;
3129 if (!list_empty(&clp->cl_delegations) 3159 if (!list_empty(&clp->cl_delegations)
3130 && clp->cl_cb_state != NFSD4_CB_UP) 3160 && clp->cl_cb_state != NFSD4_CB_UP)
@@ -3136,44 +3166,42 @@ out:
3136} 3166}
3137 3167
3138static void 3168static void
3139nfsd4_end_grace(struct net *net) 3169nfsd4_end_grace(struct nfsd_net *nn)
3140{ 3170{
3141 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
3142
3143 /* do nothing if grace period already ended */ 3171 /* do nothing if grace period already ended */
3144 if (nn->grace_ended) 3172 if (nn->grace_ended)
3145 return; 3173 return;
3146 3174
3147 dprintk("NFSD: end of grace period\n"); 3175 dprintk("NFSD: end of grace period\n");
3148 nn->grace_ended = true; 3176 nn->grace_ended = true;
3149 nfsd4_record_grace_done(net, nn->boot_time); 3177 nfsd4_record_grace_done(nn, nn->boot_time);
3150 locks_end_grace(&nn->nfsd4_manager); 3178 locks_end_grace(&nn->nfsd4_manager);
3151 /* 3179 /*
3152 * Now that every NFSv4 client has had the chance to recover and 3180 * Now that every NFSv4 client has had the chance to recover and
3153 * to see the (possibly new, possibly shorter) lease time, we 3181 * to see the (possibly new, possibly shorter) lease time, we
3154 * can safely set the next grace time to the current lease time: 3182 * can safely set the next grace time to the current lease time:
3155 */ 3183 */
3156 nfsd4_grace = nfsd4_lease; 3184 nn->nfsd4_grace = nn->nfsd4_lease;
3157} 3185}
3158 3186
3159static time_t 3187static time_t
3160nfs4_laundromat(void) 3188nfs4_laundromat(struct nfsd_net *nn)
3161{ 3189{
3162 struct nfs4_client *clp; 3190 struct nfs4_client *clp;
3163 struct nfs4_openowner *oo; 3191 struct nfs4_openowner *oo;
3164 struct nfs4_delegation *dp; 3192 struct nfs4_delegation *dp;
3165 struct list_head *pos, *next, reaplist; 3193 struct list_head *pos, *next, reaplist;
3166 time_t cutoff = get_seconds() - nfsd4_lease; 3194 time_t cutoff = get_seconds() - nn->nfsd4_lease;
3167 time_t t, clientid_val = nfsd4_lease; 3195 time_t t, clientid_val = nn->nfsd4_lease;
3168 time_t u, test_val = nfsd4_lease; 3196 time_t u, test_val = nn->nfsd4_lease;
3169 3197
3170 nfs4_lock_state(); 3198 nfs4_lock_state();
3171 3199
3172 dprintk("NFSD: laundromat service - starting\n"); 3200 dprintk("NFSD: laundromat service - starting\n");
3173 nfsd4_end_grace(&init_net); 3201 nfsd4_end_grace(nn);
3174 INIT_LIST_HEAD(&reaplist); 3202 INIT_LIST_HEAD(&reaplist);
3175 spin_lock(&client_lock); 3203 spin_lock(&nn->client_lock);
3176 list_for_each_safe(pos, next, &client_lru) { 3204 list_for_each_safe(pos, next, &nn->client_lru) {
3177 clp = list_entry(pos, struct nfs4_client, cl_lru); 3205 clp = list_entry(pos, struct nfs4_client, cl_lru);
3178 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 3206 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
3179 t = clp->cl_time - cutoff; 3207 t = clp->cl_time - cutoff;
@@ -3189,7 +3217,7 @@ nfs4_laundromat(void)
3189 unhash_client_locked(clp); 3217 unhash_client_locked(clp);
3190 list_add(&clp->cl_lru, &reaplist); 3218 list_add(&clp->cl_lru, &reaplist);
3191 } 3219 }
3192 spin_unlock(&client_lock); 3220 spin_unlock(&nn->client_lock);
3193 list_for_each_safe(pos, next, &reaplist) { 3221 list_for_each_safe(pos, next, &reaplist) {
3194 clp = list_entry(pos, struct nfs4_client, cl_lru); 3222 clp = list_entry(pos, struct nfs4_client, cl_lru);
3195 dprintk("NFSD: purging unused client (clientid %08x)\n", 3223 dprintk("NFSD: purging unused client (clientid %08x)\n",
@@ -3199,6 +3227,8 @@ nfs4_laundromat(void)
3199 spin_lock(&recall_lock); 3227 spin_lock(&recall_lock);
3200 list_for_each_safe(pos, next, &del_recall_lru) { 3228 list_for_each_safe(pos, next, &del_recall_lru) {
3201 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 3229 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3230 if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn)
3231 continue;
3202 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) { 3232 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
3203 u = dp->dl_time - cutoff; 3233 u = dp->dl_time - cutoff;
3204 if (test_val > u) 3234 if (test_val > u)
@@ -3212,8 +3242,8 @@ nfs4_laundromat(void)
3212 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 3242 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3213 unhash_delegation(dp); 3243 unhash_delegation(dp);
3214 } 3244 }
3215 test_val = nfsd4_lease; 3245 test_val = nn->nfsd4_lease;
3216 list_for_each_safe(pos, next, &close_lru) { 3246 list_for_each_safe(pos, next, &nn->close_lru) {
3217 oo = container_of(pos, struct nfs4_openowner, oo_close_lru); 3247 oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
3218 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) { 3248 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
3219 u = oo->oo_time - cutoff; 3249 u = oo->oo_time - cutoff;
@@ -3231,16 +3261,19 @@ nfs4_laundromat(void)
3231 3261
3232static struct workqueue_struct *laundry_wq; 3262static struct workqueue_struct *laundry_wq;
3233static void laundromat_main(struct work_struct *); 3263static void laundromat_main(struct work_struct *);
3234static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main);
3235 3264
3236static void 3265static void
3237laundromat_main(struct work_struct *not_used) 3266laundromat_main(struct work_struct *laundry)
3238{ 3267{
3239 time_t t; 3268 time_t t;
3269 struct delayed_work *dwork = container_of(laundry, struct delayed_work,
3270 work);
3271 struct nfsd_net *nn = container_of(dwork, struct nfsd_net,
3272 laundromat_work);
3240 3273
3241 t = nfs4_laundromat(); 3274 t = nfs4_laundromat(nn);
3242 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t); 3275 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
3243 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 3276 queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
3244} 3277}
3245 3278
3246static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp) 3279static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
@@ -3385,16 +3418,17 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
3385 return nfs_ok; 3418 return nfs_ok;
3386} 3419}
3387 3420
3388static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, bool sessions) 3421static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask,
3422 struct nfs4_stid **s, bool sessions,
3423 struct nfsd_net *nn)
3389{ 3424{
3390 struct nfs4_client *cl; 3425 struct nfs4_client *cl;
3391 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
3392 3426
3393 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3427 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3394 return nfserr_bad_stateid; 3428 return nfserr_bad_stateid;
3395 if (STALE_STATEID(stateid, nn)) 3429 if (STALE_STATEID(stateid, nn))
3396 return nfserr_stale_stateid; 3430 return nfserr_stale_stateid;
3397 cl = find_confirmed_client(&stateid->si_opaque.so_clid, sessions); 3431 cl = find_confirmed_client(&stateid->si_opaque.so_clid, sessions, nn);
3398 if (!cl) 3432 if (!cl)
3399 return nfserr_expired; 3433 return nfserr_expired;
3400 *s = find_stateid_by_type(cl, stateid, typemask); 3434 *s = find_stateid_by_type(cl, stateid, typemask);
@@ -3416,6 +3450,7 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3416 struct nfs4_delegation *dp = NULL; 3450 struct nfs4_delegation *dp = NULL;
3417 struct svc_fh *current_fh = &cstate->current_fh; 3451 struct svc_fh *current_fh = &cstate->current_fh;
3418 struct inode *ino = current_fh->fh_dentry->d_inode; 3452 struct inode *ino = current_fh->fh_dentry->d_inode;
3453 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
3419 __be32 status; 3454 __be32 status;
3420 3455
3421 if (filpp) 3456 if (filpp)
@@ -3427,7 +3462,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3427 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3462 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3428 return check_special_stateids(net, current_fh, stateid, flags); 3463 return check_special_stateids(net, current_fh, stateid, flags);
3429 3464
3430 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s, cstate->minorversion); 3465 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
3466 &s, cstate->minorversion, nn);
3431 if (status) 3467 if (status)
3432 return status; 3468 return status;
3433 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate)); 3469 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
@@ -3441,7 +3477,11 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3441 goto out; 3477 goto out;
3442 if (filpp) { 3478 if (filpp) {
3443 *filpp = dp->dl_file->fi_deleg_file; 3479 *filpp = dp->dl_file->fi_deleg_file;
3444 BUG_ON(!*filpp); 3480 if (!*filpp) {
3481 WARN_ON_ONCE(1);
3482 status = nfserr_serverfault;
3483 goto out;
3484 }
3445 } 3485 }
3446 break; 3486 break;
3447 case NFS4_OPEN_STID: 3487 case NFS4_OPEN_STID:
@@ -3568,7 +3608,8 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
3568static __be32 3608static __be32
3569nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, 3609nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3570 stateid_t *stateid, char typemask, 3610 stateid_t *stateid, char typemask,
3571 struct nfs4_ol_stateid **stpp) 3611 struct nfs4_ol_stateid **stpp,
3612 struct nfsd_net *nn)
3572{ 3613{
3573 __be32 status; 3614 __be32 status;
3574 struct nfs4_stid *s; 3615 struct nfs4_stid *s;
@@ -3577,7 +3618,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3577 seqid, STATEID_VAL(stateid)); 3618 seqid, STATEID_VAL(stateid));
3578 3619
3579 *stpp = NULL; 3620 *stpp = NULL;
3580 status = nfsd4_lookup_stateid(stateid, typemask, &s, cstate->minorversion); 3621 status = nfsd4_lookup_stateid(stateid, typemask, &s,
3622 cstate->minorversion, nn);
3581 if (status) 3623 if (status)
3582 return status; 3624 return status;
3583 *stpp = openlockstateid(s); 3625 *stpp = openlockstateid(s);
@@ -3586,13 +3628,14 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3586 return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp); 3628 return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp);
3587} 3629}
3588 3630
3589static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, stateid_t *stateid, struct nfs4_ol_stateid **stpp) 3631static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3632 stateid_t *stateid, struct nfs4_ol_stateid **stpp, struct nfsd_net *nn)
3590{ 3633{
3591 __be32 status; 3634 __be32 status;
3592 struct nfs4_openowner *oo; 3635 struct nfs4_openowner *oo;
3593 3636
3594 status = nfs4_preprocess_seqid_op(cstate, seqid, stateid, 3637 status = nfs4_preprocess_seqid_op(cstate, seqid, stateid,
3595 NFS4_OPEN_STID, stpp); 3638 NFS4_OPEN_STID, stpp, nn);
3596 if (status) 3639 if (status)
3597 return status; 3640 return status;
3598 oo = openowner((*stpp)->st_stateowner); 3641 oo = openowner((*stpp)->st_stateowner);
@@ -3608,6 +3651,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3608 __be32 status; 3651 __be32 status;
3609 struct nfs4_openowner *oo; 3652 struct nfs4_openowner *oo;
3610 struct nfs4_ol_stateid *stp; 3653 struct nfs4_ol_stateid *stp;
3654 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3611 3655
3612 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", 3656 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
3613 (int)cstate->current_fh.fh_dentry->d_name.len, 3657 (int)cstate->current_fh.fh_dentry->d_name.len,
@@ -3621,7 +3665,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3621 3665
3622 status = nfs4_preprocess_seqid_op(cstate, 3666 status = nfs4_preprocess_seqid_op(cstate,
3623 oc->oc_seqid, &oc->oc_req_stateid, 3667 oc->oc_seqid, &oc->oc_req_stateid,
3624 NFS4_OPEN_STID, &stp); 3668 NFS4_OPEN_STID, &stp, nn);
3625 if (status) 3669 if (status)
3626 goto out; 3670 goto out;
3627 oo = openowner(stp->st_stateowner); 3671 oo = openowner(stp->st_stateowner);
@@ -3664,7 +3708,7 @@ static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_ac
3664 case NFS4_SHARE_ACCESS_BOTH: 3708 case NFS4_SHARE_ACCESS_BOTH:
3665 break; 3709 break;
3666 default: 3710 default:
3667 BUG(); 3711 WARN_ON_ONCE(1);
3668 } 3712 }
3669} 3713}
3670 3714
@@ -3685,6 +3729,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3685{ 3729{
3686 __be32 status; 3730 __be32 status;
3687 struct nfs4_ol_stateid *stp; 3731 struct nfs4_ol_stateid *stp;
3732 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3688 3733
3689 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 3734 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
3690 (int)cstate->current_fh.fh_dentry->d_name.len, 3735 (int)cstate->current_fh.fh_dentry->d_name.len,
@@ -3697,7 +3742,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3697 3742
3698 nfs4_lock_state(); 3743 nfs4_lock_state();
3699 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid, 3744 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
3700 &od->od_stateid, &stp); 3745 &od->od_stateid, &stp, nn);
3701 if (status) 3746 if (status)
3702 goto out; 3747 goto out;
3703 status = nfserr_inval; 3748 status = nfserr_inval;
@@ -3760,6 +3805,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3760 __be32 status; 3805 __be32 status;
3761 struct nfs4_openowner *oo; 3806 struct nfs4_openowner *oo;
3762 struct nfs4_ol_stateid *stp; 3807 struct nfs4_ol_stateid *stp;
3808 struct net *net = SVC_NET(rqstp);
3809 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
3763 3810
3764 dprintk("NFSD: nfsd4_close on file %.*s\n", 3811 dprintk("NFSD: nfsd4_close on file %.*s\n",
3765 (int)cstate->current_fh.fh_dentry->d_name.len, 3812 (int)cstate->current_fh.fh_dentry->d_name.len,
@@ -3769,7 +3816,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3769 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid, 3816 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
3770 &close->cl_stateid, 3817 &close->cl_stateid,
3771 NFS4_OPEN_STID|NFS4_CLOSED_STID, 3818 NFS4_OPEN_STID|NFS4_CLOSED_STID,
3772 &stp); 3819 &stp, nn);
3773 if (status) 3820 if (status)
3774 goto out; 3821 goto out;
3775 oo = openowner(stp->st_stateowner); 3822 oo = openowner(stp->st_stateowner);
@@ -3791,7 +3838,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3791 * little while to handle CLOSE replay. 3838 * little while to handle CLOSE replay.
3792 */ 3839 */
3793 if (list_empty(&oo->oo_owner.so_stateids)) 3840 if (list_empty(&oo->oo_owner.so_stateids))
3794 move_to_close_lru(oo); 3841 move_to_close_lru(oo, SVC_NET(rqstp));
3795 } 3842 }
3796 } 3843 }
3797out: 3844out:
@@ -3807,15 +3854,15 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3807 struct nfs4_delegation *dp; 3854 struct nfs4_delegation *dp;
3808 stateid_t *stateid = &dr->dr_stateid; 3855 stateid_t *stateid = &dr->dr_stateid;
3809 struct nfs4_stid *s; 3856 struct nfs4_stid *s;
3810 struct inode *inode;
3811 __be32 status; 3857 __be32 status;
3858 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3812 3859
3813 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) 3860 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
3814 return status; 3861 return status;
3815 inode = cstate->current_fh.fh_dentry->d_inode;
3816 3862
3817 nfs4_lock_state(); 3863 nfs4_lock_state();
3818 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s, cstate->minorversion); 3864 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s,
3865 cstate->minorversion, nn);
3819 if (status) 3866 if (status)
3820 goto out; 3867 goto out;
3821 dp = delegstateid(s); 3868 dp = delegstateid(s);
@@ -3833,8 +3880,6 @@ out:
3833 3880
3834#define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start)) 3881#define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start))
3835 3882
3836#define LOCKOWNER_INO_HASH_BITS 8
3837#define LOCKOWNER_INO_HASH_SIZE (1 << LOCKOWNER_INO_HASH_BITS)
3838#define LOCKOWNER_INO_HASH_MASK (LOCKOWNER_INO_HASH_SIZE - 1) 3883#define LOCKOWNER_INO_HASH_MASK (LOCKOWNER_INO_HASH_SIZE - 1)
3839 3884
3840static inline u64 3885static inline u64
@@ -3852,7 +3897,7 @@ last_byte_offset(u64 start, u64 len)
3852{ 3897{
3853 u64 end; 3898 u64 end;
3854 3899
3855 BUG_ON(!len); 3900 WARN_ON_ONCE(!len);
3856 end = start + len; 3901 end = start + len;
3857 return end > start ? end - 1: NFS4_MAX_UINT64; 3902 return end > start ? end - 1: NFS4_MAX_UINT64;
3858} 3903}
@@ -3864,8 +3909,6 @@ static unsigned int lockowner_ino_hashval(struct inode *inode, u32 cl_id, struct
3864 & LOCKOWNER_INO_HASH_MASK; 3909 & LOCKOWNER_INO_HASH_MASK;
3865} 3910}
3866 3911
3867static struct list_head lockowner_ino_hashtbl[LOCKOWNER_INO_HASH_SIZE];
3868
3869/* 3912/*
3870 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that 3913 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
3871 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th 3914 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
@@ -3931,12 +3974,12 @@ static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, c
3931 3974
3932static struct nfs4_lockowner * 3975static struct nfs4_lockowner *
3933find_lockowner_str(struct inode *inode, clientid_t *clid, 3976find_lockowner_str(struct inode *inode, clientid_t *clid,
3934 struct xdr_netobj *owner) 3977 struct xdr_netobj *owner, struct nfsd_net *nn)
3935{ 3978{
3936 unsigned int hashval = lockowner_ino_hashval(inode, clid->cl_id, owner); 3979 unsigned int hashval = lockowner_ino_hashval(inode, clid->cl_id, owner);
3937 struct nfs4_lockowner *lo; 3980 struct nfs4_lockowner *lo;
3938 3981
3939 list_for_each_entry(lo, &lockowner_ino_hashtbl[hashval], lo_owner_ino_hash) { 3982 list_for_each_entry(lo, &nn->lockowner_ino_hashtbl[hashval], lo_owner_ino_hash) {
3940 if (same_lockowner_ino(lo, inode, clid, owner)) 3983 if (same_lockowner_ino(lo, inode, clid, owner))
3941 return lo; 3984 return lo;
3942 } 3985 }
@@ -3948,9 +3991,10 @@ static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, s
3948 struct inode *inode = open_stp->st_file->fi_inode; 3991 struct inode *inode = open_stp->st_file->fi_inode;
3949 unsigned int inohash = lockowner_ino_hashval(inode, 3992 unsigned int inohash = lockowner_ino_hashval(inode,
3950 clp->cl_clientid.cl_id, &lo->lo_owner.so_owner); 3993 clp->cl_clientid.cl_id, &lo->lo_owner.so_owner);
3994 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
3951 3995
3952 list_add(&lo->lo_owner.so_strhash, &ownerstr_hashtbl[strhashval]); 3996 list_add(&lo->lo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]);
3953 list_add(&lo->lo_owner_ino_hash, &lockowner_ino_hashtbl[inohash]); 3997 list_add(&lo->lo_owner_ino_hash, &nn->lockowner_ino_hashtbl[inohash]);
3954 list_add(&lo->lo_perstateid, &open_stp->st_lockowners); 3998 list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
3955} 3999}
3956 4000
@@ -4024,8 +4068,10 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, s
4024 struct nfs4_client *cl = oo->oo_owner.so_client; 4068 struct nfs4_client *cl = oo->oo_owner.so_client;
4025 struct nfs4_lockowner *lo; 4069 struct nfs4_lockowner *lo;
4026 unsigned int strhashval; 4070 unsigned int strhashval;
4071 struct nfsd_net *nn = net_generic(cl->net, nfsd_net_id);
4027 4072
4028 lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid, &lock->v.new.owner); 4073 lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid,
4074 &lock->v.new.owner, nn);
4029 if (lo) { 4075 if (lo) {
4030 if (!cstate->minorversion) 4076 if (!cstate->minorversion)
4031 return nfserr_bad_seqid; 4077 return nfserr_bad_seqid;
@@ -4065,7 +4111,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4065 bool new_state = false; 4111 bool new_state = false;
4066 int lkflg; 4112 int lkflg;
4067 int err; 4113 int err;
4068 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 4114 struct net *net = SVC_NET(rqstp);
4115 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4069 4116
4070 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", 4117 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
4071 (long long) lock->lk_offset, 4118 (long long) lock->lk_offset,
@@ -4099,7 +4146,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4099 status = nfs4_preprocess_confirmed_seqid_op(cstate, 4146 status = nfs4_preprocess_confirmed_seqid_op(cstate,
4100 lock->lk_new_open_seqid, 4147 lock->lk_new_open_seqid,
4101 &lock->lk_new_open_stateid, 4148 &lock->lk_new_open_stateid,
4102 &open_stp); 4149 &open_stp, nn);
4103 if (status) 4150 if (status)
4104 goto out; 4151 goto out;
4105 open_sop = openowner(open_stp->st_stateowner); 4152 open_sop = openowner(open_stp->st_stateowner);
@@ -4113,7 +4160,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4113 status = nfs4_preprocess_seqid_op(cstate, 4160 status = nfs4_preprocess_seqid_op(cstate,
4114 lock->lk_old_lock_seqid, 4161 lock->lk_old_lock_seqid,
4115 &lock->lk_old_lock_stateid, 4162 &lock->lk_old_lock_stateid,
4116 NFS4_LOCK_STID, &lock_stp); 4163 NFS4_LOCK_STID, &lock_stp, nn);
4117 if (status) 4164 if (status)
4118 goto out; 4165 goto out;
4119 lock_sop = lockowner(lock_stp->st_stateowner); 4166 lock_sop = lockowner(lock_stp->st_stateowner);
@@ -4124,10 +4171,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4124 goto out; 4171 goto out;
4125 4172
4126 status = nfserr_grace; 4173 status = nfserr_grace;
4127 if (locks_in_grace(SVC_NET(rqstp)) && !lock->lk_reclaim) 4174 if (locks_in_grace(net) && !lock->lk_reclaim)
4128 goto out; 4175 goto out;
4129 status = nfserr_no_grace; 4176 status = nfserr_no_grace;
4130 if (!locks_in_grace(SVC_NET(rqstp)) && lock->lk_reclaim) 4177 if (!locks_in_grace(net) && lock->lk_reclaim)
4131 goto out; 4178 goto out;
4132 4179
4133 file_lock = locks_alloc_lock(); 4180 file_lock = locks_alloc_lock();
@@ -4238,7 +4285,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4238 struct file_lock *file_lock = NULL; 4285 struct file_lock *file_lock = NULL;
4239 struct nfs4_lockowner *lo; 4286 struct nfs4_lockowner *lo;
4240 __be32 status; 4287 __be32 status;
4241 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 4288 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
4242 4289
4243 if (locks_in_grace(SVC_NET(rqstp))) 4290 if (locks_in_grace(SVC_NET(rqstp)))
4244 return nfserr_grace; 4291 return nfserr_grace;
@@ -4248,9 +4295,11 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4248 4295
4249 nfs4_lock_state(); 4296 nfs4_lock_state();
4250 4297
4251 status = nfserr_stale_clientid; 4298 if (!nfsd4_has_session(cstate)) {
4252 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid, nn)) 4299 status = lookup_clientid(&lockt->lt_clientid, false, nn, NULL);
4253 goto out; 4300 if (status)
4301 goto out;
4302 }
4254 4303
4255 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) 4304 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
4256 goto out; 4305 goto out;
@@ -4278,7 +4327,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4278 goto out; 4327 goto out;
4279 } 4328 }
4280 4329
4281 lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner); 4330 lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner, nn);
4282 if (lo) 4331 if (lo)
4283 file_lock->fl_owner = (fl_owner_t)lo; 4332 file_lock->fl_owner = (fl_owner_t)lo;
4284 file_lock->fl_pid = current->tgid; 4333 file_lock->fl_pid = current->tgid;
@@ -4313,7 +4362,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4313 struct file_lock *file_lock = NULL; 4362 struct file_lock *file_lock = NULL;
4314 __be32 status; 4363 __be32 status;
4315 int err; 4364 int err;
4316 4365 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
4366
4317 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n", 4367 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
4318 (long long) locku->lu_offset, 4368 (long long) locku->lu_offset,
4319 (long long) locku->lu_length); 4369 (long long) locku->lu_length);
@@ -4324,7 +4374,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4324 nfs4_lock_state(); 4374 nfs4_lock_state();
4325 4375
4326 status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid, 4376 status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid,
4327 &locku->lu_stateid, NFS4_LOCK_STID, &stp); 4377 &locku->lu_stateid, NFS4_LOCK_STID,
4378 &stp, nn);
4328 if (status) 4379 if (status)
4329 goto out; 4380 goto out;
4330 filp = find_any_file(stp->st_file); 4381 filp = find_any_file(stp->st_file);
@@ -4414,23 +4465,21 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4414 struct list_head matches; 4465 struct list_head matches;
4415 unsigned int hashval = ownerstr_hashval(clid->cl_id, owner); 4466 unsigned int hashval = ownerstr_hashval(clid->cl_id, owner);
4416 __be32 status; 4467 __be32 status;
4417 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 4468 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
4418 4469
4419 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", 4470 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
4420 clid->cl_boot, clid->cl_id); 4471 clid->cl_boot, clid->cl_id);
4421 4472
4422 /* XXX check for lease expiration */
4423
4424 status = nfserr_stale_clientid;
4425 if (STALE_CLIENTID(clid, nn))
4426 return status;
4427
4428 nfs4_lock_state(); 4473 nfs4_lock_state();
4429 4474
4475 status = lookup_clientid(clid, cstate->minorversion, nn, NULL);
4476 if (status)
4477 goto out;
4478
4430 status = nfserr_locks_held; 4479 status = nfserr_locks_held;
4431 INIT_LIST_HEAD(&matches); 4480 INIT_LIST_HEAD(&matches);
4432 4481
4433 list_for_each_entry(sop, &ownerstr_hashtbl[hashval], so_strhash) { 4482 list_for_each_entry(sop, &nn->ownerstr_hashtbl[hashval], so_strhash) {
4434 if (sop->so_is_open_owner) 4483 if (sop->so_is_open_owner)
4435 continue; 4484 continue;
4436 if (!same_owner_str(sop, owner, clid)) 4485 if (!same_owner_str(sop, owner, clid))
@@ -4466,73 +4515,74 @@ alloc_reclaim(void)
4466 return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL); 4515 return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
4467} 4516}
4468 4517
4469int 4518bool
4470nfs4_has_reclaimed_state(const char *name, bool use_exchange_id) 4519nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn)
4471{ 4520{
4472 unsigned int strhashval = clientstr_hashval(name); 4521 struct nfs4_client_reclaim *crp;
4473 struct nfs4_client *clp;
4474 4522
4475 clp = find_confirmed_client_by_str(name, strhashval); 4523 crp = nfsd4_find_reclaim_client(name, nn);
4476 if (!clp) 4524 return (crp && crp->cr_clp);
4477 return 0;
4478 return test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
4479} 4525}
4480 4526
4481/* 4527/*
4482 * failure => all reset bets are off, nfserr_no_grace... 4528 * failure => all reset bets are off, nfserr_no_grace...
4483 */ 4529 */
4484int 4530struct nfs4_client_reclaim *
4485nfs4_client_to_reclaim(const char *name) 4531nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn)
4486{ 4532{
4487 unsigned int strhashval; 4533 unsigned int strhashval;
4488 struct nfs4_client_reclaim *crp = NULL; 4534 struct nfs4_client_reclaim *crp;
4489 4535
4490 dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name); 4536 dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
4491 crp = alloc_reclaim(); 4537 crp = alloc_reclaim();
4492 if (!crp) 4538 if (crp) {
4493 return 0; 4539 strhashval = clientstr_hashval(name);
4494 strhashval = clientstr_hashval(name); 4540 INIT_LIST_HEAD(&crp->cr_strhash);
4495 INIT_LIST_HEAD(&crp->cr_strhash); 4541 list_add(&crp->cr_strhash, &nn->reclaim_str_hashtbl[strhashval]);
4496 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]); 4542 memcpy(crp->cr_recdir, name, HEXDIR_LEN);
4497 memcpy(crp->cr_recdir, name, HEXDIR_LEN); 4543 crp->cr_clp = NULL;
4498 reclaim_str_hashtbl_size++; 4544 nn->reclaim_str_hashtbl_size++;
4499 return 1; 4545 }
4546 return crp;
4547}
4548
4549void
4550nfs4_remove_reclaim_record(struct nfs4_client_reclaim *crp, struct nfsd_net *nn)
4551{
4552 list_del(&crp->cr_strhash);
4553 kfree(crp);
4554 nn->reclaim_str_hashtbl_size--;
4500} 4555}
4501 4556
4502void 4557void
4503nfs4_release_reclaim(void) 4558nfs4_release_reclaim(struct nfsd_net *nn)
4504{ 4559{
4505 struct nfs4_client_reclaim *crp = NULL; 4560 struct nfs4_client_reclaim *crp = NULL;
4506 int i; 4561 int i;
4507 4562
4508 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 4563 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4509 while (!list_empty(&reclaim_str_hashtbl[i])) { 4564 while (!list_empty(&nn->reclaim_str_hashtbl[i])) {
4510 crp = list_entry(reclaim_str_hashtbl[i].next, 4565 crp = list_entry(nn->reclaim_str_hashtbl[i].next,
4511 struct nfs4_client_reclaim, cr_strhash); 4566 struct nfs4_client_reclaim, cr_strhash);
4512 list_del(&crp->cr_strhash); 4567 nfs4_remove_reclaim_record(crp, nn);
4513 kfree(crp);
4514 reclaim_str_hashtbl_size--;
4515 } 4568 }
4516 } 4569 }
4517 BUG_ON(reclaim_str_hashtbl_size); 4570 WARN_ON_ONCE(nn->reclaim_str_hashtbl_size);
4518} 4571}
4519 4572
4520/* 4573/*
4521 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */ 4574 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
4522struct nfs4_client_reclaim * 4575struct nfs4_client_reclaim *
4523nfsd4_find_reclaim_client(struct nfs4_client *clp) 4576nfsd4_find_reclaim_client(const char *recdir, struct nfsd_net *nn)
4524{ 4577{
4525 unsigned int strhashval; 4578 unsigned int strhashval;
4526 struct nfs4_client_reclaim *crp = NULL; 4579 struct nfs4_client_reclaim *crp = NULL;
4527 4580
4528 dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n", 4581 dprintk("NFSD: nfs4_find_reclaim_client for recdir %s\n", recdir);
4529 clp->cl_name.len, clp->cl_name.data,
4530 clp->cl_recdir);
4531 4582
4532 /* find clp->cl_name in reclaim_str_hashtbl */ 4583 strhashval = clientstr_hashval(recdir);
4533 strhashval = clientstr_hashval(clp->cl_recdir); 4584 list_for_each_entry(crp, &nn->reclaim_str_hashtbl[strhashval], cr_strhash) {
4534 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) { 4585 if (same_name(crp->cr_recdir, recdir)) {
4535 if (same_name(crp->cr_recdir, clp->cl_recdir)) {
4536 return crp; 4586 return crp;
4537 } 4587 }
4538 } 4588 }
@@ -4543,12 +4593,12 @@ nfsd4_find_reclaim_client(struct nfs4_client *clp)
4543* Called from OPEN. Look for clientid in reclaim list. 4593* Called from OPEN. Look for clientid in reclaim list.
4544*/ 4594*/
4545__be32 4595__be32
4546nfs4_check_open_reclaim(clientid_t *clid, bool sessions) 4596nfs4_check_open_reclaim(clientid_t *clid, bool sessions, struct nfsd_net *nn)
4547{ 4597{
4548 struct nfs4_client *clp; 4598 struct nfs4_client *clp;
4549 4599
4550 /* find clientid in conf_id_hashtbl */ 4600 /* find clientid in conf_id_hashtbl */
4551 clp = find_confirmed_client(clid, sessions); 4601 clp = find_confirmed_client(clid, sessions, nn);
4552 if (clp == NULL) 4602 if (clp == NULL)
4553 return nfserr_reclaim_bad; 4603 return nfserr_reclaim_bad;
4554 4604
@@ -4557,124 +4607,177 @@ nfs4_check_open_reclaim(clientid_t *clid, bool sessions)
4557 4607
4558#ifdef CONFIG_NFSD_FAULT_INJECTION 4608#ifdef CONFIG_NFSD_FAULT_INJECTION
4559 4609
4560void nfsd_forget_clients(u64 num) 4610u64 nfsd_forget_client(struct nfs4_client *clp, u64 max)
4561{ 4611{
4562 struct nfs4_client *clp, *next; 4612 expire_client(clp);
4563 int count = 0; 4613 return 1;
4564
4565 nfs4_lock_state();
4566 list_for_each_entry_safe(clp, next, &client_lru, cl_lru) {
4567 expire_client(clp);
4568 if (++count == num)
4569 break;
4570 }
4571 nfs4_unlock_state();
4572
4573 printk(KERN_INFO "NFSD: Forgot %d clients", count);
4574} 4614}
4575 4615
4576static void release_lockowner_sop(struct nfs4_stateowner *sop) 4616u64 nfsd_print_client(struct nfs4_client *clp, u64 num)
4577{ 4617{
4578 release_lockowner(lockowner(sop)); 4618 char buf[INET6_ADDRSTRLEN];
4619 rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
4620 printk(KERN_INFO "NFS Client: %s\n", buf);
4621 return 1;
4579} 4622}
4580 4623
4581static void release_openowner_sop(struct nfs4_stateowner *sop) 4624static void nfsd_print_count(struct nfs4_client *clp, unsigned int count,
4625 const char *type)
4582{ 4626{
4583 release_openowner(openowner(sop)); 4627 char buf[INET6_ADDRSTRLEN];
4628 rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
4629 printk(KERN_INFO "NFS Client: %s has %u %s\n", buf, count, type);
4584} 4630}
4585 4631
4586static int nfsd_release_n_owners(u64 num, bool is_open_owner, 4632static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max, void (*func)(struct nfs4_lockowner *))
4587 void (*release_sop)(struct nfs4_stateowner *))
4588{ 4633{
4589 int i, count = 0; 4634 struct nfs4_openowner *oop;
4590 struct nfs4_stateowner *sop, *next; 4635 struct nfs4_lockowner *lop, *lo_next;
4636 struct nfs4_ol_stateid *stp, *st_next;
4637 u64 count = 0;
4591 4638
4592 for (i = 0; i < OWNER_HASH_SIZE; i++) { 4639 list_for_each_entry(oop, &clp->cl_openowners, oo_perclient) {
4593 list_for_each_entry_safe(sop, next, &ownerstr_hashtbl[i], so_strhash) { 4640 list_for_each_entry_safe(stp, st_next, &oop->oo_owner.so_stateids, st_perstateowner) {
4594 if (sop->so_is_open_owner != is_open_owner) 4641 list_for_each_entry_safe(lop, lo_next, &stp->st_lockowners, lo_perstateid) {
4595 continue; 4642 if (func)
4596 release_sop(sop); 4643 func(lop);
4597 if (++count == num) 4644 if (++count == max)
4598 return count; 4645 return count;
4646 }
4599 } 4647 }
4600 } 4648 }
4649
4601 return count; 4650 return count;
4602} 4651}
4603 4652
4604void nfsd_forget_locks(u64 num) 4653u64 nfsd_forget_client_locks(struct nfs4_client *clp, u64 max)
4605{ 4654{
4606 int count; 4655 return nfsd_foreach_client_lock(clp, max, release_lockowner);
4607 4656}
4608 nfs4_lock_state();
4609 count = nfsd_release_n_owners(num, false, release_lockowner_sop);
4610 nfs4_unlock_state();
4611 4657
4612 printk(KERN_INFO "NFSD: Forgot %d locks", count); 4658u64 nfsd_print_client_locks(struct nfs4_client *clp, u64 max)
4659{
4660 u64 count = nfsd_foreach_client_lock(clp, max, NULL);
4661 nfsd_print_count(clp, count, "locked files");
4662 return count;
4613} 4663}
4614 4664
4615void nfsd_forget_openowners(u64 num) 4665static u64 nfsd_foreach_client_open(struct nfs4_client *clp, u64 max, void (*func)(struct nfs4_openowner *))
4616{ 4666{
4617 int count; 4667 struct nfs4_openowner *oop, *next;
4668 u64 count = 0;
4618 4669
4619 nfs4_lock_state(); 4670 list_for_each_entry_safe(oop, next, &clp->cl_openowners, oo_perclient) {
4620 count = nfsd_release_n_owners(num, true, release_openowner_sop); 4671 if (func)
4621 nfs4_unlock_state(); 4672 func(oop);
4673 if (++count == max)
4674 break;
4675 }
4622 4676
4623 printk(KERN_INFO "NFSD: Forgot %d open owners", count); 4677 return count;
4624} 4678}
4625 4679
4626static int nfsd_process_n_delegations(u64 num, struct list_head *list) 4680u64 nfsd_forget_client_openowners(struct nfs4_client *clp, u64 max)
4627{ 4681{
4628 int i, count = 0; 4682 return nfsd_foreach_client_open(clp, max, release_openowner);
4629 struct nfs4_file *fp, *fnext; 4683}
4630 struct nfs4_delegation *dp, *dnext;
4631 4684
4632 for (i = 0; i < FILE_HASH_SIZE; i++) { 4685u64 nfsd_print_client_openowners(struct nfs4_client *clp, u64 max)
4633 list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) { 4686{
4634 list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) { 4687 u64 count = nfsd_foreach_client_open(clp, max, NULL);
4635 list_move(&dp->dl_recall_lru, list); 4688 nfsd_print_count(clp, count, "open files");
4636 if (++count == num) 4689 return count;
4637 return count; 4690}
4638 } 4691
4639 } 4692static u64 nfsd_find_all_delegations(struct nfs4_client *clp, u64 max,
4640 } 4693 struct list_head *victims)
4694{
4695 struct nfs4_delegation *dp, *next;
4696 u64 count = 0;
4641 4697
4698 list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) {
4699 if (victims)
4700 list_move(&dp->dl_recall_lru, victims);
4701 if (++count == max)
4702 break;
4703 }
4642 return count; 4704 return count;
4643} 4705}
4644 4706
4645void nfsd_forget_delegations(u64 num) 4707u64 nfsd_forget_client_delegations(struct nfs4_client *clp, u64 max)
4646{ 4708{
4647 unsigned int count; 4709 struct nfs4_delegation *dp, *next;
4648 LIST_HEAD(victims); 4710 LIST_HEAD(victims);
4649 struct nfs4_delegation *dp, *dnext; 4711 u64 count;
4650 4712
4651 spin_lock(&recall_lock); 4713 spin_lock(&recall_lock);
4652 count = nfsd_process_n_delegations(num, &victims); 4714 count = nfsd_find_all_delegations(clp, max, &victims);
4653 spin_unlock(&recall_lock); 4715 spin_unlock(&recall_lock);
4654 4716
4655 nfs4_lock_state(); 4717 list_for_each_entry_safe(dp, next, &victims, dl_recall_lru)
4656 list_for_each_entry_safe(dp, dnext, &victims, dl_recall_lru)
4657 unhash_delegation(dp); 4718 unhash_delegation(dp);
4658 nfs4_unlock_state();
4659 4719
4660 printk(KERN_INFO "NFSD: Forgot %d delegations", count); 4720 return count;
4661} 4721}
4662 4722
4663void nfsd_recall_delegations(u64 num) 4723u64 nfsd_recall_client_delegations(struct nfs4_client *clp, u64 max)
4664{ 4724{
4665 unsigned int count; 4725 struct nfs4_delegation *dp, *next;
4666 LIST_HEAD(victims); 4726 LIST_HEAD(victims);
4667 struct nfs4_delegation *dp, *dnext; 4727 u64 count;
4668 4728
4669 spin_lock(&recall_lock); 4729 spin_lock(&recall_lock);
4670 count = nfsd_process_n_delegations(num, &victims); 4730 count = nfsd_find_all_delegations(clp, max, &victims);
4671 list_for_each_entry_safe(dp, dnext, &victims, dl_recall_lru) { 4731 list_for_each_entry_safe(dp, next, &victims, dl_recall_lru)
4672 list_del(&dp->dl_recall_lru);
4673 nfsd_break_one_deleg(dp); 4732 nfsd_break_one_deleg(dp);
4674 }
4675 spin_unlock(&recall_lock); 4733 spin_unlock(&recall_lock);
4676 4734
4677 printk(KERN_INFO "NFSD: Recalled %d delegations", count); 4735 return count;
4736}
4737
4738u64 nfsd_print_client_delegations(struct nfs4_client *clp, u64 max)
4739{
4740 u64 count = 0;
4741
4742 spin_lock(&recall_lock);
4743 count = nfsd_find_all_delegations(clp, max, NULL);
4744 spin_unlock(&recall_lock);
4745
4746 nfsd_print_count(clp, count, "delegations");
4747 return count;
4748}
4749
4750u64 nfsd_for_n_state(u64 max, u64 (*func)(struct nfs4_client *, u64))
4751{
4752 struct nfs4_client *clp, *next;
4753 u64 count = 0;
4754 struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, nfsd_net_id);
4755
4756 if (!nfsd_netns_ready(nn))
4757 return 0;
4758
4759 list_for_each_entry_safe(clp, next, &nn->client_lru, cl_lru) {
4760 count += func(clp, max - count);
4761 if ((max != 0) && (count >= max))
4762 break;
4763 }
4764
4765 return count;
4766}
4767
4768struct nfs4_client *nfsd_find_client(struct sockaddr_storage *addr, size_t addr_size)
4769{
4770 struct nfs4_client *clp;
4771 struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, nfsd_net_id);
4772
4773 if (!nfsd_netns_ready(nn))
4774 return NULL;
4775
4776 list_for_each_entry(clp, &nn->client_lru, cl_lru) {
4777 if (memcmp(&clp->cl_addr, addr, addr_size) == 0)
4778 return clp;
4779 }
4780 return NULL;
4678} 4781}
4679 4782
4680#endif /* CONFIG_NFSD_FAULT_INJECTION */ 4783#endif /* CONFIG_NFSD_FAULT_INJECTION */
@@ -4686,27 +4789,10 @@ nfs4_state_init(void)
4686{ 4789{
4687 int i; 4790 int i;
4688 4791
4689 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4690 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
4691 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
4692 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
4693 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
4694 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
4695 }
4696 for (i = 0; i < SESSION_HASH_SIZE; i++)
4697 INIT_LIST_HEAD(&sessionid_hashtbl[i]);
4698 for (i = 0; i < FILE_HASH_SIZE; i++) { 4792 for (i = 0; i < FILE_HASH_SIZE; i++) {
4699 INIT_LIST_HEAD(&file_hashtbl[i]); 4793 INIT_LIST_HEAD(&file_hashtbl[i]);
4700 } 4794 }
4701 for (i = 0; i < OWNER_HASH_SIZE; i++) {
4702 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
4703 }
4704 for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++)
4705 INIT_LIST_HEAD(&lockowner_ino_hashtbl[i]);
4706 INIT_LIST_HEAD(&close_lru);
4707 INIT_LIST_HEAD(&client_lru);
4708 INIT_LIST_HEAD(&del_recall_lru); 4795 INIT_LIST_HEAD(&del_recall_lru);
4709 reclaim_str_hashtbl_size = 0;
4710} 4796}
4711 4797
4712/* 4798/*
@@ -4730,12 +4816,100 @@ set_max_delegations(void)
4730 max_delegations = nr_free_buffer_pages() >> (20 - 2 - PAGE_SHIFT); 4816 max_delegations = nr_free_buffer_pages() >> (20 - 2 - PAGE_SHIFT);
4731} 4817}
4732 4818
4733/* initialization to perform when the nfsd service is started: */ 4819static int nfs4_state_create_net(struct net *net)
4820{
4821 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4822 int i;
4823
4824 nn->conf_id_hashtbl = kmalloc(sizeof(struct list_head) *
4825 CLIENT_HASH_SIZE, GFP_KERNEL);
4826 if (!nn->conf_id_hashtbl)
4827 goto err;
4828 nn->unconf_id_hashtbl = kmalloc(sizeof(struct list_head) *
4829 CLIENT_HASH_SIZE, GFP_KERNEL);
4830 if (!nn->unconf_id_hashtbl)
4831 goto err_unconf_id;
4832 nn->ownerstr_hashtbl = kmalloc(sizeof(struct list_head) *
4833 OWNER_HASH_SIZE, GFP_KERNEL);
4834 if (!nn->ownerstr_hashtbl)
4835 goto err_ownerstr;
4836 nn->lockowner_ino_hashtbl = kmalloc(sizeof(struct list_head) *
4837 LOCKOWNER_INO_HASH_SIZE, GFP_KERNEL);
4838 if (!nn->lockowner_ino_hashtbl)
4839 goto err_lockowner_ino;
4840 nn->sessionid_hashtbl = kmalloc(sizeof(struct list_head) *
4841 SESSION_HASH_SIZE, GFP_KERNEL);
4842 if (!nn->sessionid_hashtbl)
4843 goto err_sessionid;
4844
4845 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4846 INIT_LIST_HEAD(&nn->conf_id_hashtbl[i]);
4847 INIT_LIST_HEAD(&nn->unconf_id_hashtbl[i]);
4848 }
4849 for (i = 0; i < OWNER_HASH_SIZE; i++)
4850 INIT_LIST_HEAD(&nn->ownerstr_hashtbl[i]);
4851 for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++)
4852 INIT_LIST_HEAD(&nn->lockowner_ino_hashtbl[i]);
4853 for (i = 0; i < SESSION_HASH_SIZE; i++)
4854 INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]);
4855 nn->conf_name_tree = RB_ROOT;
4856 nn->unconf_name_tree = RB_ROOT;
4857 INIT_LIST_HEAD(&nn->client_lru);
4858 INIT_LIST_HEAD(&nn->close_lru);
4859 spin_lock_init(&nn->client_lock);
4860
4861 INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main);
4862 get_net(net);
4863
4864 return 0;
4865
4866err_sessionid:
4867 kfree(nn->lockowner_ino_hashtbl);
4868err_lockowner_ino:
4869 kfree(nn->ownerstr_hashtbl);
4870err_ownerstr:
4871 kfree(nn->unconf_id_hashtbl);
4872err_unconf_id:
4873 kfree(nn->conf_id_hashtbl);
4874err:
4875 return -ENOMEM;
4876}
4877
4878static void
4879nfs4_state_destroy_net(struct net *net)
4880{
4881 int i;
4882 struct nfs4_client *clp = NULL;
4883 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4884 struct rb_node *node, *tmp;
4885
4886 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4887 while (!list_empty(&nn->conf_id_hashtbl[i])) {
4888 clp = list_entry(nn->conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
4889 destroy_client(clp);
4890 }
4891 }
4892
4893 node = rb_first(&nn->unconf_name_tree);
4894 while (node != NULL) {
4895 tmp = node;
4896 node = rb_next(tmp);
4897 clp = rb_entry(tmp, struct nfs4_client, cl_namenode);
4898 rb_erase(tmp, &nn->unconf_name_tree);
4899 destroy_client(clp);
4900 }
4901
4902 kfree(nn->sessionid_hashtbl);
4903 kfree(nn->lockowner_ino_hashtbl);
4904 kfree(nn->ownerstr_hashtbl);
4905 kfree(nn->unconf_id_hashtbl);
4906 kfree(nn->conf_id_hashtbl);
4907 put_net(net);
4908}
4734 4909
4735int 4910int
4736nfs4_state_start(void) 4911nfs4_state_start_net(struct net *net)
4737{ 4912{
4738 struct net *net = &init_net;
4739 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 4913 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4740 int ret; 4914 int ret;
4741 4915
@@ -4746,18 +4920,32 @@ nfs4_state_start(void)
4746 * to that instead and then do most of the rest of this on a per-net 4920 * to that instead and then do most of the rest of this on a per-net
4747 * basis. 4921 * basis.
4748 */ 4922 */
4749 get_net(net); 4923 if (net != &init_net)
4924 return -EINVAL;
4925
4926 ret = nfs4_state_create_net(net);
4927 if (ret)
4928 return ret;
4750 nfsd4_client_tracking_init(net); 4929 nfsd4_client_tracking_init(net);
4751 nn->boot_time = get_seconds(); 4930 nn->boot_time = get_seconds();
4752 locks_start_grace(net, &nn->nfsd4_manager); 4931 locks_start_grace(net, &nn->nfsd4_manager);
4753 nn->grace_ended = false; 4932 nn->grace_ended = false;
4754 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4933 printk(KERN_INFO "NFSD: starting %ld-second grace period (net %p)\n",
4755 nfsd4_grace); 4934 nn->nfsd4_grace, net);
4935 queue_delayed_work(laundry_wq, &nn->laundromat_work, nn->nfsd4_grace * HZ);
4936 return 0;
4937}
4938
4939/* initialization to perform when the nfsd service is started: */
4940
4941int
4942nfs4_state_start(void)
4943{
4944 int ret;
4945
4756 ret = set_callback_cred(); 4946 ret = set_callback_cred();
4757 if (ret) { 4947 if (ret)
4758 ret = -ENOMEM; 4948 return -ENOMEM;
4759 goto out_recovery;
4760 }
4761 laundry_wq = create_singlethread_workqueue("nfsd4"); 4949 laundry_wq = create_singlethread_workqueue("nfsd4");
4762 if (laundry_wq == NULL) { 4950 if (laundry_wq == NULL) {
4763 ret = -ENOMEM; 4951 ret = -ENOMEM;
@@ -4766,39 +4954,34 @@ nfs4_state_start(void)
4766 ret = nfsd4_create_callback_queue(); 4954 ret = nfsd4_create_callback_queue();
4767 if (ret) 4955 if (ret)
4768 goto out_free_laundry; 4956 goto out_free_laundry;
4769 queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ); 4957
4770 set_max_delegations(); 4958 set_max_delegations();
4959
4771 return 0; 4960 return 0;
4961
4772out_free_laundry: 4962out_free_laundry:
4773 destroy_workqueue(laundry_wq); 4963 destroy_workqueue(laundry_wq);
4774out_recovery: 4964out_recovery:
4775 nfsd4_client_tracking_exit(net);
4776 put_net(net);
4777 return ret; 4965 return ret;
4778} 4966}
4779 4967
4780static void 4968/* should be called with the state lock held */
4781__nfs4_state_shutdown(void) 4969void
4970nfs4_state_shutdown_net(struct net *net)
4782{ 4971{
4783 int i;
4784 struct nfs4_client *clp = NULL;
4785 struct nfs4_delegation *dp = NULL; 4972 struct nfs4_delegation *dp = NULL;
4786 struct list_head *pos, *next, reaplist; 4973 struct list_head *pos, *next, reaplist;
4974 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4975
4976 cancel_delayed_work_sync(&nn->laundromat_work);
4977 locks_end_grace(&nn->nfsd4_manager);
4787 4978
4788 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
4789 while (!list_empty(&conf_id_hashtbl[i])) {
4790 clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
4791 destroy_client(clp);
4792 }
4793 while (!list_empty(&unconf_str_hashtbl[i])) {
4794 clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
4795 destroy_client(clp);
4796 }
4797 }
4798 INIT_LIST_HEAD(&reaplist); 4979 INIT_LIST_HEAD(&reaplist);
4799 spin_lock(&recall_lock); 4980 spin_lock(&recall_lock);
4800 list_for_each_safe(pos, next, &del_recall_lru) { 4981 list_for_each_safe(pos, next, &del_recall_lru) {
4801 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 4982 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
4983 if (dp->dl_stid.sc_client->net != net)
4984 continue;
4802 list_move(&dp->dl_recall_lru, &reaplist); 4985 list_move(&dp->dl_recall_lru, &reaplist);
4803 } 4986 }
4804 spin_unlock(&recall_lock); 4987 spin_unlock(&recall_lock);
@@ -4807,22 +4990,14 @@ __nfs4_state_shutdown(void)
4807 unhash_delegation(dp); 4990 unhash_delegation(dp);
4808 } 4991 }
4809 4992
4810 nfsd4_client_tracking_exit(&init_net); 4993 nfsd4_client_tracking_exit(net);
4811 put_net(&init_net); 4994 nfs4_state_destroy_net(net);
4812} 4995}
4813 4996
4814void 4997void
4815nfs4_state_shutdown(void) 4998nfs4_state_shutdown(void)
4816{ 4999{
4817 struct net *net = &init_net;
4818 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4819
4820 cancel_delayed_work_sync(&laundromat_work);
4821 destroy_workqueue(laundry_wq); 5000 destroy_workqueue(laundry_wq);
4822 locks_end_grace(&nn->nfsd4_manager);
4823 nfs4_lock_state();
4824 __nfs4_state_shutdown();
4825 nfs4_unlock_state();
4826 nfsd4_destroy_callback_queue(); 5001 nfsd4_destroy_callback_queue();
4827} 5002}
4828 5003
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index fd548d155088..0dc11586682f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -53,6 +53,7 @@
53#include "vfs.h" 53#include "vfs.h"
54#include "state.h" 54#include "state.h"
55#include "cache.h" 55#include "cache.h"
56#include "netns.h"
56 57
57#define NFSDDBG_FACILITY NFSDDBG_XDR 58#define NFSDDBG_FACILITY NFSDDBG_XDR
58 59
@@ -65,17 +66,17 @@
65#define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL 66#define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL
66 67
67static __be32 68static __be32
68check_filename(char *str, int len, __be32 err) 69check_filename(char *str, int len)
69{ 70{
70 int i; 71 int i;
71 72
72 if (len == 0) 73 if (len == 0)
73 return nfserr_inval; 74 return nfserr_inval;
74 if (isdotent(str, len)) 75 if (isdotent(str, len))
75 return err; 76 return nfserr_badname;
76 for (i = 0; i < len; i++) 77 for (i = 0; i < len; i++)
77 if (str[i] == '/') 78 if (str[i] == '/')
78 return err; 79 return nfserr_badname;
79 return 0; 80 return 0;
80} 81}
81 82
@@ -422,6 +423,86 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
422 DECODE_TAIL; 423 DECODE_TAIL;
423} 424}
424 425
426static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
427{
428 DECODE_HEAD;
429 u32 dummy, uid, gid;
430 char *machine_name;
431 int i;
432 int nr_secflavs;
433
434 /* callback_sec_params4 */
435 READ_BUF(4);
436 READ32(nr_secflavs);
437 cbs->flavor = (u32)(-1);
438 for (i = 0; i < nr_secflavs; ++i) {
439 READ_BUF(4);
440 READ32(dummy);
441 switch (dummy) {
442 case RPC_AUTH_NULL:
443 /* Nothing to read */
444 if (cbs->flavor == (u32)(-1))
445 cbs->flavor = RPC_AUTH_NULL;
446 break;
447 case RPC_AUTH_UNIX:
448 READ_BUF(8);
449 /* stamp */
450 READ32(dummy);
451
452 /* machine name */
453 READ32(dummy);
454 READ_BUF(dummy);
455 SAVEMEM(machine_name, dummy);
456
457 /* uid, gid */
458 READ_BUF(8);
459 READ32(uid);
460 READ32(gid);
461
462 /* more gids */
463 READ_BUF(4);
464 READ32(dummy);
465 READ_BUF(dummy * 4);
466 if (cbs->flavor == (u32)(-1)) {
467 cbs->uid = uid;
468 cbs->gid = gid;
469 cbs->flavor = RPC_AUTH_UNIX;
470 }
471 break;
472 case RPC_AUTH_GSS:
473 dprintk("RPC_AUTH_GSS callback secflavor "
474 "not supported!\n");
475 READ_BUF(8);
476 /* gcbp_service */
477 READ32(dummy);
478 /* gcbp_handle_from_server */
479 READ32(dummy);
480 READ_BUF(dummy);
481 p += XDR_QUADLEN(dummy);
482 /* gcbp_handle_from_client */
483 READ_BUF(4);
484 READ32(dummy);
485 READ_BUF(dummy);
486 break;
487 default:
488 dprintk("Illegal callback secflavor\n");
489 return nfserr_inval;
490 }
491 }
492 DECODE_TAIL;
493}
494
495static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
496{
497 DECODE_HEAD;
498
499 READ_BUF(4);
500 READ32(bc->bc_cb_program);
501 nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
502
503 DECODE_TAIL;
504}
505
425static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) 506static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
426{ 507{
427 DECODE_HEAD; 508 DECODE_HEAD;
@@ -490,7 +571,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
490 READ32(create->cr_namelen); 571 READ32(create->cr_namelen);
491 READ_BUF(create->cr_namelen); 572 READ_BUF(create->cr_namelen);
492 SAVEMEM(create->cr_name, create->cr_namelen); 573 SAVEMEM(create->cr_name, create->cr_namelen);
493 if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval))) 574 if ((status = check_filename(create->cr_name, create->cr_namelen)))
494 return status; 575 return status;
495 576
496 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, 577 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
@@ -522,7 +603,7 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
522 READ32(link->li_namelen); 603 READ32(link->li_namelen);
523 READ_BUF(link->li_namelen); 604 READ_BUF(link->li_namelen);
524 SAVEMEM(link->li_name, link->li_namelen); 605 SAVEMEM(link->li_name, link->li_namelen);
525 if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval))) 606 if ((status = check_filename(link->li_name, link->li_namelen)))
526 return status; 607 return status;
527 608
528 DECODE_TAIL; 609 DECODE_TAIL;
@@ -616,7 +697,7 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
616 READ32(lookup->lo_len); 697 READ32(lookup->lo_len);
617 READ_BUF(lookup->lo_len); 698 READ_BUF(lookup->lo_len);
618 SAVEMEM(lookup->lo_name, lookup->lo_len); 699 SAVEMEM(lookup->lo_name, lookup->lo_len);
619 if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent))) 700 if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
620 return status; 701 return status;
621 702
622 DECODE_TAIL; 703 DECODE_TAIL;
@@ -780,7 +861,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
780 READ32(open->op_fname.len); 861 READ32(open->op_fname.len);
781 READ_BUF(open->op_fname.len); 862 READ_BUF(open->op_fname.len);
782 SAVEMEM(open->op_fname.data, open->op_fname.len); 863 SAVEMEM(open->op_fname.data, open->op_fname.len);
783 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 864 if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
784 return status; 865 return status;
785 break; 866 break;
786 case NFS4_OPEN_CLAIM_PREVIOUS: 867 case NFS4_OPEN_CLAIM_PREVIOUS:
@@ -795,7 +876,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
795 READ32(open->op_fname.len); 876 READ32(open->op_fname.len);
796 READ_BUF(open->op_fname.len); 877 READ_BUF(open->op_fname.len);
797 SAVEMEM(open->op_fname.data, open->op_fname.len); 878 SAVEMEM(open->op_fname.data, open->op_fname.len);
798 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 879 if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
799 return status; 880 return status;
800 break; 881 break;
801 case NFS4_OPEN_CLAIM_FH: 882 case NFS4_OPEN_CLAIM_FH:
@@ -907,7 +988,7 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove
907 READ32(remove->rm_namelen); 988 READ32(remove->rm_namelen);
908 READ_BUF(remove->rm_namelen); 989 READ_BUF(remove->rm_namelen);
909 SAVEMEM(remove->rm_name, remove->rm_namelen); 990 SAVEMEM(remove->rm_name, remove->rm_namelen);
910 if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent))) 991 if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
911 return status; 992 return status;
912 993
913 DECODE_TAIL; 994 DECODE_TAIL;
@@ -925,9 +1006,9 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename
925 READ32(rename->rn_tnamelen); 1006 READ32(rename->rn_tnamelen);
926 READ_BUF(rename->rn_tnamelen); 1007 READ_BUF(rename->rn_tnamelen);
927 SAVEMEM(rename->rn_tname, rename->rn_tnamelen); 1008 SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
928 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent))) 1009 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
929 return status; 1010 return status;
930 if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval))) 1011 if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen)))
931 return status; 1012 return status;
932 1013
933 DECODE_TAIL; 1014 DECODE_TAIL;
@@ -954,8 +1035,7 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
954 READ32(secinfo->si_namelen); 1035 READ32(secinfo->si_namelen);
955 READ_BUF(secinfo->si_namelen); 1036 READ_BUF(secinfo->si_namelen);
956 SAVEMEM(secinfo->si_name, secinfo->si_namelen); 1037 SAVEMEM(secinfo->si_name, secinfo->si_namelen);
957 status = check_filename(secinfo->si_name, secinfo->si_namelen, 1038 status = check_filename(secinfo->si_name, secinfo->si_namelen);
958 nfserr_noent);
959 if (status) 1039 if (status)
960 return status; 1040 return status;
961 DECODE_TAIL; 1041 DECODE_TAIL;
@@ -1026,31 +1106,14 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
1026static __be32 1106static __be32
1027nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) 1107nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
1028{ 1108{
1029#if 0
1030 struct nfsd4_compoundargs save = {
1031 .p = argp->p,
1032 .end = argp->end,
1033 .rqstp = argp->rqstp,
1034 };
1035 u32 ve_bmval[2];
1036 struct iattr ve_iattr; /* request */
1037 struct nfs4_acl *ve_acl; /* request */
1038#endif
1039 DECODE_HEAD; 1109 DECODE_HEAD;
1040 1110
1041 if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval))) 1111 if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
1042 goto out; 1112 goto out;
1043 1113
1044 /* For convenience's sake, we compare raw xdr'd attributes in 1114 /* For convenience's sake, we compare raw xdr'd attributes in
1045 * nfsd4_proc_verify; however we still decode here just to return 1115 * nfsd4_proc_verify */
1046 * correct error in case of bad xdr. */ 1116
1047#if 0
1048 status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl);
1049 if (status == nfserr_inval) {
1050 status = nfserrno(status);
1051 goto out;
1052 }
1053#endif
1054 READ_BUF(4); 1117 READ_BUF(4);
1055 READ32(verify->ve_attrlen); 1118 READ32(verify->ve_attrlen);
1056 READ_BUF(verify->ve_attrlen); 1119 READ_BUF(verify->ve_attrlen);
@@ -1063,7 +1126,6 @@ static __be32
1063nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) 1126nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1064{ 1127{
1065 int avail; 1128 int avail;
1066 int v;
1067 int len; 1129 int len;
1068 DECODE_HEAD; 1130 DECODE_HEAD;
1069 1131
@@ -1087,27 +1149,26 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1087 __FILE__, __LINE__); 1149 __FILE__, __LINE__);
1088 goto xdr_error; 1150 goto xdr_error;
1089 } 1151 }
1090 argp->rqstp->rq_vec[0].iov_base = p; 1152 write->wr_head.iov_base = p;
1091 argp->rqstp->rq_vec[0].iov_len = avail; 1153 write->wr_head.iov_len = avail;
1092 v = 0; 1154 WARN_ON(avail != (XDR_QUADLEN(avail) << 2));
1093 len = write->wr_buflen; 1155 write->wr_pagelist = argp->pagelist;
1094 while (len > argp->rqstp->rq_vec[v].iov_len) { 1156
1095 len -= argp->rqstp->rq_vec[v].iov_len; 1157 len = XDR_QUADLEN(write->wr_buflen) << 2;
1096 v++; 1158 if (len >= avail) {
1097 argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]); 1159 int pages;
1098 argp->pagelist++; 1160
1099 if (argp->pagelen >= PAGE_SIZE) { 1161 len -= avail;
1100 argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE; 1162
1101 argp->pagelen -= PAGE_SIZE; 1163 pages = len >> PAGE_SHIFT;
1102 } else { 1164 argp->pagelist += pages;
1103 argp->rqstp->rq_vec[v].iov_len = argp->pagelen; 1165 argp->pagelen -= pages * PAGE_SIZE;
1104 argp->pagelen -= len; 1166 len -= pages * PAGE_SIZE;
1105 } 1167
1168 argp->p = (__be32 *)page_address(argp->pagelist[0]);
1169 argp->end = argp->p + XDR_QUADLEN(PAGE_SIZE);
1106 } 1170 }
1107 argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); 1171 argp->p += XDR_QUADLEN(len);
1108 argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
1109 argp->rqstp->rq_vec[v].iov_len = len;
1110 write->wr_vlen = v+1;
1111 1172
1112 DECODE_TAIL; 1173 DECODE_TAIL;
1113} 1174}
@@ -1237,11 +1298,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1237 struct nfsd4_create_session *sess) 1298 struct nfsd4_create_session *sess)
1238{ 1299{
1239 DECODE_HEAD; 1300 DECODE_HEAD;
1240
1241 u32 dummy; 1301 u32 dummy;
1242 char *machine_name;
1243 int i;
1244 int nr_secflavs;
1245 1302
1246 READ_BUF(16); 1303 READ_BUF(16);
1247 COPYMEM(&sess->clientid, 8); 1304 COPYMEM(&sess->clientid, 8);
@@ -1282,58 +1339,9 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1282 goto xdr_error; 1339 goto xdr_error;
1283 } 1340 }
1284 1341
1285 READ_BUF(8); 1342 READ_BUF(4);
1286 READ32(sess->callback_prog); 1343 READ32(sess->callback_prog);
1287 1344 nfsd4_decode_cb_sec(argp, &sess->cb_sec);
1288 /* callback_sec_params4 */
1289 READ32(nr_secflavs);
1290 for (i = 0; i < nr_secflavs; ++i) {
1291 READ_BUF(4);
1292 READ32(dummy);
1293 switch (dummy) {
1294 case RPC_AUTH_NULL:
1295 /* Nothing to read */
1296 break;
1297 case RPC_AUTH_UNIX:
1298 READ_BUF(8);
1299 /* stamp */
1300 READ32(dummy);
1301
1302 /* machine name */
1303 READ32(dummy);
1304 READ_BUF(dummy);
1305 SAVEMEM(machine_name, dummy);
1306
1307 /* uid, gid */
1308 READ_BUF(8);
1309 READ32(sess->uid);
1310 READ32(sess->gid);
1311
1312 /* more gids */
1313 READ_BUF(4);
1314 READ32(dummy);
1315 READ_BUF(dummy * 4);
1316 break;
1317 case RPC_AUTH_GSS:
1318 dprintk("RPC_AUTH_GSS callback secflavor "
1319 "not supported!\n");
1320 READ_BUF(8);
1321 /* gcbp_service */
1322 READ32(dummy);
1323 /* gcbp_handle_from_server */
1324 READ32(dummy);
1325 READ_BUF(dummy);
1326 p += XDR_QUADLEN(dummy);
1327 /* gcbp_handle_from_client */
1328 READ_BUF(4);
1329 READ32(dummy);
1330 READ_BUF(dummy);
1331 break;
1332 default:
1333 dprintk("Illegal callback secflavor\n");
1334 return nfserr_inval;
1335 }
1336 }
1337 DECODE_TAIL; 1345 DECODE_TAIL;
1338} 1346}
1339 1347
@@ -1528,7 +1536,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1528 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp, 1536 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,
1529 1537
1530 /* new operations for NFSv4.1 */ 1538 /* new operations for NFSv4.1 */
1531 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, 1539 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
1532 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, 1540 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1533 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, 1541 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
1534 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, 1542 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
@@ -1568,12 +1576,6 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1568 bool cachethis = false; 1576 bool cachethis = false;
1569 int i; 1577 int i;
1570 1578
1571 /*
1572 * XXX: According to spec, we should check the tag
1573 * for UTF-8 compliance. I'm postponing this for
1574 * now because it seems that some clients do use
1575 * binary tags.
1576 */
1577 READ_BUF(4); 1579 READ_BUF(4);
1578 READ32(argp->taglen); 1580 READ32(argp->taglen);
1579 READ_BUF(argp->taglen + 8); 1581 READ_BUF(argp->taglen + 8);
@@ -1603,38 +1605,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1603 op = &argp->ops[i]; 1605 op = &argp->ops[i];
1604 op->replay = NULL; 1606 op->replay = NULL;
1605 1607
1606 /* 1608 READ_BUF(4);
1607 * We can't use READ_BUF() here because we need to handle 1609 READ32(op->opnum);
1608 * a missing opcode as an OP_WRITE + 1. So we need to check
1609 * to see if we're truly at the end of our buffer or if there
1610 * is another page we need to flip to.
1611 */
1612
1613 if (argp->p == argp->end) {
1614 if (argp->pagelen < 4) {
1615 /* There isn't an opcode still on the wire */
1616 op->opnum = OP_WRITE + 1;
1617 op->status = nfserr_bad_xdr;
1618 argp->opcnt = i+1;
1619 break;
1620 }
1621
1622 /*
1623 * False alarm. We just hit a page boundary, but there
1624 * is still data available. Move pointer across page
1625 * boundary. *snip from READ_BUF*
1626 */
1627 argp->p = page_address(argp->pagelist[0]);
1628 argp->pagelist++;
1629 if (argp->pagelen < PAGE_SIZE) {
1630 argp->end = argp->p + (argp->pagelen>>2);
1631 argp->pagelen = 0;
1632 } else {
1633 argp->end = argp->p + (PAGE_SIZE>>2);
1634 argp->pagelen -= PAGE_SIZE;
1635 }
1636 }
1637 op->opnum = ntohl(*argp->p++);
1638 1610
1639 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP) 1611 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1640 op->status = ops->decoders[op->opnum](argp, &op->u); 1612 op->status = ops->decoders[op->opnum](argp, &op->u);
@@ -2014,6 +1986,22 @@ static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
2014 return 0; 1986 return 0;
2015} 1987}
2016 1988
1989
1990static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
1991{
1992 struct path path = exp->ex_path;
1993 int err;
1994
1995 path_get(&path);
1996 while (follow_up(&path)) {
1997 if (path.dentry != path.mnt->mnt_root)
1998 break;
1999 }
2000 err = vfs_getattr(path.mnt, path.dentry, stat);
2001 path_put(&path);
2002 return err;
2003}
2004
2017/* 2005/*
2018 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle 2006 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2019 * ourselves. 2007 * ourselves.
@@ -2048,6 +2036,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2048 .mnt = exp->ex_path.mnt, 2036 .mnt = exp->ex_path.mnt,
2049 .dentry = dentry, 2037 .dentry = dentry,
2050 }; 2038 };
2039 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2051 2040
2052 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); 2041 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2053 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); 2042 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
@@ -2208,7 +2197,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2208 if (bmval0 & FATTR4_WORD0_LEASE_TIME) { 2197 if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2209 if ((buflen -= 4) < 0) 2198 if ((buflen -= 4) < 0)
2210 goto out_resource; 2199 goto out_resource;
2211 WRITE32(nfsd4_lease); 2200 WRITE32(nn->nfsd4_lease);
2212 } 2201 }
2213 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { 2202 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2214 if ((buflen -= 4) < 0) 2203 if ((buflen -= 4) < 0)
@@ -2430,18 +2419,8 @@ out_acl:
2430 * and this is the root of a cross-mounted filesystem. 2419 * and this is the root of a cross-mounted filesystem.
2431 */ 2420 */
2432 if (ignore_crossmnt == 0 && 2421 if (ignore_crossmnt == 0 &&
2433 dentry == exp->ex_path.mnt->mnt_root) { 2422 dentry == exp->ex_path.mnt->mnt_root)
2434 struct path path = exp->ex_path; 2423 get_parent_attributes(exp, &stat);
2435 path_get(&path);
2436 while (follow_up(&path)) {
2437 if (path.dentry != path.mnt->mnt_root)
2438 break;
2439 }
2440 err = vfs_getattr(path.mnt, path.dentry, &stat);
2441 path_put(&path);
2442 if (err)
2443 goto out_nfserr;
2444 }
2445 WRITE64(stat.ino); 2424 WRITE64(stat.ino);
2446 } 2425 }
2447 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { 2426 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
@@ -2927,7 +2906,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2927 struct nfsd4_read *read) 2906 struct nfsd4_read *read)
2928{ 2907{
2929 u32 eof; 2908 u32 eof;
2930 int v, pn; 2909 int v;
2910 struct page *page;
2931 unsigned long maxcount; 2911 unsigned long maxcount;
2932 long len; 2912 long len;
2933 __be32 *p; 2913 __be32 *p;
@@ -2946,11 +2926,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2946 len = maxcount; 2926 len = maxcount;
2947 v = 0; 2927 v = 0;
2948 while (len > 0) { 2928 while (len > 0) {
2949 pn = resp->rqstp->rq_resused++; 2929 page = *(resp->rqstp->rq_next_page);
2950 resp->rqstp->rq_vec[v].iov_base = 2930 if (!page) { /* ran out of pages */
2951 page_address(resp->rqstp->rq_respages[pn]); 2931 maxcount -= len;
2932 break;
2933 }
2934 resp->rqstp->rq_vec[v].iov_base = page_address(page);
2952 resp->rqstp->rq_vec[v].iov_len = 2935 resp->rqstp->rq_vec[v].iov_len =
2953 len < PAGE_SIZE ? len : PAGE_SIZE; 2936 len < PAGE_SIZE ? len : PAGE_SIZE;
2937 resp->rqstp->rq_next_page++;
2954 v++; 2938 v++;
2955 len -= PAGE_SIZE; 2939 len -= PAGE_SIZE;
2956 } 2940 }
@@ -2996,8 +2980,10 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
2996 return nfserr; 2980 return nfserr;
2997 if (resp->xbuf->page_len) 2981 if (resp->xbuf->page_len)
2998 return nfserr_resource; 2982 return nfserr_resource;
2983 if (!*resp->rqstp->rq_next_page)
2984 return nfserr_resource;
2999 2985
3000 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 2986 page = page_address(*(resp->rqstp->rq_next_page++));
3001 2987
3002 maxcount = PAGE_SIZE; 2988 maxcount = PAGE_SIZE;
3003 RESERVE_SPACE(4); 2989 RESERVE_SPACE(4);
@@ -3045,6 +3031,8 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3045 return nfserr; 3031 return nfserr;
3046 if (resp->xbuf->page_len) 3032 if (resp->xbuf->page_len)
3047 return nfserr_resource; 3033 return nfserr_resource;
3034 if (!*resp->rqstp->rq_next_page)
3035 return nfserr_resource;
3048 3036
3049 RESERVE_SPACE(NFS4_VERIFIER_SIZE); 3037 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
3050 savep = p; 3038 savep = p;
@@ -3071,7 +3059,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3071 goto err_no_verf; 3059 goto err_no_verf;
3072 } 3060 }
3073 3061
3074 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 3062 page = page_address(*(resp->rqstp->rq_next_page++));
3075 readdir->common.err = 0; 3063 readdir->common.err = 0;
3076 readdir->buflen = maxcount; 3064 readdir->buflen = maxcount;
3077 readdir->buffer = page; 3065 readdir->buffer = page;
@@ -3094,8 +3082,8 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3094 p = readdir->buffer; 3082 p = readdir->buffer;
3095 *p++ = 0; /* no more entries */ 3083 *p++ = 0; /* no more entries */
3096 *p++ = htonl(readdir->common.err == nfserr_eof); 3084 *p++ = htonl(readdir->common.err == nfserr_eof);
3097 resp->xbuf->page_len = ((char*)p) - (char*)page_address( 3085 resp->xbuf->page_len = ((char*)p) -
3098 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); 3086 (char*)page_address(*(resp->rqstp->rq_next_page-1));
3099 3087
3100 /* Use rest of head for padding and remaining ops: */ 3088 /* Use rest of head for padding and remaining ops: */
3101 resp->xbuf->tail[0].iov_base = tailbase; 3089 resp->xbuf->tail[0].iov_base = tailbase;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index dab350dfc376..74934284d9a7 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -19,7 +19,7 @@
19#include "idmap.h" 19#include "idmap.h"
20#include "nfsd.h" 20#include "nfsd.h"
21#include "cache.h" 21#include "cache.h"
22#include "fault_inject.h" 22#include "state.h"
23#include "netns.h" 23#include "netns.h"
24 24
25/* 25/*
@@ -186,9 +186,6 @@ static struct file_operations supported_enctypes_ops = {
186}; 186};
187#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ 187#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
188 188
189extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
190extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
191
192static const struct file_operations pool_stats_operations = { 189static const struct file_operations pool_stats_operations = {
193 .open = nfsd_pool_stats_open, 190 .open = nfsd_pool_stats_open,
194 .read = seq_read, 191 .read = seq_read,
@@ -399,6 +396,8 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
399{ 396{
400 char *mesg = buf; 397 char *mesg = buf;
401 int rv; 398 int rv;
399 struct net *net = &init_net;
400
402 if (size > 0) { 401 if (size > 0) {
403 int newthreads; 402 int newthreads;
404 rv = get_int(&mesg, &newthreads); 403 rv = get_int(&mesg, &newthreads);
@@ -406,11 +405,11 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
406 return rv; 405 return rv;
407 if (newthreads < 0) 406 if (newthreads < 0)
408 return -EINVAL; 407 return -EINVAL;
409 rv = nfsd_svc(newthreads); 408 rv = nfsd_svc(newthreads, net);
410 if (rv < 0) 409 if (rv < 0)
411 return rv; 410 return rv;
412 } else 411 } else
413 rv = nfsd_nrthreads(); 412 rv = nfsd_nrthreads(net);
414 413
415 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv); 414 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
416} 415}
@@ -448,9 +447,10 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
448 int len; 447 int len;
449 int npools; 448 int npools;
450 int *nthreads; 449 int *nthreads;
450 struct net *net = &init_net;
451 451
452 mutex_lock(&nfsd_mutex); 452 mutex_lock(&nfsd_mutex);
453 npools = nfsd_nrpools(); 453 npools = nfsd_nrpools(net);
454 if (npools == 0) { 454 if (npools == 0) {
455 /* 455 /*
456 * NFS is shut down. The admin can start it by 456 * NFS is shut down. The admin can start it by
@@ -478,12 +478,12 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
478 if (nthreads[i] < 0) 478 if (nthreads[i] < 0)
479 goto out_free; 479 goto out_free;
480 } 480 }
481 rv = nfsd_set_nrthreads(i, nthreads); 481 rv = nfsd_set_nrthreads(i, nthreads, net);
482 if (rv) 482 if (rv)
483 goto out_free; 483 goto out_free;
484 } 484 }
485 485
486 rv = nfsd_get_nrthreads(npools, nthreads); 486 rv = nfsd_get_nrthreads(npools, nthreads, net);
487 if (rv) 487 if (rv)
488 goto out_free; 488 goto out_free;
489 489
@@ -510,11 +510,13 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
510 unsigned minor; 510 unsigned minor;
511 ssize_t tlen = 0; 511 ssize_t tlen = 0;
512 char *sep; 512 char *sep;
513 struct net *net = &init_net;
514 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
513 515
514 if (size>0) { 516 if (size>0) {
515 if (nfsd_serv) 517 if (nn->nfsd_serv)
516 /* Cannot change versions without updating 518 /* Cannot change versions without updating
517 * nfsd_serv->sv_xdrsize, and reallocing 519 * nn->nfsd_serv->sv_xdrsize, and reallocing
518 * rq_argp and rq_resp 520 * rq_argp and rq_resp
519 */ 521 */
520 return -EBUSY; 522 return -EBUSY;
@@ -645,11 +647,13 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
645 * Zero-length write. Return a list of NFSD's current listener 647 * Zero-length write. Return a list of NFSD's current listener
646 * transports. 648 * transports.
647 */ 649 */
648static ssize_t __write_ports_names(char *buf) 650static ssize_t __write_ports_names(char *buf, struct net *net)
649{ 651{
650 if (nfsd_serv == NULL) 652 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
653
654 if (nn->nfsd_serv == NULL)
651 return 0; 655 return 0;
652 return svc_xprt_names(nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT); 656 return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
653} 657}
654 658
655/* 659/*
@@ -657,28 +661,28 @@ static ssize_t __write_ports_names(char *buf)
657 * a socket of a supported family/protocol, and we use it as an 661 * a socket of a supported family/protocol, and we use it as an
658 * nfsd listener. 662 * nfsd listener.
659 */ 663 */
660static ssize_t __write_ports_addfd(char *buf) 664static ssize_t __write_ports_addfd(char *buf, struct net *net)
661{ 665{
662 char *mesg = buf; 666 char *mesg = buf;
663 int fd, err; 667 int fd, err;
664 struct net *net = &init_net; 668 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
665 669
666 err = get_int(&mesg, &fd); 670 err = get_int(&mesg, &fd);
667 if (err != 0 || fd < 0) 671 if (err != 0 || fd < 0)
668 return -EINVAL; 672 return -EINVAL;
669 673
670 err = nfsd_create_serv(); 674 err = nfsd_create_serv(net);
671 if (err != 0) 675 if (err != 0)
672 return err; 676 return err;
673 677
674 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 678 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
675 if (err < 0) { 679 if (err < 0) {
676 nfsd_destroy(net); 680 nfsd_destroy(net);
677 return err; 681 return err;
678 } 682 }
679 683
680 /* Decrease the count, but don't shut down the service */ 684 /* Decrease the count, but don't shut down the service */
681 nfsd_serv->sv_nrthreads--; 685 nn->nfsd_serv->sv_nrthreads--;
682 return err; 686 return err;
683} 687}
684 688
@@ -686,12 +690,12 @@ static ssize_t __write_ports_addfd(char *buf)
686 * A transport listener is added by writing it's transport name and 690 * A transport listener is added by writing it's transport name and
687 * a port number. 691 * a port number.
688 */ 692 */
689static ssize_t __write_ports_addxprt(char *buf) 693static ssize_t __write_ports_addxprt(char *buf, struct net *net)
690{ 694{
691 char transport[16]; 695 char transport[16];
692 struct svc_xprt *xprt; 696 struct svc_xprt *xprt;
693 int port, err; 697 int port, err;
694 struct net *net = &init_net; 698 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
695 699
696 if (sscanf(buf, "%15s %5u", transport, &port) != 2) 700 if (sscanf(buf, "%15s %5u", transport, &port) != 2)
697 return -EINVAL; 701 return -EINVAL;
@@ -699,25 +703,25 @@ static ssize_t __write_ports_addxprt(char *buf)
699 if (port < 1 || port > USHRT_MAX) 703 if (port < 1 || port > USHRT_MAX)
700 return -EINVAL; 704 return -EINVAL;
701 705
702 err = nfsd_create_serv(); 706 err = nfsd_create_serv(net);
703 if (err != 0) 707 if (err != 0)
704 return err; 708 return err;
705 709
706 err = svc_create_xprt(nfsd_serv, transport, net, 710 err = svc_create_xprt(nn->nfsd_serv, transport, net,
707 PF_INET, port, SVC_SOCK_ANONYMOUS); 711 PF_INET, port, SVC_SOCK_ANONYMOUS);
708 if (err < 0) 712 if (err < 0)
709 goto out_err; 713 goto out_err;
710 714
711 err = svc_create_xprt(nfsd_serv, transport, net, 715 err = svc_create_xprt(nn->nfsd_serv, transport, net,
712 PF_INET6, port, SVC_SOCK_ANONYMOUS); 716 PF_INET6, port, SVC_SOCK_ANONYMOUS);
713 if (err < 0 && err != -EAFNOSUPPORT) 717 if (err < 0 && err != -EAFNOSUPPORT)
714 goto out_close; 718 goto out_close;
715 719
716 /* Decrease the count, but don't shut down the service */ 720 /* Decrease the count, but don't shut down the service */
717 nfsd_serv->sv_nrthreads--; 721 nn->nfsd_serv->sv_nrthreads--;
718 return 0; 722 return 0;
719out_close: 723out_close:
720 xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port); 724 xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
721 if (xprt != NULL) { 725 if (xprt != NULL) {
722 svc_close_xprt(xprt); 726 svc_close_xprt(xprt);
723 svc_xprt_put(xprt); 727 svc_xprt_put(xprt);
@@ -727,16 +731,17 @@ out_err:
727 return err; 731 return err;
728} 732}
729 733
730static ssize_t __write_ports(struct file *file, char *buf, size_t size) 734static ssize_t __write_ports(struct file *file, char *buf, size_t size,
735 struct net *net)
731{ 736{
732 if (size == 0) 737 if (size == 0)
733 return __write_ports_names(buf); 738 return __write_ports_names(buf, net);
734 739
735 if (isdigit(buf[0])) 740 if (isdigit(buf[0]))
736 return __write_ports_addfd(buf); 741 return __write_ports_addfd(buf, net);
737 742
738 if (isalpha(buf[0])) 743 if (isalpha(buf[0]))
739 return __write_ports_addxprt(buf); 744 return __write_ports_addxprt(buf, net);
740 745
741 return -EINVAL; 746 return -EINVAL;
742} 747}
@@ -787,9 +792,10 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
787static ssize_t write_ports(struct file *file, char *buf, size_t size) 792static ssize_t write_ports(struct file *file, char *buf, size_t size)
788{ 793{
789 ssize_t rv; 794 ssize_t rv;
795 struct net *net = &init_net;
790 796
791 mutex_lock(&nfsd_mutex); 797 mutex_lock(&nfsd_mutex);
792 rv = __write_ports(file, buf, size); 798 rv = __write_ports(file, buf, size, net);
793 mutex_unlock(&nfsd_mutex); 799 mutex_unlock(&nfsd_mutex);
794 return rv; 800 return rv;
795} 801}
@@ -821,6 +827,9 @@ int nfsd_max_blksize;
821static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 827static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
822{ 828{
823 char *mesg = buf; 829 char *mesg = buf;
830 struct net *net = &init_net;
831 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
832
824 if (size > 0) { 833 if (size > 0) {
825 int bsize; 834 int bsize;
826 int rv = get_int(&mesg, &bsize); 835 int rv = get_int(&mesg, &bsize);
@@ -835,7 +844,7 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
835 bsize = NFSSVC_MAXBLKSIZE; 844 bsize = NFSSVC_MAXBLKSIZE;
836 bsize &= ~(1024-1); 845 bsize &= ~(1024-1);
837 mutex_lock(&nfsd_mutex); 846 mutex_lock(&nfsd_mutex);
838 if (nfsd_serv) { 847 if (nn->nfsd_serv) {
839 mutex_unlock(&nfsd_mutex); 848 mutex_unlock(&nfsd_mutex);
840 return -EBUSY; 849 return -EBUSY;
841 } 850 }
@@ -848,13 +857,14 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
848} 857}
849 858
850#ifdef CONFIG_NFSD_V4 859#ifdef CONFIG_NFSD_V4
851static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) 860static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
861 time_t *time, struct nfsd_net *nn)
852{ 862{
853 char *mesg = buf; 863 char *mesg = buf;
854 int rv, i; 864 int rv, i;
855 865
856 if (size > 0) { 866 if (size > 0) {
857 if (nfsd_serv) 867 if (nn->nfsd_serv)
858 return -EBUSY; 868 return -EBUSY;
859 rv = get_int(&mesg, &i); 869 rv = get_int(&mesg, &i);
860 if (rv) 870 if (rv)
@@ -879,12 +889,13 @@ static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, tim
879 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time); 889 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
880} 890}
881 891
882static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time) 892static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
893 time_t *time, struct nfsd_net *nn)
883{ 894{
884 ssize_t rv; 895 ssize_t rv;
885 896
886 mutex_lock(&nfsd_mutex); 897 mutex_lock(&nfsd_mutex);
887 rv = __nfsd4_write_time(file, buf, size, time); 898 rv = __nfsd4_write_time(file, buf, size, time, nn);
888 mutex_unlock(&nfsd_mutex); 899 mutex_unlock(&nfsd_mutex);
889 return rv; 900 return rv;
890} 901}
@@ -912,7 +923,8 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_
912 */ 923 */
913static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 924static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
914{ 925{
915 return nfsd4_write_time(file, buf, size, &nfsd4_lease); 926 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
927 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
916} 928}
917 929
918/** 930/**
@@ -927,17 +939,19 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
927 */ 939 */
928static ssize_t write_gracetime(struct file *file, char *buf, size_t size) 940static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
929{ 941{
930 return nfsd4_write_time(file, buf, size, &nfsd4_grace); 942 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
943 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
931} 944}
932 945
933static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size) 946static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
947 struct nfsd_net *nn)
934{ 948{
935 char *mesg = buf; 949 char *mesg = buf;
936 char *recdir; 950 char *recdir;
937 int len, status; 951 int len, status;
938 952
939 if (size > 0) { 953 if (size > 0) {
940 if (nfsd_serv) 954 if (nn->nfsd_serv)
941 return -EBUSY; 955 return -EBUSY;
942 if (size > PATH_MAX || buf[size-1] != '\n') 956 if (size > PATH_MAX || buf[size-1] != '\n')
943 return -EINVAL; 957 return -EINVAL;
@@ -981,9 +995,10 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size)
981static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 995static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
982{ 996{
983 ssize_t rv; 997 ssize_t rv;
998 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
984 999
985 mutex_lock(&nfsd_mutex); 1000 mutex_lock(&nfsd_mutex);
986 rv = __write_recoverydir(file, buf, size); 1001 rv = __write_recoverydir(file, buf, size, nn);
987 mutex_unlock(&nfsd_mutex); 1002 mutex_unlock(&nfsd_mutex);
988 return rv; 1003 return rv;
989} 1004}
@@ -1063,6 +1078,7 @@ int nfsd_net_id;
1063static __net_init int nfsd_init_net(struct net *net) 1078static __net_init int nfsd_init_net(struct net *net)
1064{ 1079{
1065 int retval; 1080 int retval;
1081 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1066 1082
1067 retval = nfsd_export_init(net); 1083 retval = nfsd_export_init(net);
1068 if (retval) 1084 if (retval)
@@ -1070,6 +1086,8 @@ static __net_init int nfsd_init_net(struct net *net)
1070 retval = nfsd_idmap_init(net); 1086 retval = nfsd_idmap_init(net);
1071 if (retval) 1087 if (retval)
1072 goto out_idmap_error; 1088 goto out_idmap_error;
1089 nn->nfsd4_lease = 90; /* default lease time */
1090 nn->nfsd4_grace = 90;
1073 return 0; 1091 return 0;
1074 1092
1075out_idmap_error: 1093out_idmap_error:
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 80d5ce40aadb..de23db255c69 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -55,7 +55,6 @@ extern struct svc_version nfsd_version2, nfsd_version3,
55 nfsd_version4; 55 nfsd_version4;
56extern u32 nfsd_supported_minorversion; 56extern u32 nfsd_supported_minorversion;
57extern struct mutex nfsd_mutex; 57extern struct mutex nfsd_mutex;
58extern struct svc_serv *nfsd_serv;
59extern spinlock_t nfsd_drc_lock; 58extern spinlock_t nfsd_drc_lock;
60extern unsigned int nfsd_drc_max_mem; 59extern unsigned int nfsd_drc_max_mem;
61extern unsigned int nfsd_drc_mem_used; 60extern unsigned int nfsd_drc_mem_used;
@@ -65,26 +64,17 @@ extern const struct seq_operations nfs_exports_op;
65/* 64/*
66 * Function prototypes. 65 * Function prototypes.
67 */ 66 */
68int nfsd_svc(int nrservs); 67int nfsd_svc(int nrservs, struct net *net);
69int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); 68int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
70 69
71int nfsd_nrthreads(void); 70int nfsd_nrthreads(struct net *);
72int nfsd_nrpools(void); 71int nfsd_nrpools(struct net *);
73int nfsd_get_nrthreads(int n, int *); 72int nfsd_get_nrthreads(int n, int *, struct net *);
74int nfsd_set_nrthreads(int n, int *); 73int nfsd_set_nrthreads(int n, int *, struct net *);
75int nfsd_pool_stats_open(struct inode *, struct file *); 74int nfsd_pool_stats_open(struct inode *, struct file *);
76int nfsd_pool_stats_release(struct inode *, struct file *); 75int nfsd_pool_stats_release(struct inode *, struct file *);
77 76
78static inline void nfsd_destroy(struct net *net) 77void nfsd_destroy(struct net *net);
79{
80 int destroy = (nfsd_serv->sv_nrthreads == 1);
81
82 if (destroy)
83 svc_shutdown_net(nfsd_serv, net);
84 svc_destroy(nfsd_serv);
85 if (destroy)
86 nfsd_serv = NULL;
87}
88 78
89#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 79#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
90#ifdef CONFIG_NFSD_V2_ACL 80#ifdef CONFIG_NFSD_V2_ACL
@@ -103,7 +93,7 @@ enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
103int nfsd_vers(int vers, enum vers_op change); 93int nfsd_vers(int vers, enum vers_op change);
104int nfsd_minorversion(u32 minorversion, enum vers_op change); 94int nfsd_minorversion(u32 minorversion, enum vers_op change);
105void nfsd_reset_versions(void); 95void nfsd_reset_versions(void);
106int nfsd_create_serv(void); 96int nfsd_create_serv(struct net *net);
107 97
108extern int nfsd_max_blksize; 98extern int nfsd_max_blksize;
109 99
@@ -121,7 +111,9 @@ void nfs4_state_init(void);
121int nfsd4_init_slabs(void); 111int nfsd4_init_slabs(void);
122void nfsd4_free_slabs(void); 112void nfsd4_free_slabs(void);
123int nfs4_state_start(void); 113int nfs4_state_start(void);
114int nfs4_state_start_net(struct net *net);
124void nfs4_state_shutdown(void); 115void nfs4_state_shutdown(void);
116void nfs4_state_shutdown_net(struct net *net);
125void nfs4_reset_lease(time_t leasetime); 117void nfs4_reset_lease(time_t leasetime);
126int nfs4_reset_recoverydir(char *recdir); 118int nfs4_reset_recoverydir(char *recdir);
127char * nfs4_recoverydir(void); 119char * nfs4_recoverydir(void);
@@ -130,7 +122,9 @@ static inline void nfs4_state_init(void) { }
130static inline int nfsd4_init_slabs(void) { return 0; } 122static inline int nfsd4_init_slabs(void) { return 0; }
131static inline void nfsd4_free_slabs(void) { } 123static inline void nfsd4_free_slabs(void) { }
132static inline int nfs4_state_start(void) { return 0; } 124static inline int nfs4_state_start(void) { return 0; }
125static inline int nfs4_state_start_net(struct net *net) { return 0; }
133static inline void nfs4_state_shutdown(void) { } 126static inline void nfs4_state_shutdown(void) { }
127static inline void nfs4_state_shutdown_net(struct net *net) { }
134static inline void nfs4_reset_lease(time_t leasetime) { } 128static inline void nfs4_reset_lease(time_t leasetime) { }
135static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } 129static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
136static inline char * nfs4_recoverydir(void) {return NULL; } 130static inline char * nfs4_recoverydir(void) {return NULL; }
@@ -265,16 +259,8 @@ void nfsd_lockd_shutdown(void);
265/* Check for dir entries '.' and '..' */ 259/* Check for dir entries '.' and '..' */
266#define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.')) 260#define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.'))
267 261
268/*
269 * Time of server startup
270 */
271extern struct timeval nfssvc_boot;
272
273#ifdef CONFIG_NFSD_V4 262#ifdef CONFIG_NFSD_V4
274 263
275extern time_t nfsd4_lease;
276extern time_t nfsd4_grace;
277
278/* before processing a COMPOUND operation, we have to check that there 264/* before processing a COMPOUND operation, we have to check that there
279 * is enough space in the buffer for XDR encode to succeed. otherwise, 265 * is enough space in the buffer for XDR encode to succeed. otherwise,
280 * we might process an operation with side effects, and be unable to 266 * we might process an operation with side effects, and be unable to
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 032af381b3aa..814afaa4458a 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -572,7 +572,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
572 572
573 if (inode) 573 if (inode)
574 _fh_update(fhp, exp, dentry); 574 _fh_update(fhp, exp, dentry);
575 if (fhp->fh_handle.fh_fileid_type == 255) { 575 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
576 fh_put(fhp); 576 fh_put(fhp);
577 return nfserr_opnotsupp; 577 return nfserr_opnotsupp;
578 } 578 }
@@ -603,7 +603,7 @@ fh_update(struct svc_fh *fhp)
603 goto out; 603 goto out;
604 604
605 _fh_update(fhp, fhp->fh_export, dentry); 605 _fh_update(fhp, fhp->fh_export, dentry);
606 if (fhp->fh_handle.fh_fileid_type == 255) 606 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
607 return nfserr_opnotsupp; 607 return nfserr_opnotsupp;
608 } 608 }
609out: 609out:
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 2013aa001dab..cee62ab9d4a3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -11,7 +11,6 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/fs_struct.h> 12#include <linux/fs_struct.h>
13#include <linux/swap.h> 13#include <linux/swap.h>
14#include <linux/nsproxy.h>
15 14
16#include <linux/sunrpc/stats.h> 15#include <linux/sunrpc/stats.h>
17#include <linux/sunrpc/svcsock.h> 16#include <linux/sunrpc/svcsock.h>
@@ -22,19 +21,19 @@
22#include "nfsd.h" 21#include "nfsd.h"
23#include "cache.h" 22#include "cache.h"
24#include "vfs.h" 23#include "vfs.h"
24#include "netns.h"
25 25
26#define NFSDDBG_FACILITY NFSDDBG_SVC 26#define NFSDDBG_FACILITY NFSDDBG_SVC
27 27
28extern struct svc_program nfsd_program; 28extern struct svc_program nfsd_program;
29static int nfsd(void *vrqstp); 29static int nfsd(void *vrqstp);
30struct timeval nfssvc_boot;
31 30
32/* 31/*
33 * nfsd_mutex protects nfsd_serv -- both the pointer itself and the members 32 * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and the members
34 * of the svc_serv struct. In particular, ->sv_nrthreads but also to some 33 * of the svc_serv struct. In particular, ->sv_nrthreads but also to some
35 * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt 34 * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt
36 * 35 *
37 * If (out side the lock) nfsd_serv is non-NULL, then it must point to a 36 * If (out side the lock) nn->nfsd_serv is non-NULL, then it must point to a
38 * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number 37 * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number
39 * of nfsd threads must exist and each must listed in ->sp_all_threads in each 38 * of nfsd threads must exist and each must listed in ->sp_all_threads in each
40 * entry of ->sv_pools[]. 39 * entry of ->sv_pools[].
@@ -52,7 +51,6 @@ struct timeval nfssvc_boot;
52 * nfsd_versions 51 * nfsd_versions
53 */ 52 */
54DEFINE_MUTEX(nfsd_mutex); 53DEFINE_MUTEX(nfsd_mutex);
55struct svc_serv *nfsd_serv;
56 54
57/* 55/*
58 * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used. 56 * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used.
@@ -173,28 +171,32 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change)
173 */ 171 */
174#define NFSD_MAXSERVS 8192 172#define NFSD_MAXSERVS 8192
175 173
176int nfsd_nrthreads(void) 174int nfsd_nrthreads(struct net *net)
177{ 175{
178 int rv = 0; 176 int rv = 0;
177 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
178
179 mutex_lock(&nfsd_mutex); 179 mutex_lock(&nfsd_mutex);
180 if (nfsd_serv) 180 if (nn->nfsd_serv)
181 rv = nfsd_serv->sv_nrthreads; 181 rv = nn->nfsd_serv->sv_nrthreads;
182 mutex_unlock(&nfsd_mutex); 182 mutex_unlock(&nfsd_mutex);
183 return rv; 183 return rv;
184} 184}
185 185
186static int nfsd_init_socks(void) 186static int nfsd_init_socks(struct net *net)
187{ 187{
188 int error; 188 int error;
189 if (!list_empty(&nfsd_serv->sv_permsocks)) 189 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
190
191 if (!list_empty(&nn->nfsd_serv->sv_permsocks))
190 return 0; 192 return 0;
191 193
192 error = svc_create_xprt(nfsd_serv, "udp", &init_net, PF_INET, NFS_PORT, 194 error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT,
193 SVC_SOCK_DEFAULTS); 195 SVC_SOCK_DEFAULTS);
194 if (error < 0) 196 if (error < 0)
195 return error; 197 return error;
196 198
197 error = svc_create_xprt(nfsd_serv, "tcp", &init_net, PF_INET, NFS_PORT, 199 error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT,
198 SVC_SOCK_DEFAULTS); 200 SVC_SOCK_DEFAULTS);
199 if (error < 0) 201 if (error < 0)
200 return error; 202 return error;
@@ -202,14 +204,15 @@ static int nfsd_init_socks(void)
202 return 0; 204 return 0;
203} 205}
204 206
205static bool nfsd_up = false; 207static int nfsd_users = 0;
206 208
207static int nfsd_startup(int nrservs) 209static int nfsd_startup_generic(int nrservs)
208{ 210{
209 int ret; 211 int ret;
210 212
211 if (nfsd_up) 213 if (nfsd_users++)
212 return 0; 214 return 0;
215
213 /* 216 /*
214 * Readahead param cache - will no-op if it already exists. 217 * Readahead param cache - will no-op if it already exists.
215 * (Note therefore results will be suboptimal if number of 218 * (Note therefore results will be suboptimal if number of
@@ -218,43 +221,79 @@ static int nfsd_startup(int nrservs)
218 ret = nfsd_racache_init(2*nrservs); 221 ret = nfsd_racache_init(2*nrservs);
219 if (ret) 222 if (ret)
220 return ret; 223 return ret;
221 ret = nfsd_init_socks(); 224 ret = nfs4_state_start();
222 if (ret) 225 if (ret)
223 goto out_racache; 226 goto out_racache;
224 ret = lockd_up(&init_net); 227 return 0;
228
229out_racache:
230 nfsd_racache_shutdown();
231 return ret;
232}
233
234static void nfsd_shutdown_generic(void)
235{
236 if (--nfsd_users)
237 return;
238
239 nfs4_state_shutdown();
240 nfsd_racache_shutdown();
241}
242
243static int nfsd_startup_net(int nrservs, struct net *net)
244{
245 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
246 int ret;
247
248 if (nn->nfsd_net_up)
249 return 0;
250
251 ret = nfsd_startup_generic(nrservs);
225 if (ret) 252 if (ret)
226 goto out_racache; 253 return ret;
227 ret = nfs4_state_start(); 254 ret = nfsd_init_socks(net);
255 if (ret)
256 goto out_socks;
257 ret = lockd_up(net);
258 if (ret)
259 goto out_socks;
260 ret = nfs4_state_start_net(net);
228 if (ret) 261 if (ret)
229 goto out_lockd; 262 goto out_lockd;
230 nfsd_up = true; 263
264 nn->nfsd_net_up = true;
231 return 0; 265 return 0;
266
232out_lockd: 267out_lockd:
233 lockd_down(&init_net); 268 lockd_down(net);
234out_racache: 269out_socks:
235 nfsd_racache_shutdown(); 270 nfsd_shutdown_generic();
236 return ret; 271 return ret;
237} 272}
238 273
239static void nfsd_shutdown(void) 274static void nfsd_shutdown_net(struct net *net)
240{ 275{
276 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
277
278 nfs4_state_shutdown_net(net);
279 lockd_down(net);
280 nn->nfsd_net_up = false;
281 nfsd_shutdown_generic();
282}
283
284static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
285{
286 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
287
241 /* 288 /*
242 * write_ports can create the server without actually starting 289 * write_ports can create the server without actually starting
243 * any threads--if we get shut down before any threads are 290 * any threads--if we get shut down before any threads are
244 * started, then nfsd_last_thread will be run before any of this 291 * started, then nfsd_last_thread will be run before any of this
245 * other initialization has been done. 292 * other initialization has been done.
246 */ 293 */
247 if (!nfsd_up) 294 if (!nn->nfsd_net_up)
248 return; 295 return;
249 nfs4_state_shutdown(); 296 nfsd_shutdown_net(net);
250 lockd_down(&init_net);
251 nfsd_racache_shutdown();
252 nfsd_up = false;
253}
254
255static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
256{
257 nfsd_shutdown();
258 297
259 svc_rpcb_cleanup(serv, net); 298 svc_rpcb_cleanup(serv, net);
260 299
@@ -327,69 +366,84 @@ static int nfsd_get_default_max_blksize(void)
327 return ret; 366 return ret;
328} 367}
329 368
330int nfsd_create_serv(void) 369int nfsd_create_serv(struct net *net)
331{ 370{
332 int error; 371 int error;
333 struct net *net = current->nsproxy->net_ns; 372 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
334 373
335 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 374 WARN_ON(!mutex_is_locked(&nfsd_mutex));
336 if (nfsd_serv) { 375 if (nn->nfsd_serv) {
337 svc_get(nfsd_serv); 376 svc_get(nn->nfsd_serv);
338 return 0; 377 return 0;
339 } 378 }
340 if (nfsd_max_blksize == 0) 379 if (nfsd_max_blksize == 0)
341 nfsd_max_blksize = nfsd_get_default_max_blksize(); 380 nfsd_max_blksize = nfsd_get_default_max_blksize();
342 nfsd_reset_versions(); 381 nfsd_reset_versions();
343 nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, 382 nn->nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
344 nfsd_last_thread, nfsd, THIS_MODULE); 383 nfsd_last_thread, nfsd, THIS_MODULE);
345 if (nfsd_serv == NULL) 384 if (nn->nfsd_serv == NULL)
346 return -ENOMEM; 385 return -ENOMEM;
347 386
348 error = svc_bind(nfsd_serv, net); 387 error = svc_bind(nn->nfsd_serv, net);
349 if (error < 0) { 388 if (error < 0) {
350 svc_destroy(nfsd_serv); 389 svc_destroy(nn->nfsd_serv);
351 return error; 390 return error;
352 } 391 }
353 392
354 set_max_drc(); 393 set_max_drc();
355 do_gettimeofday(&nfssvc_boot); /* record boot time */ 394 do_gettimeofday(&nn->nfssvc_boot); /* record boot time */
356 return 0; 395 return 0;
357} 396}
358 397
359int nfsd_nrpools(void) 398int nfsd_nrpools(struct net *net)
360{ 399{
361 if (nfsd_serv == NULL) 400 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
401
402 if (nn->nfsd_serv == NULL)
362 return 0; 403 return 0;
363 else 404 else
364 return nfsd_serv->sv_nrpools; 405 return nn->nfsd_serv->sv_nrpools;
365} 406}
366 407
367int nfsd_get_nrthreads(int n, int *nthreads) 408int nfsd_get_nrthreads(int n, int *nthreads, struct net *net)
368{ 409{
369 int i = 0; 410 int i = 0;
411 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
370 412
371 if (nfsd_serv != NULL) { 413 if (nn->nfsd_serv != NULL) {
372 for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++) 414 for (i = 0; i < nn->nfsd_serv->sv_nrpools && i < n; i++)
373 nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads; 415 nthreads[i] = nn->nfsd_serv->sv_pools[i].sp_nrthreads;
374 } 416 }
375 417
376 return 0; 418 return 0;
377} 419}
378 420
379int nfsd_set_nrthreads(int n, int *nthreads) 421void nfsd_destroy(struct net *net)
422{
423 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
424 int destroy = (nn->nfsd_serv->sv_nrthreads == 1);
425
426 if (destroy)
427 svc_shutdown_net(nn->nfsd_serv, net);
428 svc_destroy(nn->nfsd_serv);
429 if (destroy)
430 nn->nfsd_serv = NULL;
431}
432
433int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
380{ 434{
381 int i = 0; 435 int i = 0;
382 int tot = 0; 436 int tot = 0;
383 int err = 0; 437 int err = 0;
384 struct net *net = &init_net; 438 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
385 439
386 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 440 WARN_ON(!mutex_is_locked(&nfsd_mutex));
387 441
388 if (nfsd_serv == NULL || n <= 0) 442 if (nn->nfsd_serv == NULL || n <= 0)
389 return 0; 443 return 0;
390 444
391 if (n > nfsd_serv->sv_nrpools) 445 if (n > nn->nfsd_serv->sv_nrpools)
392 n = nfsd_serv->sv_nrpools; 446 n = nn->nfsd_serv->sv_nrpools;
393 447
394 /* enforce a global maximum number of threads */ 448 /* enforce a global maximum number of threads */
395 tot = 0; 449 tot = 0;
@@ -419,9 +473,9 @@ int nfsd_set_nrthreads(int n, int *nthreads)
419 nthreads[0] = 1; 473 nthreads[0] = 1;
420 474
421 /* apply the new numbers */ 475 /* apply the new numbers */
422 svc_get(nfsd_serv); 476 svc_get(nn->nfsd_serv);
423 for (i = 0; i < n; i++) { 477 for (i = 0; i < n; i++) {
424 err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i], 478 err = svc_set_num_threads(nn->nfsd_serv, &nn->nfsd_serv->sv_pools[i],
425 nthreads[i]); 479 nthreads[i]);
426 if (err) 480 if (err)
427 break; 481 break;
@@ -436,11 +490,11 @@ int nfsd_set_nrthreads(int n, int *nthreads)
436 * this is the first time nrservs is nonzero. 490 * this is the first time nrservs is nonzero.
437 */ 491 */
438int 492int
439nfsd_svc(int nrservs) 493nfsd_svc(int nrservs, struct net *net)
440{ 494{
441 int error; 495 int error;
442 bool nfsd_up_before; 496 bool nfsd_up_before;
443 struct net *net = &init_net; 497 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
444 498
445 mutex_lock(&nfsd_mutex); 499 mutex_lock(&nfsd_mutex);
446 dprintk("nfsd: creating service\n"); 500 dprintk("nfsd: creating service\n");
@@ -449,29 +503,29 @@ nfsd_svc(int nrservs)
449 if (nrservs > NFSD_MAXSERVS) 503 if (nrservs > NFSD_MAXSERVS)
450 nrservs = NFSD_MAXSERVS; 504 nrservs = NFSD_MAXSERVS;
451 error = 0; 505 error = 0;
452 if (nrservs == 0 && nfsd_serv == NULL) 506 if (nrservs == 0 && nn->nfsd_serv == NULL)
453 goto out; 507 goto out;
454 508
455 error = nfsd_create_serv(); 509 error = nfsd_create_serv(net);
456 if (error) 510 if (error)
457 goto out; 511 goto out;
458 512
459 nfsd_up_before = nfsd_up; 513 nfsd_up_before = nn->nfsd_net_up;
460 514
461 error = nfsd_startup(nrservs); 515 error = nfsd_startup_net(nrservs, net);
462 if (error) 516 if (error)
463 goto out_destroy; 517 goto out_destroy;
464 error = svc_set_num_threads(nfsd_serv, NULL, nrservs); 518 error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs);
465 if (error) 519 if (error)
466 goto out_shutdown; 520 goto out_shutdown;
467 /* We are holding a reference to nfsd_serv which 521 /* We are holding a reference to nn->nfsd_serv which
468 * we don't want to count in the return value, 522 * we don't want to count in the return value,
469 * so subtract 1 523 * so subtract 1
470 */ 524 */
471 error = nfsd_serv->sv_nrthreads - 1; 525 error = nn->nfsd_serv->sv_nrthreads - 1;
472out_shutdown: 526out_shutdown:
473 if (error < 0 && !nfsd_up_before) 527 if (error < 0 && !nfsd_up_before)
474 nfsd_shutdown(); 528 nfsd_shutdown_net(net);
475out_destroy: 529out_destroy:
476 nfsd_destroy(net); /* Release server */ 530 nfsd_destroy(net); /* Release server */
477out: 531out:
@@ -487,6 +541,8 @@ static int
487nfsd(void *vrqstp) 541nfsd(void *vrqstp)
488{ 542{
489 struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp; 543 struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
544 struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
545 struct net *net = perm_sock->xpt_net;
490 int err; 546 int err;
491 547
492 /* Lock module and set up kernel thread */ 548 /* Lock module and set up kernel thread */
@@ -551,7 +607,7 @@ out:
551 /* Release the thread */ 607 /* Release the thread */
552 svc_exit_thread(rqstp); 608 svc_exit_thread(rqstp);
553 609
554 nfsd_destroy(&init_net); 610 nfsd_destroy(net);
555 611
556 /* Release module */ 612 /* Release module */
557 mutex_unlock(&nfsd_mutex); 613 mutex_unlock(&nfsd_mutex);
@@ -640,21 +696,24 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
640 } 696 }
641 697
642 /* Store reply in cache. */ 698 /* Store reply in cache. */
643 nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1); 699 nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
644 return 1; 700 return 1;
645} 701}
646 702
647int nfsd_pool_stats_open(struct inode *inode, struct file *file) 703int nfsd_pool_stats_open(struct inode *inode, struct file *file)
648{ 704{
649 int ret; 705 int ret;
706 struct net *net = &init_net;
707 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
708
650 mutex_lock(&nfsd_mutex); 709 mutex_lock(&nfsd_mutex);
651 if (nfsd_serv == NULL) { 710 if (nn->nfsd_serv == NULL) {
652 mutex_unlock(&nfsd_mutex); 711 mutex_unlock(&nfsd_mutex);
653 return -ENODEV; 712 return -ENODEV;
654 } 713 }
655 /* bump up the psudo refcount while traversing */ 714 /* bump up the psudo refcount while traversing */
656 svc_get(nfsd_serv); 715 svc_get(nn->nfsd_serv);
657 ret = svc_pool_stats_open(nfsd_serv, file); 716 ret = svc_pool_stats_open(nn->nfsd_serv, file);
658 mutex_unlock(&nfsd_mutex); 717 mutex_unlock(&nfsd_mutex);
659 return ret; 718 return ret;
660} 719}
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 65ec595e2226..979b42106979 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -246,7 +246,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
246 struct nfsd_readargs *args) 246 struct nfsd_readargs *args)
247{ 247{
248 unsigned int len; 248 unsigned int len;
249 int v,pn; 249 int v;
250 if (!(p = decode_fh(p, &args->fh))) 250 if (!(p = decode_fh(p, &args->fh)))
251 return 0; 251 return 0;
252 252
@@ -262,8 +262,9 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
262 */ 262 */
263 v=0; 263 v=0;
264 while (len > 0) { 264 while (len > 0) {
265 pn = rqstp->rq_resused++; 265 struct page *p = *(rqstp->rq_next_page++);
266 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]); 266
267 rqstp->rq_vec[v].iov_base = page_address(p);
267 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE; 268 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
268 len -= rqstp->rq_vec[v].iov_len; 269 len -= rqstp->rq_vec[v].iov_len;
269 v++; 270 v++;
@@ -355,7 +356,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli
355{ 356{
356 if (!(p = decode_fh(p, &args->fh))) 357 if (!(p = decode_fh(p, &args->fh)))
357 return 0; 358 return 0;
358 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]); 359 args->buffer = page_address(*(rqstp->rq_next_page++));
359 360
360 return xdr_argsize_check(rqstp, p); 361 return xdr_argsize_check(rqstp, p);
361} 362}
@@ -396,7 +397,7 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
396 if (args->count > PAGE_SIZE) 397 if (args->count > PAGE_SIZE)
397 args->count = PAGE_SIZE; 398 args->count = PAGE_SIZE;
398 399
399 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]); 400 args->buffer = page_address(*(rqstp->rq_next_page++));
400 401
401 return xdr_argsize_check(rqstp, p); 402 return xdr_argsize_check(rqstp, p);
402} 403}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index e036894bce57..d1c229feed52 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -150,6 +150,12 @@ struct nfsd4_channel_attrs {
150 u32 rdma_attrs; 150 u32 rdma_attrs;
151}; 151};
152 152
153struct nfsd4_cb_sec {
154 u32 flavor; /* (u32)(-1) used to mean "no valid flavor" */
155 u32 uid;
156 u32 gid;
157};
158
153struct nfsd4_create_session { 159struct nfsd4_create_session {
154 clientid_t clientid; 160 clientid_t clientid;
155 struct nfs4_sessionid sessionid; 161 struct nfs4_sessionid sessionid;
@@ -158,8 +164,12 @@ struct nfsd4_create_session {
158 struct nfsd4_channel_attrs fore_channel; 164 struct nfsd4_channel_attrs fore_channel;
159 struct nfsd4_channel_attrs back_channel; 165 struct nfsd4_channel_attrs back_channel;
160 u32 callback_prog; 166 u32 callback_prog;
161 u32 uid; 167 struct nfsd4_cb_sec cb_sec;
162 u32 gid; 168};
169
170struct nfsd4_backchannel_ctl {
171 u32 bc_cb_program;
172 struct nfsd4_cb_sec bc_cb_sec;
163}; 173};
164 174
165struct nfsd4_bind_conn_to_session { 175struct nfsd4_bind_conn_to_session {
@@ -192,6 +202,7 @@ struct nfsd4_session {
192 struct nfs4_sessionid se_sessionid; 202 struct nfs4_sessionid se_sessionid;
193 struct nfsd4_channel_attrs se_fchannel; 203 struct nfsd4_channel_attrs se_fchannel;
194 struct nfsd4_channel_attrs se_bchannel; 204 struct nfsd4_channel_attrs se_bchannel;
205 struct nfsd4_cb_sec se_cb_sec;
195 struct list_head se_conns; 206 struct list_head se_conns;
196 u32 se_cb_prog; 207 u32 se_cb_prog;
197 u32 se_cb_seq_nr; 208 u32 se_cb_seq_nr;
@@ -221,13 +232,12 @@ struct nfsd4_sessionid {
221 */ 232 */
222struct nfs4_client { 233struct nfs4_client {
223 struct list_head cl_idhash; /* hash by cl_clientid.id */ 234 struct list_head cl_idhash; /* hash by cl_clientid.id */
224 struct list_head cl_strhash; /* hash by cl_name */ 235 struct rb_node cl_namenode; /* link into by-name trees */
225 struct list_head cl_openowners; 236 struct list_head cl_openowners;
226 struct idr cl_stateids; /* stateid lookup */ 237 struct idr cl_stateids; /* stateid lookup */
227 struct list_head cl_delegations; 238 struct list_head cl_delegations;
228 struct list_head cl_lru; /* tail queue */ 239 struct list_head cl_lru; /* tail queue */
229 struct xdr_netobj cl_name; /* id generated by client */ 240 struct xdr_netobj cl_name; /* id generated by client */
230 char cl_recdir[HEXDIR_LEN]; /* recovery dir */
231 nfs4_verifier cl_verifier; /* generated by client */ 241 nfs4_verifier cl_verifier; /* generated by client */
232 time_t cl_time; /* time of last lease renewal */ 242 time_t cl_time; /* time of last lease renewal */
233 struct sockaddr_storage cl_addr; /* client ipaddress */ 243 struct sockaddr_storage cl_addr; /* client ipaddress */
@@ -242,9 +252,11 @@ struct nfs4_client {
242#define NFSD4_CLIENT_CB_KILL (1) 252#define NFSD4_CLIENT_CB_KILL (1)
243#define NFSD4_CLIENT_STABLE (2) /* client on stable storage */ 253#define NFSD4_CLIENT_STABLE (2) /* client on stable storage */
244#define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */ 254#define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */
255#define NFSD4_CLIENT_CONFIRMED (4) /* client is confirmed */
245#define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ 256#define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \
246 1 << NFSD4_CLIENT_CB_KILL) 257 1 << NFSD4_CLIENT_CB_KILL)
247 unsigned long cl_flags; 258 unsigned long cl_flags;
259 struct rpc_cred *cl_cb_cred;
248 struct rpc_clnt *cl_cb_client; 260 struct rpc_clnt *cl_cb_client;
249 u32 cl_cb_ident; 261 u32 cl_cb_ident;
250#define NFSD4_CB_UP 0 262#define NFSD4_CB_UP 0
@@ -271,6 +283,7 @@ struct nfs4_client {
271 unsigned long cl_cb_slot_busy; 283 unsigned long cl_cb_slot_busy;
272 struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ 284 struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */
273 /* wait here for slots */ 285 /* wait here for slots */
286 struct net *net;
274}; 287};
275 288
276static inline void 289static inline void
@@ -292,6 +305,7 @@ is_client_expired(struct nfs4_client *clp)
292 */ 305 */
293struct nfs4_client_reclaim { 306struct nfs4_client_reclaim {
294 struct list_head cr_strhash; /* hash by cr_name */ 307 struct list_head cr_strhash; /* hash by cr_name */
308 struct nfs4_client *cr_clp; /* pointer to associated clp */
295 char cr_recdir[HEXDIR_LEN]; /* recover dir */ 309 char cr_recdir[HEXDIR_LEN]; /* recover dir */
296}; 310};
297 311
@@ -452,25 +466,26 @@ extern __be32 nfs4_preprocess_stateid_op(struct net *net,
452 stateid_t *stateid, int flags, struct file **filp); 466 stateid_t *stateid, int flags, struct file **filp);
453extern void nfs4_lock_state(void); 467extern void nfs4_lock_state(void);
454extern void nfs4_unlock_state(void); 468extern void nfs4_unlock_state(void);
455extern int nfs4_in_grace(void); 469void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
456extern void nfs4_release_reclaim(void); 470extern void nfs4_release_reclaim(struct nfsd_net *);
457extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(struct nfs4_client *crp); 471extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
458extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions); 472 struct nfsd_net *nn);
473extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions, struct nfsd_net *nn);
459extern void nfs4_free_openowner(struct nfs4_openowner *); 474extern void nfs4_free_openowner(struct nfs4_openowner *);
460extern void nfs4_free_lockowner(struct nfs4_lockowner *); 475extern void nfs4_free_lockowner(struct nfs4_lockowner *);
461extern int set_callback_cred(void); 476extern int set_callback_cred(void);
477extern void nfsd4_init_callback(struct nfsd4_callback *);
462extern void nfsd4_probe_callback(struct nfs4_client *clp); 478extern void nfsd4_probe_callback(struct nfs4_client *clp);
463extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); 479extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
464extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); 480extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
465extern void nfsd4_do_callback_rpc(struct work_struct *);
466extern void nfsd4_cb_recall(struct nfs4_delegation *dp); 481extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
467extern int nfsd4_create_callback_queue(void); 482extern int nfsd4_create_callback_queue(void);
468extern void nfsd4_destroy_callback_queue(void); 483extern void nfsd4_destroy_callback_queue(void);
469extern void nfsd4_shutdown_callback(struct nfs4_client *); 484extern void nfsd4_shutdown_callback(struct nfs4_client *);
470extern void nfs4_put_delegation(struct nfs4_delegation *dp); 485extern void nfs4_put_delegation(struct nfs4_delegation *dp);
471extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); 486extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
472extern int nfs4_client_to_reclaim(const char *name); 487 struct nfsd_net *nn);
473extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id); 488extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn);
474extern void release_session_client(struct nfsd4_session *); 489extern void release_session_client(struct nfsd4_session *);
475extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *); 490extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *);
476 491
@@ -480,5 +495,28 @@ extern void nfsd4_client_tracking_exit(struct net *net);
480extern void nfsd4_client_record_create(struct nfs4_client *clp); 495extern void nfsd4_client_record_create(struct nfs4_client *clp);
481extern void nfsd4_client_record_remove(struct nfs4_client *clp); 496extern void nfsd4_client_record_remove(struct nfs4_client *clp);
482extern int nfsd4_client_record_check(struct nfs4_client *clp); 497extern int nfsd4_client_record_check(struct nfs4_client *clp);
483extern void nfsd4_record_grace_done(struct net *net, time_t boot_time); 498extern void nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time);
499
500/* nfs fault injection functions */
501#ifdef CONFIG_NFSD_FAULT_INJECTION
502int nfsd_fault_inject_init(void);
503void nfsd_fault_inject_cleanup(void);
504u64 nfsd_for_n_state(u64, u64 (*)(struct nfs4_client *, u64));
505struct nfs4_client *nfsd_find_client(struct sockaddr_storage *, size_t);
506
507u64 nfsd_forget_client(struct nfs4_client *, u64);
508u64 nfsd_forget_client_locks(struct nfs4_client*, u64);
509u64 nfsd_forget_client_openowners(struct nfs4_client *, u64);
510u64 nfsd_forget_client_delegations(struct nfs4_client *, u64);
511u64 nfsd_recall_client_delegations(struct nfs4_client *, u64);
512
513u64 nfsd_print_client(struct nfs4_client *, u64);
514u64 nfsd_print_client_locks(struct nfs4_client *, u64);
515u64 nfsd_print_client_openowners(struct nfs4_client *, u64);
516u64 nfsd_print_client_delegations(struct nfs4_client *, u64);
517#else /* CONFIG_NFSD_FAULT_INJECTION */
518static inline int nfsd_fault_inject_init(void) { return 0; }
519static inline void nfsd_fault_inject_cleanup(void) {}
520#endif /* CONFIG_NFSD_FAULT_INJECTION */
521
484#endif /* NFSD4_STATE_H */ 522#endif /* NFSD4_STATE_H */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c120b48ec305..f0a6d88d7fff 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -886,7 +886,7 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
886 struct splice_desc *sd) 886 struct splice_desc *sd)
887{ 887{
888 struct svc_rqst *rqstp = sd->u.data; 888 struct svc_rqst *rqstp = sd->u.data;
889 struct page **pp = rqstp->rq_respages + rqstp->rq_resused; 889 struct page **pp = rqstp->rq_next_page;
890 struct page *page = buf->page; 890 struct page *page = buf->page;
891 size_t size; 891 size_t size;
892 892
@@ -894,17 +894,15 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
894 894
895 if (rqstp->rq_res.page_len == 0) { 895 if (rqstp->rq_res.page_len == 0) {
896 get_page(page); 896 get_page(page);
897 put_page(*pp); 897 put_page(*rqstp->rq_next_page);
898 *pp = page; 898 *(rqstp->rq_next_page++) = page;
899 rqstp->rq_resused++;
900 rqstp->rq_res.page_base = buf->offset; 899 rqstp->rq_res.page_base = buf->offset;
901 rqstp->rq_res.page_len = size; 900 rqstp->rq_res.page_len = size;
902 } else if (page != pp[-1]) { 901 } else if (page != pp[-1]) {
903 get_page(page); 902 get_page(page);
904 if (*pp) 903 if (*rqstp->rq_next_page)
905 put_page(*pp); 904 put_page(*rqstp->rq_next_page);
906 *pp = page; 905 *(rqstp->rq_next_page++) = page;
907 rqstp->rq_resused++;
908 rqstp->rq_res.page_len += size; 906 rqstp->rq_res.page_len += size;
909 } else 907 } else
910 rqstp->rq_res.page_len += size; 908 rqstp->rq_res.page_len += size;
@@ -936,7 +934,8 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
936 .u.data = rqstp, 934 .u.data = rqstp,
937 }; 935 };
938 936
939 rqstp->rq_resused = 1; 937 WARN_ON_ONCE(rqstp->rq_next_page != rqstp->rq_respages + 1);
938 rqstp->rq_next_page = rqstp->rq_respages + 1;
940 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor); 939 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
941 } else { 940 } else {
942 oldfs = get_fs(); 941 oldfs = get_fs();
@@ -1020,28 +1019,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1020 inode = dentry->d_inode; 1019 inode = dentry->d_inode;
1021 exp = fhp->fh_export; 1020 exp = fhp->fh_export;
1022 1021
1023 /*
1024 * Request sync writes if
1025 * - the sync export option has been set, or
1026 * - the client requested O_SYNC behavior (NFSv3 feature).
1027 * - The file system doesn't support fsync().
1028 * When NFSv2 gathered writes have been configured for this volume,
1029 * flushing the data to disk is handled separately below.
1030 */
1031 use_wgather = (rqstp->rq_vers == 2) && EX_WGATHER(exp); 1022 use_wgather = (rqstp->rq_vers == 2) && EX_WGATHER(exp);
1032 1023
1033 if (!file->f_op->fsync) {/* COMMIT3 cannot work */
1034 stable = 2;
1035 *stablep = 2; /* FILE_SYNC */
1036 }
1037
1038 if (!EX_ISSYNC(exp)) 1024 if (!EX_ISSYNC(exp))
1039 stable = 0; 1025 stable = 0;
1040 if (stable && !use_wgather) {
1041 spin_lock(&file->f_lock);
1042 file->f_flags |= O_SYNC;
1043 spin_unlock(&file->f_lock);
1044 }
1045 1026
1046 /* Write the data. */ 1027 /* Write the data. */
1047 oldfs = get_fs(); set_fs(KERNEL_DS); 1028 oldfs = get_fs(); set_fs(KERNEL_DS);
@@ -1057,8 +1038,12 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1057 if (inode->i_mode & (S_ISUID | S_ISGID)) 1038 if (inode->i_mode & (S_ISUID | S_ISGID))
1058 kill_suid(dentry); 1039 kill_suid(dentry);
1059 1040
1060 if (stable && use_wgather) 1041 if (stable) {
1061 host_err = wait_for_concurrent_writes(file); 1042 if (use_wgather)
1043 host_err = wait_for_concurrent_writes(file);
1044 else
1045 host_err = vfs_fsync_range(file, offset, offset+*cnt, 0);
1046 }
1062 1047
1063out_nfserr: 1048out_nfserr:
1064 dprintk("nfsd: write complete host_err=%d\n", host_err); 1049 dprintk("nfsd: write complete host_err=%d\n", host_err);
@@ -1485,13 +1470,19 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1485 case NFS3_CREATE_EXCLUSIVE: 1470 case NFS3_CREATE_EXCLUSIVE:
1486 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime 1471 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
1487 && dchild->d_inode->i_atime.tv_sec == v_atime 1472 && dchild->d_inode->i_atime.tv_sec == v_atime
1488 && dchild->d_inode->i_size == 0 ) 1473 && dchild->d_inode->i_size == 0 ) {
1474 if (created)
1475 *created = 1;
1489 break; 1476 break;
1477 }
1490 case NFS4_CREATE_EXCLUSIVE4_1: 1478 case NFS4_CREATE_EXCLUSIVE4_1:
1491 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime 1479 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
1492 && dchild->d_inode->i_atime.tv_sec == v_atime 1480 && dchild->d_inode->i_atime.tv_sec == v_atime
1493 && dchild->d_inode->i_size == 0 ) 1481 && dchild->d_inode->i_size == 0 ) {
1482 if (created)
1483 *created = 1;
1494 goto set_attr; 1484 goto set_attr;
1485 }
1495 /* fallthru */ 1486 /* fallthru */
1496 case NFS3_CREATE_GUARDED: 1487 case NFS3_CREATE_GUARDED:
1497 err = nfserr_exist; 1488 err = nfserr_exist;
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index acd127d4ee82..0889bfb43dc9 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -385,7 +385,8 @@ struct nfsd4_write {
385 u64 wr_offset; /* request */ 385 u64 wr_offset; /* request */
386 u32 wr_stable_how; /* request */ 386 u32 wr_stable_how; /* request */
387 u32 wr_buflen; /* request */ 387 u32 wr_buflen; /* request */
388 int wr_vlen; 388 struct kvec wr_head;
389 struct page ** wr_pagelist; /* request */
389 390
390 u32 wr_bytes_written; /* response */ 391 u32 wr_bytes_written; /* response */
391 u32 wr_how_written; /* response */ 392 u32 wr_how_written; /* response */
@@ -462,6 +463,7 @@ struct nfsd4_op {
462 463
463 /* NFSv4.1 */ 464 /* NFSv4.1 */
464 struct nfsd4_exchange_id exchange_id; 465 struct nfsd4_exchange_id exchange_id;
466 struct nfsd4_backchannel_ctl backchannel_ctl;
465 struct nfsd4_bind_conn_to_session bind_conn_to_session; 467 struct nfsd4_bind_conn_to_session bind_conn_to_session;
466 struct nfsd4_create_session create_session; 468 struct nfsd4_create_session create_session;
467 struct nfsd4_destroy_session destroy_session; 469 struct nfsd4_destroy_session destroy_session;
@@ -526,6 +528,14 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
526 || nfsd4_is_solo_sequence(resp); 528 || nfsd4_is_solo_sequence(resp);
527} 529}
528 530
531static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
532{
533 struct nfsd4_compoundres *resp = rqstp->rq_resp;
534 struct nfsd4_compoundargs *argp = rqstp->rq_argp;
535
536 return argp->opcnt == resp->opcnt;
537}
538
529#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) 539#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)
530 540
531static inline void 541static inline void
@@ -566,6 +576,7 @@ extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
566 struct nfsd4_sequence *seq); 576 struct nfsd4_sequence *seq);
567extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, 577extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
568 struct nfsd4_compound_state *, struct nfsd4_exchange_id *); 578 struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
579extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *);
569extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *); 580extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *);
570extern __be32 nfsd4_create_session(struct svc_rqst *, 581extern __be32 nfsd4_create_session(struct svc_rqst *,
571 struct nfsd4_compound_state *, 582 struct nfsd4_compound_state *,
@@ -579,7 +590,7 @@ extern __be32 nfsd4_destroy_session(struct svc_rqst *,
579extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *); 590extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *);
580__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); 591__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *);
581extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, 592extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
582 struct nfsd4_open *open); 593 struct nfsd4_open *open, struct nfsd_net *nn);
583extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, 594extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
584 struct svc_fh *current_fh, struct nfsd4_open *open); 595 struct svc_fh *current_fh, struct nfsd4_open *open);
585extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status); 596extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status);
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index c7e6b6392ab8..5b9b5b317180 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -83,6 +83,11 @@ enum fid_type {
83 * 64 bit parent inode number. 83 * 64 bit parent inode number.
84 */ 84 */
85 FILEID_NILFS_WITH_PARENT = 0x62, 85 FILEID_NILFS_WITH_PARENT = 0x62,
86
87 /*
88 * Filesystems must not use 0xff file ID.
89 */
90 FILEID_INVALID = 0xff,
86}; 91};
87 92
88struct fid { 93struct fid {
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index f792794f6634..5dc9ee4d616e 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -217,6 +217,8 @@ extern int qword_get(char **bpp, char *dest, int bufsize);
217static inline int get_int(char **bpp, int *anint) 217static inline int get_int(char **bpp, int *anint)
218{ 218{
219 char buf[50]; 219 char buf[50];
220 char *ep;
221 int rv;
220 int len = qword_get(bpp, buf, sizeof(buf)); 222 int len = qword_get(bpp, buf, sizeof(buf));
221 223
222 if (len < 0) 224 if (len < 0)
@@ -224,9 +226,11 @@ static inline int get_int(char **bpp, int *anint)
224 if (len == 0) 226 if (len == 0)
225 return -ENOENT; 227 return -ENOENT;
226 228
227 if (kstrtoint(buf, 0, anint)) 229 rv = simple_strtol(buf, &ep, 0);
230 if (*ep)
228 return -EINVAL; 231 return -EINVAL;
229 232
233 *anint = rv;
230 return 0; 234 return 0;
231} 235}
232 236
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index d83db800fe02..676ddf53b3ee 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -243,6 +243,7 @@ struct svc_rqst {
243 struct page * rq_pages[RPCSVC_MAXPAGES]; 243 struct page * rq_pages[RPCSVC_MAXPAGES];
244 struct page * *rq_respages; /* points into rq_pages */ 244 struct page * *rq_respages; /* points into rq_pages */
245 int rq_resused; /* number of pages used for result */ 245 int rq_resused; /* number of pages used for result */
246 struct page * *rq_next_page; /* next reply page to use */
246 247
247 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */ 248 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
248 249
@@ -338,9 +339,8 @@ xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
338 339
339static inline void svc_free_res_pages(struct svc_rqst *rqstp) 340static inline void svc_free_res_pages(struct svc_rqst *rqstp)
340{ 341{
341 while (rqstp->rq_resused) { 342 while (rqstp->rq_next_page != rqstp->rq_respages) {
342 struct page **pp = (rqstp->rq_respages + 343 struct page **pp = --rqstp->rq_next_page;
343 --rqstp->rq_resused);
344 if (*pp) { 344 if (*pp) {
345 put_page(*pp); 345 put_page(*pp);
346 *pp = NULL; 346 *pp = NULL;
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 92ad02f0dcc0..62fd1b756e99 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -26,11 +26,28 @@ struct svc_sock {
26 void (*sk_owspace)(struct sock *); 26 void (*sk_owspace)(struct sock *);
27 27
28 /* private TCP part */ 28 /* private TCP part */
29 u32 sk_reclen; /* length of record */ 29 /* On-the-wire fragment header: */
30 u32 sk_tcplen; /* current read length */ 30 __be32 sk_reclen;
31 /* As we receive a record, this includes the length received so
32 * far (including the fragment header): */
33 u32 sk_tcplen;
34 /* Total length of the data (not including fragment headers)
35 * received so far in the fragments making up this rpc: */
36 u32 sk_datalen;
37
31 struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */ 38 struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */
32}; 39};
33 40
41static inline u32 svc_sock_reclen(struct svc_sock *svsk)
42{
43 return ntohl(svsk->sk_reclen) & RPC_FRAGMENT_SIZE_MASK;
44}
45
46static inline u32 svc_sock_final_rec(struct svc_sock *svsk)
47{
48 return ntohl(svsk->sk_reclen) & RPC_LAST_STREAM_FRAGMENT;
49}
50
34/* 51/*
35 * Function prototypes. 52 * Function prototypes.
36 */ 53 */
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 411f332de0b3..795a0f4e920b 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -23,7 +23,6 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/nsproxy.h>
27#include <net/ipv6.h> 26#include <net/ipv6.h>
28 27
29#include <linux/sunrpc/clnt.h> 28#include <linux/sunrpc/clnt.h>
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index dfa4ba69ff45..dbf12ac5ecb7 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -20,7 +20,6 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/kthread.h> 21#include <linux/kthread.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/nsproxy.h>
24 23
25#include <linux/sunrpc/types.h> 24#include <linux/sunrpc/types.h>
26#include <linux/sunrpc/xdr.h> 25#include <linux/sunrpc/xdr.h>
@@ -1041,7 +1040,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
1041} 1040}
1042 1041
1043/* 1042/*
1044 * Printk the given error with the address of the client that caused it. 1043 * dprintk the given error with the address of the client that caused it.
1045 */ 1044 */
1046static __printf(2, 3) 1045static __printf(2, 3)
1047void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) 1046void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
@@ -1055,8 +1054,7 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
1055 vaf.fmt = fmt; 1054 vaf.fmt = fmt;
1056 vaf.va = &args; 1055 vaf.va = &args;
1057 1056
1058 net_warn_ratelimited("svc: %s: %pV", 1057 dprintk("svc: %s: %pV", svc_print_addr(rqstp, buf, sizeof(buf)), &vaf);
1059 svc_print_addr(rqstp, buf, sizeof(buf)), &vaf);
1060 1058
1061 va_end(args); 1059 va_end(args);
1062} 1060}
@@ -1305,7 +1303,7 @@ svc_process(struct svc_rqst *rqstp)
1305 * Setup response xdr_buf. 1303 * Setup response xdr_buf.
1306 * Initially it has just one page 1304 * Initially it has just one page
1307 */ 1305 */
1308 rqstp->rq_resused = 1; 1306 rqstp->rq_next_page = &rqstp->rq_respages[1];
1309 resv->iov_base = page_address(rqstp->rq_respages[0]); 1307 resv->iov_base = page_address(rqstp->rq_respages[0]);
1310 resv->iov_len = 0; 1308 resv->iov_len = 0;
1311 rqstp->rq_res.pages = rqstp->rq_respages + 1; 1309 rqstp->rq_res.pages = rqstp->rq_respages + 1;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index cc3020d16789..0a148c9d2a5c 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -605,6 +605,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
605 rqstp->rq_respages = rqstp->rq_pages + 1 + 605 rqstp->rq_respages = rqstp->rq_pages + 1 +
606 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE); 606 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE);
607 } 607 }
608 rqstp->rq_next_page = rqstp->rq_respages+1;
608 609
609 if (serv->sv_stats) 610 if (serv->sv_stats)
610 serv->sv_stats->netudpcnt++; 611 serv->sv_stats->netudpcnt++;
@@ -878,9 +879,9 @@ static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst
878{ 879{
879 unsigned int i, len, npages; 880 unsigned int i, len, npages;
880 881
881 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 882 if (svsk->sk_datalen == 0)
882 return 0; 883 return 0;
883 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 884 len = svsk->sk_datalen;
884 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 885 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
885 for (i = 0; i < npages; i++) { 886 for (i = 0; i < npages; i++) {
886 if (rqstp->rq_pages[i] != NULL) 887 if (rqstp->rq_pages[i] != NULL)
@@ -897,9 +898,9 @@ static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
897{ 898{
898 unsigned int i, len, npages; 899 unsigned int i, len, npages;
899 900
900 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 901 if (svsk->sk_datalen == 0)
901 return; 902 return;
902 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 903 len = svsk->sk_datalen;
903 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 904 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
904 for (i = 0; i < npages; i++) { 905 for (i = 0; i < npages; i++) {
905 svsk->sk_pages[i] = rqstp->rq_pages[i]; 906 svsk->sk_pages[i] = rqstp->rq_pages[i];
@@ -911,9 +912,9 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
911{ 912{
912 unsigned int i, len, npages; 913 unsigned int i, len, npages;
913 914
914 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 915 if (svsk->sk_datalen == 0)
915 goto out; 916 goto out;
916 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 917 len = svsk->sk_datalen;
917 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 918 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
918 for (i = 0; i < npages; i++) { 919 for (i = 0; i < npages; i++) {
919 BUG_ON(svsk->sk_pages[i] == NULL); 920 BUG_ON(svsk->sk_pages[i] == NULL);
@@ -922,13 +923,12 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
922 } 923 }
923out: 924out:
924 svsk->sk_tcplen = 0; 925 svsk->sk_tcplen = 0;
926 svsk->sk_datalen = 0;
925} 927}
926 928
927/* 929/*
928 * Receive data. 930 * Receive fragment record header.
929 * If we haven't gotten the record length yet, get the next four bytes. 931 * If we haven't gotten the record length yet, get the next four bytes.
930 * Otherwise try to gobble up as much as possible up to the complete
931 * record length.
932 */ 932 */
933static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) 933static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
934{ 934{
@@ -954,32 +954,16 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
954 return -EAGAIN; 954 return -EAGAIN;
955 } 955 }
956 956
957 svsk->sk_reclen = ntohl(svsk->sk_reclen); 957 dprintk("svc: TCP record, %d bytes\n", svc_sock_reclen(svsk));
958 if (!(svsk->sk_reclen & RPC_LAST_STREAM_FRAGMENT)) { 958 if (svc_sock_reclen(svsk) + svsk->sk_datalen >
959 /* FIXME: technically, a record can be fragmented, 959 serv->sv_max_mesg) {
960 * and non-terminal fragments will not have the top 960 net_notice_ratelimited("RPC: fragment too large: %d\n",
961 * bit set in the fragment length header. 961 svc_sock_reclen(svsk));
962 * But apparently no known nfs clients send fragmented
963 * records. */
964 net_notice_ratelimited("RPC: multiple fragments per record not supported\n");
965 goto err_delete;
966 }
967
968 svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
969 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
970 if (svsk->sk_reclen > serv->sv_max_mesg) {
971 net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n",
972 (unsigned long)svsk->sk_reclen);
973 goto err_delete; 962 goto err_delete;
974 } 963 }
975 } 964 }
976 965
977 if (svsk->sk_reclen < 8) 966 return svc_sock_reclen(svsk);
978 goto err_delete; /* client is nuts. */
979
980 len = svsk->sk_reclen;
981
982 return len;
983error: 967error:
984 dprintk("RPC: TCP recv_record got %d\n", len); 968 dprintk("RPC: TCP recv_record got %d\n", len);
985 return len; 969 return len;
@@ -1023,7 +1007,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
1023 if (dst->iov_len < src->iov_len) 1007 if (dst->iov_len < src->iov_len)
1024 return -EAGAIN; /* whatever; just giving up. */ 1008 return -EAGAIN; /* whatever; just giving up. */
1025 memcpy(dst->iov_base, src->iov_base, src->iov_len); 1009 memcpy(dst->iov_base, src->iov_base, src->iov_len);
1026 xprt_complete_rqst(req->rq_task, svsk->sk_reclen); 1010 xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len);
1027 rqstp->rq_arg.len = 0; 1011 rqstp->rq_arg.len = 0;
1028 return 0; 1012 return 0;
1029} 1013}
@@ -1042,6 +1026,17 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)
1042 return i; 1026 return i;
1043} 1027}
1044 1028
1029static void svc_tcp_fragment_received(struct svc_sock *svsk)
1030{
1031 /* If we have more data, signal svc_xprt_enqueue() to try again */
1032 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1033 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1034 dprintk("svc: TCP %s record (%d bytes)\n",
1035 svc_sock_final_rec(svsk) ? "final" : "nonfinal",
1036 svc_sock_reclen(svsk));
1037 svsk->sk_tcplen = 0;
1038 svsk->sk_reclen = 0;
1039}
1045 1040
1046/* 1041/*
1047 * Receive data from a TCP socket. 1042 * Receive data from a TCP socket.
@@ -1068,29 +1063,39 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1068 goto error; 1063 goto error;
1069 1064
1070 base = svc_tcp_restore_pages(svsk, rqstp); 1065 base = svc_tcp_restore_pages(svsk, rqstp);
1071 want = svsk->sk_reclen - base; 1066 want = svc_sock_reclen(svsk) - (svsk->sk_tcplen - sizeof(rpc_fraghdr));
1072 1067
1073 vec = rqstp->rq_vec; 1068 vec = rqstp->rq_vec;
1074 1069
1075 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], 1070 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
1076 svsk->sk_reclen); 1071 svsk->sk_datalen + want);
1077 1072
1078 rqstp->rq_respages = &rqstp->rq_pages[pnum]; 1073 rqstp->rq_respages = &rqstp->rq_pages[pnum];
1074 rqstp->rq_next_page = rqstp->rq_respages + 1;
1079 1075
1080 /* Now receive data */ 1076 /* Now receive data */
1081 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); 1077 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
1082 if (len >= 0) 1078 if (len >= 0) {
1083 svsk->sk_tcplen += len; 1079 svsk->sk_tcplen += len;
1084 if (len != want) { 1080 svsk->sk_datalen += len;
1081 }
1082 if (len != want || !svc_sock_final_rec(svsk)) {
1085 svc_tcp_save_pages(svsk, rqstp); 1083 svc_tcp_save_pages(svsk, rqstp);
1086 if (len < 0 && len != -EAGAIN) 1084 if (len < 0 && len != -EAGAIN)
1087 goto err_other; 1085 goto err_delete;
1088 dprintk("svc: incomplete TCP record (%d of %d)\n", 1086 if (len == want)
1089 svsk->sk_tcplen, svsk->sk_reclen); 1087 svc_tcp_fragment_received(svsk);
1088 else
1089 dprintk("svc: incomplete TCP record (%d of %d)\n",
1090 (int)(svsk->sk_tcplen - sizeof(rpc_fraghdr)),
1091 svc_sock_reclen(svsk));
1090 goto err_noclose; 1092 goto err_noclose;
1091 } 1093 }
1092 1094
1093 rqstp->rq_arg.len = svsk->sk_reclen; 1095 if (svc_sock_reclen(svsk) < 8)
1096 goto err_delete; /* client is nuts. */
1097
1098 rqstp->rq_arg.len = svsk->sk_datalen;
1094 rqstp->rq_arg.page_base = 0; 1099 rqstp->rq_arg.page_base = 0;
1095 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { 1100 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
1096 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len; 1101 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
@@ -1107,11 +1112,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1107 len = receive_cb_reply(svsk, rqstp); 1112 len = receive_cb_reply(svsk, rqstp);
1108 1113
1109 /* Reset TCP read info */ 1114 /* Reset TCP read info */
1110 svsk->sk_reclen = 0; 1115 svsk->sk_datalen = 0;
1111 svsk->sk_tcplen = 0; 1116 svc_tcp_fragment_received(svsk);
1112 /* If we have more data, signal svc_xprt_enqueue() to try again */
1113 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1114 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1115 1117
1116 if (len < 0) 1118 if (len < 0)
1117 goto error; 1119 goto error;
@@ -1120,15 +1122,14 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1120 if (serv->sv_stats) 1122 if (serv->sv_stats)
1121 serv->sv_stats->nettcpcnt++; 1123 serv->sv_stats->nettcpcnt++;
1122 1124
1123 dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len);
1124 return rqstp->rq_arg.len; 1125 return rqstp->rq_arg.len;
1125 1126
1126error: 1127error:
1127 if (len != -EAGAIN) 1128 if (len != -EAGAIN)
1128 goto err_other; 1129 goto err_delete;
1129 dprintk("RPC: TCP recvfrom got EAGAIN\n"); 1130 dprintk("RPC: TCP recvfrom got EAGAIN\n");
1130 return 0; 1131 return 0;
1131err_other: 1132err_delete:
1132 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", 1133 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
1133 svsk->sk_xprt.xpt_server->sv_name, -len); 1134 svsk->sk_xprt.xpt_server->sv_name, -len);
1134 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1135 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
@@ -1305,6 +1306,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1305 1306
1306 svsk->sk_reclen = 0; 1307 svsk->sk_reclen = 0;
1307 svsk->sk_tcplen = 0; 1308 svsk->sk_tcplen = 0;
1309 svsk->sk_datalen = 0;
1308 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); 1310 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages));
1309 1311
1310 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1312 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 41cb63b623df..0ce75524ed21 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -521,11 +521,11 @@ next_sge:
521 rqstp->rq_pages[ch_no] = NULL; 521 rqstp->rq_pages[ch_no] = NULL;
522 522
523 /* 523 /*
524 * Detach res pages. svc_release must see a resused count of 524 * Detach res pages. If svc_release sees any it will attempt to
525 * zero or it will attempt to put them. 525 * put them.
526 */ 526 */
527 while (rqstp->rq_resused) 527 while (rqstp->rq_next_page != rqstp->rq_respages)
528 rqstp->rq_respages[--rqstp->rq_resused] = NULL; 528 *(--rqstp->rq_next_page) = NULL;
529 529
530 return err; 530 return err;
531} 531}
@@ -550,7 +550,7 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
550 550
551 /* rq_respages starts after the last arg page */ 551 /* rq_respages starts after the last arg page */
552 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no]; 552 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
553 rqstp->rq_resused = 0; 553 rqstp->rq_next_page = &rqstp->rq_arg.pages[page_no];
554 554
555 /* Rebuild rq_arg head and tail. */ 555 /* Rebuild rq_arg head and tail. */
556 rqstp->rq_arg.head[0] = head->arg.head[0]; 556 rqstp->rq_arg.head[0] = head->arg.head[0];
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 42eb7ba0b903..c1d124dc772b 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -548,6 +548,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
548 int sge_no; 548 int sge_no;
549 int sge_bytes; 549 int sge_bytes;
550 int page_no; 550 int page_no;
551 int pages;
551 int ret; 552 int ret;
552 553
553 /* Post a recv buffer to handle another request. */ 554 /* Post a recv buffer to handle another request. */
@@ -611,7 +612,8 @@ static int send_reply(struct svcxprt_rdma *rdma,
611 * respages array. They are our pages until the I/O 612 * respages array. They are our pages until the I/O
612 * completes. 613 * completes.
613 */ 614 */
614 for (page_no = 0; page_no < rqstp->rq_resused; page_no++) { 615 pages = rqstp->rq_next_page - rqstp->rq_respages;
616 for (page_no = 0; page_no < pages; page_no++) {
615 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no]; 617 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no];
616 ctxt->count++; 618 ctxt->count++;
617 rqstp->rq_respages[page_no] = NULL; 619 rqstp->rq_respages[page_no] = NULL;