diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-10 16:03:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-10 16:03:38 -0400 |
commit | 73ccb023a2f25b72c4b95499ca24760588014614 (patch) | |
tree | b0fd9968af3e929ac496f159420a25dc3e1dcafb /fs/nfs/client.c | |
parent | f94c128eefcce2e3448d543f13cd7d7b8aa660a5 (diff) | |
parent | 76b2a303384e1d6299c3a0249f0f0ce2f8f96017 (diff) |
Merge tag 'nfs-for-4.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust:
"Highlights include:
Stable bugfixes:
- Fix use after free in write error path
- Use GFP_NOIO for two allocations in writeback
- Fix a hang in OPEN related to server reboot
- Check the result of nfs4_pnfs_ds_connect
- Fix an rcu lock leak
Features:
- Removal of the unmaintained and unused OSD pNFS layout
- Cleanup and removal of lots of unnecessary dprintk()s
- Cleanup and removal of some memory failure paths now that GFP_NOFS
is guaranteed to never fail.
- Remove the v3-only data server limitation on pNFS/flexfiles
Bugfixes:
- RPC/RDMA connection handling bugfixes
- Copy offload: fixes to ensure the copied data is COMMITed to disk.
- Readdir: switch back to using the ->iterate VFS interface
- File locking fixes from Ben Coddington
- Various use-after-free and deadlock issues in pNFS
- Write path bugfixes"
* tag 'nfs-for-4.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (89 commits)
pNFS/flexfiles: Always attempt to call layoutstats when flexfiles is enabled
NFSv4.1: Work around a Linux server bug...
NFS append COMMIT after synchronous COPY
NFSv4: Fix exclusive create attributes encoding
NFSv4: Fix an rcu lock leak
nfs: use kmap/kunmap directly
NFS: always treat the invocation of nfs_getattr as cache hit when noac is on
Fix nfs_client refcounting if kmalloc fails in nfs4_proc_exchange_id and nfs4_proc_async_renew
NFSv4.1: RECLAIM_COMPLETE must handle NFS4ERR_CONN_NOT_BOUND_TO_SESSION
pNFS: Fix NULL dereference in pnfs_generic_alloc_ds_commits
pNFS: Fix a typo in pnfs_generic_alloc_ds_commits
pNFS: Fix a deadlock when coalescing writes and returning the layout
pNFS: Don't clear the layout return info if there are segments to return
pNFS: Ensure we commit the layout if it has been invalidated
pNFS: Don't send COMMITs to the DSes if the server invalidated our layout
pNFS/flexfiles: Fix up the ff_layout_write_pagelist failure path
pNFS: Ensure we check layout validity before marking it for return
NFS4.1 handle interrupted slot reuse from ERR_DELAY
NFSv4: check return value of xdr_inline_decode
nfs/filelayout: fix NULL pointer dereference in fl_pnfs_update_layout()
...
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r-- | fs/nfs/client.c | 67 |
1 files changed, 12 insertions, 55 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 04d15a0045e3..ee5ddbd36088 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -218,6 +218,7 @@ static void nfs_cb_idr_remove_locked(struct nfs_client *clp) | |||
218 | static void pnfs_init_server(struct nfs_server *server) | 218 | static void pnfs_init_server(struct nfs_server *server) |
219 | { | 219 | { |
220 | rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC"); | 220 | rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC"); |
221 | rpc_init_wait_queue(&server->uoc_rpcwaitq, "NFS UOC"); | ||
221 | } | 222 | } |
222 | 223 | ||
223 | #else | 224 | #else |
@@ -240,8 +241,6 @@ static void pnfs_init_server(struct nfs_server *server) | |||
240 | */ | 241 | */ |
241 | void nfs_free_client(struct nfs_client *clp) | 242 | void nfs_free_client(struct nfs_client *clp) |
242 | { | 243 | { |
243 | dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); | ||
244 | |||
245 | nfs_fscache_release_client_cookie(clp); | 244 | nfs_fscache_release_client_cookie(clp); |
246 | 245 | ||
247 | /* -EIO all pending I/O */ | 246 | /* -EIO all pending I/O */ |
@@ -256,8 +255,6 @@ void nfs_free_client(struct nfs_client *clp) | |||
256 | kfree(clp->cl_hostname); | 255 | kfree(clp->cl_hostname); |
257 | kfree(clp->cl_acceptor); | 256 | kfree(clp->cl_acceptor); |
258 | kfree(clp); | 257 | kfree(clp); |
259 | |||
260 | dprintk("<-- nfs_free_client()\n"); | ||
261 | } | 258 | } |
262 | EXPORT_SYMBOL_GPL(nfs_free_client); | 259 | EXPORT_SYMBOL_GPL(nfs_free_client); |
263 | 260 | ||
@@ -271,7 +268,6 @@ void nfs_put_client(struct nfs_client *clp) | |||
271 | if (!clp) | 268 | if (!clp) |
272 | return; | 269 | return; |
273 | 270 | ||
274 | dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count)); | ||
275 | nn = net_generic(clp->cl_net, nfs_net_id); | 271 | nn = net_generic(clp->cl_net, nfs_net_id); |
276 | 272 | ||
277 | if (atomic_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) { | 273 | if (atomic_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) { |
@@ -382,9 +378,6 @@ nfs_found_client(const struct nfs_client_initdata *cl_init, | |||
382 | } | 378 | } |
383 | 379 | ||
384 | smp_rmb(); | 380 | smp_rmb(); |
385 | |||
386 | dprintk("<-- %s found nfs_client %p for %s\n", | ||
387 | __func__, clp, cl_init->hostname ?: ""); | ||
388 | return clp; | 381 | return clp; |
389 | } | 382 | } |
390 | 383 | ||
@@ -403,9 +396,6 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init) | |||
403 | return NULL; | 396 | return NULL; |
404 | } | 397 | } |
405 | 398 | ||
406 | dprintk("--> nfs_get_client(%s,v%u)\n", | ||
407 | cl_init->hostname, rpc_ops->version); | ||
408 | |||
409 | /* see if the client already exists */ | 399 | /* see if the client already exists */ |
410 | do { | 400 | do { |
411 | spin_lock(&nn->nfs_client_lock); | 401 | spin_lock(&nn->nfs_client_lock); |
@@ -430,8 +420,6 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init) | |||
430 | new = rpc_ops->alloc_client(cl_init); | 420 | new = rpc_ops->alloc_client(cl_init); |
431 | } while (!IS_ERR(new)); | 421 | } while (!IS_ERR(new)); |
432 | 422 | ||
433 | dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n", | ||
434 | cl_init->hostname, PTR_ERR(new)); | ||
435 | return new; | 423 | return new; |
436 | } | 424 | } |
437 | EXPORT_SYMBOL_GPL(nfs_get_client); | 425 | EXPORT_SYMBOL_GPL(nfs_get_client); |
@@ -558,6 +546,7 @@ static int nfs_start_lockd(struct nfs_server *server) | |||
558 | .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? | 546 | .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? |
559 | 1 : 0, | 547 | 1 : 0, |
560 | .net = clp->cl_net, | 548 | .net = clp->cl_net, |
549 | .nlmclnt_ops = clp->cl_nfs_mod->rpc_ops->nlmclnt_ops, | ||
561 | }; | 550 | }; |
562 | 551 | ||
563 | if (nlm_init.nfs_version > 3) | 552 | if (nlm_init.nfs_version > 3) |
@@ -624,27 +613,21 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp, | |||
624 | { | 613 | { |
625 | int error; | 614 | int error; |
626 | 615 | ||
627 | if (clp->cl_cons_state == NFS_CS_READY) { | 616 | /* the client is already initialised */ |
628 | /* the client is already initialised */ | 617 | if (clp->cl_cons_state == NFS_CS_READY) |
629 | dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp); | ||
630 | return clp; | 618 | return clp; |
631 | } | ||
632 | 619 | ||
633 | /* | 620 | /* |
634 | * Create a client RPC handle for doing FSSTAT with UNIX auth only | 621 | * Create a client RPC handle for doing FSSTAT with UNIX auth only |
635 | * - RFC 2623, sec 2.3.2 | 622 | * - RFC 2623, sec 2.3.2 |
636 | */ | 623 | */ |
637 | error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX); | 624 | error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX); |
638 | if (error < 0) | 625 | nfs_mark_client_ready(clp, error == 0 ? NFS_CS_READY : error); |
639 | goto error; | 626 | if (error < 0) { |
640 | nfs_mark_client_ready(clp, NFS_CS_READY); | 627 | nfs_put_client(clp); |
628 | clp = ERR_PTR(error); | ||
629 | } | ||
641 | return clp; | 630 | return clp; |
642 | |||
643 | error: | ||
644 | nfs_mark_client_ready(clp, error); | ||
645 | nfs_put_client(clp); | ||
646 | dprintk("<-- nfs_init_client() = xerror %d\n", error); | ||
647 | return ERR_PTR(error); | ||
648 | } | 631 | } |
649 | EXPORT_SYMBOL_GPL(nfs_init_client); | 632 | EXPORT_SYMBOL_GPL(nfs_init_client); |
650 | 633 | ||
@@ -668,8 +651,6 @@ static int nfs_init_server(struct nfs_server *server, | |||
668 | struct nfs_client *clp; | 651 | struct nfs_client *clp; |
669 | int error; | 652 | int error; |
670 | 653 | ||
671 | dprintk("--> nfs_init_server()\n"); | ||
672 | |||
673 | nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, | 654 | nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, |
674 | data->timeo, data->retrans); | 655 | data->timeo, data->retrans); |
675 | if (data->flags & NFS_MOUNT_NORESVPORT) | 656 | if (data->flags & NFS_MOUNT_NORESVPORT) |
@@ -677,10 +658,8 @@ static int nfs_init_server(struct nfs_server *server, | |||
677 | 658 | ||
678 | /* Allocate or find a client reference we can use */ | 659 | /* Allocate or find a client reference we can use */ |
679 | clp = nfs_get_client(&cl_init); | 660 | clp = nfs_get_client(&cl_init); |
680 | if (IS_ERR(clp)) { | 661 | if (IS_ERR(clp)) |
681 | dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); | ||
682 | return PTR_ERR(clp); | 662 | return PTR_ERR(clp); |
683 | } | ||
684 | 663 | ||
685 | server->nfs_client = clp; | 664 | server->nfs_client = clp; |
686 | 665 | ||
@@ -725,13 +704,11 @@ static int nfs_init_server(struct nfs_server *server, | |||
725 | server->mountd_protocol = data->mount_server.protocol; | 704 | server->mountd_protocol = data->mount_server.protocol; |
726 | 705 | ||
727 | server->namelen = data->namlen; | 706 | server->namelen = data->namlen; |
728 | dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp); | ||
729 | return 0; | 707 | return 0; |
730 | 708 | ||
731 | error: | 709 | error: |
732 | server->nfs_client = NULL; | 710 | server->nfs_client = NULL; |
733 | nfs_put_client(clp); | 711 | nfs_put_client(clp); |
734 | dprintk("<-- nfs_init_server() = xerror %d\n", error); | ||
735 | return error; | 712 | return error; |
736 | } | 713 | } |
737 | 714 | ||
@@ -798,12 +775,10 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs | |||
798 | struct nfs_client *clp = server->nfs_client; | 775 | struct nfs_client *clp = server->nfs_client; |
799 | int error; | 776 | int error; |
800 | 777 | ||
801 | dprintk("--> nfs_probe_fsinfo()\n"); | ||
802 | |||
803 | if (clp->rpc_ops->set_capabilities != NULL) { | 778 | if (clp->rpc_ops->set_capabilities != NULL) { |
804 | error = clp->rpc_ops->set_capabilities(server, mntfh); | 779 | error = clp->rpc_ops->set_capabilities(server, mntfh); |
805 | if (error < 0) | 780 | if (error < 0) |
806 | goto out_error; | 781 | return error; |
807 | } | 782 | } |
808 | 783 | ||
809 | fsinfo.fattr = fattr; | 784 | fsinfo.fattr = fattr; |
@@ -811,7 +786,7 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs | |||
811 | memset(fsinfo.layouttype, 0, sizeof(fsinfo.layouttype)); | 786 | memset(fsinfo.layouttype, 0, sizeof(fsinfo.layouttype)); |
812 | error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); | 787 | error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); |
813 | if (error < 0) | 788 | if (error < 0) |
814 | goto out_error; | 789 | return error; |
815 | 790 | ||
816 | nfs_server_set_fsinfo(server, &fsinfo); | 791 | nfs_server_set_fsinfo(server, &fsinfo); |
817 | 792 | ||
@@ -826,12 +801,7 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs | |||
826 | server->namelen = pathinfo.max_namelen; | 801 | server->namelen = pathinfo.max_namelen; |
827 | } | 802 | } |
828 | 803 | ||
829 | dprintk("<-- nfs_probe_fsinfo() = 0\n"); | ||
830 | return 0; | 804 | return 0; |
831 | |||
832 | out_error: | ||
833 | dprintk("nfs_probe_fsinfo: error = %d\n", -error); | ||
834 | return error; | ||
835 | } | 805 | } |
836 | EXPORT_SYMBOL_GPL(nfs_probe_fsinfo); | 806 | EXPORT_SYMBOL_GPL(nfs_probe_fsinfo); |
837 | 807 | ||
@@ -927,8 +897,6 @@ EXPORT_SYMBOL_GPL(nfs_alloc_server); | |||
927 | */ | 897 | */ |
928 | void nfs_free_server(struct nfs_server *server) | 898 | void nfs_free_server(struct nfs_server *server) |
929 | { | 899 | { |
930 | dprintk("--> nfs_free_server()\n"); | ||
931 | |||
932 | nfs_server_remove_lists(server); | 900 | nfs_server_remove_lists(server); |
933 | 901 | ||
934 | if (server->destroy != NULL) | 902 | if (server->destroy != NULL) |
@@ -946,7 +914,6 @@ void nfs_free_server(struct nfs_server *server) | |||
946 | nfs_free_iostats(server->io_stats); | 914 | nfs_free_iostats(server->io_stats); |
947 | kfree(server); | 915 | kfree(server); |
948 | nfs_release_automount_timer(); | 916 | nfs_release_automount_timer(); |
949 | dprintk("<-- nfs_free_server()\n"); | ||
950 | } | 917 | } |
951 | EXPORT_SYMBOL_GPL(nfs_free_server); | 918 | EXPORT_SYMBOL_GPL(nfs_free_server); |
952 | 919 | ||
@@ -1026,10 +993,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, | |||
1026 | struct nfs_fattr *fattr_fsinfo; | 993 | struct nfs_fattr *fattr_fsinfo; |
1027 | int error; | 994 | int error; |
1028 | 995 | ||
1029 | dprintk("--> nfs_clone_server(,%llx:%llx,)\n", | ||
1030 | (unsigned long long) fattr->fsid.major, | ||
1031 | (unsigned long long) fattr->fsid.minor); | ||
1032 | |||
1033 | server = nfs_alloc_server(); | 996 | server = nfs_alloc_server(); |
1034 | if (!server) | 997 | if (!server) |
1035 | return ERR_PTR(-ENOMEM); | 998 | return ERR_PTR(-ENOMEM); |
@@ -1061,10 +1024,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, | |||
1061 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) | 1024 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) |
1062 | server->namelen = NFS4_MAXNAMLEN; | 1025 | server->namelen = NFS4_MAXNAMLEN; |
1063 | 1026 | ||
1064 | dprintk("Cloned FSID: %llx:%llx\n", | ||
1065 | (unsigned long long) server->fsid.major, | ||
1066 | (unsigned long long) server->fsid.minor); | ||
1067 | |||
1068 | error = nfs_start_lockd(server); | 1027 | error = nfs_start_lockd(server); |
1069 | if (error < 0) | 1028 | if (error < 0) |
1070 | goto out_free_server; | 1029 | goto out_free_server; |
@@ -1073,13 +1032,11 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, | |||
1073 | server->mount_time = jiffies; | 1032 | server->mount_time = jiffies; |
1074 | 1033 | ||
1075 | nfs_free_fattr(fattr_fsinfo); | 1034 | nfs_free_fattr(fattr_fsinfo); |
1076 | dprintk("<-- nfs_clone_server() = %p\n", server); | ||
1077 | return server; | 1035 | return server; |
1078 | 1036 | ||
1079 | out_free_server: | 1037 | out_free_server: |
1080 | nfs_free_fattr(fattr_fsinfo); | 1038 | nfs_free_fattr(fattr_fsinfo); |
1081 | nfs_free_server(server); | 1039 | nfs_free_server(server); |
1082 | dprintk("<-- nfs_clone_server() = error %d\n", error); | ||
1083 | return ERR_PTR(error); | 1040 | return ERR_PTR(error); |
1084 | } | 1041 | } |
1085 | EXPORT_SYMBOL_GPL(nfs_clone_server); | 1042 | EXPORT_SYMBOL_GPL(nfs_clone_server); |