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() errormaster
commit
227c3d546e
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue