fs/smb/smbdirect/socket.c

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

File Facts

System
Linux kernel
Corpus path
fs/smb/smbdirect/socket.c
Extension
.c
Size
20784 bytes
Lines
744
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) 2025, Stefan Metzmacher
 */

#include "internal.h"

bool smbdirect_frwr_is_supported(const struct ib_device_attr *attrs)
{
	/*
	 * Test if FRWR (Fast Registration Work Requests) is supported on the
	 * device This implementation requires FRWR on RDMA read/write return
	 * value: true if it is supported
	 */

	if (!(attrs->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS))
		return false;
	if (attrs->max_fast_reg_page_list_len == 0)
		return false;
	return true;
}
EXPORT_SYMBOL_GPL(smbdirect_frwr_is_supported);

static void smbdirect_socket_cleanup_work(struct work_struct *work);

static int smbdirect_socket_rdma_event_handler(struct rdma_cm_id *id,
					       struct rdma_cm_event *event)
{
	struct smbdirect_socket *sc = id->context;
	int ret = -ESTALE;

	/*
	 * This should be replaced before any real work
	 * starts! So it should never be called!
	 */

	if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL)
		ret = -ENETDOWN;
	if (IS_ERR(SMBDIRECT_DEBUG_ERR_PTR(event->status)))
		ret = event->status;
	pr_err("%s (first_error=%1pe, expected=%s) => event=%s status=%d => ret=%1pe\n",
		smbdirect_socket_status_string(sc->status),
		SMBDIRECT_DEBUG_ERR_PTR(sc->first_error),
		rdma_event_msg(sc->rdma.expected_event),
		rdma_event_msg(event->event),
		event->status,
		SMBDIRECT_DEBUG_ERR_PTR(ret));
	WARN_ONCE(1, "%s should not be called!\n", __func__);
	sc->rdma.cm_id = NULL;
	return -ESTALE;
}

int smbdirect_socket_init_new(struct net *net, struct smbdirect_socket *sc)
{
	struct rdma_cm_id *id;
	int ret;

	smbdirect_socket_init(sc);

	id = rdma_create_id(net,
			    smbdirect_socket_rdma_event_handler,
			    sc,
			    RDMA_PS_TCP,
			    IB_QPT_RC);
	if (IS_ERR(id)) {
		pr_err("%s: rdma_create_id() failed %1pe\n", __func__, id);
		return PTR_ERR(id);
	}

	ret = rdma_set_afonly(id, 1);
	if (ret) {
		rdma_destroy_id(id);
		pr_err("%s: rdma_set_afonly() failed %1pe\n",
		       __func__, SMBDIRECT_DEBUG_ERR_PTR(ret));
		return ret;
	}

	sc->rdma.cm_id = id;

	INIT_WORK(&sc->disconnect_work, smbdirect_socket_cleanup_work);

	return 0;
}

int smbdirect_socket_create_kern(struct net *net, struct smbdirect_socket **_sc)
{
	struct smbdirect_socket *sc;
	int ret;

Annotation

Implementation Notes