diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 17:02:59 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 17:02:59 -0500 |
| commit | 24a52e412ef22989b63c35428652598dc995812c (patch) | |
| tree | d8174bc4dfb2b7913896ef46f4366087da8ca42c | |
| parent | cd50b70ccd5c87794ec28bfb87b7fba9961eb0ae (diff) | |
| parent | 71a097c6de9a49afd0f96b3ecef70c4eb04efde7 (diff) | |
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
| -rw-r--r-- | fs/nfs/callback_proc.c | 2 | ||||
| -rw-r--r-- | fs/nfs/callback_xdr.c | 8 | ||||
| -rw-r--r-- | fs/nfs/delegation.c | 4 | ||||
| -rw-r--r-- | fs/nfs/direct.c | 2 | ||||
| -rw-r--r-- | fs/nfs/filelayout/filelayout.c | 53 | ||||
| -rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 43 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 1 | ||||
| -rw-r--r-- | fs/nfs/internal.h | 13 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 75 | ||||
| -rw-r--r-- | fs/nfs/nfs4session.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs4session.h | 6 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 32 | ||||
| -rw-r--r-- | fs/nfs/pnfs.h | 4 | ||||
| -rw-r--r-- | fs/nfs/pnfs_nfs.c | 30 | ||||
| -rw-r--r-- | fs/nfs/write.c | 16 | ||||
| -rw-r--r-- | include/linux/nfs_fs.h | 1 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 19 | ||||
| -rw-r--r-- | include/linux/sunrpc/metrics.h | 7 | ||||
| -rw-r--r-- | net/sunrpc/backchannel_rqst.c | 5 |
19 files changed, 165 insertions, 158 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index e36a9d78ea49..197806fb87ff 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
| @@ -427,6 +427,8 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, | |||
| 427 | if (clp == NULL) | 427 | if (clp == NULL) |
| 428 | goto out; | 428 | goto out; |
| 429 | 429 | ||
| 430 | if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) | ||
| 431 | goto out; | ||
| 430 | tbl = &clp->cl_session->bc_slot_table; | 432 | tbl = &clp->cl_session->bc_slot_table; |
| 431 | 433 | ||
| 432 | spin_lock(&tbl->slot_tbl_lock); | 434 | spin_lock(&tbl->slot_tbl_lock); |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index f4ccfe6521ec..19ca95cdfd9b 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
| @@ -313,7 +313,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, | |||
| 313 | goto out; | 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 | if (!args->devs) { | 317 | if (!args->devs) { |
| 318 | status = htonl(NFS4ERR_DELAY); | 318 | status = htonl(NFS4ERR_DELAY); |
| 319 | goto out; | 319 | goto out; |
| @@ -415,7 +415,7 @@ static __be32 decode_rc_list(struct xdr_stream *xdr, | |||
| 415 | rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); | 415 | rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); |
| 416 | if (unlikely(p == NULL)) | 416 | if (unlikely(p == NULL)) |
| 417 | goto out; | 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 | sizeof(*rc_list->rcl_refcalls), | 419 | sizeof(*rc_list->rcl_refcalls), |
| 420 | GFP_KERNEL); | 420 | GFP_KERNEL); |
| 421 | if (unlikely(rc_list->rcl_refcalls == NULL)) | 421 | if (unlikely(rc_list->rcl_refcalls == NULL)) |
| @@ -464,8 +464,10 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, | |||
| 464 | 464 | ||
| 465 | for (i = 0; i < args->csa_nrclists; i++) { | 465 | for (i = 0; i < args->csa_nrclists; i++) { |
| 466 | status = decode_rc_list(xdr, &args->csa_rclists[i]); | 466 | status = decode_rc_list(xdr, &args->csa_rclists[i]); |
| 467 | if (status) | 467 | if (status) { |
| 468 | args->csa_nrclists = i; | ||
| 468 | goto out_free; | 469 | goto out_free; |
| 470 | } | ||
| 469 | } | 471 | } |
| 470 | } | 472 | } |
| 471 | status = 0; | 473 | status = 0; |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index da5433230bb1..a1f0685b42ff 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
| @@ -180,7 +180,6 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, | |||
| 180 | delegation->cred = get_rpccred(cred); | 180 | delegation->cred = get_rpccred(cred); |
| 181 | clear_bit(NFS_DELEGATION_NEED_RECLAIM, | 181 | clear_bit(NFS_DELEGATION_NEED_RECLAIM, |
| 182 | &delegation->flags); | 182 | &delegation->flags); |
| 183 | NFS_I(inode)->delegation_state = delegation->type; | ||
| 184 | spin_unlock(&delegation->lock); | 183 | spin_unlock(&delegation->lock); |
| 185 | put_rpccred(oldcred); | 184 | put_rpccred(oldcred); |
| 186 | rcu_read_unlock(); | 185 | rcu_read_unlock(); |
| @@ -275,7 +274,6 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi, | |||
| 275 | set_bit(NFS_DELEGATION_RETURNING, &delegation->flags); | 274 | set_bit(NFS_DELEGATION_RETURNING, &delegation->flags); |
| 276 | list_del_rcu(&delegation->super_list); | 275 | list_del_rcu(&delegation->super_list); |
| 277 | delegation->inode = NULL; | 276 | delegation->inode = NULL; |
| 278 | nfsi->delegation_state = 0; | ||
| 279 | rcu_assign_pointer(nfsi->delegation, NULL); | 277 | rcu_assign_pointer(nfsi->delegation, NULL); |
| 280 | spin_unlock(&delegation->lock); | 278 | spin_unlock(&delegation->lock); |
| 281 | return delegation; | 279 | return delegation; |
| @@ -355,7 +353,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct | |||
| 355 | &delegation->stateid)) { | 353 | &delegation->stateid)) { |
| 356 | nfs_update_inplace_delegation(old_delegation, | 354 | nfs_update_inplace_delegation(old_delegation, |
| 357 | delegation); | 355 | delegation); |
| 358 | nfsi->delegation_state = old_delegation->type; | ||
| 359 | goto out; | 356 | goto out; |
| 360 | } | 357 | } |
| 361 | /* | 358 | /* |
| @@ -379,7 +376,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct | |||
| 379 | goto out; | 376 | goto out; |
| 380 | } | 377 | } |
| 381 | list_add_rcu(&delegation->super_list, &server->delegations); | 378 | list_add_rcu(&delegation->super_list, &server->delegations); |
| 382 | nfsi->delegation_state = delegation->type; | ||
| 383 | rcu_assign_pointer(nfsi->delegation, delegation); | 379 | rcu_assign_pointer(nfsi->delegation, delegation); |
| 384 | delegation = NULL; | 380 | delegation = NULL; |
| 385 | 381 | ||
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 7077521acdf4..e907c8cf732e 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -283,7 +283,7 @@ static void nfs_direct_release_pages(struct page **pages, unsigned int npages) | |||
| 283 | void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, | 283 | void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, |
| 284 | struct nfs_direct_req *dreq) | 284 | struct nfs_direct_req *dreq) |
| 285 | { | 285 | { |
| 286 | cinfo->lock = &dreq->lock; | 286 | cinfo->lock = &dreq->inode->i_lock; |
| 287 | cinfo->mds = &dreq->mds_cinfo; | 287 | cinfo->mds = &dreq->mds_cinfo; |
| 288 | cinfo->ds = &dreq->ds_cinfo; | 288 | cinfo->ds = &dreq->ds_cinfo; |
| 289 | cinfo->dreq = dreq; | 289 | cinfo->dreq = dreq; |
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index 7ae1c263c5cf..91e88a7ecef0 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c | |||
| @@ -960,52 +960,19 @@ filelayout_mark_request_commit(struct nfs_page *req, | |||
| 960 | { | 960 | { |
| 961 | struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg); | 961 | struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg); |
| 962 | u32 i, j; | 962 | u32 i, j; |
| 963 | struct list_head *list; | ||
| 964 | struct pnfs_commit_bucket *buckets; | ||
| 965 | 963 | ||
| 966 | if (fl->commit_through_mds) { | 964 | if (fl->commit_through_mds) { |
| 967 | list = &cinfo->mds->list; | 965 | nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo); |
| 968 | spin_lock(cinfo->lock); | 966 | } else { |
| 969 | goto mds_commit; | 967 | /* Note that we are calling nfs4_fl_calc_j_index on each page |
| 970 | } | 968 | * that ends up being committed to a data server. An attractive |
| 971 | 969 | * alternative is to add a field to nfs_write_data and nfs_page | |
| 972 | /* Note that we are calling nfs4_fl_calc_j_index on each page | 970 | * to store the value calculated in filelayout_write_pagelist |
| 973 | * that ends up being committed to a data server. An attractive | 971 | * and just use that here. |
| 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 | ||
| 989 | */ | 972 | */ |
| 990 | buckets[i].wlseg = pnfs_get_lseg(lseg); | 973 | j = nfs4_fl_calc_j_index(lseg, req_offset(req)); |
| 991 | } | 974 | i = select_bucket_index(fl, j); |
| 992 | set_bit(PG_COMMIT_TO_DS, &req->wb_flags); | 975 | pnfs_layout_mark_request_commit(req, lseg, cinfo, i); |
| 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); | ||
| 1009 | } | 976 | } |
| 1010 | } | 977 | } |
| 1011 | 978 | ||
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index c22ecaa86c1c..315cc68945b9 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c | |||
| @@ -1332,47 +1332,6 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) | |||
| 1332 | return PNFS_ATTEMPTED; | 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 | static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i) | 1335 | static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i) |
| 1377 | { | 1336 | { |
| 1378 | return i; | 1337 | return i; |
| @@ -1540,7 +1499,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = { | |||
| 1540 | .pg_write_ops = &ff_layout_pg_write_ops, | 1499 | .pg_write_ops = &ff_layout_pg_write_ops, |
| 1541 | .get_ds_info = ff_layout_get_ds_info, | 1500 | .get_ds_info = ff_layout_get_ds_info, |
| 1542 | .free_deviceid_node = ff_layout_free_deveiceid_node, | 1501 | .free_deviceid_node = ff_layout_free_deveiceid_node, |
| 1543 | .mark_request_commit = ff_layout_mark_request_commit, | 1502 | .mark_request_commit = pnfs_layout_mark_request_commit, |
| 1544 | .clear_request_commit = pnfs_generic_clear_request_commit, | 1503 | .clear_request_commit = pnfs_generic_clear_request_commit, |
| 1545 | .scan_commit_lists = pnfs_generic_scan_commit_lists, | 1504 | .scan_commit_lists = pnfs_generic_scan_commit_lists, |
| 1546 | .recover_commit_reqs = pnfs_generic_recover_commit_reqs, | 1505 | .recover_commit_reqs = pnfs_generic_recover_commit_reqs, |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index e4f0dcef8f54..83107be3dd01 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -1775,7 +1775,6 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) | |||
| 1775 | #if IS_ENABLED(CONFIG_NFS_V4) | 1775 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 1776 | INIT_LIST_HEAD(&nfsi->open_states); | 1776 | INIT_LIST_HEAD(&nfsi->open_states); |
| 1777 | nfsi->delegation = NULL; | 1777 | nfsi->delegation = NULL; |
| 1778 | nfsi->delegation_state = 0; | ||
| 1779 | init_rwsem(&nfsi->rwsem); | 1778 | init_rwsem(&nfsi->rwsem); |
| 1780 | nfsi->layout = NULL; | 1779 | nfsi->layout = NULL; |
| 1781 | #endif | 1780 | #endif |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 212b8c883d22..b802fb3a2d99 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
| @@ -598,6 +598,19 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) | |||
| 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 | * Determine the number of bytes of data the page contains | 614 | * Determine the number of bytes of data the page contains |
| 602 | */ | 615 | */ |
| 603 | static inline | 616 | static inline |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2e7c9f7a6f7c..88180ac5ea0e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -6648,47 +6648,47 @@ nfs41_same_server_scope(struct nfs41_server_scope *a, | |||
| 6648 | int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred) | 6648 | int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred) |
| 6649 | { | 6649 | { |
| 6650 | int status; | 6650 | int status; |
| 6651 | struct nfs41_bind_conn_to_session_args args = { | ||
| 6652 | .client = clp, | ||
| 6653 | .dir = NFS4_CDFC4_FORE_OR_BOTH, | ||
| 6654 | }; | ||
| 6651 | struct nfs41_bind_conn_to_session_res res; | 6655 | struct nfs41_bind_conn_to_session_res res; |
| 6652 | struct rpc_message msg = { | 6656 | struct rpc_message msg = { |
| 6653 | .rpc_proc = | 6657 | .rpc_proc = |
| 6654 | &nfs4_procedures[NFSPROC4_CLNT_BIND_CONN_TO_SESSION], | 6658 | &nfs4_procedures[NFSPROC4_CLNT_BIND_CONN_TO_SESSION], |
| 6655 | .rpc_argp = clp, | 6659 | .rpc_argp = &args, |
| 6656 | .rpc_resp = &res, | 6660 | .rpc_resp = &res, |
| 6657 | .rpc_cred = cred, | 6661 | .rpc_cred = cred, |
| 6658 | }; | 6662 | }; |
| 6659 | 6663 | ||
| 6660 | dprintk("--> %s\n", __func__); | 6664 | dprintk("--> %s\n", __func__); |
| 6661 | 6665 | ||
| 6662 | res.session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); | 6666 | nfs4_copy_sessionid(&args.sessionid, &clp->cl_session->sess_id); |
| 6663 | if (unlikely(res.session == NULL)) { | 6667 | if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) |
| 6664 | status = -ENOMEM; | 6668 | args.dir = NFS4_CDFC4_FORE; |
| 6665 | goto out; | ||
| 6666 | } | ||
| 6667 | 6669 | ||
| 6668 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); | 6670 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
| 6669 | trace_nfs4_bind_conn_to_session(clp, status); | 6671 | trace_nfs4_bind_conn_to_session(clp, status); |
| 6670 | if (status == 0) { | 6672 | if (status == 0) { |
| 6671 | if (memcmp(res.session->sess_id.data, | 6673 | if (memcmp(res.sessionid.data, |
| 6672 | clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) { | 6674 | clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) { |
| 6673 | dprintk("NFS: %s: Session ID mismatch\n", __func__); | 6675 | dprintk("NFS: %s: Session ID mismatch\n", __func__); |
| 6674 | status = -EIO; | 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 | dprintk("NFS: %s: Unexpected direction from server\n", | 6680 | dprintk("NFS: %s: Unexpected direction from server\n", |
| 6679 | __func__); | 6681 | __func__); |
| 6680 | status = -EIO; | 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 | dprintk("NFS: %s: Server returned RDMA mode = true\n", | 6686 | dprintk("NFS: %s: Server returned RDMA mode = true\n", |
| 6685 | __func__); | 6687 | __func__); |
| 6686 | status = -EIO; | 6688 | status = -EIO; |
| 6687 | goto out_session; | 6689 | goto out; |
| 6688 | } | 6690 | } |
| 6689 | } | 6691 | } |
| 6690 | out_session: | ||
| 6691 | kfree(res.session); | ||
| 6692 | out: | 6692 | out: |
| 6693 | dprintk("<-- %s status= %d\n", __func__, status); | 6693 | dprintk("<-- %s status= %d\n", __func__, status); |
| 6694 | return status; | 6694 | return status; |
| @@ -7166,10 +7166,11 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) | |||
| 7166 | args->bc_attrs.max_reqs); | 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 | struct nfs4_channel_attrs *sent = &args->fc_attrs; | 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 | if (rcvd->max_resp_sz > sent->max_resp_sz) | 7175 | if (rcvd->max_resp_sz > sent->max_resp_sz) |
| 7175 | return -EINVAL; | 7176 | return -EINVAL; |
| @@ -7188,11 +7189,14 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args | |||
| 7188 | return 0; | 7189 | return 0; |
| 7189 | } | 7190 | } |
| 7190 | 7191 | ||
| 7191 | static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args, struct nfs4_session *session) | 7192 | static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args, |
| 7193 | struct nfs41_create_session_res *res) | ||
| 7192 | { | 7194 | { |
| 7193 | struct nfs4_channel_attrs *sent = &args->bc_attrs; | 7195 | struct nfs4_channel_attrs *sent = &args->bc_attrs; |
| 7194 | struct nfs4_channel_attrs *rcvd = &session->bc_attrs; | 7196 | struct nfs4_channel_attrs *rcvd = &res->bc_attrs; |
| 7195 | 7197 | ||
| 7198 | if (!(res->flags & SESSION4_BACK_CHAN)) | ||
| 7199 | goto out; | ||
| 7196 | if (rcvd->max_rqst_sz > sent->max_rqst_sz) | 7200 | if (rcvd->max_rqst_sz > sent->max_rqst_sz) |
| 7197 | return -EINVAL; | 7201 | return -EINVAL; |
| 7198 | if (rcvd->max_resp_sz < sent->max_resp_sz) | 7202 | if (rcvd->max_resp_sz < sent->max_resp_sz) |
| @@ -7204,18 +7208,30 @@ static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args | |||
| 7204 | return -EINVAL; | 7208 | return -EINVAL; |
| 7205 | if (rcvd->max_reqs != sent->max_reqs) | 7209 | if (rcvd->max_reqs != sent->max_reqs) |
| 7206 | return -EINVAL; | 7210 | return -EINVAL; |
| 7211 | out: | ||
| 7207 | return 0; | 7212 | return 0; |
| 7208 | } | 7213 | } |
| 7209 | 7214 | ||
| 7210 | static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args, | 7215 | static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args, |
| 7211 | struct nfs4_session *session) | 7216 | struct nfs41_create_session_res *res) |
| 7212 | { | 7217 | { |
| 7213 | int ret; | 7218 | int ret; |
| 7214 | 7219 | ||
| 7215 | ret = nfs4_verify_fore_channel_attrs(args, session); | 7220 | ret = nfs4_verify_fore_channel_attrs(args, res); |
| 7216 | if (ret) | 7221 | if (ret) |
| 7217 | return ret; | 7222 | return ret; |
| 7218 | return nfs4_verify_back_channel_attrs(args, session); | 7223 | return nfs4_verify_back_channel_attrs(args, res); |
| 7224 | } | ||
| 7225 | |||
| 7226 | static void nfs4_update_session(struct nfs4_session *session, | ||
| 7227 | struct nfs41_create_session_res *res) | ||
| 7228 | { | ||
| 7229 | nfs4_copy_sessionid(&session->sess_id, &res->sessionid); | ||
| 7230 | session->flags = res->flags; | ||
| 7231 | memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs)); | ||
| 7232 | if (res->flags & SESSION4_BACK_CHAN) | ||
| 7233 | memcpy(&session->bc_attrs, &res->bc_attrs, | ||
| 7234 | sizeof(session->bc_attrs)); | ||
| 7219 | } | 7235 | } |
| 7220 | 7236 | ||
| 7221 | static int _nfs4_proc_create_session(struct nfs_client *clp, | 7237 | static int _nfs4_proc_create_session(struct nfs_client *clp, |
| @@ -7224,11 +7240,12 @@ static int _nfs4_proc_create_session(struct nfs_client *clp, | |||
| 7224 | struct nfs4_session *session = clp->cl_session; | 7240 | struct nfs4_session *session = clp->cl_session; |
| 7225 | struct nfs41_create_session_args args = { | 7241 | struct nfs41_create_session_args args = { |
| 7226 | .client = clp, | 7242 | .client = clp, |
| 7243 | .clientid = clp->cl_clientid, | ||
| 7244 | .seqid = clp->cl_seqid, | ||
| 7227 | .cb_program = NFS4_CALLBACK, | 7245 | .cb_program = NFS4_CALLBACK, |
| 7228 | }; | 7246 | }; |
| 7229 | struct nfs41_create_session_res res = { | 7247 | struct nfs41_create_session_res res; |
| 7230 | .client = clp, | 7248 | |
| 7231 | }; | ||
| 7232 | struct rpc_message msg = { | 7249 | struct rpc_message msg = { |
| 7233 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION], | 7250 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION], |
| 7234 | .rpc_argp = &args, | 7251 | .rpc_argp = &args, |
| @@ -7245,11 +7262,15 @@ static int _nfs4_proc_create_session(struct nfs_client *clp, | |||
| 7245 | 7262 | ||
| 7246 | if (!status) { | 7263 | if (!status) { |
| 7247 | /* Verify the session's negotiated channel_attrs values */ | 7264 | /* Verify the session's negotiated channel_attrs values */ |
| 7248 | status = nfs4_verify_channel_attrs(&args, session); | 7265 | status = nfs4_verify_channel_attrs(&args, &res); |
| 7249 | /* Increment the clientid slot sequence id */ | 7266 | /* Increment the clientid slot sequence id */ |
| 7250 | clp->cl_seqid++; | 7267 | if (clp->cl_seqid == res.seqid) |
| 7268 | clp->cl_seqid++; | ||
| 7269 | if (status) | ||
| 7270 | goto out; | ||
| 7271 | nfs4_update_session(session, &res); | ||
| 7251 | } | 7272 | } |
| 7252 | 7273 | out: | |
| 7253 | return status; | 7274 | return status; |
| 7254 | } | 7275 | } |
| 7255 | 7276 | ||
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index e799dc3c3b1d..e23366effcfb 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c | |||
| @@ -450,7 +450,7 @@ int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | |||
| 450 | tbl = &ses->fc_slot_table; | 450 | tbl = &ses->fc_slot_table; |
| 451 | tbl->session = ses; | 451 | tbl->session = ses; |
| 452 | status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); | 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 | return status; | 454 | return status; |
| 455 | /* Back channel */ | 455 | /* Back channel */ |
| 456 | tbl = &ses->bc_slot_table; | 456 | tbl = &ses->bc_slot_table; |
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index b34ada9bc6a2..fc46c7455898 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h | |||
| @@ -118,6 +118,12 @@ static inline int nfs4_has_persistent_session(const struct nfs_client *clp) | |||
| 118 | return 0; | 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 | #ifdef CONFIG_CRC32 | 127 | #ifdef CONFIG_CRC32 |
| 122 | /* | 128 | /* |
| 123 | * nfs_session_id_hash - calculate the crc32 hash for the session id | 129 | * nfs_session_id_hash - calculate the crc32 hash for the session id |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e23a0a664e12..5c399ec41079 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -1715,17 +1715,17 @@ static void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, stru | |||
| 1715 | #if defined(CONFIG_NFS_V4_1) | 1715 | #if defined(CONFIG_NFS_V4_1) |
| 1716 | /* NFSv4.1 operations */ | 1716 | /* NFSv4.1 operations */ |
| 1717 | static void encode_bind_conn_to_session(struct xdr_stream *xdr, | 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 | struct compound_hdr *hdr) | 1719 | struct compound_hdr *hdr) |
| 1720 | { | 1720 | { |
| 1721 | __be32 *p; | 1721 | __be32 *p; |
| 1722 | 1722 | ||
| 1723 | encode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION, | 1723 | encode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION, |
| 1724 | decode_bind_conn_to_session_maxsz, hdr); | 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 | p = xdr_reserve_space(xdr, 8); | 1726 | p = xdr_reserve_space(xdr, 8); |
| 1727 | *p++ = cpu_to_be32(NFS4_CDFC4_BACK_OR_BOTH); | 1727 | *p++ = cpu_to_be32(args->dir); |
| 1728 | *p = 0; /* use_conn_in_rdma_mode = False */ | 1728 | *p = (args->use_conn_in_rdma_mode) ? cpu_to_be32(1) : cpu_to_be32(0); |
| 1729 | } | 1729 | } |
| 1730 | 1730 | ||
| 1731 | static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map) | 1731 | static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map) |
| @@ -1806,8 +1806,8 @@ static void encode_create_session(struct xdr_stream *xdr, | |||
| 1806 | 1806 | ||
| 1807 | encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr); | 1807 | encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr); |
| 1808 | p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12); | 1808 | p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12); |
| 1809 | p = xdr_encode_hyper(p, clp->cl_clientid); | 1809 | p = xdr_encode_hyper(p, args->clientid); |
| 1810 | *p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */ | 1810 | *p++ = cpu_to_be32(args->seqid); /*Sequence id */ |
| 1811 | *p++ = cpu_to_be32(args->flags); /*flags */ | 1811 | *p++ = cpu_to_be32(args->flags); /*flags */ |
| 1812 | 1812 | ||
| 1813 | /* Fore Channel */ | 1813 | /* Fore Channel */ |
| @@ -2734,14 +2734,14 @@ static void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req, | |||
| 2734 | */ | 2734 | */ |
| 2735 | static void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req, | 2735 | static void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req, |
| 2736 | struct xdr_stream *xdr, | 2736 | struct xdr_stream *xdr, |
| 2737 | struct nfs_client *clp) | 2737 | struct nfs41_bind_conn_to_session_args *args) |
| 2738 | { | 2738 | { |
| 2739 | struct compound_hdr hdr = { | 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 | encode_compound_hdr(xdr, req, &hdr); | 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 | encode_nops(&hdr); | 2745 | encode_nops(&hdr); |
| 2746 | } | 2746 | } |
| 2747 | 2747 | ||
| @@ -5613,7 +5613,7 @@ static int decode_bind_conn_to_session(struct xdr_stream *xdr, | |||
| 5613 | 5613 | ||
| 5614 | status = decode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION); | 5614 | status = decode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION); |
| 5615 | if (!status) | 5615 | if (!status) |
| 5616 | status = decode_sessionid(xdr, &res->session->sess_id); | 5616 | status = decode_sessionid(xdr, &res->sessionid); |
| 5617 | if (unlikely(status)) | 5617 | if (unlikely(status)) |
| 5618 | return status; | 5618 | return status; |
| 5619 | 5619 | ||
| @@ -5641,12 +5641,10 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
| 5641 | { | 5641 | { |
| 5642 | __be32 *p; | 5642 | __be32 *p; |
| 5643 | int status; | 5643 | int status; |
| 5644 | struct nfs_client *clp = res->client; | ||
| 5645 | struct nfs4_session *session = clp->cl_session; | ||
| 5646 | 5644 | ||
| 5647 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); | 5645 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); |
| 5648 | if (!status) | 5646 | if (!status) |
| 5649 | status = decode_sessionid(xdr, &session->sess_id); | 5647 | status = decode_sessionid(xdr, &res->sessionid); |
| 5650 | if (unlikely(status)) | 5648 | if (unlikely(status)) |
| 5651 | return status; | 5649 | return status; |
| 5652 | 5650 | ||
| @@ -5654,13 +5652,13 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
| 5654 | p = xdr_inline_decode(xdr, 8); | 5652 | p = xdr_inline_decode(xdr, 8); |
| 5655 | if (unlikely(!p)) | 5653 | if (unlikely(!p)) |
| 5656 | goto out_overflow; | 5654 | goto out_overflow; |
| 5657 | clp->cl_seqid = be32_to_cpup(p++); | 5655 | res->seqid = be32_to_cpup(p++); |
| 5658 | session->flags = be32_to_cpup(p); | 5656 | res->flags = be32_to_cpup(p); |
| 5659 | 5657 | ||
| 5660 | /* Channel attributes */ | 5658 | /* Channel attributes */ |
| 5661 | status = decode_chan_attrs(xdr, &session->fc_attrs); | 5659 | status = decode_chan_attrs(xdr, &res->fc_attrs); |
| 5662 | if (!status) | 5660 | if (!status) |
| 5663 | status = decode_chan_attrs(xdr, &session->bc_attrs); | 5661 | status = decode_chan_attrs(xdr, &res->bc_attrs); |
| 5664 | return status; | 5662 | return status; |
| 5665 | out_overflow: | 5663 | out_overflow: |
| 5666 | print_overflow_msg(__func__, xdr); | 5664 | print_overflow_msg(__func__, xdr); |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 797cd6253adf..635f0865671c 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
| @@ -344,6 +344,10 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, | |||
| 344 | struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, | 344 | struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, |
| 345 | struct xdr_stream *xdr, | 345 | struct xdr_stream *xdr, |
| 346 | gfp_t gfp_flags); | 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 | static inline bool nfs_have_layout(struct inode *inode) | 352 | static inline bool nfs_have_layout(struct inode *inode) |
| 349 | { | 353 | { |
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index fdc4f6562bb7..54e36b38fb5f 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c | |||
| @@ -838,3 +838,33 @@ out_err: | |||
| 838 | return NULL; | 838 | return NULL; |
| 839 | } | 839 | } |
| 840 | EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr); | 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); | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 88a6d2196ece..595d81e354d1 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -789,13 +789,8 @@ nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, | |||
| 789 | nfs_list_add_request(req, dst); | 789 | nfs_list_add_request(req, dst); |
| 790 | cinfo->mds->ncommit++; | 790 | cinfo->mds->ncommit++; |
| 791 | spin_unlock(cinfo->lock); | 791 | spin_unlock(cinfo->lock); |
| 792 | if (!cinfo->dreq) { | 792 | if (!cinfo->dreq) |
| 793 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 793 | nfs_mark_page_unstable(req->wb_page); |
| 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 | } | ||
| 799 | } | 794 | } |
| 800 | EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); | 795 | EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); |
| 801 | 796 | ||
| @@ -1605,11 +1600,8 @@ void nfs_retry_commit(struct list_head *page_list, | |||
| 1605 | req = nfs_list_entry(page_list->next); | 1600 | req = nfs_list_entry(page_list->next); |
| 1606 | nfs_list_remove_request(req); | 1601 | nfs_list_remove_request(req); |
| 1607 | nfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx); | 1602 | nfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx); |
| 1608 | if (!cinfo->dreq) { | 1603 | if (!cinfo->dreq) |
| 1609 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 1604 | nfs_clear_page_commit(req->wb_page); |
| 1610 | dec_bdi_stat(inode_to_bdi(page_file_mapping(req->wb_page)->host), | ||
| 1611 | BDI_RECLAIMABLE); | ||
| 1612 | } | ||
| 1613 | nfs_unlock_and_release_request(req); | 1605 | nfs_unlock_and_release_request(req); |
| 1614 | } | 1606 | } |
| 1615 | } | 1607 | } |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 6d627b92df53..2f77e0c651c8 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -180,7 +180,6 @@ struct nfs_inode { | |||
| 180 | /* NFSv4 state */ | 180 | /* NFSv4 state */ |
| 181 | struct list_head open_states; | 181 | struct list_head open_states; |
| 182 | struct nfs_delegation __rcu *delegation; | 182 | struct nfs_delegation __rcu *delegation; |
| 183 | fmode_t delegation_state; | ||
| 184 | struct rw_semaphore rwsem; | 183 | struct rw_semaphore rwsem; |
| 185 | 184 | ||
| 186 | /* pNFS layout information */ | 185 | /* pNFS layout information */ |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 38d96ba935c2..4cb3eaa89cf7 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -1167,8 +1167,15 @@ struct nfs41_impl_id { | |||
| 1167 | struct nfstime4 date; | 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 | struct nfs41_bind_conn_to_session_res { | 1177 | struct nfs41_bind_conn_to_session_res { |
| 1171 | struct nfs4_session *session; | 1178 | struct nfs4_sessionid sessionid; |
| 1172 | u32 dir; | 1179 | u32 dir; |
| 1173 | bool use_conn_in_rdma_mode; | 1180 | bool use_conn_in_rdma_mode; |
| 1174 | }; | 1181 | }; |
| @@ -1185,6 +1192,8 @@ struct nfs41_exchange_id_res { | |||
| 1185 | 1192 | ||
| 1186 | struct nfs41_create_session_args { | 1193 | struct nfs41_create_session_args { |
| 1187 | struct nfs_client *client; | 1194 | struct nfs_client *client; |
| 1195 | u64 clientid; | ||
| 1196 | uint32_t seqid; | ||
| 1188 | uint32_t flags; | 1197 | uint32_t flags; |
| 1189 | uint32_t cb_program; | 1198 | uint32_t cb_program; |
| 1190 | struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ | 1199 | struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ |
| @@ -1192,7 +1201,11 @@ struct nfs41_create_session_args { | |||
| 1192 | }; | 1201 | }; |
| 1193 | 1202 | ||
| 1194 | struct nfs41_create_session_res { | 1203 | struct nfs41_create_session_res { |
| 1195 | struct nfs_client *client; | 1204 | struct nfs4_sessionid sessionid; |
| 1205 | uint32_t seqid; | ||
| 1206 | uint32_t flags; | ||
| 1207 | struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ | ||
| 1208 | struct nfs4_channel_attrs bc_attrs; /* Back Channel */ | ||
| 1196 | }; | 1209 | }; |
| 1197 | 1210 | ||
| 1198 | struct nfs41_reclaim_complete_args { | 1211 | struct nfs41_reclaim_complete_args { |
| @@ -1351,7 +1364,7 @@ struct nfs_commit_completion_ops { | |||
| 1351 | }; | 1364 | }; |
| 1352 | 1365 | ||
| 1353 | struct nfs_commit_info { | 1366 | struct nfs_commit_info { |
| 1354 | spinlock_t *lock; | 1367 | spinlock_t *lock; /* inode->i_lock */ |
| 1355 | struct nfs_mds_commit_info *mds; | 1368 | struct nfs_mds_commit_info *mds; |
| 1356 | struct pnfs_ds_commit_info *ds; | 1369 | struct pnfs_ds_commit_info *ds; |
| 1357 | struct nfs_direct_req *dreq; /* O_DIRECT request */ | 1370 | struct nfs_direct_req *dreq; /* O_DIRECT request */ |
diff --git a/include/linux/sunrpc/metrics.h b/include/linux/sunrpc/metrics.h index 7e61a17030a4..694eecb2f1b5 100644 --- a/include/linux/sunrpc/metrics.h +++ b/include/linux/sunrpc/metrics.h | |||
| @@ -89,8 +89,11 @@ void rpc_free_iostats(struct rpc_iostats *); | |||
| 89 | static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } | 89 | static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } |
| 90 | static inline void rpc_count_iostats(const struct rpc_task *task, | 90 | static inline void rpc_count_iostats(const struct rpc_task *task, |
| 91 | struct rpc_iostats *stats) {} | 91 | struct rpc_iostats *stats) {} |
| 92 | static inline void rpc_count_iostats_metrics(const struct rpc_task *, | 92 | static inline void rpc_count_iostats_metrics(const struct rpc_task *task, |
| 93 | struct rpc_iostats *) {} | 93 | struct rpc_iostats *stats) |
| 94 | { | ||
| 95 | } | ||
| 96 | |||
| 94 | static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} | 97 | static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} |
| 95 | static inline void rpc_free_iostats(struct rpc_iostats *stats) {} | 98 | static inline void rpc_free_iostats(struct rpc_iostats *stats) {} |
| 96 | 99 | ||
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 651f49ab601f..9dd0ea8db463 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
| @@ -309,12 +309,15 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) | |||
| 309 | struct rpc_xprt *xprt = req->rq_xprt; | 309 | struct rpc_xprt *xprt = req->rq_xprt; |
| 310 | struct svc_serv *bc_serv = xprt->bc_serv; | 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 | req->rq_private_buf.len = copied; | 316 | req->rq_private_buf.len = copied; |
| 313 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); | 317 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); |
| 314 | 318 | ||
| 315 | dprintk("RPC: add callback request to list\n"); | 319 | dprintk("RPC: add callback request to list\n"); |
| 316 | spin_lock(&bc_serv->sv_cb_lock); | 320 | spin_lock(&bc_serv->sv_cb_lock); |
| 317 | list_del(&req->rq_bc_pa_list); | ||
| 318 | list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); | 321 | list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); |
| 319 | wake_up(&bc_serv->sv_cb_waitq); | 322 | wake_up(&bc_serv->sv_cb_waitq); |
| 320 | spin_unlock(&bc_serv->sv_cb_lock); | 323 | spin_unlock(&bc_serv->sv_cb_lock); |
