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 'nfs-for-3.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull more NFS client updates from Trond Myklebust:
"Highlights include:

- Fix a use-after-free in decode_cb_sequence_args()
- Fix a compile error when #undef CONFIG_PROC_FS
- NFSv4.1 backchannel spinlocking issue
- Cleanups in the NFS unstable write code requested by Linus
- NFSv4.1 fix issues when the server denies our backchannel request
- Cleanups in create_session and bind_conn_to_session"

* tag 'nfs-for-3.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFSv4.1: Clean up bind_conn_to_session
NFSv4.1: Always set up a forward channel when binding the session
NFSv4.1: Don't set up a backchannel if the server didn't agree to do so
NFSv4.1: Clean up create_session
pnfs: Refactor the *_layout_mark_request_commit to use pnfs_layout_mark_request_commit
NFSv4: Kill unused nfs_inode->delegation_state field
NFS: struct nfs_commit_info.lock must always point to inode->i_lock
nfs: Can call nfs_clear_page_commit() instead
nfs: Provide and use helper functions for marking a page as unstable
SUNRPC: Always manipulate rpc_rqst::rq_bc_pa_list under xprt->bc_pa_lock
SUNRPC: Fix a compile error when #undef CONFIG_PROC_FS
NFSv4.1: Convert open-coded array allocation calls to kmalloc_array()
NFSv4.1: Fix a kfree() of uninitialised pointers in decode_cb_sequence_args

