0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/sunrpc/clnt.h>
0035 #include <linux/sunrpc/xprt.h>
0036 #include <linux/sunrpc/svc_xprt.h>
0037 #include <linux/slab.h>
0038 #include "nfsd.h"
0039 #include "state.h"
0040 #include "netns.h"
0041 #include "trace.h"
0042 #include "xdr4cb.h"
0043 #include "xdr4.h"
0044
0045 #define NFSDDBG_FACILITY NFSDDBG_PROC
0046
0047 static void nfsd4_mark_cb_fault(struct nfs4_client *, int reason);
0048
0049 #define NFSPROC4_CB_NULL 0
0050 #define NFSPROC4_CB_COMPOUND 1
0051
0052
0053
0054 struct nfs4_cb_compound_hdr {
0055
0056 u32 ident;
0057 u32 nops;
0058 __be32 *nops_p;
0059 u32 minorversion;
0060
0061 int status;
0062 };
0063
0064 static __be32 *xdr_encode_empty_array(__be32 *p)
0065 {
0066 *p++ = xdr_zero;
0067 return p;
0068 }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 enum nfs_cb_opnum4 {
0088 OP_CB_GETATTR = 3,
0089 OP_CB_RECALL = 4,
0090 OP_CB_LAYOUTRECALL = 5,
0091 OP_CB_NOTIFY = 6,
0092 OP_CB_PUSH_DELEG = 7,
0093 OP_CB_RECALL_ANY = 8,
0094 OP_CB_RECALLABLE_OBJ_AVAIL = 9,
0095 OP_CB_RECALL_SLOT = 10,
0096 OP_CB_SEQUENCE = 11,
0097 OP_CB_WANTS_CANCELLED = 12,
0098 OP_CB_NOTIFY_LOCK = 13,
0099 OP_CB_NOTIFY_DEVICEID = 14,
0100 OP_CB_OFFLOAD = 15,
0101 OP_CB_ILLEGAL = 10044
0102 };
0103
0104 static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op)
0105 {
0106 __be32 *p;
0107
0108 p = xdr_reserve_space(xdr, 4);
0109 *p = cpu_to_be32(op);
0110 }
0111
0112
0113
0114
0115
0116
0117 static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh)
0118 {
0119 u32 length = fh->fh_size;
0120 __be32 *p;
0121
0122 BUG_ON(length > NFS4_FHSIZE);
0123 p = xdr_reserve_space(xdr, 4 + length);
0124 xdr_encode_opaque(p, &fh->fh_raw, length);
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static void encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid)
0136 {
0137 __be32 *p;
0138
0139 p = xdr_reserve_space(xdr, NFS4_STATEID_SIZE);
0140 *p++ = cpu_to_be32(sid->si_generation);
0141 xdr_encode_opaque_fixed(p, &sid->si_opaque, NFS4_STATEID_OTHER_SIZE);
0142 }
0143
0144
0145
0146
0147
0148
0149 static void encode_sessionid4(struct xdr_stream *xdr,
0150 const struct nfsd4_session *session)
0151 {
0152 __be32 *p;
0153
0154 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN);
0155 xdr_encode_opaque_fixed(p, session->se_sessionid.data,
0156 NFS4_MAX_SESSIONID_LEN);
0157 }
0158
0159
0160
0161
0162 static const struct {
0163 int stat;
0164 int errno;
0165 } nfs_cb_errtbl[] = {
0166 { NFS4_OK, 0 },
0167 { NFS4ERR_PERM, -EPERM },
0168 { NFS4ERR_NOENT, -ENOENT },
0169 { NFS4ERR_IO, -EIO },
0170 { NFS4ERR_NXIO, -ENXIO },
0171 { NFS4ERR_ACCESS, -EACCES },
0172 { NFS4ERR_EXIST, -EEXIST },
0173 { NFS4ERR_XDEV, -EXDEV },
0174 { NFS4ERR_NOTDIR, -ENOTDIR },
0175 { NFS4ERR_ISDIR, -EISDIR },
0176 { NFS4ERR_INVAL, -EINVAL },
0177 { NFS4ERR_FBIG, -EFBIG },
0178 { NFS4ERR_NOSPC, -ENOSPC },
0179 { NFS4ERR_ROFS, -EROFS },
0180 { NFS4ERR_MLINK, -EMLINK },
0181 { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG },
0182 { NFS4ERR_NOTEMPTY, -ENOTEMPTY },
0183 { NFS4ERR_DQUOT, -EDQUOT },
0184 { NFS4ERR_STALE, -ESTALE },
0185 { NFS4ERR_BADHANDLE, -EBADHANDLE },
0186 { NFS4ERR_BAD_COOKIE, -EBADCOOKIE },
0187 { NFS4ERR_NOTSUPP, -ENOTSUPP },
0188 { NFS4ERR_TOOSMALL, -ETOOSMALL },
0189 { NFS4ERR_SERVERFAULT, -ESERVERFAULT },
0190 { NFS4ERR_BADTYPE, -EBADTYPE },
0191 { NFS4ERR_LOCKED, -EAGAIN },
0192 { NFS4ERR_RESOURCE, -EREMOTEIO },
0193 { NFS4ERR_SYMLINK, -ELOOP },
0194 { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
0195 { NFS4ERR_DEADLOCK, -EDEADLK },
0196 { -1, -EIO }
0197 };
0198
0199
0200
0201
0202
0203
0204
0205
0206 static int nfs_cb_stat_to_errno(int status)
0207 {
0208 int i;
0209
0210 for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) {
0211 if (nfs_cb_errtbl[i].stat == status)
0212 return nfs_cb_errtbl[i].errno;
0213 }
0214
0215 dprintk("NFSD: Unrecognized NFS CB status value: %u\n", status);
0216 return -status;
0217 }
0218
0219 static int decode_cb_op_status(struct xdr_stream *xdr,
0220 enum nfs_cb_opnum4 expected, int *status)
0221 {
0222 __be32 *p;
0223 u32 op;
0224
0225 p = xdr_inline_decode(xdr, 4 + 4);
0226 if (unlikely(p == NULL))
0227 goto out_overflow;
0228 op = be32_to_cpup(p++);
0229 if (unlikely(op != expected))
0230 goto out_unexpected;
0231 *status = nfs_cb_stat_to_errno(be32_to_cpup(p));
0232 return 0;
0233 out_overflow:
0234 return -EIO;
0235 out_unexpected:
0236 dprintk("NFSD: Callback server returned operation %d but "
0237 "we issued a request for %d\n", op, expected);
0238 return -EIO;
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 static void encode_cb_compound4args(struct xdr_stream *xdr,
0252 struct nfs4_cb_compound_hdr *hdr)
0253 {
0254 __be32 * p;
0255
0256 p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
0257 p = xdr_encode_empty_array(p);
0258 *p++ = cpu_to_be32(hdr->minorversion);
0259 *p++ = cpu_to_be32(hdr->ident);
0260
0261 hdr->nops_p = p;
0262 *p = cpu_to_be32(hdr->nops);
0263 }
0264
0265
0266
0267
0268 static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr)
0269 {
0270 BUG_ON(hdr->nops > NFS4_MAX_BACK_CHANNEL_OPS);
0271 *hdr->nops_p = cpu_to_be32(hdr->nops);
0272 }
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 static int decode_cb_compound4res(struct xdr_stream *xdr,
0284 struct nfs4_cb_compound_hdr *hdr)
0285 {
0286 u32 length;
0287 __be32 *p;
0288
0289 p = xdr_inline_decode(xdr, 4 + 4);
0290 if (unlikely(p == NULL))
0291 goto out_overflow;
0292 hdr->status = be32_to_cpup(p++);
0293
0294 length = be32_to_cpup(p++);
0295 p = xdr_inline_decode(xdr, length + 4);
0296 if (unlikely(p == NULL))
0297 goto out_overflow;
0298 p += XDR_QUADLEN(length);
0299 hdr->nops = be32_to_cpup(p);
0300 return 0;
0301 out_overflow:
0302 return -EIO;
0303 }
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 static void encode_cb_recall4args(struct xdr_stream *xdr,
0315 const struct nfs4_delegation *dp,
0316 struct nfs4_cb_compound_hdr *hdr)
0317 {
0318 __be32 *p;
0319
0320 encode_nfs_cb_opnum4(xdr, OP_CB_RECALL);
0321 encode_stateid4(xdr, &dp->dl_stid.sc_stateid);
0322
0323 p = xdr_reserve_space(xdr, 4);
0324 *p++ = xdr_zero;
0325
0326 encode_nfs_fh4(xdr, &dp->dl_stid.sc_file->fi_fhandle);
0327
0328 hdr->nops++;
0329 }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 static void encode_cb_sequence4args(struct xdr_stream *xdr,
0344 const struct nfsd4_callback *cb,
0345 struct nfs4_cb_compound_hdr *hdr)
0346 {
0347 struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
0348 __be32 *p;
0349
0350 if (hdr->minorversion == 0)
0351 return;
0352
0353 encode_nfs_cb_opnum4(xdr, OP_CB_SEQUENCE);
0354 encode_sessionid4(xdr, session);
0355
0356 p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4 + 4);
0357 *p++ = cpu_to_be32(session->se_cb_seq_nr);
0358 *p++ = xdr_zero;
0359 *p++ = xdr_zero;
0360 *p++ = xdr_zero;
0361 xdr_encode_empty_array(p);
0362
0363 hdr->nops++;
0364 }
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387 static int decode_cb_sequence4resok(struct xdr_stream *xdr,
0388 struct nfsd4_callback *cb)
0389 {
0390 struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
0391 int status = -ESERVERFAULT;
0392 __be32 *p;
0393 u32 dummy;
0394
0395
0396
0397
0398
0399 p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN + 4 + 4 + 4 + 4);
0400 if (unlikely(p == NULL))
0401 goto out_overflow;
0402
0403 if (memcmp(p, session->se_sessionid.data, NFS4_MAX_SESSIONID_LEN)) {
0404 dprintk("NFS: %s Invalid session id\n", __func__);
0405 goto out;
0406 }
0407 p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN);
0408
0409 dummy = be32_to_cpup(p++);
0410 if (dummy != session->se_cb_seq_nr) {
0411 dprintk("NFS: %s Invalid sequence number\n", __func__);
0412 goto out;
0413 }
0414
0415 dummy = be32_to_cpup(p++);
0416 if (dummy != 0) {
0417 dprintk("NFS: %s Invalid slotid\n", __func__);
0418 goto out;
0419 }
0420
0421
0422
0423
0424 status = 0;
0425 out:
0426 cb->cb_seq_status = status;
0427 return status;
0428 out_overflow:
0429 status = -EIO;
0430 goto out;
0431 }
0432
0433 static int decode_cb_sequence4res(struct xdr_stream *xdr,
0434 struct nfsd4_callback *cb)
0435 {
0436 int status;
0437
0438 if (cb->cb_clp->cl_minorversion == 0)
0439 return 0;
0440
0441 status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &cb->cb_seq_status);
0442 if (unlikely(status || cb->cb_seq_status))
0443 return status;
0444
0445 return decode_cb_sequence4resok(xdr, cb);
0446 }
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460 static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
0461 const void *__unused)
0462 {
0463 xdr_reserve_space(xdr, 0);
0464 }
0465
0466
0467
0468
0469 static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr,
0470 const void *data)
0471 {
0472 const struct nfsd4_callback *cb = data;
0473 const struct nfs4_delegation *dp = cb_to_delegation(cb);
0474 struct nfs4_cb_compound_hdr hdr = {
0475 .ident = cb->cb_clp->cl_cb_ident,
0476 .minorversion = cb->cb_clp->cl_minorversion,
0477 };
0478
0479 encode_cb_compound4args(xdr, &hdr);
0480 encode_cb_sequence4args(xdr, cb, &hdr);
0481 encode_cb_recall4args(xdr, dp, &hdr);
0482 encode_cb_nops(&hdr);
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
0496 void *__unused)
0497 {
0498 return 0;
0499 }
0500
0501
0502
0503
0504 static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
0505 struct xdr_stream *xdr,
0506 void *data)
0507 {
0508 struct nfsd4_callback *cb = data;
0509 struct nfs4_cb_compound_hdr hdr;
0510 int status;
0511
0512 status = decode_cb_compound4res(xdr, &hdr);
0513 if (unlikely(status))
0514 return status;
0515
0516 status = decode_cb_sequence4res(xdr, cb);
0517 if (unlikely(status || cb->cb_seq_status))
0518 return status;
0519
0520 return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status);
0521 }
0522
0523 #ifdef CONFIG_NFSD_PNFS
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550 static void encode_cb_layout4args(struct xdr_stream *xdr,
0551 const struct nfs4_layout_stateid *ls,
0552 struct nfs4_cb_compound_hdr *hdr)
0553 {
0554 __be32 *p;
0555
0556 BUG_ON(hdr->minorversion == 0);
0557
0558 p = xdr_reserve_space(xdr, 5 * 4);
0559 *p++ = cpu_to_be32(OP_CB_LAYOUTRECALL);
0560 *p++ = cpu_to_be32(ls->ls_layout_type);
0561 *p++ = cpu_to_be32(IOMODE_ANY);
0562 *p++ = cpu_to_be32(1);
0563 *p = cpu_to_be32(RETURN_FILE);
0564
0565 encode_nfs_fh4(xdr, &ls->ls_stid.sc_file->fi_fhandle);
0566
0567 p = xdr_reserve_space(xdr, 2 * 8);
0568 p = xdr_encode_hyper(p, 0);
0569 xdr_encode_hyper(p, NFS4_MAX_UINT64);
0570
0571 encode_stateid4(xdr, &ls->ls_recall_sid);
0572
0573 hdr->nops++;
0574 }
0575
0576 static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req,
0577 struct xdr_stream *xdr,
0578 const void *data)
0579 {
0580 const struct nfsd4_callback *cb = data;
0581 const struct nfs4_layout_stateid *ls =
0582 container_of(cb, struct nfs4_layout_stateid, ls_recall);
0583 struct nfs4_cb_compound_hdr hdr = {
0584 .ident = 0,
0585 .minorversion = cb->cb_clp->cl_minorversion,
0586 };
0587
0588 encode_cb_compound4args(xdr, &hdr);
0589 encode_cb_sequence4args(xdr, cb, &hdr);
0590 encode_cb_layout4args(xdr, ls, &hdr);
0591 encode_cb_nops(&hdr);
0592 }
0593
0594 static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp,
0595 struct xdr_stream *xdr,
0596 void *data)
0597 {
0598 struct nfsd4_callback *cb = data;
0599 struct nfs4_cb_compound_hdr hdr;
0600 int status;
0601
0602 status = decode_cb_compound4res(xdr, &hdr);
0603 if (unlikely(status))
0604 return status;
0605
0606 status = decode_cb_sequence4res(xdr, cb);
0607 if (unlikely(status || cb->cb_seq_status))
0608 return status;
0609
0610 return decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &cb->cb_status);
0611 }
0612 #endif
0613
0614 static void encode_stateowner(struct xdr_stream *xdr, struct nfs4_stateowner *so)
0615 {
0616 __be32 *p;
0617
0618 p = xdr_reserve_space(xdr, 8 + 4 + so->so_owner.len);
0619 p = xdr_encode_opaque_fixed(p, &so->so_client->cl_clientid, 8);
0620 xdr_encode_opaque(p, so->so_owner.data, so->so_owner.len);
0621 }
0622
0623 static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req,
0624 struct xdr_stream *xdr,
0625 const void *data)
0626 {
0627 const struct nfsd4_callback *cb = data;
0628 const struct nfsd4_blocked_lock *nbl =
0629 container_of(cb, struct nfsd4_blocked_lock, nbl_cb);
0630 struct nfs4_lockowner *lo = (struct nfs4_lockowner *)nbl->nbl_lock.fl_owner;
0631 struct nfs4_cb_compound_hdr hdr = {
0632 .ident = 0,
0633 .minorversion = cb->cb_clp->cl_minorversion,
0634 };
0635
0636 __be32 *p;
0637
0638 BUG_ON(hdr.minorversion == 0);
0639
0640 encode_cb_compound4args(xdr, &hdr);
0641 encode_cb_sequence4args(xdr, cb, &hdr);
0642
0643 p = xdr_reserve_space(xdr, 4);
0644 *p = cpu_to_be32(OP_CB_NOTIFY_LOCK);
0645 encode_nfs_fh4(xdr, &nbl->nbl_fh);
0646 encode_stateowner(xdr, &lo->lo_owner);
0647 hdr.nops++;
0648
0649 encode_cb_nops(&hdr);
0650 }
0651
0652 static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp,
0653 struct xdr_stream *xdr,
0654 void *data)
0655 {
0656 struct nfsd4_callback *cb = data;
0657 struct nfs4_cb_compound_hdr hdr;
0658 int status;
0659
0660 status = decode_cb_compound4res(xdr, &hdr);
0661 if (unlikely(status))
0662 return status;
0663
0664 status = decode_cb_sequence4res(xdr, cb);
0665 if (unlikely(status || cb->cb_seq_status))
0666 return status;
0667
0668 return decode_cb_op_status(xdr, OP_CB_NOTIFY_LOCK, &cb->cb_status);
0669 }
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690 static void encode_offload_info4(struct xdr_stream *xdr,
0691 const struct nfsd4_cb_offload *cbo)
0692 {
0693 __be32 *p;
0694
0695 p = xdr_reserve_space(xdr, 4);
0696 *p = cbo->co_nfserr;
0697 switch (cbo->co_nfserr) {
0698 case nfs_ok:
0699 p = xdr_reserve_space(xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE);
0700 p = xdr_encode_empty_array(p);
0701 p = xdr_encode_hyper(p, cbo->co_res.wr_bytes_written);
0702 *p++ = cpu_to_be32(cbo->co_res.wr_stable_how);
0703 p = xdr_encode_opaque_fixed(p, cbo->co_res.wr_verifier.data,
0704 NFS4_VERIFIER_SIZE);
0705 break;
0706 default:
0707 p = xdr_reserve_space(xdr, 8);
0708
0709 p = xdr_encode_hyper(p, 0);
0710 }
0711 }
0712
0713 static void encode_cb_offload4args(struct xdr_stream *xdr,
0714 const struct nfsd4_cb_offload *cbo,
0715 struct nfs4_cb_compound_hdr *hdr)
0716 {
0717 __be32 *p;
0718
0719 p = xdr_reserve_space(xdr, 4);
0720 *p = cpu_to_be32(OP_CB_OFFLOAD);
0721 encode_nfs_fh4(xdr, &cbo->co_fh);
0722 encode_stateid4(xdr, &cbo->co_res.cb_stateid);
0723 encode_offload_info4(xdr, cbo);
0724
0725 hdr->nops++;
0726 }
0727
0728 static void nfs4_xdr_enc_cb_offload(struct rpc_rqst *req,
0729 struct xdr_stream *xdr,
0730 const void *data)
0731 {
0732 const struct nfsd4_callback *cb = data;
0733 const struct nfsd4_cb_offload *cbo =
0734 container_of(cb, struct nfsd4_cb_offload, co_cb);
0735 struct nfs4_cb_compound_hdr hdr = {
0736 .ident = 0,
0737 .minorversion = cb->cb_clp->cl_minorversion,
0738 };
0739
0740 encode_cb_compound4args(xdr, &hdr);
0741 encode_cb_sequence4args(xdr, cb, &hdr);
0742 encode_cb_offload4args(xdr, cbo, &hdr);
0743 encode_cb_nops(&hdr);
0744 }
0745
0746 static int nfs4_xdr_dec_cb_offload(struct rpc_rqst *rqstp,
0747 struct xdr_stream *xdr,
0748 void *data)
0749 {
0750 struct nfsd4_callback *cb = data;
0751 struct nfs4_cb_compound_hdr hdr;
0752 int status;
0753
0754 status = decode_cb_compound4res(xdr, &hdr);
0755 if (unlikely(status))
0756 return status;
0757
0758 status = decode_cb_sequence4res(xdr, cb);
0759 if (unlikely(status || cb->cb_seq_status))
0760 return status;
0761
0762 return decode_cb_op_status(xdr, OP_CB_OFFLOAD, &cb->cb_status);
0763 }
0764
0765
0766
0767 #define PROC(proc, call, argtype, restype) \
0768 [NFSPROC4_CLNT_##proc] = { \
0769 .p_proc = NFSPROC4_CB_##call, \
0770 .p_encode = nfs4_xdr_enc_##argtype, \
0771 .p_decode = nfs4_xdr_dec_##restype, \
0772 .p_arglen = NFS4_enc_##argtype##_sz, \
0773 .p_replen = NFS4_dec_##restype##_sz, \
0774 .p_statidx = NFSPROC4_CB_##call, \
0775 .p_name = #proc, \
0776 }
0777
0778 static const struct rpc_procinfo nfs4_cb_procedures[] = {
0779 PROC(CB_NULL, NULL, cb_null, cb_null),
0780 PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall),
0781 #ifdef CONFIG_NFSD_PNFS
0782 PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout),
0783 #endif
0784 PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock),
0785 PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload),
0786 };
0787
0788 static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)];
0789 static const struct rpc_version nfs_cb_version4 = {
0790
0791
0792
0793
0794
0795
0796
0797 .number = 1,
0798 .nrprocs = ARRAY_SIZE(nfs4_cb_procedures),
0799 .procs = nfs4_cb_procedures,
0800 .counts = nfs4_cb_counts,
0801 };
0802
0803 static const struct rpc_version *nfs_cb_version[2] = {
0804 [1] = &nfs_cb_version4,
0805 };
0806
0807 static const struct rpc_program cb_program;
0808
0809 static struct rpc_stat cb_stats = {
0810 .program = &cb_program
0811 };
0812
0813 #define NFS4_CALLBACK 0x40000000
0814 static const struct rpc_program cb_program = {
0815 .name = "nfs4_cb",
0816 .number = NFS4_CALLBACK,
0817 .nrvers = ARRAY_SIZE(nfs_cb_version),
0818 .version = nfs_cb_version,
0819 .stats = &cb_stats,
0820 .pipe_dir_name = "nfsd4_cb",
0821 };
0822
0823 static int max_cb_time(struct net *net)
0824 {
0825 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0826
0827
0828
0829
0830
0831
0832 if (WARN_ON_ONCE(nn->nfsd4_lease > 3600))
0833 return 360 * HZ;
0834
0835 return max(((u32)nn->nfsd4_lease)/10, 1u) * HZ;
0836 }
0837
0838 static struct workqueue_struct *callback_wq;
0839
0840 static bool nfsd4_queue_cb(struct nfsd4_callback *cb)
0841 {
0842 return queue_work(callback_wq, &cb->cb_work);
0843 }
0844
0845 static void nfsd41_cb_inflight_begin(struct nfs4_client *clp)
0846 {
0847 atomic_inc(&clp->cl_cb_inflight);
0848 }
0849
0850 static void nfsd41_cb_inflight_end(struct nfs4_client *clp)
0851 {
0852
0853 if (atomic_dec_and_test(&clp->cl_cb_inflight))
0854 wake_up_var(&clp->cl_cb_inflight);
0855 }
0856
0857 static void nfsd41_cb_inflight_wait_complete(struct nfs4_client *clp)
0858 {
0859 wait_var_event(&clp->cl_cb_inflight,
0860 !atomic_read(&clp->cl_cb_inflight));
0861 }
0862
0863 static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
0864 {
0865 if (clp->cl_minorversion == 0) {
0866 client->cl_principal = clp->cl_cred.cr_targ_princ ?
0867 clp->cl_cred.cr_targ_princ : "nfs";
0868
0869 return get_cred(rpc_machine_cred());
0870 } else {
0871 struct cred *kcred;
0872
0873 kcred = prepare_kernel_cred(NULL);
0874 if (!kcred)
0875 return NULL;
0876
0877 kcred->uid = ses->se_cb_sec.uid;
0878 kcred->gid = ses->se_cb_sec.gid;
0879 return kcred;
0880 }
0881 }
0882
0883 static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
0884 {
0885 int maxtime = max_cb_time(clp->net);
0886 struct rpc_timeout timeparms = {
0887 .to_initval = maxtime,
0888 .to_retries = 0,
0889 .to_maxval = maxtime,
0890 };
0891 struct rpc_create_args args = {
0892 .net = clp->net,
0893 .address = (struct sockaddr *) &conn->cb_addr,
0894 .addrsize = conn->cb_addrlen,
0895 .saddress = (struct sockaddr *) &conn->cb_saddr,
0896 .timeout = &timeparms,
0897 .program = &cb_program,
0898 .version = 1,
0899 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
0900 .cred = current_cred(),
0901 };
0902 struct rpc_clnt *client;
0903 const struct cred *cred;
0904
0905 if (clp->cl_minorversion == 0) {
0906 if (!clp->cl_cred.cr_principal &&
0907 (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5)) {
0908 trace_nfsd_cb_setup_err(clp, -EINVAL);
0909 return -EINVAL;
0910 }
0911 args.client_name = clp->cl_cred.cr_principal;
0912 args.prognumber = conn->cb_prog;
0913 args.protocol = XPRT_TRANSPORT_TCP;
0914 args.authflavor = clp->cl_cred.cr_flavor;
0915 clp->cl_cb_ident = conn->cb_ident;
0916 } else {
0917 if (!conn->cb_xprt)
0918 return -EINVAL;
0919 clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
0920 clp->cl_cb_session = ses;
0921 args.bc_xprt = conn->cb_xprt;
0922 args.prognumber = clp->cl_cb_session->se_cb_prog;
0923 args.protocol = conn->cb_xprt->xpt_class->xcl_ident |
0924 XPRT_TRANSPORT_BC;
0925 args.authflavor = ses->se_cb_sec.flavor;
0926 }
0927
0928 client = rpc_create(&args);
0929 if (IS_ERR(client)) {
0930 trace_nfsd_cb_setup_err(clp, PTR_ERR(client));
0931 return PTR_ERR(client);
0932 }
0933 cred = get_backchannel_cred(clp, client, ses);
0934 if (!cred) {
0935 trace_nfsd_cb_setup_err(clp, -ENOMEM);
0936 rpc_shutdown_client(client);
0937 return -ENOMEM;
0938 }
0939 clp->cl_cb_client = client;
0940 clp->cl_cb_cred = cred;
0941 rcu_read_lock();
0942 trace_nfsd_cb_setup(clp, rpc_peeraddr2str(client, RPC_DISPLAY_NETID),
0943 args.authflavor);
0944 rcu_read_unlock();
0945 return 0;
0946 }
0947
0948 static void nfsd4_mark_cb_state(struct nfs4_client *clp, int newstate)
0949 {
0950 if (clp->cl_cb_state != newstate) {
0951 clp->cl_cb_state = newstate;
0952 trace_nfsd_cb_state(clp);
0953 }
0954 }
0955
0956 static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
0957 {
0958 if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
0959 return;
0960 nfsd4_mark_cb_state(clp, NFSD4_CB_DOWN);
0961 }
0962
0963 static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
0964 {
0965 if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
0966 return;
0967 nfsd4_mark_cb_state(clp, NFSD4_CB_FAULT);
0968 }
0969
0970 static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
0971 {
0972 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
0973
0974 if (task->tk_status)
0975 nfsd4_mark_cb_down(clp, task->tk_status);
0976 else
0977 nfsd4_mark_cb_state(clp, NFSD4_CB_UP);
0978 }
0979
0980 static void nfsd4_cb_probe_release(void *calldata)
0981 {
0982 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
0983
0984 nfsd41_cb_inflight_end(clp);
0985
0986 }
0987
0988 static const struct rpc_call_ops nfsd4_cb_probe_ops = {
0989
0990
0991 .rpc_call_done = nfsd4_cb_probe_done,
0992 .rpc_release = nfsd4_cb_probe_release,
0993 };
0994
0995
0996
0997
0998
0999 void nfsd4_probe_callback(struct nfs4_client *clp)
1000 {
1001 trace_nfsd_cb_probe(clp);
1002 nfsd4_mark_cb_state(clp, NFSD4_CB_UNKNOWN);
1003 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags);
1004 nfsd4_run_cb(&clp->cl_cb_null);
1005 }
1006
1007 void nfsd4_probe_callback_sync(struct nfs4_client *clp)
1008 {
1009 nfsd4_probe_callback(clp);
1010 flush_workqueue(callback_wq);
1011 }
1012
1013 void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
1014 {
1015 nfsd4_mark_cb_state(clp, NFSD4_CB_UNKNOWN);
1016 spin_lock(&clp->cl_lock);
1017 memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn));
1018 spin_unlock(&clp->cl_lock);
1019 }
1020
1021
1022
1023
1024
1025
1026 static bool nfsd41_cb_get_slot(struct nfsd4_callback *cb, struct rpc_task *task)
1027 {
1028 struct nfs4_client *clp = cb->cb_clp;
1029
1030 if (!cb->cb_holds_slot &&
1031 test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
1032 rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
1033
1034 if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
1035 dprintk("%s slot is busy\n", __func__);
1036 return false;
1037 }
1038 rpc_wake_up_queued_task(&clp->cl_cb_waitq, task);
1039 }
1040 cb->cb_holds_slot = true;
1041 return true;
1042 }
1043
1044 static void nfsd41_cb_release_slot(struct nfsd4_callback *cb)
1045 {
1046 struct nfs4_client *clp = cb->cb_clp;
1047
1048 if (cb->cb_holds_slot) {
1049 cb->cb_holds_slot = false;
1050 clear_bit(0, &clp->cl_cb_slot_busy);
1051 rpc_wake_up_next(&clp->cl_cb_waitq);
1052 }
1053 }
1054
1055 static void nfsd41_destroy_cb(struct nfsd4_callback *cb)
1056 {
1057 struct nfs4_client *clp = cb->cb_clp;
1058
1059 nfsd41_cb_release_slot(cb);
1060 if (cb->cb_ops && cb->cb_ops->release)
1061 cb->cb_ops->release(cb);
1062 nfsd41_cb_inflight_end(clp);
1063 }
1064
1065
1066
1067
1068
1069 static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
1070 {
1071 struct nfsd4_callback *cb = calldata;
1072 struct nfs4_client *clp = cb->cb_clp;
1073 u32 minorversion = clp->cl_minorversion;
1074
1075
1076
1077
1078
1079 cb->cb_seq_status = 1;
1080 cb->cb_status = 0;
1081 if (minorversion && !nfsd41_cb_get_slot(cb, task))
1082 return;
1083 rpc_call_start(task);
1084 }
1085
1086 static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback *cb)
1087 {
1088 struct nfs4_client *clp = cb->cb_clp;
1089 struct nfsd4_session *session = clp->cl_cb_session;
1090 bool ret = true;
1091
1092 if (!clp->cl_minorversion) {
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 if (RPC_SIGNALLED(task))
1103 goto need_restart;
1104
1105 return true;
1106 }
1107
1108 if (!cb->cb_holds_slot)
1109 goto need_restart;
1110
1111 switch (cb->cb_seq_status) {
1112 case 0:
1113
1114
1115
1116
1117
1118
1119
1120 ++session->se_cb_seq_nr;
1121 break;
1122 case -ESERVERFAULT:
1123 ++session->se_cb_seq_nr;
1124 fallthrough;
1125 case 1:
1126 case -NFS4ERR_BADSESSION:
1127 nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status);
1128 ret = false;
1129 break;
1130 case -NFS4ERR_DELAY:
1131 if (!rpc_restart_call(task))
1132 goto out;
1133
1134 rpc_delay(task, 2 * HZ);
1135 return false;
1136 case -NFS4ERR_BADSLOT:
1137 goto retry_nowait;
1138 case -NFS4ERR_SEQ_MISORDERED:
1139 if (session->se_cb_seq_nr != 1) {
1140 session->se_cb_seq_nr = 1;
1141 goto retry_nowait;
1142 }
1143 break;
1144 default:
1145 nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status);
1146 dprintk("%s: unprocessed error %d\n", __func__,
1147 cb->cb_seq_status);
1148 }
1149
1150 nfsd41_cb_release_slot(cb);
1151 dprintk("%s: freed slot, new seqid=%d\n", __func__,
1152 clp->cl_cb_session->se_cb_seq_nr);
1153
1154 if (RPC_SIGNALLED(task))
1155 goto need_restart;
1156 out:
1157 return ret;
1158 retry_nowait:
1159 if (rpc_restart_call_prepare(task))
1160 ret = false;
1161 goto out;
1162 need_restart:
1163 if (!test_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags)) {
1164 task->tk_status = 0;
1165 cb->cb_need_restart = true;
1166 }
1167 return false;
1168 }
1169
1170 static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
1171 {
1172 struct nfsd4_callback *cb = calldata;
1173 struct nfs4_client *clp = cb->cb_clp;
1174
1175 if (!nfsd4_cb_sequence_done(task, cb))
1176 return;
1177
1178 if (cb->cb_status) {
1179 WARN_ON_ONCE(task->tk_status);
1180 task->tk_status = cb->cb_status;
1181 }
1182
1183 switch (cb->cb_ops->done(cb, task)) {
1184 case 0:
1185 task->tk_status = 0;
1186 rpc_restart_call_prepare(task);
1187 return;
1188 case 1:
1189 switch (task->tk_status) {
1190 case -EIO:
1191 case -ETIMEDOUT:
1192 case -EACCES:
1193 nfsd4_mark_cb_down(clp, task->tk_status);
1194 }
1195 break;
1196 default:
1197 BUG();
1198 }
1199 }
1200
1201 static void nfsd4_cb_release(void *calldata)
1202 {
1203 struct nfsd4_callback *cb = calldata;
1204
1205 if (cb->cb_need_restart)
1206 nfsd4_queue_cb(cb);
1207 else
1208 nfsd41_destroy_cb(cb);
1209
1210 }
1211
1212 static const struct rpc_call_ops nfsd4_cb_ops = {
1213 .rpc_call_prepare = nfsd4_cb_prepare,
1214 .rpc_call_done = nfsd4_cb_done,
1215 .rpc_release = nfsd4_cb_release,
1216 };
1217
1218 int nfsd4_create_callback_queue(void)
1219 {
1220 callback_wq = alloc_ordered_workqueue("nfsd4_callbacks", 0);
1221 if (!callback_wq)
1222 return -ENOMEM;
1223 return 0;
1224 }
1225
1226 void nfsd4_destroy_callback_queue(void)
1227 {
1228 destroy_workqueue(callback_wq);
1229 }
1230
1231
1232 void nfsd4_shutdown_callback(struct nfs4_client *clp)
1233 {
1234 if (clp->cl_cb_state != NFSD4_CB_UNKNOWN)
1235 trace_nfsd_cb_shutdown(clp);
1236
1237 set_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags);
1238
1239
1240
1241
1242
1243 nfsd4_run_cb(&clp->cl_cb_null);
1244 flush_workqueue(callback_wq);
1245 nfsd41_cb_inflight_wait_complete(clp);
1246 }
1247
1248
1249 static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp)
1250 {
1251 struct nfsd4_session *s;
1252 struct nfsd4_conn *c;
1253
1254 list_for_each_entry(s, &clp->cl_sessions, se_perclnt) {
1255 list_for_each_entry(c, &s->se_conns, cn_persession) {
1256 if (c->cn_flags & NFS4_CDFC4_BACK)
1257 return c;
1258 }
1259 }
1260 return NULL;
1261 }
1262
1263
1264
1265
1266
1267
1268
1269 static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
1270 {
1271 struct nfs4_cb_conn conn;
1272 struct nfs4_client *clp = cb->cb_clp;
1273 struct nfsd4_session *ses = NULL;
1274 struct nfsd4_conn *c;
1275 int err;
1276
1277
1278
1279
1280
1281 if (clp->cl_cb_client) {
1282 rpc_shutdown_client(clp->cl_cb_client);
1283 clp->cl_cb_client = NULL;
1284 put_cred(clp->cl_cb_cred);
1285 clp->cl_cb_cred = NULL;
1286 }
1287 if (clp->cl_cb_conn.cb_xprt) {
1288 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1289 clp->cl_cb_conn.cb_xprt = NULL;
1290 }
1291 if (test_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags))
1292 return;
1293 spin_lock(&clp->cl_lock);
1294
1295
1296
1297
1298 BUG_ON(!(clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK));
1299 clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags);
1300 memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn));
1301 c = __nfsd4_find_backchannel(clp);
1302 if (c) {
1303 svc_xprt_get(c->cn_xprt);
1304 conn.cb_xprt = c->cn_xprt;
1305 ses = c->cn_session;
1306 }
1307 spin_unlock(&clp->cl_lock);
1308
1309 err = setup_callback_client(clp, &conn, ses);
1310 if (err) {
1311 nfsd4_mark_cb_down(clp, err);
1312 if (c)
1313 svc_xprt_put(c->cn_xprt);
1314 return;
1315 }
1316 }
1317
1318 static void
1319 nfsd4_run_cb_work(struct work_struct *work)
1320 {
1321 struct nfsd4_callback *cb =
1322 container_of(work, struct nfsd4_callback, cb_work);
1323 struct nfs4_client *clp = cb->cb_clp;
1324 struct rpc_clnt *clnt;
1325 int flags;
1326
1327 if (cb->cb_need_restart) {
1328 cb->cb_need_restart = false;
1329 } else {
1330 if (cb->cb_ops && cb->cb_ops->prepare)
1331 cb->cb_ops->prepare(cb);
1332 }
1333
1334 if (clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK)
1335 nfsd4_process_cb_update(cb);
1336
1337 clnt = clp->cl_cb_client;
1338 if (!clnt) {
1339
1340 nfsd41_destroy_cb(cb);
1341 return;
1342 }
1343
1344
1345
1346
1347 if (!cb->cb_ops && clp->cl_minorversion) {
1348 nfsd4_mark_cb_state(clp, NFSD4_CB_UP);
1349 nfsd41_destroy_cb(cb);
1350 return;
1351 }
1352
1353 cb->cb_msg.rpc_cred = clp->cl_cb_cred;
1354 flags = clp->cl_minorversion ? RPC_TASK_NOCONNECT : RPC_TASK_SOFTCONN;
1355 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | flags,
1356 cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
1357 }
1358
1359 void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
1360 const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op)
1361 {
1362 cb->cb_clp = clp;
1363 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[op];
1364 cb->cb_msg.rpc_argp = cb;
1365 cb->cb_msg.rpc_resp = cb;
1366 cb->cb_ops = ops;
1367 INIT_WORK(&cb->cb_work, nfsd4_run_cb_work);
1368 cb->cb_seq_status = 1;
1369 cb->cb_status = 0;
1370 cb->cb_need_restart = false;
1371 cb->cb_holds_slot = false;
1372 }
1373
1374 void nfsd4_run_cb(struct nfsd4_callback *cb)
1375 {
1376 struct nfs4_client *clp = cb->cb_clp;
1377
1378 nfsd41_cb_inflight_begin(clp);
1379 if (!nfsd4_queue_cb(cb))
1380 nfsd41_cb_inflight_end(clp);
1381 }