aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 12:36:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 12:36:34 -0500
commit2d4dce0070448bcb5ccd04553a4be4635417f565 (patch)
tree300915d2df0b8f28072d090c21d8ac084cd5f6c0 /fs
parentea88eeac0cb8328014b53d80ca631e8dc0dc18dc (diff)
parentcd6c5968582a273561464fe6b1e8cc8214be02df (diff)
Merge tag 'nfs-for-3.8-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Features include: - Full audit of BUG_ON asserts in the NFS, SUNRPC and lockd client code. Remove altogether where possible, and replace with WARN_ON_ONCE and appropriate error returns where not. - NFSv4.1 client adds session dynamic slot table management. There is matching server side code that has been submitted to Bruce for consideration. Together, this code allows the server to dynamically manage the amount of memory it allocates to the duplicate request cache for each client. It will constantly resize those caches to reserve more memory for clients that are hot while shrinking caches for those that are quiescent. In addition, there are assorted bugfixes for the generic NFS write code, fixes to deal with the drop_nlink() warnings, and yet another fix for NFSv4 getacl." * tag 'nfs-for-3.8-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (106 commits) SUNRPC: continue run over clients list on PipeFS event instead of break NFS: Don't use SetPageError in the NFS writeback code SUNRPC: variable 'svsk' is unused in function bc_send_request SUNRPC: Handle ECONNREFUSED in xs_local_setup_socket NFSv4.1: Deal effectively with interrupted RPC calls. NFSv4.1: Move the RPC timestamp out of the slot. NFSv4.1: Try to deal with NFS4ERR_SEQ_MISORDERED. NFS: nfs_lookup_revalidate should not trust an inode with i_nlink == 0 NFS: Fix calls to drop_nlink() NFS: Ensure that we always drop inodes that have been marked as stale nfs: Remove unused list nfs4_clientid_list nfs: Remove duplicate function declaration in internal.h NFS: avoid NULL dereference in nfs_destroy_server SUNRPC handle EKEYEXPIRED in call_refreshresult SUNRPC set gss gc_expiry to full lifetime nfs: fix page dirtying in NFS DIO read codepath nfs: don't zero out the rest of the page if we hit the EOF on a DIO READ NFSv4.1: Be conservative about the client highest slotid NFSv4.1: Handle NFS4ERR_BADSLOT errors correctly nfs: don't extend writes to cover entire page if pagecache is invalid ...
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/clnt4xdr.c8
-rw-r--r--fs/lockd/clntproc.c3
-rw-r--r--fs/lockd/clntxdr.c8
-rw-r--r--fs/lockd/host.c15
-rw-r--r--fs/lockd/mon.c3
-rw-r--r--fs/nfs/Makefile2
-rw-r--r--fs/nfs/blocklayout/blocklayout.c1
-rw-r--r--fs/nfs/cache_lib.c1
-rw-r--r--fs/nfs/callback.h4
-rw-r--r--fs/nfs/callback_proc.c17
-rw-r--r--fs/nfs/callback_xdr.c5
-rw-r--r--fs/nfs/client.c9
-rw-r--r--fs/nfs/dir.c22
-rw-r--r--fs/nfs/direct.c17
-rw-r--r--fs/nfs/inode.c10
-rw-r--r--fs/nfs/internal.h42
-rw-r--r--fs/nfs/mount_clnt.c7
-rw-r--r--fs/nfs/nfs2xdr.c4
-rw-r--r--fs/nfs/nfs3proc.c6
-rw-r--r--fs/nfs/nfs3xdr.c7
-rw-r--r--fs/nfs/nfs4_fs.h29
-rw-r--r--fs/nfs/nfs4client.c5
-rw-r--r--fs/nfs/nfs4file.c1
-rw-r--r--fs/nfs/nfs4filelayout.c45
-rw-r--r--fs/nfs/nfs4filelayoutdev.c3
-rw-r--r--fs/nfs/nfs4proc.c820
-rw-r--r--fs/nfs/nfs4session.c552
-rw-r--r--fs/nfs/nfs4session.h142
-rw-r--r--fs/nfs/nfs4state.c143
-rw-r--r--fs/nfs/nfs4super.c1
-rw-r--r--fs/nfs/nfs4xdr.c52
-rw-r--r--fs/nfs/objlayout/objlayout.c11
-rw-r--r--fs/nfs/pnfs.c17
-rw-r--r--fs/nfs/proc.c43
-rw-r--r--fs/nfs/super.c2
-rw-r--r--fs/nfs/write.c31
36 files changed, 1115 insertions, 973 deletions
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c
index 13ad1539fbf2..00ec0b9c94d1 100644
--- a/fs/lockd/clnt4xdr.c
+++ b/fs/lockd/clnt4xdr.c
@@ -64,10 +64,6 @@ static void nlm4_compute_offsets(const struct nlm_lock *lock,
64{ 64{
65 const struct file_lock *fl = &lock->fl; 65 const struct file_lock *fl = &lock->fl;
66 66
67 BUG_ON(fl->fl_start > NLM4_OFFSET_MAX);
68 BUG_ON(fl->fl_end > NLM4_OFFSET_MAX &&
69 fl->fl_end != OFFSET_MAX);
70
71 *l_offset = loff_t_to_s64(fl->fl_start); 67 *l_offset = loff_t_to_s64(fl->fl_start);
72 if (fl->fl_end == OFFSET_MAX) 68 if (fl->fl_end == OFFSET_MAX)
73 *l_len = 0; 69 *l_len = 0;
@@ -122,7 +118,6 @@ static void encode_netobj(struct xdr_stream *xdr,
122{ 118{
123 __be32 *p; 119 __be32 *p;
124 120
125 BUG_ON(length > XDR_MAX_NETOBJ);
126 p = xdr_reserve_space(xdr, 4 + length); 121 p = xdr_reserve_space(xdr, 4 + length);
127 xdr_encode_opaque(p, data, length); 122 xdr_encode_opaque(p, data, length);
128} 123}
@@ -156,7 +151,6 @@ out_overflow:
156static void encode_cookie(struct xdr_stream *xdr, 151static void encode_cookie(struct xdr_stream *xdr,
157 const struct nlm_cookie *cookie) 152 const struct nlm_cookie *cookie)
158{ 153{
159 BUG_ON(cookie->len > NLM_MAXCOOKIELEN);
160 encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); 154 encode_netobj(xdr, (u8 *)&cookie->data, cookie->len);
161} 155}
162 156
@@ -198,7 +192,6 @@ out_overflow:
198 */ 192 */
199static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) 193static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh)
200{ 194{
201 BUG_ON(fh->size > NFS3_FHSIZE);
202 encode_netobj(xdr, (u8 *)&fh->data, fh->size); 195 encode_netobj(xdr, (u8 *)&fh->data, fh->size);
203} 196}
204 197
@@ -336,7 +329,6 @@ static void encode_caller_name(struct xdr_stream *xdr, const char *name)
336 u32 length = strlen(name); 329 u32 length = strlen(name);
337 __be32 *p; 330 __be32 *p;
338 331
339 BUG_ON(length > NLM_MAXSTRLEN);
340 p = xdr_reserve_space(xdr, 4 + length); 332 p = xdr_reserve_space(xdr, 4 + length);
341 xdr_encode_opaque(p, name, length); 333 xdr_encode_opaque(p, name, length);
342} 334}
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 05d29124c6ab..54f9e6ce0430 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -141,7 +141,7 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
141 141
142static void nlmclnt_release_lockargs(struct nlm_rqst *req) 142static void nlmclnt_release_lockargs(struct nlm_rqst *req)
143{ 143{
144 BUG_ON(req->a_args.lock.fl.fl_ops != NULL); 144 WARN_ON_ONCE(req->a_args.lock.fl.fl_ops != NULL);
145} 145}
146 146
147/** 147/**
@@ -465,7 +465,6 @@ static const struct file_lock_operations nlmclnt_lock_ops = {
465 465
466static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host) 466static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host)
467{ 467{
468 BUG_ON(fl->fl_ops != NULL);
469 fl->fl_u.nfs_fl.state = 0; 468 fl->fl_u.nfs_fl.state = 0;
470 fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner); 469 fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner);
471 INIT_LIST_HEAD(&fl->fl_u.nfs_fl.list); 470 INIT_LIST_HEAD(&fl->fl_u.nfs_fl.list);
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c
index 982d2676e1f8..9a55797a1cd4 100644
--- a/fs/lockd/clntxdr.c
+++ b/fs/lockd/clntxdr.c
@@ -60,10 +60,6 @@ static void nlm_compute_offsets(const struct nlm_lock *lock,
60{ 60{
61 const struct file_lock *fl = &lock->fl; 61 const struct file_lock *fl = &lock->fl;
62 62
63 BUG_ON(fl->fl_start > NLM_OFFSET_MAX);
64 BUG_ON(fl->fl_end > NLM_OFFSET_MAX &&
65 fl->fl_end != OFFSET_MAX);
66
67 *l_offset = loff_t_to_s32(fl->fl_start); 63 *l_offset = loff_t_to_s32(fl->fl_start);
68 if (fl->fl_end == OFFSET_MAX) 64 if (fl->fl_end == OFFSET_MAX)
69 *l_len = 0; 65 *l_len = 0;
@@ -119,7 +115,6 @@ static void encode_netobj(struct xdr_stream *xdr,
119{ 115{
120 __be32 *p; 116 __be32 *p;
121 117
122 BUG_ON(length > XDR_MAX_NETOBJ);
123 p = xdr_reserve_space(xdr, 4 + length); 118 p = xdr_reserve_space(xdr, 4 + length);
124 xdr_encode_opaque(p, data, length); 119 xdr_encode_opaque(p, data, length);
125} 120}
@@ -153,7 +148,6 @@ out_overflow:
153static void encode_cookie(struct xdr_stream *xdr, 148static void encode_cookie(struct xdr_stream *xdr,
154 const struct nlm_cookie *cookie) 149 const struct nlm_cookie *cookie)
155{ 150{
156 BUG_ON(cookie->len > NLM_MAXCOOKIELEN);
157 encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); 151 encode_netobj(xdr, (u8 *)&cookie->data, cookie->len);
158} 152}
159 153
@@ -195,7 +189,6 @@ out_overflow:
195 */ 189 */
196static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) 190static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh)
197{ 191{
198 BUG_ON(fh->size != NFS2_FHSIZE);
199 encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE); 192 encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE);
200} 193}
201 194
@@ -330,7 +323,6 @@ static void encode_caller_name(struct xdr_stream *xdr, const char *name)
330 u32 length = strlen(name); 323 u32 length = strlen(name);
331 __be32 *p; 324 __be32 *p;
332 325
333 BUG_ON(length > NLM_MAXSTRLEN);
334 p = xdr_reserve_space(xdr, 4 + length); 326 p = xdr_reserve_space(xdr, 4 + length);
335 xdr_encode_opaque(p, name, length); 327 xdr_encode_opaque(p, name, length);
336} 328}
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index f9b22e58f78f..0e17090c310f 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -177,9 +177,6 @@ static void nlm_destroy_host_locked(struct nlm_host *host)
177 177
178 dprintk("lockd: destroy host %s\n", host->h_name); 178 dprintk("lockd: destroy host %s\n", host->h_name);
179 179
180 BUG_ON(!list_empty(&host->h_lockowners));
181 BUG_ON(atomic_read(&host->h_count));
182
183 hlist_del_init(&host->h_hash); 180 hlist_del_init(&host->h_hash);
184 181
185 nsm_unmonitor(host); 182 nsm_unmonitor(host);
@@ -289,13 +286,12 @@ void nlmclnt_release_host(struct nlm_host *host)
289 286
290 dprintk("lockd: release client host %s\n", host->h_name); 287 dprintk("lockd: release client host %s\n", host->h_name);
291 288
292 BUG_ON(atomic_read(&host->h_count) < 0); 289 WARN_ON_ONCE(host->h_server);
293 BUG_ON(host->h_server);
294 290
295 if (atomic_dec_and_test(&host->h_count)) { 291 if (atomic_dec_and_test(&host->h_count)) {
296 BUG_ON(!list_empty(&host->h_lockowners)); 292 WARN_ON_ONCE(!list_empty(&host->h_lockowners));
297 BUG_ON(!list_empty(&host->h_granted)); 293 WARN_ON_ONCE(!list_empty(&host->h_granted));
298 BUG_ON(!list_empty(&host->h_reclaim)); 294 WARN_ON_ONCE(!list_empty(&host->h_reclaim));
299 295
300 mutex_lock(&nlm_host_mutex); 296 mutex_lock(&nlm_host_mutex);
301 nlm_destroy_host_locked(host); 297 nlm_destroy_host_locked(host);
@@ -412,8 +408,7 @@ void nlmsvc_release_host(struct nlm_host *host)
412 408
413 dprintk("lockd: release server host %s\n", host->h_name); 409 dprintk("lockd: release server host %s\n", host->h_name);
414 410
415 BUG_ON(atomic_read(&host->h_count) < 0); 411 WARN_ON_ONCE(!host->h_server);
416 BUG_ON(!host->h_server);
417 atomic_dec(&host->h_count); 412 atomic_dec(&host->h_count);
418} 413}
419 414
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 3d7e09bcc0e9..3c2cfc683631 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -154,8 +154,6 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
154 .rpc_resp = res, 154 .rpc_resp = res,
155 }; 155 };
156 156
157 BUG_ON(clnt == NULL);
158
159 memset(res, 0, sizeof(*res)); 157 memset(res, 0, sizeof(*res));
160 158
161 msg.rpc_proc = &clnt->cl_procinfo[proc]; 159 msg.rpc_proc = &clnt->cl_procinfo[proc];
@@ -466,7 +464,6 @@ static void encode_nsm_string(struct xdr_stream *xdr, const char *string)
466 const u32 len = strlen(string); 464 const u32 len = strlen(string);
467 __be32 *p; 465 __be32 *p;
468 466
469 BUG_ON(len > SM_MAXSTRLEN);
470 p = xdr_reserve_space(xdr, 4 + len); 467 p = xdr_reserve_space(xdr, 4 + len);
471 xdr_encode_opaque(p, string, len); 468 xdr_encode_opaque(p, string, len);
472} 469}
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index b7db60897f91..cce2c057bd2d 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -24,7 +24,7 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o
24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ 24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
25 nfs4namespace.o nfs4getroot.o nfs4client.o 25 nfs4namespace.o nfs4getroot.o nfs4client.o
26nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o 26nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
27nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o 27nfsv4-$(CONFIG_NFS_V4_1) += nfs4session.o pnfs.o pnfs_dev.o
28 28
29obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o 29obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
30nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o 30nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index f1027b06a1a9..4fa788c93f46 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -40,6 +40,7 @@
40#include <linux/pagevec.h> 40#include <linux/pagevec.h>
41 41
42#include "../pnfs.h" 42#include "../pnfs.h"
43#include "../nfs4session.h"
43#include "../internal.h" 44#include "../internal.h"
44#include "blocklayout.h" 45#include "blocklayout.h"
45 46
diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index dded26368111..862a2f16db64 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -118,7 +118,6 @@ int nfs_cache_register_sb(struct super_block *sb, struct cache_detail *cd)
118 struct dentry *dir; 118 struct dentry *dir;
119 119
120 dir = rpc_d_lookup_sb(sb, "cache"); 120 dir = rpc_d_lookup_sb(sb, "cache");
121 BUG_ON(dir == NULL);
122 ret = sunrpc_cache_register_pipefs(dir, cd->name, 0600, cd); 121 ret = sunrpc_cache_register_pipefs(dir, cd->name, 0600, cd);
123 dput(dir); 122 dput(dir);
124 return ret; 123 return ret;
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 4251c2ae06ad..efd54f0a4c46 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -142,7 +142,7 @@ extern __be32 nfs4_callback_recallany(struct cb_recallanyargs *args,
142 142
143struct cb_recallslotargs { 143struct cb_recallslotargs {
144 struct sockaddr *crsa_addr; 144 struct sockaddr *crsa_addr;
145 uint32_t crsa_target_max_slots; 145 uint32_t crsa_target_highest_slotid;
146}; 146};
147extern __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, 147extern __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args,
148 void *dummy, 148 void *dummy,
@@ -167,8 +167,6 @@ extern __be32 nfs4_callback_layoutrecall(
167 struct cb_layoutrecallargs *args, 167 struct cb_layoutrecallargs *args,
168 void *dummy, struct cb_process_state *cps); 168 void *dummy, struct cb_process_state *cps);
169 169
170extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
171
172struct cb_devicenotifyitem { 170struct cb_devicenotifyitem {
173 uint32_t cbd_notify_type; 171 uint32_t cbd_notify_type;
174 uint32_t cbd_layout_type; 172 uint32_t cbd_layout_type;
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 76b4a7a3e559..c89b26bc9759 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -14,6 +14,7 @@
14#include "delegation.h" 14#include "delegation.h"
15#include "internal.h" 15#include "internal.h"
16#include "pnfs.h" 16#include "pnfs.h"
17#include "nfs4session.h"
17 18
18#ifdef NFS_DEBUG 19#ifdef NFS_DEBUG
19#define NFSDBG_FACILITY NFSDBG_CALLBACK 20#define NFSDBG_FACILITY NFSDBG_CALLBACK
@@ -216,7 +217,6 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
216 } 217 }
217 pnfs_get_layout_hdr(lo); 218 pnfs_get_layout_hdr(lo);
218 spin_unlock(&ino->i_lock); 219 spin_unlock(&ino->i_lock);
219 BUG_ON(!list_empty(&lo->plh_bulk_recall));
220 list_add(&lo->plh_bulk_recall, &recall_list); 220 list_add(&lo->plh_bulk_recall, &recall_list);
221 } 221 }
222 } 222 }
@@ -562,23 +562,16 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,
562 if (!cps->clp) /* set in cb_sequence */ 562 if (!cps->clp) /* set in cb_sequence */
563 goto out; 563 goto out;
564 564
565 dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target max slots %d\n", 565 dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target highest slotid %d\n",
566 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR), 566 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR),
567 args->crsa_target_max_slots); 567 args->crsa_target_highest_slotid);
568 568
569 fc_tbl = &cps->clp->cl_session->fc_slot_table; 569 fc_tbl = &cps->clp->cl_session->fc_slot_table;
570 570
571 status = htonl(NFS4ERR_BAD_HIGH_SLOT);
572 if (args->crsa_target_max_slots > fc_tbl->max_slots ||
573 args->crsa_target_max_slots < 1)
574 goto out;
575
576 status = htonl(NFS4_OK); 571 status = htonl(NFS4_OK);
577 if (args->crsa_target_max_slots == fc_tbl->max_slots)
578 goto out;
579 572
580 fc_tbl->target_max_slots = args->crsa_target_max_slots; 573 nfs41_set_target_slotid(fc_tbl, args->crsa_target_highest_slotid);
581 nfs41_handle_recall_slot(cps->clp); 574 nfs41_server_notify_target_slotid_update(cps->clp);
582out: 575out:
583 dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); 576 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
584 return status; 577 return status;
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 742ff4ffced7..59461c957d9d 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -16,6 +16,7 @@
16#include "nfs4_fs.h" 16#include "nfs4_fs.h"
17#include "callback.h" 17#include "callback.h"
18#include "internal.h" 18#include "internal.h"
19#include "nfs4session.h"
19 20
20#define CB_OP_TAGLEN_MAXSZ (512) 21#define CB_OP_TAGLEN_MAXSZ (512)
21#define CB_OP_HDR_RES_MAXSZ (2 + CB_OP_TAGLEN_MAXSZ) 22#define CB_OP_HDR_RES_MAXSZ (2 + CB_OP_TAGLEN_MAXSZ)
@@ -520,7 +521,7 @@ static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
520 p = read_buf(xdr, 4); 521 p = read_buf(xdr, 4);
521 if (unlikely(p == NULL)) 522 if (unlikely(p == NULL))
522 return htonl(NFS4ERR_BADXDR); 523 return htonl(NFS4ERR_BADXDR);
523 args->crsa_target_max_slots = ntohl(*p++); 524 args->crsa_target_highest_slotid = ntohl(*p++);
524 return 0; 525 return 0;
525} 526}
526 527
@@ -762,7 +763,7 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
762 * A single slot, so highest used slotid is either 0 or -1 763 * A single slot, so highest used slotid is either 0 or -1
763 */ 764 */
764 tbl->highest_used_slotid = NFS4_NO_SLOT; 765 tbl->highest_used_slotid = NFS4_NO_SLOT;
765 nfs4_check_drain_bc_complete(session); 766 nfs4_session_drain_complete(session, tbl);
766 spin_unlock(&tbl->slot_tbl_lock); 767 spin_unlock(&tbl->slot_tbl_lock);
767} 768}
768 769
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 8b39a42ac35e..9f3c66438d0e 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -277,7 +277,7 @@ void nfs_put_client(struct nfs_client *clp)
277 nfs_cb_idr_remove_locked(clp); 277 nfs_cb_idr_remove_locked(clp);
278 spin_unlock(&nn->nfs_client_lock); 278 spin_unlock(&nn->nfs_client_lock);
279 279
280 BUG_ON(!list_empty(&clp->cl_superblocks)); 280 WARN_ON_ONCE(!list_empty(&clp->cl_superblocks));
281 281
282 clp->rpc_ops->free_client(clp); 282 clp->rpc_ops->free_client(clp);
283 } 283 }
@@ -615,8 +615,7 @@ EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
615 */ 615 */
616static void nfs_destroy_server(struct nfs_server *server) 616static void nfs_destroy_server(struct nfs_server *server)
617{ 617{
618 if (!(server->flags & NFS_MOUNT_LOCAL_FLOCK) || 618 if (server->nlm_host)
619 !(server->flags & NFS_MOUNT_LOCAL_FCNTL))
620 nlmclnt_done(server->nlm_host); 619 nlmclnt_done(server->nlm_host);
621} 620}
622 621
@@ -1061,10 +1060,6 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
1061 if (error < 0) 1060 if (error < 0)
1062 goto error; 1061 goto error;
1063 1062
1064 BUG_ON(!server->nfs_client);
1065 BUG_ON(!server->nfs_client->rpc_ops);
1066 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1067
1068 /* Probe the root fh to retrieve its FSID */ 1063 /* Probe the root fh to retrieve its FSID */
1069 error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr); 1064 error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
1070 if (error < 0) 1065 if (error < 0)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 1cc71f60b491..32e6c53520e2 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -979,10 +979,11 @@ static int nfs_is_exclusive_create(struct inode *dir, unsigned int flags)
979 * particular file and the "nocto" mount flag is not set. 979 * particular file and the "nocto" mount flag is not set.
980 * 980 *
981 */ 981 */
982static inline 982static
983int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags) 983int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
984{ 984{
985 struct nfs_server *server = NFS_SERVER(inode); 985 struct nfs_server *server = NFS_SERVER(inode);
986 int ret;
986 987
987 if (IS_AUTOMOUNT(inode)) 988 if (IS_AUTOMOUNT(inode))
988 return 0; 989 return 0;
@@ -993,9 +994,13 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
993 if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) && 994 if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) &&
994 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) 995 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
995 goto out_force; 996 goto out_force;
996 return 0; 997out:
998 return (inode->i_nlink == 0) ? -ENOENT : 0;
997out_force: 999out_force:
998 return __nfs_revalidate_inode(server, inode); 1000 ret = __nfs_revalidate_inode(server, inode);
1001 if (ret != 0)
1002 return ret;
1003 goto out;
999} 1004}
1000 1005
1001/* 1006/*
@@ -1156,11 +1161,14 @@ static int nfs_dentry_delete(const struct dentry *dentry)
1156 1161
1157} 1162}
1158 1163
1164/* Ensure that we revalidate inode->i_nlink */
1159static void nfs_drop_nlink(struct inode *inode) 1165static void nfs_drop_nlink(struct inode *inode)
1160{ 1166{
1161 spin_lock(&inode->i_lock); 1167 spin_lock(&inode->i_lock);
1162 if (inode->i_nlink > 0) 1168 /* drop the inode if we're reasonably sure this is the last link */
1163 drop_nlink(inode); 1169 if (inode->i_nlink == 1)
1170 clear_nlink(inode);
1171 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
1164 spin_unlock(&inode->i_lock); 1172 spin_unlock(&inode->i_lock);
1165} 1173}
1166 1174
@@ -1175,8 +1183,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
1175 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; 1183 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
1176 1184
1177 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { 1185 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
1178 drop_nlink(inode);
1179 nfs_complete_unlink(dentry, inode); 1186 nfs_complete_unlink(dentry, inode);
1187 nfs_drop_nlink(inode);
1180 } 1188 }
1181 iput(inode); 1189 iput(inode);
1182} 1190}
@@ -1647,10 +1655,8 @@ static int nfs_safe_remove(struct dentry *dentry)
1647 if (inode != NULL) { 1655 if (inode != NULL) {
1648 NFS_PROTO(inode)->return_delegation(inode); 1656 NFS_PROTO(inode)->return_delegation(inode);
1649 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1657 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1650 /* The VFS may want to delete this inode */
1651 if (error == 0) 1658 if (error == 0)
1652 nfs_drop_nlink(inode); 1659 nfs_drop_nlink(inode);
1653 nfs_mark_for_revalidate(inode);
1654 } else 1660 } else
1655 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1661 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1656 if (error == -ENOENT) 1662 if (error == -ENOENT)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index cae26cbd59ee..0bd7a55a5f07 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -266,21 +266,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
266 struct nfs_page *req = nfs_list_entry(hdr->pages.next); 266 struct nfs_page *req = nfs_list_entry(hdr->pages.next);
267 struct page *page = req->wb_page; 267 struct page *page = req->wb_page;
268 268
269 if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) { 269 if (!PageCompound(page) && bytes < hdr->good_bytes)
270 if (bytes > hdr->good_bytes) 270 set_page_dirty(page);
271 zero_user(page, 0, PAGE_SIZE);
272 else if (hdr->good_bytes - bytes < PAGE_SIZE)
273 zero_user_segment(page,
274 hdr->good_bytes & ~PAGE_MASK,
275 PAGE_SIZE);
276 }
277 if (!PageCompound(page)) {
278 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
279 if (bytes < hdr->good_bytes)
280 set_page_dirty(page);
281 } else
282 set_page_dirty(page);
283 }
284 bytes += req->wb_bytes; 271 bytes += req->wb_bytes;
285 nfs_list_remove_request(req); 272 nfs_list_remove_request(req);
286 nfs_direct_readpage_release(req); 273 nfs_direct_readpage_release(req);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6fa01aea2488..2faae14d89f4 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -107,13 +107,19 @@ u64 nfs_compat_user_ino64(u64 fileid)
107 return ino; 107 return ino;
108} 108}
109 109
110int nfs_drop_inode(struct inode *inode)
111{
112 return NFS_STALE(inode) || generic_drop_inode(inode);
113}
114EXPORT_SYMBOL_GPL(nfs_drop_inode);
115
110void nfs_clear_inode(struct inode *inode) 116void nfs_clear_inode(struct inode *inode)
111{ 117{
112 /* 118 /*
113 * The following should never happen... 119 * The following should never happen...
114 */ 120 */
115 BUG_ON(nfs_have_writebacks(inode)); 121 WARN_ON_ONCE(nfs_have_writebacks(inode));
116 BUG_ON(!list_empty(&NFS_I(inode)->open_files)); 122 WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files));
117 nfs_zap_acl_cache(inode); 123 nfs_zap_acl_cache(inode);
118 nfs_access_zap_cache(inode); 124 nfs_access_zap_cache(inode);
119 nfs_fscache_release_inode_cookie(inode); 125 nfs_fscache_release_inode_cookie(inode);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 05521cadac2e..f0e6c7df1a07 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -18,27 +18,6 @@ struct nfs_string;
18 */ 18 */
19#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 19#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
20 20
21/*
22 * Determine if sessions are in use.
23 */
24static inline int nfs4_has_session(const struct nfs_client *clp)
25{
26#ifdef CONFIG_NFS_V4_1
27 if (clp->cl_session)
28 return 1;
29#endif /* CONFIG_NFS_V4_1 */
30 return 0;
31}
32
33static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
34{
35#ifdef CONFIG_NFS_V4_1
36 if (nfs4_has_session(clp))
37 return (clp->cl_session->flags & SESSION4_PERSIST);
38#endif /* CONFIG_NFS_V4_1 */
39 return 0;
40}
41
42static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr) 21static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
43{ 22{
44 if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid)) 23 if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid))
@@ -276,8 +255,6 @@ extern const u32 nfs41_maxwrite_overhead;
276extern struct rpc_procinfo nfs4_procedures[]; 255extern struct rpc_procinfo nfs4_procedures[];
277#endif 256#endif
278 257
279extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
280
281/* proc.c */ 258/* proc.c */
282void nfs_close_context(struct nfs_open_context *ctx, int is_sync); 259void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
283extern struct nfs_client *nfs_init_client(struct nfs_client *clp, 260extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
@@ -319,6 +296,7 @@ extern struct workqueue_struct *nfsiod_workqueue;
319extern struct inode *nfs_alloc_inode(struct super_block *sb); 296extern struct inode *nfs_alloc_inode(struct super_block *sb);
320extern void nfs_destroy_inode(struct inode *); 297extern void nfs_destroy_inode(struct inode *);
321extern int nfs_write_inode(struct inode *, struct writeback_control *); 298extern int nfs_write_inode(struct inode *, struct writeback_control *);
299extern int nfs_drop_inode(struct inode *);
322extern void nfs_clear_inode(struct inode *); 300extern void nfs_clear_inode(struct inode *);
323extern void nfs_evict_inode(struct inode *); 301extern void nfs_evict_inode(struct inode *);
324void nfs_zap_acl_cache(struct inode *inode); 302void nfs_zap_acl_cache(struct inode *inode);
@@ -386,9 +364,6 @@ extern int nfs_initiate_read(struct rpc_clnt *clnt,
386extern void nfs_read_prepare(struct rpc_task *task, void *calldata); 364extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
387extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc, 365extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
388 struct nfs_pgio_header *hdr); 366 struct nfs_pgio_header *hdr);
389extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
390 struct inode *inode,
391 const struct nfs_pgio_completion_ops *compl_ops);
392extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio); 367extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
393extern void nfs_readdata_release(struct nfs_read_data *rdata); 368extern void nfs_readdata_release(struct nfs_read_data *rdata);
394 369
@@ -411,9 +386,6 @@ extern struct nfs_write_header *nfs_writehdr_alloc(void);
411extern void nfs_writehdr_free(struct nfs_pgio_header *hdr); 386extern void nfs_writehdr_free(struct nfs_pgio_header *hdr);
412extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc, 387extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
413 struct nfs_pgio_header *hdr); 388 struct nfs_pgio_header *hdr);
414extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
415 struct inode *inode, int ioflags,
416 const struct nfs_pgio_completion_ops *compl_ops);
417extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio); 389extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
418extern void nfs_writedata_release(struct nfs_write_data *wdata); 390extern void nfs_writedata_release(struct nfs_write_data *wdata);
419extern void nfs_commit_free(struct nfs_commit_data *p); 391extern void nfs_commit_free(struct nfs_commit_data *p);
@@ -474,18 +446,6 @@ extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
474 const struct rpc_timeout *timeparms, 446 const struct rpc_timeout *timeparms,
475 const char *ip_addr, 447 const char *ip_addr,
476 rpc_authflavor_t authflavour); 448 rpc_authflavor_t authflavour);
477extern int _nfs4_call_sync(struct rpc_clnt *clnt,
478 struct nfs_server *server,
479 struct rpc_message *msg,
480 struct nfs4_sequence_args *args,
481 struct nfs4_sequence_res *res,
482 int cache_reply);
483extern int _nfs4_call_sync_session(struct rpc_clnt *clnt,
484 struct nfs_server *server,
485 struct rpc_message *msg,
486 struct nfs4_sequence_args *args,
487 struct nfs4_sequence_res *res,
488 int cache_reply);
489extern int nfs40_walk_client_list(struct nfs_client *clp, 449extern int nfs40_walk_client_list(struct nfs_client *clp,
490 struct nfs_client **result, 450 struct nfs_client **result,
491 struct rpc_cred *cred); 451 struct rpc_cred *cred);
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 015f71f8f62c..91a6faf811ac 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -169,6 +169,9 @@ int nfs_mount(struct nfs_mount_request *info)
169 (info->hostname ? info->hostname : "server"), 169 (info->hostname ? info->hostname : "server"),
170 info->dirpath); 170 info->dirpath);
171 171
172 if (strlen(info->dirpath) > MNTPATHLEN)
173 return -ENAMETOOLONG;
174
172 if (info->noresvport) 175 if (info->noresvport)
173 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; 176 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
174 177
@@ -242,6 +245,9 @@ void nfs_umount(const struct nfs_mount_request *info)
242 struct rpc_clnt *clnt; 245 struct rpc_clnt *clnt;
243 int status; 246 int status;
244 247
248 if (strlen(info->dirpath) > MNTPATHLEN)
249 return;
250
245 if (info->noresvport) 251 if (info->noresvport)
246 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; 252 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
247 253
@@ -283,7 +289,6 @@ static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
283 const u32 pathname_len = strlen(pathname); 289 const u32 pathname_len = strlen(pathname);
284 __be32 *p; 290 __be32 *p;
285 291
286 BUG_ON(pathname_len > MNTPATHLEN);
287 p = xdr_reserve_space(xdr, 4 + pathname_len); 292 p = xdr_reserve_space(xdr, 4 + pathname_len);
288 xdr_encode_opaque(p, pathname, pathname_len); 293 xdr_encode_opaque(p, pathname, pathname_len);
289} 294}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index d04f0df7be55..06b9df49f7f7 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -195,7 +195,6 @@ static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
195{ 195{
196 __be32 *p; 196 __be32 *p;
197 197
198 BUG_ON(fh->size != NFS2_FHSIZE);
199 p = xdr_reserve_space(xdr, NFS2_FHSIZE); 198 p = xdr_reserve_space(xdr, NFS2_FHSIZE);
200 memcpy(p, fh->data, NFS2_FHSIZE); 199 memcpy(p, fh->data, NFS2_FHSIZE);
201} 200}
@@ -388,7 +387,7 @@ static void encode_filename(struct xdr_stream *xdr,
388{ 387{
389 __be32 *p; 388 __be32 *p;
390 389
391 BUG_ON(length > NFS2_MAXNAMLEN); 390 WARN_ON_ONCE(length > NFS2_MAXNAMLEN);
392 p = xdr_reserve_space(xdr, 4 + length); 391 p = xdr_reserve_space(xdr, 4 + length);
393 xdr_encode_opaque(p, name, length); 392 xdr_encode_opaque(p, name, length);
394} 393}
@@ -428,7 +427,6 @@ static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
428{ 427{
429 __be32 *p; 428 __be32 *p;
430 429
431 BUG_ON(length > NFS2_MAXPATHLEN);
432 p = xdr_reserve_space(xdr, 4); 430 p = xdr_reserve_space(xdr, 4);
433 *p = cpu_to_be32(length); 431 *p = cpu_to_be32(length);
434 xdr_write_pages(xdr, pages, 0, length); 432 xdr_write_pages(xdr, pages, 0, length);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 69322096c325..70efb63b1e42 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -24,14 +24,14 @@
24 24
25#define NFSDBG_FACILITY NFSDBG_PROC 25#define NFSDBG_FACILITY NFSDBG_PROC
26 26
27/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */ 27/* A wrapper to handle the EJUKEBOX error messages */
28static int 28static int
29nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) 29nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
30{ 30{
31 int res; 31 int res;
32 do { 32 do {
33 res = rpc_call_sync(clnt, msg, flags); 33 res = rpc_call_sync(clnt, msg, flags);
34 if (res != -EJUKEBOX && res != -EKEYEXPIRED) 34 if (res != -EJUKEBOX)
35 break; 35 break;
36 freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); 36 freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
37 res = -ERESTARTSYS; 37 res = -ERESTARTSYS;
@@ -44,7 +44,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
44static int 44static int
45nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode) 45nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
46{ 46{
47 if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED) 47 if (task->tk_status != -EJUKEBOX)
48 return 0; 48 return 0;
49 if (task->tk_status == -EJUKEBOX) 49 if (task->tk_status == -EJUKEBOX)
50 nfs_inc_stats(inode, NFSIOS_DELAY); 50 nfs_inc_stats(inode, NFSIOS_DELAY);
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 6cbe89400dfc..bffc32406fbf 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -198,7 +198,7 @@ static void encode_filename3(struct xdr_stream *xdr,
198{ 198{
199 __be32 *p; 199 __be32 *p;
200 200
201 BUG_ON(length > NFS3_MAXNAMLEN); 201 WARN_ON_ONCE(length > NFS3_MAXNAMLEN);
202 p = xdr_reserve_space(xdr, 4 + length); 202 p = xdr_reserve_space(xdr, 4 + length);
203 xdr_encode_opaque(p, name, length); 203 xdr_encode_opaque(p, name, length);
204} 204}
@@ -238,7 +238,6 @@ out_overflow:
238static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, 238static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
239 const u32 length) 239 const u32 length)
240{ 240{
241 BUG_ON(length > NFS3_MAXPATHLEN);
242 encode_uint32(xdr, length); 241 encode_uint32(xdr, length);
243 xdr_write_pages(xdr, pages, 0, length); 242 xdr_write_pages(xdr, pages, 0, length);
244} 243}
@@ -388,7 +387,6 @@ out_overflow:
388 */ 387 */
389static void encode_ftype3(struct xdr_stream *xdr, const u32 type) 388static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
390{ 389{
391 BUG_ON(type > NF3FIFO);
392 encode_uint32(xdr, type); 390 encode_uint32(xdr, type);
393} 391}
394 392
@@ -443,7 +441,7 @@ static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
443{ 441{
444 __be32 *p; 442 __be32 *p;
445 443
446 BUG_ON(fh->size > NFS3_FHSIZE); 444 WARN_ON_ONCE(fh->size > NFS3_FHSIZE);
447 p = xdr_reserve_space(xdr, 4 + fh->size); 445 p = xdr_reserve_space(xdr, 4 + fh->size);
448 xdr_encode_opaque(p, fh->data, fh->size); 446 xdr_encode_opaque(p, fh->data, fh->size);
449} 447}
@@ -1339,6 +1337,7 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
1339 error = nfsacl_encode(xdr->buf, base, args->inode, 1337 error = nfsacl_encode(xdr->buf, base, args->inode,
1340 (args->mask & NFS_ACL) ? 1338 (args->mask & NFS_ACL) ?
1341 args->acl_access : NULL, 1, 0); 1339 args->acl_access : NULL, 1, 0);
1340 /* FIXME: this is just broken */
1342 BUG_ON(error < 0); 1341 BUG_ON(error < 0);
1343 error = nfsacl_encode(xdr->buf, base + error, args->inode, 1342 error = nfsacl_encode(xdr->buf, base + error, args->inode,
1344 (args->mask & NFS_DFACL) ? 1343 (args->mask & NFS_DFACL) ?
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index a525fdefccde..a3f488b074a2 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -11,6 +11,8 @@
11 11
12#if IS_ENABLED(CONFIG_NFS_V4) 12#if IS_ENABLED(CONFIG_NFS_V4)
13 13
14#define NFS4_MAX_LOOP_ON_RECOVER (10)
15
14struct idmap; 16struct idmap;
15 17
16enum nfs4_client_state { 18enum nfs4_client_state {
@@ -21,18 +23,12 @@ enum nfs4_client_state {
21 NFS4CLNT_RECLAIM_NOGRACE, 23 NFS4CLNT_RECLAIM_NOGRACE,
22 NFS4CLNT_DELEGRETURN, 24 NFS4CLNT_DELEGRETURN,
23 NFS4CLNT_SESSION_RESET, 25 NFS4CLNT_SESSION_RESET,
24 NFS4CLNT_RECALL_SLOT,
25 NFS4CLNT_LEASE_CONFIRM, 26 NFS4CLNT_LEASE_CONFIRM,
26 NFS4CLNT_SERVER_SCOPE_MISMATCH, 27 NFS4CLNT_SERVER_SCOPE_MISMATCH,
27 NFS4CLNT_PURGE_STATE, 28 NFS4CLNT_PURGE_STATE,
28 NFS4CLNT_BIND_CONN_TO_SESSION, 29 NFS4CLNT_BIND_CONN_TO_SESSION,
29}; 30};
30 31
31enum nfs4_session_state {
32 NFS4_SESSION_INITING,
33 NFS4_SESSION_DRAINING,
34};
35
36#define NFS4_RENEW_TIMEOUT 0x01 32#define NFS4_RENEW_TIMEOUT 0x01
37#define NFS4_RENEW_DELEGATION_CB 0x02 33#define NFS4_RENEW_DELEGATION_CB 0x02
38 34
@@ -43,8 +39,7 @@ struct nfs4_minor_version_ops {
43 struct nfs_server *server, 39 struct nfs_server *server,
44 struct rpc_message *msg, 40 struct rpc_message *msg,
45 struct nfs4_sequence_args *args, 41 struct nfs4_sequence_args *args,
46 struct nfs4_sequence_res *res, 42 struct nfs4_sequence_res *res);
47 int cache_reply);
48 bool (*match_stateid)(const nfs4_stateid *, 43 bool (*match_stateid)(const nfs4_stateid *,
49 const nfs4_stateid *); 44 const nfs4_stateid *);
50 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *, 45 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
@@ -241,18 +236,14 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *ser
241 return server->nfs_client->cl_session; 236 return server->nfs_client->cl_session;
242} 237}
243 238
244extern bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy);
245extern int nfs4_setup_sequence(const struct nfs_server *server, 239extern int nfs4_setup_sequence(const struct nfs_server *server,
246 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 240 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
247 struct rpc_task *task); 241 struct rpc_task *task);
248extern int nfs41_setup_sequence(struct nfs4_session *session, 242extern int nfs41_setup_sequence(struct nfs4_session *session,
249 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 243 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
250 struct rpc_task *task); 244 struct rpc_task *task);
251extern void nfs4_destroy_session(struct nfs4_session *session);
252extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
253extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *); 245extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *);
254extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *); 246extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *);
255extern int nfs4_init_session(struct nfs_server *server);
256extern int nfs4_proc_get_lease_time(struct nfs_client *clp, 247extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
257 struct nfs_fsinfo *fsinfo); 248 struct nfs_fsinfo *fsinfo);
258extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, 249extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
@@ -280,11 +271,7 @@ static inline int nfs4_setup_sequence(const struct nfs_server *server,
280 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 271 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
281 struct rpc_task *task) 272 struct rpc_task *task)
282{ 273{
283 return 0; 274 rpc_call_start(task);
284}
285
286static inline int nfs4_init_session(struct nfs_server *server)
287{
288 return 0; 275 return 0;
289} 276}
290 277
@@ -321,17 +308,20 @@ extern void nfs4_renew_state(struct work_struct *);
321 308
322/* nfs4state.c */ 309/* nfs4state.c */
323struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp); 310struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
311struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
324struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp); 312struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
325int nfs4_discover_server_trunking(struct nfs_client *clp, 313int nfs4_discover_server_trunking(struct nfs_client *clp,
326 struct nfs_client **); 314 struct nfs_client **);
327int nfs40_discover_server_trunking(struct nfs_client *clp, 315int nfs40_discover_server_trunking(struct nfs_client *clp,
328 struct nfs_client **, struct rpc_cred *); 316 struct nfs_client **, struct rpc_cred *);
329#if defined(CONFIG_NFS_V4_1) 317#if defined(CONFIG_NFS_V4_1)
330struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
331struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp); 318struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
332int nfs41_discover_server_trunking(struct nfs_client *clp, 319int nfs41_discover_server_trunking(struct nfs_client *clp,
333 struct nfs_client **, struct rpc_cred *); 320 struct nfs_client **, struct rpc_cred *);
334extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); 321extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
322extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
323extern void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp);
324
335#else 325#else
336static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) 326static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
337{ 327{
@@ -349,11 +339,12 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
349extern void nfs_inode_find_state_and_recover(struct inode *inode, 339extern void nfs_inode_find_state_and_recover(struct inode *inode,
350 const nfs4_stateid *stateid); 340 const nfs4_stateid *stateid);
351extern void nfs4_schedule_lease_recovery(struct nfs_client *); 341extern void nfs4_schedule_lease_recovery(struct nfs_client *);
342extern int nfs4_wait_clnt_recover(struct nfs_client *clp);
343extern int nfs4_client_recover_expired_lease(struct nfs_client *clp);
352extern void nfs4_schedule_state_manager(struct nfs_client *); 344extern void nfs4_schedule_state_manager(struct nfs_client *);
353extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); 345extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
354extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); 346extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
355extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); 347extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
356extern void nfs41_handle_recall_slot(struct nfs_client *clp);
357extern void nfs41_handle_server_scope(struct nfs_client *, 348extern void nfs41_handle_server_scope(struct nfs_client *,
358 struct nfs41_server_scope **); 349 struct nfs41_server_scope **);
359extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 350extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 6bacfde1319a..acc347268124 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -12,6 +12,7 @@
12#include "internal.h" 12#include "internal.h"
13#include "callback.h" 13#include "callback.h"
14#include "delegation.h" 14#include "delegation.h"
15#include "nfs4session.h"
15#include "pnfs.h" 16#include "pnfs.h"
16#include "netns.h" 17#include "netns.h"
17 18
@@ -713,10 +714,6 @@ static int nfs4_server_common_setup(struct nfs_server *server,
713 struct nfs_fattr *fattr; 714 struct nfs_fattr *fattr;
714 int error; 715 int error;
715 716
716 BUG_ON(!server->nfs_client);
717 BUG_ON(!server->nfs_client->rpc_ops);
718 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
719
720 /* data servers support only a subset of NFSv4.1 */ 717 /* data servers support only a subset of NFSv4.1 */
721 if (is_ds_only_client(server->nfs_client)) 718 if (is_ds_only_client(server->nfs_client))
722 return -EPROTONOSUPPORT; 719 return -EPROTONOSUPPORT;
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index afddd6639afb..e7699308364a 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -20,7 +20,6 @@ nfs4_file_open(struct inode *inode, struct file *filp)
20 struct iattr attr; 20 struct iattr attr;
21 int err; 21 int err;
22 22
23 BUG_ON(inode != dentry->d_inode);
24 /* 23 /*
25 * If no cached dentry exists or if it's negative, NFSv4 handled the 24 * If no cached dentry exists or if it's negative, NFSv4 handled the
26 * opens in ->lookup() or ->create(). 25 * opens in ->lookup() or ->create().
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 2e45fd9c02a3..194c48410336 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -35,6 +35,7 @@
35 35
36#include <linux/sunrpc/metrics.h> 36#include <linux/sunrpc/metrics.h>
37 37
38#include "nfs4session.h"
38#include "internal.h" 39#include "internal.h"
39#include "delegation.h" 40#include "delegation.h"
40#include "nfs4filelayout.h" 41#include "nfs4filelayout.h"
@@ -178,7 +179,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
178 break; 179 break;
179 case -NFS4ERR_DELAY: 180 case -NFS4ERR_DELAY:
180 case -NFS4ERR_GRACE: 181 case -NFS4ERR_GRACE:
181 case -EKEYEXPIRED:
182 rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX); 182 rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX);
183 break; 183 break;
184 case -NFS4ERR_RETRY_UNCACHED_REP: 184 case -NFS4ERR_RETRY_UNCACHED_REP:
@@ -306,12 +306,10 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
306 } 306 }
307 rdata->read_done_cb = filelayout_read_done_cb; 307 rdata->read_done_cb = filelayout_read_done_cb;
308 308
309 if (nfs41_setup_sequence(rdata->ds_clp->cl_session, 309 nfs41_setup_sequence(rdata->ds_clp->cl_session,
310 &rdata->args.seq_args, &rdata->res.seq_res, 310 &rdata->args.seq_args,
311 task)) 311 &rdata->res.seq_res,
312 return; 312 task);
313
314 rpc_call_start(task);
315} 313}
316 314
317static void filelayout_read_call_done(struct rpc_task *task, void *data) 315static void filelayout_read_call_done(struct rpc_task *task, void *data)
@@ -408,12 +406,10 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
408 rpc_exit(task, 0); 406 rpc_exit(task, 0);
409 return; 407 return;
410 } 408 }
411 if (nfs41_setup_sequence(wdata->ds_clp->cl_session, 409 nfs41_setup_sequence(wdata->ds_clp->cl_session,
412 &wdata->args.seq_args, &wdata->res.seq_res, 410 &wdata->args.seq_args,
413 task)) 411 &wdata->res.seq_res,
414 return; 412 task);
415
416 rpc_call_start(task);
417} 413}
418 414
419static void filelayout_write_call_done(struct rpc_task *task, void *data) 415static void filelayout_write_call_done(struct rpc_task *task, void *data)
@@ -449,12 +445,10 @@ static void filelayout_commit_prepare(struct rpc_task *task, void *data)
449{ 445{
450 struct nfs_commit_data *wdata = data; 446 struct nfs_commit_data *wdata = data;
451 447
452 if (nfs41_setup_sequence(wdata->ds_clp->cl_session, 448 nfs41_setup_sequence(wdata->ds_clp->cl_session,
453 &wdata->args.seq_args, &wdata->res.seq_res, 449 &wdata->args.seq_args,
454 task)) 450 &wdata->res.seq_res,
455 return; 451 task);
456
457 rpc_call_start(task);
458} 452}
459 453
460static void filelayout_write_commit_done(struct rpc_task *task, void *data) 454static void filelayout_write_commit_done(struct rpc_task *task, void *data)
@@ -512,7 +506,6 @@ filelayout_read_pagelist(struct nfs_read_data *data)
512 loff_t offset = data->args.offset; 506 loff_t offset = data->args.offset;
513 u32 j, idx; 507 u32 j, idx;
514 struct nfs_fh *fh; 508 struct nfs_fh *fh;
515 int status;
516 509
517 dprintk("--> %s ino %lu pgbase %u req %Zu@%llu\n", 510 dprintk("--> %s ino %lu pgbase %u req %Zu@%llu\n",
518 __func__, hdr->inode->i_ino, 511 __func__, hdr->inode->i_ino,
@@ -538,9 +531,8 @@ filelayout_read_pagelist(struct nfs_read_data *data)
538 data->mds_offset = offset; 531 data->mds_offset = offset;
539 532
540 /* Perform an asynchronous read to ds */ 533 /* Perform an asynchronous read to ds */
541 status = nfs_initiate_read(ds->ds_clp->cl_rpcclient, data, 534 nfs_initiate_read(ds->ds_clp->cl_rpcclient, data,
542 &filelayout_read_call_ops, RPC_TASK_SOFTCONN); 535 &filelayout_read_call_ops, RPC_TASK_SOFTCONN);
543 BUG_ON(status != 0);
544 return PNFS_ATTEMPTED; 536 return PNFS_ATTEMPTED;
545} 537}
546 538
@@ -554,7 +546,6 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
554 loff_t offset = data->args.offset; 546 loff_t offset = data->args.offset;
555 u32 j, idx; 547 u32 j, idx;
556 struct nfs_fh *fh; 548 struct nfs_fh *fh;
557 int status;
558 549
559 /* Retrieve the correct rpc_client for the byte range */ 550 /* Retrieve the correct rpc_client for the byte range */
560 j = nfs4_fl_calc_j_index(lseg, offset); 551 j = nfs4_fl_calc_j_index(lseg, offset);
@@ -579,10 +570,9 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
579 data->args.offset = filelayout_get_dserver_offset(lseg, offset); 570 data->args.offset = filelayout_get_dserver_offset(lseg, offset);
580 571
581 /* Perform an asynchronous write */ 572 /* Perform an asynchronous write */
582 status = nfs_initiate_write(ds->ds_clp->cl_rpcclient, data, 573 nfs_initiate_write(ds->ds_clp->cl_rpcclient, data,
583 &filelayout_write_call_ops, sync, 574 &filelayout_write_call_ops, sync,
584 RPC_TASK_SOFTCONN); 575 RPC_TASK_SOFTCONN);
585 BUG_ON(status != 0);
586 return PNFS_ATTEMPTED; 576 return PNFS_ATTEMPTED;
587} 577}
588 578
@@ -909,7 +899,7 @@ static void
909filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, 899filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
910 struct nfs_page *req) 900 struct nfs_page *req)
911{ 901{
912 BUG_ON(pgio->pg_lseg != NULL); 902 WARN_ON_ONCE(pgio->pg_lseg != NULL);
913 903
914 if (req->wb_offset != req->wb_pgbase) { 904 if (req->wb_offset != req->wb_pgbase) {
915 /* 905 /*
@@ -939,7 +929,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
939 struct nfs_commit_info cinfo; 929 struct nfs_commit_info cinfo;
940 int status; 930 int status;
941 931
942 BUG_ON(pgio->pg_lseg != NULL); 932 WARN_ON_ONCE(pgio->pg_lseg != NULL);
943 933
944 if (req->wb_offset != req->wb_pgbase) 934 if (req->wb_offset != req->wb_pgbase)
945 goto out_mds; 935 goto out_mds;
@@ -1187,7 +1177,6 @@ static void filelayout_recover_commit_reqs(struct list_head *dst,
1187 */ 1177 */
1188 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) { 1178 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
1189 if (transfer_commit_list(&b->written, dst, cinfo, 0)) { 1179 if (transfer_commit_list(&b->written, dst, cinfo, 0)) {
1190 BUG_ON(!list_empty(&b->written));
1191 pnfs_put_lseg(b->wlseg); 1180 pnfs_put_lseg(b->wlseg);
1192 b->wlseg = NULL; 1181 b->wlseg = NULL;
1193 } 1182 }
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index a8eaa9b7bb0f..b720064bcd7f 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34 34
35#include "internal.h" 35#include "internal.h"
36#include "nfs4session.h"
36#include "nfs4filelayout.h" 37#include "nfs4filelayout.h"
37 38
38#define NFSDBG_FACILITY NFSDBG_PNFS_LD 39#define NFSDBG_FACILITY NFSDBG_PNFS_LD
@@ -162,8 +163,6 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
162 dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr, 163 dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
163 mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor); 164 mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor);
164 165
165 BUG_ON(list_empty(&ds->ds_addrs));
166
167 list_for_each_entry(da, &ds->ds_addrs, da_node) { 166 list_for_each_entry(da, &ds->ds_addrs, da_node) {
168 dprintk("%s: DS %s: trying address %s\n", 167 dprintk("%s: DS %s: trying address %s\n",
169 __func__, ds->ds_remotestr, da->da_remotestr); 168 __func__, ds->ds_remotestr, da->da_remotestr);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5eec4429970c..493f0f41c554 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -52,7 +52,6 @@
52#include <linux/mount.h> 52#include <linux/mount.h>
53#include <linux/module.h> 53#include <linux/module.h>
54#include <linux/nfs_idmap.h> 54#include <linux/nfs_idmap.h>
55#include <linux/sunrpc/bc_xprt.h>
56#include <linux/xattr.h> 55#include <linux/xattr.h>
57#include <linux/utsname.h> 56#include <linux/utsname.h>
58#include <linux/freezer.h> 57#include <linux/freezer.h>
@@ -64,14 +63,14 @@
64#include "callback.h" 63#include "callback.h"
65#include "pnfs.h" 64#include "pnfs.h"
66#include "netns.h" 65#include "netns.h"
66#include "nfs4session.h"
67
67 68
68#define NFSDBG_FACILITY NFSDBG_PROC 69#define NFSDBG_FACILITY NFSDBG_PROC
69 70
70#define NFS4_POLL_RETRY_MIN (HZ/10) 71#define NFS4_POLL_RETRY_MIN (HZ/10)
71#define NFS4_POLL_RETRY_MAX (15*HZ) 72#define NFS4_POLL_RETRY_MAX (15*HZ)
72 73
73#define NFS4_MAX_LOOP_ON_RECOVER (10)
74
75struct nfs4_opendata; 74struct nfs4_opendata;
76static int _nfs4_proc_open(struct nfs4_opendata *data); 75static int _nfs4_proc_open(struct nfs4_opendata *data);
77static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 76static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
@@ -206,7 +205,6 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
206{ 205{
207 __be32 *start, *p; 206 __be32 *start, *p;
208 207
209 BUG_ON(readdir->count < 80);
210 if (cookie > 2) { 208 if (cookie > 2) {
211 readdir->cookie = cookie; 209 readdir->cookie = cookie;
212 memcpy(&readdir->verifier, verifier, sizeof(readdir->verifier)); 210 memcpy(&readdir->verifier, verifier, sizeof(readdir->verifier));
@@ -256,22 +254,6 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
256 kunmap_atomic(start); 254 kunmap_atomic(start);
257} 255}
258 256
259static int nfs4_wait_clnt_recover(struct nfs_client *clp)
260{
261 int res;
262
263 might_sleep();
264
265 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
266 nfs_wait_bit_killable, TASK_KILLABLE);
267 if (res)
268 return res;
269
270 if (clp->cl_cons_state < 0)
271 return clp->cl_cons_state;
272 return 0;
273}
274
275static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) 257static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
276{ 258{
277 int res = 0; 259 int res = 0;
@@ -351,7 +333,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
351 } 333 }
352 case -NFS4ERR_GRACE: 334 case -NFS4ERR_GRACE:
353 case -NFS4ERR_DELAY: 335 case -NFS4ERR_DELAY:
354 case -EKEYEXPIRED:
355 ret = nfs4_delay(server->client, &exception->timeout); 336 ret = nfs4_delay(server->client, &exception->timeout);
356 if (ret != 0) 337 if (ret != 0)
357 break; 338 break;
@@ -397,144 +378,136 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
397 378
398#if defined(CONFIG_NFS_V4_1) 379#if defined(CONFIG_NFS_V4_1)
399 380
400/*
401 * nfs4_free_slot - free a slot and efficiently update slot table.
402 *
403 * freeing a slot is trivially done by clearing its respective bit
404 * in the bitmap.
405 * If the freed slotid equals highest_used_slotid we want to update it
406 * so that the server would be able to size down the slot table if needed,
407 * otherwise we know that the highest_used_slotid is still in use.
408 * When updating highest_used_slotid there may be "holes" in the bitmap
409 * so we need to scan down from highest_used_slotid to 0 looking for the now
410 * highest slotid in use.
411 * If none found, highest_used_slotid is set to NFS4_NO_SLOT.
412 *
413 * Must be called while holding tbl->slot_tbl_lock
414 */
415static void
416nfs4_free_slot(struct nfs4_slot_table *tbl, u32 slotid)
417{
418 BUG_ON(slotid >= NFS4_MAX_SLOT_TABLE);
419 /* clear used bit in bitmap */
420 __clear_bit(slotid, tbl->used_slots);
421
422 /* update highest_used_slotid when it is freed */
423 if (slotid == tbl->highest_used_slotid) {
424 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
425 if (slotid < tbl->max_slots)
426 tbl->highest_used_slotid = slotid;
427 else
428 tbl->highest_used_slotid = NFS4_NO_SLOT;
429 }
430 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
431 slotid, tbl->highest_used_slotid);
432}
433
434bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy)
435{
436 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
437 return true;
438}
439
440/*
441 * Signal state manager thread if session fore channel is drained
442 */
443static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
444{
445 if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
446 rpc_wake_up_first(&ses->fc_slot_table.slot_tbl_waitq,
447 nfs4_set_task_privileged, NULL);
448 return;
449 }
450
451 if (ses->fc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
452 return;
453
454 dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__);
455 complete(&ses->fc_slot_table.complete);
456}
457
458/*
459 * Signal state manager thread if session back channel is drained
460 */
461void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
462{
463 if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) ||
464 ses->bc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
465 return;
466 dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__);
467 complete(&ses->bc_slot_table.complete);
468}
469
470static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) 381static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
471{ 382{
383 struct nfs4_session *session;
472 struct nfs4_slot_table *tbl; 384 struct nfs4_slot_table *tbl;
385 bool send_new_highest_used_slotid = false;
473 386
474 tbl = &res->sr_session->fc_slot_table;
475 if (!res->sr_slot) { 387 if (!res->sr_slot) {
476 /* just wake up the next guy waiting since 388 /* just wake up the next guy waiting since
477 * we may have not consumed a slot after all */ 389 * we may have not consumed a slot after all */
478 dprintk("%s: No slot\n", __func__); 390 dprintk("%s: No slot\n", __func__);
479 return; 391 return;
480 } 392 }
393 tbl = res->sr_slot->table;
394 session = tbl->session;
481 395
482 spin_lock(&tbl->slot_tbl_lock); 396 spin_lock(&tbl->slot_tbl_lock);
483 nfs4_free_slot(tbl, res->sr_slot - tbl->slots); 397 /* Be nice to the server: try to ensure that the last transmitted
484 nfs4_check_drain_fc_complete(res->sr_session); 398 * value for highest_user_slotid <= target_highest_slotid
399 */
400 if (tbl->highest_used_slotid > tbl->target_highest_slotid)
401 send_new_highest_used_slotid = true;
402
403 if (nfs41_wake_and_assign_slot(tbl, res->sr_slot)) {
404 send_new_highest_used_slotid = false;
405 goto out_unlock;
406 }
407 nfs4_free_slot(tbl, res->sr_slot);
408
409 if (tbl->highest_used_slotid != NFS4_NO_SLOT)
410 send_new_highest_used_slotid = false;
411out_unlock:
485 spin_unlock(&tbl->slot_tbl_lock); 412 spin_unlock(&tbl->slot_tbl_lock);
486 res->sr_slot = NULL; 413 res->sr_slot = NULL;
414 if (send_new_highest_used_slotid)
415 nfs41_server_notify_highest_slotid_update(session->clp);
487} 416}
488 417
489static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 418static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
490{ 419{
491 unsigned long timestamp; 420 struct nfs4_session *session;
421 struct nfs4_slot *slot;
492 struct nfs_client *clp; 422 struct nfs_client *clp;
493 423 bool interrupted = false;
494 /* 424 int ret = 1;
495 * sr_status remains 1 if an RPC level error occurred. The server
496 * may or may not have processed the sequence operation..
497 * Proceed as if the server received and processed the sequence
498 * operation.
499 */
500 if (res->sr_status == 1)
501 res->sr_status = NFS_OK;
502 425
503 /* don't increment the sequence number if the task wasn't sent */ 426 /* don't increment the sequence number if the task wasn't sent */
504 if (!RPC_WAS_SENT(task)) 427 if (!RPC_WAS_SENT(task))
505 goto out; 428 goto out;
506 429
430 slot = res->sr_slot;
431 session = slot->table->session;
432
433 if (slot->interrupted) {
434 slot->interrupted = 0;
435 interrupted = true;
436 }
437
507 /* Check the SEQUENCE operation status */ 438 /* Check the SEQUENCE operation status */
508 switch (res->sr_status) { 439 switch (res->sr_status) {
509 case 0: 440 case 0:
510 /* Update the slot's sequence and clientid lease timer */ 441 /* Update the slot's sequence and clientid lease timer */
511 ++res->sr_slot->seq_nr; 442 ++slot->seq_nr;
512 timestamp = res->sr_renewal_time; 443 clp = session->clp;
513 clp = res->sr_session->clp; 444 do_renew_lease(clp, res->sr_timestamp);
514 do_renew_lease(clp, timestamp);
515 /* Check sequence flags */ 445 /* Check sequence flags */
516 if (res->sr_status_flags != 0) 446 if (res->sr_status_flags != 0)
517 nfs4_schedule_lease_recovery(clp); 447 nfs4_schedule_lease_recovery(clp);
448 nfs41_update_target_slotid(slot->table, slot, res);
518 break; 449 break;
450 case 1:
451 /*
452 * sr_status remains 1 if an RPC level error occurred.
453 * The server may or may not have processed the sequence
454 * operation..
455 * Mark the slot as having hosted an interrupted RPC call.
456 */
457 slot->interrupted = 1;
458 goto out;
519 case -NFS4ERR_DELAY: 459 case -NFS4ERR_DELAY:
520 /* The server detected a resend of the RPC call and 460 /* The server detected a resend of the RPC call and
521 * returned NFS4ERR_DELAY as per Section 2.10.6.2 461 * returned NFS4ERR_DELAY as per Section 2.10.6.2
522 * of RFC5661. 462 * of RFC5661.
523 */ 463 */
524 dprintk("%s: slot=%td seq=%d: Operation in progress\n", 464 dprintk("%s: slot=%u seq=%u: Operation in progress\n",
525 __func__, 465 __func__,
526 res->sr_slot - res->sr_session->fc_slot_table.slots, 466 slot->slot_nr,
527 res->sr_slot->seq_nr); 467 slot->seq_nr);
528 goto out_retry; 468 goto out_retry;
469 case -NFS4ERR_BADSLOT:
470 /*
471 * The slot id we used was probably retired. Try again
472 * using a different slot id.
473 */
474 goto retry_nowait;
475 case -NFS4ERR_SEQ_MISORDERED:
476 /*
477 * Was the last operation on this sequence interrupted?
478 * If so, retry after bumping the sequence number.
479 */
480 if (interrupted) {
481 ++slot->seq_nr;
482 goto retry_nowait;
483 }
484 /*
485 * Could this slot have been previously retired?
486 * If so, then the server may be expecting seq_nr = 1!
487 */
488 if (slot->seq_nr != 1) {
489 slot->seq_nr = 1;
490 goto retry_nowait;
491 }
492 break;
493 case -NFS4ERR_SEQ_FALSE_RETRY:
494 ++slot->seq_nr;
495 goto retry_nowait;
529 default: 496 default:
530 /* Just update the slot sequence no. */ 497 /* Just update the slot sequence no. */
531 ++res->sr_slot->seq_nr; 498 ++slot->seq_nr;
532 } 499 }
533out: 500out:
534 /* The session may be reset by one of the error handlers. */ 501 /* The session may be reset by one of the error handlers. */
535 dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); 502 dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
536 nfs41_sequence_free_slot(res); 503 nfs41_sequence_free_slot(res);
537 return 1; 504 return ret;
505retry_nowait:
506 if (rpc_restart_call_prepare(task)) {
507 task->tk_status = 0;
508 ret = 0;
509 }
510 goto out;
538out_retry: 511out_retry:
539 if (!rpc_restart_call(task)) 512 if (!rpc_restart_call(task))
540 goto out; 513 goto out;
@@ -545,55 +518,27 @@ out_retry:
545static int nfs4_sequence_done(struct rpc_task *task, 518static int nfs4_sequence_done(struct rpc_task *task,
546 struct nfs4_sequence_res *res) 519 struct nfs4_sequence_res *res)
547{ 520{
548 if (res->sr_session == NULL) 521 if (res->sr_slot == NULL)
549 return 1; 522 return 1;
550 return nfs41_sequence_done(task, res); 523 return nfs41_sequence_done(task, res);
551} 524}
552 525
553/*
554 * nfs4_find_slot - efficiently look for a free slot
555 *
556 * nfs4_find_slot looks for an unset bit in the used_slots bitmap.
557 * If found, we mark the slot as used, update the highest_used_slotid,
558 * and respectively set up the sequence operation args.
559 * The slot number is returned if found, or NFS4_NO_SLOT otherwise.
560 *
561 * Note: must be called with under the slot_tbl_lock.
562 */
563static u32
564nfs4_find_slot(struct nfs4_slot_table *tbl)
565{
566 u32 slotid;
567 u32 ret_id = NFS4_NO_SLOT;
568
569 dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
570 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
571 tbl->max_slots);
572 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots);
573 if (slotid >= tbl->max_slots)
574 goto out;
575 __set_bit(slotid, tbl->used_slots);
576 if (slotid > tbl->highest_used_slotid ||
577 tbl->highest_used_slotid == NFS4_NO_SLOT)
578 tbl->highest_used_slotid = slotid;
579 ret_id = slotid;
580out:
581 dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
582 __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id);
583 return ret_id;
584}
585
586static void nfs41_init_sequence(struct nfs4_sequence_args *args, 526static void nfs41_init_sequence(struct nfs4_sequence_args *args,
587 struct nfs4_sequence_res *res, int cache_reply) 527 struct nfs4_sequence_res *res, int cache_reply)
588{ 528{
589 args->sa_session = NULL; 529 args->sa_slot = NULL;
590 args->sa_cache_this = 0; 530 args->sa_cache_this = 0;
531 args->sa_privileged = 0;
591 if (cache_reply) 532 if (cache_reply)
592 args->sa_cache_this = 1; 533 args->sa_cache_this = 1;
593 res->sr_session = NULL;
594 res->sr_slot = NULL; 534 res->sr_slot = NULL;
595} 535}
596 536
537static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
538{
539 args->sa_privileged = 1;
540}
541
597int nfs41_setup_sequence(struct nfs4_session *session, 542int nfs41_setup_sequence(struct nfs4_session *session,
598 struct nfs4_sequence_args *args, 543 struct nfs4_sequence_args *args,
599 struct nfs4_sequence_res *res, 544 struct nfs4_sequence_res *res,
@@ -601,59 +546,59 @@ int nfs41_setup_sequence(struct nfs4_session *session,
601{ 546{
602 struct nfs4_slot *slot; 547 struct nfs4_slot *slot;
603 struct nfs4_slot_table *tbl; 548 struct nfs4_slot_table *tbl;
604 u32 slotid;
605 549
606 dprintk("--> %s\n", __func__); 550 dprintk("--> %s\n", __func__);
607 /* slot already allocated? */ 551 /* slot already allocated? */
608 if (res->sr_slot != NULL) 552 if (res->sr_slot != NULL)
609 return 0; 553 goto out_success;
610 554
611 tbl = &session->fc_slot_table; 555 tbl = &session->fc_slot_table;
612 556
557 task->tk_timeout = 0;
558
613 spin_lock(&tbl->slot_tbl_lock); 559 spin_lock(&tbl->slot_tbl_lock);
614 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && 560 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) &&
615 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { 561 !args->sa_privileged) {
616 /* The state manager will wait until the slot table is empty */ 562 /* The state manager will wait until the slot table is empty */
617 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
618 spin_unlock(&tbl->slot_tbl_lock);
619 dprintk("%s session is draining\n", __func__); 563 dprintk("%s session is draining\n", __func__);
620 return -EAGAIN; 564 goto out_sleep;
621 } 565 }
622 566
623 if (!rpc_queue_empty(&tbl->slot_tbl_waitq) && 567 slot = nfs4_alloc_slot(tbl);
624 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { 568 if (IS_ERR(slot)) {
625 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 569 /* If out of memory, try again in 1/4 second */
626 spin_unlock(&tbl->slot_tbl_lock); 570 if (slot == ERR_PTR(-ENOMEM))
627 dprintk("%s enforce FIFO order\n", __func__); 571 task->tk_timeout = HZ >> 2;
628 return -EAGAIN;
629 }
630
631 slotid = nfs4_find_slot(tbl);
632 if (slotid == NFS4_NO_SLOT) {
633 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
634 spin_unlock(&tbl->slot_tbl_lock);
635 dprintk("<-- %s: no free slots\n", __func__); 572 dprintk("<-- %s: no free slots\n", __func__);
636 return -EAGAIN; 573 goto out_sleep;
637 } 574 }
638 spin_unlock(&tbl->slot_tbl_lock); 575 spin_unlock(&tbl->slot_tbl_lock);
639 576
640 rpc_task_set_priority(task, RPC_PRIORITY_NORMAL); 577 args->sa_slot = slot;
641 slot = tbl->slots + slotid;
642 args->sa_session = session;
643 args->sa_slotid = slotid;
644 578
645 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr); 579 dprintk("<-- %s slotid=%d seqid=%d\n", __func__,
580 slot->slot_nr, slot->seq_nr);
646 581
647 res->sr_session = session;
648 res->sr_slot = slot; 582 res->sr_slot = slot;
649 res->sr_renewal_time = jiffies; 583 res->sr_timestamp = jiffies;
650 res->sr_status_flags = 0; 584 res->sr_status_flags = 0;
651 /* 585 /*
652 * sr_status is only set in decode_sequence, and so will remain 586 * sr_status is only set in decode_sequence, and so will remain
653 * set to 1 if an rpc level failure occurs. 587 * set to 1 if an rpc level failure occurs.
654 */ 588 */
655 res->sr_status = 1; 589 res->sr_status = 1;
590out_success:
591 rpc_call_start(task);
656 return 0; 592 return 0;
593out_sleep:
594 /* Privileged tasks are queued with top priority */
595 if (args->sa_privileged)
596 rpc_sleep_on_priority(&tbl->slot_tbl_waitq, task,
597 NULL, RPC_PRIORITY_PRIVILEGED);
598 else
599 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
600 spin_unlock(&tbl->slot_tbl_lock);
601 return -EAGAIN;
657} 602}
658EXPORT_SYMBOL_GPL(nfs41_setup_sequence); 603EXPORT_SYMBOL_GPL(nfs41_setup_sequence);
659 604
@@ -665,12 +610,14 @@ int nfs4_setup_sequence(const struct nfs_server *server,
665 struct nfs4_session *session = nfs4_get_session(server); 610 struct nfs4_session *session = nfs4_get_session(server);
666 int ret = 0; 611 int ret = 0;
667 612
668 if (session == NULL) 613 if (session == NULL) {
614 rpc_call_start(task);
669 goto out; 615 goto out;
616 }
670 617
671 dprintk("--> %s clp %p session %p sr_slot %td\n", 618 dprintk("--> %s clp %p session %p sr_slot %d\n",
672 __func__, session->clp, session, res->sr_slot ? 619 __func__, session->clp, session, res->sr_slot ?
673 res->sr_slot - session->fc_slot_table.slots : -1); 620 res->sr_slot->slot_nr : -1);
674 621
675 ret = nfs41_setup_sequence(session, args, res, task); 622 ret = nfs41_setup_sequence(session, args, res, task);
676out: 623out:
@@ -687,19 +634,11 @@ struct nfs41_call_sync_data {
687static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata) 634static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
688{ 635{
689 struct nfs41_call_sync_data *data = calldata; 636 struct nfs41_call_sync_data *data = calldata;
637 struct nfs4_session *session = nfs4_get_session(data->seq_server);
690 638
691 dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server); 639 dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);
692 640
693 if (nfs4_setup_sequence(data->seq_server, data->seq_args, 641 nfs41_setup_sequence(session, data->seq_args, data->seq_res, task);
694 data->seq_res, task))
695 return;
696 rpc_call_start(task);
697}
698
699static void nfs41_call_priv_sync_prepare(struct rpc_task *task, void *calldata)
700{
701 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
702 nfs41_call_sync_prepare(task, calldata);
703} 642}
704 643
705static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 644static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
@@ -714,17 +653,11 @@ static const struct rpc_call_ops nfs41_call_sync_ops = {
714 .rpc_call_done = nfs41_call_sync_done, 653 .rpc_call_done = nfs41_call_sync_done,
715}; 654};
716 655
717static const struct rpc_call_ops nfs41_call_priv_sync_ops = {
718 .rpc_call_prepare = nfs41_call_priv_sync_prepare,
719 .rpc_call_done = nfs41_call_sync_done,
720};
721
722static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, 656static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
723 struct nfs_server *server, 657 struct nfs_server *server,
724 struct rpc_message *msg, 658 struct rpc_message *msg,
725 struct nfs4_sequence_args *args, 659 struct nfs4_sequence_args *args,
726 struct nfs4_sequence_res *res, 660 struct nfs4_sequence_res *res)
727 int privileged)
728{ 661{
729 int ret; 662 int ret;
730 struct rpc_task *task; 663 struct rpc_task *task;
@@ -740,8 +673,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
740 .callback_data = &data 673 .callback_data = &data
741 }; 674 };
742 675
743 if (privileged)
744 task_setup.callback_ops = &nfs41_call_priv_sync_ops;
745 task = rpc_run_task(&task_setup); 676 task = rpc_run_task(&task_setup);
746 if (IS_ERR(task)) 677 if (IS_ERR(task))
747 ret = PTR_ERR(task); 678 ret = PTR_ERR(task);
@@ -752,24 +683,18 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
752 return ret; 683 return ret;
753} 684}
754 685
755int _nfs4_call_sync_session(struct rpc_clnt *clnt,
756 struct nfs_server *server,
757 struct rpc_message *msg,
758 struct nfs4_sequence_args *args,
759 struct nfs4_sequence_res *res,
760 int cache_reply)
761{
762 nfs41_init_sequence(args, res, cache_reply);
763 return nfs4_call_sync_sequence(clnt, server, msg, args, res, 0);
764}
765
766#else 686#else
767static inline 687static
768void nfs41_init_sequence(struct nfs4_sequence_args *args, 688void nfs41_init_sequence(struct nfs4_sequence_args *args,
769 struct nfs4_sequence_res *res, int cache_reply) 689 struct nfs4_sequence_res *res, int cache_reply)
770{ 690{
771} 691}
772 692
693static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
694{
695}
696
697
773static int nfs4_sequence_done(struct rpc_task *task, 698static int nfs4_sequence_done(struct rpc_task *task,
774 struct nfs4_sequence_res *res) 699 struct nfs4_sequence_res *res)
775{ 700{
@@ -777,18 +702,17 @@ static int nfs4_sequence_done(struct rpc_task *task,
777} 702}
778#endif /* CONFIG_NFS_V4_1 */ 703#endif /* CONFIG_NFS_V4_1 */
779 704
705static
780int _nfs4_call_sync(struct rpc_clnt *clnt, 706int _nfs4_call_sync(struct rpc_clnt *clnt,
781 struct nfs_server *server, 707 struct nfs_server *server,
782 struct rpc_message *msg, 708 struct rpc_message *msg,
783 struct nfs4_sequence_args *args, 709 struct nfs4_sequence_args *args,
784 struct nfs4_sequence_res *res, 710 struct nfs4_sequence_res *res)
785 int cache_reply)
786{ 711{
787 nfs41_init_sequence(args, res, cache_reply);
788 return rpc_call_sync(clnt, msg, 0); 712 return rpc_call_sync(clnt, msg, 0);
789} 713}
790 714
791static inline 715static
792int nfs4_call_sync(struct rpc_clnt *clnt, 716int nfs4_call_sync(struct rpc_clnt *clnt,
793 struct nfs_server *server, 717 struct nfs_server *server,
794 struct rpc_message *msg, 718 struct rpc_message *msg,
@@ -796,8 +720,9 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
796 struct nfs4_sequence_res *res, 720 struct nfs4_sequence_res *res,
797 int cache_reply) 721 int cache_reply)
798{ 722{
723 nfs41_init_sequence(args, res, cache_reply);
799 return server->nfs_client->cl_mvops->call_sync(clnt, server, msg, 724 return server->nfs_client->cl_mvops->call_sync(clnt, server, msg,
800 args, res, cache_reply); 725 args, res);
801} 726}
802 727
803static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 728static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
@@ -1445,13 +1370,6 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1445 nfs_inode_find_state_and_recover(state->inode, 1370 nfs_inode_find_state_and_recover(state->inode,
1446 stateid); 1371 stateid);
1447 nfs4_schedule_stateid_recovery(server, state); 1372 nfs4_schedule_stateid_recovery(server, state);
1448 case -EKEYEXPIRED:
1449 /*
1450 * User RPCSEC_GSS context has expired.
1451 * We cannot recover this stateid now, so
1452 * skip it and allow recovery thread to
1453 * proceed.
1454 */
1455 case -ENOMEM: 1373 case -ENOMEM:
1456 err = 0; 1374 err = 0;
1457 goto out; 1375 goto out;
@@ -1574,20 +1492,12 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1574 &data->o_res.seq_res, 1492 &data->o_res.seq_res,
1575 task) != 0) 1493 task) != 0)
1576 nfs_release_seqid(data->o_arg.seqid); 1494 nfs_release_seqid(data->o_arg.seqid);
1577 else
1578 rpc_call_start(task);
1579 return; 1495 return;
1580unlock_no_action: 1496unlock_no_action:
1581 rcu_read_unlock(); 1497 rcu_read_unlock();
1582out_no_action: 1498out_no_action:
1583 task->tk_action = NULL; 1499 task->tk_action = NULL;
1584 1500 nfs4_sequence_done(task, &data->o_res.seq_res);
1585}
1586
1587static void nfs4_recover_open_prepare(struct rpc_task *task, void *calldata)
1588{
1589 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
1590 nfs4_open_prepare(task, calldata);
1591} 1501}
1592 1502
1593static void nfs4_open_done(struct rpc_task *task, void *calldata) 1503static void nfs4_open_done(struct rpc_task *task, void *calldata)
@@ -1648,12 +1558,6 @@ static const struct rpc_call_ops nfs4_open_ops = {
1648 .rpc_release = nfs4_open_release, 1558 .rpc_release = nfs4_open_release,
1649}; 1559};
1650 1560
1651static const struct rpc_call_ops nfs4_recover_open_ops = {
1652 .rpc_call_prepare = nfs4_recover_open_prepare,
1653 .rpc_call_done = nfs4_open_done,
1654 .rpc_release = nfs4_open_release,
1655};
1656
1657static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover) 1561static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1658{ 1562{
1659 struct inode *dir = data->dir->d_inode; 1563 struct inode *dir = data->dir->d_inode;
@@ -1683,7 +1587,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1683 data->rpc_status = 0; 1587 data->rpc_status = 0;
1684 data->cancelled = 0; 1588 data->cancelled = 0;
1685 if (isrecover) 1589 if (isrecover)
1686 task_setup_data.callback_ops = &nfs4_recover_open_ops; 1590 nfs4_set_sequence_privileged(&o_arg->seq_args);
1687 task = rpc_run_task(&task_setup_data); 1591 task = rpc_run_task(&task_setup_data);
1688 if (IS_ERR(task)) 1592 if (IS_ERR(task))
1689 return PTR_ERR(task); 1593 return PTR_ERR(task);
@@ -1789,24 +1693,6 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1789 return 0; 1693 return 0;
1790} 1694}
1791 1695
1792static int nfs4_client_recover_expired_lease(struct nfs_client *clp)
1793{
1794 unsigned int loop;
1795 int ret;
1796
1797 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
1798 ret = nfs4_wait_clnt_recover(clp);
1799 if (ret != 0)
1800 break;
1801 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1802 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
1803 break;
1804 nfs4_schedule_state_manager(clp);
1805 ret = -EIO;
1806 }
1807 return ret;
1808}
1809
1810static int nfs4_recover_expired_lease(struct nfs_server *server) 1696static int nfs4_recover_expired_lease(struct nfs_server *server)
1811{ 1697{
1812 return nfs4_client_recover_expired_lease(server->nfs_client); 1698 return nfs4_client_recover_expired_lease(server->nfs_client);
@@ -2282,6 +2168,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2282 if (!call_close) { 2168 if (!call_close) {
2283 /* Note: exit _without_ calling nfs4_close_done */ 2169 /* Note: exit _without_ calling nfs4_close_done */
2284 task->tk_action = NULL; 2170 task->tk_action = NULL;
2171 nfs4_sequence_done(task, &calldata->res.seq_res);
2285 goto out; 2172 goto out;
2286 } 2173 }
2287 2174
@@ -2299,8 +2186,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2299 &calldata->res.seq_res, 2186 &calldata->res.seq_res,
2300 task) != 0) 2187 task) != 0)
2301 nfs_release_seqid(calldata->arg.seqid); 2188 nfs_release_seqid(calldata->arg.seqid);
2302 else
2303 rpc_call_start(task);
2304out: 2189out:
2305 dprintk("%s: done!\n", __func__); 2190 dprintk("%s: done!\n", __func__);
2306} 2191}
@@ -2533,7 +2418,8 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2533 rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS]; 2418 rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS];
2534 2419
2535 len = rpcauth_list_flavors(flav_array, ARRAY_SIZE(flav_array)); 2420 len = rpcauth_list_flavors(flav_array, ARRAY_SIZE(flav_array));
2536 BUG_ON(len < 0); 2421 if (len < 0)
2422 return len;
2537 2423
2538 for (i = 0; i < len; i++) { 2424 for (i = 0; i < len; i++) {
2539 /* AUTH_UNIX is the default flavor if none was specified, 2425 /* AUTH_UNIX is the default flavor if none was specified,
@@ -3038,12 +2924,10 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
3038 2924
3039static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data) 2925static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
3040{ 2926{
3041 if (nfs4_setup_sequence(NFS_SERVER(data->dir), 2927 nfs4_setup_sequence(NFS_SERVER(data->dir),
3042 &data->args.seq_args, 2928 &data->args.seq_args,
3043 &data->res.seq_res, 2929 &data->res.seq_res,
3044 task)) 2930 task);
3045 return;
3046 rpc_call_start(task);
3047} 2931}
3048 2932
3049static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) 2933static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
@@ -3071,12 +2955,10 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
3071 2955
3072static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data) 2956static void nfs4_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
3073{ 2957{
3074 if (nfs4_setup_sequence(NFS_SERVER(data->old_dir), 2958 nfs4_setup_sequence(NFS_SERVER(data->old_dir),
3075 &data->args.seq_args, 2959 &data->args.seq_args,
3076 &data->res.seq_res, 2960 &data->res.seq_res,
3077 task)) 2961 task);
3078 return;
3079 rpc_call_start(task);
3080} 2962}
3081 2963
3082static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, 2964static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
@@ -3362,9 +3244,6 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3362 int mode = sattr->ia_mode; 3244 int mode = sattr->ia_mode;
3363 int status = -ENOMEM; 3245 int status = -ENOMEM;
3364 3246
3365 BUG_ON(!(sattr->ia_valid & ATTR_MODE));
3366 BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode));
3367
3368 data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4SOCK); 3247 data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4SOCK);
3369 if (data == NULL) 3248 if (data == NULL)
3370 goto out; 3249 goto out;
@@ -3380,10 +3259,13 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3380 data->arg.ftype = NF4CHR; 3259 data->arg.ftype = NF4CHR;
3381 data->arg.u.device.specdata1 = MAJOR(rdev); 3260 data->arg.u.device.specdata1 = MAJOR(rdev);
3382 data->arg.u.device.specdata2 = MINOR(rdev); 3261 data->arg.u.device.specdata2 = MINOR(rdev);
3262 } else if (!S_ISSOCK(mode)) {
3263 status = -EINVAL;
3264 goto out_free;
3383 } 3265 }
3384 3266
3385 status = nfs4_do_create(dir, dentry, data); 3267 status = nfs4_do_create(dir, dentry, data);
3386 3268out_free:
3387 nfs4_free_createdata(data); 3269 nfs4_free_createdata(data);
3388out: 3270out:
3389 return status; 3271 return status;
@@ -3565,12 +3447,10 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
3565 3447
3566static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 3448static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
3567{ 3449{
3568 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), 3450 nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3569 &data->args.seq_args, 3451 &data->args.seq_args,
3570 &data->res.seq_res, 3452 &data->res.seq_res,
3571 task)) 3453 task);
3572 return;
3573 rpc_call_start(task);
3574} 3454}
3575 3455
3576static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) 3456static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
@@ -3631,22 +3511,18 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
3631 3511
3632static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 3512static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
3633{ 3513{
3634 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), 3514 nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3635 &data->args.seq_args, 3515 &data->args.seq_args,
3636 &data->res.seq_res, 3516 &data->res.seq_res,
3637 task)) 3517 task);
3638 return;
3639 rpc_call_start(task);
3640} 3518}
3641 3519
3642static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) 3520static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
3643{ 3521{
3644 if (nfs4_setup_sequence(NFS_SERVER(data->inode), 3522 nfs4_setup_sequence(NFS_SERVER(data->inode),
3645 &data->args.seq_args, 3523 &data->args.seq_args,
3646 &data->res.seq_res, 3524 &data->res.seq_res,
3647 task)) 3525 task);
3648 return;
3649 rpc_call_start(task);
3650} 3526}
3651 3527
3652static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *data) 3528static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *data)
@@ -3937,8 +3813,13 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3937 goto out_free; 3813 goto out_free;
3938 } 3814 }
3939 nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); 3815 nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len);
3940 if (buf) 3816 if (buf) {
3817 if (res.acl_len > buflen) {
3818 ret = -ERANGE;
3819 goto out_free;
3820 }
3941 _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); 3821 _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len);
3822 }
3942out_ok: 3823out_ok:
3943 ret = res.acl_len; 3824 ret = res.acl_len;
3944out_free: 3825out_free:
@@ -4085,7 +3966,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
4085 case -NFS4ERR_DELAY: 3966 case -NFS4ERR_DELAY:
4086 nfs_inc_server_stats(server, NFSIOS_DELAY); 3967 nfs_inc_server_stats(server, NFSIOS_DELAY);
4087 case -NFS4ERR_GRACE: 3968 case -NFS4ERR_GRACE:
4088 case -EKEYEXPIRED:
4089 rpc_delay(task, NFS4_POLL_RETRY_MAX); 3969 rpc_delay(task, NFS4_POLL_RETRY_MAX);
4090 task->tk_status = 0; 3970 task->tk_status = 0;
4091 return -EAGAIN; 3971 return -EAGAIN;
@@ -4293,11 +4173,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
4293 4173
4294 d_data = (struct nfs4_delegreturndata *)data; 4174 d_data = (struct nfs4_delegreturndata *)data;
4295 4175
4296 if (nfs4_setup_sequence(d_data->res.server, 4176 nfs4_setup_sequence(d_data->res.server,
4297 &d_data->args.seq_args, 4177 &d_data->args.seq_args,
4298 &d_data->res.seq_res, task)) 4178 &d_data->res.seq_res,
4299 return; 4179 task);
4300 rpc_call_start(task);
4301} 4180}
4302#endif /* CONFIG_NFS_V4_1 */ 4181#endif /* CONFIG_NFS_V4_1 */
4303 4182
@@ -4543,6 +4422,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
4543 if (test_bit(NFS_LOCK_INITIALIZED, &calldata->lsp->ls_flags) == 0) { 4422 if (test_bit(NFS_LOCK_INITIALIZED, &calldata->lsp->ls_flags) == 0) {
4544 /* Note: exit _without_ running nfs4_locku_done */ 4423 /* Note: exit _without_ running nfs4_locku_done */
4545 task->tk_action = NULL; 4424 task->tk_action = NULL;
4425 nfs4_sequence_done(task, &calldata->res.seq_res);
4546 return; 4426 return;
4547 } 4427 }
4548 calldata->timestamp = jiffies; 4428 calldata->timestamp = jiffies;
@@ -4551,8 +4431,6 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
4551 &calldata->res.seq_res, 4431 &calldata->res.seq_res,
4552 task) != 0) 4432 task) != 0)
4553 nfs_release_seqid(calldata->arg.seqid); 4433 nfs_release_seqid(calldata->arg.seqid);
4554 else
4555 rpc_call_start(task);
4556} 4434}
4557 4435
4558static const struct rpc_call_ops nfs4_locku_ops = { 4436static const struct rpc_call_ops nfs4_locku_ops = {
@@ -4696,8 +4574,9 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
4696 return; 4574 return;
4697 /* Do we need to do an open_to_lock_owner? */ 4575 /* Do we need to do an open_to_lock_owner? */
4698 if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { 4576 if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
4699 if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) 4577 if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) {
4700 goto out_release_lock_seqid; 4578 goto out_release_lock_seqid;
4579 }
4701 data->arg.open_stateid = &state->stateid; 4580 data->arg.open_stateid = &state->stateid;
4702 data->arg.new_lock_owner = 1; 4581 data->arg.new_lock_owner = 1;
4703 data->res.open_seqid = data->arg.open_seqid; 4582 data->res.open_seqid = data->arg.open_seqid;
@@ -4707,20 +4586,12 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
4707 if (nfs4_setup_sequence(data->server, 4586 if (nfs4_setup_sequence(data->server,
4708 &data->arg.seq_args, 4587 &data->arg.seq_args,
4709 &data->res.seq_res, 4588 &data->res.seq_res,
4710 task) == 0) { 4589 task) == 0)
4711 rpc_call_start(task);
4712 return; 4590 return;
4713 }
4714 nfs_release_seqid(data->arg.open_seqid); 4591 nfs_release_seqid(data->arg.open_seqid);
4715out_release_lock_seqid: 4592out_release_lock_seqid:
4716 nfs_release_seqid(data->arg.lock_seqid); 4593 nfs_release_seqid(data->arg.lock_seqid);
4717 dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); 4594 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
4718}
4719
4720static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
4721{
4722 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4723 nfs4_lock_prepare(task, calldata);
4724} 4595}
4725 4596
4726static void nfs4_lock_done(struct rpc_task *task, void *calldata) 4597static void nfs4_lock_done(struct rpc_task *task, void *calldata)
@@ -4775,12 +4646,6 @@ static const struct rpc_call_ops nfs4_lock_ops = {
4775 .rpc_release = nfs4_lock_release, 4646 .rpc_release = nfs4_lock_release,
4776}; 4647};
4777 4648
4778static const struct rpc_call_ops nfs4_recover_lock_ops = {
4779 .rpc_call_prepare = nfs4_recover_lock_prepare,
4780 .rpc_call_done = nfs4_lock_done,
4781 .rpc_release = nfs4_lock_release,
4782};
4783
4784static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) 4649static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
4785{ 4650{
4786 switch (error) { 4651 switch (error) {
@@ -4823,15 +4688,15 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4823 return -ENOMEM; 4688 return -ENOMEM;
4824 if (IS_SETLKW(cmd)) 4689 if (IS_SETLKW(cmd))
4825 data->arg.block = 1; 4690 data->arg.block = 1;
4826 if (recovery_type > NFS_LOCK_NEW) {
4827 if (recovery_type == NFS_LOCK_RECLAIM)
4828 data->arg.reclaim = NFS_LOCK_RECLAIM;
4829 task_setup_data.callback_ops = &nfs4_recover_lock_ops;
4830 }
4831 nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1); 4691 nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
4832 msg.rpc_argp = &data->arg; 4692 msg.rpc_argp = &data->arg;
4833 msg.rpc_resp = &data->res; 4693 msg.rpc_resp = &data->res;
4834 task_setup_data.callback_data = data; 4694 task_setup_data.callback_data = data;
4695 if (recovery_type > NFS_LOCK_NEW) {
4696 if (recovery_type == NFS_LOCK_RECLAIM)
4697 data->arg.reclaim = NFS_LOCK_RECLAIM;
4698 nfs4_set_sequence_privileged(&data->arg.seq_args);
4699 }
4835 task = rpc_run_task(&task_setup_data); 4700 task = rpc_run_task(&task_setup_data);
4836 if (IS_ERR(task)) 4701 if (IS_ERR(task))
4837 return PTR_ERR(task); 4702 return PTR_ERR(task);
@@ -5100,15 +4965,6 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
5100 nfs4_schedule_stateid_recovery(server, state); 4965 nfs4_schedule_stateid_recovery(server, state);
5101 err = 0; 4966 err = 0;
5102 goto out; 4967 goto out;
5103 case -EKEYEXPIRED:
5104 /*
5105 * User RPCSEC_GSS context has expired.
5106 * We cannot recover this stateid now, so
5107 * skip it and allow recovery thread to
5108 * proceed.
5109 */
5110 err = 0;
5111 goto out;
5112 case -ENOMEM: 4968 case -ENOMEM:
5113 case -NFS4ERR_DENIED: 4969 case -NFS4ERR_DENIED:
5114 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 4970 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
@@ -5357,7 +5213,6 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred
5357 }; 5213 };
5358 5214
5359 dprintk("--> %s\n", __func__); 5215 dprintk("--> %s\n", __func__);
5360 BUG_ON(clp == NULL);
5361 5216
5362 res.session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); 5217 res.session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
5363 if (unlikely(res.session == NULL)) { 5218 if (unlikely(res.session == NULL)) {
@@ -5569,20 +5424,16 @@ struct nfs4_get_lease_time_data {
5569static void nfs4_get_lease_time_prepare(struct rpc_task *task, 5424static void nfs4_get_lease_time_prepare(struct rpc_task *task,
5570 void *calldata) 5425 void *calldata)
5571{ 5426{
5572 int ret;
5573 struct nfs4_get_lease_time_data *data = 5427 struct nfs4_get_lease_time_data *data =
5574 (struct nfs4_get_lease_time_data *)calldata; 5428 (struct nfs4_get_lease_time_data *)calldata;
5575 5429
5576 dprintk("--> %s\n", __func__); 5430 dprintk("--> %s\n", __func__);
5577 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
5578 /* just setup sequence, do not trigger session recovery 5431 /* just setup sequence, do not trigger session recovery
5579 since we're invoked within one */ 5432 since we're invoked within one */
5580 ret = nfs41_setup_sequence(data->clp->cl_session, 5433 nfs41_setup_sequence(data->clp->cl_session,
5581 &data->args->la_seq_args, 5434 &data->args->la_seq_args,
5582 &data->res->lr_seq_res, task); 5435 &data->res->lr_seq_res,
5583 5436 task);
5584 BUG_ON(ret == -EAGAIN);
5585 rpc_call_start(task);
5586 dprintk("<-- %s\n", __func__); 5437 dprintk("<-- %s\n", __func__);
5587} 5438}
5588 5439
@@ -5644,6 +5495,7 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
5644 int status; 5495 int status;
5645 5496
5646 nfs41_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0); 5497 nfs41_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0);
5498 nfs4_set_sequence_privileged(&args.la_seq_args);
5647 dprintk("--> %s\n", __func__); 5499 dprintk("--> %s\n", __func__);
5648 task = rpc_run_task(&task_setup); 5500 task = rpc_run_task(&task_setup);
5649 5501
@@ -5658,145 +5510,6 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
5658 return status; 5510 return status;
5659} 5511}
5660 5512
5661static struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags)
5662{
5663 return kcalloc(max_slots, sizeof(struct nfs4_slot), gfp_flags);
5664}
5665
5666static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
5667 struct nfs4_slot *new,
5668 u32 max_slots,
5669 u32 ivalue)
5670{
5671 struct nfs4_slot *old = NULL;
5672 u32 i;
5673
5674 spin_lock(&tbl->slot_tbl_lock);
5675 if (new) {
5676 old = tbl->slots;
5677 tbl->slots = new;
5678 tbl->max_slots = max_slots;
5679 }
5680 tbl->highest_used_slotid = NFS4_NO_SLOT;
5681 for (i = 0; i < tbl->max_slots; i++)
5682 tbl->slots[i].seq_nr = ivalue;
5683 spin_unlock(&tbl->slot_tbl_lock);
5684 kfree(old);
5685}
5686
5687/*
5688 * (re)Initialise a slot table
5689 */
5690static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
5691 u32 ivalue)
5692{
5693 struct nfs4_slot *new = NULL;
5694 int ret = -ENOMEM;
5695
5696 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
5697 max_reqs, tbl->max_slots);
5698
5699 /* Does the newly negotiated max_reqs match the existing slot table? */
5700 if (max_reqs != tbl->max_slots) {
5701 new = nfs4_alloc_slots(max_reqs, GFP_NOFS);
5702 if (!new)
5703 goto out;
5704 }
5705 ret = 0;
5706
5707 nfs4_add_and_init_slots(tbl, new, max_reqs, ivalue);
5708 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
5709 tbl, tbl->slots, tbl->max_slots);
5710out:
5711 dprintk("<-- %s: return %d\n", __func__, ret);
5712 return ret;
5713}
5714
5715/* Destroy the slot table */
5716static void nfs4_destroy_slot_tables(struct nfs4_session *session)
5717{
5718 if (session->fc_slot_table.slots != NULL) {
5719 kfree(session->fc_slot_table.slots);
5720 session->fc_slot_table.slots = NULL;
5721 }
5722 if (session->bc_slot_table.slots != NULL) {
5723 kfree(session->bc_slot_table.slots);
5724 session->bc_slot_table.slots = NULL;
5725 }
5726 return;
5727}
5728
5729/*
5730 * Initialize or reset the forechannel and backchannel tables
5731 */
5732static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
5733{
5734 struct nfs4_slot_table *tbl;
5735 int status;
5736
5737 dprintk("--> %s\n", __func__);
5738 /* Fore channel */
5739 tbl = &ses->fc_slot_table;
5740 status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5741 if (status) /* -ENOMEM */
5742 return status;
5743 /* Back channel */
5744 tbl = &ses->bc_slot_table;
5745 status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5746 if (status && tbl->slots == NULL)
5747 /* Fore and back channel share a connection so get
5748 * both slot tables or neither */
5749 nfs4_destroy_slot_tables(ses);
5750 return status;
5751}
5752
5753struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
5754{
5755 struct nfs4_session *session;
5756 struct nfs4_slot_table *tbl;
5757
5758 session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
5759 if (!session)
5760 return NULL;
5761
5762 tbl = &session->fc_slot_table;
5763 tbl->highest_used_slotid = NFS4_NO_SLOT;
5764 spin_lock_init(&tbl->slot_tbl_lock);
5765 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
5766 init_completion(&tbl->complete);
5767
5768 tbl = &session->bc_slot_table;
5769 tbl->highest_used_slotid = NFS4_NO_SLOT;
5770 spin_lock_init(&tbl->slot_tbl_lock);
5771 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
5772 init_completion(&tbl->complete);
5773
5774 session->session_state = 1<<NFS4_SESSION_INITING;
5775
5776 session->clp = clp;
5777 return session;
5778}
5779
5780void nfs4_destroy_session(struct nfs4_session *session)
5781{
5782 struct rpc_xprt *xprt;
5783 struct rpc_cred *cred;
5784
5785 cred = nfs4_get_exchange_id_cred(session->clp);
5786 nfs4_proc_destroy_session(session, cred);
5787 if (cred)
5788 put_rpccred(cred);
5789
5790 rcu_read_lock();
5791 xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
5792 rcu_read_unlock();
5793 dprintk("%s Destroy backchannel for xprt %p\n",
5794 __func__, xprt);
5795 xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
5796 nfs4_destroy_slot_tables(session);
5797 kfree(session);
5798}
5799
5800/* 5513/*
5801 * Initialize the values to be used by the client in CREATE_SESSION 5514 * Initialize the values to be used by the client in CREATE_SESSION
5802 * If nfs4_init_session set the fore channel request and response sizes, 5515 * If nfs4_init_session set the fore channel request and response sizes,
@@ -5809,8 +5522,8 @@ void nfs4_destroy_session(struct nfs4_session *session)
5809static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) 5522static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
5810{ 5523{
5811 struct nfs4_session *session = args->client->cl_session; 5524 struct nfs4_session *session = args->client->cl_session;
5812 unsigned int mxrqst_sz = session->fc_attrs.max_rqst_sz, 5525 unsigned int mxrqst_sz = session->fc_target_max_rqst_sz,
5813 mxresp_sz = session->fc_attrs.max_resp_sz; 5526 mxresp_sz = session->fc_target_max_resp_sz;
5814 5527
5815 if (mxrqst_sz == 0) 5528 if (mxrqst_sz == 0)
5816 mxrqst_sz = NFS_MAX_FILE_IO_SIZE; 5529 mxrqst_sz = NFS_MAX_FILE_IO_SIZE;
@@ -5919,10 +5632,9 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
5919 5632
5920 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5633 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5921 5634
5922 if (!status) 5635 if (!status) {
5923 /* Verify the session's negotiated channel_attrs values */ 5636 /* Verify the session's negotiated channel_attrs values */
5924 status = nfs4_verify_channel_attrs(&args, session); 5637 status = nfs4_verify_channel_attrs(&args, session);
5925 if (!status) {
5926 /* Increment the clientid slot sequence id */ 5638 /* Increment the clientid slot sequence id */
5927 clp->cl_seqid++; 5639 clp->cl_seqid++;
5928 } 5640 }
@@ -5992,83 +5704,6 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
5992} 5704}
5993 5705
5994/* 5706/*
5995 * With sessions, the client is not marked ready until after a
5996 * successful EXCHANGE_ID and CREATE_SESSION.
5997 *
5998 * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
5999 * other versions of NFS can be tried.
6000 */
6001static int nfs41_check_session_ready(struct nfs_client *clp)
6002{
6003 int ret;
6004
6005 if (clp->cl_cons_state == NFS_CS_SESSION_INITING) {
6006 ret = nfs4_client_recover_expired_lease(clp);
6007 if (ret)
6008 return ret;
6009 }
6010 if (clp->cl_cons_state < NFS_CS_READY)
6011 return -EPROTONOSUPPORT;
6012 smp_rmb();
6013 return 0;
6014}
6015
6016int nfs4_init_session(struct nfs_server *server)
6017{
6018 struct nfs_client *clp = server->nfs_client;
6019 struct nfs4_session *session;
6020 unsigned int rsize, wsize;
6021
6022 if (!nfs4_has_session(clp))
6023 return 0;
6024
6025 session = clp->cl_session;
6026 spin_lock(&clp->cl_lock);
6027 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
6028
6029 rsize = server->rsize;
6030 if (rsize == 0)
6031 rsize = NFS_MAX_FILE_IO_SIZE;
6032 wsize = server->wsize;
6033 if (wsize == 0)
6034 wsize = NFS_MAX_FILE_IO_SIZE;
6035
6036 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
6037 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
6038 }
6039 spin_unlock(&clp->cl_lock);
6040
6041 return nfs41_check_session_ready(clp);
6042}
6043
6044int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time)
6045{
6046 struct nfs4_session *session = clp->cl_session;
6047 int ret;
6048
6049 spin_lock(&clp->cl_lock);
6050 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
6051 /*
6052 * Do not set NFS_CS_CHECK_LEASE_TIME instead set the
6053 * DS lease to be equal to the MDS lease.
6054 */
6055 clp->cl_lease_time = lease_time;
6056 clp->cl_last_renewal = jiffies;
6057 }
6058 spin_unlock(&clp->cl_lock);
6059
6060 ret = nfs41_check_session_ready(clp);
6061 if (ret)
6062 return ret;
6063 /* Test for the DS role */
6064 if (!is_ds_client(clp))
6065 return -ENODEV;
6066 return 0;
6067}
6068EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
6069
6070
6071/*
6072 * Renew the cl_session lease. 5707 * Renew the cl_session lease.
6073 */ 5708 */
6074struct nfs4_sequence_data { 5709struct nfs4_sequence_data {
@@ -6133,9 +5768,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
6133 args = task->tk_msg.rpc_argp; 5768 args = task->tk_msg.rpc_argp;
6134 res = task->tk_msg.rpc_resp; 5769 res = task->tk_msg.rpc_resp;
6135 5770
6136 if (nfs41_setup_sequence(clp->cl_session, args, res, task)) 5771 nfs41_setup_sequence(clp->cl_session, args, res, task);
6137 return;
6138 rpc_call_start(task);
6139} 5772}
6140 5773
6141static const struct rpc_call_ops nfs41_sequence_ops = { 5774static const struct rpc_call_ops nfs41_sequence_ops = {
@@ -6144,7 +5777,9 @@ static const struct rpc_call_ops nfs41_sequence_ops = {
6144 .rpc_release = nfs41_sequence_release, 5777 .rpc_release = nfs41_sequence_release,
6145}; 5778};
6146 5779
6147static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) 5780static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
5781 struct rpc_cred *cred,
5782 bool is_privileged)
6148{ 5783{
6149 struct nfs4_sequence_data *calldata; 5784 struct nfs4_sequence_data *calldata;
6150 struct rpc_message msg = { 5785 struct rpc_message msg = {
@@ -6166,6 +5801,8 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
6166 return ERR_PTR(-ENOMEM); 5801 return ERR_PTR(-ENOMEM);
6167 } 5802 }
6168 nfs41_init_sequence(&calldata->args, &calldata->res, 0); 5803 nfs41_init_sequence(&calldata->args, &calldata->res, 0);
5804 if (is_privileged)
5805 nfs4_set_sequence_privileged(&calldata->args);
6169 msg.rpc_argp = &calldata->args; 5806 msg.rpc_argp = &calldata->args;
6170 msg.rpc_resp = &calldata->res; 5807 msg.rpc_resp = &calldata->res;
6171 calldata->clp = clp; 5808 calldata->clp = clp;
@@ -6181,7 +5818,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
6181 5818
6182 if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0) 5819 if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
6183 return 0; 5820 return 0;
6184 task = _nfs41_proc_sequence(clp, cred); 5821 task = _nfs41_proc_sequence(clp, cred, false);
6185 if (IS_ERR(task)) 5822 if (IS_ERR(task))
6186 ret = PTR_ERR(task); 5823 ret = PTR_ERR(task);
6187 else 5824 else
@@ -6195,7 +5832,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
6195 struct rpc_task *task; 5832 struct rpc_task *task;
6196 int ret; 5833 int ret;
6197 5834
6198 task = _nfs41_proc_sequence(clp, cred); 5835 task = _nfs41_proc_sequence(clp, cred, true);
6199 if (IS_ERR(task)) { 5836 if (IS_ERR(task)) {
6200 ret = PTR_ERR(task); 5837 ret = PTR_ERR(task);
6201 goto out; 5838 goto out;
@@ -6224,13 +5861,10 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
6224{ 5861{
6225 struct nfs4_reclaim_complete_data *calldata = data; 5862 struct nfs4_reclaim_complete_data *calldata = data;
6226 5863
6227 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); 5864 nfs41_setup_sequence(calldata->clp->cl_session,
6228 if (nfs41_setup_sequence(calldata->clp->cl_session, 5865 &calldata->arg.seq_args,
6229 &calldata->arg.seq_args, 5866 &calldata->res.seq_res,
6230 &calldata->res.seq_res, task)) 5867 task);
6231 return;
6232
6233 rpc_call_start(task);
6234} 5868}
6235 5869
6236static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nfs_client *clp) 5870static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nfs_client *clp)
@@ -6307,6 +5941,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
6307 calldata->arg.one_fs = 0; 5941 calldata->arg.one_fs = 0;
6308 5942
6309 nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0); 5943 nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0);
5944 nfs4_set_sequence_privileged(&calldata->arg.seq_args);
6310 msg.rpc_argp = &calldata->arg; 5945 msg.rpc_argp = &calldata->arg;
6311 msg.rpc_resp = &calldata->res; 5946 msg.rpc_resp = &calldata->res;
6312 task_setup_data.callback_data = calldata; 5947 task_setup_data.callback_data = calldata;
@@ -6330,6 +5965,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
6330{ 5965{
6331 struct nfs4_layoutget *lgp = calldata; 5966 struct nfs4_layoutget *lgp = calldata;
6332 struct nfs_server *server = NFS_SERVER(lgp->args.inode); 5967 struct nfs_server *server = NFS_SERVER(lgp->args.inode);
5968 struct nfs4_session *session = nfs4_get_session(server);
6333 5969
6334 dprintk("--> %s\n", __func__); 5970 dprintk("--> %s\n", __func__);
6335 /* Note the is a race here, where a CB_LAYOUTRECALL can come in 5971 /* Note the is a race here, where a CB_LAYOUTRECALL can come in
@@ -6337,16 +5973,14 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
6337 * However, that is not so catastrophic, and there seems 5973 * However, that is not so catastrophic, and there seems
6338 * to be no way to prevent it completely. 5974 * to be no way to prevent it completely.
6339 */ 5975 */
6340 if (nfs4_setup_sequence(server, &lgp->args.seq_args, 5976 if (nfs41_setup_sequence(session, &lgp->args.seq_args,
6341 &lgp->res.seq_res, task)) 5977 &lgp->res.seq_res, task))
6342 return; 5978 return;
6343 if (pnfs_choose_layoutget_stateid(&lgp->args.stateid, 5979 if (pnfs_choose_layoutget_stateid(&lgp->args.stateid,
6344 NFS_I(lgp->args.inode)->layout, 5980 NFS_I(lgp->args.inode)->layout,
6345 lgp->args.ctx->state)) { 5981 lgp->args.ctx->state)) {
6346 rpc_exit(task, NFS4_OK); 5982 rpc_exit(task, NFS4_OK);
6347 return;
6348 } 5983 }
6349 rpc_call_start(task);
6350} 5984}
6351 5985
6352static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) 5986static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
@@ -6359,7 +5993,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
6359 5993
6360 dprintk("--> %s\n", __func__); 5994 dprintk("--> %s\n", __func__);
6361 5995
6362 if (!nfs4_sequence_done(task, &lgp->res.seq_res)) 5996 if (!nfs41_sequence_done(task, &lgp->res.seq_res))
6363 goto out; 5997 goto out;
6364 5998
6365 switch (task->tk_status) { 5999 switch (task->tk_status) {
@@ -6510,10 +6144,10 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
6510 struct nfs4_layoutreturn *lrp = calldata; 6144 struct nfs4_layoutreturn *lrp = calldata;
6511 6145
6512 dprintk("--> %s\n", __func__); 6146 dprintk("--> %s\n", __func__);
6513 if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args, 6147 nfs41_setup_sequence(lrp->clp->cl_session,
6514 &lrp->res.seq_res, task)) 6148 &lrp->args.seq_args,
6515 return; 6149 &lrp->res.seq_res,
6516 rpc_call_start(task); 6150 task);
6517} 6151}
6518 6152
6519static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) 6153static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
@@ -6523,7 +6157,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
6523 6157
6524 dprintk("--> %s\n", __func__); 6158 dprintk("--> %s\n", __func__);
6525 6159
6526 if (!nfs4_sequence_done(task, &lrp->res.seq_res)) 6160 if (!nfs41_sequence_done(task, &lrp->res.seq_res))
6527 return; 6161 return;
6528 6162
6529 server = NFS_SERVER(lrp->args.inode); 6163 server = NFS_SERVER(lrp->args.inode);
@@ -6672,11 +6306,12 @@ static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata)
6672{ 6306{
6673 struct nfs4_layoutcommit_data *data = calldata; 6307 struct nfs4_layoutcommit_data *data = calldata;
6674 struct nfs_server *server = NFS_SERVER(data->args.inode); 6308 struct nfs_server *server = NFS_SERVER(data->args.inode);
6309 struct nfs4_session *session = nfs4_get_session(server);
6675 6310
6676 if (nfs4_setup_sequence(server, &data->args.seq_args, 6311 nfs41_setup_sequence(session,
6677 &data->res.seq_res, task)) 6312 &data->args.seq_args,
6678 return; 6313 &data->res.seq_res,
6679 rpc_call_start(task); 6314 task);
6680} 6315}
6681 6316
6682static void 6317static void
@@ -6685,7 +6320,7 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
6685 struct nfs4_layoutcommit_data *data = calldata; 6320 struct nfs4_layoutcommit_data *data = calldata;
6686 struct nfs_server *server = NFS_SERVER(data->args.inode); 6321 struct nfs_server *server = NFS_SERVER(data->args.inode);
6687 6322
6688 if (!nfs4_sequence_done(task, &data->res.seq_res)) 6323 if (!nfs41_sequence_done(task, &data->res.seq_res))
6689 return; 6324 return;
6690 6325
6691 switch (task->tk_status) { /* Just ignore these failures */ 6326 switch (task->tk_status) { /* Just ignore these failures */
@@ -6873,7 +6508,9 @@ static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6873 6508
6874 dprintk("NFS call test_stateid %p\n", stateid); 6509 dprintk("NFS call test_stateid %p\n", stateid);
6875 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 6510 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
6876 status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1); 6511 nfs4_set_sequence_privileged(&args.seq_args);
6512 status = nfs4_call_sync_sequence(server->client, server, &msg,
6513 &args.seq_args, &res.seq_res);
6877 if (status != NFS_OK) { 6514 if (status != NFS_OK) {
6878 dprintk("NFS reply test_stateid: failed, %d\n", status); 6515 dprintk("NFS reply test_stateid: failed, %d\n", status);
6879 return status; 6516 return status;
@@ -6920,8 +6557,9 @@ static int _nfs4_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6920 6557
6921 dprintk("NFS call free_stateid %p\n", stateid); 6558 dprintk("NFS call free_stateid %p\n", stateid);
6922 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 6559 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
6560 nfs4_set_sequence_privileged(&args.seq_args);
6923 status = nfs4_call_sync_sequence(server->client, server, &msg, 6561 status = nfs4_call_sync_sequence(server->client, server, &msg,
6924 &args.seq_args, &res.seq_res, 1); 6562 &args.seq_args, &res.seq_res);
6925 dprintk("NFS reply free_stateid: %d\n", status); 6563 dprintk("NFS reply free_stateid: %d\n", status);
6926 return status; 6564 return status;
6927} 6565}
@@ -7041,7 +6679,7 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
7041#if defined(CONFIG_NFS_V4_1) 6679#if defined(CONFIG_NFS_V4_1)
7042static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { 6680static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
7043 .minor_version = 1, 6681 .minor_version = 1,
7044 .call_sync = _nfs4_call_sync_session, 6682 .call_sync = nfs4_call_sync_sequence,
7045 .match_stateid = nfs41_match_stateid, 6683 .match_stateid = nfs41_match_stateid,
7046 .find_root_sec = nfs41_find_root_sec, 6684 .find_root_sec = nfs41_find_root_sec,
7047 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 6685 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
new file mode 100644
index 000000000000..ebda5f4a031b
--- /dev/null
+++ b/fs/nfs/nfs4session.c
@@ -0,0 +1,552 @@
1/*
2 * fs/nfs/nfs4session.c
3 *
4 * Copyright (c) 2012 Trond Myklebust <Trond.Myklebust@netapp.com>
5 *
6 */
7#include <linux/kernel.h>
8#include <linux/errno.h>
9#include <linux/string.h>
10#include <linux/printk.h>
11#include <linux/slab.h>
12#include <linux/sunrpc/sched.h>
13#include <linux/sunrpc/bc_xprt.h>
14#include <linux/nfs.h>
15#include <linux/nfs4.h>
16#include <linux/nfs_fs.h>
17#include <linux/module.h>
18
19#include "nfs4_fs.h"
20#include "internal.h"
21#include "nfs4session.h"
22#include "callback.h"
23
24#define NFSDBG_FACILITY NFSDBG_STATE
25
26/*
27 * nfs4_shrink_slot_table - free retired slots from the slot table
28 */
29static void nfs4_shrink_slot_table(struct nfs4_slot_table *tbl, u32 newsize)
30{
31 struct nfs4_slot **p;
32 if (newsize >= tbl->max_slots)
33 return;
34
35 p = &tbl->slots;
36 while (newsize--)
37 p = &(*p)->next;
38 while (*p) {
39 struct nfs4_slot *slot = *p;
40
41 *p = slot->next;
42 kfree(slot);
43 tbl->max_slots--;
44 }
45}
46
47/*
48 * nfs4_free_slot - free a slot and efficiently update slot table.
49 *
50 * freeing a slot is trivially done by clearing its respective bit
51 * in the bitmap.
52 * If the freed slotid equals highest_used_slotid we want to update it
53 * so that the server would be able to size down the slot table if needed,
54 * otherwise we know that the highest_used_slotid is still in use.
55 * When updating highest_used_slotid there may be "holes" in the bitmap
56 * so we need to scan down from highest_used_slotid to 0 looking for the now
57 * highest slotid in use.
58 * If none found, highest_used_slotid is set to NFS4_NO_SLOT.
59 *
60 * Must be called while holding tbl->slot_tbl_lock
61 */
62void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
63{
64 u32 slotid = slot->slot_nr;
65
66 /* clear used bit in bitmap */
67 __clear_bit(slotid, tbl->used_slots);
68
69 /* update highest_used_slotid when it is freed */
70 if (slotid == tbl->highest_used_slotid) {
71 u32 new_max = find_last_bit(tbl->used_slots, slotid);
72 if (new_max < slotid)
73 tbl->highest_used_slotid = new_max;
74 else {
75 tbl->highest_used_slotid = NFS4_NO_SLOT;
76 nfs4_session_drain_complete(tbl->session, tbl);
77 }
78 }
79 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
80 slotid, tbl->highest_used_slotid);
81}
82
83static struct nfs4_slot *nfs4_new_slot(struct nfs4_slot_table *tbl,
84 u32 slotid, u32 seq_init, gfp_t gfp_mask)
85{
86 struct nfs4_slot *slot;
87
88 slot = kzalloc(sizeof(*slot), gfp_mask);
89 if (slot) {
90 slot->table = tbl;
91 slot->slot_nr = slotid;
92 slot->seq_nr = seq_init;
93 }
94 return slot;
95}
96
97static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl,
98 u32 slotid, u32 seq_init, gfp_t gfp_mask)
99{
100 struct nfs4_slot **p, *slot;
101
102 p = &tbl->slots;
103 for (;;) {
104 if (*p == NULL) {
105 *p = nfs4_new_slot(tbl, tbl->max_slots,
106 seq_init, gfp_mask);
107 if (*p == NULL)
108 break;
109 tbl->max_slots++;
110 }
111 slot = *p;
112 if (slot->slot_nr == slotid)
113 return slot;
114 p = &slot->next;
115 }
116 return ERR_PTR(-ENOMEM);
117}
118
119/*
120 * nfs4_alloc_slot - efficiently look for a free slot
121 *
122 * nfs4_alloc_slot looks for an unset bit in the used_slots bitmap.
123 * If found, we mark the slot as used, update the highest_used_slotid,
124 * and respectively set up the sequence operation args.
125 *
126 * Note: must be called with under the slot_tbl_lock.
127 */
128struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)
129{
130 struct nfs4_slot *ret = ERR_PTR(-EBUSY);
131 u32 slotid;
132
133 dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
134 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
135 tbl->max_slotid + 1);
136 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1);
137 if (slotid > tbl->max_slotid)
138 goto out;
139 ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT);
140 if (IS_ERR(ret))
141 goto out;
142 __set_bit(slotid, tbl->used_slots);
143 if (slotid > tbl->highest_used_slotid ||
144 tbl->highest_used_slotid == NFS4_NO_SLOT)
145 tbl->highest_used_slotid = slotid;
146 ret->generation = tbl->generation;
147
148out:
149 dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
150 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
151 !IS_ERR(ret) ? ret->slot_nr : -1);
152 return ret;
153}
154
155static int nfs4_grow_slot_table(struct nfs4_slot_table *tbl,
156 u32 max_reqs, u32 ivalue)
157{
158 if (max_reqs <= tbl->max_slots)
159 return 0;
160 if (!IS_ERR(nfs4_find_or_create_slot(tbl, max_reqs - 1, ivalue, GFP_NOFS)))
161 return 0;
162 return -ENOMEM;
163}
164
165static void nfs4_reset_slot_table(struct nfs4_slot_table *tbl,
166 u32 server_highest_slotid,
167 u32 ivalue)
168{
169 struct nfs4_slot **p;
170
171 nfs4_shrink_slot_table(tbl, server_highest_slotid + 1);
172 p = &tbl->slots;
173 while (*p) {
174 (*p)->seq_nr = ivalue;
175 (*p)->interrupted = 0;
176 p = &(*p)->next;
177 }
178 tbl->highest_used_slotid = NFS4_NO_SLOT;
179 tbl->target_highest_slotid = server_highest_slotid;
180 tbl->server_highest_slotid = server_highest_slotid;
181 tbl->d_target_highest_slotid = 0;
182 tbl->d2_target_highest_slotid = 0;
183 tbl->max_slotid = server_highest_slotid;
184}
185
186/*
187 * (re)Initialise a slot table
188 */
189static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl,
190 u32 max_reqs, u32 ivalue)
191{
192 int ret;
193
194 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
195 max_reqs, tbl->max_slots);
196
197 if (max_reqs > NFS4_MAX_SLOT_TABLE)
198 max_reqs = NFS4_MAX_SLOT_TABLE;
199
200 ret = nfs4_grow_slot_table(tbl, max_reqs, ivalue);
201 if (ret)
202 goto out;
203
204 spin_lock(&tbl->slot_tbl_lock);
205 nfs4_reset_slot_table(tbl, max_reqs - 1, ivalue);
206 spin_unlock(&tbl->slot_tbl_lock);
207
208 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
209 tbl, tbl->slots, tbl->max_slots);
210out:
211 dprintk("<-- %s: return %d\n", __func__, ret);
212 return ret;
213}
214
215/* Destroy the slot table */
216static void nfs4_destroy_slot_tables(struct nfs4_session *session)
217{
218 nfs4_shrink_slot_table(&session->fc_slot_table, 0);
219 nfs4_shrink_slot_table(&session->bc_slot_table, 0);
220}
221
222static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
223{
224 struct nfs4_sequence_args *args = task->tk_msg.rpc_argp;
225 struct nfs4_sequence_res *res = task->tk_msg.rpc_resp;
226 struct nfs4_slot *slot = pslot;
227 struct nfs4_slot_table *tbl = slot->table;
228
229 if (nfs4_session_draining(tbl->session) && !args->sa_privileged)
230 return false;
231 slot->generation = tbl->generation;
232 args->sa_slot = slot;
233 res->sr_timestamp = jiffies;
234 res->sr_slot = slot;
235 res->sr_status_flags = 0;
236 res->sr_status = 1;
237 return true;
238}
239
240static bool __nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
241 struct nfs4_slot *slot)
242{
243 if (rpc_wake_up_first(&tbl->slot_tbl_waitq, nfs41_assign_slot, slot))
244 return true;
245 return false;
246}
247
248bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
249 struct nfs4_slot *slot)
250{
251 if (slot->slot_nr > tbl->max_slotid)
252 return false;
253 return __nfs41_wake_and_assign_slot(tbl, slot);
254}
255
256static bool nfs41_try_wake_next_slot_table_entry(struct nfs4_slot_table *tbl)
257{
258 struct nfs4_slot *slot = nfs4_alloc_slot(tbl);
259 if (!IS_ERR(slot)) {
260 bool ret = __nfs41_wake_and_assign_slot(tbl, slot);
261 if (ret)
262 return ret;
263 nfs4_free_slot(tbl, slot);
264 }
265 return false;
266}
267
268void nfs41_wake_slot_table(struct nfs4_slot_table *tbl)
269{
270 for (;;) {
271 if (!nfs41_try_wake_next_slot_table_entry(tbl))
272 break;
273 }
274}
275
276static void nfs41_set_max_slotid_locked(struct nfs4_slot_table *tbl,
277 u32 target_highest_slotid)
278{
279 u32 max_slotid;
280
281 max_slotid = min(NFS4_MAX_SLOT_TABLE - 1, target_highest_slotid);
282 if (max_slotid > tbl->server_highest_slotid)
283 max_slotid = tbl->server_highest_slotid;
284 if (max_slotid > tbl->target_highest_slotid)
285 max_slotid = tbl->target_highest_slotid;
286 tbl->max_slotid = max_slotid;
287 nfs41_wake_slot_table(tbl);
288}
289
290/* Update the client's idea of target_highest_slotid */
291static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
292 u32 target_highest_slotid)
293{
294 if (tbl->target_highest_slotid == target_highest_slotid)
295 return;
296 tbl->target_highest_slotid = target_highest_slotid;
297 tbl->generation++;
298}
299
300void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
301 u32 target_highest_slotid)
302{
303 spin_lock(&tbl->slot_tbl_lock);
304 nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
305 tbl->d_target_highest_slotid = 0;
306 tbl->d2_target_highest_slotid = 0;
307 nfs41_set_max_slotid_locked(tbl, target_highest_slotid);
308 spin_unlock(&tbl->slot_tbl_lock);
309}
310
311static void nfs41_set_server_slotid_locked(struct nfs4_slot_table *tbl,
312 u32 highest_slotid)
313{
314 if (tbl->server_highest_slotid == highest_slotid)
315 return;
316 if (tbl->highest_used_slotid > highest_slotid)
317 return;
318 /* Deallocate slots */
319 nfs4_shrink_slot_table(tbl, highest_slotid + 1);
320 tbl->server_highest_slotid = highest_slotid;
321}
322
323static s32 nfs41_derivative_target_slotid(s32 s1, s32 s2)
324{
325 s1 -= s2;
326 if (s1 == 0)
327 return 0;
328 if (s1 < 0)
329 return (s1 - 1) >> 1;
330 return (s1 + 1) >> 1;
331}
332
333static int nfs41_sign_s32(s32 s1)
334{
335 if (s1 > 0)
336 return 1;
337 if (s1 < 0)
338 return -1;
339 return 0;
340}
341
342static bool nfs41_same_sign_or_zero_s32(s32 s1, s32 s2)
343{
344 if (!s1 || !s2)
345 return true;
346 return nfs41_sign_s32(s1) == nfs41_sign_s32(s2);
347}
348
349/* Try to eliminate outliers by checking for sharp changes in the
350 * derivatives and second derivatives
351 */
352static bool nfs41_is_outlier_target_slotid(struct nfs4_slot_table *tbl,
353 u32 new_target)
354{
355 s32 d_target, d2_target;
356 bool ret = true;
357
358 d_target = nfs41_derivative_target_slotid(new_target,
359 tbl->target_highest_slotid);
360 d2_target = nfs41_derivative_target_slotid(d_target,
361 tbl->d_target_highest_slotid);
362 /* Is first derivative same sign? */
363 if (nfs41_same_sign_or_zero_s32(d_target, tbl->d_target_highest_slotid))
364 ret = false;
365 /* Is second derivative same sign? */
366 if (nfs41_same_sign_or_zero_s32(d2_target, tbl->d2_target_highest_slotid))
367 ret = false;
368 tbl->d_target_highest_slotid = d_target;
369 tbl->d2_target_highest_slotid = d2_target;
370 return ret;
371}
372
373void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
374 struct nfs4_slot *slot,
375 struct nfs4_sequence_res *res)
376{
377 spin_lock(&tbl->slot_tbl_lock);
378 if (!nfs41_is_outlier_target_slotid(tbl, res->sr_target_highest_slotid))
379 nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid);
380 if (tbl->generation == slot->generation)
381 nfs41_set_server_slotid_locked(tbl, res->sr_highest_slotid);
382 nfs41_set_max_slotid_locked(tbl, res->sr_target_highest_slotid);
383 spin_unlock(&tbl->slot_tbl_lock);
384}
385
386/*
387 * Initialize or reset the forechannel and backchannel tables
388 */
389int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
390{
391 struct nfs4_slot_table *tbl;
392 int status;
393
394 dprintk("--> %s\n", __func__);
395 /* Fore channel */
396 tbl = &ses->fc_slot_table;
397 tbl->session = ses;
398 status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
399 if (status) /* -ENOMEM */
400 return status;
401 /* Back channel */
402 tbl = &ses->bc_slot_table;
403 tbl->session = ses;
404 status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
405 if (status && tbl->slots == NULL)
406 /* Fore and back channel share a connection so get
407 * both slot tables or neither */
408 nfs4_destroy_slot_tables(ses);
409 return status;
410}
411
412struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
413{
414 struct nfs4_session *session;
415 struct nfs4_slot_table *tbl;
416
417 session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
418 if (!session)
419 return NULL;
420
421 tbl = &session->fc_slot_table;
422 tbl->highest_used_slotid = NFS4_NO_SLOT;
423 spin_lock_init(&tbl->slot_tbl_lock);
424 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
425 init_completion(&tbl->complete);
426
427 tbl = &session->bc_slot_table;
428 tbl->highest_used_slotid = NFS4_NO_SLOT;
429 spin_lock_init(&tbl->slot_tbl_lock);
430 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
431 init_completion(&tbl->complete);
432
433 session->session_state = 1<<NFS4_SESSION_INITING;
434
435 session->clp = clp;
436 return session;
437}
438
439void nfs4_destroy_session(struct nfs4_session *session)
440{
441 struct rpc_xprt *xprt;
442 struct rpc_cred *cred;
443
444 cred = nfs4_get_exchange_id_cred(session->clp);
445 nfs4_proc_destroy_session(session, cred);
446 if (cred)
447 put_rpccred(cred);
448
449 rcu_read_lock();
450 xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
451 rcu_read_unlock();
452 dprintk("%s Destroy backchannel for xprt %p\n",
453 __func__, xprt);
454 xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
455 nfs4_destroy_slot_tables(session);
456 kfree(session);
457}
458
459/*
460 * With sessions, the client is not marked ready until after a
461 * successful EXCHANGE_ID and CREATE_SESSION.
462 *
463 * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
464 * other versions of NFS can be tried.
465 */
466static int nfs41_check_session_ready(struct nfs_client *clp)
467{
468 int ret;
469
470 if (clp->cl_cons_state == NFS_CS_SESSION_INITING) {
471 ret = nfs4_client_recover_expired_lease(clp);
472 if (ret)
473 return ret;
474 }
475 if (clp->cl_cons_state < NFS_CS_READY)
476 return -EPROTONOSUPPORT;
477 smp_rmb();
478 return 0;
479}
480
481int nfs4_init_session(struct nfs_server *server)
482{
483 struct nfs_client *clp = server->nfs_client;
484 struct nfs4_session *session;
485 unsigned int target_max_rqst_sz = NFS_MAX_FILE_IO_SIZE;
486 unsigned int target_max_resp_sz = NFS_MAX_FILE_IO_SIZE;
487
488 if (!nfs4_has_session(clp))
489 return 0;
490
491 if (server->rsize != 0)
492 target_max_resp_sz = server->rsize;
493 target_max_resp_sz += nfs41_maxread_overhead;
494
495 if (server->wsize != 0)
496 target_max_rqst_sz = server->wsize;
497 target_max_rqst_sz += nfs41_maxwrite_overhead;
498
499 session = clp->cl_session;
500 spin_lock(&clp->cl_lock);
501 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
502 /* Initialise targets and channel attributes */
503 session->fc_target_max_rqst_sz = target_max_rqst_sz;
504 session->fc_attrs.max_rqst_sz = target_max_rqst_sz;
505 session->fc_target_max_resp_sz = target_max_resp_sz;
506 session->fc_attrs.max_resp_sz = target_max_resp_sz;
507 } else {
508 /* Just adjust the targets */
509 if (target_max_rqst_sz > session->fc_target_max_rqst_sz) {
510 session->fc_target_max_rqst_sz = target_max_rqst_sz;
511 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
512 }
513 if (target_max_resp_sz > session->fc_target_max_resp_sz) {
514 session->fc_target_max_resp_sz = target_max_resp_sz;
515 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
516 }
517 }
518 spin_unlock(&clp->cl_lock);
519
520 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
521 nfs4_schedule_lease_recovery(clp);
522
523 return nfs41_check_session_ready(clp);
524}
525
526int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time)
527{
528 struct nfs4_session *session = clp->cl_session;
529 int ret;
530
531 spin_lock(&clp->cl_lock);
532 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
533 /*
534 * Do not set NFS_CS_CHECK_LEASE_TIME instead set the
535 * DS lease to be equal to the MDS lease.
536 */
537 clp->cl_lease_time = lease_time;
538 clp->cl_last_renewal = jiffies;
539 }
540 spin_unlock(&clp->cl_lock);
541
542 ret = nfs41_check_session_ready(clp);
543 if (ret)
544 return ret;
545 /* Test for the DS role */
546 if (!is_ds_client(clp))
547 return -ENODEV;
548 return 0;
549}
550EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
551
552
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
new file mode 100644
index 000000000000..6f3cb39386d4
--- /dev/null
+++ b/fs/nfs/nfs4session.h
@@ -0,0 +1,142 @@
1/*
2 * fs/nfs/nfs4session.h
3 *
4 * Copyright (c) 2012 Trond Myklebust <Trond.Myklebust@netapp.com>
5 *
6 */
7#ifndef __LINUX_FS_NFS_NFS4SESSION_H
8#define __LINUX_FS_NFS_NFS4SESSION_H
9
10/* maximum number of slots to use */
11#define NFS4_DEF_SLOT_TABLE_SIZE (16U)
12#define NFS4_MAX_SLOT_TABLE (1024U)
13#define NFS4_NO_SLOT ((u32)-1)
14
15#if IS_ENABLED(CONFIG_NFS_V4)
16
17/* Sessions slot seqid */
18struct nfs4_slot {
19 struct nfs4_slot_table *table;
20 struct nfs4_slot *next;
21 unsigned long generation;
22 u32 slot_nr;
23 u32 seq_nr;
24 unsigned int interrupted : 1;
25};
26
27/* Sessions */
28#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
29struct nfs4_slot_table {
30 struct nfs4_session *session; /* Parent session */
31 struct nfs4_slot *slots; /* seqid per slot */
32 unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
33 spinlock_t slot_tbl_lock;
34 struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
35 u32 max_slots; /* # slots in table */
36 u32 max_slotid; /* Max allowed slotid value */
37 u32 highest_used_slotid; /* sent to server on each SEQ.
38 * op for dynamic resizing */
39 u32 target_highest_slotid; /* Server max_slot target */
40 u32 server_highest_slotid; /* Server highest slotid */
41 s32 d_target_highest_slotid; /* Derivative */
42 s32 d2_target_highest_slotid; /* 2nd derivative */
43 unsigned long generation; /* Generation counter for
44 target_highest_slotid */
45 struct completion complete;
46};
47
48/*
49 * Session related parameters
50 */
51struct nfs4_session {
52 struct nfs4_sessionid sess_id;
53 u32 flags;
54 unsigned long session_state;
55 u32 hash_alg;
56 u32 ssv_len;
57
58 /* The fore and back channel */
59 struct nfs4_channel_attrs fc_attrs;
60 struct nfs4_slot_table fc_slot_table;
61 struct nfs4_channel_attrs bc_attrs;
62 struct nfs4_slot_table bc_slot_table;
63 struct nfs_client *clp;
64 /* Create session arguments */
65 unsigned int fc_target_max_rqst_sz;
66 unsigned int fc_target_max_resp_sz;
67};
68
69enum nfs4_session_state {
70 NFS4_SESSION_INITING,
71 NFS4_SESSION_DRAINING,
72};
73
74#if defined(CONFIG_NFS_V4_1)
75extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl);
76extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot);
77
78extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
79 u32 target_highest_slotid);
80extern void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
81 struct nfs4_slot *slot,
82 struct nfs4_sequence_res *res);
83
84extern int nfs4_setup_session_slot_tables(struct nfs4_session *ses);
85
86extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
87extern void nfs4_destroy_session(struct nfs4_session *session);
88extern int nfs4_init_session(struct nfs_server *server);
89extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
90
91extern void nfs4_session_drain_complete(struct nfs4_session *session,
92 struct nfs4_slot_table *tbl);
93
94static inline bool nfs4_session_draining(struct nfs4_session *session)
95{
96 return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state);
97}
98
99bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
100 struct nfs4_slot *slot);
101void nfs41_wake_slot_table(struct nfs4_slot_table *tbl);
102
103/*
104 * Determine if sessions are in use.
105 */
106static inline int nfs4_has_session(const struct nfs_client *clp)
107{
108 if (clp->cl_session)
109 return 1;
110 return 0;
111}
112
113static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
114{
115 if (nfs4_has_session(clp))
116 return (clp->cl_session->flags & SESSION4_PERSIST);
117 return 0;
118}
119
120#else /* defined(CONFIG_NFS_V4_1) */
121
122static inline int nfs4_init_session(struct nfs_server *server)
123{
124 return 0;
125}
126
127/*
128 * Determine if sessions are in use.
129 */
130static inline int nfs4_has_session(const struct nfs_client *clp)
131{
132 return 0;
133}
134
135static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
136{
137 return 0;
138}
139
140#endif /* defined(CONFIG_NFS_V4_1) */
141#endif /* IS_ENABLED(CONFIG_NFS_V4) */
142#endif /* __LINUX_FS_NFS_NFS4SESSION_H */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index c351e6b39838..9448c579d41a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -57,6 +57,7 @@
57#include "callback.h" 57#include "callback.h"
58#include "delegation.h" 58#include "delegation.h"
59#include "internal.h" 59#include "internal.h"
60#include "nfs4session.h"
60#include "pnfs.h" 61#include "pnfs.h"
61#include "netns.h" 62#include "netns.h"
62 63
@@ -66,7 +67,6 @@
66 67
67const nfs4_stateid zero_stateid; 68const nfs4_stateid zero_stateid;
68static DEFINE_MUTEX(nfs_clid_init_mutex); 69static DEFINE_MUTEX(nfs_clid_init_mutex);
69static LIST_HEAD(nfs4_clientid_list);
70 70
71int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 71int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
72{ 72{
@@ -254,24 +254,27 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
254{ 254{
255 struct nfs4_session *ses = clp->cl_session; 255 struct nfs4_session *ses = clp->cl_session;
256 struct nfs4_slot_table *tbl; 256 struct nfs4_slot_table *tbl;
257 int max_slots;
258 257
259 if (ses == NULL) 258 if (ses == NULL)
260 return; 259 return;
261 tbl = &ses->fc_slot_table; 260 tbl = &ses->fc_slot_table;
262 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) { 261 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
263 spin_lock(&tbl->slot_tbl_lock); 262 spin_lock(&tbl->slot_tbl_lock);
264 max_slots = tbl->max_slots; 263 nfs41_wake_slot_table(tbl);
265 while (max_slots--) {
266 if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
267 nfs4_set_task_privileged,
268 NULL) == NULL)
269 break;
270 }
271 spin_unlock(&tbl->slot_tbl_lock); 264 spin_unlock(&tbl->slot_tbl_lock);
272 } 265 }
273} 266}
274 267
268/*
269 * Signal state manager thread if session fore channel is drained
270 */
271void nfs4_session_drain_complete(struct nfs4_session *session,
272 struct nfs4_slot_table *tbl)
273{
274 if (nfs4_session_draining(session))
275 complete(&tbl->complete);
276}
277
275static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl) 278static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
276{ 279{
277 spin_lock(&tbl->slot_tbl_lock); 280 spin_lock(&tbl->slot_tbl_lock);
@@ -303,7 +306,6 @@ static void nfs41_finish_session_reset(struct nfs_client *clp)
303 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 306 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
304 clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); 307 clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
305 /* create_session negotiated new slot table */ 308 /* create_session negotiated new slot table */
306 clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
307 clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state); 309 clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
308 nfs41_setup_state_renewal(clp); 310 nfs41_setup_state_renewal(clp);
309} 311}
@@ -1086,7 +1088,6 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
1086 */ 1088 */
1087static void nfs_increment_seqid(int status, struct nfs_seqid *seqid) 1089static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
1088{ 1090{
1089 BUG_ON(list_first_entry(&seqid->sequence->list, struct nfs_seqid, list) != seqid);
1090 switch (status) { 1091 switch (status) {
1091 case 0: 1092 case 0:
1092 break; 1093 break;
@@ -1209,6 +1210,40 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
1209} 1210}
1210EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery); 1211EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery);
1211 1212
1213int nfs4_wait_clnt_recover(struct nfs_client *clp)
1214{
1215 int res;
1216
1217 might_sleep();
1218
1219 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
1220 nfs_wait_bit_killable, TASK_KILLABLE);
1221 if (res)
1222 return res;
1223
1224 if (clp->cl_cons_state < 0)
1225 return clp->cl_cons_state;
1226 return 0;
1227}
1228
1229int nfs4_client_recover_expired_lease(struct nfs_client *clp)
1230{
1231 unsigned int loop;
1232 int ret;
1233
1234 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
1235 ret = nfs4_wait_clnt_recover(clp);
1236 if (ret != 0)
1237 break;
1238 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1239 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
1240 break;
1241 nfs4_schedule_state_manager(clp);
1242 ret = -EIO;
1243 }
1244 return ret;
1245}
1246
1212/* 1247/*
1213 * nfs40_handle_cb_pathdown - return all delegations after NFS4ERR_CB_PATH_DOWN 1248 * nfs40_handle_cb_pathdown - return all delegations after NFS4ERR_CB_PATH_DOWN
1214 * @clp: client to process 1249 * @clp: client to process
@@ -1401,14 +1436,6 @@ restart:
1401 /* Mark the file as being 'closed' */ 1436 /* Mark the file as being 'closed' */
1402 state->state = 0; 1437 state->state = 0;
1403 break; 1438 break;
1404 case -EKEYEXPIRED:
1405 /*
1406 * User RPCSEC_GSS context has expired.
1407 * We cannot recover this stateid now, so
1408 * skip it and allow recovery thread to
1409 * proceed.
1410 */
1411 break;
1412 case -NFS4ERR_ADMIN_REVOKED: 1439 case -NFS4ERR_ADMIN_REVOKED:
1413 case -NFS4ERR_STALE_STATEID: 1440 case -NFS4ERR_STALE_STATEID:
1414 case -NFS4ERR_BAD_STATEID: 1441 case -NFS4ERR_BAD_STATEID:
@@ -1561,14 +1588,6 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
1561 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); 1588 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
1562} 1589}
1563 1590
1564static void nfs4_warn_keyexpired(const char *s)
1565{
1566 printk_ratelimited(KERN_WARNING "Error: state manager"
1567 " encountered RPCSEC_GSS session"
1568 " expired against NFSv4 server %s.\n",
1569 s);
1570}
1571
1572static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) 1591static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1573{ 1592{
1574 switch (error) { 1593 switch (error) {
@@ -1602,10 +1621,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1602 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1621 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1603 set_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state); 1622 set_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
1604 break; 1623 break;
1605 case -EKEYEXPIRED:
1606 /* Nothing we can do */
1607 nfs4_warn_keyexpired(clp->cl_hostname);
1608 break;
1609 default: 1624 default:
1610 dprintk("%s: failed to handle error %d for server %s\n", 1625 dprintk("%s: failed to handle error %d for server %s\n",
1611 __func__, error, clp->cl_hostname); 1626 __func__, error, clp->cl_hostname);
@@ -1722,8 +1737,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
1722 dprintk("%s: exit with error %d for server %s\n", 1737 dprintk("%s: exit with error %d for server %s\n",
1723 __func__, -EPROTONOSUPPORT, clp->cl_hostname); 1738 __func__, -EPROTONOSUPPORT, clp->cl_hostname);
1724 return -EPROTONOSUPPORT; 1739 return -EPROTONOSUPPORT;
1725 case -EKEYEXPIRED:
1726 nfs4_warn_keyexpired(clp->cl_hostname);
1727 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1740 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1728 * in nfs4_exchange_id */ 1741 * in nfs4_exchange_id */
1729 default: 1742 default:
@@ -1876,7 +1889,6 @@ again:
1876 break; 1889 break;
1877 1890
1878 case -EKEYEXPIRED: 1891 case -EKEYEXPIRED:
1879 nfs4_warn_keyexpired(clp->cl_hostname);
1880 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1892 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1881 * in nfs4_exchange_id */ 1893 * in nfs4_exchange_id */
1882 status = -EKEYEXPIRED; 1894 status = -EKEYEXPIRED;
@@ -1907,14 +1919,23 @@ void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
1907} 1919}
1908EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); 1920EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery);
1909 1921
1910void nfs41_handle_recall_slot(struct nfs_client *clp) 1922static void nfs41_ping_server(struct nfs_client *clp)
1911{ 1923{
1912 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); 1924 /* Use CHECK_LEASE to ping the server with a SEQUENCE */
1913 dprintk("%s: scheduling slot recall for server %s\n", __func__, 1925 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1914 clp->cl_hostname);
1915 nfs4_schedule_state_manager(clp); 1926 nfs4_schedule_state_manager(clp);
1916} 1927}
1917 1928
1929void nfs41_server_notify_target_slotid_update(struct nfs_client *clp)
1930{
1931 nfs41_ping_server(clp);
1932}
1933
1934void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp)
1935{
1936 nfs41_ping_server(clp);
1937}
1938
1918static void nfs4_reset_all_state(struct nfs_client *clp) 1939static void nfs4_reset_all_state(struct nfs_client *clp)
1919{ 1940{
1920 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { 1941 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
@@ -2024,35 +2045,6 @@ out:
2024 return status; 2045 return status;
2025} 2046}
2026 2047
2027static int nfs4_recall_slot(struct nfs_client *clp)
2028{
2029 struct nfs4_slot_table *fc_tbl;
2030 struct nfs4_slot *new, *old;
2031 int i;
2032
2033 if (!nfs4_has_session(clp))
2034 return 0;
2035 nfs4_begin_drain_session(clp);
2036 fc_tbl = &clp->cl_session->fc_slot_table;
2037 new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
2038 GFP_NOFS);
2039 if (!new)
2040 return -ENOMEM;
2041
2042 spin_lock(&fc_tbl->slot_tbl_lock);
2043 for (i = 0; i < fc_tbl->target_max_slots; i++)
2044 new[i].seq_nr = fc_tbl->slots[i].seq_nr;
2045 old = fc_tbl->slots;
2046 fc_tbl->slots = new;
2047 fc_tbl->max_slots = fc_tbl->target_max_slots;
2048 fc_tbl->target_max_slots = 0;
2049 clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots;
2050 spin_unlock(&fc_tbl->slot_tbl_lock);
2051
2052 kfree(old);
2053 return 0;
2054}
2055
2056static int nfs4_bind_conn_to_session(struct nfs_client *clp) 2048static int nfs4_bind_conn_to_session(struct nfs_client *clp)
2057{ 2049{
2058 struct rpc_cred *cred; 2050 struct rpc_cred *cred;
@@ -2083,7 +2075,6 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
2083#else /* CONFIG_NFS_V4_1 */ 2075#else /* CONFIG_NFS_V4_1 */
2084static int nfs4_reset_session(struct nfs_client *clp) { return 0; } 2076static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
2085static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; } 2077static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
2086static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
2087 2078
2088static int nfs4_bind_conn_to_session(struct nfs_client *clp) 2079static int nfs4_bind_conn_to_session(struct nfs_client *clp)
2089{ 2080{
@@ -2115,15 +2106,6 @@ static void nfs4_state_manager(struct nfs_client *clp)
2115 continue; 2106 continue;
2116 } 2107 }
2117 2108
2118 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
2119 section = "check lease";
2120 status = nfs4_check_lease(clp);
2121 if (status < 0)
2122 goto out_error;
2123 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
2124 continue;
2125 }
2126
2127 /* Initialize or reset the session */ 2109 /* Initialize or reset the session */
2128 if (test_and_clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) { 2110 if (test_and_clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) {
2129 section = "reset session"; 2111 section = "reset session";
@@ -2144,10 +2126,9 @@ static void nfs4_state_manager(struct nfs_client *clp)
2144 continue; 2126 continue;
2145 } 2127 }
2146 2128
2147 /* Recall session slots */ 2129 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
2148 if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state)) { 2130 section = "check lease";
2149 section = "recall slot"; 2131 status = nfs4_check_lease(clp);
2150 status = nfs4_recall_slot(clp);
2151 if (status < 0) 2132 if (status < 0)
2152 goto out_error; 2133 goto out_error;
2153 continue; 2134 continue;
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index bd61221ad2c5..84d2e9e2f313 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -51,6 +51,7 @@ static const struct super_operations nfs4_sops = {
51 .alloc_inode = nfs_alloc_inode, 51 .alloc_inode = nfs_alloc_inode,
52 .destroy_inode = nfs_destroy_inode, 52 .destroy_inode = nfs_destroy_inode,
53 .write_inode = nfs4_write_inode, 53 .write_inode = nfs4_write_inode,
54 .drop_inode = nfs_drop_inode,
54 .put_super = nfs_put_super, 55 .put_super = nfs_put_super,
55 .statfs = nfs_statfs, 56 .statfs = nfs_statfs,
56 .evict_inode = nfs4_evict_inode, 57 .evict_inode = nfs4_evict_inode,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 40836ee5dc3a..26b143920433 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -56,6 +56,7 @@
56 56
57#include "nfs4_fs.h" 57#include "nfs4_fs.h"
58#include "internal.h" 58#include "internal.h"
59#include "nfs4session.h"
59#include "pnfs.h" 60#include "pnfs.h"
60#include "netns.h" 61#include "netns.h"
61 62
@@ -270,6 +271,8 @@ static int nfs4_stat_to_errno(int);
270 271
271#if defined(CONFIG_NFS_V4_1) 272#if defined(CONFIG_NFS_V4_1)
272#define NFS4_MAX_MACHINE_NAME_LEN (64) 273#define NFS4_MAX_MACHINE_NAME_LEN (64)
274#define IMPL_NAME_LIMIT (sizeof(utsname()->sysname) + sizeof(utsname()->release) + \
275 sizeof(utsname()->version) + sizeof(utsname()->machine) + 8)
273 276
274#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \ 277#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \
275 encode_verifier_maxsz + \ 278 encode_verifier_maxsz + \
@@ -282,7 +285,7 @@ static int nfs4_stat_to_errno(int);
282 1 /* nii_domain */ + \ 285 1 /* nii_domain */ + \
283 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 286 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
284 1 /* nii_name */ + \ 287 1 /* nii_name */ + \
285 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 288 XDR_QUADLEN(IMPL_NAME_LIMIT) + \
286 3 /* nii_date */) 289 3 /* nii_date */)
287#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \ 290#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
288 2 /* eir_clientid */ + \ 291 2 /* eir_clientid */ + \
@@ -936,7 +939,7 @@ static void encode_compound_hdr(struct xdr_stream *xdr,
936 * but this is not required as a MUST for the server to do so. */ 939 * but this is not required as a MUST for the server to do so. */
937 hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen; 940 hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen;
938 941
939 BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); 942 WARN_ON_ONCE(hdr->taglen > NFS4_MAXTAGLEN);
940 encode_string(xdr, hdr->taglen, hdr->tag); 943 encode_string(xdr, hdr->taglen, hdr->tag);
941 p = reserve_space(xdr, 8); 944 p = reserve_space(xdr, 8);
942 *p++ = cpu_to_be32(hdr->minorversion); 945 *p++ = cpu_to_be32(hdr->minorversion);
@@ -955,7 +958,7 @@ static void encode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 op,
955 958
956static void encode_nops(struct compound_hdr *hdr) 959static void encode_nops(struct compound_hdr *hdr)
957{ 960{
958 BUG_ON(hdr->nops > NFS4_MAX_OPS); 961 WARN_ON_ONCE(hdr->nops > NFS4_MAX_OPS);
959 *hdr->nops_p = htonl(hdr->nops); 962 *hdr->nops_p = htonl(hdr->nops);
960} 963}
961 964
@@ -1403,7 +1406,6 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a
1403 *p = cpu_to_be32(NFS4_OPEN_NOCREATE); 1406 *p = cpu_to_be32(NFS4_OPEN_NOCREATE);
1404 break; 1407 break;
1405 default: 1408 default:
1406 BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
1407 *p = cpu_to_be32(NFS4_OPEN_CREATE); 1409 *p = cpu_to_be32(NFS4_OPEN_CREATE);
1408 encode_createmode(xdr, arg); 1410 encode_createmode(xdr, arg);
1409 } 1411 }
@@ -1621,7 +1623,6 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun
1621 p = reserve_space(xdr, 2*4); 1623 p = reserve_space(xdr, 2*4);
1622 *p++ = cpu_to_be32(1); 1624 *p++ = cpu_to_be32(1);
1623 *p = cpu_to_be32(FATTR4_WORD0_ACL); 1625 *p = cpu_to_be32(FATTR4_WORD0_ACL);
1624 BUG_ON(arg->acl_len % 4);
1625 p = reserve_space(xdr, 4); 1626 p = reserve_space(xdr, 4);
1626 *p = cpu_to_be32(arg->acl_len); 1627 *p = cpu_to_be32(arg->acl_len);
1627 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); 1628 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
@@ -1713,7 +1714,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1713 struct compound_hdr *hdr) 1714 struct compound_hdr *hdr)
1714{ 1715{
1715 __be32 *p; 1716 __be32 *p;
1716 char impl_name[NFS4_OPAQUE_LIMIT]; 1717 char impl_name[IMPL_NAME_LIMIT];
1717 int len = 0; 1718 int len = 0;
1718 1719
1719 encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr); 1720 encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr);
@@ -1728,7 +1729,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1728 if (send_implementation_id && 1729 if (send_implementation_id &&
1729 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 && 1730 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
1730 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) 1731 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN)
1731 <= NFS4_OPAQUE_LIMIT + 1) 1732 <= sizeof(impl_name) + 1)
1732 len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s", 1733 len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s",
1733 utsname()->sysname, utsname()->release, 1734 utsname()->sysname, utsname()->release,
1734 utsname()->version, utsname()->machine); 1735 utsname()->version, utsname()->machine);
@@ -1835,18 +1836,16 @@ static void encode_sequence(struct xdr_stream *xdr,
1835 struct compound_hdr *hdr) 1836 struct compound_hdr *hdr)
1836{ 1837{
1837#if defined(CONFIG_NFS_V4_1) 1838#if defined(CONFIG_NFS_V4_1)
1838 struct nfs4_session *session = args->sa_session; 1839 struct nfs4_session *session;
1839 struct nfs4_slot_table *tp; 1840 struct nfs4_slot_table *tp;
1840 struct nfs4_slot *slot; 1841 struct nfs4_slot *slot = args->sa_slot;
1841 __be32 *p; 1842 __be32 *p;
1842 1843
1843 if (!session) 1844 if (slot == NULL)
1844 return; 1845 return;
1845 1846
1846 tp = &session->fc_slot_table; 1847 tp = slot->table;
1847 1848 session = tp->session;
1848 WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE);
1849 slot = tp->slots + args->sa_slotid;
1850 1849
1851 encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr); 1850 encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr);
1852 1851
@@ -1860,12 +1859,12 @@ static void encode_sequence(struct xdr_stream *xdr,
1860 ((u32 *)session->sess_id.data)[1], 1859 ((u32 *)session->sess_id.data)[1],
1861 ((u32 *)session->sess_id.data)[2], 1860 ((u32 *)session->sess_id.data)[2],
1862 ((u32 *)session->sess_id.data)[3], 1861 ((u32 *)session->sess_id.data)[3],
1863 slot->seq_nr, args->sa_slotid, 1862 slot->seq_nr, slot->slot_nr,
1864 tp->highest_used_slotid, args->sa_cache_this); 1863 tp->highest_used_slotid, args->sa_cache_this);
1865 p = reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 16); 1864 p = reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 16);
1866 p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); 1865 p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
1867 *p++ = cpu_to_be32(slot->seq_nr); 1866 *p++ = cpu_to_be32(slot->seq_nr);
1868 *p++ = cpu_to_be32(args->sa_slotid); 1867 *p++ = cpu_to_be32(slot->slot_nr);
1869 *p++ = cpu_to_be32(tp->highest_used_slotid); 1868 *p++ = cpu_to_be32(tp->highest_used_slotid);
1870 *p = cpu_to_be32(args->sa_cache_this); 1869 *p = cpu_to_be32(args->sa_cache_this);
1871#endif /* CONFIG_NFS_V4_1 */ 1870#endif /* CONFIG_NFS_V4_1 */
@@ -2027,8 +2026,9 @@ static void encode_free_stateid(struct xdr_stream *xdr,
2027static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args) 2026static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
2028{ 2027{
2029#if defined(CONFIG_NFS_V4_1) 2028#if defined(CONFIG_NFS_V4_1)
2030 if (args->sa_session) 2029
2031 return args->sa_session->clp->cl_mvops->minor_version; 2030 if (args->sa_slot)
2031 return args->sa_slot->table->session->clp->cl_mvops->minor_version;
2032#endif /* CONFIG_NFS_V4_1 */ 2032#endif /* CONFIG_NFS_V4_1 */
2033 return 0; 2033 return 0;
2034} 2034}
@@ -5509,12 +5509,13 @@ static int decode_sequence(struct xdr_stream *xdr,
5509 struct rpc_rqst *rqstp) 5509 struct rpc_rqst *rqstp)
5510{ 5510{
5511#if defined(CONFIG_NFS_V4_1) 5511#if defined(CONFIG_NFS_V4_1)
5512 struct nfs4_session *session;
5512 struct nfs4_sessionid id; 5513 struct nfs4_sessionid id;
5513 u32 dummy; 5514 u32 dummy;
5514 int status; 5515 int status;
5515 __be32 *p; 5516 __be32 *p;
5516 5517
5517 if (!res->sr_session) 5518 if (res->sr_slot == NULL)
5518 return 0; 5519 return 0;
5519 5520
5520 status = decode_op_hdr(xdr, OP_SEQUENCE); 5521 status = decode_op_hdr(xdr, OP_SEQUENCE);
@@ -5528,8 +5529,9 @@ static int decode_sequence(struct xdr_stream *xdr,
5528 * sequence number, the server is looney tunes. 5529 * sequence number, the server is looney tunes.
5529 */ 5530 */
5530 status = -EREMOTEIO; 5531 status = -EREMOTEIO;
5532 session = res->sr_slot->table->session;
5531 5533
5532 if (memcmp(id.data, res->sr_session->sess_id.data, 5534 if (memcmp(id.data, session->sess_id.data,
5533 NFS4_MAX_SESSIONID_LEN)) { 5535 NFS4_MAX_SESSIONID_LEN)) {
5534 dprintk("%s Invalid session id\n", __func__); 5536 dprintk("%s Invalid session id\n", __func__);
5535 goto out_err; 5537 goto out_err;
@@ -5547,14 +5549,14 @@ static int decode_sequence(struct xdr_stream *xdr,
5547 } 5549 }
5548 /* slot id */ 5550 /* slot id */
5549 dummy = be32_to_cpup(p++); 5551 dummy = be32_to_cpup(p++);
5550 if (dummy != res->sr_slot - res->sr_session->fc_slot_table.slots) { 5552 if (dummy != res->sr_slot->slot_nr) {
5551 dprintk("%s Invalid slot id\n", __func__); 5553 dprintk("%s Invalid slot id\n", __func__);
5552 goto out_err; 5554 goto out_err;
5553 } 5555 }
5554 /* highest slot id - currently not processed */ 5556 /* highest slot id */
5555 dummy = be32_to_cpup(p++); 5557 res->sr_highest_slotid = be32_to_cpup(p++);
5556 /* target highest slot id - currently not processed */ 5558 /* target highest slot id */
5557 dummy = be32_to_cpup(p++); 5559 res->sr_target_highest_slotid = be32_to_cpup(p++);
5558 /* result flags */ 5560 /* result flags */
5559 res->sr_status_flags = be32_to_cpup(p); 5561 res->sr_status_flags = be32_to_cpup(p);
5560 status = 0; 5562 status = 0;
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index 874613545301..a9ebd817278b 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -148,17 +148,6 @@ end_offset(u64 start, u64 len)
148 return end >= start ? end : NFS4_MAX_UINT64; 148 return end >= start ? end : NFS4_MAX_UINT64;
149} 149}
150 150
151/* last octet in a range */
152static inline u64
153last_byte_offset(u64 start, u64 len)
154{
155 u64 end;
156
157 BUG_ON(!len);
158 end = start + len;
159 return end > start ? end - 1 : NFS4_MAX_UINT64;
160}
161
162static void _fix_verify_io_params(struct pnfs_layout_segment *lseg, 151static void _fix_verify_io_params(struct pnfs_layout_segment *lseg,
163 struct page ***p_pages, unsigned *p_pgbase, 152 struct page ***p_pages, unsigned *p_pgbase,
164 u64 offset, unsigned long count) 153 u64 offset, unsigned long count)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2878f97bd78d..e7165d915362 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -369,17 +369,6 @@ end_offset(u64 start, u64 len)
369 return end >= start ? end : NFS4_MAX_UINT64; 369 return end >= start ? end : NFS4_MAX_UINT64;
370} 370}
371 371
372/* last octet in a range */
373static inline u64
374last_byte_offset(u64 start, u64 len)
375{
376 u64 end;
377
378 BUG_ON(!len);
379 end = start + len;
380 return end > start ? end - 1 : NFS4_MAX_UINT64;
381}
382
383/* 372/*
384 * is l2 fully contained in l1? 373 * is l2 fully contained in l1?
385 * start1 end1 374 * start1 end1
@@ -645,7 +634,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
645 634
646 dprintk("--> %s\n", __func__); 635 dprintk("--> %s\n", __func__);
647 636
648 BUG_ON(ctx == NULL);
649 lgp = kzalloc(sizeof(*lgp), gfp_flags); 637 lgp = kzalloc(sizeof(*lgp), gfp_flags);
650 if (lgp == NULL) 638 if (lgp == NULL)
651 return NULL; 639 return NULL;
@@ -1126,7 +1114,6 @@ pnfs_update_layout(struct inode *ino,
1126 * chance of a CB_LAYOUTRECALL(FILE) coming in. 1114 * chance of a CB_LAYOUTRECALL(FILE) coming in.
1127 */ 1115 */
1128 spin_lock(&clp->cl_lock); 1116 spin_lock(&clp->cl_lock);
1129 BUG_ON(!list_empty(&lo->plh_layouts));
1130 list_add_tail(&lo->plh_layouts, &server->layouts); 1117 list_add_tail(&lo->plh_layouts, &server->layouts);
1131 spin_unlock(&clp->cl_lock); 1118 spin_unlock(&clp->cl_lock);
1132 } 1119 }
@@ -1222,7 +1209,7 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r
1222{ 1209{
1223 u64 rd_size = req->wb_bytes; 1210 u64 rd_size = req->wb_bytes;
1224 1211
1225 BUG_ON(pgio->pg_lseg != NULL); 1212 WARN_ON_ONCE(pgio->pg_lseg != NULL);
1226 1213
1227 if (req->wb_offset != req->wb_pgbase) { 1214 if (req->wb_offset != req->wb_pgbase) {
1228 nfs_pageio_reset_read_mds(pgio); 1215 nfs_pageio_reset_read_mds(pgio);
@@ -1251,7 +1238,7 @@ void
1251pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, 1238pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
1252 struct nfs_page *req, u64 wb_size) 1239 struct nfs_page *req, u64 wb_size)
1253{ 1240{
1254 BUG_ON(pgio->pg_lseg != NULL); 1241 WARN_ON_ONCE(pgio->pg_lseg != NULL);
1255 1242
1256 if (req->wb_offset != req->wb_pgbase) { 1243 if (req->wb_offset != req->wb_pgbase) {
1257 nfs_pageio_reset_write_mds(pgio); 1244 nfs_pageio_reset_write_mds(pgio);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 50a88c3546ed..f084dac948e1 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -47,39 +47,6 @@
47#define NFSDBG_FACILITY NFSDBG_PROC 47#define NFSDBG_FACILITY NFSDBG_PROC
48 48
49/* 49/*
50 * wrapper to handle the -EKEYEXPIRED error message. This should generally
51 * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
52 * support the NFSERR_JUKEBOX error code, but we handle this situation in the
53 * same way that we handle that error with NFSv3.
54 */
55static int
56nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
57{
58 int res;
59 do {
60 res = rpc_call_sync(clnt, msg, flags);
61 if (res != -EKEYEXPIRED)
62 break;
63 freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
64 res = -ERESTARTSYS;
65 } while (!fatal_signal_pending(current));
66 return res;
67}
68
69#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags)
70
71static int
72nfs_async_handle_expired_key(struct rpc_task *task)
73{
74 if (task->tk_status != -EKEYEXPIRED)
75 return 0;
76 task->tk_status = 0;
77 rpc_restart_call(task);
78 rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
79 return 1;
80}
81
82/*
83 * Bare-bones access to getattr: this is for nfs_read_super. 50 * Bare-bones access to getattr: this is for nfs_read_super.
84 */ 51 */
85static int 52static int
@@ -364,8 +331,6 @@ static void nfs_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlink
364 331
365static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) 332static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
366{ 333{
367 if (nfs_async_handle_expired_key(task))
368 return 0;
369 nfs_mark_for_revalidate(dir); 334 nfs_mark_for_revalidate(dir);
370 return 1; 335 return 1;
371} 336}
@@ -385,8 +350,6 @@ static int
385nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir, 350nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
386 struct inode *new_dir) 351 struct inode *new_dir)
387{ 352{
388 if (nfs_async_handle_expired_key(task))
389 return 0;
390 nfs_mark_for_revalidate(old_dir); 353 nfs_mark_for_revalidate(old_dir);
391 nfs_mark_for_revalidate(new_dir); 354 nfs_mark_for_revalidate(new_dir);
392 return 1; 355 return 1;
@@ -642,9 +605,6 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
642{ 605{
643 struct inode *inode = data->header->inode; 606 struct inode *inode = data->header->inode;
644 607
645 if (nfs_async_handle_expired_key(task))
646 return -EAGAIN;
647
648 nfs_invalidate_atime(inode); 608 nfs_invalidate_atime(inode);
649 if (task->tk_status >= 0) { 609 if (task->tk_status >= 0) {
650 nfs_refresh_inode(inode, data->res.fattr); 610 nfs_refresh_inode(inode, data->res.fattr);
@@ -671,9 +631,6 @@ static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
671{ 631{
672 struct inode *inode = data->header->inode; 632 struct inode *inode = data->header->inode;
673 633
674 if (nfs_async_handle_expired_key(task))
675 return -EAGAIN;
676
677 if (task->tk_status >= 0) 634 if (task->tk_status >= 0)
678 nfs_post_op_update_inode_force_wcc(inode, data->res.fattr); 635 nfs_post_op_update_inode_force_wcc(inode, data->res.fattr);
679 return 0; 636 return 0;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 652d3f7176a9..aa5315bb3666 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -64,6 +64,7 @@
64#include "iostat.h" 64#include "iostat.h"
65#include "internal.h" 65#include "internal.h"
66#include "fscache.h" 66#include "fscache.h"
67#include "nfs4session.h"
67#include "pnfs.h" 68#include "pnfs.h"
68#include "nfs.h" 69#include "nfs.h"
69 70
@@ -307,6 +308,7 @@ const struct super_operations nfs_sops = {
307 .alloc_inode = nfs_alloc_inode, 308 .alloc_inode = nfs_alloc_inode,
308 .destroy_inode = nfs_destroy_inode, 309 .destroy_inode = nfs_destroy_inode,
309 .write_inode = nfs_write_inode, 310 .write_inode = nfs_write_inode,
311 .drop_inode = nfs_drop_inode,
310 .put_super = nfs_put_super, 312 .put_super = nfs_put_super,
311 .statfs = nfs_statfs, 313 .statfs = nfs_statfs,
312 .evict_inode = nfs_evict_inode, 314 .evict_inode = nfs_evict_inode,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 9347ab7c9574..5209916e1222 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -202,7 +202,6 @@ out:
202/* A writeback failed: mark the page as bad, and invalidate the page cache */ 202/* A writeback failed: mark the page as bad, and invalidate the page cache */
203static void nfs_set_pageerror(struct page *page) 203static void nfs_set_pageerror(struct page *page)
204{ 204{
205 SetPageError(page);
206 nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page)); 205 nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page));
207} 206}
208 207
@@ -239,21 +238,18 @@ int nfs_congestion_kb;
239#define NFS_CONGESTION_OFF_THRESH \ 238#define NFS_CONGESTION_OFF_THRESH \
240 (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2)) 239 (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
241 240
242static int nfs_set_page_writeback(struct page *page) 241static void nfs_set_page_writeback(struct page *page)
243{ 242{
243 struct nfs_server *nfss = NFS_SERVER(page_file_mapping(page)->host);
244 int ret = test_set_page_writeback(page); 244 int ret = test_set_page_writeback(page);
245 245
246 if (!ret) { 246 WARN_ON_ONCE(ret != 0);
247 struct inode *inode = page_file_mapping(page)->host;
248 struct nfs_server *nfss = NFS_SERVER(inode);
249 247
250 if (atomic_long_inc_return(&nfss->writeback) > 248 if (atomic_long_inc_return(&nfss->writeback) >
251 NFS_CONGESTION_ON_THRESH) { 249 NFS_CONGESTION_ON_THRESH) {
252 set_bdi_congested(&nfss->backing_dev_info, 250 set_bdi_congested(&nfss->backing_dev_info,
253 BLK_RW_ASYNC); 251 BLK_RW_ASYNC);
254 }
255 } 252 }
256 return ret;
257} 253}
258 254
259static void nfs_end_page_writeback(struct page *page) 255static void nfs_end_page_writeback(struct page *page)
@@ -315,10 +311,10 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
315 if (IS_ERR(req)) 311 if (IS_ERR(req))
316 goto out; 312 goto out;
317 313
318 ret = nfs_set_page_writeback(page); 314 nfs_set_page_writeback(page);
319 BUG_ON(ret != 0); 315 WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
320 BUG_ON(test_bit(PG_CLEAN, &req->wb_flags));
321 316
317 ret = 0;
322 if (!nfs_pageio_add_request(pgio, req)) { 318 if (!nfs_pageio_add_request(pgio, req)) {
323 nfs_redirty_request(req); 319 nfs_redirty_request(req);
324 ret = pgio->pg_error; 320 ret = pgio->pg_error;
@@ -451,8 +447,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
451 struct inode *inode = req->wb_context->dentry->d_inode; 447 struct inode *inode = req->wb_context->dentry->d_inode;
452 struct nfs_inode *nfsi = NFS_I(inode); 448 struct nfs_inode *nfsi = NFS_I(inode);
453 449
454 BUG_ON (!NFS_WBACK_BUSY(req));
455
456 spin_lock(&inode->i_lock); 450 spin_lock(&inode->i_lock);
457 if (likely(!PageSwapCache(req->wb_page))) { 451 if (likely(!PageSwapCache(req->wb_page))) {
458 set_page_private(req->wb_page, 0); 452 set_page_private(req->wb_page, 0);
@@ -884,7 +878,7 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
884{ 878{
885 if (nfs_have_delegated_attributes(inode)) 879 if (nfs_have_delegated_attributes(inode))
886 goto out; 880 goto out;
887 if (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE) 881 if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE))
888 return false; 882 return false;
889out: 883out:
890 return PageUptodate(page) != 0; 884 return PageUptodate(page) != 0;
@@ -1727,7 +1721,6 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
1727 struct nfs_page *req; 1721 struct nfs_page *req;
1728 int ret = 0; 1722 int ret = 0;
1729 1723
1730 BUG_ON(!PageLocked(page));
1731 for (;;) { 1724 for (;;) {
1732 wait_on_page_writeback(page); 1725 wait_on_page_writeback(page);
1733 req = nfs_page_find_request(page); 1726 req = nfs_page_find_request(page);
@@ -1829,7 +1822,7 @@ int __init nfs_init_writepagecache(void)
1829 goto out_destroy_write_mempool; 1822 goto out_destroy_write_mempool;
1830 1823
1831 nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, 1824 nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
1832 nfs_wdata_cachep); 1825 nfs_cdata_cachep);
1833 if (nfs_commit_mempool == NULL) 1826 if (nfs_commit_mempool == NULL)
1834 goto out_destroy_commit_cache; 1827 goto out_destroy_commit_cache;
1835 1828