aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p
diff options
context:
space:
mode:
authorSimon Derr <simon.derr@bull.net>2013-06-21 09:32:34 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2013-07-07 23:02:26 -0400
commitea071aa1365eaf8a79b33bd8699cb0811dcddf34 (patch)
treec948ded09d3e1b10bf75abde352b50b13f2581a2 /net/9p
parentd9a738597faf7cd2edeec82ce8fd81969fed8390 (diff)
9P: Fix fcall allocation for rdma
The current code assumes that when a request in the request array does have a tc, it also has a rc. This is normally true, but not always : when using RDMA, req->rc will temporarily be set to NULL after the request has been sent. That is usually OK though, as when the reply arrives, req->rc will be reassigned to a sane value before the request is recycled. But there is a catch : if the request is flushed, the reply will never arrive, and req->rc will be NULL, but not req->tc. This patch fixes p9_tag_alloc to take this into account. Signed-off-by: Simon Derr <simon.derr@bull.net> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'net/9p')
-rw-r--r--net/9p/client.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 01f1779eba80..5828769d1f3d 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -258,27 +258,25 @@ p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
258 req = &c->reqs[row][col]; 258 req = &c->reqs[row][col];
259 if (!req->tc) { 259 if (!req->tc) {
260 req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_NOFS); 260 req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_NOFS);
261 if (!req->wq) { 261 if (!req->wq)
262 pr_err("Couldn't grow tag array\n"); 262 goto grow_failed;
263 return ERR_PTR(-ENOMEM); 263
264 }
265 init_waitqueue_head(req->wq); 264 init_waitqueue_head(req->wq);
266 req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, 265 req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
267 GFP_NOFS); 266 GFP_NOFS);
267 if (!req->tc)
268 goto grow_failed;
269
270 req->tc->capacity = alloc_msize;
271 req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
272 }
273 if (!req->rc) {
268 req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, 274 req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
269 GFP_NOFS); 275 GFP_NOFS);
270 if ((!req->tc) || (!req->rc)) { 276 if (!req->rc)
271 pr_err("Couldn't grow tag array\n"); 277 goto grow_failed;
272 kfree(req->tc); 278
273 kfree(req->rc);
274 kfree(req->wq);
275 req->tc = req->rc = NULL;
276 req->wq = NULL;
277 return ERR_PTR(-ENOMEM);
278 }
279 req->tc->capacity = alloc_msize;
280 req->rc->capacity = alloc_msize; 279 req->rc->capacity = alloc_msize;
281 req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
282 req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall); 280 req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
283 } 281 }
284 282
@@ -288,7 +286,16 @@ p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
288 req->tc->tag = tag-1; 286 req->tc->tag = tag-1;
289 req->status = REQ_STATUS_ALLOC; 287 req->status = REQ_STATUS_ALLOC;
290 288
291 return &c->reqs[row][col]; 289 return req;
290
291grow_failed:
292 pr_err("Couldn't grow tag array\n");
293 kfree(req->tc);
294 kfree(req->rc);
295 kfree(req->wq);
296 req->tc = req->rc = NULL;
297 req->wq = NULL;
298 return ERR_PTR(-ENOMEM);
292} 299}
293 300
294/** 301/**