2 * Copyright (c) 2001 The Regents of the University of Michigan.
5 * Kendrick Smith <kmsmith@umich.edu>
6 * Andy Adamson <andros@umich.edu>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <linux/sunrpc/clnt.h>
35 #include <linux/sunrpc/svc_xprt.h>
36 #include <linux/slab.h>
40 #define NFSDDBG_FACILITY NFSDDBG_PROC
42 #define NFSPROC4_CB_NULL 0
43 #define NFSPROC4_CB_COMPOUND 1
45 /* Index of predefined Linux callback client operations */
48 NFSPROC4_CLNT_CB_NULL
= 0,
49 NFSPROC4_CLNT_CB_RECALL
,
50 NFSPROC4_CLNT_CB_SEQUENCE
,
53 #define NFS4_MAXTAGLEN 20
55 #define NFS4_enc_cb_null_sz 0
56 #define NFS4_dec_cb_null_sz 0
57 #define cb_compound_enc_hdr_sz 4
58 #define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2))
59 #define sessionid_sz (NFS4_MAX_SESSIONID_LEN >> 2)
60 #define cb_sequence_enc_sz (sessionid_sz + 4 + \
61 1 /* no referring calls list yet */)
62 #define cb_sequence_dec_sz (op_dec_sz + sessionid_sz + 4)
66 #define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2))
67 #define enc_stateid_sz (NFS4_STATEID_SIZE >> 2)
68 #define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \
69 cb_sequence_enc_sz + \
70 1 + enc_stateid_sz + \
73 #define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \
74 cb_sequence_dec_sz + \
78 * Generic decode routines from fs/nfs/nfs4xdr.c
85 dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \
89 #define READ32(x) (x) = ntohl(*p++)
90 #define READ64(x) do { \
91 (x) = (u64)ntohl(*p++) << 32; \
94 #define READTIME(x) do { \
96 (x.tv_sec) = ntohl(*p++); \
97 (x.tv_nsec) = ntohl(*p++); \
99 #define READ_BUF(nbytes) do { \
100 p = xdr_inline_decode(xdr, nbytes); \
102 dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
103 __func__, __LINE__); \
108 struct nfs4_cb_compound_hdr
{
110 u32 ident
; /* minorversion 0 only */
121 } nfs_cb_errtbl
[] = {
123 { NFS4ERR_PERM
, EPERM
},
124 { NFS4ERR_NOENT
, ENOENT
},
126 { NFS4ERR_NXIO
, ENXIO
},
127 { NFS4ERR_ACCESS
, EACCES
},
128 { NFS4ERR_EXIST
, EEXIST
},
129 { NFS4ERR_XDEV
, EXDEV
},
130 { NFS4ERR_NOTDIR
, ENOTDIR
},
131 { NFS4ERR_ISDIR
, EISDIR
},
132 { NFS4ERR_INVAL
, EINVAL
},
133 { NFS4ERR_FBIG
, EFBIG
},
134 { NFS4ERR_NOSPC
, ENOSPC
},
135 { NFS4ERR_ROFS
, EROFS
},
136 { NFS4ERR_MLINK
, EMLINK
},
137 { NFS4ERR_NAMETOOLONG
, ENAMETOOLONG
},
138 { NFS4ERR_NOTEMPTY
, ENOTEMPTY
},
139 { NFS4ERR_DQUOT
, EDQUOT
},
140 { NFS4ERR_STALE
, ESTALE
},
141 { NFS4ERR_BADHANDLE
, EBADHANDLE
},
142 { NFS4ERR_BAD_COOKIE
, EBADCOOKIE
},
143 { NFS4ERR_NOTSUPP
, ENOTSUPP
},
144 { NFS4ERR_TOOSMALL
, ETOOSMALL
},
145 { NFS4ERR_SERVERFAULT
, ESERVERFAULT
},
146 { NFS4ERR_BADTYPE
, EBADTYPE
},
147 { NFS4ERR_LOCKED
, EAGAIN
},
148 { NFS4ERR_RESOURCE
, EREMOTEIO
},
149 { NFS4ERR_SYMLINK
, ELOOP
},
150 { NFS4ERR_OP_ILLEGAL
, EOPNOTSUPP
},
151 { NFS4ERR_DEADLOCK
, EDEADLK
},
156 nfs_cb_stat_to_errno(int stat
)
159 for (i
= 0; nfs_cb_errtbl
[i
].stat
!= -1; i
++) {
160 if (nfs_cb_errtbl
[i
].stat
== stat
)
161 return nfs_cb_errtbl
[i
].errno
;
163 /* If we cannot translate the error, the recovery routines should
165 * Note: remaining NFSv4 error codes have values > 10000, so should
166 * not conflict with native Linux error codes.
171 static __be32
*xdr_encode_empty_array(__be32
*p
)
178 * Encode/decode NFSv4 CB basic data types
180 * Basic NFSv4 callback data types are defined in section 15 of RFC
181 * 3530: "Network File System (NFS) version 4 Protocol" and section
182 * 20 of RFC 5661: "Network File System (NFS) Version 4 Minor Version
189 * enum nfs_cb_opnum4 {
197 OP_CB_LAYOUTRECALL
= 5,
199 OP_CB_PUSH_DELEG
= 7,
200 OP_CB_RECALL_ANY
= 8,
201 OP_CB_RECALLABLE_OBJ_AVAIL
= 9,
202 OP_CB_RECALL_SLOT
= 10,
204 OP_CB_WANTS_CANCELLED
= 12,
205 OP_CB_NOTIFY_LOCK
= 13,
206 OP_CB_NOTIFY_DEVICEID
= 14,
207 OP_CB_ILLEGAL
= 10044
210 static void encode_nfs_cb_opnum4(struct xdr_stream
*xdr
, enum nfs_cb_opnum4 op
)
214 p
= xdr_reserve_space(xdr
, 4);
215 *p
= cpu_to_be32(op
);
221 * typedef opaque nfs_fh4<NFS4_FHSIZE>;
223 static void encode_nfs_fh4(struct xdr_stream
*xdr
, const struct knfsd_fh
*fh
)
225 u32 length
= fh
->fh_size
;
228 BUG_ON(length
> NFS4_FHSIZE
);
229 p
= xdr_reserve_space(xdr
, 4 + length
);
230 xdr_encode_opaque(p
, &fh
->fh_base
, length
);
241 static void encode_stateid4(struct xdr_stream
*xdr
, const stateid_t
*sid
)
245 p
= xdr_reserve_space(xdr
, NFS4_STATEID_SIZE
);
246 *p
++ = cpu_to_be32(sid
->si_generation
);
247 xdr_encode_opaque_fixed(p
, &sid
->si_opaque
, NFS4_STATEID_OTHER_SIZE
);
253 * typedef opaque sessionid4[NFS4_SESSIONID_SIZE];
255 static void encode_sessionid4(struct xdr_stream
*xdr
,
256 const struct nfsd4_session
*session
)
260 p
= xdr_reserve_space(xdr
, NFS4_MAX_SESSIONID_LEN
);
261 xdr_encode_opaque_fixed(p
, session
->se_sessionid
.data
,
262 NFS4_MAX_SESSIONID_LEN
);
268 * struct CB_COMPOUND4args {
270 * uint32_t minorversion;
271 * uint32_t callback_ident;
272 * nfs_cb_argop4 argarray<>;
275 static void encode_cb_compound4args(struct xdr_stream
*xdr
,
276 struct nfs4_cb_compound_hdr
*hdr
)
280 p
= xdr_reserve_space(xdr
, 4 + 4 + 4 + 4);
281 p
= xdr_encode_empty_array(p
); /* empty tag */
282 *p
++ = cpu_to_be32(hdr
->minorversion
);
283 *p
++ = cpu_to_be32(hdr
->ident
);
286 *p
= cpu_to_be32(hdr
->nops
); /* argarray element count */
290 * Update argarray element count
292 static void encode_cb_nops(struct nfs4_cb_compound_hdr
*hdr
)
294 BUG_ON(hdr
->nops
> NFS4_MAX_BACK_CHANNEL_OPS
);
295 *hdr
->nops_p
= cpu_to_be32(hdr
->nops
);
301 * struct CB_RECALL4args {
307 static void encode_cb_recall4args(struct xdr_stream
*xdr
,
308 const struct nfs4_delegation
*dp
,
309 struct nfs4_cb_compound_hdr
*hdr
)
313 encode_nfs_cb_opnum4(xdr
, OP_CB_RECALL
);
314 encode_stateid4(xdr
, &dp
->dl_stateid
);
316 p
= xdr_reserve_space(xdr
, 4);
317 *p
++ = xdr_zero
; /* truncate */
319 encode_nfs_fh4(xdr
, &dp
->dl_fh
);
327 * struct CB_SEQUENCE4args {
328 * sessionid4 csa_sessionid;
329 * sequenceid4 csa_sequenceid;
330 * slotid4 csa_slotid;
331 * slotid4 csa_highest_slotid;
332 * bool csa_cachethis;
333 * referring_call_list4 csa_referring_call_lists<>;
336 static void encode_cb_sequence4args(struct xdr_stream
*xdr
,
337 const struct nfsd4_callback
*cb
,
338 struct nfs4_cb_compound_hdr
*hdr
)
340 struct nfsd4_session
*session
= cb
->cb_clp
->cl_cb_session
;
343 if (hdr
->minorversion
== 0)
346 encode_nfs_cb_opnum4(xdr
, OP_CB_SEQUENCE
);
347 encode_sessionid4(xdr
, session
);
349 p
= xdr_reserve_space(xdr
, 4 + 4 + 4 + 4 + 4);
350 *p
++ = cpu_to_be32(session
->se_cb_seq_nr
); /* csa_sequenceid */
351 *p
++ = xdr_zero
; /* csa_slotid */
352 *p
++ = xdr_zero
; /* csa_highest_slotid */
353 *p
++ = xdr_zero
; /* csa_cachethis */
354 xdr_encode_empty_array(p
); /* csa_referring_call_lists */
360 * NFSv4.0 and NFSv4.1 XDR encode functions
362 * NFSv4.0 callback argument types are defined in section 15 of RFC
363 * 3530: "Network File System (NFS) version 4 Protocol" and section 20
364 * of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1
369 * NB: Without this zero space reservation, callbacks over krb5p fail
371 static int nfs4_xdr_enc_cb_null(struct rpc_rqst
*req
, __be32
*p
, void *__unused
)
373 struct xdr_stream xdrs
, *xdr
= &xdrs
;
375 xdr_init_encode(&xdrs
, &req
->rq_snd_buf
, p
);
376 xdr_reserve_space(xdr
, 0);
381 * 20.2. Operation 4: CB_RECALL - Recall a Delegation
383 static int nfs4_xdr_enc_cb_recall(struct rpc_rqst
*req
, __be32
*p
,
384 const struct nfsd4_callback
*cb
)
386 struct xdr_stream xdr
;
387 const struct nfs4_delegation
*args
= cb
->cb_op
;
388 struct nfs4_cb_compound_hdr hdr
= {
389 .ident
= cb
->cb_clp
->cl_cb_ident
,
390 .minorversion
= cb
->cb_minorversion
,
393 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
394 encode_cb_compound4args(&xdr
, &hdr
);
395 encode_cb_sequence4args(&xdr
, cb
, &hdr
);
396 encode_cb_recall4args(&xdr
, args
, &hdr
);
397 encode_cb_nops(&hdr
);
403 decode_cb_compound_hdr(struct xdr_stream
*xdr
, struct nfs4_cb_compound_hdr
*hdr
){
409 /* We've got no use for the tag; ignore it: */
411 READ_BUF(taglen
+ 4);
412 p
+= XDR_QUADLEN(taglen
);
418 decode_cb_op_hdr(struct xdr_stream
*xdr
, enum nfs_opnum4 expected
)
426 if (op
!= expected
) {
427 dprintk("NFSD: decode_cb_op_hdr: Callback server returned "
428 " operation %d but we issued a request for %d\n",
433 if (nfserr
!= NFS_OK
)
434 return -nfs_cb_stat_to_errno(nfserr
);
439 * Our current back channel implmentation supports a single backchannel
440 * with a single slot.
443 decode_cb_sequence(struct xdr_stream
*xdr
, struct nfsd4_callback
*cb
,
444 struct rpc_rqst
*rqstp
)
446 struct nfsd4_session
*ses
= cb
->cb_clp
->cl_cb_session
;
447 struct nfs4_sessionid id
;
452 if (cb
->cb_minorversion
== 0)
455 status
= decode_cb_op_hdr(xdr
, OP_CB_SEQUENCE
);
460 * If the server returns different values for sessionID, slotID or
461 * sequence number, the server is looney tunes.
463 status
= -ESERVERFAULT
;
465 READ_BUF(NFS4_MAX_SESSIONID_LEN
+ 16);
466 memcpy(id
.data
, p
, NFS4_MAX_SESSIONID_LEN
);
467 p
+= XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN
);
468 if (memcmp(id
.data
, ses
->se_sessionid
.data
, NFS4_MAX_SESSIONID_LEN
)) {
469 dprintk("%s Invalid session id\n", __func__
);
473 if (dummy
!= ses
->se_cb_seq_nr
) {
474 dprintk("%s Invalid sequence number\n", __func__
);
477 READ32(dummy
); /* slotid must be 0 */
479 dprintk("%s Invalid slotid\n", __func__
);
482 /* FIXME: process highest slotid and target highest slotid */
490 nfs4_xdr_dec_cb_null(struct rpc_rqst
*req
, __be32
*p
)
496 nfs4_xdr_dec_cb_recall(struct rpc_rqst
*rqstp
, __be32
*p
,
497 struct nfsd4_callback
*cb
)
499 struct xdr_stream xdr
;
500 struct nfs4_cb_compound_hdr hdr
;
503 xdr_init_decode(&xdr
, &rqstp
->rq_rcv_buf
, p
);
504 status
= decode_cb_compound_hdr(&xdr
, &hdr
);
508 status
= decode_cb_sequence(&xdr
, cb
, rqstp
);
512 status
= decode_cb_op_hdr(&xdr
, OP_CB_RECALL
);
518 * RPC procedure tables
520 #define PROC(proc, call, argtype, restype) \
521 [NFSPROC4_CLNT_##proc] = { \
522 .p_proc = NFSPROC4_CB_##call, \
523 .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
524 .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
525 .p_arglen = NFS4_##argtype##_sz, \
526 .p_replen = NFS4_##restype##_sz, \
527 .p_statidx = NFSPROC4_CB_##call, \
531 static struct rpc_procinfo nfs4_cb_procedures
[] = {
532 PROC(CB_NULL
, NULL
, enc_cb_null
, dec_cb_null
),
533 PROC(CB_RECALL
, COMPOUND
, enc_cb_recall
, dec_cb_recall
),
536 static struct rpc_version nfs_cb_version4
= {
538 * Note on the callback rpc program version number: despite language in rfc
539 * 5661 section 18.36.3 requiring servers to use 4 in this field, the
540 * official xdr descriptions for both 4.0 and 4.1 specify version 1, and
541 * in practice that appears to be what implementations use. The section
542 * 18.36.3 language is expected to be fixed in an erratum.
545 .nrprocs
= ARRAY_SIZE(nfs4_cb_procedures
),
546 .procs
= nfs4_cb_procedures
549 static struct rpc_version
* nfs_cb_version
[] = {
553 static struct rpc_program cb_program
;
555 static struct rpc_stat cb_stats
= {
556 .program
= &cb_program
559 #define NFS4_CALLBACK 0x40000000
560 static struct rpc_program cb_program
= {
562 .number
= NFS4_CALLBACK
,
563 .nrvers
= ARRAY_SIZE(nfs_cb_version
),
564 .version
= nfs_cb_version
,
566 .pipe_dir_name
= "/nfsd4_cb",
569 static int max_cb_time(void)
571 return max(nfsd4_lease
/10, (time_t)1) * HZ
;
574 /* Reference counting, callback cleanup, etc., all look racy as heck.
575 * And why is cl_cb_set an atomic? */
577 int setup_callback_client(struct nfs4_client
*clp
, struct nfs4_cb_conn
*conn
)
579 struct rpc_timeout timeparms
= {
580 .to_initval
= max_cb_time(),
583 struct rpc_create_args args
= {
585 .address
= (struct sockaddr
*) &conn
->cb_addr
,
586 .addrsize
= conn
->cb_addrlen
,
587 .timeout
= &timeparms
,
588 .program
= &cb_program
,
590 .authflavor
= clp
->cl_flavor
,
591 .flags
= (RPC_CLNT_CREATE_NOPING
| RPC_CLNT_CREATE_QUIET
),
593 struct rpc_clnt
*client
;
595 if (clp
->cl_minorversion
== 0) {
596 if (!clp
->cl_principal
&& (clp
->cl_flavor
>= RPC_AUTH_GSS_KRB5
))
598 args
.client_name
= clp
->cl_principal
;
599 args
.prognumber
= conn
->cb_prog
,
600 args
.protocol
= XPRT_TRANSPORT_TCP
;
601 clp
->cl_cb_ident
= conn
->cb_ident
;
603 args
.bc_xprt
= conn
->cb_xprt
;
604 args
.prognumber
= clp
->cl_cb_session
->se_cb_prog
;
605 args
.protocol
= XPRT_TRANSPORT_BC_TCP
;
607 /* Create RPC client */
608 client
= rpc_create(&args
);
609 if (IS_ERR(client
)) {
610 dprintk("NFSD: couldn't create callback client: %ld\n",
612 return PTR_ERR(client
);
614 clp
->cl_cb_client
= client
;
619 static void warn_no_callback_path(struct nfs4_client
*clp
, int reason
)
621 dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
622 (int)clp
->cl_name
.len
, clp
->cl_name
.data
, reason
);
625 static void nfsd4_cb_probe_done(struct rpc_task
*task
, void *calldata
)
627 struct nfs4_client
*clp
= container_of(calldata
, struct nfs4_client
, cl_cb_null
);
630 warn_no_callback_path(clp
, task
->tk_status
);
632 atomic_set(&clp
->cl_cb_set
, 1);
635 static const struct rpc_call_ops nfsd4_cb_probe_ops
= {
636 /* XXX: release method to ensure we set the cb channel down if
637 * necessary on early failure? */
638 .rpc_call_done
= nfsd4_cb_probe_done
,
641 static struct rpc_cred
*callback_cred
;
643 int set_callback_cred(void)
647 callback_cred
= rpc_lookup_machine_cred();
653 static struct workqueue_struct
*callback_wq
;
655 static void do_probe_callback(struct nfs4_client
*clp
)
657 struct nfsd4_callback
*cb
= &clp
->cl_cb_null
;
662 cb
->cb_msg
.rpc_proc
= &nfs4_cb_procedures
[NFSPROC4_CLNT_CB_NULL
];
663 cb
->cb_msg
.rpc_argp
= NULL
;
664 cb
->cb_msg
.rpc_resp
= NULL
;
665 cb
->cb_msg
.rpc_cred
= callback_cred
;
667 cb
->cb_ops
= &nfsd4_cb_probe_ops
;
669 queue_work(callback_wq
, &cb
->cb_work
);
673 * Poke the callback thread to process any updates to the callback
674 * parameters, and send a null probe.
676 void nfsd4_probe_callback(struct nfs4_client
*clp
)
678 set_bit(NFSD4_CLIENT_CB_UPDATE
, &clp
->cl_cb_flags
);
679 do_probe_callback(clp
);
682 void nfsd4_change_callback(struct nfs4_client
*clp
, struct nfs4_cb_conn
*conn
)
684 BUG_ON(atomic_read(&clp
->cl_cb_set
));
686 spin_lock(&clp
->cl_lock
);
687 memcpy(&clp
->cl_cb_conn
, conn
, sizeof(struct nfs4_cb_conn
));
688 spin_unlock(&clp
->cl_lock
);
692 * There's currently a single callback channel slot.
693 * If the slot is available, then mark it busy. Otherwise, set the
694 * thread for sleeping on the callback RPC wait queue.
696 static int nfsd41_cb_setup_sequence(struct nfs4_client
*clp
,
697 struct rpc_task
*task
)
699 u32
*ptr
= (u32
*)clp
->cl_cb_session
->se_sessionid
.data
;
702 dprintk("%s: %u:%u:%u:%u\n", __func__
,
703 ptr
[0], ptr
[1], ptr
[2], ptr
[3]);
705 if (test_and_set_bit(0, &clp
->cl_cb_slot_busy
) != 0) {
706 rpc_sleep_on(&clp
->cl_cb_waitq
, task
, NULL
);
707 dprintk("%s slot is busy\n", __func__
);
712 dprintk("%s status=%d\n", __func__
, status
);
717 * TODO: cb_sequence should support referring call lists, cachethis, multiple
718 * slots, and mark callback channel down on communication errors.
720 static void nfsd4_cb_prepare(struct rpc_task
*task
, void *calldata
)
722 struct nfsd4_callback
*cb
= calldata
;
723 struct nfs4_delegation
*dp
= container_of(cb
, struct nfs4_delegation
, dl_recall
);
724 struct nfs4_client
*clp
= dp
->dl_client
;
725 u32 minorversion
= clp
->cl_minorversion
;
728 cb
->cb_minorversion
= minorversion
;
730 status
= nfsd41_cb_setup_sequence(clp
, task
);
732 if (status
!= -EAGAIN
) {
733 /* terminate rpc task */
734 task
->tk_status
= status
;
735 task
->tk_action
= NULL
;
740 rpc_call_start(task
);
743 static void nfsd4_cb_done(struct rpc_task
*task
, void *calldata
)
745 struct nfsd4_callback
*cb
= calldata
;
746 struct nfs4_delegation
*dp
= container_of(cb
, struct nfs4_delegation
, dl_recall
);
747 struct nfs4_client
*clp
= dp
->dl_client
;
749 dprintk("%s: minorversion=%d\n", __func__
,
750 clp
->cl_minorversion
);
752 if (clp
->cl_minorversion
) {
753 /* No need for lock, access serialized in nfsd4_cb_prepare */
754 ++clp
->cl_cb_session
->se_cb_seq_nr
;
755 clear_bit(0, &clp
->cl_cb_slot_busy
);
756 rpc_wake_up_next(&clp
->cl_cb_waitq
);
757 dprintk("%s: freed slot, new seqid=%d\n", __func__
,
758 clp
->cl_cb_session
->se_cb_seq_nr
);
760 /* We're done looking into the sequence information */
761 task
->tk_msg
.rpc_resp
= NULL
;
766 static void nfsd4_cb_recall_done(struct rpc_task
*task
, void *calldata
)
768 struct nfsd4_callback
*cb
= calldata
;
769 struct nfs4_delegation
*dp
= container_of(cb
, struct nfs4_delegation
, dl_recall
);
770 struct nfs4_client
*clp
= dp
->dl_client
;
771 struct rpc_clnt
*current_rpc_client
= clp
->cl_cb_client
;
773 nfsd4_cb_done(task
, calldata
);
775 if (current_rpc_client
== NULL
) {
776 /* We're shutting down; give up. */
777 /* XXX: err, or is it ok just to fall through
778 * and rpc_restart_call? */
782 switch (task
->tk_status
) {
786 case -NFS4ERR_BAD_STATEID
:
787 /* Race: client probably got cb_recall
788 * before open reply granting delegation */
791 /* Network partition? */
792 atomic_set(&clp
->cl_cb_set
, 0);
793 warn_no_callback_path(clp
, task
->tk_status
);
794 if (current_rpc_client
!= task
->tk_client
) {
795 /* queue a callback on the new connection: */
796 atomic_inc(&dp
->dl_count
);
801 if (dp
->dl_retries
--) {
802 rpc_delay(task
, 2*HZ
);
804 rpc_restart_call_prepare(task
);
807 atomic_set(&clp
->cl_cb_set
, 0);
808 warn_no_callback_path(clp
, task
->tk_status
);
812 static void nfsd4_cb_recall_release(void *calldata
)
814 struct nfsd4_callback
*cb
= calldata
;
815 struct nfs4_delegation
*dp
= container_of(cb
, struct nfs4_delegation
, dl_recall
);
817 nfs4_put_delegation(dp
);
820 static const struct rpc_call_ops nfsd4_cb_recall_ops
= {
821 .rpc_call_prepare
= nfsd4_cb_prepare
,
822 .rpc_call_done
= nfsd4_cb_recall_done
,
823 .rpc_release
= nfsd4_cb_recall_release
,
826 int nfsd4_create_callback_queue(void)
828 callback_wq
= create_singlethread_workqueue("nfsd4_callbacks");
834 void nfsd4_destroy_callback_queue(void)
836 destroy_workqueue(callback_wq
);
839 /* must be called under the state lock */
840 void nfsd4_shutdown_callback(struct nfs4_client
*clp
)
842 set_bit(NFSD4_CLIENT_KILL
, &clp
->cl_cb_flags
);
844 * Note this won't actually result in a null callback;
845 * instead, nfsd4_do_callback_rpc() will detect the killed
846 * client, destroy the rpc client, and stop:
848 do_probe_callback(clp
);
849 flush_workqueue(callback_wq
);
852 void nfsd4_release_cb(struct nfsd4_callback
*cb
)
854 if (cb
->cb_ops
->rpc_release
)
855 cb
->cb_ops
->rpc_release(cb
);
858 void nfsd4_process_cb_update(struct nfsd4_callback
*cb
)
860 struct nfs4_cb_conn conn
;
861 struct nfs4_client
*clp
= cb
->cb_clp
;
865 * This is either an update, or the client dying; in either case,
866 * kill the old client:
868 if (clp
->cl_cb_client
) {
869 rpc_shutdown_client(clp
->cl_cb_client
);
870 clp
->cl_cb_client
= NULL
;
872 if (test_bit(NFSD4_CLIENT_KILL
, &clp
->cl_cb_flags
))
874 spin_lock(&clp
->cl_lock
);
876 * Only serialized callback code is allowed to clear these
877 * flags; main nfsd code can only set them:
879 BUG_ON(!clp
->cl_cb_flags
);
880 clear_bit(NFSD4_CLIENT_CB_UPDATE
, &clp
->cl_cb_flags
);
881 memcpy(&conn
, &cb
->cb_clp
->cl_cb_conn
, sizeof(struct nfs4_cb_conn
));
882 spin_unlock(&clp
->cl_lock
);
884 err
= setup_callback_client(clp
, &conn
);
886 warn_no_callback_path(clp
, err
);
889 void nfsd4_do_callback_rpc(struct work_struct
*w
)
891 struct nfsd4_callback
*cb
= container_of(w
, struct nfsd4_callback
, cb_work
);
892 struct nfs4_client
*clp
= cb
->cb_clp
;
893 struct rpc_clnt
*clnt
;
895 if (clp
->cl_cb_flags
)
896 nfsd4_process_cb_update(cb
);
898 clnt
= clp
->cl_cb_client
;
900 /* Callback channel broken, or client killed; give up: */
901 nfsd4_release_cb(cb
);
904 rpc_call_async(clnt
, &cb
->cb_msg
, RPC_TASK_SOFT
| RPC_TASK_SOFTCONN
,
908 void nfsd4_cb_recall(struct nfs4_delegation
*dp
)
910 struct nfsd4_callback
*cb
= &dp
->dl_recall
;
914 cb
->cb_clp
= dp
->dl_client
;
915 cb
->cb_msg
.rpc_proc
= &nfs4_cb_procedures
[NFSPROC4_CLNT_CB_RECALL
];
916 cb
->cb_msg
.rpc_argp
= cb
;
917 cb
->cb_msg
.rpc_resp
= cb
;
918 cb
->cb_msg
.rpc_cred
= callback_cred
;
920 cb
->cb_ops
= &nfsd4_cb_recall_ops
;
923 queue_work(callback_wq
, &dp
->dl_recall
.cb_work
);