@@ -67,8 +67,10 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
67
67
return false;
68
68
69
69
sess = ksmbd_session_lookup_all (conn , id );
70
- if (sess )
70
+ if (sess ) {
71
+ ksmbd_user_session_put (sess );
71
72
return true;
73
+ }
72
74
pr_err ("Invalid user session id: %llu\n" , id );
73
75
return false;
74
76
}
@@ -605,10 +607,8 @@ int smb2_check_user_session(struct ksmbd_work *work)
605
607
606
608
/* Check for validity of user session */
607
609
work -> sess = ksmbd_session_lookup_all (conn , sess_id );
608
- if (work -> sess ) {
609
- ksmbd_user_session_get (work -> sess );
610
+ if (work -> sess )
610
611
return 1 ;
611
- }
612
612
ksmbd_debug (SMB , "Invalid user session, Uid %llu\n" , sess_id );
613
613
return - ENOENT ;
614
614
}
@@ -1701,37 +1701,44 @@ int smb2_sess_setup(struct ksmbd_work *work)
1701
1701
1702
1702
if (conn -> dialect != sess -> dialect ) {
1703
1703
rc = - EINVAL ;
1704
+ ksmbd_user_session_put (sess );
1704
1705
goto out_err ;
1705
1706
}
1706
1707
1707
1708
if (!(req -> hdr .Flags & SMB2_FLAGS_SIGNED )) {
1708
1709
rc = - EINVAL ;
1710
+ ksmbd_user_session_put (sess );
1709
1711
goto out_err ;
1710
1712
}
1711
1713
1712
1714
if (strncmp (conn -> ClientGUID , sess -> ClientGUID ,
1713
1715
SMB2_CLIENT_GUID_SIZE )) {
1714
1716
rc = - ENOENT ;
1717
+ ksmbd_user_session_put (sess );
1715
1718
goto out_err ;
1716
1719
}
1717
1720
1718
1721
if (sess -> state == SMB2_SESSION_IN_PROGRESS ) {
1719
1722
rc = - EACCES ;
1723
+ ksmbd_user_session_put (sess );
1720
1724
goto out_err ;
1721
1725
}
1722
1726
1723
1727
if (sess -> state == SMB2_SESSION_EXPIRED ) {
1724
1728
rc = - EFAULT ;
1729
+ ksmbd_user_session_put (sess );
1725
1730
goto out_err ;
1726
1731
}
1732
+ ksmbd_user_session_put (sess );
1727
1733
1728
1734
if (ksmbd_conn_need_reconnect (conn )) {
1729
1735
rc = - EFAULT ;
1730
1736
sess = NULL ;
1731
1737
goto out_err ;
1732
1738
}
1733
1739
1734
- if (ksmbd_session_lookup (conn , sess_id )) {
1740
+ sess = ksmbd_session_lookup (conn , sess_id );
1741
+ if (!sess ) {
1735
1742
rc = - EACCES ;
1736
1743
goto out_err ;
1737
1744
}
@@ -1742,7 +1749,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
1742
1749
}
1743
1750
1744
1751
conn -> binding = true;
1745
- ksmbd_user_session_get (sess );
1746
1752
} else if ((conn -> dialect < SMB30_PROT_ID ||
1747
1753
server_conf .flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL ) &&
1748
1754
(req -> Flags & SMB2_SESSION_REQ_FLAG_BINDING )) {
@@ -1769,7 +1775,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
1769
1775
}
1770
1776
1771
1777
conn -> binding = false;
1772
- ksmbd_user_session_get (sess );
1773
1778
}
1774
1779
work -> sess = sess ;
1775
1780
@@ -2197,9 +2202,9 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
2197
2202
int smb2_session_logoff (struct ksmbd_work * work )
2198
2203
{
2199
2204
struct ksmbd_conn * conn = work -> conn ;
2205
+ struct ksmbd_session * sess = work -> sess ;
2200
2206
struct smb2_logoff_req * req ;
2201
2207
struct smb2_logoff_rsp * rsp ;
2202
- struct ksmbd_session * sess ;
2203
2208
u64 sess_id ;
2204
2209
int err ;
2205
2210
@@ -2221,11 +2226,6 @@ int smb2_session_logoff(struct ksmbd_work *work)
2221
2226
ksmbd_close_session_fds (work );
2222
2227
ksmbd_conn_wait_idle (conn );
2223
2228
2224
- /*
2225
- * Re-lookup session to validate if session is deleted
2226
- * while waiting request complete
2227
- */
2228
- sess = ksmbd_session_lookup_all (conn , sess_id );
2229
2229
if (ksmbd_tree_conn_session_logoff (sess )) {
2230
2230
ksmbd_debug (SMB , "Invalid tid %d\n" , req -> hdr .Id .SyncId .TreeId );
2231
2231
rsp -> hdr .Status = STATUS_NETWORK_NAME_DELETED ;
@@ -4228,6 +4228,7 @@ static bool __query_dir(struct dir_context *ctx, const char *name, int namlen,
4228
4228
/* dot and dotdot entries are already reserved */
4229
4229
if (!strcmp ("." , name ) || !strcmp (".." , name ))
4230
4230
return true;
4231
+ d_info -> num_scan ++ ;
4231
4232
if (ksmbd_share_veto_filename (priv -> work -> tcon -> share_conf , name ))
4232
4233
return true;
4233
4234
if (!match_pattern (name , namlen , priv -> search_pattern ))
@@ -4390,8 +4391,17 @@ int smb2_query_dir(struct ksmbd_work *work)
4390
4391
query_dir_private .info_level = req -> FileInformationClass ;
4391
4392
dir_fp -> readdir_data .private = & query_dir_private ;
4392
4393
set_ctx_actor (& dir_fp -> readdir_data .ctx , __query_dir );
4393
-
4394
+ again :
4395
+ d_info .num_scan = 0 ;
4394
4396
rc = iterate_dir (dir_fp -> filp , & dir_fp -> readdir_data .ctx );
4397
+ /*
4398
+ * num_entry can be 0 if the directory iteration stops before reaching
4399
+ * the end of the directory and no file is matched with the search
4400
+ * pattern.
4401
+ */
4402
+ if (rc >= 0 && !d_info .num_entry && d_info .num_scan &&
4403
+ d_info .out_buf_len > 0 )
4404
+ goto again ;
4395
4405
/*
4396
4406
* req->OutputBufferLength is too small to contain even one entry.
4397
4407
* In this case, it immediately returns OutputBufferLength 0 to client.
@@ -6016,15 +6026,13 @@ static int set_file_basic_info(struct ksmbd_file *fp,
6016
6026
attrs .ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET );
6017
6027
}
6018
6028
6019
- attrs .ia_valid |= ATTR_CTIME ;
6020
6029
if (file_info -> ChangeTime )
6021
- attrs .ia_ctime = ksmbd_NTtimeToUnix (file_info -> ChangeTime );
6022
- else
6023
- attrs .ia_ctime = inode_get_ctime (inode );
6030
+ inode_set_ctime_to_ts (inode ,
6031
+ ksmbd_NTtimeToUnix (file_info -> ChangeTime ));
6024
6032
6025
6033
if (file_info -> LastWriteTime ) {
6026
6034
attrs .ia_mtime = ksmbd_NTtimeToUnix (file_info -> LastWriteTime );
6027
- attrs .ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET );
6035
+ attrs .ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME );
6028
6036
}
6029
6037
6030
6038
if (file_info -> Attributes ) {
@@ -6066,8 +6074,6 @@ static int set_file_basic_info(struct ksmbd_file *fp,
6066
6074
return - EACCES ;
6067
6075
6068
6076
inode_lock (inode );
6069
- inode_set_ctime_to_ts (inode , attrs .ia_ctime );
6070
- attrs .ia_valid &= ~ATTR_CTIME ;
6071
6077
rc = notify_change (idmap , dentry , & attrs , NULL );
6072
6078
inode_unlock (inode );
6073
6079
}
@@ -8982,6 +8988,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
8982
8988
le64_to_cpu (tr_hdr -> SessionId ));
8983
8989
return - ECONNABORTED ;
8984
8990
}
8991
+ ksmbd_user_session_put (sess );
8985
8992
8986
8993
iov [0 ].iov_base = buf ;
8987
8994
iov [0 ].iov_len = sizeof (struct smb2_transform_hdr ) + 4 ;
0 commit comments