two ksmbd server fixes

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmnz64kACgkQiiy9cAdy
 T1GLPgv/cuJlvhCW4NknYvOplaHZrOYFIeO3DFWc5GvAFO/9nK+6R2s7OoL2CNV+
 QR5CTsWZgYq0vm2Vj2XeuyrnsmCvLkCTY/nmOVmHGxPfyKbjuIvKS5m2+mHiON9p
 aqNqAui03n8OGBACFi7LeaY3hH/8g2MlxbT3uwcbWbaUkZ6UiF1TaNw/hkFkIsnJ
 CarnOd0K08chXMwSIFttFeUYeZg0tVOUG80Zw5YJwnjxn8MY2VI6rf9fu4GVwbZY
 +ycqI49BjaG/CAVMcrPOJnceDkuO1jsfv39HHjXSEwTpE3GtgsS+RFMl2CTOsb/H
 VVdHBsq5pJ/E4zqbhwB+/oju75Ke8/xhNjsXliyqqkZW4vRnQUBKZSh1jarXoFV9
 GW4Eg+cx5nduDI8qVB8IxoEvrwhF1dvbTkEGKN5r7Zy2SlyqvhXiDl0voRGm2am4
 gD9SsKRkdm/wWUoFT2VVeFu4I7rj4ne42LNbhtmmzvkIWLJuvAXmynk2GGMgGrjk
 /1TlyI0t
 =Rq2W
 -----END PGP SIGNATURE-----

Merge tag 'v7.1-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:

 - Fix shutdown (stop sessions)

 - Fix readdir unsupported info level

* tag 'v7.1-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: rewrite stop_sessions() with restartable iteration
  smb: server: handle readdir_info_level_struct_sz() error
master
Linus Torvalds 2026-05-01 12:16:42 -07:00
commit 227c3d546e
3 changed files with 47 additions and 10 deletions

View File

@ -540,24 +540,54 @@ out:
static void stop_sessions(void)
{
struct ksmbd_conn *conn;
struct ksmbd_conn *conn, *target;
struct ksmbd_transport *t;
bool any;
int bkt;
/*
* Serialised via init_lock; no concurrent stop_sessions() can
* touch conn->stop_called, so writing it under the read lock is
* safe.
*/
again:
target = NULL;
any = false;
down_read(&conn_list_lock);
hash_for_each(conn_list, bkt, conn, hlist) {
t = conn->transport;
ksmbd_conn_set_exiting(conn);
if (t->ops->shutdown) {
up_read(&conn_list_lock);
t->ops->shutdown(t);
down_read(&conn_list_lock);
}
any = true;
if (conn->stop_called)
continue;
atomic_inc(&conn->refcnt);
conn->stop_called = true;
/*
* Mark the connection EXITING while still holding the
* read lock so the selection and the status transition
* happen together. Do not regress a connection that has
* already advanced to RELEASING on its own (e.g. the
* handler exited its receive loop for an unrelated
* reason).
*/
if (READ_ONCE(conn->status) != KSMBD_SESS_RELEASING)
ksmbd_conn_set_exiting(conn);
target = conn;
break;
}
up_read(&conn_list_lock);
if (!hash_empty(conn_list)) {
if (target) {
t = target->transport;
if (t->ops->shutdown)
t->ops->shutdown(t);
if (atomic_dec_and_test(&target->refcnt)) {
ida_destroy(&target->async_ida);
t->ops->free_transport(t);
kfree(target);
}
goto again;
}
if (any) {
msleep(100);
goto again;
}

View File

@ -49,6 +49,7 @@ struct ksmbd_conn {
struct mutex srv_mutex;
int status;
unsigned int cli_cap;
bool stop_called;
union {
__be32 inet_addr;
#if IS_ENABLED(CONFIG_IPV6)

View File

@ -3946,7 +3946,13 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
goto free_conv_name;
}
struct_sz = readdir_info_level_struct_sz(info_level) + conv_len;
struct_sz = readdir_info_level_struct_sz(info_level);
if (struct_sz == -EOPNOTSUPP) {
rc = -EINVAL;
goto free_conv_name;
}
struct_sz += conv_len;
next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT);
d_info->last_entry_off_align = next_entry_offset - struct_sz;