+165 -158
+2
fs/nfs/callback_proc.c
··· 427 427 if (clp == NULL) 428 428 goto out; 429 429 430 + if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) 431 + goto out; 430 432 tbl = &clp->cl_session->bc_slot_table; 431 433 432 434 spin_lock(&tbl->slot_tbl_lock);
+5 -3
fs/nfs/callback_xdr.c
··· 313 313 goto out; 314 314 } 315 315 316 - args->devs = kmalloc(n * sizeof(*args->devs), GFP_KERNEL); 316 + args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL); 317 317 if (!args->devs) { 318 318 status = htonl(NFS4ERR_DELAY); 319 319 goto out; ··· 415 415 rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); 416 416 if (unlikely(p == NULL)) 417 417 goto out; 418 - rc_list->rcl_refcalls = kmalloc(rc_list->rcl_nrefcalls * 418 + rc_list->rcl_refcalls = kmalloc_array(rc_list->rcl_nrefcalls, 419 419 sizeof(*rc_list->rcl_refcalls), 420 420 GFP_KERNEL); 421 421 if (unlikely(rc_list->rcl_refcalls == NULL)) ··· 464 464 465 465 for (i = 0; i < args->csa_nrclists; i++) { 466 466 status = decode_rc_list(xdr, &args->csa_rclists[i]); 467 - if (status) 467 + if (status) { 468 + args->csa_nrclists = i; 468 469 goto out_free; 470 + } 469 471 } 470 472 } 471 473 status = 0;
-4
fs/nfs/delegation.c
··· 180 180 delegation->cred = get_rpccred(cred); 181 181 clear_bit(NFS_DELEGATION_NEED_RECLAIM, 182 182 &delegation->flags); 183 - NFS_I(inode)->delegation_state = delegation->type; 184 183 spin_unlock(&delegation->lock); 185 184 put_rpccred(oldcred); 186 185 rcu_read_unlock(); ··· 274 275 set_bit(NFS_DELEGATION_RETURNING, &delegation->flags); 275 276 list_del_rcu(&delegation->super_list); 276 277 delegation->inode = NULL; 277 - nfsi->delegation_state = 0; 278 278 rcu_assign_pointer(nfsi->delegation, NULL); 279 279 spin_unlock(&delegation->lock); 280 280 return delegation; ··· 353 355 &delegation->stateid)) { 354 356 nfs_update_inplace_delegation(old_delegation, 355 357 delegation); 356 - nfsi->delegation_state = old_delegation->type; 357 358 goto out; 358 359 } 359 360 /* ··· 376 379 goto out; 377 380 } 378 381 list_add_rcu(&delegation->super_list, &server->delegations); 379 - nfsi->delegation_state = delegation->type; 380 382 rcu_assign_pointer(nfsi->delegation, delegation); 381 383 delegation = NULL; 382 384
+1 -1
fs/nfs/direct.c
··· 283 283 void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, 284 284 struct nfs_direct_req *dreq) 285 285 { 286 - cinfo->lock = &dreq->lock; 286 + cinfo->lock = &dreq->inode->i_lock; 287 287 cinfo->mds = &dreq->mds_cinfo; 288 288 cinfo->ds = &dreq->ds_cinfo; 289 289 cinfo->dreq = dreq;
+10 -43
fs/nfs/filelayout/filelayout.c
··· 960 960 { 961 961 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg); 962 962 u32 i, j; 963 - struct list_head *list; 964 - struct pnfs_commit_bucket *buckets; 965 963 966 964 if (fl->commit_through_mds) { 967 - list = &cinfo->mds->list; 968 - spin_lock(cinfo->lock); 969 - goto mds_commit; 970 - } 971 - 972 - /* Note that we are calling nfs4_fl_calc_j_index on each page 973 - * that ends up being committed to a data server. An attractive 974 - * alternative is to add a field to nfs_write_data and nfs_page 975 - * to store the value calculated in filelayout_write_pagelist 976 - * and just use that here. 977 - */ 978 - j = nfs4_fl_calc_j_index(lseg, req_offset(req)); 979 - i = select_bucket_index(fl, j); 980 - spin_lock(cinfo->lock); 981 - buckets = cinfo->ds->buckets; 982 - list = &buckets[i].written; 983 - if (list_empty(list)) { 984 - /* Non-empty buckets hold a reference on the lseg. That ref 985 - * is normally transferred to the COMMIT call and released 986 - * there. It could also be released if the last req is pulled 987 - * off due to a rewrite, in which case it will be done in 988 - * pnfs_generic_clear_request_commit 965 + nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo); 966 + } else { 967 + /* Note that we are calling nfs4_fl_calc_j_index on each page 968 + * that ends up being committed to a data server. An attractive 969 + * alternative is to add a field to nfs_write_data and nfs_page 970 + * to store the value calculated in filelayout_write_pagelist 971 + * and just use that here. 989 972 */ 990 - buckets[i].wlseg = pnfs_get_lseg(lseg); 991 - } 992 - set_bit(PG_COMMIT_TO_DS, &req->wb_flags); 993 - cinfo->ds->nwritten++; 994 - 995 - mds_commit: 996 - /* nfs_request_add_commit_list(). We need to add req to list without 997 - * dropping cinfo lock. 998 - */ 999 - set_bit(PG_CLEAN, &(req)->wb_flags); 1000 - nfs_list_add_request(req, list); 1001 - cinfo->mds->ncommit++; 1002 - spin_unlock(cinfo->lock); 1003 - if (!cinfo->dreq) { 1004 - inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1005 - inc_bdi_stat(inode_to_bdi(page_file_mapping(req->wb_page)->host), 1006 - BDI_RECLAIMABLE); 1007 - __mark_inode_dirty(req->wb_context->dentry->d_inode, 1008 - I_DIRTY_DATASYNC); 973 + j = nfs4_fl_calc_j_index(lseg, req_offset(req)); 974 + i = select_bucket_index(fl, j); 975 + pnfs_layout_mark_request_commit(req, lseg, cinfo, i); 1009 976 } 1010 977 } 1011 978
+1 -42
fs/nfs/flexfilelayout/flexfilelayout.c
··· 1332 1332 return PNFS_ATTEMPTED; 1333 1333 } 1334 1334 1335 - static void 1336 - ff_layout_mark_request_commit(struct nfs_page *req, 1337 - struct pnfs_layout_segment *lseg, 1338 - struct nfs_commit_info *cinfo, 1339 - u32 ds_commit_idx) 1340 - { 1341 - struct list_head *list; 1342 - struct pnfs_commit_bucket *buckets; 1343 - 1344 - spin_lock(cinfo->lock); 1345 - buckets = cinfo->ds->buckets; 1346 - list = &buckets[ds_commit_idx].written; 1347 - if (list_empty(list)) { 1348 - /* Non-empty buckets hold a reference on the lseg. That ref 1349 - * is normally transferred to the COMMIT call and released 1350 - * there. It could also be released if the last req is pulled 1351 - * off due to a rewrite, in which case it will be done in 1352 - * pnfs_common_clear_request_commit 1353 - */ 1354 - WARN_ON_ONCE(buckets[ds_commit_idx].wlseg != NULL); 1355 - buckets[ds_commit_idx].wlseg = pnfs_get_lseg(lseg); 1356 - } 1357 - set_bit(PG_COMMIT_TO_DS, &req->wb_flags); 1358 - cinfo->ds->nwritten++; 1359 - 1360 - /* nfs_request_add_commit_list(). We need to add req to list without 1361 - * dropping cinfo lock. 1362 - */ 1363 - set_bit(PG_CLEAN, &(req)->wb_flags); 1364 - nfs_list_add_request(req, list); 1365 - cinfo->mds->ncommit++; 1366 - spin_unlock(cinfo->lock); 1367 - if (!cinfo->dreq) { 1368 - inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1369 - inc_bdi_stat(inode_to_bdi(page_file_mapping(req->wb_page)->host), 1370 - BDI_RECLAIMABLE); 1371 - __mark_inode_dirty(req->wb_context->dentry->d_inode, 1372 - I_DIRTY_DATASYNC); 1373 - } 1374 - } 1375 - 1376 1335 static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i) 1377 1336 { 1378 1337 return i; ··· 1499 1540 .pg_write_ops = &ff_layout_pg_write_ops, 1500 1541 .get_ds_info = ff_layout_get_ds_info, 1501 1542 .free_deviceid_node = ff_layout_free_deveiceid_node, 1502 - .mark_request_commit = ff_layout_mark_request_commit, 1543 + .mark_request_commit = pnfs_layout_mark_request_commit, 1503 1544 .clear_request_commit = pnfs_generic_clear_request_commit, 1504 1545 .scan_commit_lists = pnfs_generic_scan_commit_lists, 1505 1546 .recover_commit_reqs = pnfs_generic_recover_commit_reqs,
-1
fs/nfs/inode.c
··· 1775 1775 #if IS_ENABLED(CONFIG_NFS_V4) 1776 1776 INIT_LIST_HEAD(&nfsi->open_states); 1777 1777 nfsi->delegation = NULL; 1778 - nfsi->delegation_state = 0; 1779 1778 init_rwsem(&nfsi->rwsem); 1780 1779 nfsi->layout = NULL; 1781 1780 #endif
+13
fs/nfs/internal.h
··· 598 598 } 599 599 600 600 /* 601 + * Record the page as unstable and mark its inode as dirty. 602 + */ 603 + static inline 604 + void nfs_mark_page_unstable(struct page *page) 605 + { 606 + struct inode *inode = page_file_mapping(page)->host; 607 + 608 + inc_zone_page_state(page, NR_UNSTABLE_NFS); 609 + inc_bdi_stat(inode_to_bdi(inode), BDI_RECLAIMABLE); 610 + __mark_inode_dirty(inode, I_DIRTY_DATASYNC); 611 + } 612 + 613 + /* 601 614 * Determine the number of bytes of data the page contains 602 615 */ 603 616 static inline
+48 -27
fs/nfs/nfs4proc.c
··· 6648 6648 int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred) 6649 6649 { 6650 6650 int status; 6651 + struct nfs41_bind_conn_to_session_args args = { 6652 + .client = clp, 6653 + .dir = NFS4_CDFC4_FORE_OR_BOTH, 6654 + }; 6651 6655 struct nfs41_bind_conn_to_session_res res; 6652 6656 struct rpc_message msg = { 6653 6657 .rpc_proc = 6654 6658 &nfs4_procedures[NFSPROC4_CLNT_BIND_CONN_TO_SESSION], 6655 - .rpc_argp = clp, 6659 + .rpc_argp = &args, 6656 6660 .rpc_resp = &res, 6657 6661 .rpc_cred = cred, 6658 6662 }; 6659 6663 6660 6664 dprintk("--> %s\n", __func__); 6661 6665 6662 - res.session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); 6663 - if (unlikely(res.session == NULL)) { 6664 - status = -ENOMEM; 6665 - goto out; 6666 - } 6666 + nfs4_copy_sessionid(&args.sessionid, &clp->cl_session->sess_id); 6667 + if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) 6668 + args.dir = NFS4_CDFC4_FORE; 6667 6669 6668 6670 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 6669 6671 trace_nfs4_bind_conn_to_session(clp, status); 6670 6672 if (status == 0) { 6671 - if (memcmp(res.session->sess_id.data, 6673 + if (memcmp(res.sessionid.data, 6672 6674 clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) { 6673 6675 dprintk("NFS: %s: Session ID mismatch\n", __func__); 6674 6676 status = -EIO; 6675 - goto out_session; 6677 + goto out; 6676 6678 } 6677 - if (res.dir != NFS4_CDFS4_BOTH) { 6679 + if ((res.dir & args.dir) != res.dir || res.dir == 0) { 6678 6680 dprintk("NFS: %s: Unexpected direction from server\n", 6679 6681 __func__); 6680 6682 status = -EIO; 6681 - goto out_session; 6683 + goto out; 6682 6684 } 6683 - if (res.use_conn_in_rdma_mode) { 6685 + if (res.use_conn_in_rdma_mode != args.use_conn_in_rdma_mode) { 6684 6686 dprintk("NFS: %s: Server returned RDMA mode = true\n", 6685 6687 __func__); 6686 6688 status = -EIO; 6687 - goto out_session; 6689 + goto out; 6688 6690 } 6689 6691 } 6690 - out_session: 6691 - kfree(res.session); 6692 6692 out: 6693 6693 dprintk("<-- %s status= %d\n", __func__, status); 6694 6694 return status; ··· 7166 7166 args->bc_attrs.max_reqs); 7167 7167 } 7168 7168 7169 - static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args, struct nfs4_session *session) 7169 + static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args, 7170 + struct nfs41_create_session_res *res) 7170 7171 { 7171 7172 struct nfs4_channel_attrs *sent = &args->fc_attrs; 7172 - struct nfs4_channel_attrs *rcvd = &session->fc_attrs; 7173 + struct nfs4_channel_attrs *rcvd = &res->fc_attrs; 7173 7174 7174 7175 if (rcvd->max_resp_sz > sent->max_resp_sz) 7175 7176 return -EINVAL; ··· 7189 7188 return 0; 7190 7189 } 7191 7190 7192 - static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args, struct nfs4_session *session) 7191 + static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args, 7192 + struct nfs41_create_session_res *res) 7193 7193 { 7194 7194 struct nfs4_channel_attrs *sent = &args->bc_attrs; 7195 - struct nfs4_channel_attrs *rcvd = &session->bc_attrs; 7195 + struct nfs4_channel_attrs *rcvd = &res->bc_attrs; 7196 7196 7197 + if (!(res->flags & SESSION4_BACK_CHAN)) 7198 + goto out; 7197 7199 if (rcvd->max_rqst_sz > sent->max_rqst_sz) 7198 7200 return -EINVAL; 7199 7201 if (rcvd->max_resp_sz < sent->max_resp_sz) ··· 7208 7204 return -EINVAL; 7209 7205 if (rcvd->max_reqs != sent->max_reqs) 7210 7206 return -EINVAL; 7207 + out: 7211 7208 return 0; 7212 7209 } 7213 7210 7214 7211 static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args, 7215 - struct nfs4_session *session) 7212 + struct nfs41_create_session_res *res) 7216 7213 { 7217 7214 int ret; 7218 7215 7219 - ret = nfs4_verify_fore_channel_attrs(args, session); 7216 + ret = nfs4_verify_fore_channel_attrs(args, res); 7220 7217 if (ret) 7221 7218 return ret; 7222 - return nfs4_verify_back_channel_attrs(args, session); 7219 + return nfs4_verify_back_channel_attrs(args, res); 7220 + } 7221 + 7222 + static void nfs4_update_session(struct nfs4_session *session, 7223 + struct nfs41_create_session_res *res) 7224 + { 7225 + nfs4_copy_sessionid(&session->sess_id, &res->sessionid); 7226 + session->flags = res->flags; 7227 + memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs)); 7228 + if (res->flags & SESSION4_BACK_CHAN) 7229 + memcpy(&session->bc_attrs, &res->bc_attrs, 7230 + sizeof(session->bc_attrs)); 7223 7231 } 7224 7232 7225 7233 static int _nfs4_proc_create_session(struct nfs_client *clp, ··· 7240 7224 struct nfs4_session *session = clp->cl_session; 7241 7225 struct nfs41_create_session_args args = { 7242 7226 .client = clp, 7227 + .clientid = clp->cl_clientid, 7228 + .seqid = clp->cl_seqid, 7243 7229 .cb_program = NFS4_CALLBACK, 7244 7230 }; 7245 - struct nfs41_create_session_res res = { 7246 - .client = clp, 7247 - }; 7231 + struct nfs41_create_session_res res; 7232 + 7248 7233 struct rpc_message msg = { 7249 7234 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION], 7250 7235 .rpc_argp = &args, ··· 7262 7245 7263 7246 if (!status) { 7264 7247 /* Verify the session's negotiated channel_attrs values */ 7265 - status = nfs4_verify_channel_attrs(&args, session); 7248 + status = nfs4_verify_channel_attrs(&args, &res); 7266 7249 /* Increment the clientid slot sequence id */ 7267 - clp->cl_seqid++; 7250 + if (clp->cl_seqid == res.seqid) 7251 + clp->cl_seqid++; 7252 + if (status) 7253 + goto out; 7254 + nfs4_update_session(session, &res); 7268 7255 } 7269 - 7256 + out: 7270 7257 return status; 7271 7258 } 7272 7259
+1 -1
fs/nfs/nfs4session.c
··· 450 450 tbl = &ses->fc_slot_table; 451 451 tbl->session = ses; 452 452 status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); 453 - if (status) /* -ENOMEM */ 453 + if (status || !(ses->flags & SESSION4_BACK_CHAN)) /* -ENOMEM */ 454 454 return status; 455 455 /* Back channel */ 456 456 tbl = &ses->bc_slot_table;
+6
fs/nfs/nfs4session.h
··· 118 118 return 0; 119 119 } 120 120 121 + static inline void nfs4_copy_sessionid(struct nfs4_sessionid *dst, 122 + const struct nfs4_sessionid *src) 123 + { 124 + memcpy(dst->data, src->data, NFS4_MAX_SESSIONID_LEN); 125 + } 126 + 121 127 #ifdef CONFIG_CRC32 122 128 /* 123 129 * nfs_session_id_hash - calculate the crc32 hash for the session id
+15 -17
fs/nfs/nfs4xdr.c
··· 1715 1715 #if defined(CONFIG_NFS_V4_1) 1716 1716 /* NFSv4.1 operations */ 1717 1717 static void encode_bind_conn_to_session(struct xdr_stream *xdr, 1718 - struct nfs4_session *session, 1718 + struct nfs41_bind_conn_to_session_args *args, 1719 1719 struct compound_hdr *hdr) 1720 1720 { 1721 1721 __be32 *p; 1722 1722 1723 1723 encode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION, 1724 1724 decode_bind_conn_to_session_maxsz, hdr); 1725 - encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); 1725 + encode_opaque_fixed(xdr, args->sessionid.data, NFS4_MAX_SESSIONID_LEN); 1726 1726 p = xdr_reserve_space(xdr, 8); 1727 - *p++ = cpu_to_be32(NFS4_CDFC4_BACK_OR_BOTH); 1728 - *p = 0; /* use_conn_in_rdma_mode = False */ 1727 + *p++ = cpu_to_be32(args->dir); 1728 + *p = (args->use_conn_in_rdma_mode) ? cpu_to_be32(1) : cpu_to_be32(0); 1729 1729 } 1730 1730 1731 1731 static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map) ··· 1806 1806 1807 1807 encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr); 1808 1808 p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12); 1809 - p = xdr_encode_hyper(p, clp->cl_clientid); 1810 - *p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */ 1809 + p = xdr_encode_hyper(p, args->clientid); 1810 + *p++ = cpu_to_be32(args->seqid); /*Sequence id */ 1811 1811 *p++ = cpu_to_be32(args->flags); /*flags */ 1812 1812 1813 1813 /* Fore Channel */ ··· 2734 2734 */ 2735 2735 static void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req, 2736 2736 struct xdr_stream *xdr, 2737 - struct nfs_client *clp) 2737 + struct nfs41_bind_conn_to_session_args *args) 2738 2738 { 2739 2739 struct compound_hdr hdr = { 2740 - .minorversion = clp->cl_mvops->minor_version, 2740 + .minorversion = args->client->cl_mvops->minor_version, 2741 2741 }; 2742 2742 2743 2743 encode_compound_hdr(xdr, req, &hdr); 2744 - encode_bind_conn_to_session(xdr, clp->cl_session, &hdr); 2744 + encode_bind_conn_to_session(xdr, args, &hdr); 2745 2745 encode_nops(&hdr); 2746 2746 } 2747 2747 ··· 5613 5613 5614 5614 status = decode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION); 5615 5615 if (!status) 5616 - status = decode_sessionid(xdr, &res->session->sess_id); 5616 + status = decode_sessionid(xdr, &res->sessionid); 5617 5617 if (unlikely(status)) 5618 5618 return status; 5619 5619 ··· 5641 5641 { 5642 5642 __be32 *p; 5643 5643 int status; 5644 - struct nfs_client *clp = res->client; 5645 - struct nfs4_session *session = clp->cl_session; 5646 5644 5647 5645 status = decode_op_hdr(xdr, OP_CREATE_SESSION); 5648 5646 if (!status) 5649 - status = decode_sessionid(xdr, &session->sess_id); 5647 + status = decode_sessionid(xdr, &res->sessionid); 5650 5648 if (unlikely(status)) 5651 5649 return status; 5652 5650 ··· 5652 5654 p = xdr_inline_decode(xdr, 8); 5653 5655 if (unlikely(!p)) 5654 5656 goto out_overflow; 5655 - clp->cl_seqid = be32_to_cpup(p++); 5656 - session->flags = be32_to_cpup(p); 5657 + res->seqid = be32_to_cpup(p++); 5658 + res->flags = be32_to_cpup(p); 5657 5659 5658 5660 /* Channel attributes */ 5659 - status = decode_chan_attrs(xdr, &session->fc_attrs); 5661 + status = decode_chan_attrs(xdr, &res->fc_attrs); 5660 5662 if (!status) 5661 - status = decode_chan_attrs(xdr, &session->bc_attrs); 5663 + status = decode_chan_attrs(xdr, &res->bc_attrs); 5662 5664 return status; 5663 5665 out_overflow: 5664 5666 print_overflow_msg(__func__, xdr);
+4
fs/nfs/pnfs.h
··· 344 344 struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, 345 345 struct xdr_stream *xdr, 346 346 gfp_t gfp_flags); 347 + void pnfs_layout_mark_request_commit(struct nfs_page *req, 348 + struct pnfs_layout_segment *lseg, 349 + struct nfs_commit_info *cinfo, 350 + u32 ds_commit_idx); 347 351 348 352 static inline bool nfs_have_layout(struct inode *inode) 349 353 {
+30
fs/nfs/pnfs_nfs.c
··· 838 838 return NULL; 839 839 } 840 840 EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr); 841 + 842 + void 843 + pnfs_layout_mark_request_commit(struct nfs_page *req, 844 + struct pnfs_layout_segment *lseg, 845 + struct nfs_commit_info *cinfo, 846 + u32 ds_commit_idx) 847 + { 848 + struct list_head *list; 849 + struct pnfs_commit_bucket *buckets; 850 + 851 + spin_lock(cinfo->lock); 852 + buckets = cinfo->ds->buckets; 853 + list = &buckets[ds_commit_idx].written; 854 + if (list_empty(list)) { 855 + /* Non-empty buckets hold a reference on the lseg. That ref 856 + * is normally transferred to the COMMIT call and released 857 + * there. It could also be released if the last req is pulled 858 + * off due to a rewrite, in which case it will be done in 859 + * pnfs_common_clear_request_commit 860 + */ 861 + WARN_ON_ONCE(buckets[ds_commit_idx].wlseg != NULL); 862 + buckets[ds_commit_idx].wlseg = pnfs_get_lseg(lseg); 863 + } 864 + set_bit(PG_COMMIT_TO_DS, &req->wb_flags); 865 + cinfo->ds->nwritten++; 866 + spin_unlock(cinfo->lock); 867 + 868 + nfs_request_add_commit_list(req, list, cinfo); 869 + } 870 + EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
+4 -12
fs/nfs/write.c
··· 789 789 nfs_list_add_request(req, dst); 790 790 cinfo->mds->ncommit++; 791 791 spin_unlock(cinfo->lock); 792 - if (!cinfo->dreq) { 793 - inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 794 - inc_bdi_stat(inode_to_bdi(page_file_mapping(req->wb_page)->host), 795 - BDI_RECLAIMABLE); 796 - __mark_inode_dirty(req->wb_context->dentry->d_inode, 797 - I_DIRTY_DATASYNC); 798 - } 792 + if (!cinfo->dreq) 793 + nfs_mark_page_unstable(req->wb_page); 799 794 } 800 795 EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); 801 796 ··· 1600 1605 req = nfs_list_entry(page_list->next); 1601 1606 nfs_list_remove_request(req); 1602 1607 nfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx); 1603 - if (!cinfo->dreq) { 1604 - dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1605 - dec_bdi_stat(inode_to_bdi(page_file_mapping(req->wb_page)->host), 1606 - BDI_RECLAIMABLE); 1607 - } 1608 + if (!cinfo->dreq) 1609 + nfs_clear_page_commit(req->wb_page); 1608 1610 nfs_unlock_and_release_request(req); 1609 1611 } 1610 1612 }
-1
include/linux/nfs_fs.h
··· 180 180 /* NFSv4 state */ 181 181 struct list_head open_states; 182 182 struct nfs_delegation __rcu *delegation; 183 - fmode_t delegation_state; 184 183 struct rw_semaphore rwsem; 185 184 186 185 /* pNFS layout information */
+16 -3
include/linux/nfs_xdr.h
··· 1167 1167 struct nfstime4 date; 1168 1168 }; 1169 1169 1170 + struct nfs41_bind_conn_to_session_args { 1171 + struct nfs_client *client; 1172 + struct nfs4_sessionid sessionid; 1173 + u32 dir; 1174 + bool use_conn_in_rdma_mode; 1175 + }; 1176 + 1170 1177 struct nfs41_bind_conn_to_session_res { 1171 - struct nfs4_session *session; 1178 + struct nfs4_sessionid sessionid; 1172 1179 u32 dir; 1173 1180 bool use_conn_in_rdma_mode; 1174 1181 }; ··· 1192 1185 1193 1186 struct nfs41_create_session_args { 1194 1187 struct nfs_client *client; 1188 + u64 clientid; 1189 + uint32_t seqid; 1195 1190 uint32_t flags; 1196 1191 uint32_t cb_program; 1197 1192 struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ ··· 1201 1192 }; 1202 1193 1203 1194 struct nfs41_create_session_res { 1204 - struct nfs_client *client; 1195 + struct nfs4_sessionid sessionid; 1196 + uint32_t seqid; 1197 + uint32_t flags; 1198 + struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ 1199 + struct nfs4_channel_attrs bc_attrs; /* Back Channel */ 1205 1200 }; 1206 1201 1207 1202 struct nfs41_reclaim_complete_args { ··· 1364 1351 }; 1365 1352 1366 1353 struct nfs_commit_info { 1367 - spinlock_t *lock; 1354 + spinlock_t *lock; /* inode->i_lock */ 1368 1355 struct nfs_mds_commit_info *mds; 1369 1356 struct pnfs_ds_commit_info *ds; 1370 1357 struct nfs_direct_req *dreq; /* O_DIRECT request */
+5 -2
include/linux/sunrpc/metrics.h
··· 89 89 static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } 90 90 static inline void rpc_count_iostats(const struct rpc_task *task, 91 91 struct rpc_iostats *stats) {} 92 - static inline void rpc_count_iostats_metrics(const struct rpc_task *, 93 - struct rpc_iostats *) {} 92 + static inline void rpc_count_iostats_metrics(const struct rpc_task *task, 93 + struct rpc_iostats *stats) 94 + { 95 + } 96 + 94 97 static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} 95 98 static inline void rpc_free_iostats(struct rpc_iostats *stats) {} 96 99
+4 -1
net/sunrpc/backchannel_rqst.c
··· 309 309 struct rpc_xprt *xprt = req->rq_xprt; 310 310 struct svc_serv *bc_serv = xprt->bc_serv; 311 311 312 + spin_lock(&xprt->bc_pa_lock); 313 + list_del(&req->rq_bc_pa_list); 314 + spin_unlock(&xprt->bc_pa_lock); 315 + 312 316 req->rq_private_buf.len = copied; 313 317 set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); 314 318 315 319 dprintk("RPC: add callback request to list\n"); 316 320 spin_lock(&bc_serv->sv_cb_lock); 317 - list_del(&req->rq_bc_pa_list); 318 321 list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); 319 322 wake_up(&bc_serv->sv_cb_waitq); 320 323 spin_unlock(&bc_serv->sv_cb_lock);