diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-24 15:39:09 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-24 15:39:09 -0500 |
commit | c52cb4311f20538fcb69420e55a19ac622546a08 (patch) | |
tree | f3fb973aa9271276bb17f7c78ac1e9e26d97e5e6 /net | |
parent | 00e3f5cc305c8a056a22cecedab3a71d59dae1fc (diff) | |
parent | a333e4bf2556b93c908e56b39be7bbd555f1b6cc (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.c | 88 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 2 |
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 | ||