Skip to content

Commit bacb6c1

Browse files
tonylujkuba-moo
authored andcommitted
net/smc: Don't call clcsock shutdown twice when smc shutdown
When applications call shutdown() with SHUT_RDWR in userspace, smc_close_active() calls kernel_sock_shutdown(), and it is called twice in smc_shutdown(). This fixes this by checking sk_state before do clcsock shutdown, and avoids missing the application's call of smc_shutdown(). Link: https://lore.kernel.org/linux-s390/[email protected]/ Fixes: 606a63c ("net/smc: Ensure the active closing peer first closes clcsock") Signed-off-by: Tony Lu <[email protected]> Reviewed-by: Wen Gu <[email protected]> Acked-by: Karsten Graul <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 01d9cc2 commit bacb6c1

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

net/smc/af_smc.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2370,8 +2370,10 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
23702370
static int smc_shutdown(struct socket *sock, int how)
23712371
{
23722372
struct sock *sk = sock->sk;
2373+
bool do_shutdown = true;
23732374
struct smc_sock *smc;
23742375
int rc = -EINVAL;
2376+
int old_state;
23752377
int rc1 = 0;
23762378

23772379
smc = smc_sk(sk);
@@ -2398,7 +2400,11 @@ static int smc_shutdown(struct socket *sock, int how)
23982400
}
23992401
switch (how) {
24002402
case SHUT_RDWR: /* shutdown in both directions */
2403+
old_state = sk->sk_state;
24012404
rc = smc_close_active(smc);
2405+
if (old_state == SMC_ACTIVE &&
2406+
sk->sk_state == SMC_PEERCLOSEWAIT1)
2407+
do_shutdown = false;
24022408
break;
24032409
case SHUT_WR:
24042410
rc = smc_close_shutdown_write(smc);
@@ -2408,7 +2414,7 @@ static int smc_shutdown(struct socket *sock, int how)
24082414
/* nothing more to do because peer is not involved */
24092415
break;
24102416
}
2411-
if (smc->clcsock)
2417+
if (do_shutdown && smc->clcsock)
24122418
rc1 = kernel_sock_shutdown(smc->clcsock, how);
24132419
/* map sock_shutdown_cmd constants to sk_shutdown value range */
24142420
sk->sk_shutdown |= how + 1;

0 commit comments

Comments
 (0)