@@ -1993,6 +1993,9 @@ int smb2_tree_connect(struct ksmbd_work *work)
1993
1993
if (conn -> posix_ext_supported )
1994
1994
status .tree_conn -> posix_extensions = true;
1995
1995
1996
+ write_lock (& sess -> tree_conns_lock );
1997
+ status .tree_conn -> t_state = TREE_CONNECTED ;
1998
+ write_unlock (& sess -> tree_conns_lock );
1996
1999
rsp -> StructureSize = cpu_to_le16 (16 );
1997
2000
out_err1 :
1998
2001
rsp -> Capabilities = 0 ;
@@ -2122,27 +2125,50 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
2122
2125
2123
2126
ksmbd_debug (SMB , "request\n" );
2124
2127
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
+
2125
2158
rsp -> StructureSize = cpu_to_le16 (4 );
2126
2159
err = ksmbd_iov_pin_rsp (work , rsp ,
2127
2160
sizeof (struct smb2_tree_disconnect_rsp ));
2128
2161
if (err ) {
2129
2162
rsp -> hdr .Status = STATUS_INSUFFICIENT_RESOURCES ;
2130
- smb2_set_err_rsp (work );
2131
- return err ;
2163
+ goto err_out ;
2132
2164
}
2133
2165
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 ;
2136
2167
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 ;
2141
2171
2142
- ksmbd_close_tree_conn_fds (work );
2143
- ksmbd_tree_conn_disconnect (sess , tcon );
2144
- work -> tcon = NULL ;
2145
- return 0 ;
2146
2172
}
2147
2173
2148
2174
/**
@@ -2164,17 +2190,17 @@ int smb2_session_logoff(struct ksmbd_work *work)
2164
2190
2165
2191
ksmbd_debug (SMB , "request\n" );
2166
2192
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 ;
2173
2197
smb2_set_err_rsp (work );
2174
- return err ;
2198
+ return - ENOENT ;
2175
2199
}
2176
-
2200
+ sess_id = le64_to_cpu ( req -> hdr . SessionId );
2177
2201
ksmbd_all_conn_set_status (sess_id , KSMBD_SESS_NEED_RECONNECT );
2202
+ ksmbd_conn_unlock (conn );
2203
+
2178
2204
ksmbd_close_session_fds (work );
2179
2205
ksmbd_conn_wait_idle (conn , sess_id );
2180
2206
@@ -2196,6 +2222,14 @@ int smb2_session_logoff(struct ksmbd_work *work)
2196
2222
ksmbd_free_user (sess -> user );
2197
2223
sess -> user = NULL ;
2198
2224
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
+ }
2199
2233
return 0 ;
2200
2234
}
2201
2235
@@ -3370,8 +3404,10 @@ int smb2_open(struct ksmbd_work *work)
3370
3404
}
3371
3405
ksmbd_revert_fsids (work );
3372
3406
err_out1 :
3373
- if (!rc )
3407
+ if (!rc ) {
3408
+ ksmbd_update_fstate (& work -> sess -> file_table , fp , FP_INITED );
3374
3409
rc = ksmbd_iov_pin_rsp (work , (void * )rsp , iov_len );
3410
+ }
3375
3411
if (rc ) {
3376
3412
if (rc == - EINVAL )
3377
3413
rsp -> hdr .Status = STATUS_INVALID_PARAMETER ;
@@ -7028,10 +7064,6 @@ int smb2_lock(struct ksmbd_work *work)
7028
7064
7029
7065
ksmbd_debug (SMB ,
7030
7066
"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 );
7035
7067
list_add (& smb_lock -> llist , & rollback_list );
7036
7068
7037
7069
argv = kmalloc (sizeof (void * ), GFP_KERNEL );
@@ -7062,9 +7094,6 @@ int smb2_lock(struct ksmbd_work *work)
7062
7094
7063
7095
if (work -> state != KSMBD_WORK_ACTIVE ) {
7064
7096
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 );
7068
7097
locks_free_lock (flock );
7069
7098
7070
7099
if (work -> state == KSMBD_WORK_CANCELLED ) {
@@ -7084,19 +7113,16 @@ int smb2_lock(struct ksmbd_work *work)
7084
7113
}
7085
7114
7086
7115
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 );
7090
7116
release_async_work (work );
7091
7117
goto retry ;
7092
7118
} else if (!rc ) {
7119
+ list_add (& smb_lock -> llist , & rollback_list );
7093
7120
spin_lock (& work -> conn -> llist_lock );
7094
7121
list_add_tail (& smb_lock -> clist ,
7095
7122
& work -> conn -> lock_list );
7096
7123
list_add_tail (& smb_lock -> flist ,
7097
7124
& fp -> lock_list );
7098
7125
spin_unlock (& work -> conn -> llist_lock );
7099
- list_add (& smb_lock -> llist , & rollback_list );
7100
7126
ksmbd_debug (SMB , "successful in taking lock\n" );
7101
7127
} else {
7102
7128
goto out ;
@@ -8036,10 +8062,10 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
8036
8062
goto err_out ;
8037
8063
}
8038
8064
8039
- opinfo_put (opinfo );
8040
- ksmbd_fd_put (work , fp );
8041
8065
opinfo -> op_state = OPLOCK_STATE_NONE ;
8042
8066
wake_up_interruptible_all (& opinfo -> oplock_q );
8067
+ opinfo_put (opinfo );
8068
+ ksmbd_fd_put (work , fp );
8043
8069
8044
8070
rsp -> StructureSize = cpu_to_le16 (24 );
8045
8071
rsp -> OplockLevel = rsp_oplevel ;
0 commit comments