diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 114 | ||||
-rw-r--r-- | net/9p/trans_fd.c | 14 | ||||
-rw-r--r-- | net/9p/trans_rdma.c | 1 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 1 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 2 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 2 | ||||
-rw-r--r-- | net/rds/rds.h | 2 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 6 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_sendto.c | 3 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 3 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 26 |
12 files changed, 98 insertions, 78 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 1eb580c38fbb..dd43a8289b0d 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -203,7 +203,6 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag) | |||
203 | p9pdu_reset(req->tc); | 203 | p9pdu_reset(req->tc); |
204 | p9pdu_reset(req->rc); | 204 | p9pdu_reset(req->rc); |
205 | 205 | ||
206 | req->flush_tag = 0; | ||
207 | req->tc->tag = tag-1; | 206 | req->tc->tag = tag-1; |
208 | req->status = REQ_STATUS_ALLOC; | 207 | req->status = REQ_STATUS_ALLOC; |
209 | 208 | ||
@@ -324,35 +323,9 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r) | |||
324 | */ | 323 | */ |
325 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req) | 324 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req) |
326 | { | 325 | { |
327 | struct p9_req_t *other_req; | ||
328 | unsigned long flags; | ||
329 | |||
330 | P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); | 326 | P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); |
331 | 327 | wake_up(req->wq); | |
332 | if (req->status == REQ_STATUS_ERROR) | 328 | P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); |
333 | wake_up(req->wq); | ||
334 | |||
335 | if (req->flush_tag) { /* flush receive path */ | ||
336 | P9_DPRINTK(P9_DEBUG_9P, "<<< RFLUSH %d\n", req->tc->tag); | ||
337 | spin_lock_irqsave(&c->lock, flags); | ||
338 | other_req = p9_tag_lookup(c, req->flush_tag); | ||
339 | if (other_req->status != REQ_STATUS_FLSH) /* stale flush */ | ||
340 | spin_unlock_irqrestore(&c->lock, flags); | ||
341 | else { | ||
342 | other_req->status = REQ_STATUS_FLSHD; | ||
343 | spin_unlock_irqrestore(&c->lock, flags); | ||
344 | wake_up(other_req->wq); | ||
345 | } | ||
346 | p9_free_req(c, req); | ||
347 | } else { /* normal receive path */ | ||
348 | P9_DPRINTK(P9_DEBUG_MUX, "normal: tag %d\n", req->tc->tag); | ||
349 | spin_lock_irqsave(&c->lock, flags); | ||
350 | if (req->status != REQ_STATUS_FLSHD) | ||
351 | req->status = REQ_STATUS_RCVD; | ||
352 | spin_unlock_irqrestore(&c->lock, flags); | ||
353 | wake_up(req->wq); | ||
354 | P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); | ||
355 | } | ||
356 | } | 329 | } |
357 | EXPORT_SYMBOL(p9_client_cb); | 330 | EXPORT_SYMBOL(p9_client_cb); |
358 | 331 | ||
@@ -486,9 +459,15 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) | |||
486 | if (IS_ERR(req)) | 459 | if (IS_ERR(req)) |
487 | return PTR_ERR(req); | 460 | return PTR_ERR(req); |
488 | 461 | ||
489 | req->flush_tag = oldtag; | ||
490 | 462 | ||
491 | /* we don't free anything here because RPC isn't complete */ | 463 | /* if we haven't received a response for oldreq, |
464 | remove it from the list. */ | ||
465 | spin_lock(&c->lock); | ||
466 | if (oldreq->status == REQ_STATUS_FLSH) | ||
467 | list_del(&oldreq->req_list); | ||
468 | spin_unlock(&c->lock); | ||
469 | |||
470 | p9_free_req(c, req); | ||
492 | return 0; | 471 | return 0; |
493 | } | 472 | } |
494 | 473 | ||
@@ -509,7 +488,6 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) | |||
509 | struct p9_req_t *req; | 488 | struct p9_req_t *req; |
510 | unsigned long flags; | 489 | unsigned long flags; |
511 | int sigpending; | 490 | int sigpending; |
512 | int flushed = 0; | ||
513 | 491 | ||
514 | P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); | 492 | P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); |
515 | 493 | ||
@@ -546,42 +524,28 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) | |||
546 | goto reterr; | 524 | goto reterr; |
547 | } | 525 | } |
548 | 526 | ||
549 | /* if it was a flush we just transmitted, return our tag */ | ||
550 | if (type == P9_TFLUSH) | ||
551 | return req; | ||
552 | again: | ||
553 | P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag); | 527 | P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag); |
554 | err = wait_event_interruptible(*req->wq, | 528 | err = wait_event_interruptible(*req->wq, |
555 | req->status >= REQ_STATUS_RCVD); | 529 | req->status >= REQ_STATUS_RCVD); |
556 | P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d (flushed=%d)\n", | 530 | P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d\n", |
557 | req->wq, tag, err, flushed); | 531 | req->wq, tag, err); |
558 | 532 | ||
559 | if (req->status == REQ_STATUS_ERROR) { | 533 | if (req->status == REQ_STATUS_ERROR) { |
560 | P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); | 534 | P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); |
561 | err = req->t_err; | 535 | err = req->t_err; |
562 | } else if (err == -ERESTARTSYS && flushed) { | ||
563 | P9_DPRINTK(P9_DEBUG_MUX, "flushed - going again\n"); | ||
564 | goto again; | ||
565 | } else if (req->status == REQ_STATUS_FLSHD) { | ||
566 | P9_DPRINTK(P9_DEBUG_MUX, "flushed - erestartsys\n"); | ||
567 | err = -ERESTARTSYS; | ||
568 | } | 536 | } |
569 | 537 | ||
570 | if ((err == -ERESTARTSYS) && (c->status == Connected) && (!flushed)) { | 538 | if ((err == -ERESTARTSYS) && (c->status == Connected)) { |
571 | P9_DPRINTK(P9_DEBUG_MUX, "flushing\n"); | 539 | P9_DPRINTK(P9_DEBUG_MUX, "flushing\n"); |
572 | spin_lock_irqsave(&c->lock, flags); | ||
573 | if (req->status == REQ_STATUS_SENT) | ||
574 | req->status = REQ_STATUS_FLSH; | ||
575 | spin_unlock_irqrestore(&c->lock, flags); | ||
576 | sigpending = 1; | 540 | sigpending = 1; |
577 | flushed = 1; | ||
578 | clear_thread_flag(TIF_SIGPENDING); | 541 | clear_thread_flag(TIF_SIGPENDING); |
579 | 542 | ||
580 | if (c->trans_mod->cancel(c, req)) { | 543 | if (c->trans_mod->cancel(c, req)) |
581 | err = p9_client_flush(c, req); | 544 | p9_client_flush(c, req); |
582 | if (err == 0) | 545 | |
583 | goto again; | 546 | /* if we received the response anyway, don't signal error */ |
584 | } | 547 | if (req->status == REQ_STATUS_RCVD) |
548 | err = 0; | ||
585 | } | 549 | } |
586 | 550 | ||
587 | if (sigpending) { | 551 | if (sigpending) { |
@@ -1244,19 +1208,53 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | |||
1244 | ret->name, ret->uid, ret->gid, ret->muid, ret->extension, | 1208 | ret->name, ret->uid, ret->gid, ret->muid, ret->extension, |
1245 | ret->n_uid, ret->n_gid, ret->n_muid); | 1209 | ret->n_uid, ret->n_gid, ret->n_muid); |
1246 | 1210 | ||
1211 | p9_free_req(clnt, req); | ||
1212 | return ret; | ||
1213 | |||
1247 | free_and_error: | 1214 | free_and_error: |
1248 | p9_free_req(clnt, req); | 1215 | p9_free_req(clnt, req); |
1249 | error: | 1216 | error: |
1250 | return ret; | 1217 | kfree(ret); |
1218 | return ERR_PTR(err); | ||
1251 | } | 1219 | } |
1252 | EXPORT_SYMBOL(p9_client_stat); | 1220 | EXPORT_SYMBOL(p9_client_stat); |
1253 | 1221 | ||
1222 | static int p9_client_statsize(struct p9_wstat *wst, int optional) | ||
1223 | { | ||
1224 | int ret; | ||
1225 | |||
1226 | /* size[2] type[2] dev[4] qid[13] */ | ||
1227 | /* mode[4] atime[4] mtime[4] length[8]*/ | ||
1228 | /* name[s] uid[s] gid[s] muid[s] */ | ||
1229 | ret = 2+2+4+13+4+4+4+8+2+2+2+2; | ||
1230 | |||
1231 | if (wst->name) | ||
1232 | ret += strlen(wst->name); | ||
1233 | if (wst->uid) | ||
1234 | ret += strlen(wst->uid); | ||
1235 | if (wst->gid) | ||
1236 | ret += strlen(wst->gid); | ||
1237 | if (wst->muid) | ||
1238 | ret += strlen(wst->muid); | ||
1239 | |||
1240 | if (optional) { | ||
1241 | ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */ | ||
1242 | if (wst->extension) | ||
1243 | ret += strlen(wst->extension); | ||
1244 | } | ||
1245 | |||
1246 | return ret; | ||
1247 | } | ||
1248 | |||
1254 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | 1249 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) |
1255 | { | 1250 | { |
1256 | int err; | 1251 | int err; |
1257 | struct p9_req_t *req; | 1252 | struct p9_req_t *req; |
1258 | struct p9_client *clnt; | 1253 | struct p9_client *clnt; |
1259 | 1254 | ||
1255 | err = 0; | ||
1256 | clnt = fid->clnt; | ||
1257 | wst->size = p9_client_statsize(wst, clnt->dotu); | ||
1260 | P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid); | 1258 | P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid); |
1261 | P9_DPRINTK(P9_DEBUG_9P, | 1259 | P9_DPRINTK(P9_DEBUG_9P, |
1262 | " sz=%x type=%x dev=%x qid=%x.%llx.%x\n" | 1260 | " sz=%x type=%x dev=%x qid=%x.%llx.%x\n" |
@@ -1268,10 +1266,8 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | |||
1268 | wst->atime, wst->mtime, (unsigned long long)wst->length, | 1266 | wst->atime, wst->mtime, (unsigned long long)wst->length, |
1269 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, | 1267 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, |
1270 | wst->n_uid, wst->n_gid, wst->n_muid); | 1268 | wst->n_uid, wst->n_gid, wst->n_muid); |
1271 | err = 0; | ||
1272 | clnt = fid->clnt; | ||
1273 | 1269 | ||
1274 | req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, 0, wst); | 1270 | req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size, wst); |
1275 | if (IS_ERR(req)) { | 1271 | if (IS_ERR(req)) { |
1276 | err = PTR_ERR(req); | 1272 | err = PTR_ERR(req); |
1277 | goto error; | 1273 | goto error; |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index c613ed08a5ee..a2a1814c7a8d 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -213,8 +213,8 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
213 | spin_unlock_irqrestore(&m->client->lock, flags); | 213 | spin_unlock_irqrestore(&m->client->lock, flags); |
214 | 214 | ||
215 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { | 215 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { |
216 | list_del(&req->req_list); | ||
217 | P9_DPRINTK(P9_DEBUG_ERROR, "call back req %p\n", req); | 216 | P9_DPRINTK(P9_DEBUG_ERROR, "call back req %p\n", req); |
217 | list_del(&req->req_list); | ||
218 | p9_client_cb(m->client, req); | 218 | p9_client_cb(m->client, req); |
219 | } | 219 | } |
220 | } | 220 | } |
@@ -336,7 +336,8 @@ static void p9_read_work(struct work_struct *work) | |||
336 | "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); | 336 | "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); |
337 | 337 | ||
338 | m->req = p9_tag_lookup(m->client, tag); | 338 | m->req = p9_tag_lookup(m->client, tag); |
339 | if (!m->req) { | 339 | if (!m->req || (m->req->status != REQ_STATUS_SENT && |
340 | m->req->status != REQ_STATUS_FLSH)) { | ||
340 | P9_DPRINTK(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", | 341 | P9_DPRINTK(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", |
341 | tag); | 342 | tag); |
342 | err = -EIO; | 343 | err = -EIO; |
@@ -361,10 +362,11 @@ static void p9_read_work(struct work_struct *work) | |||
361 | if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */ | 362 | if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */ |
362 | P9_DPRINTK(P9_DEBUG_TRANS, "got new packet\n"); | 363 | P9_DPRINTK(P9_DEBUG_TRANS, "got new packet\n"); |
363 | spin_lock(&m->client->lock); | 364 | spin_lock(&m->client->lock); |
365 | if (m->req->status != REQ_STATUS_ERROR) | ||
366 | m->req->status = REQ_STATUS_RCVD; | ||
364 | list_del(&m->req->req_list); | 367 | list_del(&m->req->req_list); |
365 | spin_unlock(&m->client->lock); | 368 | spin_unlock(&m->client->lock); |
366 | p9_client_cb(m->client, m->req); | 369 | p9_client_cb(m->client, m->req); |
367 | |||
368 | m->rbuf = NULL; | 370 | m->rbuf = NULL; |
369 | m->rpos = 0; | 371 | m->rpos = 0; |
370 | m->rsize = 0; | 372 | m->rsize = 0; |
@@ -454,6 +456,7 @@ static void p9_write_work(struct work_struct *work) | |||
454 | req = list_entry(m->unsent_req_list.next, struct p9_req_t, | 456 | req = list_entry(m->unsent_req_list.next, struct p9_req_t, |
455 | req_list); | 457 | req_list); |
456 | req->status = REQ_STATUS_SENT; | 458 | req->status = REQ_STATUS_SENT; |
459 | P9_DPRINTK(P9_DEBUG_TRANS, "move req %p\n", req); | ||
457 | list_move_tail(&req->req_list, &m->req_list); | 460 | list_move_tail(&req->req_list, &m->req_list); |
458 | 461 | ||
459 | m->wbuf = req->tc->sdata; | 462 | m->wbuf = req->tc->sdata; |
@@ -683,12 +686,13 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) | |||
683 | P9_DPRINTK(P9_DEBUG_TRANS, "client %p req %p\n", client, req); | 686 | P9_DPRINTK(P9_DEBUG_TRANS, "client %p req %p\n", client, req); |
684 | 687 | ||
685 | spin_lock(&client->lock); | 688 | spin_lock(&client->lock); |
686 | list_del(&req->req_list); | ||
687 | 689 | ||
688 | if (req->status == REQ_STATUS_UNSENT) { | 690 | if (req->status == REQ_STATUS_UNSENT) { |
691 | list_del(&req->req_list); | ||
689 | req->status = REQ_STATUS_FLSHD; | 692 | req->status = REQ_STATUS_FLSHD; |
690 | ret = 0; | 693 | ret = 0; |
691 | } | 694 | } else if (req->status == REQ_STATUS_SENT) |
695 | req->status = REQ_STATUS_FLSH; | ||
692 | 696 | ||
693 | spin_unlock(&client->lock); | 697 | spin_unlock(&client->lock); |
694 | 698 | ||
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 7fa0eb20b2f6..ac4990041ebb 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
@@ -295,6 +295,7 @@ handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma, | |||
295 | goto err_out; | 295 | goto err_out; |
296 | 296 | ||
297 | req->rc = c->rc; | 297 | req->rc = c->rc; |
298 | req->status = REQ_STATUS_RCVD; | ||
298 | p9_client_cb(client, req); | 299 | p9_client_cb(client, req); |
299 | 300 | ||
300 | return; | 301 | return; |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 2d7781ec663b..bb8579a141a8 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -134,6 +134,7 @@ static void req_done(struct virtqueue *vq) | |||
134 | P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc); | 134 | P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc); |
135 | P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag); | 135 | P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag); |
136 | req = p9_tag_lookup(chan->client, rc->tag); | 136 | req = p9_tag_lookup(chan->client, rc->tag); |
137 | req->status = REQ_STATUS_RCVD; | ||
137 | p9_client_cb(chan->client, req); | 138 | p9_client_cb(chan->client, req); |
138 | } | 139 | } |
139 | } | 140 | } |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 70df3dcc3cf6..d9233ec50610 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -477,7 +477,7 @@ minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
477 | 477 | ||
478 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 478 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
479 | sband = hw->wiphy->bands[i]; | 479 | sband = hw->wiphy->bands[i]; |
480 | if (sband->n_bitrates > max_rates) | 480 | if (sband && sband->n_bitrates > max_rates) |
481 | max_rates = sband->n_bitrates; | 481 | max_rates = sband->n_bitrates; |
482 | } | 482 | } |
483 | 483 | ||
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 01d59a8e334c..8bef9a1262ff 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -378,7 +378,7 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw, | |||
378 | 378 | ||
379 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 379 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
380 | sband = hw->wiphy->bands[i]; | 380 | sband = hw->wiphy->bands[i]; |
381 | if (sband->n_bitrates > max_rates) | 381 | if (sband && sband->n_bitrates > max_rates) |
382 | max_rates = sband->n_bitrates; | 382 | max_rates = sband->n_bitrates; |
383 | } | 383 | } |
384 | 384 | ||
diff --git a/net/rds/rds.h b/net/rds/rds.h index 619f0a30a4e5..71794449ca4e 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h | |||
@@ -638,7 +638,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *, | |||
638 | void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force); | 638 | void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force); |
639 | 639 | ||
640 | /* stats.c */ | 640 | /* stats.c */ |
641 | DECLARE_PER_CPU(struct rds_statistics, rds_stats); | 641 | DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats); |
642 | #define rds_stats_inc_which(which, member) do { \ | 642 | #define rds_stats_inc_which(which, member) do { \ |
643 | per_cpu(which, get_cpu()).member++; \ | 643 | per_cpu(which, get_cpu()).member++; \ |
644 | put_cpu(); \ | 644 | put_cpu(); \ |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index a0bfe53f1621..06ca058572f2 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -672,10 +672,8 @@ xprt_init_autodisconnect(unsigned long data) | |||
672 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) | 672 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) |
673 | goto out_abort; | 673 | goto out_abort; |
674 | spin_unlock(&xprt->transport_lock); | 674 | spin_unlock(&xprt->transport_lock); |
675 | if (xprt_connecting(xprt)) | 675 | set_bit(XPRT_CONNECTION_CLOSE, &xprt->state); |
676 | xprt_release_write(xprt, NULL); | 676 | queue_work(rpciod_workqueue, &xprt->task_cleanup); |
677 | else | ||
678 | queue_work(rpciod_workqueue, &xprt->task_cleanup); | ||
679 | return; | 677 | return; |
680 | out_abort: | 678 | out_abort: |
681 | spin_unlock(&xprt->transport_lock); | 679 | spin_unlock(&xprt->transport_lock); |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 629a28764da9..42a6f9f20285 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
@@ -265,7 +265,7 @@ static int fast_reg_read_chunks(struct svcxprt_rdma *xprt, | |||
265 | frmr->page_list->page_list[page_no] = | 265 | frmr->page_list->page_list[page_no] = |
266 | ib_dma_map_single(xprt->sc_cm_id->device, | 266 | ib_dma_map_single(xprt->sc_cm_id->device, |
267 | page_address(rqstp->rq_arg.pages[page_no]), | 267 | page_address(rqstp->rq_arg.pages[page_no]), |
268 | PAGE_SIZE, DMA_TO_DEVICE); | 268 | PAGE_SIZE, DMA_FROM_DEVICE); |
269 | if (ib_dma_mapping_error(xprt->sc_cm_id->device, | 269 | if (ib_dma_mapping_error(xprt->sc_cm_id->device, |
270 | frmr->page_list->page_list[page_no])) | 270 | frmr->page_list->page_list[page_no])) |
271 | goto fatal_err; | 271 | goto fatal_err; |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 6c26a675435a..8b510c5e8777 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c | |||
@@ -183,6 +183,7 @@ static int fast_reg_xdr(struct svcxprt_rdma *xprt, | |||
183 | 183 | ||
184 | fatal_err: | 184 | fatal_err: |
185 | printk("svcrdma: Error fast registering memory for xprt %p\n", xprt); | 185 | printk("svcrdma: Error fast registering memory for xprt %p\n", xprt); |
186 | vec->frmr = NULL; | ||
186 | svc_rdma_put_frmr(xprt, frmr); | 187 | svc_rdma_put_frmr(xprt, frmr); |
187 | return -EIO; | 188 | return -EIO; |
188 | } | 189 | } |
@@ -516,6 +517,7 @@ static int send_reply(struct svcxprt_rdma *rdma, | |||
516 | "svcrdma: could not post a receive buffer, err=%d." | 517 | "svcrdma: could not post a receive buffer, err=%d." |
517 | "Closing transport %p.\n", ret, rdma); | 518 | "Closing transport %p.\n", ret, rdma); |
518 | set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); | 519 | set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); |
520 | svc_rdma_put_frmr(rdma, vec->frmr); | ||
519 | svc_rdma_put_context(ctxt, 0); | 521 | svc_rdma_put_context(ctxt, 0); |
520 | return -ENOTCONN; | 522 | return -ENOTCONN; |
521 | } | 523 | } |
@@ -606,6 +608,7 @@ static int send_reply(struct svcxprt_rdma *rdma, | |||
606 | return 0; | 608 | return 0; |
607 | 609 | ||
608 | err: | 610 | err: |
611 | svc_rdma_unmap_dma(ctxt); | ||
609 | svc_rdma_put_frmr(rdma, vec->frmr); | 612 | svc_rdma_put_frmr(rdma, vec->frmr); |
610 | svc_rdma_put_context(ctxt, 1); | 613 | svc_rdma_put_context(ctxt, 1); |
611 | return -EIO; | 614 | return -EIO; |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 3d810e7df3fb..4b0c2fa15e0b 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -520,8 +520,9 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt) | |||
520 | svc_xprt_get(&xprt->sc_xprt); | 520 | svc_xprt_get(&xprt->sc_xprt); |
521 | ret = ib_post_recv(xprt->sc_qp, &recv_wr, &bad_recv_wr); | 521 | ret = ib_post_recv(xprt->sc_qp, &recv_wr, &bad_recv_wr); |
522 | if (ret) { | 522 | if (ret) { |
523 | svc_xprt_put(&xprt->sc_xprt); | 523 | svc_rdma_unmap_dma(ctxt); |
524 | svc_rdma_put_context(ctxt, 1); | 524 | svc_rdma_put_context(ctxt, 1); |
525 | svc_xprt_put(&xprt->sc_xprt); | ||
525 | } | 526 | } |
526 | return ret; | 527 | return ret; |
527 | 528 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index d40ff50887aa..e18596146013 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -807,6 +807,9 @@ static void xs_reset_transport(struct sock_xprt *transport) | |||
807 | * | 807 | * |
808 | * This is used when all requests are complete; ie, no DRC state remains | 808 | * This is used when all requests are complete; ie, no DRC state remains |
809 | * on the server we want to save. | 809 | * on the server we want to save. |
810 | * | ||
811 | * The caller _must_ be holding XPRT_LOCKED in order to avoid issues with | ||
812 | * xs_reset_transport() zeroing the socket from underneath a writer. | ||
810 | */ | 813 | */ |
811 | static void xs_close(struct rpc_xprt *xprt) | 814 | static void xs_close(struct rpc_xprt *xprt) |
812 | { | 815 | { |
@@ -824,6 +827,14 @@ static void xs_close(struct rpc_xprt *xprt) | |||
824 | xprt_disconnect_done(xprt); | 827 | xprt_disconnect_done(xprt); |
825 | } | 828 | } |
826 | 829 | ||
830 | static void xs_tcp_close(struct rpc_xprt *xprt) | ||
831 | { | ||
832 | if (test_and_clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state)) | ||
833 | xs_close(xprt); | ||
834 | else | ||
835 | xs_tcp_shutdown(xprt); | ||
836 | } | ||
837 | |||
827 | /** | 838 | /** |
828 | * xs_destroy - prepare to shutdown a transport | 839 | * xs_destroy - prepare to shutdown a transport |
829 | * @xprt: doomed transport | 840 | * @xprt: doomed transport |
@@ -1772,6 +1783,15 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | |||
1772 | xprt, -status, xprt_connected(xprt), | 1783 | xprt, -status, xprt_connected(xprt), |
1773 | sock->sk->sk_state); | 1784 | sock->sk->sk_state); |
1774 | switch (status) { | 1785 | switch (status) { |
1786 | default: | ||
1787 | printk("%s: connect returned unhandled error %d\n", | ||
1788 | __func__, status); | ||
1789 | case -EADDRNOTAVAIL: | ||
1790 | /* We're probably in TIME_WAIT. Get rid of existing socket, | ||
1791 | * and retry | ||
1792 | */ | ||
1793 | set_bit(XPRT_CONNECTION_CLOSE, &xprt->state); | ||
1794 | xprt_force_disconnect(xprt); | ||
1775 | case -ECONNREFUSED: | 1795 | case -ECONNREFUSED: |
1776 | case -ECONNRESET: | 1796 | case -ECONNRESET: |
1777 | case -ENETUNREACH: | 1797 | case -ENETUNREACH: |
@@ -1782,10 +1802,6 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | |||
1782 | xprt_clear_connecting(xprt); | 1802 | xprt_clear_connecting(xprt); |
1783 | return; | 1803 | return; |
1784 | } | 1804 | } |
1785 | /* get rid of existing socket, and retry */ | ||
1786 | xs_tcp_shutdown(xprt); | ||
1787 | printk("%s: connect returned unhandled error %d\n", | ||
1788 | __func__, status); | ||
1789 | out_eagain: | 1805 | out_eagain: |
1790 | status = -EAGAIN; | 1806 | status = -EAGAIN; |
1791 | out: | 1807 | out: |
@@ -1994,7 +2010,7 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
1994 | .buf_free = rpc_free, | 2010 | .buf_free = rpc_free, |
1995 | .send_request = xs_tcp_send_request, | 2011 | .send_request = xs_tcp_send_request, |
1996 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | 2012 | .set_retrans_timeout = xprt_set_retrans_timeout_def, |
1997 | .close = xs_tcp_shutdown, | 2013 | .close = xs_tcp_close, |
1998 | .destroy = xs_destroy, | 2014 | .destroy = xs_destroy, |
1999 | .print_stats = xs_tcp_print_stats, | 2015 | .print_stats = xs_tcp_print_stats, |
2000 | }; | 2016 | }; |