| From 00e158fb91dfaff3f94746f260d11f1a4853506e Mon Sep 17 00:00:00 2001 |
| From: Tony Lu <tonylu@linux.alibaba.com> |
| Date: Wed, 1 Dec 2021 14:42:16 +0800 |
| Subject: net/smc: Keep smc_close_final rc during active close |
| |
| From: Tony Lu <tonylu@linux.alibaba.com> |
| |
| commit 00e158fb91dfaff3f94746f260d11f1a4853506e upstream. |
| |
| When smc_close_final() returns error, the return code overwrites by |
| kernel_sock_shutdown() in smc_close_active(). The return code of |
| smc_close_final() is more important than kernel_sock_shutdown(), and it |
| will pass to userspace directly. |
| |
| Fix it by keeping both return codes, if smc_close_final() raises an |
| error, return it or kernel_sock_shutdown()'s. |
| |
| Link: https://lore.kernel.org/linux-s390/1f67548e-cbf6-0dce-82b5-10288a4583bd@linux.ibm.com/ |
| Fixes: 606a63c9783a ("net/smc: Ensure the active closing peer first closes clcsock") |
| Suggested-by: Karsten Graul <kgraul@linux.ibm.com> |
| Signed-off-by: Tony Lu <tonylu@linux.alibaba.com> |
| Reviewed-by: Wen Gu <guwen@linux.alibaba.com> |
| Acked-by: Karsten Graul <kgraul@linux.ibm.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/smc/smc_close.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/net/smc/smc_close.c |
| +++ b/net/smc/smc_close.c |
| @@ -195,6 +195,7 @@ int smc_close_active(struct smc_sock *sm |
| int old_state; |
| long timeout; |
| int rc = 0; |
| + int rc1 = 0; |
| |
| timeout = current->flags & PF_EXITING ? |
| 0 : sock_flag(sk, SOCK_LINGER) ? |
| @@ -232,8 +233,11 @@ again: |
| /* actively shutdown clcsock before peer close it, |
| * prevent peer from entering TIME_WAIT state. |
| */ |
| - if (smc->clcsock && smc->clcsock->sk) |
| - rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); |
| + if (smc->clcsock && smc->clcsock->sk) { |
| + rc1 = kernel_sock_shutdown(smc->clcsock, |
| + SHUT_RDWR); |
| + rc = rc ? rc : rc1; |
| + } |
| } else { |
| /* peer event has changed the state */ |
| goto again; |