Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfsd-4.14' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
"More RDMA work and some op-structure constification from Chuck Lever,
and a small cleanup to our xdr encoding"

* tag 'nfsd-4.14' of git://linux-nfs.org/~bfields/linux:
svcrdma: Estimate Send Queue depth properly
rdma core: Add rdma_rw_mr_payload()
svcrdma: Limit RQ depth
svcrdma: Populate tail iovec when receiving
nfsd: Incoming xdr_bufs may have content in tail buffer
svcrdma: Clean up svc_rdma_build_read_chunk()
sunrpc: Const-ify struct sv_serv_ops
nfsd: Const-ify NFSv4 encoding and decoding ops arrays
sunrpc: Const-ify instances of struct svc_xprt_ops
nfsd4: individual encoders no longer see error cases
nfsd4: skip encoder in trivial error cases
nfsd4: define ->op_release for compound ops
nfsd4: opdesc will be useful outside nfs4proc.c
nfsd4: move some nfsd4 op definitions to xdr4.h

+323 -401
+24
drivers/infiniband/core/rw.c
··· 643 643 } 644 644 EXPORT_SYMBOL(rdma_rw_ctx_destroy_signature); 645 645 646 + /** 647 + * rdma_rw_mr_factor - return number of MRs required for a payload 648 + * @device: device handling the connection 649 + * @port_num: port num to which the connection is bound 650 + * @maxpages: maximum payload pages per rdma_rw_ctx 651 + * 652 + * Returns the number of MRs the device requires to move @maxpayload 653 + * bytes. The returned value is used during transport creation to 654 + * compute max_rdma_ctxts and the size of the transport's Send and 655 + * Send Completion Queues. 656 + */ 657 + unsigned int rdma_rw_mr_factor(struct ib_device *device, u8 port_num, 658 + unsigned int maxpages) 659 + { 660 + unsigned int mr_pages; 661 + 662 + if (rdma_rw_can_use_mr(device, port_num)) 663 + mr_pages = rdma_rw_fr_page_list_len(device); 664 + else 665 + mr_pages = device->attrs.max_sge_rd; 666 + return DIV_ROUND_UP(maxpages, mr_pages); 667 + } 668 + EXPORT_SYMBOL(rdma_rw_mr_factor); 669 + 646 670 void rdma_rw_init_qp(struct ib_device *dev, struct ib_qp_init_attr *attr) 647 671 { 648 672 u32 factor;
+1 -1
fs/lockd/svc.c
··· 396 396 return error; 397 397 } 398 398 399 - static struct svc_serv_ops lockd_sv_ops = { 399 + static const struct svc_serv_ops lockd_sv_ops = { 400 400 .svo_shutdown = svc_rpcb_cleanup, 401 401 .svo_enqueue_xprt = svc_xprt_do_enqueue, 402 402 };
+5 -5
fs/nfs/callback.c
··· 226 226 return ret; 227 227 } 228 228 229 - static struct svc_serv_ops nfs40_cb_sv_ops = { 229 + static const struct svc_serv_ops nfs40_cb_sv_ops = { 230 230 .svo_function = nfs4_callback_svc, 231 231 .svo_enqueue_xprt = svc_xprt_do_enqueue, 232 232 .svo_setup = svc_set_num_threads_sync, 233 233 .svo_module = THIS_MODULE, 234 234 }; 235 235 #if defined(CONFIG_NFS_V4_1) 236 - static struct svc_serv_ops nfs41_cb_sv_ops = { 236 + static const struct svc_serv_ops nfs41_cb_sv_ops = { 237 237 .svo_function = nfs41_callback_svc, 238 238 .svo_enqueue_xprt = svc_xprt_do_enqueue, 239 239 .svo_setup = svc_set_num_threads_sync, 240 240 .svo_module = THIS_MODULE, 241 241 }; 242 242 243 - static struct svc_serv_ops *nfs4_cb_sv_ops[] = { 243 + static const struct svc_serv_ops *nfs4_cb_sv_ops[] = { 244 244 [0] = &nfs40_cb_sv_ops, 245 245 [1] = &nfs41_cb_sv_ops, 246 246 }; 247 247 #else 248 - static struct svc_serv_ops *nfs4_cb_sv_ops[] = { 248 + static const struct svc_serv_ops *nfs4_cb_sv_ops[] = { 249 249 [0] = &nfs40_cb_sv_ops, 250 250 [1] = NULL, 251 251 }; ··· 254 254 static struct svc_serv *nfs_callback_create_svc(int minorversion) 255 255 { 256 256 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 257 + const struct svc_serv_ops *sv_ops; 257 258 struct svc_serv *serv; 258 - struct svc_serv_ops *sv_ops; 259 259 260 260 /* 261 261 * Check whether we're already up and running.
+50 -60
fs/nfsd/nfs4proc.c
··· 784 784 return status; 785 785 } 786 786 787 + 788 + static void 789 + nfsd4_read_release(union nfsd4_op_u *u) 790 + { 791 + if (u->read.rd_filp) 792 + fput(u->read.rd_filp); 793 + } 794 + 787 795 static __be32 788 796 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 789 797 union nfsd4_op_u *u) ··· 918 910 u->secinfo_no_name.sin_exp = exp_get(cstate->current_fh.fh_export); 919 911 fh_put(&cstate->current_fh); 920 912 return nfs_ok; 913 + } 914 + 915 + static void 916 + nfsd4_secinfo_release(union nfsd4_op_u *u) 917 + { 918 + if (u->secinfo.si_exp) 919 + exp_put(u->secinfo.si_exp); 921 920 } 922 921 923 922 static __be32 ··· 1350 1335 return nfserr; 1351 1336 } 1352 1337 1338 + static void 1339 + nfsd4_getdeviceinfo_release(union nfsd4_op_u *u) 1340 + { 1341 + kfree(u->getdeviceinfo.gd_device); 1342 + } 1343 + 1353 1344 static __be32 1354 1345 nfsd4_layoutget(struct svc_rqst *rqstp, 1355 1346 struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) ··· 1434 1413 nfs4_put_stid(&ls->ls_stid); 1435 1414 out: 1436 1415 return nfserr; 1416 + } 1417 + 1418 + static void 1419 + nfsd4_layoutget_release(union nfsd4_op_u *u) 1420 + { 1421 + kfree(u->layoutget.lg_content); 1437 1422 } 1438 1423 1439 1424 static __be32 ··· 1568 1541 nfsdstats.nfs4_opcount[opnum]++; 1569 1542 } 1570 1543 1571 - enum nfsd4_op_flags { 1572 - ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 1573 - ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 1574 - ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ 1575 - /* For rfc 5661 section 2.6.3.1.1: */ 1576 - OP_HANDLES_WRONGSEC = 1 << 3, 1577 - OP_IS_PUTFH_LIKE = 1 << 4, 1578 - /* 1579 - * These are the ops whose result size we estimate before 1580 - * encoding, to avoid performing an op then not being able to 1581 - * respond or cache a response. This includes writes and setattrs 1582 - * as well as the operations usually called "nonidempotent": 1583 - */ 1584 - OP_MODIFIES_SOMETHING = 1 << 5, 1585 - /* 1586 - * Cache compounds containing these ops in the xid-based drc: 1587 - * We use the DRC for compounds containing non-idempotent 1588 - * operations, *except* those that are 4.1-specific (since 1589 - * sessions provide their own EOS), and except for stateful 1590 - * operations other than setclientid and setclientid_confirm 1591 - * (since sequence numbers provide EOS for open, lock, etc in 1592 - * the v4.0 case). 1593 - */ 1594 - OP_CACHEME = 1 << 6, 1595 - /* 1596 - * These are ops which clear current state id. 1597 - */ 1598 - OP_CLEAR_STATEID = 1 << 7, 1599 - }; 1600 - 1601 - struct nfsd4_operation { 1602 - __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1603 - union nfsd4_op_u *); 1604 - u32 op_flags; 1605 - char *op_name; 1606 - /* Try to get response size before operation */ 1607 - u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *); 1608 - void (*op_get_currentstateid)(struct nfsd4_compound_state *, 1609 - union nfsd4_op_u *); 1610 - void (*op_set_currentstateid)(struct nfsd4_compound_state *, 1611 - union nfsd4_op_u *); 1612 - }; 1613 - 1614 1544 static const struct nfsd4_operation nfsd4_ops[]; 1615 1545 1616 1546 static const char *nfsd4_op_name(unsigned opnum); ··· 1605 1621 return nfs_ok; 1606 1622 } 1607 1623 1608 - static inline const struct nfsd4_operation *OPDESC(struct nfsd4_op *op) 1624 + const struct nfsd4_operation *OPDESC(struct nfsd4_op *op) 1609 1625 { 1610 1626 return &nfsd4_ops[op->opnum]; 1611 1627 } ··· 1678 1694 struct nfsd4_compoundargs *args = rqstp->rq_argp; 1679 1695 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1680 1696 struct nfsd4_op *op; 1681 - const struct nfsd4_operation *opdesc; 1682 1697 struct nfsd4_compound_state *cstate = &resp->cstate; 1683 1698 struct svc_fh *current_fh = &cstate->current_fh; 1684 1699 struct svc_fh *save_fh = &cstate->save_fh; ··· 1730 1747 goto encode_op; 1731 1748 } 1732 1749 1733 - opdesc = OPDESC(op); 1734 - 1735 1750 if (!current_fh->fh_dentry) { 1736 - if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1751 + if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1737 1752 op->status = nfserr_nofilehandle; 1738 1753 goto encode_op; 1739 1754 } 1740 1755 } else if (current_fh->fh_export->ex_fslocs.migrated && 1741 - !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1756 + !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1742 1757 op->status = nfserr_moved; 1743 1758 goto encode_op; 1744 1759 } ··· 1744 1763 fh_clear_wcc(current_fh); 1745 1764 1746 1765 /* If op is non-idempotent */ 1747 - if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { 1766 + if (op->opdesc->op_flags & OP_MODIFIES_SOMETHING) { 1748 1767 /* 1749 1768 * Don't execute this op if we couldn't encode a 1750 1769 * succesful reply: 1751 1770 */ 1752 - u32 plen = opdesc->op_rsize_bop(rqstp, op); 1771 + u32 plen = op->opdesc->op_rsize_bop(rqstp, op); 1753 1772 /* 1754 1773 * Plus if there's another operation, make sure 1755 1774 * we'll have space to at least encode an error: ··· 1762 1781 if (op->status) 1763 1782 goto encode_op; 1764 1783 1765 - if (opdesc->op_get_currentstateid) 1766 - opdesc->op_get_currentstateid(cstate, &op->u); 1767 - op->status = opdesc->op_func(rqstp, cstate, &op->u); 1784 + if (op->opdesc->op_get_currentstateid) 1785 + op->opdesc->op_get_currentstateid(cstate, &op->u); 1786 + op->status = op->opdesc->op_func(rqstp, cstate, &op->u); 1768 1787 1769 1788 /* Only from SEQUENCE */ 1770 1789 if (cstate->status == nfserr_replay_cache) { ··· 1773 1792 goto out; 1774 1793 } 1775 1794 if (!op->status) { 1776 - if (opdesc->op_set_currentstateid) 1777 - opdesc->op_set_currentstateid(cstate, &op->u); 1795 + if (op->opdesc->op_set_currentstateid) 1796 + op->opdesc->op_set_currentstateid(cstate, &op->u); 1778 1797 1779 - if (opdesc->op_flags & OP_CLEAR_STATEID) 1798 + if (op->opdesc->op_flags & OP_CLEAR_STATEID) 1780 1799 clear_current_stateid(cstate); 1781 1800 1782 1801 if (need_wrongsec_check(rqstp)) ··· 2141 2160 }, 2142 2161 [OP_LOCK] = { 2143 2162 .op_func = nfsd4_lock, 2144 - .op_flags = OP_MODIFIES_SOMETHING, 2163 + .op_flags = OP_MODIFIES_SOMETHING | 2164 + OP_NONTRIVIAL_ERROR_ENCODE, 2145 2165 .op_name = "OP_LOCK", 2146 2166 .op_rsize_bop = nfsd4_lock_rsize, 2147 2167 .op_set_currentstateid = nfsd4_set_lockstateid, 2148 2168 }, 2149 2169 [OP_LOCKT] = { 2150 2170 .op_func = nfsd4_lockt, 2171 + .op_flags = OP_NONTRIVIAL_ERROR_ENCODE, 2151 2172 .op_name = "OP_LOCKT", 2152 2173 .op_rsize_bop = nfsd4_lock_rsize, 2153 2174 }, ··· 2221 2238 }, 2222 2239 [OP_READ] = { 2223 2240 .op_func = nfsd4_read, 2241 + .op_release = nfsd4_read_release, 2224 2242 .op_name = "OP_READ", 2225 2243 .op_rsize_bop = nfsd4_read_rsize, 2226 2244 .op_get_currentstateid = nfsd4_get_readstateid, ··· 2271 2287 }, 2272 2288 [OP_SECINFO] = { 2273 2289 .op_func = nfsd4_secinfo, 2290 + .op_release = nfsd4_secinfo_release, 2274 2291 .op_flags = OP_HANDLES_WRONGSEC, 2275 2292 .op_name = "OP_SECINFO", 2276 2293 .op_rsize_bop = nfsd4_secinfo_rsize, ··· 2279 2294 [OP_SETATTR] = { 2280 2295 .op_func = nfsd4_setattr, 2281 2296 .op_name = "OP_SETATTR", 2282 - .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 2297 + .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME 2298 + | OP_NONTRIVIAL_ERROR_ENCODE, 2283 2299 .op_rsize_bop = nfsd4_setattr_rsize, 2284 2300 .op_get_currentstateid = nfsd4_get_setattrstateid, 2285 2301 }, 2286 2302 [OP_SETCLIENTID] = { 2287 2303 .op_func = nfsd4_setclientid, 2288 2304 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 2289 - | OP_MODIFIES_SOMETHING | OP_CACHEME, 2305 + | OP_MODIFIES_SOMETHING | OP_CACHEME 2306 + | OP_NONTRIVIAL_ERROR_ENCODE, 2290 2307 .op_name = "OP_SETCLIENTID", 2291 2308 .op_rsize_bop = nfsd4_setclientid_rsize, 2292 2309 }, ··· 2375 2388 }, 2376 2389 [OP_SECINFO_NO_NAME] = { 2377 2390 .op_func = nfsd4_secinfo_no_name, 2391 + .op_release = nfsd4_secinfo_release, 2378 2392 .op_flags = OP_HANDLES_WRONGSEC, 2379 2393 .op_name = "OP_SECINFO_NO_NAME", 2380 2394 .op_rsize_bop = nfsd4_secinfo_rsize, ··· 2396 2408 #ifdef CONFIG_NFSD_PNFS 2397 2409 [OP_GETDEVICEINFO] = { 2398 2410 .op_func = nfsd4_getdeviceinfo, 2411 + .op_release = nfsd4_getdeviceinfo_release, 2399 2412 .op_flags = ALLOWED_WITHOUT_FH, 2400 2413 .op_name = "OP_GETDEVICEINFO", 2401 2414 .op_rsize_bop = nfsd4_getdeviceinfo_rsize, 2402 2415 }, 2403 2416 [OP_LAYOUTGET] = { 2404 2417 .op_func = nfsd4_layoutget, 2418 + .op_release = nfsd4_layoutget_release, 2405 2419 .op_flags = OP_MODIFIES_SOMETHING, 2406 2420 .op_name = "OP_LAYOUTGET", 2407 2421 .op_rsize_bop = nfsd4_layoutget_rsize,
+132 -214
fs/nfsd/nfs4xdr.c
··· 159 159 */ 160 160 unsigned int avail = (char *)argp->end - (char *)argp->p; 161 161 __be32 *p; 162 + 163 + if (argp->pagelen == 0) { 164 + struct kvec *vec = &argp->rqstp->rq_arg.tail[0]; 165 + 166 + if (!argp->tail) { 167 + argp->tail = true; 168 + avail = vec->iov_len; 169 + argp->p = vec->iov_base; 170 + argp->end = vec->iov_base + avail; 171 + } 172 + 173 + if (avail < nbytes) 174 + return NULL; 175 + 176 + p = argp->p; 177 + argp->p += XDR_QUADLEN(nbytes); 178 + return p; 179 + } 180 + 162 181 if (avail + argp->pagelen < nbytes) 163 182 return NULL; 164 183 if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ ··· 1797 1778 1798 1779 typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); 1799 1780 1800 - static nfsd4_dec nfsd4_dec_ops[] = { 1781 + static const nfsd4_dec nfsd4_dec_ops[] = { 1801 1782 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, 1802 1783 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, 1803 1784 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, ··· 1946 1927 op->opnum = OP_ILLEGAL; 1947 1928 op->status = nfserr_op_illegal; 1948 1929 } 1930 + op->opdesc = OPDESC(op); 1949 1931 /* 1950 1932 * We'll try to cache the result in the DRC if any one 1951 1933 * op in the compound wants to be cached: ··· 3122 3102 struct xdr_stream *xdr = &resp->xdr; 3123 3103 __be32 *p; 3124 3104 3125 - if (!nfserr) { 3126 - p = xdr_reserve_space(xdr, 8); 3127 - if (!p) 3128 - return nfserr_resource; 3129 - *p++ = cpu_to_be32(access->ac_supported); 3130 - *p++ = cpu_to_be32(access->ac_resp_access); 3131 - } 3132 - return nfserr; 3105 + p = xdr_reserve_space(xdr, 8); 3106 + if (!p) 3107 + return nfserr_resource; 3108 + *p++ = cpu_to_be32(access->ac_supported); 3109 + *p++ = cpu_to_be32(access->ac_resp_access); 3110 + return 0; 3133 3111 } 3134 3112 3135 3113 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) ··· 3135 3117 struct xdr_stream *xdr = &resp->xdr; 3136 3118 __be32 *p; 3137 3119 3138 - if (!nfserr) { 3139 - p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8); 3140 - if (!p) 3141 - return nfserr_resource; 3142 - p = xdr_encode_opaque_fixed(p, bcts->sessionid.data, 3143 - NFS4_MAX_SESSIONID_LEN); 3144 - *p++ = cpu_to_be32(bcts->dir); 3145 - /* Upshifting from TCP to RDMA is not supported */ 3146 - *p++ = cpu_to_be32(0); 3147 - } 3148 - return nfserr; 3120 + p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8); 3121 + if (!p) 3122 + return nfserr_resource; 3123 + p = xdr_encode_opaque_fixed(p, bcts->sessionid.data, 3124 + NFS4_MAX_SESSIONID_LEN); 3125 + *p++ = cpu_to_be32(bcts->dir); 3126 + /* Upshifting from TCP to RDMA is not supported */ 3127 + *p++ = cpu_to_be32(0); 3128 + return 0; 3149 3129 } 3150 3130 3151 3131 static __be32 ··· 3151 3135 { 3152 3136 struct xdr_stream *xdr = &resp->xdr; 3153 3137 3154 - if (!nfserr) 3155 - nfserr = nfsd4_encode_stateid(xdr, &close->cl_stateid); 3156 - 3157 - return nfserr; 3138 + return nfsd4_encode_stateid(xdr, &close->cl_stateid); 3158 3139 } 3159 3140 3160 3141 ··· 3161 3148 struct xdr_stream *xdr = &resp->xdr; 3162 3149 __be32 *p; 3163 3150 3164 - if (!nfserr) { 3165 - p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); 3166 - if (!p) 3167 - return nfserr_resource; 3168 - p = xdr_encode_opaque_fixed(p, commit->co_verf.data, 3151 + p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); 3152 + if (!p) 3153 + return nfserr_resource; 3154 + p = xdr_encode_opaque_fixed(p, commit->co_verf.data, 3169 3155 NFS4_VERIFIER_SIZE); 3170 - } 3171 - return nfserr; 3156 + return 0; 3172 3157 } 3173 3158 3174 3159 static __be32 ··· 3175 3164 struct xdr_stream *xdr = &resp->xdr; 3176 3165 __be32 *p; 3177 3166 3178 - if (!nfserr) { 3179 - p = xdr_reserve_space(xdr, 20); 3180 - if (!p) 3181 - return nfserr_resource; 3182 - encode_cinfo(p, &create->cr_cinfo); 3183 - nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0], 3184 - create->cr_bmval[1], create->cr_bmval[2]); 3185 - } 3186 - return nfserr; 3167 + p = xdr_reserve_space(xdr, 20); 3168 + if (!p) 3169 + return nfserr_resource; 3170 + encode_cinfo(p, &create->cr_cinfo); 3171 + nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0], 3172 + create->cr_bmval[1], create->cr_bmval[2]); 3173 + return 0; 3187 3174 } 3188 3175 3189 3176 static __be32 ··· 3190 3181 struct svc_fh *fhp = getattr->ga_fhp; 3191 3182 struct xdr_stream *xdr = &resp->xdr; 3192 3183 3193 - if (nfserr) 3194 - return nfserr; 3195 - 3196 - nfserr = nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry, 3197 - getattr->ga_bmval, 3198 - resp->rqstp, 0); 3199 - return nfserr; 3184 + return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry, 3185 + getattr->ga_bmval, resp->rqstp, 0); 3200 3186 } 3201 3187 3202 3188 static __be32 ··· 3202 3198 unsigned int len; 3203 3199 __be32 *p; 3204 3200 3205 - if (!nfserr) { 3206 - len = fhp->fh_handle.fh_size; 3207 - p = xdr_reserve_space(xdr, len + 4); 3208 - if (!p) 3209 - return nfserr_resource; 3210 - p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len); 3211 - } 3212 - return nfserr; 3201 + len = fhp->fh_handle.fh_size; 3202 + p = xdr_reserve_space(xdr, len + 4); 3203 + if (!p) 3204 + return nfserr_resource; 3205 + p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len); 3206 + return 0; 3213 3207 } 3214 3208 3215 3209 /* ··· 3277 3275 { 3278 3276 struct xdr_stream *xdr = &resp->xdr; 3279 3277 3280 - if (!nfserr) 3281 - nfserr = nfsd4_encode_stateid(xdr, &locku->lu_stateid); 3282 - 3283 - return nfserr; 3278 + return nfsd4_encode_stateid(xdr, &locku->lu_stateid); 3284 3279 } 3285 3280 3286 3281 ··· 3287 3288 struct xdr_stream *xdr = &resp->xdr; 3288 3289 __be32 *p; 3289 3290 3290 - if (!nfserr) { 3291 - p = xdr_reserve_space(xdr, 20); 3292 - if (!p) 3293 - return nfserr_resource; 3294 - p = encode_cinfo(p, &link->li_cinfo); 3295 - } 3296 - return nfserr; 3291 + p = xdr_reserve_space(xdr, 20); 3292 + if (!p) 3293 + return nfserr_resource; 3294 + p = encode_cinfo(p, &link->li_cinfo); 3295 + return 0; 3297 3296 } 3298 3297 3299 3298 ··· 3301 3304 struct xdr_stream *xdr = &resp->xdr; 3302 3305 __be32 *p; 3303 3306 3304 - if (nfserr) 3305 - goto out; 3306 - 3307 3307 nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid); 3308 3308 if (nfserr) 3309 - goto out; 3309 + return nfserr; 3310 3310 p = xdr_reserve_space(xdr, 24); 3311 3311 if (!p) 3312 3312 return nfserr_resource; ··· 3313 3319 nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1], 3314 3320 open->op_bmval[2]); 3315 3321 if (nfserr) 3316 - goto out; 3322 + return nfserr; 3317 3323 3318 3324 p = xdr_reserve_space(xdr, 4); 3319 3325 if (!p) ··· 3386 3392 BUG(); 3387 3393 } 3388 3394 /* XXX save filehandle here */ 3389 - out: 3390 - return nfserr; 3395 + return 0; 3391 3396 } 3392 3397 3393 3398 static __be32 ··· 3394 3401 { 3395 3402 struct xdr_stream *xdr = &resp->xdr; 3396 3403 3397 - if (!nfserr) 3398 - nfserr = nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid); 3399 - 3400 - return nfserr; 3404 + return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid); 3401 3405 } 3402 3406 3403 3407 static __be32 ··· 3402 3412 { 3403 3413 struct xdr_stream *xdr = &resp->xdr; 3404 3414 3405 - if (!nfserr) 3406 - nfserr = nfsd4_encode_stateid(xdr, &od->od_stateid); 3407 - 3408 - return nfserr; 3415 + return nfsd4_encode_stateid(xdr, &od->od_stateid); 3409 3416 } 3410 3417 3411 3418 static __be32 nfsd4_encode_splice_read( ··· 3539 3552 struct raparms *ra = NULL; 3540 3553 __be32 *p; 3541 3554 3542 - if (nfserr) 3543 - goto out; 3544 - 3545 3555 p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */ 3546 3556 if (!p) { 3547 3557 WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)); 3548 - nfserr = nfserr_resource; 3549 - goto out; 3558 + return nfserr_resource; 3550 3559 } 3551 3560 if (resp->xdr.buf->page_len && 3552 3561 test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) { 3553 3562 WARN_ON_ONCE(1); 3554 - nfserr = nfserr_resource; 3555 - goto out; 3563 + return nfserr_resource; 3556 3564 } 3557 3565 xdr_commit_encode(xdr); 3558 3566 ··· 3571 3589 if (nfserr) 3572 3590 xdr_truncate_encode(xdr, starting_len); 3573 3591 3574 - out: 3575 - if (file) 3576 - fput(file); 3577 3592 return nfserr; 3578 3593 } 3579 3594 ··· 3583 3604 struct xdr_stream *xdr = &resp->xdr; 3584 3605 int length_offset = xdr->buf->len; 3585 3606 __be32 *p; 3586 - 3587 - if (nfserr) 3588 - return nfserr; 3589 3607 3590 3608 p = xdr_reserve_space(xdr, 4); 3591 3609 if (!p) ··· 3626 3650 struct xdr_stream *xdr = &resp->xdr; 3627 3651 int starting_len = xdr->buf->len; 3628 3652 __be32 *p; 3629 - 3630 - if (nfserr) 3631 - return nfserr; 3632 3653 3633 3654 p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); 3634 3655 if (!p) ··· 3712 3739 struct xdr_stream *xdr = &resp->xdr; 3713 3740 __be32 *p; 3714 3741 3715 - if (!nfserr) { 3716 - p = xdr_reserve_space(xdr, 20); 3717 - if (!p) 3718 - return nfserr_resource; 3719 - p = encode_cinfo(p, &remove->rm_cinfo); 3720 - } 3721 - return nfserr; 3742 + p = xdr_reserve_space(xdr, 20); 3743 + if (!p) 3744 + return nfserr_resource; 3745 + p = encode_cinfo(p, &remove->rm_cinfo); 3746 + return 0; 3722 3747 } 3723 3748 3724 3749 static __be32 ··· 3725 3754 struct xdr_stream *xdr = &resp->xdr; 3726 3755 __be32 *p; 3727 3756 3728 - if (!nfserr) { 3729 - p = xdr_reserve_space(xdr, 40); 3730 - if (!p) 3731 - return nfserr_resource; 3732 - p = encode_cinfo(p, &rename->rn_sinfo); 3733 - p = encode_cinfo(p, &rename->rn_tinfo); 3734 - } 3735 - return nfserr; 3757 + p = xdr_reserve_space(xdr, 40); 3758 + if (!p) 3759 + return nfserr_resource; 3760 + p = encode_cinfo(p, &rename->rn_sinfo); 3761 + p = encode_cinfo(p, &rename->rn_tinfo); 3762 + return 0; 3736 3763 } 3737 3764 3738 3765 static __be32 3739 - nfsd4_do_encode_secinfo(struct xdr_stream *xdr, 3740 - __be32 nfserr, struct svc_export *exp) 3766 + nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp) 3741 3767 { 3742 3768 u32 i, nflavs, supported; 3743 3769 struct exp_flavor_info *flavs; ··· 3742 3774 __be32 *p, *flavorsp; 3743 3775 static bool report = true; 3744 3776 3745 - if (nfserr) 3746 - goto out; 3747 - nfserr = nfserr_resource; 3748 3777 if (exp->ex_nflavors) { 3749 3778 flavs = exp->ex_flavors; 3750 3779 nflavs = exp->ex_nflavors; ··· 3765 3800 supported = 0; 3766 3801 p = xdr_reserve_space(xdr, 4); 3767 3802 if (!p) 3768 - goto out; 3803 + return nfserr_resource; 3769 3804 flavorsp = p++; /* to be backfilled later */ 3770 3805 3771 3806 for (i = 0; i < nflavs; i++) { ··· 3777 3812 p = xdr_reserve_space(xdr, 4 + 4 + 3778 3813 XDR_LEN(info.oid.len) + 4 + 4); 3779 3814 if (!p) 3780 - goto out; 3815 + return nfserr_resource; 3781 3816 *p++ = cpu_to_be32(RPC_AUTH_GSS); 3782 3817 p = xdr_encode_opaque(p, info.oid.data, info.oid.len); 3783 3818 *p++ = cpu_to_be32(info.qop); ··· 3786 3821 supported++; 3787 3822 p = xdr_reserve_space(xdr, 4); 3788 3823 if (!p) 3789 - goto out; 3824 + return nfserr_resource; 3790 3825 *p++ = cpu_to_be32(pf); 3791 3826 } else { 3792 3827 if (report) ··· 3798 3833 if (nflavs != supported) 3799 3834 report = false; 3800 3835 *flavorsp = htonl(supported); 3801 - nfserr = 0; 3802 - out: 3803 - if (exp) 3804 - exp_put(exp); 3805 - return nfserr; 3836 + return 0; 3806 3837 } 3807 3838 3808 3839 static __be32 ··· 3807 3846 { 3808 3847 struct xdr_stream *xdr = &resp->xdr; 3809 3848 3810 - return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->si_exp); 3849 + return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp); 3811 3850 } 3812 3851 3813 3852 static __be32 ··· 3816 3855 { 3817 3856 struct xdr_stream *xdr = &resp->xdr; 3818 3857 3819 - return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->sin_exp); 3858 + return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp); 3820 3859 } 3821 3860 3822 3861 /* ··· 3877 3916 struct xdr_stream *xdr = &resp->xdr; 3878 3917 __be32 *p; 3879 3918 3880 - if (!nfserr) { 3881 - p = xdr_reserve_space(xdr, 16); 3882 - if (!p) 3883 - return nfserr_resource; 3884 - *p++ = cpu_to_be32(write->wr_bytes_written); 3885 - *p++ = cpu_to_be32(write->wr_how_written); 3886 - p = xdr_encode_opaque_fixed(p, write->wr_verifier.data, 3887 - NFS4_VERIFIER_SIZE); 3888 - } 3889 - return nfserr; 3919 + p = xdr_reserve_space(xdr, 16); 3920 + if (!p) 3921 + return nfserr_resource; 3922 + *p++ = cpu_to_be32(write->wr_bytes_written); 3923 + *p++ = cpu_to_be32(write->wr_how_written); 3924 + p = xdr_encode_opaque_fixed(p, write->wr_verifier.data, 3925 + NFS4_VERIFIER_SIZE); 3926 + return 0; 3890 3927 } 3891 3928 3892 3929 static __be32 ··· 3897 3938 char *server_scope; 3898 3939 int major_id_sz; 3899 3940 int server_scope_sz; 3900 - int status = 0; 3901 3941 uint64_t minor_id = 0; 3902 - 3903 - if (nfserr) 3904 - return nfserr; 3905 3942 3906 3943 major_id = utsname()->nodename; 3907 3944 major_id_sz = strlen(major_id); ··· 3923 3968 break; 3924 3969 case SP4_MACH_CRED: 3925 3970 /* spo_must_enforce bitmap: */ 3926 - status = nfsd4_encode_bitmap(xdr, 3971 + nfserr = nfsd4_encode_bitmap(xdr, 3927 3972 exid->spo_must_enforce[0], 3928 3973 exid->spo_must_enforce[1], 3929 3974 exid->spo_must_enforce[2]); 3930 - if (status) 3931 - goto out; 3975 + if (nfserr) 3976 + return nfserr; 3932 3977 /* spo_must_allow bitmap: */ 3933 - status = nfsd4_encode_bitmap(xdr, 3978 + nfserr = nfsd4_encode_bitmap(xdr, 3934 3979 exid->spo_must_allow[0], 3935 3980 exid->spo_must_allow[1], 3936 3981 exid->spo_must_allow[2]); 3937 - if (status) 3938 - goto out; 3982 + if (nfserr) 3983 + return nfserr; 3939 3984 break; 3940 3985 default: 3941 3986 WARN_ON_ONCE(1); ··· 3962 4007 /* Implementation id */ 3963 4008 *p++ = cpu_to_be32(0); /* zero length nfs_impl_id4 array */ 3964 4009 return 0; 3965 - out: 3966 - return status; 3967 4010 } 3968 4011 3969 4012 static __be32 ··· 3970 4017 { 3971 4018 struct xdr_stream *xdr = &resp->xdr; 3972 4019 __be32 *p; 3973 - 3974 - if (nfserr) 3975 - return nfserr; 3976 4020 3977 4021 p = xdr_reserve_space(xdr, 24); 3978 4022 if (!p) ··· 4024 4074 struct xdr_stream *xdr = &resp->xdr; 4025 4075 __be32 *p; 4026 4076 4027 - if (nfserr) 4028 - return nfserr; 4029 - 4030 4077 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20); 4031 4078 if (!p) 4032 4079 return nfserr_resource; ··· 4048 4101 struct nfsd4_test_stateid_id *stateid, *next; 4049 4102 __be32 *p; 4050 4103 4051 - if (nfserr) 4052 - return nfserr; 4053 - 4054 4104 p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids)); 4055 4105 if (!p) 4056 4106 return nfserr_resource; ··· 4057 4113 *p++ = stateid->ts_id_status; 4058 4114 } 4059 4115 4060 - return nfserr; 4116 + return 0; 4061 4117 } 4062 4118 4063 4119 #ifdef CONFIG_NFSD_PNFS ··· 4070 4126 u32 starting_len = xdr->buf->len, needed_len; 4071 4127 __be32 *p; 4072 4128 4073 - dprintk("%s: err %d\n", __func__, be32_to_cpu(nfserr)); 4074 - if (nfserr) 4075 - goto out; 4076 - 4077 - nfserr = nfserr_resource; 4078 4129 p = xdr_reserve_space(xdr, 4); 4079 4130 if (!p) 4080 - goto out; 4131 + return nfserr_resource; 4081 4132 4082 4133 *p++ = cpu_to_be32(gdev->gd_layout_type); 4083 4134 ··· 4088 4149 */ 4089 4150 if (xdr->buf->len + 4 > gdev->gd_maxcount) 4090 4151 goto toosmall; 4091 - goto out; 4152 + return nfserr; 4092 4153 } 4093 4154 } 4094 4155 4095 - nfserr = nfserr_resource; 4096 4156 if (gdev->gd_notify_types) { 4097 4157 p = xdr_reserve_space(xdr, 4 + 4); 4098 4158 if (!p) 4099 - goto out; 4159 + return nfserr_resource; 4100 4160 *p++ = cpu_to_be32(1); /* bitmap length */ 4101 4161 *p++ = cpu_to_be32(gdev->gd_notify_types); 4102 4162 } else { 4103 4163 p = xdr_reserve_space(xdr, 4); 4104 4164 if (!p) 4105 - goto out; 4165 + return nfserr_resource; 4106 4166 *p++ = 0; 4107 4167 } 4108 4168 4109 - nfserr = 0; 4110 - out: 4111 - kfree(gdev->gd_device); 4112 - dprintk("%s: done: %d\n", __func__, be32_to_cpu(nfserr)); 4113 - return nfserr; 4114 - 4169 + return 0; 4115 4170 toosmall: 4116 4171 dprintk("%s: maxcount too small\n", __func__); 4117 4172 needed_len = xdr->buf->len + 4 /* notifications */; 4118 4173 xdr_truncate_encode(xdr, starting_len); 4119 4174 p = xdr_reserve_space(xdr, 4); 4120 - if (!p) { 4121 - nfserr = nfserr_resource; 4122 - } else { 4123 - *p++ = cpu_to_be32(needed_len); 4124 - nfserr = nfserr_toosmall; 4125 - } 4126 - goto out; 4175 + if (!p) 4176 + return nfserr_resource; 4177 + *p++ = cpu_to_be32(needed_len); 4178 + return nfserr_toosmall; 4127 4179 } 4128 4180 4129 4181 static __be32 ··· 4125 4195 const struct nfsd4_layout_ops *ops; 4126 4196 __be32 *p; 4127 4197 4128 - dprintk("%s: err %d\n", __func__, nfserr); 4129 - if (nfserr) 4130 - goto out; 4131 - 4132 - nfserr = nfserr_resource; 4133 4198 p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t)); 4134 4199 if (!p) 4135 - goto out; 4200 + return nfserr_resource; 4136 4201 4137 4202 *p++ = cpu_to_be32(1); /* we always set return-on-close */ 4138 4203 *p++ = cpu_to_be32(lgp->lg_sid.si_generation); ··· 4141 4216 *p++ = cpu_to_be32(lgp->lg_layout_type); 4142 4217 4143 4218 ops = nfsd4_layout_ops[lgp->lg_layout_type]; 4144 - nfserr = ops->encode_layoutget(xdr, lgp); 4145 - out: 4146 - kfree(lgp->lg_content); 4147 - return nfserr; 4219 + return ops->encode_layoutget(xdr, lgp); 4148 4220 } 4149 4221 4150 4222 static __be32 ··· 4150 4228 { 4151 4229 struct xdr_stream *xdr = &resp->xdr; 4152 4230 __be32 *p; 4153 - 4154 - if (nfserr) 4155 - return nfserr; 4156 4231 4157 4232 p = xdr_reserve_space(xdr, 4); 4158 4233 if (!p) ··· 4162 4243 p = xdr_encode_hyper(p, lcp->lc_newsize); 4163 4244 } 4164 4245 4165 - return nfs_ok; 4246 + return 0; 4166 4247 } 4167 4248 4168 4249 static __be32 ··· 4172 4253 struct xdr_stream *xdr = &resp->xdr; 4173 4254 __be32 *p; 4174 4255 4175 - if (nfserr) 4176 - return nfserr; 4177 - 4178 4256 p = xdr_reserve_space(xdr, 4); 4179 4257 if (!p) 4180 4258 return nfserr_resource; 4181 4259 *p++ = cpu_to_be32(lrp->lrs_present); 4182 4260 if (lrp->lrs_present) 4183 4261 return nfsd4_encode_stateid(xdr, &lrp->lr_sid); 4184 - return nfs_ok; 4262 + return 0; 4185 4263 } 4186 4264 #endif /* CONFIG_NFSD_PNFS */ 4187 4265 ··· 4205 4289 { 4206 4290 __be32 *p; 4207 4291 4208 - if (!nfserr) { 4209 - nfserr = nfsd42_encode_write_res(resp, &copy->cp_res); 4210 - if (nfserr) 4211 - return nfserr; 4292 + nfserr = nfsd42_encode_write_res(resp, &copy->cp_res); 4293 + if (nfserr) 4294 + return nfserr; 4212 4295 4213 - p = xdr_reserve_space(&resp->xdr, 4 + 4); 4214 - *p++ = cpu_to_be32(copy->cp_consecutive); 4215 - *p++ = cpu_to_be32(copy->cp_synchronous); 4216 - } 4217 - return nfserr; 4296 + p = xdr_reserve_space(&resp->xdr, 4 + 4); 4297 + *p++ = cpu_to_be32(copy->cp_consecutive); 4298 + *p++ = cpu_to_be32(copy->cp_synchronous); 4299 + return 0; 4218 4300 } 4219 4301 4220 4302 static __be32 ··· 4221 4307 { 4222 4308 __be32 *p; 4223 4309 4224 - if (nfserr) 4225 - return nfserr; 4226 - 4227 4310 p = xdr_reserve_space(&resp->xdr, 4 + 8); 4228 4311 *p++ = cpu_to_be32(seek->seek_eof); 4229 4312 p = xdr_encode_hyper(p, seek->seek_pos); 4230 4313 4231 - return nfserr; 4314 + return 0; 4232 4315 } 4233 4316 4234 4317 static __be32 ··· 4241 4330 * since we don't need to filter out obsolete ops as this is 4242 4331 * done in the decoding phase. 4243 4332 */ 4244 - static nfsd4_enc nfsd4_enc_ops[] = { 4333 + static const nfsd4_enc nfsd4_enc_ops[] = { 4245 4334 [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access, 4246 4335 [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close, 4247 4336 [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit, ··· 4360 4449 struct xdr_stream *xdr = &resp->xdr; 4361 4450 struct nfs4_stateowner *so = resp->cstate.replay_owner; 4362 4451 struct svc_rqst *rqstp = resp->rqstp; 4452 + const struct nfsd4_operation *opdesc = op->opdesc; 4363 4453 int post_err_offset; 4364 4454 nfsd4_enc encoder; 4365 4455 __be32 *p; ··· 4375 4463 4376 4464 if (op->opnum == OP_ILLEGAL) 4377 4465 goto status; 4466 + if (op->status && opdesc && 4467 + !(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE)) 4468 + goto status; 4378 4469 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) || 4379 4470 !nfsd4_enc_ops[op->opnum]); 4380 4471 encoder = nfsd4_enc_ops[op->opnum]; 4381 4472 op->status = encoder(resp, op->status, &op->u); 4473 + if (opdesc && opdesc->op_release) 4474 + opdesc->op_release(&op->u); 4382 4475 xdr_commit_encode(xdr); 4383 4476 4384 4477 /* nfsd4_check_resp_size guarantees enough room for error status */ ··· 4490 4573 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; 4491 4574 args->pagelist = rqstp->rq_arg.pages; 4492 4575 args->pagelen = rqstp->rq_arg.page_len; 4576 + args->tail = false; 4493 4577 args->tmpp = NULL; 4494 4578 args->to_free = NULL; 4495 4579 args->ops = args->iops;
+1 -1
fs/nfsd/nfssvc.c
··· 475 475 return ret; 476 476 } 477 477 478 - static struct svc_serv_ops nfsd_thread_sv_ops = { 478 + static const struct svc_serv_ops nfsd_thread_sv_ops = { 479 479 .svo_shutdown = nfsd_last_thread, 480 480 .svo_function = nfsd, 481 481 .svo_enqueue_xprt = svc_xprt_do_enqueue,
+50
fs/nfsd/xdr4.h
··· 538 538 539 539 struct nfsd4_op { 540 540 int opnum; 541 + const struct nfsd4_operation * opdesc; 541 542 __be32 status; 542 543 union nfsd4_op_u { 543 544 struct nfsd4_access access; ··· 615 614 __be32 * end; 616 615 struct page ** pagelist; 617 616 int pagelen; 617 + bool tail; 618 618 __be32 tmp[8]; 619 619 __be32 * tmpp; 620 620 struct svcxdr_tmpbuf *to_free; ··· 663 661 return argp->opcnt == resp->opcnt; 664 662 } 665 663 664 + const struct nfsd4_operation *OPDESC(struct nfsd4_op *op); 666 665 int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op); 667 666 void warn_on_nonidempotent_op(struct nfsd4_op *op); 668 667 ··· 750 747 extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp, 751 748 struct nfsd4_compound_state *, union nfsd4_op_u *); 752 749 extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr); 750 + 751 + enum nfsd4_op_flags { 752 + ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 753 + ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 754 + ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ 755 + /* For rfc 5661 section 2.6.3.1.1: */ 756 + OP_HANDLES_WRONGSEC = 1 << 3, 757 + OP_IS_PUTFH_LIKE = 1 << 4, 758 + /* 759 + * These are the ops whose result size we estimate before 760 + * encoding, to avoid performing an op then not being able to 761 + * respond or cache a response. This includes writes and setattrs 762 + * as well as the operations usually called "nonidempotent": 763 + */ 764 + OP_MODIFIES_SOMETHING = 1 << 5, 765 + /* 766 + * Cache compounds containing these ops in the xid-based drc: 767 + * We use the DRC for compounds containing non-idempotent 768 + * operations, *except* those that are 4.1-specific (since 769 + * sessions provide their own EOS), and except for stateful 770 + * operations other than setclientid and setclientid_confirm 771 + * (since sequence numbers provide EOS for open, lock, etc in 772 + * the v4.0 case). 773 + */ 774 + OP_CACHEME = 1 << 6, 775 + /* 776 + * These are ops which clear current state id. 777 + */ 778 + OP_CLEAR_STATEID = 1 << 7, 779 + /* Most ops return only an error on failure; some may do more: */ 780 + OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8, 781 + }; 782 + 783 + struct nfsd4_operation { 784 + __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 785 + union nfsd4_op_u *); 786 + void (*op_release)(union nfsd4_op_u *); 787 + u32 op_flags; 788 + char *op_name; 789 + /* Try to get response size before operation */ 790 + u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *); 791 + void (*op_get_currentstateid)(struct nfsd4_compound_state *, 792 + union nfsd4_op_u *); 793 + void (*op_set_currentstateid)(struct nfsd4_compound_state *, 794 + union nfsd4_op_u *); 795 + }; 796 + 753 797 754 798 #endif 755 799
+3 -3
include/linux/sunrpc/svc.h
··· 99 99 100 100 unsigned int sv_nrpools; /* number of thread pools */ 101 101 struct svc_pool * sv_pools; /* array of thread pools */ 102 - struct svc_serv_ops *sv_ops; /* server operations */ 102 + const struct svc_serv_ops *sv_ops; /* server operations */ 103 103 #if defined(CONFIG_SUNRPC_BACKCHANNEL) 104 104 struct list_head sv_cb_list; /* queue for callback requests 105 105 * that arrive over the same ··· 465 465 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); 466 466 int svc_bind(struct svc_serv *serv, struct net *net); 467 467 struct svc_serv *svc_create(struct svc_program *, unsigned int, 468 - struct svc_serv_ops *); 468 + const struct svc_serv_ops *); 469 469 struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv, 470 470 struct svc_pool *pool, int node); 471 471 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, ··· 475 475 unsigned int svc_pool_map_get(void); 476 476 void svc_pool_map_put(void); 477 477 struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, 478 - struct svc_serv_ops *); 478 + const struct svc_serv_ops *); 479 479 int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); 480 480 int svc_set_num_threads_sync(struct svc_serv *, struct svc_pool *, int); 481 481 int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
+2 -2
include/linux/sunrpc/svc_xprt.h
··· 31 31 struct svc_xprt_class { 32 32 const char *xcl_name; 33 33 struct module *xcl_owner; 34 - struct svc_xprt_ops *xcl_ops; 34 + const struct svc_xprt_ops *xcl_ops; 35 35 struct list_head xcl_list; 36 36 u32 xcl_max_payload; 37 37 int xcl_ident; ··· 49 49 50 50 struct svc_xprt { 51 51 struct svc_xprt_class *xpt_class; 52 - struct svc_xprt_ops *xpt_ops; 52 + const struct svc_xprt_ops *xpt_ops; 53 53 struct kref xpt_ref; 54 54 struct list_head xpt_list; 55 55 struct list_head xpt_ready;
+2
include/rdma/rw.h
··· 81 81 int rdma_rw_ctx_post(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, 82 82 struct ib_cqe *cqe, struct ib_send_wr *chain_wr); 83 83 84 + unsigned int rdma_rw_mr_factor(struct ib_device *device, u8 port_num, 85 + unsigned int maxpages); 84 86 void rdma_rw_init_qp(struct ib_device *dev, struct ib_qp_init_attr *attr); 85 87 int rdma_rw_init_mrs(struct ib_qp *qp, struct ib_qp_init_attr *attr); 86 88 void rdma_rw_cleanup_mrs(struct ib_qp *qp);
+3 -3
net/sunrpc/svc.c
··· 421 421 */ 422 422 static struct svc_serv * 423 423 __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, 424 - struct svc_serv_ops *ops) 424 + const struct svc_serv_ops *ops) 425 425 { 426 426 struct svc_serv *serv; 427 427 unsigned int vers; ··· 486 486 487 487 struct svc_serv * 488 488 svc_create(struct svc_program *prog, unsigned int bufsize, 489 - struct svc_serv_ops *ops) 489 + const struct svc_serv_ops *ops) 490 490 { 491 491 return __svc_create(prog, bufsize, /*npools*/1, ops); 492 492 } ··· 494 494 495 495 struct svc_serv * 496 496 svc_create_pooled(struct svc_program *prog, unsigned int bufsize, 497 - struct svc_serv_ops *ops) 497 + const struct svc_serv_ops *ops) 498 498 { 499 499 struct svc_serv *serv; 500 500 unsigned int npools = svc_pool_map_get();
+3 -3
net/sunrpc/svcsock.c
··· 693 693 return svc_create_socket(serv, IPPROTO_UDP, net, sa, salen, flags); 694 694 } 695 695 696 - static struct svc_xprt_ops svc_udp_ops = { 696 + static const struct svc_xprt_ops svc_udp_ops = { 697 697 .xpo_create = svc_udp_create, 698 698 .xpo_recvfrom = svc_udp_recvfrom, 699 699 .xpo_sendto = svc_udp_sendto, ··· 1241 1241 { 1242 1242 } 1243 1243 1244 - static struct svc_xprt_ops svc_tcp_bc_ops = { 1244 + static const struct svc_xprt_ops svc_tcp_bc_ops = { 1245 1245 .xpo_create = svc_bc_tcp_create, 1246 1246 .xpo_detach = svc_bc_tcp_sock_detach, 1247 1247 .xpo_free = svc_bc_sock_free, ··· 1275 1275 } 1276 1276 #endif /* CONFIG_SUNRPC_BACKCHANNEL */ 1277 1277 1278 - static struct svc_xprt_ops svc_tcp_ops = { 1278 + static const struct svc_xprt_ops svc_tcp_ops = { 1279 1279 .xpo_create = svc_tcp_create, 1280 1280 .xpo_recvfrom = svc_tcp_recvfrom, 1281 1281 .xpo_sendto = svc_tcp_sendto,
+20 -96
net/sunrpc/xprtrdma/svc_rdma_rw.c
··· 660 660 return -EIO; 661 661 } 662 662 663 + /* Walk the segments in the Read chunk starting at @p and construct 664 + * RDMA Read operations to pull the chunk to the server. 665 + */ 663 666 static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, 664 667 struct svc_rdma_read_info *info, 665 668 __be32 *p) 666 669 { 667 670 int ret; 668 671 672 + ret = -EINVAL; 669 673 info->ri_chunklen = 0; 670 - while (*p++ != xdr_zero) { 674 + while (*p++ != xdr_zero && be32_to_cpup(p++) == info->ri_position) { 671 675 u32 rs_handle, rs_length; 672 676 u64 rs_offset; 673 677 674 - if (be32_to_cpup(p++) != info->ri_position) 675 - break; 676 678 rs_handle = be32_to_cpup(p++); 677 679 rs_length = be32_to_cpup(p++); 678 680 p = xdr_decode_hyper(p, &rs_offset); ··· 689 687 } 690 688 691 689 return ret; 692 - } 693 - 694 - /* If there is inline content following the Read chunk, append it to 695 - * the page list immediately following the data payload. This has to 696 - * be done after the reader function has determined how many pages 697 - * were consumed for RDMA Read. 698 - * 699 - * On entry, ri_pageno and ri_pageoff point directly to the end of the 700 - * page list. On exit, both have been updated to the new "next byte". 701 - * 702 - * Assumptions: 703 - * - Inline content fits entirely in rq_pages[0] 704 - * - Trailing content is only a handful of bytes 705 - */ 706 - static int svc_rdma_copy_tail(struct svc_rqst *rqstp, 707 - struct svc_rdma_read_info *info) 708 - { 709 - struct svc_rdma_op_ctxt *head = info->ri_readctxt; 710 - unsigned int tail_length, remaining; 711 - u8 *srcp, *destp; 712 - 713 - /* Assert that all inline content fits in page 0. This is an 714 - * implementation limit, not a protocol limit. 715 - */ 716 - if (head->arg.head[0].iov_len > PAGE_SIZE) { 717 - pr_warn_once("svcrdma: too much trailing inline content\n"); 718 - return -EINVAL; 719 - } 720 - 721 - srcp = head->arg.head[0].iov_base; 722 - srcp += info->ri_position; 723 - tail_length = head->arg.head[0].iov_len - info->ri_position; 724 - remaining = tail_length; 725 - 726 - /* If there is room on the last page in the page list, try to 727 - * fit the trailing content there. 728 - */ 729 - if (info->ri_pageoff > 0) { 730 - unsigned int len; 731 - 732 - len = min_t(unsigned int, remaining, 733 - PAGE_SIZE - info->ri_pageoff); 734 - destp = page_address(rqstp->rq_pages[info->ri_pageno]); 735 - destp += info->ri_pageoff; 736 - 737 - memcpy(destp, srcp, len); 738 - srcp += len; 739 - destp += len; 740 - info->ri_pageoff += len; 741 - remaining -= len; 742 - 743 - if (info->ri_pageoff == PAGE_SIZE) { 744 - info->ri_pageno++; 745 - info->ri_pageoff = 0; 746 - } 747 - } 748 - 749 - /* Otherwise, a fresh page is needed. */ 750 - if (remaining) { 751 - head->arg.pages[info->ri_pageno] = 752 - rqstp->rq_pages[info->ri_pageno]; 753 - head->count++; 754 - 755 - destp = page_address(rqstp->rq_pages[info->ri_pageno]); 756 - memcpy(destp, srcp, remaining); 757 - info->ri_pageoff += remaining; 758 - } 759 - 760 - head->arg.page_len += tail_length; 761 - head->arg.len += tail_length; 762 - head->arg.buflen += tail_length; 763 - return 0; 764 690 } 765 691 766 692 /* Construct RDMA Reads to pull over a normal Read chunk. The chunk ··· 715 785 if (ret < 0) 716 786 goto out; 717 787 718 - /* Read chunk may need XDR round-up (see RFC 5666, s. 3.7). 788 + /* Split the Receive buffer between the head and tail 789 + * buffers at Read chunk's position. XDR roundup of the 790 + * chunk is not included in either the pagelist or in 791 + * the tail. 719 792 */ 720 - if (info->ri_chunklen & 3) { 721 - u32 padlen = 4 - (info->ri_chunklen & 3); 793 + head->arg.tail[0].iov_base = 794 + head->arg.head[0].iov_base + info->ri_position; 795 + head->arg.tail[0].iov_len = 796 + head->arg.head[0].iov_len - info->ri_position; 797 + head->arg.head[0].iov_len = info->ri_position; 722 798 723 - info->ri_chunklen += padlen; 724 - 725 - /* NB: data payload always starts on XDR alignment, 726 - * thus the pad can never contain a page boundary. 727 - */ 728 - info->ri_pageoff += padlen; 729 - if (info->ri_pageoff == PAGE_SIZE) { 730 - info->ri_pageno++; 731 - info->ri_pageoff = 0; 732 - } 733 - } 799 + /* Read chunk may need XDR roundup (see RFC 5666, s. 3.7). 800 + * 801 + * NFSv2/3 write decoders need the length of the tail to 802 + * contain the size of the roundup padding. 803 + */ 804 + head->arg.tail[0].iov_len += 4 - (info->ri_chunklen & 3); 734 805 735 806 head->arg.page_len = info->ri_chunklen; 736 807 head->arg.len += info->ri_chunklen; 737 808 head->arg.buflen += info->ri_chunklen; 738 - 739 - if (info->ri_position < head->arg.head[0].iov_len) { 740 - ret = svc_rdma_copy_tail(rqstp, info); 741 - if (ret < 0) 742 - goto out; 743 - } 744 - head->arg.head[0].iov_len = info->ri_position; 745 809 746 810 out: 747 811 return ret;
+27 -13
net/sunrpc/xprtrdma/svc_rdma_transport.c
··· 51 51 #include <linux/workqueue.h> 52 52 #include <rdma/ib_verbs.h> 53 53 #include <rdma/rdma_cm.h> 54 + #include <rdma/rw.h> 54 55 #include <linux/sunrpc/svc_rdma.h> 55 56 #include <linux/export.h> 56 57 #include "xprt_rdma.h" ··· 71 70 static int svc_rdma_secure_port(struct svc_rqst *); 72 71 static void svc_rdma_kill_temp_xprt(struct svc_xprt *); 73 72 74 - static struct svc_xprt_ops svc_rdma_ops = { 73 + static const struct svc_xprt_ops svc_rdma_ops = { 75 74 .xpo_create = svc_rdma_create, 76 75 .xpo_recvfrom = svc_rdma_recvfrom, 77 76 .xpo_sendto = svc_rdma_sendto, ··· 99 98 static void svc_rdma_bc_detach(struct svc_xprt *); 100 99 static void svc_rdma_bc_free(struct svc_xprt *); 101 100 102 - static struct svc_xprt_ops svc_rdma_bc_ops = { 101 + static const struct svc_xprt_ops svc_rdma_bc_ops = { 103 102 .xpo_create = svc_rdma_bc_create, 104 103 .xpo_detach = svc_rdma_bc_detach, 105 104 .xpo_free = svc_rdma_bc_free, ··· 168 167 { 169 168 unsigned int i; 170 169 171 - /* Each RPC/RDMA credit can consume a number of send 172 - * and receive WQEs. One ctxt is allocated for each. 170 + /* Each RPC/RDMA credit can consume one Receive and 171 + * one Send WQE at the same time. 173 172 */ 174 173 i = xprt->sc_sq_depth + xprt->sc_rq_depth; 175 174 ··· 714 713 struct ib_qp_init_attr qp_attr; 715 714 struct ib_device *dev; 716 715 struct sockaddr *sap; 717 - unsigned int i; 716 + unsigned int i, ctxts; 718 717 int ret = 0; 719 718 720 719 listen_rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt); ··· 743 742 newxprt->sc_max_sge = min((size_t)dev->attrs.max_sge, 744 743 (size_t)RPCSVC_MAXPAGES); 745 744 newxprt->sc_max_req_size = svcrdma_max_req_size; 746 - newxprt->sc_max_requests = min_t(u32, dev->attrs.max_qp_wr, 747 - svcrdma_max_requests); 748 - newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests); 749 - newxprt->sc_max_bc_requests = min_t(u32, dev->attrs.max_qp_wr, 750 - svcrdma_max_bc_requests); 745 + newxprt->sc_max_requests = svcrdma_max_requests; 746 + newxprt->sc_max_bc_requests = svcrdma_max_bc_requests; 751 747 newxprt->sc_rq_depth = newxprt->sc_max_requests + 752 748 newxprt->sc_max_bc_requests; 753 - newxprt->sc_sq_depth = newxprt->sc_rq_depth; 749 + if (newxprt->sc_rq_depth > dev->attrs.max_qp_wr) { 750 + pr_warn("svcrdma: reducing receive depth to %d\n", 751 + dev->attrs.max_qp_wr); 752 + newxprt->sc_rq_depth = dev->attrs.max_qp_wr; 753 + newxprt->sc_max_requests = newxprt->sc_rq_depth - 2; 754 + newxprt->sc_max_bc_requests = 2; 755 + } 756 + newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests); 757 + ctxts = rdma_rw_mr_factor(dev, newxprt->sc_port_num, RPCSVC_MAXPAGES); 758 + ctxts *= newxprt->sc_max_requests; 759 + newxprt->sc_sq_depth = newxprt->sc_rq_depth + ctxts; 760 + if (newxprt->sc_sq_depth > dev->attrs.max_qp_wr) { 761 + pr_warn("svcrdma: reducing send depth to %d\n", 762 + dev->attrs.max_qp_wr); 763 + newxprt->sc_sq_depth = dev->attrs.max_qp_wr; 764 + } 754 765 atomic_set(&newxprt->sc_sq_avail, newxprt->sc_sq_depth); 755 766 756 767 if (!svc_rdma_prealloc_ctxts(newxprt)) ··· 797 784 qp_attr.event_handler = qp_event_handler; 798 785 qp_attr.qp_context = &newxprt->sc_xprt; 799 786 qp_attr.port_num = newxprt->sc_port_num; 800 - qp_attr.cap.max_rdma_ctxs = newxprt->sc_max_requests; 801 - qp_attr.cap.max_send_wr = newxprt->sc_sq_depth; 787 + qp_attr.cap.max_rdma_ctxs = ctxts; 788 + qp_attr.cap.max_send_wr = newxprt->sc_sq_depth - ctxts; 802 789 qp_attr.cap.max_recv_wr = newxprt->sc_rq_depth; 803 790 qp_attr.cap.max_send_sge = newxprt->sc_max_sge; 804 791 qp_attr.cap.max_recv_sge = newxprt->sc_max_sge; ··· 866 853 dprintk(" remote address : %pIS:%u\n", sap, rpc_get_port(sap)); 867 854 dprintk(" max_sge : %d\n", newxprt->sc_max_sge); 868 855 dprintk(" sq_depth : %d\n", newxprt->sc_sq_depth); 856 + dprintk(" rdma_rw_ctxs : %d\n", ctxts); 869 857 dprintk(" max_requests : %d\n", newxprt->sc_max_requests); 870 858 dprintk(" ord : %d\n", newxprt->sc_ord); 871 859