diff options
| author | Breno Leitao <leitao@debian.org> | 2026-08-05 07:52:36 -0700 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-08-10 11:47:20 -1000 |
| commit | a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656 (patch) | |
| tree | 39f5b258386e1127d253d293194e9a2991bf3c34 /fs/smb/server/connection.h | |
| download | linux-stable-a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656.tar.gz linux-stable-a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656.zip | |
workqueue: skip the node_nr_active update for non-unbound workqueuesgrafted
apply_wqattrs_commit() updates node_nr_active->max unconditionally.
wq->node_nr_active[] is only allocated for unbound workqueues, so guard
the call before per-cpu workqueues start using this path.
No functional change: only unbound workqueues reach apply_wqattrs_*()
today.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'fs/smb/server/connection.h')
| -rw-r--r-- | fs/smb/server/connection.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h new file mode 100644 index 000000000..ec75633b7 --- /dev/null +++ b/fs/smb/server/connection.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2018 Samsung Electronics Co., Ltd. + */ + +#ifndef __KSMBD_CONNECTION_H__ +#define __KSMBD_CONNECTION_H__ + +#include <linux/list.h> +#include <linux/inet.h> +#include <linux/ip.h> +#include <net/sock.h> +#include <net/tcp.h> +#include <net/inet_connection_sock.h> +#include <net/request_sock.h> +#include <linux/kthread.h> +#include <linux/nls.h> +#include <linux/unicode.h> +#include <linux/workqueue.h> + +#include "smb_common.h" +#include "ksmbd_work.h" + +struct smbdirect_buffer_descriptor_v1; + +#define KSMBD_SOCKET_BACKLOG 16 + +enum { + KSMBD_SESS_NEW = 0, + KSMBD_SESS_GOOD, + KSMBD_SESS_EXITING, + KSMBD_SESS_NEED_RECONNECT, + KSMBD_SESS_NEED_NEGOTIATE, + KSMBD_SESS_NEED_SETUP, + KSMBD_SESS_RELEASING +}; + +struct ksmbd_conn_stats { + atomic_t open_files_count; + atomic64_t request_served; +}; + +struct ksmbd_transport; + +struct ksmbd_conn { + struct smb_version_values *vals; + struct smb_version_ops *ops; + struct smb_version_cmds *cmds; + unsigned int max_cmds; + struct mutex srv_mutex; + int status; + unsigned int cli_cap; + bool stop_called; + union { + __be32 inet_addr; +#if IS_ENABLED(CONFIG_IPV6) + u8 inet6_addr[16]; +#endif + }; + unsigned int inet_hash; + char *request_buf; + struct ksmbd_transport *transport; + struct nls_table *local_nls; + struct unicode_map *um; + struct hlist_node hlist; + struct rw_semaphore session_lock; + /* smb session 1 per user */ + struct xarray sessions; + unsigned long last_active; + /* How many request are running currently */ + atomic_t req_running; + /* References which are made for this Server object*/ + atomic_t r_count; + unsigned int total_credits; + unsigned int outstanding_credits; + spinlock_t credits_lock; + wait_queue_head_t req_running_q; + wait_queue_head_t r_count_q; + /* Lock to protect requests list*/ + spinlock_t request_lock; + struct list_head requests; + struct list_head async_requests; + int connection_type; + struct ksmbd_conn_stats stats; + char ClientGUID[SMB2_CLIENT_GUID_SIZE]; + struct ntlmssp_auth ntlmssp; + + spinlock_t llist_lock; + struct list_head lock_list; + + struct preauth_integrity_info *preauth_info; + + bool need_neg; + unsigned int auth_mechs; + unsigned int preferred_auth_mech; + bool sign; + bool use_spnego:1; + __u16 cli_sec_mode; + __u16 srv_sec_mode; + /* dialect index that server chose */ + __u16 dialect; + + char *mechToken; + unsigned int mechTokenLen; + + struct ksmbd_conn_ops *conn_ops; + + /* Preauth Session Table */ + struct list_head preauth_sess_table; + + struct sockaddr_storage peer_addr; + + /* Identifier for async message */ + struct ida async_ida; + + __le16 cipher_type; + __le16 compress_algorithm; + /* Negotiated SMB 3.1.1 compression capabilities. */ + bool compress_chained; + bool compress_pattern; + bool posix_ext_supported; + bool signing_negotiated; + __le16 signing_algorithm; + bool binding; + atomic_t refcnt; + bool is_aapl; + struct work_struct release_work; +}; + +struct ksmbd_conn_ops { + int (*process_fn)(struct ksmbd_conn *conn); + int (*terminate_fn)(struct ksmbd_conn *conn); +}; + +struct ksmbd_transport_ops { + void (*disconnect)(struct ksmbd_transport *t); + void (*shutdown)(struct ksmbd_transport *t); + int (*read)(struct ksmbd_transport *t, char *buf, + unsigned int size, int max_retries); + int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov, + int size, bool need_invalidate_rkey, + unsigned int remote_key); + int (*rdma_read)(struct ksmbd_transport *t, + void *buf, unsigned int len, + struct smbdirect_buffer_descriptor_v1 *desc, + unsigned int desc_len); + int (*rdma_write)(struct ksmbd_transport *t, + void *buf, unsigned int len, + struct smbdirect_buffer_descriptor_v1 *desc, + unsigned int desc_len); + void (*free_transport)(struct ksmbd_transport *kt); +}; + +struct ksmbd_transport { + struct ksmbd_conn *conn; + const struct ksmbd_transport_ops *ops; +}; + +#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ) +#define KSMBD_TCP_SEND_TIMEOUT (5 * HZ) +#define KSMBD_TCP_PEER_SOCKADDR(c) ((struct sockaddr *)&((c)->peer_addr)) + +#define CONN_HASH_BITS 12 +extern DECLARE_HASHTABLE(conn_list, CONN_HASH_BITS); +extern struct rw_semaphore conn_list_lock; + +bool ksmbd_conn_alive(struct ksmbd_conn *conn); +void ksmbd_conn_wait_idle(struct ksmbd_conn *conn); +int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id); +struct ksmbd_conn *ksmbd_conn_alloc(void); +void ksmbd_conn_free(struct ksmbd_conn *conn); +struct ksmbd_conn *ksmbd_conn_get(struct ksmbd_conn *conn); +void ksmbd_conn_put(struct ksmbd_conn *conn); +int ksmbd_conn_wq_init(void); +void ksmbd_conn_wq_destroy(void); +bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c); +int ksmbd_conn_write(struct ksmbd_work *work); +int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, + void *buf, unsigned int buflen, + struct smbdirect_buffer_descriptor_v1 *desc, + unsigned int desc_len); +int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, + void *buf, unsigned int buflen, + struct smbdirect_buffer_descriptor_v1 *desc, + unsigned int desc_len); +void ksmbd_conn_enqueue_request(struct ksmbd_work *work); +void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); +void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops); +int ksmbd_conn_handler_loop(void *p); +int ksmbd_conn_transport_init(void); +void ksmbd_conn_transport_destroy(void); +void ksmbd_conn_lock(struct ksmbd_conn *conn); +void ksmbd_conn_unlock(struct ksmbd_conn *conn); +void ksmbd_conn_r_count_inc(struct ksmbd_conn *conn); +void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn); + +/* + * WARNING + * + * This is a hack. We will move status to a proper place once we land + * a multi-sessions support. + */ +static inline bool ksmbd_conn_good(struct ksmbd_conn *conn) +{ + return READ_ONCE(conn->status) == KSMBD_SESS_GOOD; +} + +static inline bool ksmbd_conn_need_negotiate(struct ksmbd_conn *conn) +{ + return READ_ONCE(conn->status) == KSMBD_SESS_NEED_NEGOTIATE; +} + +static inline bool ksmbd_conn_need_setup(struct ksmbd_conn *conn) +{ + return READ_ONCE(conn->status) == KSMBD_SESS_NEED_SETUP; +} + +static inline bool ksmbd_conn_need_reconnect(struct ksmbd_conn *conn) +{ + return READ_ONCE(conn->status) == KSMBD_SESS_NEED_RECONNECT; +} + +static inline bool ksmbd_conn_exiting(struct ksmbd_conn *conn) +{ + return READ_ONCE(conn->status) == KSMBD_SESS_EXITING; +} + +static inline bool ksmbd_conn_releasing(struct ksmbd_conn *conn) +{ + return READ_ONCE(conn->status) == KSMBD_SESS_RELEASING; +} + +static inline void ksmbd_conn_set_new(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_NEW); +} + +static inline void ksmbd_conn_set_good(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_GOOD); +} + +static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_NEED_NEGOTIATE); +} + +static inline void ksmbd_conn_set_need_setup(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_NEED_SETUP); +} + +static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_NEED_RECONNECT); +} + +static inline void ksmbd_conn_set_exiting(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_EXITING); +} + +static inline void ksmbd_conn_set_releasing(struct ksmbd_conn *conn) +{ + WRITE_ONCE(conn->status, KSMBD_SESS_RELEASING); +} + +void ksmbd_all_conn_set_status(u64 sess_id, u32 status); +#endif /* __CONNECTION_H__ */ |
