aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/blocklayout/rpc_pipefs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-11-15 17:15:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-11-15 17:15:16 -0500
commit1afcb6ed0d34c5794a51fe325076f006c8babaf4 (patch)
treea39a9b36d96dca051c0506cfde57269a1cd1a31c /fs/nfs/blocklayout/rpc_pipefs.c
parent56c381f93d57b88a3e667a2f55137947315c17e2 (diff)
parentb3ecba096729f521312d1863ad22530695527aed (diff)
Merge tag 'nfs-for-3.18-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: "Highlights include: - stable patches to fix NFSv4.x delegation reclaim error paths - fix a bug whereby we were advertising NFSv4.1 but using NFSv4.2 features - fix a use-after-free problem with pNFS block layouts - fix a memory leak in the pNFS files O_DIRECT code - replace an intrusive and Oops-prone performance fix in the NFSv4 atomic open code with a safer one-line version and revert the two original patches" * tag 'nfs-for-3.18-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: sunrpc: fix sleeping under rcu_read_lock in gss_stringify_acceptor NFS: Don't try to reclaim delegation open state if recovery failed NFSv4: Ensure that we call FREE_STATEID when NFSv4.x stateids are revoked NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return NFSv4.1: nfs41_clear_delegation_stateid shouldn't trust NFS_DELEGATED_STATE NFSv4: Ensure that we remove NFSv4.0 delegations when state has expired NFS: SEEK is an NFS v4.2 feature nfs: Fix use of uninitialized variable in nfs_getattr() nfs: Remove bogus assignment nfs: remove spurious WARN_ON_ONCE in write path pnfs/blocklayout: serialize GETDEVICEINFO calls nfs: fix pnfs direct write memory leak Revert "NFS: nfs4_do_open should add negative results to the dcache." Revert "NFS: remove BUG possibility in nfs4_open_and_get_state" NFSv4: Ensure nfs_atomic_open set the dentry verifier on ENOENT
Diffstat (limited to 'fs/nfs/blocklayout/rpc_pipefs.c')
-rw-r--r--fs/nfs/blocklayout/rpc_pipefs.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/nfs/blocklayout/rpc_pipefs.c b/fs/nfs/blocklayout/rpc_pipefs.c
index e966c023b1b7..acbf9ca4018c 100644
--- a/fs/nfs/blocklayout/rpc_pipefs.c
+++ b/fs/nfs/blocklayout/rpc_pipefs.c
@@ -65,17 +65,18 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
65 65
66 dprintk("%s CREATING PIPEFS MESSAGE\n", __func__); 66 dprintk("%s CREATING PIPEFS MESSAGE\n", __func__);
67 67
68 mutex_lock(&nn->bl_mutex);
68 bl_pipe_msg.bl_wq = &nn->bl_wq; 69 bl_pipe_msg.bl_wq = &nn->bl_wq;
69 70
70 b->simple.len += 4; /* single volume */ 71 b->simple.len += 4; /* single volume */
71 if (b->simple.len > PAGE_SIZE) 72 if (b->simple.len > PAGE_SIZE)
72 return -EIO; 73 goto out_unlock;
73 74
74 memset(msg, 0, sizeof(*msg)); 75 memset(msg, 0, sizeof(*msg));
75 msg->len = sizeof(*bl_msg) + b->simple.len; 76 msg->len = sizeof(*bl_msg) + b->simple.len;
76 msg->data = kzalloc(msg->len, gfp_mask); 77 msg->data = kzalloc(msg->len, gfp_mask);
77 if (!msg->data) 78 if (!msg->data)
78 goto out; 79 goto out_free_data;
79 80
80 bl_msg = msg->data; 81 bl_msg = msg->data;
81 bl_msg->type = BL_DEVICE_MOUNT, 82 bl_msg->type = BL_DEVICE_MOUNT,
@@ -87,7 +88,7 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
87 rc = rpc_queue_upcall(nn->bl_device_pipe, msg); 88 rc = rpc_queue_upcall(nn->bl_device_pipe, msg);
88 if (rc < 0) { 89 if (rc < 0) {
89 remove_wait_queue(&nn->bl_wq, &wq); 90 remove_wait_queue(&nn->bl_wq, &wq);
90 goto out; 91 goto out_free_data;
91 } 92 }
92 93
93 set_current_state(TASK_UNINTERRUPTIBLE); 94 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -97,12 +98,14 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
97 if (reply->status != BL_DEVICE_REQUEST_PROC) { 98 if (reply->status != BL_DEVICE_REQUEST_PROC) {
98 printk(KERN_WARNING "%s failed to decode device: %d\n", 99 printk(KERN_WARNING "%s failed to decode device: %d\n",
99 __func__, reply->status); 100 __func__, reply->status);
100 goto out; 101 goto out_free_data;
101 } 102 }
102 103
103 dev = MKDEV(reply->major, reply->minor); 104 dev = MKDEV(reply->major, reply->minor);
104out: 105out_free_data:
105 kfree(msg->data); 106 kfree(msg->data);
107out_unlock:
108 mutex_unlock(&nn->bl_mutex);
106 return dev; 109 return dev;
107} 110}
108 111
@@ -232,6 +235,7 @@ static int nfs4blocklayout_net_init(struct net *net)
232 struct nfs_net *nn = net_generic(net, nfs_net_id); 235 struct nfs_net *nn = net_generic(net, nfs_net_id);
233 struct dentry *dentry; 236 struct dentry *dentry;
234 237
238 mutex_init(&nn->bl_mutex);
235 init_waitqueue_head(&nn->bl_wq); 239 init_waitqueue_head(&nn->bl_wq);
236 nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0); 240 nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0);
237 if (IS_ERR(nn->bl_device_pipe)) 241 if (IS_ERR(nn->bl_device_pipe))