aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-11-01 18:09:48 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-11-07 19:39:58 -0500
commitcb73a9f4649bf63c0397e565a15abf8a91ecf56f (patch)
tree96fb7200465a50047c92089ee4b504a3ebcfe9bb
parentc6bb3ca27d78b902baa143b931a8d9ef53298afa (diff)
nfsd4: implement backchannel_ctl operation
This operation is mandatory for servers to implement. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--Documentation/filesystems/nfs/nfs41-server.txt7
-rw-r--r--fs/nfsd/nfs4proc.c6
-rw-r--r--fs/nfsd/nfs4state.c14
-rw-r--r--fs/nfsd/nfs4xdr.c13
-rw-r--r--fs/nfsd/state.h5
-rw-r--r--fs/nfsd/xdr4.h2
6 files changed, 40 insertions, 7 deletions
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt
index 092fad92a3f..f5ddff2da30 100644
--- a/Documentation/filesystems/nfs/nfs41-server.txt
+++ b/Documentation/filesystems/nfs/nfs41-server.txt
@@ -39,11 +39,6 @@ interoperability problems with future clients. Known issues:
39 from a linux client are possible, but we aren't really 39 from a linux client are possible, but we aren't really
40 conformant with the spec (for example, we don't use kerberos 40 conformant with the spec (for example, we don't use kerberos
41 on the backchannel correctly). 41 on the backchannel correctly).
42 - Incomplete backchannel support: incomplete backchannel gss
43 support and no support for BACKCHANNEL_CTL mean that
44 callbacks (hence delegations and layouts) may not be
45 available and clients confused by the incomplete
46 implementation may fail.
47 - We do not support SSV, which provides security for shared 42 - We do not support SSV, which provides security for shared
48 client-server state (thus preventing unauthorized tampering 43 client-server state (thus preventing unauthorized tampering
49 with locks and opens, for example). It is mandatory for 44 with locks and opens, for example). It is mandatory for
@@ -89,7 +84,7 @@ Operations
89 | | MNI | or OPT) | | 84 | | MNI | or OPT) | |
90 +----------------------+------------+--------------+----------------+ 85 +----------------------+------------+--------------+----------------+
91 | ACCESS | REQ | | Section 18.1 | 86 | ACCESS | REQ | | Section 18.1 |
92NS | BACKCHANNEL_CTL | REQ | | Section 18.33 | 87I | BACKCHANNEL_CTL | REQ | | Section 18.33 |
93I | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | 88I | BIND_CONN_TO_SESSION | REQ | | Section 18.34 |
94 | CLOSE | REQ | | Section 18.2 | 89 | CLOSE | REQ | | Section 18.2 |
95 | COMMIT | REQ | | Section 18.3 | 90 | COMMIT | REQ | | Section 18.3 |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 6c9a4b291db..f955176f1b6 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1666,6 +1666,12 @@ static struct nfsd4_operation nfsd4_ops[] = {
1666 .op_name = "OP_EXCHANGE_ID", 1666 .op_name = "OP_EXCHANGE_ID",
1667 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize, 1667 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize,
1668 }, 1668 },
1669 [OP_BACKCHANNEL_CTL] = {
1670 .op_func = (nfsd4op_func)nfsd4_backchannel_ctl,
1671 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1672 .op_name = "OP_BACKCHANNEL_CTL",
1673 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1674 },
1669 [OP_BIND_CONN_TO_SESSION] = { 1675 [OP_BIND_CONN_TO_SESSION] = {
1670 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, 1676 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
1671 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1677 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index dbbbd2fe523..4023e77687e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1865,6 +1865,20 @@ static __be32 nfsd4_map_bcts_dir(u32 *dir)
1865 return nfserr_inval; 1865 return nfserr_inval;
1866} 1866}
1867 1867
1868__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_backchannel_ctl *bc)
1869{
1870 struct nfsd4_session *session = cstate->session;
1871
1872 spin_lock(&client_lock);
1873 session->se_cb_prog = bc->bc_cb_program;
1874 session->se_cb_sec = bc->bc_cb_sec;
1875 spin_unlock(&client_lock);
1876
1877 nfsd4_probe_callback(session->se_client);
1878
1879 return nfs_ok;
1880}
1881
1868__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, 1882__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1869 struct nfsd4_compound_state *cstate, 1883 struct nfsd4_compound_state *cstate,
1870 struct nfsd4_bind_conn_to_session *bcts) 1884 struct nfsd4_bind_conn_to_session *bcts)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 511f980b605..d7e7c110246 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -483,6 +483,17 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
483 DECODE_TAIL; 483 DECODE_TAIL;
484} 484}
485 485
486static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
487{
488 DECODE_HEAD;
489
490 READ_BUF(4);
491 READ32(bc->bc_cb_program);
492 nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
493
494 DECODE_TAIL;
495}
496
486static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) 497static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
487{ 498{
488 DECODE_HEAD; 499 DECODE_HEAD;
@@ -1536,7 +1547,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1536 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp, 1547 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,
1537 1548
1538 /* new operations for NFSv4.1 */ 1549 /* new operations for NFSv4.1 */
1539 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, 1550 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
1540 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, 1551 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1541 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, 1552 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
1542 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, 1553 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index bff856c34a3..758bc9c2646 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -166,6 +166,11 @@ struct nfsd4_create_session {
166 struct nfsd4_cb_sec cb_sec; 166 struct nfsd4_cb_sec cb_sec;
167}; 167};
168 168
169struct nfsd4_backchannel_ctl {
170 u32 bc_cb_program;
171 struct nfsd4_cb_sec bc_cb_sec;
172};
173
169struct nfsd4_bind_conn_to_session { 174struct nfsd4_bind_conn_to_session {
170 struct nfs4_sessionid sessionid; 175 struct nfs4_sessionid sessionid;
171 u32 dir; 176 u32 dir;
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index acd127d4ee8..71c5c47f275 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -462,6 +462,7 @@ struct nfsd4_op {
462 462
463 /* NFSv4.1 */ 463 /* NFSv4.1 */
464 struct nfsd4_exchange_id exchange_id; 464 struct nfsd4_exchange_id exchange_id;
465 struct nfsd4_backchannel_ctl backchannel_ctl;
465 struct nfsd4_bind_conn_to_session bind_conn_to_session; 466 struct nfsd4_bind_conn_to_session bind_conn_to_session;
466 struct nfsd4_create_session create_session; 467 struct nfsd4_create_session create_session;
467 struct nfsd4_destroy_session destroy_session; 468 struct nfsd4_destroy_session destroy_session;
@@ -566,6 +567,7 @@ extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
566 struct nfsd4_sequence *seq); 567 struct nfsd4_sequence *seq);
567extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, 568extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
568 struct nfsd4_compound_state *, struct nfsd4_exchange_id *); 569 struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
570extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *);
569extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *); 571extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *);
570extern __be32 nfsd4_create_session(struct svc_rqst *, 572extern __be32 nfsd4_create_session(struct svc_rqst *,
571 struct nfsd4_compound_state *, 573 struct nfsd4_compound_state *,