@@ -373,6 +373,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
373373 sk -> sk_prot -> hash (sk );
374374 sk_refcnt_debug_inc (sk );
375375 mutex_init (& smc -> clcsock_release_lock );
376+ smc_init_saved_callbacks (smc );
376377
377378 return sk ;
378379}
@@ -782,20 +783,32 @@ static void smc_fback_error_report(struct sock *clcsk)
782783 smc_fback_forward_wakeup (smc , clcsk , smc -> clcsk_error_report );
783784}
784785
786+ static void smc_fback_replace_callbacks (struct smc_sock * smc )
787+ {
788+ struct sock * clcsk = smc -> clcsock -> sk ;
789+
790+ clcsk -> sk_user_data = (void * )((uintptr_t )smc | SK_USER_DATA_NOCOPY );
791+
792+ smc_clcsock_replace_cb (& clcsk -> sk_state_change , smc_fback_state_change ,
793+ & smc -> clcsk_state_change );
794+ smc_clcsock_replace_cb (& clcsk -> sk_data_ready , smc_fback_data_ready ,
795+ & smc -> clcsk_data_ready );
796+ smc_clcsock_replace_cb (& clcsk -> sk_write_space , smc_fback_write_space ,
797+ & smc -> clcsk_write_space );
798+ smc_clcsock_replace_cb (& clcsk -> sk_error_report , smc_fback_error_report ,
799+ & smc -> clcsk_error_report );
800+ }
801+
785802static int smc_switch_to_fallback (struct smc_sock * smc , int reason_code )
786803{
787- struct sock * clcsk ;
788804 int rc = 0 ;
789805
790806 mutex_lock (& smc -> clcsock_release_lock );
791807 if (!smc -> clcsock ) {
792808 rc = - EBADF ;
793809 goto out ;
794810 }
795- clcsk = smc -> clcsock -> sk ;
796811
797- if (smc -> use_fallback )
798- goto out ;
799812 smc -> use_fallback = true;
800813 smc -> fallback_rsn = reason_code ;
801814 smc_stat_fallback (smc );
@@ -810,18 +823,7 @@ static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
810823 * in smc sk->sk_wq and they should be woken up
811824 * as clcsock's wait queue is woken up.
812825 */
813- smc -> clcsk_state_change = clcsk -> sk_state_change ;
814- smc -> clcsk_data_ready = clcsk -> sk_data_ready ;
815- smc -> clcsk_write_space = clcsk -> sk_write_space ;
816- smc -> clcsk_error_report = clcsk -> sk_error_report ;
817-
818- clcsk -> sk_state_change = smc_fback_state_change ;
819- clcsk -> sk_data_ready = smc_fback_data_ready ;
820- clcsk -> sk_write_space = smc_fback_write_space ;
821- clcsk -> sk_error_report = smc_fback_error_report ;
822-
823- smc -> clcsock -> sk -> sk_user_data =
824- (void * )((uintptr_t )smc | SK_USER_DATA_NOCOPY );
826+ smc_fback_replace_callbacks (smc );
825827 }
826828out :
827829 mutex_unlock (& smc -> clcsock_release_lock );
@@ -1596,6 +1598,19 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
15961598 * function; switch it back to the original sk_data_ready function
15971599 */
15981600 new_clcsock -> sk -> sk_data_ready = lsmc -> clcsk_data_ready ;
1601+
1602+ /* if new clcsock has also inherited the fallback-specific callback
1603+ * functions, switch them back to the original ones.
1604+ */
1605+ if (lsmc -> use_fallback ) {
1606+ if (lsmc -> clcsk_state_change )
1607+ new_clcsock -> sk -> sk_state_change = lsmc -> clcsk_state_change ;
1608+ if (lsmc -> clcsk_write_space )
1609+ new_clcsock -> sk -> sk_write_space = lsmc -> clcsk_write_space ;
1610+ if (lsmc -> clcsk_error_report )
1611+ new_clcsock -> sk -> sk_error_report = lsmc -> clcsk_error_report ;
1612+ }
1613+
15991614 (* new_smc )-> clcsock = new_clcsock ;
16001615out :
16011616 return rc ;
@@ -2397,10 +2412,10 @@ static int smc_listen(struct socket *sock, int backlog)
23972412 /* save original sk_data_ready function and establish
23982413 * smc-specific sk_data_ready function
23992414 */
2400- smc -> clcsk_data_ready = smc -> clcsock -> sk -> sk_data_ready ;
2401- smc -> clcsock -> sk -> sk_data_ready = smc_clcsock_data_ready ;
24022415 smc -> clcsock -> sk -> sk_user_data =
24032416 (void * )((uintptr_t )smc | SK_USER_DATA_NOCOPY );
2417+ smc_clcsock_replace_cb (& smc -> clcsock -> sk -> sk_data_ready ,
2418+ smc_clcsock_data_ready , & smc -> clcsk_data_ready );
24042419
24052420 /* save original ops */
24062421 smc -> ori_af_ops = inet_csk (smc -> clcsock -> sk )-> icsk_af_ops ;
@@ -2415,7 +2430,9 @@ static int smc_listen(struct socket *sock, int backlog)
24152430
24162431 rc = kernel_listen (smc -> clcsock , backlog );
24172432 if (rc ) {
2418- smc -> clcsock -> sk -> sk_data_ready = smc -> clcsk_data_ready ;
2433+ smc_clcsock_restore_cb (& smc -> clcsock -> sk -> sk_data_ready ,
2434+ & smc -> clcsk_data_ready );
2435+ smc -> clcsock -> sk -> sk_user_data = NULL ;
24192436 goto out ;
24202437 }
24212438 sk -> sk_max_ack_backlog = backlog ;
0 commit comments