aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-24 15:39:09 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-24 15:39:09 -0500
commitc52cb4311f20538fcb69420e55a19ac622546a08 (patch)
treef3fb973aa9271276bb17f7c78ac1e9e26d97e5e6 /net
parent00e3f5cc305c8a056a22cecedab3a71d59dae1fc (diff)
parenta333e4bf2556b93c908e56b39be7bbd555f1b6cc (diff)
Merge tag 'for-linus-4.5-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull 9p updates from Eric Van Hensbergen: "Sorry for the last minute pull request, there's was a change that didn't get pulled into for-next until two weeks ago and I wanted to give it some bake time. Summary: Rework and error handling fixes, primarily in the fscatch and fd transports" * tag 'for-linus-4.5-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: fs/9p: use fscache mutex rather than spinlock 9p: trans_fd, bail out if recv fcall if missing 9p: trans_fd, read rework to use p9_parse_header net/9p: Add device name details on error
Diffstat (limited to 'net')
-rw-r--r--net/9p/trans_fd.c88
-rw-r--r--net/9p/trans_virtio.c2
2 files changed, 47 insertions, 43 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index bced8c074c12..7bc2208b6cc4 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -108,9 +108,7 @@ struct p9_poll_wait {
108 * @unsent_req_list: accounting for requests that haven't been sent 108 * @unsent_req_list: accounting for requests that haven't been sent
109 * @req: current request being processed (if any) 109 * @req: current request being processed (if any)
110 * @tmp_buf: temporary buffer to read in header 110 * @tmp_buf: temporary buffer to read in header
111 * @rsize: amount to read for current frame 111 * @rc: temporary fcall for reading current frame
112 * @rpos: read position in current frame
113 * @rbuf: current read buffer
114 * @wpos: write position for current frame 112 * @wpos: write position for current frame
115 * @wsize: amount of data to write for current frame 113 * @wsize: amount of data to write for current frame
116 * @wbuf: current write buffer 114 * @wbuf: current write buffer
@@ -131,9 +129,7 @@ struct p9_conn {
131 struct list_head unsent_req_list; 129 struct list_head unsent_req_list;
132 struct p9_req_t *req; 130 struct p9_req_t *req;
133 char tmp_buf[7]; 131 char tmp_buf[7];
134 int rsize; 132 struct p9_fcall rc;
135 int rpos;
136 char *rbuf;
137 int wpos; 133 int wpos;
138 int wsize; 134 int wsize;
139 char *wbuf; 135 char *wbuf;
@@ -305,69 +301,77 @@ static void p9_read_work(struct work_struct *work)
305 if (m->err < 0) 301 if (m->err < 0)
306 return; 302 return;
307 303
308 p9_debug(P9_DEBUG_TRANS, "start mux %p pos %d\n", m, m->rpos); 304 p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset);
309 305
310 if (!m->rbuf) { 306 if (!m->rc.sdata) {
311 m->rbuf = m->tmp_buf; 307 m->rc.sdata = m->tmp_buf;
312 m->rpos = 0; 308 m->rc.offset = 0;
313 m->rsize = 7; /* start by reading header */ 309 m->rc.capacity = 7; /* start by reading header */
314 } 310 }
315 311
316 clear_bit(Rpending, &m->wsched); 312 clear_bit(Rpending, &m->wsched);
317 p9_debug(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d\n", 313 p9_debug(P9_DEBUG_TRANS, "read mux %p pos %zd size: %zd = %zd\n",
318 m, m->rpos, m->rsize, m->rsize-m->rpos); 314 m, m->rc.offset, m->rc.capacity,
319 err = p9_fd_read(m->client, m->rbuf + m->rpos, 315 m->rc.capacity - m->rc.offset);
320 m->rsize - m->rpos); 316 err = p9_fd_read(m->client, m->rc.sdata + m->rc.offset,
317 m->rc.capacity - m->rc.offset);
321 p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err); 318 p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
322 if (err == -EAGAIN) { 319 if (err == -EAGAIN)
323 goto end_clear; 320 goto end_clear;
324 }
325 321
326 if (err <= 0) 322 if (err <= 0)
327 goto error; 323 goto error;
328 324
329 m->rpos += err; 325 m->rc.offset += err;
330 326
331 if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */ 327 /* header read in */
332 u16 tag; 328 if ((!m->req) && (m->rc.offset == m->rc.capacity)) {
333 p9_debug(P9_DEBUG_TRANS, "got new header\n"); 329 p9_debug(P9_DEBUG_TRANS, "got new header\n");
334 330
335 n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */ 331 err = p9_parse_header(&m->rc, NULL, NULL, NULL, 0);
336 if (n >= m->client->msize) { 332 if (err) {
333 p9_debug(P9_DEBUG_ERROR,
334 "error parsing header: %d\n", err);
335 goto error;
336 }
337
338 if (m->rc.size >= m->client->msize) {
337 p9_debug(P9_DEBUG_ERROR, 339 p9_debug(P9_DEBUG_ERROR,
338 "requested packet size too big: %d\n", n); 340 "requested packet size too big: %d\n",
341 m->rc.size);
339 err = -EIO; 342 err = -EIO;
340 goto error; 343 goto error;
341 } 344 }
342 345
343 tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
344 p9_debug(P9_DEBUG_TRANS, 346 p9_debug(P9_DEBUG_TRANS,
345 "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); 347 "mux %p pkt: size: %d bytes tag: %d\n",
348 m, m->rc.size, m->rc.tag);
346 349
347 m->req = p9_tag_lookup(m->client, tag); 350 m->req = p9_tag_lookup(m->client, m->rc.tag);
348 if (!m->req || (m->req->status != REQ_STATUS_SENT)) { 351 if (!m->req || (m->req->status != REQ_STATUS_SENT)) {
349 p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", 352 p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
350 tag); 353 m->rc.tag);
351 err = -EIO; 354 err = -EIO;
352 goto error; 355 goto error;
353 } 356 }
354 357
355 if (m->req->rc == NULL) { 358 if (m->req->rc == NULL) {
356 m->req->rc = kmalloc(sizeof(struct p9_fcall) + 359 p9_debug(P9_DEBUG_ERROR,
357 m->client->msize, GFP_NOFS); 360 "No recv fcall for tag %d (req %p), disconnecting!\n",
358 if (!m->req->rc) { 361 m->rc.tag, m->req);
359 m->req = NULL; 362 m->req = NULL;
360 err = -ENOMEM; 363 err = -EIO;
361 goto error; 364 goto error;
362 }
363 } 365 }
364 m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall); 366 m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall);
365 memcpy(m->rbuf, m->tmp_buf, m->rsize); 367 memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
366 m->rsize = n; 368 m->rc.capacity = m->rc.size;
367 } 369 }
368 370
369 /* not an else because some packets (like clunk) have no payload */ 371 /* packet is read in
370 if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */ 372 * not an else because some packets (like clunk) have no payload
373 */
374 if ((m->req) && (m->rc.offset == m->rc.capacity)) {
371 p9_debug(P9_DEBUG_TRANS, "got new packet\n"); 375 p9_debug(P9_DEBUG_TRANS, "got new packet\n");
372 spin_lock(&m->client->lock); 376 spin_lock(&m->client->lock);
373 if (m->req->status != REQ_STATUS_ERROR) 377 if (m->req->status != REQ_STATUS_ERROR)
@@ -375,9 +379,9 @@ static void p9_read_work(struct work_struct *work)
375 list_del(&m->req->req_list); 379 list_del(&m->req->req_list);
376 spin_unlock(&m->client->lock); 380 spin_unlock(&m->client->lock);
377 p9_client_cb(m->client, m->req, status); 381 p9_client_cb(m->client, m->req, status);
378 m->rbuf = NULL; 382 m->rc.sdata = NULL;
379 m->rpos = 0; 383 m->rc.offset = 0;
380 m->rsize = 0; 384 m->rc.capacity = 0;
381 m->req = NULL; 385 m->req = NULL;
382 } 386 }
383 387
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 199bc76202d2..4acb1d5417aa 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -658,7 +658,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
658 mutex_unlock(&virtio_9p_lock); 658 mutex_unlock(&virtio_9p_lock);
659 659
660 if (!found) { 660 if (!found) {
661 pr_err("no channels available\n"); 661 pr_err("no channels available for device %s\n", devname);
662 return ret; 662 return ret;
663 } 663 }
664 664