diff options
| author | Dominique Martinet <dominique.martinet@cea.fr> | 2015-09-03 05:28:20 -0400 |
|---|---|---|
| committer | Eric Van Hensbergen <ericvh@gmail.com> | 2015-11-14 09:12:41 -0500 |
| commit | 947867aa195b65471f4767fdf761e3841577f90e (patch) | |
| tree | 3bcccc5dc06567d244b9ebad61ae54461e007317 | |
| parent | c7c72c5a127507687c737ede0f97d85bde674433 (diff) | |
9p: trans_fd, read rework to use p9_parse_header
Most of the changes here are no-op and just renaming to use a
fcall struct, needed for p9_parse_header
It fixes the unaligned memory access to read the tag and defers to
common functions for part of the protocol knowledge (although header
length is still hard-coded...)
Reported-By: Rob Landley <rob@landley.net>
Signed-Off-By: Dominique Martinet <dominique.martinet@cea.fr>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
| -rw-r--r-- | net/9p/trans_fd.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index bced8c074c12..a270dcc4ad9a 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,49 +301,56 @@ 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) { |
| 337 | p9_debug(P9_DEBUG_ERROR, | 333 | p9_debug(P9_DEBUG_ERROR, |
| 338 | "requested packet size too big: %d\n", n); | 334 | "error parsing header: %d\n", err); |
| 335 | goto error; | ||
| 336 | } | ||
| 337 | |||
| 338 | if (m->rc.size >= m->client->msize) { | ||
| 339 | p9_debug(P9_DEBUG_ERROR, | ||
| 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 | } |
| @@ -361,13 +364,15 @@ static void p9_read_work(struct work_struct *work) | |||
| 361 | goto error; | 364 | goto error; |
| 362 | } | 365 | } |
| 363 | } | 366 | } |
| 364 | m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall); | 367 | m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall); |
| 365 | memcpy(m->rbuf, m->tmp_buf, m->rsize); | 368 | memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity); |
| 366 | m->rsize = n; | 369 | m->rc.capacity = m->rc.size; |
| 367 | } | 370 | } |
| 368 | 371 | ||
| 369 | /* not an else because some packets (like clunk) have no payload */ | 372 | /* packet is read in |
| 370 | if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */ | 373 | * not an else because some packets (like clunk) have no payload |
| 374 | */ | ||
| 375 | if ((m->req) && (m->rc.offset == m->rc.capacity)) { | ||
| 371 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); | 376 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); |
| 372 | spin_lock(&m->client->lock); | 377 | spin_lock(&m->client->lock); |
| 373 | if (m->req->status != REQ_STATUS_ERROR) | 378 | if (m->req->status != REQ_STATUS_ERROR) |
| @@ -375,9 +380,9 @@ static void p9_read_work(struct work_struct *work) | |||
| 375 | list_del(&m->req->req_list); | 380 | list_del(&m->req->req_list); |
| 376 | spin_unlock(&m->client->lock); | 381 | spin_unlock(&m->client->lock); |
| 377 | p9_client_cb(m->client, m->req, status); | 382 | p9_client_cb(m->client, m->req, status); |
| 378 | m->rbuf = NULL; | 383 | m->rc.sdata = NULL; |
| 379 | m->rpos = 0; | 384 | m->rc.offset = 0; |
| 380 | m->rsize = 0; | 385 | m->rc.capacity = 0; |
| 381 | m->req = NULL; | 386 | m->req = NULL; |
| 382 | } | 387 | } |
| 383 | 388 | ||
