fs/smb/server/transport_tcp.c

Source file repositories/reference/linux-study-clean/fs/smb/server/transport_tcp.c

File Facts

System
Linux kernel
Corpus path
fs/smb/server/transport_tcp.c
Extension
.c
Size
16540 bytes
Lines
685
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct interface {
	struct task_struct	*ksmbd_kthread;
	struct socket		*ksmbd_socket;
	struct list_head	entry;
	char			*name;
	int			state;
};

static LIST_HEAD(iface_list);

static int bind_additional_ifaces;

struct tcp_transport {
	struct ksmbd_transport		transport;
	struct socket			*sock;
	struct kvec			*iov;
	unsigned int			nr_iov;
};

static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops;

static void tcp_stop_kthread(struct task_struct *kthread);
static struct interface *alloc_iface(char *ifname);
static void ksmbd_tcp_disconnect(struct ksmbd_transport *t);

#define KSMBD_TRANS(t)	(&(t)->transport)
#define TCP_TRANS(t)	((struct tcp_transport *)container_of(t, \
				struct tcp_transport, transport))

static inline void ksmbd_tcp_nodelay(struct socket *sock)
{
	tcp_sock_set_nodelay(sock->sk);
}

static inline void ksmbd_tcp_reuseaddr(struct socket *sock)
{
	sock_set_reuseaddr(sock->sk);
}

static struct tcp_transport *alloc_transport(struct socket *client_sk)
{
	struct tcp_transport *t;
	struct ksmbd_conn *conn;

	t = kzalloc_obj(*t, KSMBD_DEFAULT_GFP);
	if (!t)
		return NULL;
	t->sock = client_sk;

	conn = ksmbd_conn_alloc();
	if (!conn) {
		kfree(t);
		return NULL;
	}

#if IS_ENABLED(CONFIG_IPV6)
	if (client_sk->sk->sk_family == AF_INET6) {
		memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16);
		conn->inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr);
	} else {
		conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
		conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr);
	}
#else
	conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
	conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr);
#endif
	down_write(&conn_list_lock);
	hash_add(conn_list, &conn->hlist, conn->inet_hash);
	up_write(&conn_list_lock);

	conn->transport = KSMBD_TRANS(t);
	KSMBD_TRANS(t)->conn = conn;
	KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
	return t;
}

static void ksmbd_tcp_free_transport(struct ksmbd_transport *kt)
{
	struct tcp_transport *t = TCP_TRANS(kt);

	sock_release(t->sock);
	kfree(t->iov);
	kfree(t);
}

static void free_transport(struct tcp_transport *t)
{
	kernel_sock_shutdown(t->sock, SHUT_RDWR);
	ksmbd_conn_free(KSMBD_TRANS(t)->conn);

Annotation

Implementation Notes