@@ -568,6 +568,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
568568 }
569569 t -> negotiation_requested = true;
570570 t -> full_packet_received = true;
571+ enqueue_reassembly (t , recvmsg , 0 );
571572 wake_up_interruptible (& t -> wait_status );
572573 break ;
573574 case SMB_DIRECT_MSG_DATA_TRANSFER : {
@@ -1594,19 +1595,13 @@ static int smb_direct_accept_client(struct smb_direct_transport *t)
15941595 pr_err ("error at rdma_accept: %d\n" , ret );
15951596 return ret ;
15961597 }
1597-
1598- wait_event_interruptible (t -> wait_status ,
1599- t -> status != SMB_DIRECT_CS_NEW );
1600- if (t -> status != SMB_DIRECT_CS_CONNECTED )
1601- return - ENOTCONN ;
16021598 return 0 ;
16031599}
16041600
1605- static int smb_direct_negotiate (struct smb_direct_transport * t )
1601+ static int smb_direct_prepare_negotiation (struct smb_direct_transport * t )
16061602{
16071603 int ret ;
16081604 struct smb_direct_recvmsg * recvmsg ;
1609- struct smb_direct_negotiate_req * req ;
16101605
16111606 recvmsg = get_free_recvmsg (t );
16121607 if (!recvmsg )
@@ -1616,44 +1611,20 @@ static int smb_direct_negotiate(struct smb_direct_transport *t)
16161611 ret = smb_direct_post_recv (t , recvmsg );
16171612 if (ret ) {
16181613 pr_err ("Can't post recv: %d\n" , ret );
1619- goto out ;
1614+ goto out_err ;
16201615 }
16211616
16221617 t -> negotiation_requested = false;
16231618 ret = smb_direct_accept_client (t );
16241619 if (ret ) {
16251620 pr_err ("Can't accept client\n" );
1626- goto out ;
1621+ goto out_err ;
16271622 }
16281623
16291624 smb_direct_post_recv_credits (& t -> post_recv_credits_work .work );
1630-
1631- ksmbd_debug (RDMA , "Waiting for SMB_DIRECT negotiate request\n" );
1632- ret = wait_event_interruptible_timeout (t -> wait_status ,
1633- t -> negotiation_requested ||
1634- t -> status == SMB_DIRECT_CS_DISCONNECTED ,
1635- SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ );
1636- if (ret <= 0 || t -> status == SMB_DIRECT_CS_DISCONNECTED ) {
1637- ret = ret < 0 ? ret : - ETIMEDOUT ;
1638- goto out ;
1639- }
1640-
1641- ret = smb_direct_check_recvmsg (recvmsg );
1642- if (ret == - ECONNABORTED )
1643- goto out ;
1644-
1645- req = (struct smb_direct_negotiate_req * )recvmsg -> packet ;
1646- t -> max_recv_size = min_t (int , t -> max_recv_size ,
1647- le32_to_cpu (req -> preferred_send_size ));
1648- t -> max_send_size = min_t (int , t -> max_send_size ,
1649- le32_to_cpu (req -> max_receive_size ));
1650- t -> max_fragmented_send_size =
1651- le32_to_cpu (req -> max_fragmented_size );
1652-
1653- ret = smb_direct_send_negotiate_response (t , ret );
1654- out :
1655- if (recvmsg )
1656- put_recvmsg (t , recvmsg );
1625+ return 0 ;
1626+ out_err :
1627+ put_recvmsg (t , recvmsg );
16571628 return ret ;
16581629}
16591630
@@ -1890,6 +1861,47 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t,
18901861static int smb_direct_prepare (struct ksmbd_transport * t )
18911862{
18921863 struct smb_direct_transport * st = smb_trans_direct_transfort (t );
1864+ struct smb_direct_recvmsg * recvmsg ;
1865+ struct smb_direct_negotiate_req * req ;
1866+ int ret ;
1867+
1868+ ksmbd_debug (RDMA , "Waiting for SMB_DIRECT negotiate request\n" );
1869+ ret = wait_event_interruptible_timeout (st -> wait_status ,
1870+ st -> negotiation_requested ||
1871+ st -> status == SMB_DIRECT_CS_DISCONNECTED ,
1872+ SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ );
1873+ if (ret <= 0 || st -> status == SMB_DIRECT_CS_DISCONNECTED )
1874+ return ret < 0 ? ret : - ETIMEDOUT ;
1875+
1876+ recvmsg = get_first_reassembly (st );
1877+ if (!recvmsg )
1878+ return - ECONNABORTED ;
1879+
1880+ ret = smb_direct_check_recvmsg (recvmsg );
1881+ if (ret == - ECONNABORTED )
1882+ goto out ;
1883+
1884+ req = (struct smb_direct_negotiate_req * )recvmsg -> packet ;
1885+ st -> max_recv_size = min_t (int , st -> max_recv_size ,
1886+ le32_to_cpu (req -> preferred_send_size ));
1887+ st -> max_send_size = min_t (int , st -> max_send_size ,
1888+ le32_to_cpu (req -> max_receive_size ));
1889+ st -> max_fragmented_send_size =
1890+ le32_to_cpu (req -> max_fragmented_size );
1891+
1892+ ret = smb_direct_send_negotiate_response (st , ret );
1893+ out :
1894+ spin_lock_irq (& st -> reassembly_queue_lock );
1895+ st -> reassembly_queue_length -- ;
1896+ list_del (& recvmsg -> list );
1897+ spin_unlock_irq (& st -> reassembly_queue_lock );
1898+ put_recvmsg (st , recvmsg );
1899+
1900+ return ret ;
1901+ }
1902+
1903+ static int smb_direct_connect (struct smb_direct_transport * st )
1904+ {
18931905 int ret ;
18941906 struct ib_qp_cap qp_cap ;
18951907
@@ -1911,13 +1923,11 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
19111923 return ret ;
19121924 }
19131925
1914- ret = smb_direct_negotiate (st );
1926+ ret = smb_direct_prepare_negotiation (st );
19151927 if (ret ) {
19161928 pr_err ("Can't negotiate: %d\n" , ret );
19171929 return ret ;
19181930 }
1919-
1920- st -> status = SMB_DIRECT_CS_CONNECTED ;
19211931 return 0 ;
19221932}
19231933
@@ -1933,6 +1943,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs)
19331943static int smb_direct_handle_connect_request (struct rdma_cm_id * new_cm_id )
19341944{
19351945 struct smb_direct_transport * t ;
1946+ int ret ;
19361947
19371948 if (!rdma_frwr_is_supported (& new_cm_id -> device -> attrs )) {
19381949 ksmbd_debug (RDMA ,
@@ -1945,18 +1956,23 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
19451956 if (!t )
19461957 return - ENOMEM ;
19471958
1959+ ret = smb_direct_connect (t );
1960+ if (ret )
1961+ goto out_err ;
1962+
19481963 KSMBD_TRANS (t )-> handler = kthread_run (ksmbd_conn_handler_loop ,
19491964 KSMBD_TRANS (t )-> conn , "ksmbd:r%u" ,
19501965 smb_direct_port );
19511966 if (IS_ERR (KSMBD_TRANS (t )-> handler )) {
1952- int ret = PTR_ERR (KSMBD_TRANS (t )-> handler );
1953-
1967+ ret = PTR_ERR (KSMBD_TRANS (t )-> handler );
19541968 pr_err ("Can't start thread\n" );
1955- free_transport (t );
1956- return ret ;
1969+ goto out_err ;
19571970 }
19581971
19591972 return 0 ;
1973+ out_err :
1974+ free_transport (t );
1975+ return ret ;
19601976}
19611977
19621978static int smb_direct_listen_handler (struct rdma_cm_id * cm_id ,
0 commit comments