diff options
author | Josef Bacik <jbacik@fb.com> | 2017-10-24 15:57:18 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-10-24 20:50:59 -0400 |
commit | 32e67a3a06b88904155170560b7a63d372b320bd (patch) | |
tree | b51b63e136dec5ffeb42af6c68fe866b719fbd6d | |
parent | 875397464a55dd750198f799626959ad4cf45563 (diff) |
nbd: handle interrupted sendmsg with a sndtimeo set
If you do not set sk_sndtimeo you will get -ERESTARTSYS if there is a
pending signal when you enter sendmsg, which we handle properly.
However if you set a timeout for your commands we'll set sk_sndtimeo to
that timeout, which means that sendmsg will start returning -EINTR
instead of -ERESTARTSYS. Fix this by checking either cases and doing
the correct thing.
Cc: stable@vger.kernel.org
Fixes: dc88e34d69d8 ("nbd: set sk->sk_sndtimeo for our sockets")
Reported-and-tested-by: Daniel Xu <dlxu@fb.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/nbd.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index baebbdfd74d5..9adfb5445f8d 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -386,6 +386,15 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, | |||
386 | return result; | 386 | return result; |
387 | } | 387 | } |
388 | 388 | ||
389 | /* | ||
390 | * Different settings for sk->sk_sndtimeo can result in different return values | ||
391 | * if there is a signal pending when we enter sendmsg, because reasons? | ||
392 | */ | ||
393 | static inline int was_interrupted(int result) | ||
394 | { | ||
395 | return result == -ERESTARTSYS || result == -EINTR; | ||
396 | } | ||
397 | |||
389 | /* always call with the tx_lock held */ | 398 | /* always call with the tx_lock held */ |
390 | static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) | 399 | static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) |
391 | { | 400 | { |
@@ -458,7 +467,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) | |||
458 | result = sock_xmit(nbd, index, 1, &from, | 467 | result = sock_xmit(nbd, index, 1, &from, |
459 | (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); | 468 | (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); |
460 | if (result <= 0) { | 469 | if (result <= 0) { |
461 | if (result == -ERESTARTSYS) { | 470 | if (was_interrupted(result)) { |
462 | /* If we havne't sent anything we can just return BUSY, | 471 | /* If we havne't sent anything we can just return BUSY, |
463 | * however if we have sent something we need to make | 472 | * however if we have sent something we need to make |
464 | * sure we only allow this req to be sent until we are | 473 | * sure we only allow this req to be sent until we are |
@@ -502,7 +511,7 @@ send_pages: | |||
502 | } | 511 | } |
503 | result = sock_xmit(nbd, index, 1, &from, flags, &sent); | 512 | result = sock_xmit(nbd, index, 1, &from, flags, &sent); |
504 | if (result <= 0) { | 513 | if (result <= 0) { |
505 | if (result == -ERESTARTSYS) { | 514 | if (was_interrupted(result)) { |
506 | /* We've already sent the header, we | 515 | /* We've already sent the header, we |
507 | * have no choice but to set pending and | 516 | * have no choice but to set pending and |
508 | * return BUSY. | 517 | * return BUSY. |