aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 16:17:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 16:17:26 -0500
commit18bce371ae09af6c20ee62c1092a4d1d0e84dd49 (patch)
treef3467fafd8e49392e3f6efef7b88a7b4dd3b7b06
parentec08bdb148767f1193f5f3028749ed865ac27181 (diff)
parenta8f2800b4f7b76cecb7209cb6a7d2b14904fc711 (diff)
Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.38' of git://linux-nfs.org/~bfields/linux: (62 commits) nfsd4: fix callback restarting nfsd: break lease on unlink, link, and rename nfsd4: break lease on nfsd setattr nfsd: don't support msnfs export option nfsd4: initialize cb_per_client nfsd4: allow restarting callbacks nfsd4: simplify nfsd4_cb_prepare nfsd4: give out delegations more quickly in 4.1 case nfsd4: add helper function to run callbacks nfsd4: make sure sequence flags are set after destroy_session nfsd4: re-probe callback on connection loss nfsd4: set sequence flag when backchannel is down nfsd4: keep finer-grained callback status rpc: allow xprt_class->setup to return a preexisting xprt rpc: keep backchannel xprt as long as server connection rpc: move sk_bc_xprt to svc_xprt nfsd4: allow backchannel recovery nfsd4: support BIND_CONN_TO_SESSION nfsd4: modify session list under cl_lock Documentation: fl_mylease no longer exists ... Fix up conflicts in fs/nfsd/vfs.c with the vfs-scale work. The vfs-scale work touched some msnfs cases, and this merge removes support for that entirely, so the conflict was trivial to resolve.
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--fs/locks.c8
-rw-r--r--fs/nfsd/acl.h (renamed from include/linux/nfs4_acl.h)2
-rw-r--r--fs/nfsd/export.c4
-rw-r--r--fs/nfsd/idmap.h (renamed from include/linux/nfsd_idmap.h)6
-rw-r--r--fs/nfsd/nfs3proc.c8
-rw-r--r--fs/nfsd/nfs4acl.c2
-rw-r--r--fs/nfsd/nfs4callback.c151
-rw-r--r--fs/nfsd/nfs4idmap.c15
-rw-r--r--fs/nfsd/nfs4proc.c59
-rw-r--r--fs/nfsd/nfs4recover.c1
-rw-r--r--fs/nfsd/nfs4state.c243
-rw-r--r--fs/nfsd/nfs4xdr.c115
-rw-r--r--fs/nfsd/nfsctl.c4
-rw-r--r--fs/nfsd/nfsd.h1
-rw-r--r--fs/nfsd/nfsproc.c6
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/nfsd/state.h16
-rw-r--r--fs/nfsd/vfs.c85
-rw-r--r--fs/nfsd/xdr4.h9
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/nfs4.h6
-rw-r--r--include/linux/nfsd/export.h2
-rw-r--r--include/linux/sunrpc/cache.h3
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/linux/sunrpc/svc_xprt.h2
-rw-r--r--include/linux/sunrpc/svcsock.h1
-rw-r--r--include/linux/sunrpc/xprt.h1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/cache.c54
-rw-r--r--net/sunrpc/svc.c3
-rw-r--r--net/sunrpc/svc_xprt.c97
-rw-r--r--net/sunrpc/svcauth.c1
-rw-r--r--net/sunrpc/svcauth_unix.c17
-rw-r--r--net/sunrpc/svcsock.c20
-rw-r--r--net/sunrpc/xprt.c5
-rw-r--r--net/sunrpc/xprtsock.c34
38 files changed, 608 insertions, 383 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 977d8919cc6..ef9349a4b5d 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -343,7 +343,6 @@ prototypes:
343 int (*fl_grant)(struct file_lock *, struct file_lock *, int); 343 int (*fl_grant)(struct file_lock *, struct file_lock *, int);
344 void (*fl_release_private)(struct file_lock *); 344 void (*fl_release_private)(struct file_lock *);
345 void (*fl_break)(struct file_lock *); /* break_lease callback */ 345 void (*fl_break)(struct file_lock *); /* break_lease callback */
346 int (*fl_mylease)(struct file_lock *, struct file_lock *);
347 int (*fl_change)(struct file_lock **, int); 346 int (*fl_change)(struct file_lock **, int);
348 347
349locking rules: 348locking rules:
@@ -353,7 +352,6 @@ fl_notify: yes no
353fl_grant: no no 352fl_grant: no no
354fl_release_private: maybe no 353fl_release_private: maybe no
355fl_break: yes no 354fl_break: yes no
356fl_mylease: yes no
357fl_change yes no 355fl_change yes no
358 356
359--------------------------- buffer_head ----------------------------------- 357--------------------------- buffer_head -----------------------------------
diff --git a/fs/locks.c b/fs/locks.c
index 08415b2a6d3..0f3998291f7 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -444,15 +444,9 @@ static void lease_release_private_callback(struct file_lock *fl)
444 fl->fl_file->f_owner.signum = 0; 444 fl->fl_file->f_owner.signum = 0;
445} 445}
446 446
447static int lease_mylease_callback(struct file_lock *fl, struct file_lock *try)
448{
449 return fl->fl_file == try->fl_file;
450}
451
452static const struct lock_manager_operations lease_manager_ops = { 447static const struct lock_manager_operations lease_manager_ops = {
453 .fl_break = lease_break_callback, 448 .fl_break = lease_break_callback,
454 .fl_release_private = lease_release_private_callback, 449 .fl_release_private = lease_release_private_callback,
455 .fl_mylease = lease_mylease_callback,
456 .fl_change = lease_modify, 450 .fl_change = lease_modify,
457}; 451};
458 452
@@ -1405,7 +1399,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
1405 for (before = &inode->i_flock; 1399 for (before = &inode->i_flock;
1406 ((fl = *before) != NULL) && IS_LEASE(fl); 1400 ((fl = *before) != NULL) && IS_LEASE(fl);
1407 before = &fl->fl_next) { 1401 before = &fl->fl_next) {
1408 if (lease->fl_lmops->fl_mylease(fl, lease)) 1402 if (fl->fl_file == filp)
1409 my_before = before; 1403 my_before = before;
1410 else if (fl->fl_type == (F_INPROGRESS | F_UNLCK)) 1404 else if (fl->fl_type == (F_INPROGRESS | F_UNLCK))
1411 /* 1405 /*
diff --git a/include/linux/nfs4_acl.h b/fs/nfsd/acl.h
index c9c05a78e9b..34e5c40af5e 100644
--- a/include/linux/nfs4_acl.h
+++ b/fs/nfsd/acl.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * include/linux/nfs4_acl.c
3 *
4 * Common NFSv4 ACL handling definitions. 2 * Common NFSv4 ACL handling definitions.
5 * 3 *
6 * Copyright (c) 2002 The Regents of the University of Michigan. 4 * Copyright (c) 2002 The Regents of the University of Michigan.
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index c0fcb7ab7f6..8b31e5f8795 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -1,4 +1,3 @@
1#define MSNFS /* HACK HACK */
2/* 1/*
3 * NFS exporting and validation. 2 * NFS exporting and validation.
4 * 3 *
@@ -1444,9 +1443,6 @@ static struct flags {
1444 { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, 1443 { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
1445 { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, 1444 { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
1446 { NFSEXP_V4ROOT, {"v4root", ""}}, 1445 { NFSEXP_V4ROOT, {"v4root", ""}},
1447#ifdef MSNFS
1448 { NFSEXP_MSNFS, {"msnfs", ""}},
1449#endif
1450 { 0, {"", ""}} 1446 { 0, {"", ""}}
1451}; 1447};
1452 1448
diff --git a/include/linux/nfsd_idmap.h b/fs/nfsd/idmap.h
index d4a2ac18bd4..2f3be132153 100644
--- a/include/linux/nfsd_idmap.h
+++ b/fs/nfsd/idmap.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * include/linux/nfsd_idmap.h
3 *
4 * Mapping of UID to name and vice versa. 2 * Mapping of UID to name and vice versa.
5 * 3 *
6 * Copyright (c) 2002, 2003 The Regents of the University of 4 * Copyright (c) 2002, 2003 The Regents of the University of
@@ -56,8 +54,8 @@ static inline void nfsd_idmap_shutdown(void)
56} 54}
57#endif 55#endif
58 56
59int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); 57__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
60int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *); 58__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
61int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *); 59int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *);
62int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *); 60int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *);
63 61
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 5b7e3021e06..2247fc91d5e 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -151,10 +151,10 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
151 __be32 nfserr; 151 __be32 nfserr;
152 u32 max_blocksize = svc_max_payload(rqstp); 152 u32 max_blocksize = svc_max_payload(rqstp);
153 153
154 dprintk("nfsd: READ(3) %s %lu bytes at %lu\n", 154 dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n",
155 SVCFH_fmt(&argp->fh), 155 SVCFH_fmt(&argp->fh),
156 (unsigned long) argp->count, 156 (unsigned long) argp->count,
157 (unsigned long) argp->offset); 157 (unsigned long long) argp->offset);
158 158
159 /* Obtain buffer pointer for payload. 159 /* Obtain buffer pointer for payload.
160 * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) 160 * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof)
@@ -191,10 +191,10 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
191 __be32 nfserr; 191 __be32 nfserr;
192 unsigned long cnt = argp->len; 192 unsigned long cnt = argp->len;
193 193
194 dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n", 194 dprintk("nfsd: WRITE(3) %s %d bytes at %Lu%s\n",
195 SVCFH_fmt(&argp->fh), 195 SVCFH_fmt(&argp->fh),
196 argp->len, 196 argp->len,
197 (unsigned long) argp->offset, 197 (unsigned long long) argp->offset,
198 argp->stable? " stable" : ""); 198 argp->stable? " stable" : "");
199 199
200 fh_copy(&resp->fh, &argp->fh); 200 fh_copy(&resp->fh, &argp->fh);
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index e4805261515..ad88f1c0a4c 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -36,7 +36,7 @@
36 36
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/nfs_fs.h> 38#include <linux/nfs_fs.h>
39#include <linux/nfs4_acl.h> 39#include "acl.h"
40 40
41 41
42/* mode bit translations: */ 42/* mode bit translations: */
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 21a63da305f..3be975e1891 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -628,10 +628,8 @@ static int max_cb_time(void)
628 return max(nfsd4_lease/10, (time_t)1) * HZ; 628 return max(nfsd4_lease/10, (time_t)1) * HZ;
629} 629}
630 630
631/* Reference counting, callback cleanup, etc., all look racy as heck.
632 * And why is cl_cb_set an atomic? */
633 631
634int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn) 632static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
635{ 633{
636 struct rpc_timeout timeparms = { 634 struct rpc_timeout timeparms = {
637 .to_initval = max_cb_time(), 635 .to_initval = max_cb_time(),
@@ -641,6 +639,7 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
641 .net = &init_net, 639 .net = &init_net,
642 .address = (struct sockaddr *) &conn->cb_addr, 640 .address = (struct sockaddr *) &conn->cb_addr,
643 .addrsize = conn->cb_addrlen, 641 .addrsize = conn->cb_addrlen,
642 .saddress = (struct sockaddr *) &conn->cb_saddr,
644 .timeout = &timeparms, 643 .timeout = &timeparms,
645 .program = &cb_program, 644 .program = &cb_program,
646 .version = 0, 645 .version = 0,
@@ -657,6 +656,10 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
657 args.protocol = XPRT_TRANSPORT_TCP; 656 args.protocol = XPRT_TRANSPORT_TCP;
658 clp->cl_cb_ident = conn->cb_ident; 657 clp->cl_cb_ident = conn->cb_ident;
659 } else { 658 } else {
659 if (!conn->cb_xprt)
660 return -EINVAL;
661 clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
662 clp->cl_cb_session = ses;
660 args.bc_xprt = conn->cb_xprt; 663 args.bc_xprt = conn->cb_xprt;
661 args.prognumber = clp->cl_cb_session->se_cb_prog; 664 args.prognumber = clp->cl_cb_session->se_cb_prog;
662 args.protocol = XPRT_TRANSPORT_BC_TCP; 665 args.protocol = XPRT_TRANSPORT_BC_TCP;
@@ -679,14 +682,20 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason)
679 (int)clp->cl_name.len, clp->cl_name.data, reason); 682 (int)clp->cl_name.len, clp->cl_name.data, reason);
680} 683}
681 684
685static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
686{
687 clp->cl_cb_state = NFSD4_CB_DOWN;
688 warn_no_callback_path(clp, reason);
689}
690
682static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) 691static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
683{ 692{
684 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null); 693 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
685 694
686 if (task->tk_status) 695 if (task->tk_status)
687 warn_no_callback_path(clp, task->tk_status); 696 nfsd4_mark_cb_down(clp, task->tk_status);
688 else 697 else
689 atomic_set(&clp->cl_cb_set, 1); 698 clp->cl_cb_state = NFSD4_CB_UP;
690} 699}
691 700
692static const struct rpc_call_ops nfsd4_cb_probe_ops = { 701static const struct rpc_call_ops nfsd4_cb_probe_ops = {
@@ -709,6 +718,11 @@ int set_callback_cred(void)
709 718
710static struct workqueue_struct *callback_wq; 719static struct workqueue_struct *callback_wq;
711 720
721static void run_nfsd4_cb(struct nfsd4_callback *cb)
722{
723 queue_work(callback_wq, &cb->cb_work);
724}
725
712static void do_probe_callback(struct nfs4_client *clp) 726static void do_probe_callback(struct nfs4_client *clp)
713{ 727{
714 struct nfsd4_callback *cb = &clp->cl_cb_null; 728 struct nfsd4_callback *cb = &clp->cl_cb_null;
@@ -723,7 +737,7 @@ static void do_probe_callback(struct nfs4_client *clp)
723 737
724 cb->cb_ops = &nfsd4_cb_probe_ops; 738 cb->cb_ops = &nfsd4_cb_probe_ops;
725 739
726 queue_work(callback_wq, &cb->cb_work); 740 run_nfsd4_cb(cb);
727} 741}
728 742
729/* 743/*
@@ -732,14 +746,21 @@ static void do_probe_callback(struct nfs4_client *clp)
732 */ 746 */
733void nfsd4_probe_callback(struct nfs4_client *clp) 747void nfsd4_probe_callback(struct nfs4_client *clp)
734{ 748{
749 /* XXX: atomicity? Also, should we be using cl_cb_flags? */
750 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
735 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); 751 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags);
736 do_probe_callback(clp); 752 do_probe_callback(clp);
737} 753}
738 754
739void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn) 755void nfsd4_probe_callback_sync(struct nfs4_client *clp)
740{ 756{
741 BUG_ON(atomic_read(&clp->cl_cb_set)); 757 nfsd4_probe_callback(clp);
758 flush_workqueue(callback_wq);
759}
742 760
761void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
762{
763 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
743 spin_lock(&clp->cl_lock); 764 spin_lock(&clp->cl_lock);
744 memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn)); 765 memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn));
745 spin_unlock(&clp->cl_lock); 766 spin_unlock(&clp->cl_lock);
@@ -750,24 +771,14 @@ void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
750 * If the slot is available, then mark it busy. Otherwise, set the 771 * If the slot is available, then mark it busy. Otherwise, set the
751 * thread for sleeping on the callback RPC wait queue. 772 * thread for sleeping on the callback RPC wait queue.
752 */ 773 */
753static int nfsd41_cb_setup_sequence(struct nfs4_client *clp, 774static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
754 struct rpc_task *task)
755{ 775{
756 u32 *ptr = (u32 *)clp->cl_cb_session->se_sessionid.data;
757 int status = 0;
758
759 dprintk("%s: %u:%u:%u:%u\n", __func__,
760 ptr[0], ptr[1], ptr[2], ptr[3]);
761
762 if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { 776 if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
763 rpc_sleep_on(&clp->cl_cb_waitq, task, NULL); 777 rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
764 dprintk("%s slot is busy\n", __func__); 778 dprintk("%s slot is busy\n", __func__);
765 status = -EAGAIN; 779 return false;
766 goto out;
767 } 780 }
768out: 781 return true;
769 dprintk("%s status=%d\n", __func__, status);
770 return status;
771} 782}
772 783
773/* 784/*
@@ -780,20 +791,19 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
780 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); 791 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
781 struct nfs4_client *clp = dp->dl_client; 792 struct nfs4_client *clp = dp->dl_client;
782 u32 minorversion = clp->cl_minorversion; 793 u32 minorversion = clp->cl_minorversion;
783 int status = 0;
784 794
785 cb->cb_minorversion = minorversion; 795 cb->cb_minorversion = minorversion;
786 if (minorversion) { 796 if (minorversion) {
787 status = nfsd41_cb_setup_sequence(clp, task); 797 if (!nfsd41_cb_get_slot(clp, task))
788 if (status) {
789 if (status != -EAGAIN) {
790 /* terminate rpc task */
791 task->tk_status = status;
792 task->tk_action = NULL;
793 }
794 return; 798 return;
795 }
796 } 799 }
800 spin_lock(&clp->cl_lock);
801 if (list_empty(&cb->cb_per_client)) {
802 /* This is the first call, not a restart */
803 cb->cb_done = false;
804 list_add(&cb->cb_per_client, &clp->cl_callbacks);
805 }
806 spin_unlock(&clp->cl_lock);
797 rpc_call_start(task); 807 rpc_call_start(task);
798} 808}
799 809
@@ -829,15 +839,18 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
829 839
830 nfsd4_cb_done(task, calldata); 840 nfsd4_cb_done(task, calldata);
831 841
832 if (current_rpc_client == NULL) { 842 if (current_rpc_client != task->tk_client) {
833 /* We're shutting down; give up. */ 843 /* We're shutting down or changing cl_cb_client; leave
834 /* XXX: err, or is it ok just to fall through 844 * it to nfsd4_process_cb_update to restart the call if
835 * and rpc_restart_call? */ 845 * necessary. */
836 return; 846 return;
837 } 847 }
838 848
849 if (cb->cb_done)
850 return;
839 switch (task->tk_status) { 851 switch (task->tk_status) {
840 case 0: 852 case 0:
853 cb->cb_done = true;
841 return; 854 return;
842 case -EBADHANDLE: 855 case -EBADHANDLE:
843 case -NFS4ERR_BAD_STATEID: 856 case -NFS4ERR_BAD_STATEID:
@@ -846,32 +859,30 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
846 break; 859 break;
847 default: 860 default:
848 /* Network partition? */ 861 /* Network partition? */
849 atomic_set(&clp->cl_cb_set, 0); 862 nfsd4_mark_cb_down(clp, task->tk_status);
850 warn_no_callback_path(clp, task->tk_status);
851 if (current_rpc_client != task->tk_client) {
852 /* queue a callback on the new connection: */
853 atomic_inc(&dp->dl_count);
854 nfsd4_cb_recall(dp);
855 return;
856 }
857 } 863 }
858 if (dp->dl_retries--) { 864 if (dp->dl_retries--) {
859 rpc_delay(task, 2*HZ); 865 rpc_delay(task, 2*HZ);
860 task->tk_status = 0; 866 task->tk_status = 0;
861 rpc_restart_call_prepare(task); 867 rpc_restart_call_prepare(task);
862 return; 868 return;
863 } else {
864 atomic_set(&clp->cl_cb_set, 0);
865 warn_no_callback_path(clp, task->tk_status);
866 } 869 }
870 nfsd4_mark_cb_down(clp, task->tk_status);
871 cb->cb_done = true;
867} 872}
868 873
869static void nfsd4_cb_recall_release(void *calldata) 874static void nfsd4_cb_recall_release(void *calldata)
870{ 875{
871 struct nfsd4_callback *cb = calldata; 876 struct nfsd4_callback *cb = calldata;
877 struct nfs4_client *clp = cb->cb_clp;
872 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); 878 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
873 879
874 nfs4_put_delegation(dp); 880 if (cb->cb_done) {
881 spin_lock(&clp->cl_lock);
882 list_del(&cb->cb_per_client);
883 spin_unlock(&clp->cl_lock);
884 nfs4_put_delegation(dp);
885 }
875} 886}
876 887
877static const struct rpc_call_ops nfsd4_cb_recall_ops = { 888static const struct rpc_call_ops nfsd4_cb_recall_ops = {
@@ -906,16 +917,33 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp)
906 flush_workqueue(callback_wq); 917 flush_workqueue(callback_wq);
907} 918}
908 919
909void nfsd4_release_cb(struct nfsd4_callback *cb) 920static void nfsd4_release_cb(struct nfsd4_callback *cb)
910{ 921{
911 if (cb->cb_ops->rpc_release) 922 if (cb->cb_ops->rpc_release)
912 cb->cb_ops->rpc_release(cb); 923 cb->cb_ops->rpc_release(cb);
913} 924}
914 925
915void nfsd4_process_cb_update(struct nfsd4_callback *cb) 926/* requires cl_lock: */
927static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp)
928{
929 struct nfsd4_session *s;
930 struct nfsd4_conn *c;
931
932 list_for_each_entry(s, &clp->cl_sessions, se_perclnt) {
933 list_for_each_entry(c, &s->se_conns, cn_persession) {
934 if (c->cn_flags & NFS4_CDFC4_BACK)
935 return c;
936 }
937 }
938 return NULL;
939}
940
941static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
916{ 942{
917 struct nfs4_cb_conn conn; 943 struct nfs4_cb_conn conn;
918 struct nfs4_client *clp = cb->cb_clp; 944 struct nfs4_client *clp = cb->cb_clp;
945 struct nfsd4_session *ses = NULL;
946 struct nfsd4_conn *c;
919 int err; 947 int err;
920 948
921 /* 949 /*
@@ -926,6 +954,10 @@ void nfsd4_process_cb_update(struct nfsd4_callback *cb)
926 rpc_shutdown_client(clp->cl_cb_client); 954 rpc_shutdown_client(clp->cl_cb_client);
927 clp->cl_cb_client = NULL; 955 clp->cl_cb_client = NULL;
928 } 956 }
957 if (clp->cl_cb_conn.cb_xprt) {
958 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
959 clp->cl_cb_conn.cb_xprt = NULL;
960 }
929 if (test_bit(NFSD4_CLIENT_KILL, &clp->cl_cb_flags)) 961 if (test_bit(NFSD4_CLIENT_KILL, &clp->cl_cb_flags))
930 return; 962 return;
931 spin_lock(&clp->cl_lock); 963 spin_lock(&clp->cl_lock);
@@ -936,11 +968,22 @@ void nfsd4_process_cb_update(struct nfsd4_callback *cb)
936 BUG_ON(!clp->cl_cb_flags); 968 BUG_ON(!clp->cl_cb_flags);
937 clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); 969 clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags);
938 memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn)); 970 memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn));
971 c = __nfsd4_find_backchannel(clp);
972 if (c) {
973 svc_xprt_get(c->cn_xprt);
974 conn.cb_xprt = c->cn_xprt;
975 ses = c->cn_session;
976 }
939 spin_unlock(&clp->cl_lock); 977 spin_unlock(&clp->cl_lock);
940 978
941 err = setup_callback_client(clp, &conn); 979 err = setup_callback_client(clp, &conn, ses);
942 if (err) 980 if (err) {
943 warn_no_callback_path(clp, err); 981 warn_no_callback_path(clp, err);
982 return;
983 }
984 /* Yay, the callback channel's back! Restart any callbacks: */
985 list_for_each_entry(cb, &clp->cl_callbacks, cb_per_client)
986 run_nfsd4_cb(cb);
944} 987}
945 988
946void nfsd4_do_callback_rpc(struct work_struct *w) 989void nfsd4_do_callback_rpc(struct work_struct *w)
@@ -965,10 +1008,11 @@ void nfsd4_do_callback_rpc(struct work_struct *w)
965void nfsd4_cb_recall(struct nfs4_delegation *dp) 1008void nfsd4_cb_recall(struct nfs4_delegation *dp)
966{ 1009{
967 struct nfsd4_callback *cb = &dp->dl_recall; 1010 struct nfsd4_callback *cb = &dp->dl_recall;
1011 struct nfs4_client *clp = dp->dl_client;
968 1012
969 dp->dl_retries = 1; 1013 dp->dl_retries = 1;
970 cb->cb_op = dp; 1014 cb->cb_op = dp;
971 cb->cb_clp = dp->dl_client; 1015 cb->cb_clp = clp;
972 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL]; 1016 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
973 cb->cb_msg.rpc_argp = cb; 1017 cb->cb_msg.rpc_argp = cb;
974 cb->cb_msg.rpc_resp = cb; 1018 cb->cb_msg.rpc_resp = cb;
@@ -977,5 +1021,8 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp)
977 cb->cb_ops = &nfsd4_cb_recall_ops; 1021 cb->cb_ops = &nfsd4_cb_recall_ops;
978 dp->dl_retries = 1; 1022 dp->dl_retries = 1;
979 1023
980 queue_work(callback_wq, &dp->dl_recall.cb_work); 1024 INIT_LIST_HEAD(&cb->cb_per_client);
1025 cb->cb_done = true;
1026
1027 run_nfsd4_cb(&dp->dl_recall);
981} 1028}
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index f0695e815f0..6d2c397d458 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -33,10 +33,11 @@
33 */ 33 */
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/nfsd_idmap.h>
37#include <linux/seq_file.h> 36#include <linux/seq_file.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
39#include <linux/slab.h> 38#include <linux/slab.h>
39#include "idmap.h"
40#include "nfsd.h"
40 41
41/* 42/*
42 * Cache entry 43 * Cache entry
@@ -514,7 +515,7 @@ rqst_authname(struct svc_rqst *rqstp)
514 return clp->name; 515 return clp->name;
515} 516}
516 517
517static int 518static __be32
518idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, 519idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
519 uid_t *id) 520 uid_t *id)
520{ 521{
@@ -524,15 +525,15 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
524 int ret; 525 int ret;
525 526
526 if (namelen + 1 > sizeof(key.name)) 527 if (namelen + 1 > sizeof(key.name))
527 return -EINVAL; 528 return nfserr_badowner;
528 memcpy(key.name, name, namelen); 529 memcpy(key.name, name, namelen);
529 key.name[namelen] = '\0'; 530 key.name[namelen] = '\0';
530 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 531 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
531 ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); 532 ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item);
532 if (ret == -ENOENT) 533 if (ret == -ENOENT)
533 ret = -ESRCH; /* nfserr_badname */ 534 return nfserr_badowner;
534 if (ret) 535 if (ret)
535 return ret; 536 return nfserrno(ret);
536 *id = item->id; 537 *id = item->id;
537 cache_put(&item->h, &nametoid_cache); 538 cache_put(&item->h, &nametoid_cache);
538 return 0; 539 return 0;
@@ -560,14 +561,14 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
560 return ret; 561 return ret;
561} 562}
562 563
563int 564__be32
564nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, 565nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
565 __u32 *id) 566 __u32 *id)
566{ 567{
567 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); 568 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
568} 569}
569 570
570int 571__be32
571nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, 572nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
572 __u32 *id) 573 __u32 *id)
573{ 574{
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0cdfd022bb7..db52546143d 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -604,9 +604,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
604 return status; 604 return status;
605} 605}
606 606
607static __be32 607static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
608nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
609 void *arg)
610{ 608{
611 struct svc_fh tmp_fh; 609 struct svc_fh tmp_fh;
612 __be32 ret; 610 __be32 ret;
@@ -615,13 +613,19 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
615 ret = exp_pseudoroot(rqstp, &tmp_fh); 613 ret = exp_pseudoroot(rqstp, &tmp_fh);
616 if (ret) 614 if (ret)
617 return ret; 615 return ret;
618 if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { 616 if (tmp_fh.fh_dentry == fh->fh_dentry) {
619 fh_put(&tmp_fh); 617 fh_put(&tmp_fh);
620 return nfserr_noent; 618 return nfserr_noent;
621 } 619 }
622 fh_put(&tmp_fh); 620 fh_put(&tmp_fh);
623 return nfsd_lookup(rqstp, &cstate->current_fh, 621 return nfsd_lookup(rqstp, fh, "..", 2, fh);
624 "..", 2, &cstate->current_fh); 622}
623
624static __be32
625nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
626 void *arg)
627{
628 return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
625} 629}
626 630
627static __be32 631static __be32
@@ -769,10 +773,36 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
769 } else 773 } else
770 secinfo->si_exp = exp; 774 secinfo->si_exp = exp;
771 dput(dentry); 775 dput(dentry);
776 if (cstate->minorversion)
777 /* See rfc 5661 section 2.6.3.1.1.8 */
778 fh_put(&cstate->current_fh);
772 return err; 779 return err;
773} 780}
774 781
775static __be32 782static __be32
783nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
784 struct nfsd4_secinfo_no_name *sin)
785{
786 __be32 err;
787
788 switch (sin->sin_style) {
789 case NFS4_SECINFO_STYLE4_CURRENT_FH:
790 break;
791 case NFS4_SECINFO_STYLE4_PARENT:
792 err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
793 if (err)
794 return err;
795 break;
796 default:
797 return nfserr_inval;
798 }
799 exp_get(cstate->current_fh.fh_export);
800 sin->sin_exp = cstate->current_fh.fh_export;
801 fh_put(&cstate->current_fh);
802 return nfs_ok;
803}
804
805static __be32
776nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 806nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
777 struct nfsd4_setattr *setattr) 807 struct nfsd4_setattr *setattr)
778{ 808{
@@ -974,8 +1004,8 @@ static const char *nfsd4_op_name(unsigned opnum);
974 * Also note, enforced elsewhere: 1004 * Also note, enforced elsewhere:
975 * - SEQUENCE other than as first op results in 1005 * - SEQUENCE other than as first op results in
976 * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().) 1006 * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
977 * - BIND_CONN_TO_SESSION must be the only op in its compound 1007 * - BIND_CONN_TO_SESSION must be the only op in its compound.
978 * (Will be enforced in nfsd4_bind_conn_to_session().) 1008 * (Enforced in nfsd4_bind_conn_to_session().)
979 * - DESTROY_SESSION must be the final operation in a compound, if 1009 * - DESTROY_SESSION must be the final operation in a compound, if
980 * sessionid's in SEQUENCE and DESTROY_SESSION are the same. 1010 * sessionid's in SEQUENCE and DESTROY_SESSION are the same.
981 * (Enforced in nfsd4_destroy_session().) 1011 * (Enforced in nfsd4_destroy_session().)
@@ -1126,10 +1156,6 @@ encode_op:
1126 1156
1127 nfsd4_increment_op_stats(op->opnum); 1157 nfsd4_increment_op_stats(op->opnum);
1128 } 1158 }
1129 if (!rqstp->rq_usedeferral && status == nfserr_dropit) {
1130 dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__);
1131 status = nfserr_jukebox;
1132 }
1133 1159
1134 resp->cstate.status = status; 1160 resp->cstate.status = status;
1135 fh_put(&resp->cstate.current_fh); 1161 fh_put(&resp->cstate.current_fh);
@@ -1300,6 +1326,11 @@ static struct nfsd4_operation nfsd4_ops[] = {
1300 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1326 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
1301 .op_name = "OP_EXCHANGE_ID", 1327 .op_name = "OP_EXCHANGE_ID",
1302 }, 1328 },
1329 [OP_BIND_CONN_TO_SESSION] = {
1330 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
1331 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
1332 .op_name = "OP_BIND_CONN_TO_SESSION",
1333 },
1303 [OP_CREATE_SESSION] = { 1334 [OP_CREATE_SESSION] = {
1304 .op_func = (nfsd4op_func)nfsd4_create_session, 1335 .op_func = (nfsd4op_func)nfsd4_create_session,
1305 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1336 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
@@ -1320,6 +1351,10 @@ static struct nfsd4_operation nfsd4_ops[] = {
1320 .op_flags = ALLOWED_WITHOUT_FH, 1351 .op_flags = ALLOWED_WITHOUT_FH,
1321 .op_name = "OP_RECLAIM_COMPLETE", 1352 .op_name = "OP_RECLAIM_COMPLETE",
1322 }, 1353 },
1354 [OP_SECINFO_NO_NAME] = {
1355 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
1356 .op_name = "OP_SECINFO_NO_NAME",
1357 },
1323}; 1358};
1324 1359
1325static const char *nfsd4_op_name(unsigned opnum) 1360static const char *nfsd4_op_name(unsigned opnum)
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 7e26caab2a2..ffb59ef6f82 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -302,7 +302,6 @@ purge_old(struct dentry *parent, struct dentry *child)
302{ 302{
303 int status; 303 int status;
304 304
305 /* note: we currently use this path only for minorversion 0 */
306 if (nfs4_has_reclaimed_state(child->d_name.name, false)) 305 if (nfs4_has_reclaimed_state(child->d_name.name, false))
307 return 0; 306 return 0;
308 307
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index fbd18c3074b..d98d0213285 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -230,7 +230,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
230 dp->dl_client = clp; 230 dp->dl_client = clp;
231 get_nfs4_file(fp); 231 get_nfs4_file(fp);
232 dp->dl_file = fp; 232 dp->dl_file = fp;
233 nfs4_file_get_access(fp, O_RDONLY); 233 dp->dl_vfs_file = find_readable_file(fp);
234 get_file(dp->dl_vfs_file);
234 dp->dl_flock = NULL; 235 dp->dl_flock = NULL;
235 dp->dl_type = type; 236 dp->dl_type = type;
236 dp->dl_stateid.si_boot = boot_time; 237 dp->dl_stateid.si_boot = boot_time;
@@ -252,6 +253,7 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
252 if (atomic_dec_and_test(&dp->dl_count)) { 253 if (atomic_dec_and_test(&dp->dl_count)) {
253 dprintk("NFSD: freeing dp %p\n",dp); 254 dprintk("NFSD: freeing dp %p\n",dp);
254 put_nfs4_file(dp->dl_file); 255 put_nfs4_file(dp->dl_file);
256 fput(dp->dl_vfs_file);
255 kmem_cache_free(deleg_slab, dp); 257 kmem_cache_free(deleg_slab, dp);
256 num_delegations--; 258 num_delegations--;
257 } 259 }
@@ -265,12 +267,10 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
265static void 267static void
266nfs4_close_delegation(struct nfs4_delegation *dp) 268nfs4_close_delegation(struct nfs4_delegation *dp)
267{ 269{
268 struct file *filp = find_readable_file(dp->dl_file);
269
270 dprintk("NFSD: close_delegation dp %p\n",dp); 270 dprintk("NFSD: close_delegation dp %p\n",dp);
271 /* XXX: do we even need this check?: */
271 if (dp->dl_flock) 272 if (dp->dl_flock)
272 vfs_setlease(filp, F_UNLCK, &dp->dl_flock); 273 vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock);
273 nfs4_file_put_access(dp->dl_file, O_RDONLY);
274} 274}
275 275
276/* Called under the state lock. */ 276/* Called under the state lock. */
@@ -642,6 +642,7 @@ static void nfsd4_conn_lost(struct svc_xpt_user *u)
642 free_conn(c); 642 free_conn(c);
643 } 643 }
644 spin_unlock(&clp->cl_lock); 644 spin_unlock(&clp->cl_lock);
645 nfsd4_probe_callback(clp);
645} 646}
646 647
647static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags) 648static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
@@ -679,15 +680,12 @@ static int nfsd4_register_conn(struct nfsd4_conn *conn)
679 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); 680 return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
680} 681}
681 682
682static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) 683static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir)
683{ 684{
684 struct nfsd4_conn *conn; 685 struct nfsd4_conn *conn;
685 u32 flags = NFS4_CDFC4_FORE;
686 int ret; 686 int ret;
687 687
688 if (ses->se_flags & SESSION4_BACK_CHAN) 688 conn = alloc_conn(rqstp, dir);
689 flags |= NFS4_CDFC4_BACK;
690 conn = alloc_conn(rqstp, flags);
691 if (!conn) 689 if (!conn)
692 return nfserr_jukebox; 690 return nfserr_jukebox;
693 nfsd4_hash_conn(conn, ses); 691 nfsd4_hash_conn(conn, ses);
@@ -698,6 +696,17 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
698 return nfs_ok; 696 return nfs_ok;
699} 697}
700 698
699static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses)
700{
701 u32 dir = NFS4_CDFC4_FORE;
702
703 if (ses->se_flags & SESSION4_BACK_CHAN)
704 dir |= NFS4_CDFC4_BACK;
705
706 return nfsd4_new_conn(rqstp, ses, dir);
707}
708
709/* must be called under client_lock */
701static void nfsd4_del_conns(struct nfsd4_session *s) 710static void nfsd4_del_conns(struct nfsd4_session *s)
702{ 711{
703 struct nfs4_client *clp = s->se_client; 712 struct nfs4_client *clp = s->se_client;
@@ -749,6 +758,8 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
749 */ 758 */
750 slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached); 759 slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached);
751 numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs); 760 numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs);
761 if (numslots < 1)
762 return NULL;
752 763
753 new = alloc_session(slotsize, numslots); 764 new = alloc_session(slotsize, numslots);
754 if (!new) { 765 if (!new) {
@@ -769,25 +780,30 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
769 idx = hash_sessionid(&new->se_sessionid); 780 idx = hash_sessionid(&new->se_sessionid);
770 spin_lock(&client_lock); 781 spin_lock(&client_lock);
771 list_add(&new->se_hash, &sessionid_hashtbl[idx]); 782 list_add(&new->se_hash, &sessionid_hashtbl[idx]);
783 spin_lock(&clp->cl_lock);
772 list_add(&new->se_perclnt, &clp->cl_sessions); 784 list_add(&new->se_perclnt, &clp->cl_sessions);
785 spin_unlock(&clp->cl_lock);
773 spin_unlock(&client_lock); 786 spin_unlock(&client_lock);
774 787
775 status = nfsd4_new_conn(rqstp, new); 788 status = nfsd4_new_conn_from_crses(rqstp, new);
776 /* whoops: benny points out, status is ignored! (err, or bogus) */ 789 /* whoops: benny points out, status is ignored! (err, or bogus) */
777 if (status) { 790 if (status) {
778 free_session(&new->se_ref); 791 free_session(&new->se_ref);
779 return NULL; 792 return NULL;
780 } 793 }
781 if (!clp->cl_cb_session && (cses->flags & SESSION4_BACK_CHAN)) { 794 if (cses->flags & SESSION4_BACK_CHAN) {
782 struct sockaddr *sa = svc_addr(rqstp); 795 struct sockaddr *sa = svc_addr(rqstp);
783 796 /*
784 clp->cl_cb_session = new; 797 * This is a little silly; with sessions there's no real
785 clp->cl_cb_conn.cb_xprt = rqstp->rq_xprt; 798 * use for the callback address. Use the peer address
786 svc_xprt_get(rqstp->rq_xprt); 799 * as a reasonable default for now, but consider fixing
800 * the rpc client not to require an address in the
801 * future:
802 */
787 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa); 803 rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
788 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa); 804 clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
789 nfsd4_probe_callback(clp);
790 } 805 }
806 nfsd4_probe_callback(clp);
791 return new; 807 return new;
792} 808}
793 809
@@ -817,7 +833,9 @@ static void
817unhash_session(struct nfsd4_session *ses) 833unhash_session(struct nfsd4_session *ses)
818{ 834{
819 list_del(&ses->se_hash); 835 list_del(&ses->se_hash);
836 spin_lock(&ses->se_client->cl_lock);
820 list_del(&ses->se_perclnt); 837 list_del(&ses->se_perclnt);
838 spin_unlock(&ses->se_client->cl_lock);
821} 839}
822 840
823/* must be called under the client_lock */ 841/* must be called under the client_lock */
@@ -923,8 +941,10 @@ unhash_client_locked(struct nfs4_client *clp)
923 941
924 mark_client_expired(clp); 942 mark_client_expired(clp);
925 list_del(&clp->cl_lru); 943 list_del(&clp->cl_lru);
944 spin_lock(&clp->cl_lock);
926 list_for_each_entry(ses, &clp->cl_sessions, se_perclnt) 945 list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
927 list_del_init(&ses->se_hash); 946 list_del_init(&ses->se_hash);
947 spin_unlock(&clp->cl_lock);
928} 948}
929 949
930static void 950static void
@@ -1051,12 +1071,13 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1051 1071
1052 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 1072 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
1053 atomic_set(&clp->cl_refcount, 0); 1073 atomic_set(&clp->cl_refcount, 0);
1054 atomic_set(&clp->cl_cb_set, 0); 1074 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
1055 INIT_LIST_HEAD(&clp->cl_idhash); 1075 INIT_LIST_HEAD(&clp->cl_idhash);
1056 INIT_LIST_HEAD(&clp->cl_strhash); 1076 INIT_LIST_HEAD(&clp->cl_strhash);
1057 INIT_LIST_HEAD(&clp->cl_openowners); 1077 INIT_LIST_HEAD(&clp->cl_openowners);
1058 INIT_LIST_HEAD(&clp->cl_delegations); 1078 INIT_LIST_HEAD(&clp->cl_delegations);
1059 INIT_LIST_HEAD(&clp->cl_lru); 1079 INIT_LIST_HEAD(&clp->cl_lru);
1080 INIT_LIST_HEAD(&clp->cl_callbacks);
1060 spin_lock_init(&clp->cl_lock); 1081 spin_lock_init(&clp->cl_lock);
1061 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); 1082 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
1062 clp->cl_time = get_seconds(); 1083 clp->cl_time = get_seconds();
@@ -1132,54 +1153,55 @@ find_unconfirmed_client(clientid_t *clid)
1132 return NULL; 1153 return NULL;
1133} 1154}
1134 1155
1135/* 1156static bool clp_used_exchangeid(struct nfs4_client *clp)
1136 * Return 1 iff clp's clientid establishment method matches the use_exchange_id
1137 * parameter. Matching is based on the fact the at least one of the
1138 * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1
1139 *
1140 * FIXME: we need to unify the clientid namespaces for nfsv4.x
1141 * and correctly deal with client upgrade/downgrade in EXCHANGE_ID
1142 * and SET_CLIENTID{,_CONFIRM}
1143 */
1144static inline int
1145match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id)
1146{ 1157{
1147 bool has_exchange_flags = (clp->cl_exchange_flags != 0); 1158 return clp->cl_exchange_flags != 0;
1148 return use_exchange_id == has_exchange_flags; 1159}
1149}
1150 1160
1151static struct nfs4_client * 1161static struct nfs4_client *
1152find_confirmed_client_by_str(const char *dname, unsigned int hashval, 1162find_confirmed_client_by_str(const char *dname, unsigned int hashval)
1153 bool use_exchange_id)
1154{ 1163{
1155 struct nfs4_client *clp; 1164 struct nfs4_client *clp;
1156 1165
1157 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { 1166 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
1158 if (same_name(clp->cl_recdir, dname) && 1167 if (same_name(clp->cl_recdir, dname))
1159 match_clientid_establishment(clp, use_exchange_id))
1160 return clp; 1168 return clp;
1161 } 1169 }
1162 return NULL; 1170 return NULL;
1163} 1171}
1164 1172
1165static struct nfs4_client * 1173static struct nfs4_client *
1166find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, 1174find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
1167 bool use_exchange_id)
1168{ 1175{
1169 struct nfs4_client *clp; 1176 struct nfs4_client *clp;
1170 1177
1171 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { 1178 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
1172 if (same_name(clp->cl_recdir, dname) && 1179 if (same_name(clp->cl_recdir, dname))
1173 match_clientid_establishment(clp, use_exchange_id))
1174 return clp; 1180 return clp;
1175 } 1181 }
1176 return NULL; 1182 return NULL;
1177} 1183}
1178 1184
1185static void rpc_svcaddr2sockaddr(struct sockaddr *sa, unsigned short family, union svc_addr_u *svcaddr)
1186{
1187 switch (family) {
1188 case AF_INET:
1189 ((struct sockaddr_in *)sa)->sin_family = AF_INET;
1190 ((struct sockaddr_in *)sa)->sin_addr = svcaddr->addr;
1191 return;
1192 case AF_INET6:
1193 ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6;
1194 ((struct sockaddr_in6 *)sa)->sin6_addr = svcaddr->addr6;
1195 return;
1196 }
1197}
1198
1179static void 1199static void
1180gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid) 1200gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
1181{ 1201{
1182 struct nfs4_cb_conn *conn = &clp->cl_cb_conn; 1202 struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
1203 struct sockaddr *sa = svc_addr(rqstp);
1204 u32 scopeid = rpc_get_scope_id(sa);
1183 unsigned short expected_family; 1205 unsigned short expected_family;
1184 1206
1185 /* Currently, we only support tcp and tcp6 for the callback channel */ 1207 /* Currently, we only support tcp and tcp6 for the callback channel */
@@ -1205,6 +1227,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid)
1205 1227
1206 conn->cb_prog = se->se_callback_prog; 1228 conn->cb_prog = se->se_callback_prog;
1207 conn->cb_ident = se->se_callback_ident; 1229 conn->cb_ident = se->se_callback_ident;
1230 rpc_svcaddr2sockaddr((struct sockaddr *)&conn->cb_saddr, expected_family, &rqstp->rq_daddr);
1208 return; 1231 return;
1209out_err: 1232out_err:
1210 conn->cb_addr.ss_family = AF_UNSPEC; 1233 conn->cb_addr.ss_family = AF_UNSPEC;
@@ -1344,7 +1367,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1344 case SP4_NONE: 1367 case SP4_NONE:
1345 break; 1368 break;
1346 case SP4_SSV: 1369 case SP4_SSV:
1347 return nfserr_encr_alg_unsupp; 1370 return nfserr_serverfault;
1348 default: 1371 default:
1349 BUG(); /* checked by xdr code */ 1372 BUG(); /* checked by xdr code */
1350 case SP4_MACH_CRED: 1373 case SP4_MACH_CRED:
@@ -1361,8 +1384,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1361 nfs4_lock_state(); 1384 nfs4_lock_state();
1362 status = nfs_ok; 1385 status = nfs_ok;
1363 1386
1364 conf = find_confirmed_client_by_str(dname, strhashval, true); 1387 conf = find_confirmed_client_by_str(dname, strhashval);
1365 if (conf) { 1388 if (conf) {
1389 if (!clp_used_exchangeid(conf)) {
1390 status = nfserr_clid_inuse; /* XXX: ? */
1391 goto out;
1392 }
1366 if (!same_verf(&verf, &conf->cl_verifier)) { 1393 if (!same_verf(&verf, &conf->cl_verifier)) {
1367 /* 18.35.4 case 8 */ 1394 /* 18.35.4 case 8 */
1368 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1395 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
@@ -1403,7 +1430,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1403 goto out; 1430 goto out;
1404 } 1431 }
1405 1432
1406 unconf = find_unconfirmed_client_by_str(dname, strhashval, true); 1433 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1407 if (unconf) { 1434 if (unconf) {
1408 /* 1435 /*
1409 * Possible retry or client restart. Per 18.35.4 case 4, 1436 * Possible retry or client restart. Per 18.35.4 case 4,
@@ -1560,6 +1587,8 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1560 status = nfs_ok; 1587 status = nfs_ok;
1561 memcpy(cr_ses->sessionid.data, new->se_sessionid.data, 1588 memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
1562 NFS4_MAX_SESSIONID_LEN); 1589 NFS4_MAX_SESSIONID_LEN);
1590 memcpy(&cr_ses->fore_channel, &new->se_fchannel,
1591 sizeof(struct nfsd4_channel_attrs));
1563 cs_slot->sl_seqid++; 1592 cs_slot->sl_seqid++;
1564 cr_ses->seqid = cs_slot->sl_seqid; 1593 cr_ses->seqid = cs_slot->sl_seqid;
1565 1594
@@ -1581,6 +1610,45 @@ static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
1581 return argp->opcnt == resp->opcnt; 1610 return argp->opcnt == resp->opcnt;
1582} 1611}
1583 1612
1613static __be32 nfsd4_map_bcts_dir(u32 *dir)
1614{
1615 switch (*dir) {
1616 case NFS4_CDFC4_FORE:
1617 case NFS4_CDFC4_BACK:
1618 return nfs_ok;
1619 case NFS4_CDFC4_FORE_OR_BOTH:
1620 case NFS4_CDFC4_BACK_OR_BOTH:
1621 *dir = NFS4_CDFC4_BOTH;
1622 return nfs_ok;
1623 };
1624 return nfserr_inval;
1625}
1626
1627__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1628 struct nfsd4_compound_state *cstate,
1629 struct nfsd4_bind_conn_to_session *bcts)
1630{
1631 __be32 status;
1632
1633 if (!nfsd4_last_compound_op(rqstp))
1634 return nfserr_not_only_op;
1635 spin_lock(&client_lock);
1636 cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid);
1637 /* Sorta weird: we only need the refcnt'ing because new_conn acquires
1638 * client_lock iself: */
1639 if (cstate->session) {
1640 nfsd4_get_session(cstate->session);
1641 atomic_inc(&cstate->session->se_client->cl_refcount);
1642 }
1643 spin_unlock(&client_lock);
1644 if (!cstate->session)
1645 return nfserr_badsession;
1646
1647 status = nfsd4_map_bcts_dir(&bcts->dir);
1648 nfsd4_new_conn(rqstp, cstate->session, bcts->dir);
1649 return nfs_ok;
1650}
1651
1584static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) 1652static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
1585{ 1653{
1586 if (!session) 1654 if (!session)
@@ -1619,8 +1687,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
1619 spin_unlock(&client_lock); 1687 spin_unlock(&client_lock);
1620 1688
1621 nfs4_lock_state(); 1689 nfs4_lock_state();
1622 /* wait for callbacks */ 1690 nfsd4_probe_callback_sync(ses->se_client);
1623 nfsd4_shutdown_callback(ses->se_client);
1624 nfs4_unlock_state(); 1691 nfs4_unlock_state();
1625 1692
1626 nfsd4_del_conns(ses); 1693 nfsd4_del_conns(ses);
@@ -1733,8 +1800,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1733out: 1800out:
1734 /* Hold a session reference until done processing the compound. */ 1801 /* Hold a session reference until done processing the compound. */
1735 if (cstate->session) { 1802 if (cstate->session) {
1803 struct nfs4_client *clp = session->se_client;
1804
1736 nfsd4_get_session(cstate->session); 1805 nfsd4_get_session(cstate->session);
1737 atomic_inc(&session->se_client->cl_refcount); 1806 atomic_inc(&clp->cl_refcount);
1807 if (clp->cl_cb_state == NFSD4_CB_DOWN)
1808 seq->status_flags |= SEQ4_STATUS_CB_PATH_DOWN;
1738 } 1809 }
1739 kfree(conn); 1810 kfree(conn);
1740 spin_unlock(&client_lock); 1811 spin_unlock(&client_lock);
@@ -1775,7 +1846,6 @@ __be32
1775nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1846nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1776 struct nfsd4_setclientid *setclid) 1847 struct nfsd4_setclientid *setclid)
1777{ 1848{
1778 struct sockaddr *sa = svc_addr(rqstp);
1779 struct xdr_netobj clname = { 1849 struct xdr_netobj clname = {
1780 .len = setclid->se_namelen, 1850 .len = setclid->se_namelen,
1781 .data = setclid->se_name, 1851 .data = setclid->se_name,
@@ -1801,10 +1871,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1801 strhashval = clientstr_hashval(dname); 1871 strhashval = clientstr_hashval(dname);
1802 1872
1803 nfs4_lock_state(); 1873 nfs4_lock_state();
1804 conf = find_confirmed_client_by_str(dname, strhashval, false); 1874 conf = find_confirmed_client_by_str(dname, strhashval);
1805 if (conf) { 1875 if (conf) {
1806 /* RFC 3530 14.2.33 CASE 0: */ 1876 /* RFC 3530 14.2.33 CASE 0: */
1807 status = nfserr_clid_inuse; 1877 status = nfserr_clid_inuse;
1878 if (clp_used_exchangeid(conf))
1879 goto out;
1808 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { 1880 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
1809 char addr_str[INET6_ADDRSTRLEN]; 1881 char addr_str[INET6_ADDRSTRLEN];
1810 rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str, 1882 rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str,
@@ -1819,7 +1891,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1819 * has a description of SETCLIENTID request processing consisting 1891 * has a description of SETCLIENTID request processing consisting
1820 * of 5 bullet points, labeled as CASE0 - CASE4 below. 1892 * of 5 bullet points, labeled as CASE0 - CASE4 below.
1821 */ 1893 */
1822 unconf = find_unconfirmed_client_by_str(dname, strhashval, false); 1894 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1823 status = nfserr_resource; 1895 status = nfserr_resource;
1824 if (!conf) { 1896 if (!conf) {
1825 /* 1897 /*
@@ -1876,7 +1948,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1876 * for consistent minorversion use throughout: 1948 * for consistent minorversion use throughout:
1877 */ 1949 */
1878 new->cl_minorversion = 0; 1950 new->cl_minorversion = 0;
1879 gen_callback(new, setclid, rpc_get_scope_id(sa)); 1951 gen_callback(new, setclid, rqstp);
1880 add_to_unconfirmed(new, strhashval); 1952 add_to_unconfirmed(new, strhashval);
1881 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; 1953 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
1882 setclid->se_clientid.cl_id = new->cl_clientid.cl_id; 1954 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
@@ -1935,7 +2007,6 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1935 if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 2007 if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
1936 status = nfserr_clid_inuse; 2008 status = nfserr_clid_inuse;
1937 else { 2009 else {
1938 atomic_set(&conf->cl_cb_set, 0);
1939 nfsd4_change_callback(conf, &unconf->cl_cb_conn); 2010 nfsd4_change_callback(conf, &unconf->cl_cb_conn);
1940 nfsd4_probe_callback(conf); 2011 nfsd4_probe_callback(conf);
1941 expire_client(unconf); 2012 expire_client(unconf);
@@ -1964,7 +2035,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
1964 unsigned int hash = 2035 unsigned int hash =
1965 clientstr_hashval(unconf->cl_recdir); 2036 clientstr_hashval(unconf->cl_recdir);
1966 conf = find_confirmed_client_by_str(unconf->cl_recdir, 2037 conf = find_confirmed_client_by_str(unconf->cl_recdir,
1967 hash, false); 2038 hash);
1968 if (conf) { 2039 if (conf) {
1969 nfsd4_remove_clid_dir(conf); 2040 nfsd4_remove_clid_dir(conf);
1970 expire_client(conf); 2041 expire_client(conf);
@@ -2300,41 +2371,6 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
2300 nfsd4_cb_recall(dp); 2371 nfsd4_cb_recall(dp);
2301} 2372}
2302 2373
2303/*
2304 * The file_lock is being reapd.
2305 *
2306 * Called by locks_free_lock() with lock_flocks() held.
2307 */
2308static
2309void nfsd_release_deleg_cb(struct file_lock *fl)
2310{
2311 struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
2312
2313 dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d\n", fl,dp, atomic_read(&dp->dl_count));
2314
2315 if (!(fl->fl_flags & FL_LEASE) || !dp)
2316 return;
2317 dp->dl_flock = NULL;
2318}
2319
2320/*
2321 * Called from setlease() with lock_flocks() held
2322 */
2323static
2324int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
2325{
2326 struct nfs4_delegation *onlistd =
2327 (struct nfs4_delegation *)onlist->fl_owner;
2328 struct nfs4_delegation *tryd =
2329 (struct nfs4_delegation *)try->fl_owner;
2330
2331 if (onlist->fl_lmops != try->fl_lmops)
2332 return 0;
2333
2334 return onlistd->dl_client == tryd->dl_client;
2335}
2336
2337
2338static 2374static
2339int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) 2375int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2340{ 2376{
@@ -2346,8 +2382,6 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2346 2382
2347static const struct lock_manager_operations nfsd_lease_mng_ops = { 2383static const struct lock_manager_operations nfsd_lease_mng_ops = {
2348 .fl_break = nfsd_break_deleg_cb, 2384 .fl_break = nfsd_break_deleg_cb,
2349 .fl_release_private = nfsd_release_deleg_cb,
2350 .fl_mylease = nfsd_same_client_deleg_cb,
2351 .fl_change = nfsd_change_deleg_cb, 2385 .fl_change = nfsd_change_deleg_cb,
2352}; 2386};
2353 2387
@@ -2514,8 +2548,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
2514 if (!fp->fi_fds[oflag]) { 2548 if (!fp->fi_fds[oflag]) {
2515 status = nfsd_open(rqstp, cur_fh, S_IFREG, access, 2549 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
2516 &fp->fi_fds[oflag]); 2550 &fp->fi_fds[oflag]);
2517 if (status == nfserr_dropit)
2518 status = nfserr_jukebox;
2519 if (status) 2551 if (status)
2520 return status; 2552 return status;
2521 } 2553 }
@@ -2596,6 +2628,19 @@ nfs4_set_claim_prev(struct nfsd4_open *open)
2596 open->op_stateowner->so_client->cl_firststate = 1; 2628 open->op_stateowner->so_client->cl_firststate = 1;
2597} 2629}
2598 2630
2631/* Should we give out recallable state?: */
2632static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
2633{
2634 if (clp->cl_cb_state == NFSD4_CB_UP)
2635 return true;
2636 /*
2637 * In the sessions case, since we don't have to establish a
2638 * separate connection for callbacks, we assume it's OK
2639 * until we hear otherwise:
2640 */
2641 return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
2642}
2643
2599/* 2644/*
2600 * Attempt to hand out a delegation. 2645 * Attempt to hand out a delegation.
2601 */ 2646 */
@@ -2604,10 +2649,11 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2604{ 2649{
2605 struct nfs4_delegation *dp; 2650 struct nfs4_delegation *dp;
2606 struct nfs4_stateowner *sop = stp->st_stateowner; 2651 struct nfs4_stateowner *sop = stp->st_stateowner;
2607 int cb_up = atomic_read(&sop->so_client->cl_cb_set); 2652 int cb_up;
2608 struct file_lock *fl; 2653 struct file_lock *fl;
2609 int status, flag = 0; 2654 int status, flag = 0;
2610 2655
2656 cb_up = nfsd4_cb_channel_good(sop->so_client);
2611 flag = NFS4_OPEN_DELEGATE_NONE; 2657 flag = NFS4_OPEN_DELEGATE_NONE;
2612 open->op_recall = 0; 2658 open->op_recall = 0;
2613 switch (open->op_claim_type) { 2659 switch (open->op_claim_type) {
@@ -2655,7 +2701,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2655 dp->dl_flock = fl; 2701 dp->dl_flock = fl;
2656 2702
2657 /* vfs_setlease checks to see if delegation should be handed out. 2703 /* vfs_setlease checks to see if delegation should be handed out.
2658 * the lock_manager callbacks fl_mylease and fl_change are used 2704 * the lock_manager callback fl_change is used
2659 */ 2705 */
2660 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { 2706 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
2661 dprintk("NFSD: setlease failed [%d], no delegation\n", status); 2707 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
@@ -2794,7 +2840,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2794 renew_client(clp); 2840 renew_client(clp);
2795 status = nfserr_cb_path_down; 2841 status = nfserr_cb_path_down;
2796 if (!list_empty(&clp->cl_delegations) 2842 if (!list_empty(&clp->cl_delegations)
2797 && !atomic_read(&clp->cl_cb_set)) 2843 && clp->cl_cb_state != NFSD4_CB_UP)
2798 goto out; 2844 goto out;
2799 status = nfs_ok; 2845 status = nfs_ok;
2800out: 2846out:
@@ -3081,9 +3127,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3081 if (status) 3127 if (status)
3082 goto out; 3128 goto out;
3083 renew_client(dp->dl_client); 3129 renew_client(dp->dl_client);
3084 if (filpp) 3130 if (filpp) {
3085 *filpp = find_readable_file(dp->dl_file); 3131 *filpp = find_readable_file(dp->dl_file);
3086 BUG_ON(!*filpp); 3132 BUG_ON(!*filpp);
3133 }
3087 } else { /* open or lock stateid */ 3134 } else { /* open or lock stateid */
3088 stp = find_stateid(stateid, flags); 3135 stp = find_stateid(stateid, flags);
3089 if (!stp) 3136 if (!stp)
@@ -4107,7 +4154,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
4107 unsigned int strhashval = clientstr_hashval(name); 4154 unsigned int strhashval = clientstr_hashval(name);
4108 struct nfs4_client *clp; 4155 struct nfs4_client *clp;
4109 4156
4110 clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id); 4157 clp = find_confirmed_client_by_str(name, strhashval);
4111 return clp ? 1 : 0; 4158 return clp ? 1 : 0;
4112} 4159}
4113 4160
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index f35a94a0402..956629b9cdc 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -44,13 +44,14 @@
44#include <linux/namei.h> 44#include <linux/namei.h>
45#include <linux/statfs.h> 45#include <linux/statfs.h>
46#include <linux/utsname.h> 46#include <linux/utsname.h>
47#include <linux/nfsd_idmap.h>
48#include <linux/nfs4_acl.h>
49#include <linux/sunrpc/svcauth_gss.h> 47#include <linux/sunrpc/svcauth_gss.h>
50 48
49#include "idmap.h"
50#include "acl.h"
51#include "xdr4.h" 51#include "xdr4.h"
52#include "vfs.h" 52#include "vfs.h"
53 53
54
54#define NFSDDBG_FACILITY NFSDDBG_XDR 55#define NFSDDBG_FACILITY NFSDDBG_XDR
55 56
56/* 57/*
@@ -288,17 +289,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
288 len += XDR_QUADLEN(dummy32) << 2; 289 len += XDR_QUADLEN(dummy32) << 2;
289 READMEM(buf, dummy32); 290 READMEM(buf, dummy32);
290 ace->whotype = nfs4_acl_get_whotype(buf, dummy32); 291 ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
291 host_err = 0; 292 status = nfs_ok;
292 if (ace->whotype != NFS4_ACL_WHO_NAMED) 293 if (ace->whotype != NFS4_ACL_WHO_NAMED)
293 ace->who = 0; 294 ace->who = 0;
294 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 295 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
295 host_err = nfsd_map_name_to_gid(argp->rqstp, 296 status = nfsd_map_name_to_gid(argp->rqstp,
296 buf, dummy32, &ace->who); 297 buf, dummy32, &ace->who);
297 else 298 else
298 host_err = nfsd_map_name_to_uid(argp->rqstp, 299 status = nfsd_map_name_to_uid(argp->rqstp,
299 buf, dummy32, &ace->who); 300 buf, dummy32, &ace->who);
300 if (host_err) 301 if (status)
301 goto out_nfserr; 302 return status;
302 } 303 }
303 } else 304 } else
304 *acl = NULL; 305 *acl = NULL;
@@ -420,6 +421,21 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
420 DECODE_TAIL; 421 DECODE_TAIL;
421} 422}
422 423
424static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
425{
426 DECODE_HEAD;
427 u32 dummy;
428
429 READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
430 COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
431 READ32(bcts->dir);
432 /* XXX: Perhaps Tom Tucker could help us figure out how we
433 * should be using ctsa_use_conn_in_rdma_mode: */
434 READ32(dummy);
435
436 DECODE_TAIL;
437}
438
423static __be32 439static __be32
424nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) 440nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
425{ 441{
@@ -847,6 +863,17 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
847} 863}
848 864
849static __be32 865static __be32
866nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
867 struct nfsd4_secinfo_no_name *sin)
868{
869 DECODE_HEAD;
870
871 READ_BUF(4);
872 READ32(sin->sin_style);
873 DECODE_TAIL;
874}
875
876static __be32
850nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 877nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
851{ 878{
852 __be32 status; 879 __be32 status;
@@ -1005,7 +1032,7 @@ static __be32
1005nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, 1032nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1006 struct nfsd4_exchange_id *exid) 1033 struct nfsd4_exchange_id *exid)
1007{ 1034{
1008 int dummy; 1035 int dummy, tmp;
1009 DECODE_HEAD; 1036 DECODE_HEAD;
1010 1037
1011 READ_BUF(NFS4_VERIFIER_SIZE); 1038 READ_BUF(NFS4_VERIFIER_SIZE);
@@ -1053,15 +1080,23 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1053 1080
1054 /* ssp_hash_algs<> */ 1081 /* ssp_hash_algs<> */
1055 READ_BUF(4); 1082 READ_BUF(4);
1056 READ32(dummy); 1083 READ32(tmp);
1057 READ_BUF(dummy); 1084 while (tmp--) {
1058 p += XDR_QUADLEN(dummy); 1085 READ_BUF(4);
1086 READ32(dummy);
1087 READ_BUF(dummy);
1088 p += XDR_QUADLEN(dummy);
1089 }
1059 1090
1060 /* ssp_encr_algs<> */ 1091 /* ssp_encr_algs<> */
1061 READ_BUF(4); 1092 READ_BUF(4);
1062 READ32(dummy); 1093 READ32(tmp);
1063 READ_BUF(dummy); 1094 while (tmp--) {
1064 p += XDR_QUADLEN(dummy); 1095 READ_BUF(4);
1096 READ32(dummy);
1097 READ_BUF(dummy);
1098 p += XDR_QUADLEN(dummy);
1099 }
1065 1100
1066 /* ssp_window and ssp_num_gss_handles */ 1101 /* ssp_window and ssp_num_gss_handles */
1067 READ_BUF(8); 1102 READ_BUF(8);
@@ -1339,7 +1374,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1339 1374
1340 /* new operations for NFSv4.1 */ 1375 /* new operations for NFSv4.1 */
1341 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, 1376 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp,
1342 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_notsupp, 1377 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1343 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, 1378 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
1344 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, 1379 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
1345 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, 1380 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session,
@@ -1350,7 +1385,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1350 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, 1385 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
1351 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, 1386 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
1352 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, 1387 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
1353 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_notsupp, 1388 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1354 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, 1389 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
1355 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, 1390 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
1356 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, 1391 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -2309,8 +2344,6 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2309 case nfserr_resource: 2344 case nfserr_resource:
2310 nfserr = nfserr_toosmall; 2345 nfserr = nfserr_toosmall;
2311 goto fail; 2346 goto fail;
2312 case nfserr_dropit:
2313 goto fail;
2314 case nfserr_noent: 2347 case nfserr_noent:
2315 goto skip_entry; 2348 goto skip_entry;
2316 default: 2349 default:
@@ -2365,6 +2398,21 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2365 return nfserr; 2398 return nfserr;
2366} 2399}
2367 2400
2401static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2402{
2403 __be32 *p;
2404
2405 if (!nfserr) {
2406 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
2407 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
2408 WRITE32(bcts->dir);
2409 /* XXX: ? */
2410 WRITE32(0);
2411 ADJUST_ARGS();
2412 }
2413 return nfserr;
2414}
2415
2368static __be32 2416static __be32
2369nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) 2417nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2370{ 2418{
@@ -2826,11 +2874,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2826} 2874}
2827 2875
2828static __be32 2876static __be32
2829nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, 2877nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
2830 struct nfsd4_secinfo *secinfo) 2878 __be32 nfserr,struct svc_export *exp)
2831{ 2879{
2832 int i = 0; 2880 int i = 0;
2833 struct svc_export *exp = secinfo->si_exp;
2834 u32 nflavs; 2881 u32 nflavs;
2835 struct exp_flavor_info *flavs; 2882 struct exp_flavor_info *flavs;
2836 struct exp_flavor_info def_flavs[2]; 2883 struct exp_flavor_info def_flavs[2];
@@ -2892,6 +2939,20 @@ out:
2892 return nfserr; 2939 return nfserr;
2893} 2940}
2894 2941
2942static __be32
2943nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
2944 struct nfsd4_secinfo *secinfo)
2945{
2946 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
2947}
2948
2949static __be32
2950nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
2951 struct nfsd4_secinfo_no_name *secinfo)
2952{
2953 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
2954}
2955
2895/* 2956/*
2896 * The SETATTR encode routine is special -- it always encodes a bitmap, 2957 * The SETATTR encode routine is special -- it always encodes a bitmap,
2897 * regardless of the error status. 2958 * regardless of the error status.
@@ -3076,13 +3137,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3076 WRITE32(seq->seqid); 3137 WRITE32(seq->seqid);
3077 WRITE32(seq->slotid); 3138 WRITE32(seq->slotid);
3078 WRITE32(seq->maxslots); 3139 WRITE32(seq->maxslots);
3079 /* 3140 /* For now: target_maxslots = maxslots */
3080 * FIXME: for now:
3081 * target_maxslots = maxslots
3082 * status_flags = 0
3083 */
3084 WRITE32(seq->maxslots); 3141 WRITE32(seq->maxslots);
3085 WRITE32(0); 3142 WRITE32(seq->status_flags);
3086 3143
3087 ADJUST_ARGS(); 3144 ADJUST_ARGS();
3088 resp->cstate.datap = p; /* DRC cache data pointer */ 3145 resp->cstate.datap = p; /* DRC cache data pointer */
@@ -3143,7 +3200,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3143 3200
3144 /* NFSv4.1 operations */ 3201 /* NFSv4.1 operations */
3145 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, 3202 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop,
3146 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop, 3203 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3147 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3204 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
3148 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3205 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
3149 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3206 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session,
@@ -3154,7 +3211,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3154 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, 3211 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
3155 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, 3212 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
3156 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, 3213 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
3157 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop, 3214 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
3158 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, 3215 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
3159 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, 3216 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
3160 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3217 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 4514ebbee4d..33b3e2b0677 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -8,12 +8,12 @@
8#include <linux/namei.h> 8#include <linux/namei.h>
9#include <linux/ctype.h> 9#include <linux/ctype.h>
10 10
11#include <linux/nfsd_idmap.h>
12#include <linux/sunrpc/svcsock.h> 11#include <linux/sunrpc/svcsock.h>
13#include <linux/nfsd/syscall.h> 12#include <linux/nfsd/syscall.h>
14#include <linux/lockd/lockd.h> 13#include <linux/lockd/lockd.h>
15#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/clnt.h>
16 15
16#include "idmap.h"
17#include "nfsd.h" 17#include "nfsd.h"
18#include "cache.h" 18#include "cache.h"
19 19
@@ -127,6 +127,7 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
127 127
128static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) 128static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
129{ 129{
130#ifdef CONFIG_NFSD_DEPRECATED
130 static int warned; 131 static int warned;
131 if (file->f_dentry->d_name.name[0] == '.' && !warned) { 132 if (file->f_dentry->d_name.name[0] == '.' && !warned) {
132 printk(KERN_INFO 133 printk(KERN_INFO
@@ -135,6 +136,7 @@ static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size
135 current->comm, file->f_dentry->d_name.name); 136 current->comm, file->f_dentry->d_name.name);
136 warned = 1; 137 warned = 1;
137 } 138 }
139#endif
138 if (! file->private_data) { 140 if (! file->private_data) {
139 /* An attempt to read a transaction file without writing 141 /* An attempt to read a transaction file without writing
140 * causes a 0-byte write so that the file can return 142 * causes a 0-byte write so that the file can return
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 6b641cf2c19..7ecfa242030 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -158,6 +158,7 @@ void nfsd_lockd_shutdown(void);
158#define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) 158#define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP)
159#define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) 159#define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR)
160#define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) 160#define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE)
161#define nfserr_badowner cpu_to_be32(NFSERR_BADOWNER)
161#define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) 162#define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD)
162#define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) 163#define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL)
163#define nfserr_grace cpu_to_be32(NFSERR_GRACE) 164#define nfserr_grace cpu_to_be32(NFSERR_GRACE)
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 08e17264784..e15dc45fc5e 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -735,9 +735,9 @@ nfserrno (int errno)
735 { nfserr_stale, -ESTALE }, 735 { nfserr_stale, -ESTALE },
736 { nfserr_jukebox, -ETIMEDOUT }, 736 { nfserr_jukebox, -ETIMEDOUT },
737 { nfserr_jukebox, -ERESTARTSYS }, 737 { nfserr_jukebox, -ERESTARTSYS },
738 { nfserr_dropit, -EAGAIN }, 738 { nfserr_jukebox, -EAGAIN },
739 { nfserr_dropit, -ENOMEM }, 739 { nfserr_jukebox, -EWOULDBLOCK },
740 { nfserr_badname, -ESRCH }, 740 { nfserr_jukebox, -ENOMEM },
741 { nfserr_io, -ETXTBSY }, 741 { nfserr_io, -ETXTBSY },
742 { nfserr_notsupp, -EOPNOTSUPP }, 742 { nfserr_notsupp, -EOPNOTSUPP },
743 { nfserr_toosmall, -ETOOSMALL }, 743 { nfserr_toosmall, -ETOOSMALL },
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 2bae1d86f5f..18743c4d8bc 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -608,7 +608,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
608 /* Now call the procedure handler, and encode NFS status. */ 608 /* Now call the procedure handler, and encode NFS status. */
609 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); 609 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
610 nfserr = map_new_errors(rqstp->rq_vers, nfserr); 610 nfserr = map_new_errors(rqstp->rq_vers, nfserr);
611 if (nfserr == nfserr_dropit) { 611 if (nfserr == nfserr_dropit || rqstp->rq_dropme) {
612 dprintk("nfsd: Dropping request; may be revisited later\n"); 612 dprintk("nfsd: Dropping request; may be revisited later\n");
613 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 613 nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
614 return 0; 614 return 0;
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 39adc27b068..3074656ba7b 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -68,10 +68,12 @@ typedef struct {
68struct nfsd4_callback { 68struct nfsd4_callback {
69 void *cb_op; 69 void *cb_op;
70 struct nfs4_client *cb_clp; 70 struct nfs4_client *cb_clp;
71 struct list_head cb_per_client;
71 u32 cb_minorversion; 72 u32 cb_minorversion;
72 struct rpc_message cb_msg; 73 struct rpc_message cb_msg;
73 const struct rpc_call_ops *cb_ops; 74 const struct rpc_call_ops *cb_ops;
74 struct work_struct cb_work; 75 struct work_struct cb_work;
76 bool cb_done;
75}; 77};
76 78
77struct nfs4_delegation { 79struct nfs4_delegation {
@@ -81,6 +83,7 @@ struct nfs4_delegation {
81 atomic_t dl_count; /* ref count */ 83 atomic_t dl_count; /* ref count */
82 struct nfs4_client *dl_client; 84 struct nfs4_client *dl_client;
83 struct nfs4_file *dl_file; 85 struct nfs4_file *dl_file;
86 struct file *dl_vfs_file;
84 struct file_lock *dl_flock; 87 struct file_lock *dl_flock;
85 u32 dl_type; 88 u32 dl_type;
86 time_t dl_time; 89 time_t dl_time;
@@ -95,6 +98,7 @@ struct nfs4_delegation {
95struct nfs4_cb_conn { 98struct nfs4_cb_conn {
96 /* SETCLIENTID info */ 99 /* SETCLIENTID info */
97 struct sockaddr_storage cb_addr; 100 struct sockaddr_storage cb_addr;
101 struct sockaddr_storage cb_saddr;
98 size_t cb_addrlen; 102 size_t cb_addrlen;
99 u32 cb_prog; /* used only in 4.0 case; 103 u32 cb_prog; /* used only in 4.0 case;
100 per-session otherwise */ 104 per-session otherwise */
@@ -146,6 +150,11 @@ struct nfsd4_create_session {
146 u32 gid; 150 u32 gid;
147}; 151};
148 152
153struct nfsd4_bind_conn_to_session {
154 struct nfs4_sessionid sessionid;
155 u32 dir;
156};
157
149/* The single slot clientid cache structure */ 158/* The single slot clientid cache structure */
150struct nfsd4_clid_slot { 159struct nfsd4_clid_slot {
151 u32 sl_seqid; 160 u32 sl_seqid;
@@ -235,9 +244,13 @@ struct nfs4_client {
235 unsigned long cl_cb_flags; 244 unsigned long cl_cb_flags;
236 struct rpc_clnt *cl_cb_client; 245 struct rpc_clnt *cl_cb_client;
237 u32 cl_cb_ident; 246 u32 cl_cb_ident;
238 atomic_t cl_cb_set; 247#define NFSD4_CB_UP 0
248#define NFSD4_CB_UNKNOWN 1
249#define NFSD4_CB_DOWN 2
250 int cl_cb_state;
239 struct nfsd4_callback cl_cb_null; 251 struct nfsd4_callback cl_cb_null;
240 struct nfsd4_session *cl_cb_session; 252 struct nfsd4_session *cl_cb_session;
253 struct list_head cl_callbacks; /* list of in-progress callbacks */
241 254
242 /* for all client information that callback code might need: */ 255 /* for all client information that callback code might need: */
243 spinlock_t cl_lock; 256 spinlock_t cl_lock;
@@ -454,6 +467,7 @@ extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
454extern void nfs4_free_stateowner(struct kref *kref); 467extern void nfs4_free_stateowner(struct kref *kref);
455extern int set_callback_cred(void); 468extern int set_callback_cred(void);
456extern void nfsd4_probe_callback(struct nfs4_client *clp); 469extern void nfsd4_probe_callback(struct nfs4_client *clp);
470extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
457extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); 471extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
458extern void nfsd4_do_callback_rpc(struct work_struct *); 472extern void nfsd4_do_callback_rpc(struct work_struct *);
459extern void nfsd4_cb_recall(struct nfs4_delegation *dp); 473extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 230b79fbf00..a3c7f701395 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1,4 +1,3 @@
1#define MSNFS /* HACK HACK */
2/* 1/*
3 * File operations used by nfsd. Some of these have been ripped from 2 * File operations used by nfsd. Some of these have been ripped from
4 * other parts of the kernel because they weren't exported, others 3 * other parts of the kernel because they weren't exported, others
@@ -35,8 +34,8 @@
35#endif /* CONFIG_NFSD_V3 */ 34#endif /* CONFIG_NFSD_V3 */
36 35
37#ifdef CONFIG_NFSD_V4 36#ifdef CONFIG_NFSD_V4
38#include <linux/nfs4_acl.h> 37#include "acl.h"
39#include <linux/nfsd_idmap.h> 38#include "idmap.h"
40#endif /* CONFIG_NFSD_V4 */ 39#endif /* CONFIG_NFSD_V4 */
41 40
42#include "nfsd.h" 41#include "nfsd.h"
@@ -273,6 +272,13 @@ out:
273 return err; 272 return err;
274} 273}
275 274
275static int nfsd_break_lease(struct inode *inode)
276{
277 if (!S_ISREG(inode->i_mode))
278 return 0;
279 return break_lease(inode, O_WRONLY | O_NONBLOCK);
280}
281
276/* 282/*
277 * Commit metadata changes to stable storage. 283 * Commit metadata changes to stable storage.
278 */ 284 */
@@ -375,16 +381,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
375 goto out; 381 goto out;
376 } 382 }
377 383
378 /*
379 * If we are changing the size of the file, then
380 * we need to break all leases.
381 */
382 host_err = break_lease(inode, O_WRONLY | O_NONBLOCK);
383 if (host_err == -EWOULDBLOCK)
384 host_err = -ETIMEDOUT;
385 if (host_err) /* ENOMEM or EWOULDBLOCK */
386 goto out_nfserr;
387
388 host_err = get_write_access(inode); 384 host_err = get_write_access(inode);
389 if (host_err) 385 if (host_err)
390 goto out_nfserr; 386 goto out_nfserr;
@@ -425,7 +421,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
425 421
426 err = nfserr_notsync; 422 err = nfserr_notsync;
427 if (!check_guard || guardtime == inode->i_ctime.tv_sec) { 423 if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
424 host_err = nfsd_break_lease(inode);
425 if (host_err)
426 goto out_nfserr;
428 fh_lock(fhp); 427 fh_lock(fhp);
428
429 host_err = notify_change(dentry, iap); 429 host_err = notify_change(dentry, iap);
430 err = nfserrno(host_err); 430 err = nfserrno(host_err);
431 fh_unlock(fhp); 431 fh_unlock(fhp);
@@ -752,8 +752,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
752 */ 752 */
753 if (!(access & NFSD_MAY_NOT_BREAK_LEASE)) 753 if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
754 host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0)); 754 host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
755 if (host_err == -EWOULDBLOCK)
756 host_err = -ETIMEDOUT;
757 if (host_err) /* NOMEM or WOULDBLOCK */ 755 if (host_err) /* NOMEM or WOULDBLOCK */
758 goto out_nfserr; 756 goto out_nfserr;
759 757
@@ -874,15 +872,6 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
874 return __splice_from_pipe(pipe, sd, nfsd_splice_actor); 872 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
875} 873}
876 874
877static inline int svc_msnfs(struct svc_fh *ffhp)
878{
879#ifdef MSNFS
880 return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
881#else
882 return 0;
883#endif
884}
885
886static __be32 875static __be32
887nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 876nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
888 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 877 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -895,9 +884,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
895 err = nfserr_perm; 884 err = nfserr_perm;
896 inode = file->f_path.dentry->d_inode; 885 inode = file->f_path.dentry->d_inode;
897 886
898 if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
899 goto out;
900
901 if (file->f_op->splice_read && rqstp->rq_splice_ok) { 887 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
902 struct splice_desc sd = { 888 struct splice_desc sd = {
903 .len = 0, 889 .len = 0,
@@ -922,7 +908,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
922 fsnotify_access(file); 908 fsnotify_access(file);
923 } else 909 } else
924 err = nfserrno(host_err); 910 err = nfserrno(host_err);
925out:
926 return err; 911 return err;
927} 912}
928 913
@@ -987,14 +972,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
987 int stable = *stablep; 972 int stable = *stablep;
988 int use_wgather; 973 int use_wgather;
989 974
990#ifdef MSNFS
991 err = nfserr_perm;
992
993 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
994 (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
995 goto out;
996#endif
997
998 dentry = file->f_path.dentry; 975 dentry = file->f_path.dentry;
999 inode = dentry->d_inode; 976 inode = dentry->d_inode;
1000 exp = fhp->fh_export; 977 exp = fhp->fh_export;
@@ -1045,7 +1022,6 @@ out_nfserr:
1045 err = 0; 1022 err = 0;
1046 else 1023 else
1047 err = nfserrno(host_err); 1024 err = nfserrno(host_err);
1048out:
1049 return err; 1025 return err;
1050} 1026}
1051 1027
@@ -1665,6 +1641,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1665 err = nfserrno(host_err); 1641 err = nfserrno(host_err);
1666 goto out_dput; 1642 goto out_dput;
1667 } 1643 }
1644 err = nfserr_noent;
1645 if (!dold->d_inode)
1646 goto out_drop_write;
1647 host_err = nfsd_break_lease(dold->d_inode);
1648 if (host_err)
1649 goto out_drop_write;
1668 host_err = vfs_link(dold, dirp, dnew); 1650 host_err = vfs_link(dold, dirp, dnew);
1669 if (!host_err) { 1651 if (!host_err) {
1670 err = nfserrno(commit_metadata(ffhp)); 1652 err = nfserrno(commit_metadata(ffhp));
@@ -1676,6 +1658,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1676 else 1658 else
1677 err = nfserrno(host_err); 1659 err = nfserrno(host_err);
1678 } 1660 }
1661out_drop_write:
1679 mnt_drop_write(tfhp->fh_export->ex_path.mnt); 1662 mnt_drop_write(tfhp->fh_export->ex_path.mnt);
1680out_dput: 1663out_dput:
1681 dput(dnew); 1664 dput(dnew);
@@ -1750,12 +1733,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1750 if (ndentry == trap) 1733 if (ndentry == trap)
1751 goto out_dput_new; 1734 goto out_dput_new;
1752 1735
1753 if (svc_msnfs(ffhp) &&
1754 ((odentry->d_count > 1) || (ndentry->d_count > 1))) {
1755 host_err = -EPERM;
1756 goto out_dput_new;
1757 }
1758
1759 host_err = -EXDEV; 1736 host_err = -EXDEV;
1760 if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) 1737 if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt)
1761 goto out_dput_new; 1738 goto out_dput_new;
@@ -1763,15 +1740,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1763 if (host_err) 1740 if (host_err)
1764 goto out_dput_new; 1741 goto out_dput_new;
1765 1742
1743 host_err = nfsd_break_lease(odentry->d_inode);
1744 if (host_err)
1745 goto out_drop_write;
1766 host_err = vfs_rename(fdir, odentry, tdir, ndentry); 1746 host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1767 if (!host_err) { 1747 if (!host_err) {
1768 host_err = commit_metadata(tfhp); 1748 host_err = commit_metadata(tfhp);
1769 if (!host_err) 1749 if (!host_err)
1770 host_err = commit_metadata(ffhp); 1750 host_err = commit_metadata(ffhp);
1771 } 1751 }
1772 1752out_drop_write:
1773 mnt_drop_write(ffhp->fh_export->ex_path.mnt); 1753 mnt_drop_write(ffhp->fh_export->ex_path.mnt);
1774
1775 out_dput_new: 1754 out_dput_new:
1776 dput(ndentry); 1755 dput(ndentry);
1777 out_dput_old: 1756 out_dput_old:
@@ -1834,18 +1813,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1834 if (host_err) 1813 if (host_err)
1835 goto out_nfserr; 1814 goto out_nfserr;
1836 1815
1837 if (type != S_IFDIR) { /* It's UNLINK */ 1816 host_err = nfsd_break_lease(rdentry->d_inode);
1838#ifdef MSNFS 1817 if (host_err)
1839 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && 1818 goto out_put;
1840 (rdentry->d_count > 1)) { 1819 if (type != S_IFDIR)
1841 host_err = -EPERM;
1842 } else
1843#endif
1844 host_err = vfs_unlink(dirp, rdentry); 1820 host_err = vfs_unlink(dirp, rdentry);
1845 } else { /* It's RMDIR */ 1821 else
1846 host_err = vfs_rmdir(dirp, rdentry); 1822 host_err = vfs_rmdir(dirp, rdentry);
1847 } 1823out_put:
1848
1849 dput(rdentry); 1824 dput(rdentry);
1850 1825
1851 if (!host_err) 1826 if (!host_err)
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 60fce3dc5cb..366401e1a53 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -311,6 +311,11 @@ struct nfsd4_secinfo {
311 struct svc_export *si_exp; /* response */ 311 struct svc_export *si_exp; /* response */
312}; 312};
313 313
314struct nfsd4_secinfo_no_name {
315 u32 sin_style; /* request */
316 struct svc_export *sin_exp; /* response */
317};
318
314struct nfsd4_setattr { 319struct nfsd4_setattr {
315 stateid_t sa_stateid; /* request */ 320 stateid_t sa_stateid; /* request */
316 u32 sa_bmval[3]; /* request */ 321 u32 sa_bmval[3]; /* request */
@@ -373,8 +378,8 @@ struct nfsd4_sequence {
373 u32 cachethis; /* request */ 378 u32 cachethis; /* request */
374#if 0 379#if 0
375 u32 target_maxslots; /* response */ 380 u32 target_maxslots; /* response */
376 u32 status_flags; /* response */
377#endif /* not yet */ 381#endif /* not yet */
382 u32 status_flags; /* response */
378}; 383};
379 384
380struct nfsd4_destroy_session { 385struct nfsd4_destroy_session {
@@ -422,6 +427,7 @@ struct nfsd4_op {
422 427
423 /* NFSv4.1 */ 428 /* NFSv4.1 */
424 struct nfsd4_exchange_id exchange_id; 429 struct nfsd4_exchange_id exchange_id;
430 struct nfsd4_bind_conn_to_session bind_conn_to_session;
425 struct nfsd4_create_session create_session; 431 struct nfsd4_create_session create_session;
426 struct nfsd4_destroy_session destroy_session; 432 struct nfsd4_destroy_session destroy_session;
427 struct nfsd4_sequence sequence; 433 struct nfsd4_sequence sequence;
@@ -518,6 +524,7 @@ extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
518 struct nfsd4_sequence *seq); 524 struct nfsd4_sequence *seq);
519extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, 525extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
520 struct nfsd4_compound_state *, struct nfsd4_exchange_id *); 526 struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
527extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *);
521extern __be32 nfsd4_create_session(struct svc_rqst *, 528extern __be32 nfsd4_create_session(struct svc_rqst *,
522 struct nfsd4_compound_state *, 529 struct nfsd4_compound_state *,
523 struct nfsd4_create_session *); 530 struct nfsd4_create_session *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3984f2358d1..ed6ee473cc8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1066,7 +1066,6 @@ struct lock_manager_operations {
1066 int (*fl_grant)(struct file_lock *, struct file_lock *, int); 1066 int (*fl_grant)(struct file_lock *, struct file_lock *, int);
1067 void (*fl_release_private)(struct file_lock *); 1067 void (*fl_release_private)(struct file_lock *);
1068 void (*fl_break)(struct file_lock *); 1068 void (*fl_break)(struct file_lock *);
1069 int (*fl_mylease)(struct file_lock *, struct file_lock *);
1070 int (*fl_change)(struct file_lock **, int); 1069 int (*fl_change)(struct file_lock **, int);
1071}; 1070};
1072 1071
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 9b46300b430..134716e5e35 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -65,6 +65,9 @@
65 65
66#define NFS4_CDFC4_FORE 0x1 66#define NFS4_CDFC4_FORE 0x1
67#define NFS4_CDFC4_BACK 0x2 67#define NFS4_CDFC4_BACK 0x2
68#define NFS4_CDFC4_BOTH 0x3
69#define NFS4_CDFC4_FORE_OR_BOTH 0x3
70#define NFS4_CDFC4_BACK_OR_BOTH 0x7
68 71
69#define NFS4_SET_TO_SERVER_TIME 0 72#define NFS4_SET_TO_SERVER_TIME 0
70#define NFS4_SET_TO_CLIENT_TIME 1 73#define NFS4_SET_TO_CLIENT_TIME 1
@@ -140,6 +143,9 @@
140#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200 143#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200
141#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400 144#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400
142 145
146#define NFS4_SECINFO_STYLE4_CURRENT_FH 0
147#define NFS4_SECINFO_STYLE4_PARENT 1
148
143#define NFS4_MAX_UINT64 (~(u64)0) 149#define NFS4_MAX_UINT64 (~(u64)0)
144 150
145/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations. 151/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 8ae78a61eea..bd316159278 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -35,7 +35,7 @@
35#define NFSEXP_NOHIDE 0x0200 35#define NFSEXP_NOHIDE 0x0200
36#define NFSEXP_NOSUBTREECHECK 0x0400 36#define NFSEXP_NOSUBTREECHECK 0x0400
37#define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */ 37#define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */
38#define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect */ 38#define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect; no longer supported */
39#define NFSEXP_FSID 0x2000 39#define NFSEXP_FSID 0x2000
40#define NFSEXP_CROSSMOUNT 0x4000 40#define NFSEXP_CROSSMOUNT 0x4000
41#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */ 41#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 78aa104250b..7898ea13de7 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -256,10 +256,13 @@ static inline time_t get_expiry(char **bpp)
256 return rv - boot.tv_sec; 256 return rv - boot.tv_sec;
257} 257}
258 258
259#ifdef CONFIG_NFSD_DEPRECATED
259static inline void sunrpc_invalidate(struct cache_head *h, 260static inline void sunrpc_invalidate(struct cache_head *h,
260 struct cache_detail *detail) 261 struct cache_detail *detail)
261{ 262{
262 h->expiry_time = seconds_since_boot() - 1; 263 h->expiry_time = seconds_since_boot() - 1;
263 detail->nextcheck = seconds_since_boot(); 264 detail->nextcheck = seconds_since_boot();
264} 265}
266#endif /* CONFIG_NFSD_DEPRECATED */
267
265#endif /* _LINUX_SUNRPC_CACHE_H_ */ 268#endif /* _LINUX_SUNRPC_CACHE_H_ */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index c81d4d8be3a..ea29330b78b 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -269,6 +269,7 @@ struct svc_rqst {
269 struct cache_req rq_chandle; /* handle passed to caches for 269 struct cache_req rq_chandle; /* handle passed to caches for
270 * request delaying 270 * request delaying
271 */ 271 */
272 bool rq_dropme;
272 /* Catering to nfsd */ 273 /* Catering to nfsd */
273 struct auth_domain * rq_client; /* RPC peer info */ 274 struct auth_domain * rq_client; /* RPC peer info */
274 struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ 275 struct auth_domain * rq_gssclient; /* "gss/"-style peer info */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 357da5e0daa..059877b4d85 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -63,7 +63,6 @@ struct svc_xprt {
63#define XPT_LISTENER 11 /* listening endpoint */ 63#define XPT_LISTENER 11 /* listening endpoint */
64#define XPT_CACHE_AUTH 12 /* cache auth info */ 64#define XPT_CACHE_AUTH 12 /* cache auth info */
65 65
66 struct svc_pool *xpt_pool; /* current pool iff queued */
67 struct svc_serv *xpt_server; /* service for transport */ 66 struct svc_serv *xpt_server; /* service for transport */
68 atomic_t xpt_reserved; /* space on outq that is rsvd */ 67 atomic_t xpt_reserved; /* space on outq that is rsvd */
69 struct mutex xpt_mutex; /* to serialize sending data */ 68 struct mutex xpt_mutex; /* to serialize sending data */
@@ -81,6 +80,7 @@ struct svc_xprt {
81 void *xpt_bc_sid; /* back channel session ID */ 80 void *xpt_bc_sid; /* back channel session ID */
82 81
83 struct net *xpt_net; 82 struct net *xpt_net;
83 struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */
84}; 84};
85 85
86static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) 86static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 1b353a76c30..04dba23c59f 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -28,7 +28,6 @@ struct svc_sock {
28 /* private TCP part */ 28 /* private TCP part */
29 u32 sk_reclen; /* length of record */ 29 u32 sk_reclen; /* length of record */
30 u32 sk_tcplen; /* current read length */ 30 u32 sk_tcplen; /* current read length */
31 struct rpc_xprt *sk_bc_xprt; /* NFSv4.1 backchannel xprt */
32}; 31};
33 32
34/* 33/*
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 89d10d279a2..bef0f535f74 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -321,6 +321,7 @@ void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie);
321#define XPRT_CLOSING (6) 321#define XPRT_CLOSING (6)
322#define XPRT_CONNECTION_ABORT (7) 322#define XPRT_CONNECTION_ABORT (7)
323#define XPRT_CONNECTION_CLOSE (8) 323#define XPRT_CONNECTION_CLOSE (8)
324#define XPRT_INITIALIZED (9)
324 325
325static inline void xprt_set_connected(struct rpc_xprt *xprt) 326static inline void xprt_set_connected(struct rpc_xprt *xprt)
326{ 327{
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 75ee993ea05..9576f35ab70 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -137,7 +137,7 @@ arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4])
137 ms_usage = 13; 137 ms_usage = 13;
138 break; 138 break;
139 default: 139 default:
140 return EINVAL;; 140 return -EINVAL;
141 } 141 }
142 salt[0] = (ms_usage >> 0) & 0xff; 142 salt[0] = (ms_usage >> 0) & 0xff;
143 salt[1] = (ms_usage >> 8) & 0xff; 143 salt[1] = (ms_usage >> 8) & 0xff;
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index dec2a6fc7c1..bcdae78fdfc 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -67,7 +67,6 @@ static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b)
67 67
68#define RSI_HASHBITS 6 68#define RSI_HASHBITS 6
69#define RSI_HASHMAX (1<<RSI_HASHBITS) 69#define RSI_HASHMAX (1<<RSI_HASHBITS)
70#define RSI_HASHMASK (RSI_HASHMAX-1)
71 70
72struct rsi { 71struct rsi {
73 struct cache_head h; 72 struct cache_head h;
@@ -319,7 +318,6 @@ static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
319 318
320#define RSC_HASHBITS 10 319#define RSC_HASHBITS 10
321#define RSC_HASHMAX (1<<RSC_HASHBITS) 320#define RSC_HASHMAX (1<<RSC_HASHBITS)
322#define RSC_HASHMASK (RSC_HASHMAX-1)
323 321
324#define GSS_SEQ_WIN 128 322#define GSS_SEQ_WIN 128
325 323
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index e433e7580e2..72ad836e4fe 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -37,7 +37,7 @@
37 37
38#define RPCDBG_FACILITY RPCDBG_CACHE 38#define RPCDBG_FACILITY RPCDBG_CACHE
39 39
40static void cache_defer_req(struct cache_req *req, struct cache_head *item); 40static bool cache_defer_req(struct cache_req *req, struct cache_head *item);
41static void cache_revisit_request(struct cache_head *item); 41static void cache_revisit_request(struct cache_head *item);
42 42
43static void cache_init(struct cache_head *h) 43static void cache_init(struct cache_head *h)
@@ -128,6 +128,7 @@ static void cache_fresh_locked(struct cache_head *head, time_t expiry)
128{ 128{
129 head->expiry_time = expiry; 129 head->expiry_time = expiry;
130 head->last_refresh = seconds_since_boot(); 130 head->last_refresh = seconds_since_boot();
131 smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */
131 set_bit(CACHE_VALID, &head->flags); 132 set_bit(CACHE_VALID, &head->flags);
132} 133}
133 134
@@ -208,11 +209,36 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head
208 /* entry is valid */ 209 /* entry is valid */
209 if (test_bit(CACHE_NEGATIVE, &h->flags)) 210 if (test_bit(CACHE_NEGATIVE, &h->flags))
210 return -ENOENT; 211 return -ENOENT;
211 else 212 else {
213 /*
214 * In combination with write barrier in
215 * sunrpc_cache_update, ensures that anyone
216 * using the cache entry after this sees the
217 * updated contents:
218 */
219 smp_rmb();
212 return 0; 220 return 0;
221 }
213 } 222 }
214} 223}
215 224
225static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h)
226{
227 int rv;
228
229 write_lock(&detail->hash_lock);
230 rv = cache_is_valid(detail, h);
231 if (rv != -EAGAIN) {
232 write_unlock(&detail->hash_lock);
233 return rv;
234 }
235 set_bit(CACHE_NEGATIVE, &h->flags);
236 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
237 write_unlock(&detail->hash_lock);
238 cache_fresh_unlocked(h, detail);
239 return -ENOENT;
240}
241
216/* 242/*
217 * This is the generic cache management routine for all 243 * This is the generic cache management routine for all
218 * the authentication caches. 244 * the authentication caches.
@@ -251,14 +277,8 @@ int cache_check(struct cache_detail *detail,
251 case -EINVAL: 277 case -EINVAL:
252 clear_bit(CACHE_PENDING, &h->flags); 278 clear_bit(CACHE_PENDING, &h->flags);
253 cache_revisit_request(h); 279 cache_revisit_request(h);
254 if (rv == -EAGAIN) { 280 rv = try_to_negate_entry(detail, h);
255 set_bit(CACHE_NEGATIVE, &h->flags);
256 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
257 cache_fresh_unlocked(h, detail);
258 rv = -ENOENT;
259 }
260 break; 281 break;
261
262 case -EAGAIN: 282 case -EAGAIN:
263 clear_bit(CACHE_PENDING, &h->flags); 283 clear_bit(CACHE_PENDING, &h->flags);
264 cache_revisit_request(h); 284 cache_revisit_request(h);
@@ -268,9 +288,11 @@ int cache_check(struct cache_detail *detail,
268 } 288 }
269 289
270 if (rv == -EAGAIN) { 290 if (rv == -EAGAIN) {
271 cache_defer_req(rqstp, h); 291 if (!cache_defer_req(rqstp, h)) {
272 if (!test_bit(CACHE_PENDING, &h->flags)) { 292 /*
273 /* Request is not deferred */ 293 * Request was not deferred; handle it as best
294 * we can ourselves:
295 */
274 rv = cache_is_valid(detail, h); 296 rv = cache_is_valid(detail, h);
275 if (rv == -EAGAIN) 297 if (rv == -EAGAIN)
276 rv = -ETIMEDOUT; 298 rv = -ETIMEDOUT;
@@ -618,18 +640,19 @@ static void cache_limit_defers(void)
618 discard->revisit(discard, 1); 640 discard->revisit(discard, 1);
619} 641}
620 642
621static void cache_defer_req(struct cache_req *req, struct cache_head *item) 643/* Return true if and only if a deferred request is queued. */
644static bool cache_defer_req(struct cache_req *req, struct cache_head *item)
622{ 645{
623 struct cache_deferred_req *dreq; 646 struct cache_deferred_req *dreq;
624 647
625 if (req->thread_wait) { 648 if (req->thread_wait) {
626 cache_wait_req(req, item); 649 cache_wait_req(req, item);
627 if (!test_bit(CACHE_PENDING, &item->flags)) 650 if (!test_bit(CACHE_PENDING, &item->flags))
628 return; 651 return false;
629 } 652 }
630 dreq = req->defer(req); 653 dreq = req->defer(req);
631 if (dreq == NULL) 654 if (dreq == NULL)
632 return; 655 return false;
633 setup_deferral(dreq, item, 1); 656 setup_deferral(dreq, item, 1);
634 if (!test_bit(CACHE_PENDING, &item->flags)) 657 if (!test_bit(CACHE_PENDING, &item->flags))
635 /* Bit could have been cleared before we managed to 658 /* Bit could have been cleared before we managed to
@@ -638,6 +661,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
638 cache_revisit_request(item); 661 cache_revisit_request(item);
639 662
640 cache_limit_defers(); 663 cache_limit_defers();
664 return true;
641} 665}
642 666
643static void cache_revisit_request(struct cache_head *item) 667static void cache_revisit_request(struct cache_head *item)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 0e659c665a8..08e05a8ce02 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1001,6 +1001,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1001 rqstp->rq_splice_ok = 1; 1001 rqstp->rq_splice_ok = 1;
1002 /* Will be turned off only when NFSv4 Sessions are used */ 1002 /* Will be turned off only when NFSv4 Sessions are used */
1003 rqstp->rq_usedeferral = 1; 1003 rqstp->rq_usedeferral = 1;
1004 rqstp->rq_dropme = false;
1004 1005
1005 /* Setup reply header */ 1006 /* Setup reply header */
1006 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); 1007 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
@@ -1102,7 +1103,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1102 *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); 1103 *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
1103 1104
1104 /* Encode reply */ 1105 /* Encode reply */
1105 if (*statp == rpc_drop_reply) { 1106 if (rqstp->rq_dropme) {
1106 if (procp->pc_release) 1107 if (procp->pc_release)
1107 procp->pc_release(rqstp, NULL, rqstp->rq_resp); 1108 procp->pc_release(rqstp, NULL, rqstp->rq_resp);
1108 goto dropit; 1109 goto dropit;
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 3f2c5559ca1..ab86b7927f8 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -13,6 +13,7 @@
13#include <linux/sunrpc/stats.h> 13#include <linux/sunrpc/stats.h>
14#include <linux/sunrpc/svc_xprt.h> 14#include <linux/sunrpc/svc_xprt.h>
15#include <linux/sunrpc/svcsock.h> 15#include <linux/sunrpc/svcsock.h>
16#include <linux/sunrpc/xprt.h>
16 17
17#define RPCDBG_FACILITY RPCDBG_SVCXPRT 18#define RPCDBG_FACILITY RPCDBG_SVCXPRT
18 19
@@ -128,6 +129,9 @@ static void svc_xprt_free(struct kref *kref)
128 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) 129 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags))
129 svcauth_unix_info_release(xprt); 130 svcauth_unix_info_release(xprt);
130 put_net(xprt->xpt_net); 131 put_net(xprt->xpt_net);
132 /* See comment on corresponding get in xs_setup_bc_tcp(): */
133 if (xprt->xpt_bc_xprt)
134 xprt_put(xprt->xpt_bc_xprt);
131 xprt->xpt_ops->xpo_free(xprt); 135 xprt->xpt_ops->xpo_free(xprt);
132 module_put(owner); 136 module_put(owner);
133} 137}
@@ -303,6 +307,15 @@ static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp)
303 list_del(&rqstp->rq_list); 307 list_del(&rqstp->rq_list);
304} 308}
305 309
310static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)
311{
312 if (xprt->xpt_flags & ((1<<XPT_CONN)|(1<<XPT_CLOSE)))
313 return true;
314 if (xprt->xpt_flags & ((1<<XPT_DATA)|(1<<XPT_DEFERRED)))
315 return xprt->xpt_ops->xpo_has_wspace(xprt);
316 return false;
317}
318
306/* 319/*
307 * Queue up a transport with data pending. If there are idle nfsd 320 * Queue up a transport with data pending. If there are idle nfsd
308 * processes, wake 'em up. 321 * processes, wake 'em up.
@@ -315,8 +328,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
315 struct svc_rqst *rqstp; 328 struct svc_rqst *rqstp;
316 int cpu; 329 int cpu;
317 330
318 if (!(xprt->xpt_flags & 331 if (!svc_xprt_has_something_to_do(xprt))
319 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
320 return; 332 return;
321 333
322 cpu = get_cpu(); 334 cpu = get_cpu();
@@ -343,28 +355,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
343 dprintk("svc: transport %p busy, not enqueued\n", xprt); 355 dprintk("svc: transport %p busy, not enqueued\n", xprt);
344 goto out_unlock; 356 goto out_unlock;
345 } 357 }
346 BUG_ON(xprt->xpt_pool != NULL);
347 xprt->xpt_pool = pool;
348
349 /* Handle pending connection */
350 if (test_bit(XPT_CONN, &xprt->xpt_flags))
351 goto process;
352
353 /* Handle close in-progress */
354 if (test_bit(XPT_CLOSE, &xprt->xpt_flags))
355 goto process;
356
357 /* Check if we have space to reply to a request */
358 if (!xprt->xpt_ops->xpo_has_wspace(xprt)) {
359 /* Don't enqueue while not enough space for reply */
360 dprintk("svc: no write space, transport %p not enqueued\n",
361 xprt);
362 xprt->xpt_pool = NULL;
363 clear_bit(XPT_BUSY, &xprt->xpt_flags);
364 goto out_unlock;
365 }
366 358
367 process:
368 if (!list_empty(&pool->sp_threads)) { 359 if (!list_empty(&pool->sp_threads)) {
369 rqstp = list_entry(pool->sp_threads.next, 360 rqstp = list_entry(pool->sp_threads.next,
370 struct svc_rqst, 361 struct svc_rqst,
@@ -381,13 +372,11 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
381 rqstp->rq_reserved = serv->sv_max_mesg; 372 rqstp->rq_reserved = serv->sv_max_mesg;
382 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 373 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
383 pool->sp_stats.threads_woken++; 374 pool->sp_stats.threads_woken++;
384 BUG_ON(xprt->xpt_pool != pool);
385 wake_up(&rqstp->rq_wait); 375 wake_up(&rqstp->rq_wait);
386 } else { 376 } else {
387 dprintk("svc: transport %p put into queue\n", xprt); 377 dprintk("svc: transport %p put into queue\n", xprt);
388 list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); 378 list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
389 pool->sp_stats.sockets_queued++; 379 pool->sp_stats.sockets_queued++;
390 BUG_ON(xprt->xpt_pool != pool);
391 } 380 }
392 381
393out_unlock: 382out_unlock:
@@ -426,7 +415,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
426void svc_xprt_received(struct svc_xprt *xprt) 415void svc_xprt_received(struct svc_xprt *xprt)
427{ 416{
428 BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); 417 BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
429 xprt->xpt_pool = NULL;
430 /* As soon as we clear busy, the xprt could be closed and 418 /* As soon as we clear busy, the xprt could be closed and
431 * 'put', so we need a reference to call svc_xprt_enqueue with: 419 * 'put', so we need a reference to call svc_xprt_enqueue with:
432 */ 420 */
@@ -722,7 +710,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
722 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { 710 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
723 dprintk("svc_recv: found XPT_CLOSE\n"); 711 dprintk("svc_recv: found XPT_CLOSE\n");
724 svc_delete_xprt(xprt); 712 svc_delete_xprt(xprt);
725 } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { 713 /* Leave XPT_BUSY set on the dead xprt: */
714 goto out;
715 }
716 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
726 struct svc_xprt *newxpt; 717 struct svc_xprt *newxpt;
727 newxpt = xprt->xpt_ops->xpo_accept(xprt); 718 newxpt = xprt->xpt_ops->xpo_accept(xprt);
728 if (newxpt) { 719 if (newxpt) {
@@ -747,28 +738,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
747 spin_unlock_bh(&serv->sv_lock); 738 spin_unlock_bh(&serv->sv_lock);
748 svc_xprt_received(newxpt); 739 svc_xprt_received(newxpt);
749 } 740 }
750 svc_xprt_received(xprt); 741 } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
751 } else {
752 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", 742 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
753 rqstp, pool->sp_id, xprt, 743 rqstp, pool->sp_id, xprt,
754 atomic_read(&xprt->xpt_ref.refcount)); 744 atomic_read(&xprt->xpt_ref.refcount));
755 rqstp->rq_deferred = svc_deferred_dequeue(xprt); 745 rqstp->rq_deferred = svc_deferred_dequeue(xprt);
756 if (rqstp->rq_deferred) { 746 if (rqstp->rq_deferred)
757 svc_xprt_received(xprt);
758 len = svc_deferred_recv(rqstp); 747 len = svc_deferred_recv(rqstp);
759 } else { 748 else
760 len = xprt->xpt_ops->xpo_recvfrom(rqstp); 749 len = xprt->xpt_ops->xpo_recvfrom(rqstp);
761 svc_xprt_received(xprt);
762 }
763 dprintk("svc: got len=%d\n", len); 750 dprintk("svc: got len=%d\n", len);
764 } 751 }
752 svc_xprt_received(xprt);
765 753
766 /* No data, incomplete (TCP) read, or accept() */ 754 /* No data, incomplete (TCP) read, or accept() */
767 if (len == 0 || len == -EAGAIN) { 755 if (len == 0 || len == -EAGAIN)
768 rqstp->rq_res.len = 0; 756 goto out;
769 svc_xprt_release(rqstp); 757
770 return -EAGAIN;
771 }
772 clear_bit(XPT_OLD, &xprt->xpt_flags); 758 clear_bit(XPT_OLD, &xprt->xpt_flags);
773 759
774 rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); 760 rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp));
@@ -777,6 +763,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
777 if (serv->sv_stats) 763 if (serv->sv_stats)
778 serv->sv_stats->netcnt++; 764 serv->sv_stats->netcnt++;
779 return len; 765 return len;
766out:
767 rqstp->rq_res.len = 0;
768 svc_xprt_release(rqstp);
769 return -EAGAIN;
780} 770}
781EXPORT_SYMBOL_GPL(svc_recv); 771EXPORT_SYMBOL_GPL(svc_recv);
782 772
@@ -935,7 +925,12 @@ void svc_close_xprt(struct svc_xprt *xprt)
935 if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) 925 if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
936 /* someone else will have to effect the close */ 926 /* someone else will have to effect the close */
937 return; 927 return;
938 928 /*
929 * We expect svc_close_xprt() to work even when no threads are
930 * running (e.g., while configuring the server before starting
931 * any threads), so if the transport isn't busy, we delete
932 * it ourself:
933 */
939 svc_delete_xprt(xprt); 934 svc_delete_xprt(xprt);
940} 935}
941EXPORT_SYMBOL_GPL(svc_close_xprt); 936EXPORT_SYMBOL_GPL(svc_close_xprt);
@@ -945,16 +940,16 @@ void svc_close_all(struct list_head *xprt_list)
945 struct svc_xprt *xprt; 940 struct svc_xprt *xprt;
946 struct svc_xprt *tmp; 941 struct svc_xprt *tmp;
947 942
943 /*
944 * The server is shutting down, and no more threads are running.
945 * svc_xprt_enqueue() might still be running, but at worst it
946 * will re-add the xprt to sp_sockets, which will soon get
947 * freed. So we don't bother with any more locking, and don't
948 * leave the close to the (nonexistent) server threads:
949 */
948 list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { 950 list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
949 set_bit(XPT_CLOSE, &xprt->xpt_flags); 951 set_bit(XPT_CLOSE, &xprt->xpt_flags);
950 if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { 952 svc_delete_xprt(xprt);
951 /* Waiting to be processed, but no threads left,
952 * So just remove it from the waiting list
953 */
954 list_del_init(&xprt->xpt_ready);
955 clear_bit(XPT_BUSY, &xprt->xpt_flags);
956 }
957 svc_close_xprt(xprt);
958 } 953 }
959} 954}
960 955
@@ -1028,6 +1023,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
1028 } 1023 }
1029 svc_xprt_get(rqstp->rq_xprt); 1024 svc_xprt_get(rqstp->rq_xprt);
1030 dr->xprt = rqstp->rq_xprt; 1025 dr->xprt = rqstp->rq_xprt;
1026 rqstp->rq_dropme = true;
1031 1027
1032 dr->handle.revisit = svc_revisit; 1028 dr->handle.revisit = svc_revisit;
1033 return &dr->handle; 1029 return &dr->handle;
@@ -1065,14 +1061,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
1065 if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) 1061 if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags))
1066 return NULL; 1062 return NULL;
1067 spin_lock(&xprt->xpt_lock); 1063 spin_lock(&xprt->xpt_lock);
1068 clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
1069 if (!list_empty(&xprt->xpt_deferred)) { 1064 if (!list_empty(&xprt->xpt_deferred)) {
1070 dr = list_entry(xprt->xpt_deferred.next, 1065 dr = list_entry(xprt->xpt_deferred.next,
1071 struct svc_deferred_req, 1066 struct svc_deferred_req,
1072 handle.recent); 1067 handle.recent);
1073 list_del_init(&dr->handle.recent); 1068 list_del_init(&dr->handle.recent);
1074 set_bit(XPT_DEFERRED, &xprt->xpt_flags); 1069 } else
1075 } 1070 clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
1076 spin_unlock(&xprt->xpt_lock); 1071 spin_unlock(&xprt->xpt_lock);
1077 return dr; 1072 return dr;
1078} 1073}
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 4e9393c2468..7963569fc04 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -118,7 +118,6 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister);
118 118
119#define DN_HASHBITS 6 119#define DN_HASHBITS 6
120#define DN_HASHMAX (1<<DN_HASHBITS) 120#define DN_HASHMAX (1<<DN_HASHBITS)
121#define DN_HASHMASK (DN_HASHMAX-1)
122 121
123static struct hlist_head auth_domain_table[DN_HASHMAX]; 122static struct hlist_head auth_domain_table[DN_HASHMAX];
124static spinlock_t auth_domain_lock = 123static spinlock_t auth_domain_lock =
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 560677d187f..30916b06c12 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -30,7 +30,9 @@
30 30
31struct unix_domain { 31struct unix_domain {
32 struct auth_domain h; 32 struct auth_domain h;
33#ifdef CONFIG_NFSD_DEPRECATED
33 int addr_changes; 34 int addr_changes;
35#endif /* CONFIG_NFSD_DEPRECATED */
34 /* other stuff later */ 36 /* other stuff later */
35}; 37};
36 38
@@ -64,7 +66,9 @@ struct auth_domain *unix_domain_find(char *name)
64 return NULL; 66 return NULL;
65 } 67 }
66 new->h.flavour = &svcauth_unix; 68 new->h.flavour = &svcauth_unix;
69#ifdef CONFIG_NFSD_DEPRECATED
67 new->addr_changes = 0; 70 new->addr_changes = 0;
71#endif /* CONFIG_NFSD_DEPRECATED */
68 rv = auth_domain_lookup(name, &new->h); 72 rv = auth_domain_lookup(name, &new->h);
69 } 73 }
70} 74}
@@ -85,14 +89,15 @@ static void svcauth_unix_domain_release(struct auth_domain *dom)
85 */ 89 */
86#define IP_HASHBITS 8 90#define IP_HASHBITS 8
87#define IP_HASHMAX (1<<IP_HASHBITS) 91#define IP_HASHMAX (1<<IP_HASHBITS)
88#define IP_HASHMASK (IP_HASHMAX-1)
89 92
90struct ip_map { 93struct ip_map {
91 struct cache_head h; 94 struct cache_head h;
92 char m_class[8]; /* e.g. "nfsd" */ 95 char m_class[8]; /* e.g. "nfsd" */
93 struct in6_addr m_addr; 96 struct in6_addr m_addr;
94 struct unix_domain *m_client; 97 struct unix_domain *m_client;
98#ifdef CONFIG_NFSD_DEPRECATED
95 int m_add_change; 99 int m_add_change;
100#endif /* CONFIG_NFSD_DEPRECATED */
96}; 101};
97 102
98static void ip_map_put(struct kref *kref) 103static void ip_map_put(struct kref *kref)
@@ -146,7 +151,9 @@ static void update(struct cache_head *cnew, struct cache_head *citem)
146 151
147 kref_get(&item->m_client->h.ref); 152 kref_get(&item->m_client->h.ref);
148 new->m_client = item->m_client; 153 new->m_client = item->m_client;
154#ifdef CONFIG_NFSD_DEPRECATED
149 new->m_add_change = item->m_add_change; 155 new->m_add_change = item->m_add_change;
156#endif /* CONFIG_NFSD_DEPRECATED */
150} 157}
151static struct cache_head *ip_map_alloc(void) 158static struct cache_head *ip_map_alloc(void)
152{ 159{
@@ -331,6 +338,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
331 ip.h.flags = 0; 338 ip.h.flags = 0;
332 if (!udom) 339 if (!udom)
333 set_bit(CACHE_NEGATIVE, &ip.h.flags); 340 set_bit(CACHE_NEGATIVE, &ip.h.flags);
341#ifdef CONFIG_NFSD_DEPRECATED
334 else { 342 else {
335 ip.m_add_change = udom->addr_changes; 343 ip.m_add_change = udom->addr_changes;
336 /* if this is from the legacy set_client system call, 344 /* if this is from the legacy set_client system call,
@@ -339,6 +347,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
339 if (expiry == NEVER) 347 if (expiry == NEVER)
340 ip.m_add_change++; 348 ip.m_add_change++;
341 } 349 }
350#endif /* CONFIG_NFSD_DEPRECATED */
342 ip.h.expiry_time = expiry; 351 ip.h.expiry_time = expiry;
343 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, 352 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
344 hash_str(ipm->m_class, IP_HASHBITS) ^ 353 hash_str(ipm->m_class, IP_HASHBITS) ^
@@ -358,6 +367,7 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm,
358 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); 367 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
359} 368}
360 369
370#ifdef CONFIG_NFSD_DEPRECATED
361int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) 371int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom)
362{ 372{
363 struct unix_domain *udom; 373 struct unix_domain *udom;
@@ -402,8 +412,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
402 return NULL; 412 return NULL;
403 413
404 if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { 414 if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) {
405 if (test_and_set_bit(CACHE_NEGATIVE, &ipm->h.flags) == 0) 415 sunrpc_invalidate(&ipm->h, sn->ip_map_cache);
406 auth_domain_put(&ipm->m_client->h);
407 rv = NULL; 416 rv = NULL;
408 } else { 417 } else {
409 rv = &ipm->m_client->h; 418 rv = &ipm->m_client->h;
@@ -413,6 +422,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
413 return rv; 422 return rv;
414} 423}
415EXPORT_SYMBOL_GPL(auth_unix_lookup); 424EXPORT_SYMBOL_GPL(auth_unix_lookup);
425#endif /* CONFIG_NFSD_DEPRECATED */
416 426
417void svcauth_unix_purge(void) 427void svcauth_unix_purge(void)
418{ 428{
@@ -497,7 +507,6 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
497 */ 507 */
498#define GID_HASHBITS 8 508#define GID_HASHBITS 8
499#define GID_HASHMAX (1<<GID_HASHBITS) 509#define GID_HASHMAX (1<<GID_HASHBITS)
500#define GID_HASHMASK (GID_HASHMAX - 1)
501 510
502struct unix_gid { 511struct unix_gid {
503 struct cache_head h; 512 struct cache_head h;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index d265aa700bb..7bd3bbba471 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -331,19 +331,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen,
331 len = onelen; 331 len = onelen;
332 break; 332 break;
333 } 333 }
334 if (toclose && strcmp(toclose, buf + len) == 0) 334 if (toclose && strcmp(toclose, buf + len) == 0) {
335 closesk = svsk; 335 closesk = svsk;
336 else 336 svc_xprt_get(&closesk->sk_xprt);
337 } else
337 len += onelen; 338 len += onelen;
338 } 339 }
339 spin_unlock_bh(&serv->sv_lock); 340 spin_unlock_bh(&serv->sv_lock);
340 341
341 if (closesk) 342 if (closesk) {
342 /* Should unregister with portmap, but you cannot 343 /* Should unregister with portmap, but you cannot
343 * unregister just one protocol... 344 * unregister just one protocol...
344 */ 345 */
345 svc_close_xprt(&closesk->sk_xprt); 346 svc_close_xprt(&closesk->sk_xprt);
346 else if (toclose) 347 svc_xprt_put(&closesk->sk_xprt);
348 } else if (toclose)
347 return -ENOENT; 349 return -ENOENT;
348 return len; 350 return len;
349} 351}
@@ -992,15 +994,17 @@ static int svc_process_calldir(struct svc_sock *svsk, struct svc_rqst *rqstp,
992 vec[0] = rqstp->rq_arg.head[0]; 994 vec[0] = rqstp->rq_arg.head[0];
993 } else { 995 } else {
994 /* REPLY */ 996 /* REPLY */
995 if (svsk->sk_bc_xprt) 997 struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt;
996 req = xprt_lookup_rqst(svsk->sk_bc_xprt, xid); 998
999 if (bc_xprt)
1000 req = xprt_lookup_rqst(bc_xprt, xid);
997 1001
998 if (!req) { 1002 if (!req) {
999 printk(KERN_NOTICE 1003 printk(KERN_NOTICE
1000 "%s: Got unrecognized reply: " 1004 "%s: Got unrecognized reply: "
1001 "calldir 0x%x sk_bc_xprt %p xid %08x\n", 1005 "calldir 0x%x xpt_bc_xprt %p xid %08x\n",
1002 __func__, ntohl(calldir), 1006 __func__, ntohl(calldir),
1003 svsk->sk_bc_xprt, xid); 1007 bc_xprt, xid);
1004 vec[0] = rqstp->rq_arg.head[0]; 1008 vec[0] = rqstp->rq_arg.head[0];
1005 goto out; 1009 goto out;
1006 } 1010 }
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 4c8f18aff7c..856274d7e85 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -965,6 +965,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req)
965 xprt = kzalloc(size, GFP_KERNEL); 965 xprt = kzalloc(size, GFP_KERNEL);
966 if (xprt == NULL) 966 if (xprt == NULL)
967 goto out; 967 goto out;
968 kref_init(&xprt->kref);
968 969
969 xprt->max_reqs = max_req; 970 xprt->max_reqs = max_req;
970 xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); 971 xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL);
@@ -1101,8 +1102,10 @@ found:
1101 -PTR_ERR(xprt)); 1102 -PTR_ERR(xprt));
1102 return xprt; 1103 return xprt;
1103 } 1104 }
1105 if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state))
1106 /* ->setup returned a pre-initialized xprt: */
1107 return xprt;
1104 1108
1105 kref_init(&xprt->kref);
1106 spin_lock_init(&xprt->transport_lock); 1109 spin_lock_init(&xprt->transport_lock);
1107 spin_lock_init(&xprt->reserve_lock); 1110 spin_lock_init(&xprt->reserve_lock);
1108 1111
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 96549df836e..c431f5a5796 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2359,6 +2359,15 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2359 struct svc_sock *bc_sock; 2359 struct svc_sock *bc_sock;
2360 struct rpc_xprt *ret; 2360 struct rpc_xprt *ret;
2361 2361
2362 if (args->bc_xprt->xpt_bc_xprt) {
2363 /*
2364 * This server connection already has a backchannel
2365 * export; we can't create a new one, as we wouldn't be
2366 * able to match replies based on xid any more. So,
2367 * reuse the already-existing one:
2368 */
2369 return args->bc_xprt->xpt_bc_xprt;
2370 }
2362 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); 2371 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
2363 if (IS_ERR(xprt)) 2372 if (IS_ERR(xprt))
2364 return xprt; 2373 return xprt;
@@ -2375,16 +2384,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2375 xprt->reestablish_timeout = 0; 2384 xprt->reestablish_timeout = 0;
2376 xprt->idle_timeout = 0; 2385 xprt->idle_timeout = 0;
2377 2386
2378 /*
2379 * The backchannel uses the same socket connection as the
2380 * forechannel
2381 */
2382 xprt->bc_xprt = args->bc_xprt;
2383 bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt);
2384 bc_sock->sk_bc_xprt = xprt;
2385 transport->sock = bc_sock->sk_sock;
2386 transport->inet = bc_sock->sk_sk;
2387
2388 xprt->ops = &bc_tcp_ops; 2387 xprt->ops = &bc_tcp_ops;
2389 2388
2390 switch (addr->sa_family) { 2389 switch (addr->sa_family) {
@@ -2407,6 +2406,20 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2407 xprt->address_strings[RPC_DISPLAY_PROTO]); 2406 xprt->address_strings[RPC_DISPLAY_PROTO]);
2408 2407
2409 /* 2408 /*
2409 * Once we've associated a backchannel xprt with a connection,
2410 * we want to keep it around as long as long as the connection
2411 * lasts, in case we need to start using it for a backchannel
2412 * again; this reference won't be dropped until bc_xprt is
2413 * destroyed.
2414 */
2415 xprt_get(xprt);
2416 args->bc_xprt->xpt_bc_xprt = xprt;
2417 xprt->bc_xprt = args->bc_xprt;
2418 bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt);
2419 transport->sock = bc_sock->sk_sock;
2420 transport->inet = bc_sock->sk_sk;
2421
2422 /*
2410 * Since we don't want connections for the backchannel, we set 2423 * Since we don't want connections for the backchannel, we set
2411 * the xprt status to connected 2424 * the xprt status to connected
2412 */ 2425 */
@@ -2415,6 +2428,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2415 2428
2416 if (try_module_get(THIS_MODULE)) 2429 if (try_module_get(THIS_MODULE))
2417 return xprt; 2430 return xprt;
2431 xprt_put(xprt);
2418 ret = ERR_PTR(-EINVAL); 2432 ret = ERR_PTR(-EINVAL);
2419out_err: 2433out_err:
2420 xprt_free(xprt); 2434 xprt_free(xprt);