fs/smb/smbdirect/listen.c

Source file repositories/reference/linux-study-clean/fs/smb/smbdirect/listen.c

File Facts

System
Linux kernel
Corpus path
fs/smb/smbdirect/listen.c
Extension
.c
Size
8875 bytes
Lines
309
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration 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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Copyright (C) 2017, Microsoft Corporation.
 *   Copyright (C) 2018, LG Electronics.
 *   Copyright (c) 2025, Stefan Metzmacher
 */

#include "internal.h"

static int smbdirect_listen_rdma_event_handler(struct rdma_cm_id *id,
					       struct rdma_cm_event *event);

int smbdirect_socket_listen(struct smbdirect_socket *sc, int backlog)
{
	int ret;

	if (backlog < 0)
		return -EINVAL;
	if (!backlog)
		backlog = 1; /* use 1 as default for now */

	if (sc->first_error)
		return -EINVAL;

	if (sc->status != SMBDIRECT_SOCKET_CREATED)
		return -EINVAL;

	if (WARN_ON_ONCE(!sc->rdma.cm_id))
		return -EINVAL;

	if (sc->rdma.cm_id->device)
		smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
			"try to listen on addr: %pISpsfc dev: %.*s\n",
			&sc->rdma.cm_id->route.addr.src_addr,
			IB_DEVICE_NAME_MAX,
			sc->rdma.cm_id->device->name);
	else
		smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
			"try to listen on addr: %pISpsfc\n",
			&sc->rdma.cm_id->route.addr.src_addr);

	/* already checked above */
	WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_CREATED);
	sc->status = SMBDIRECT_SOCKET_LISTENING;
	sc->rdma.expected_event = RDMA_CM_EVENT_CONNECT_REQUEST;
	rdma_lock_handler(sc->rdma.cm_id);
	sc->rdma.cm_id->event_handler = smbdirect_listen_rdma_event_handler;
	rdma_unlock_handler(sc->rdma.cm_id);

	ret = rdma_listen(sc->rdma.cm_id, backlog);
	if (ret) {
		sc->first_error = ret;
		sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
		if (sc->rdma.cm_id->device)
			smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
				"listening failed %1pe on addr: %pISpsfc dev: %.*s\n",
				SMBDIRECT_DEBUG_ERR_PTR(ret),
				&sc->rdma.cm_id->route.addr.src_addr,
				IB_DEVICE_NAME_MAX,
				sc->rdma.cm_id->device->name);
		else
			smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
				"listening failed %1pe on addr: %pISpsfc\n",
				SMBDIRECT_DEBUG_ERR_PTR(ret),
				&sc->rdma.cm_id->route.addr.src_addr);
		return ret;
	}

	/*
	 * This is a value > 0, checked above,
	 * so we are able to use sc->listen.backlog == -1,
	 * as indication that the socket was never
	 * a listener.
	 */
	sc->listen.backlog = backlog;

	if (sc->rdma.cm_id->device)
		smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
			"listening on addr: %pISpsfc dev: %.*s\n",
			&sc->rdma.cm_id->route.addr.src_addr,
			IB_DEVICE_NAME_MAX,
			sc->rdma.cm_id->device->name);
	else
		smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
			"listening on addr: %pISpsfc\n",
			&sc->rdma.cm_id->route.addr.src_addr);

	/*
	 * The rest happens async via smbdirect_listen_rdma_event_handler()
	 */

Annotation

Implementation Notes