@@ -1993,6 +1993,9 @@ int smb2_tree_connect(struct ksmbd_work *work)
19931993 if (conn -> posix_ext_supported )
19941994 status .tree_conn -> posix_extensions = true;
19951995
1996+ write_lock (& sess -> tree_conns_lock );
1997+ status .tree_conn -> t_state = TREE_CONNECTED ;
1998+ write_unlock (& sess -> tree_conns_lock );
19961999 rsp -> StructureSize = cpu_to_le16 (16 );
19972000out_err1 :
19982001 rsp -> Capabilities = 0 ;
@@ -2122,27 +2125,50 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
21222125
21232126 ksmbd_debug (SMB , "request\n" );
21242127
2128+ if (!tcon ) {
2129+ ksmbd_debug (SMB , "Invalid tid %d\n" , req -> hdr .Id .SyncId .TreeId );
2130+
2131+ rsp -> hdr .Status = STATUS_NETWORK_NAME_DELETED ;
2132+ err = - ENOENT ;
2133+ goto err_out ;
2134+ }
2135+
2136+ ksmbd_close_tree_conn_fds (work );
2137+
2138+ write_lock (& sess -> tree_conns_lock );
2139+ if (tcon -> t_state == TREE_DISCONNECTED ) {
2140+ write_unlock (& sess -> tree_conns_lock );
2141+ rsp -> hdr .Status = STATUS_NETWORK_NAME_DELETED ;
2142+ err = - ENOENT ;
2143+ goto err_out ;
2144+ }
2145+
2146+ WARN_ON_ONCE (atomic_dec_and_test (& tcon -> refcount ));
2147+ tcon -> t_state = TREE_DISCONNECTED ;
2148+ write_unlock (& sess -> tree_conns_lock );
2149+
2150+ err = ksmbd_tree_conn_disconnect (sess , tcon );
2151+ if (err ) {
2152+ rsp -> hdr .Status = STATUS_NETWORK_NAME_DELETED ;
2153+ goto err_out ;
2154+ }
2155+
2156+ work -> tcon = NULL ;
2157+
21252158 rsp -> StructureSize = cpu_to_le16 (4 );
21262159 err = ksmbd_iov_pin_rsp (work , rsp ,
21272160 sizeof (struct smb2_tree_disconnect_rsp ));
21282161 if (err ) {
21292162 rsp -> hdr .Status = STATUS_INSUFFICIENT_RESOURCES ;
2130- smb2_set_err_rsp (work );
2131- return err ;
2163+ goto err_out ;
21322164 }
21332165
2134- if (!tcon || test_and_set_bit (TREE_CONN_EXPIRE , & tcon -> status )) {
2135- ksmbd_debug (SMB , "Invalid tid %d\n" , req -> hdr .Id .SyncId .TreeId );
2166+ return 0 ;
21362167
2137- rsp -> hdr .Status = STATUS_NETWORK_NAME_DELETED ;
2138- smb2_set_err_rsp (work );
2139- return - ENOENT ;
2140- }
2168+ err_out :
2169+ smb2_set_err_rsp (work );
2170+ return err ;
21412171
2142- ksmbd_close_tree_conn_fds (work );
2143- ksmbd_tree_conn_disconnect (sess , tcon );
2144- work -> tcon = NULL ;
2145- return 0 ;
21462172}
21472173
21482174/**
@@ -2164,17 +2190,17 @@ int smb2_session_logoff(struct ksmbd_work *work)
21642190
21652191 ksmbd_debug (SMB , "request\n" );
21662192
2167- sess_id = le64_to_cpu (req -> hdr .SessionId );
2168-
2169- rsp -> StructureSize = cpu_to_le16 (4 );
2170- err = ksmbd_iov_pin_rsp (work , rsp , sizeof (struct smb2_logoff_rsp ));
2171- if (err ) {
2172- rsp -> hdr .Status = STATUS_INSUFFICIENT_RESOURCES ;
2193+ ksmbd_conn_lock (conn );
2194+ if (!ksmbd_conn_good (conn )) {
2195+ ksmbd_conn_unlock (conn );
2196+ rsp -> hdr .Status = STATUS_NETWORK_NAME_DELETED ;
21732197 smb2_set_err_rsp (work );
2174- return err ;
2198+ return - ENOENT ;
21752199 }
2176-
2200+ sess_id = le64_to_cpu ( req -> hdr . SessionId );
21772201 ksmbd_all_conn_set_status (sess_id , KSMBD_SESS_NEED_RECONNECT );
2202+ ksmbd_conn_unlock (conn );
2203+
21782204 ksmbd_close_session_fds (work );
21792205 ksmbd_conn_wait_idle (conn , sess_id );
21802206
@@ -2196,6 +2222,14 @@ int smb2_session_logoff(struct ksmbd_work *work)
21962222 ksmbd_free_user (sess -> user );
21972223 sess -> user = NULL ;
21982224 ksmbd_all_conn_set_status (sess_id , KSMBD_SESS_NEED_NEGOTIATE );
2225+
2226+ rsp -> StructureSize = cpu_to_le16 (4 );
2227+ err = ksmbd_iov_pin_rsp (work , rsp , sizeof (struct smb2_logoff_rsp ));
2228+ if (err ) {
2229+ rsp -> hdr .Status = STATUS_INSUFFICIENT_RESOURCES ;
2230+ smb2_set_err_rsp (work );
2231+ return err ;
2232+ }
21992233 return 0 ;
22002234}
22012235
@@ -3370,8 +3404,10 @@ int smb2_open(struct ksmbd_work *work)
33703404 }
33713405 ksmbd_revert_fsids (work );
33723406err_out1 :
3373- if (!rc )
3407+ if (!rc ) {
3408+ ksmbd_update_fstate (& work -> sess -> file_table , fp , FP_INITED );
33743409 rc = ksmbd_iov_pin_rsp (work , (void * )rsp , iov_len );
3410+ }
33753411 if (rc ) {
33763412 if (rc == - EINVAL )
33773413 rsp -> hdr .Status = STATUS_INVALID_PARAMETER ;
@@ -7028,10 +7064,6 @@ int smb2_lock(struct ksmbd_work *work)
70287064
70297065 ksmbd_debug (SMB ,
70307066 "would have to wait for getting lock\n" );
7031- spin_lock (& work -> conn -> llist_lock );
7032- list_add_tail (& smb_lock -> clist ,
7033- & work -> conn -> lock_list );
7034- spin_unlock (& work -> conn -> llist_lock );
70357067 list_add (& smb_lock -> llist , & rollback_list );
70367068
70377069 argv = kmalloc (sizeof (void * ), GFP_KERNEL );
@@ -7062,9 +7094,6 @@ int smb2_lock(struct ksmbd_work *work)
70627094
70637095 if (work -> state != KSMBD_WORK_ACTIVE ) {
70647096 list_del (& smb_lock -> llist );
7065- spin_lock (& work -> conn -> llist_lock );
7066- list_del (& smb_lock -> clist );
7067- spin_unlock (& work -> conn -> llist_lock );
70687097 locks_free_lock (flock );
70697098
70707099 if (work -> state == KSMBD_WORK_CANCELLED ) {
@@ -7084,19 +7113,16 @@ int smb2_lock(struct ksmbd_work *work)
70847113 }
70857114
70867115 list_del (& smb_lock -> llist );
7087- spin_lock (& work -> conn -> llist_lock );
7088- list_del (& smb_lock -> clist );
7089- spin_unlock (& work -> conn -> llist_lock );
70907116 release_async_work (work );
70917117 goto retry ;
70927118 } else if (!rc ) {
7119+ list_add (& smb_lock -> llist , & rollback_list );
70937120 spin_lock (& work -> conn -> llist_lock );
70947121 list_add_tail (& smb_lock -> clist ,
70957122 & work -> conn -> lock_list );
70967123 list_add_tail (& smb_lock -> flist ,
70977124 & fp -> lock_list );
70987125 spin_unlock (& work -> conn -> llist_lock );
7099- list_add (& smb_lock -> llist , & rollback_list );
71007126 ksmbd_debug (SMB , "successful in taking lock\n" );
71017127 } else {
71027128 goto out ;
@@ -8036,10 +8062,10 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
80368062 goto err_out ;
80378063 }
80388064
8039- opinfo_put (opinfo );
8040- ksmbd_fd_put (work , fp );
80418065 opinfo -> op_state = OPLOCK_STATE_NONE ;
80428066 wake_up_interruptible_all (& opinfo -> oplock_q );
8067+ opinfo_put (opinfo );
8068+ ksmbd_fd_put (work , fp );
80438069
80448070 rsp -> StructureSize = cpu_to_le16 (24 );
80458071 rsp -> OplockLevel = rsp_oplevel ;
0 commit comments