drivers/block/rnbd/rnbd-clt.c

Source file repositories/reference/linux-study-clean/drivers/block/rnbd/rnbd-clt.c

File Facts

System
Linux kernel
Corpus path
drivers/block/rnbd/rnbd-clt.c
Extension
.c
Size
46845 bytes
Lines
1836
Domain
Driver Families
Bucket
drivers/block
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct blk_mq_ops rnbd_mq_ops = {
	.queue_rq	= rnbd_queue_rq,
	.complete	= rnbd_softirq_done_fn,
	.map_queues     = rnbd_rdma_map_queues,
	.poll           = rnbd_rdma_poll,
};

static int setup_mq_tags(struct rnbd_clt_session *sess)
{
	struct blk_mq_tag_set *tag_set = &sess->tag_set;

	memset(tag_set, 0, sizeof(*tag_set));
	tag_set->ops		= &rnbd_mq_ops;
	tag_set->queue_depth	= sess->queue_depth;
	tag_set->numa_node		= NUMA_NO_NODE;
	tag_set->flags		= BLK_MQ_F_TAG_QUEUE_SHARED;
	tag_set->cmd_size	= sizeof(struct rnbd_iu) + RNBD_RDMA_SGL_SIZE;

	/* for HCTX_TYPE_DEFAULT, HCTX_TYPE_READ, HCTX_TYPE_POLL */
	tag_set->nr_maps        = sess->nr_poll_queues ? HCTX_MAX_TYPES : 2;
	/*
	 * HCTX_TYPE_DEFAULT and HCTX_TYPE_READ share one set of queues
	 * others are for HCTX_TYPE_POLL
	 */
	tag_set->nr_hw_queues	= num_online_cpus() + sess->nr_poll_queues;
	tag_set->driver_data    = sess;

	return blk_mq_alloc_tag_set(tag_set);
}

static struct rnbd_clt_session *
find_and_get_or_create_sess(const char *sessname,
			    const struct rtrs_addr *paths,
			    size_t path_cnt, u16 port_nr, u32 nr_poll_queues)
{
	struct rnbd_clt_session *sess;
	struct rtrs_attrs attrs;
	int err;
	bool first = false;
	struct rtrs_clt_ops rtrs_ops;

	sess = find_or_create_sess(sessname, &first);
	if (sess == ERR_PTR(-ENOMEM)) {
		return ERR_PTR(-ENOMEM);
	} else if ((nr_poll_queues && !first) ||  (!nr_poll_queues && sess->nr_poll_queues)) {
		/*
		 * A device MUST have its own session to use the polling-mode.
		 * It must fail to map new device with the same session.
		 */
		err = -EINVAL;
		goto put_sess;
	}

	if (!first)
		return sess;

	if (!path_cnt) {
		pr_err("Session %s not found, and path parameter not given", sessname);
		err = -ENXIO;
		goto put_sess;
	}

	rtrs_ops = (struct rtrs_clt_ops) {
		.priv = sess,
		.link_ev = rnbd_clt_link_ev,
	};
	/*
	 * Nothing was found, establish rtrs connection and proceed further.
	 */
	sess->rtrs = rtrs_clt_open(&rtrs_ops, sessname,
				   paths, path_cnt, port_nr,
				   0, /* Do not use pdu of rtrs */
				   RECONNECT_DELAY,
				   MAX_RECONNECTS, nr_poll_queues);
	if (IS_ERR(sess->rtrs)) {
		err = PTR_ERR(sess->rtrs);
		goto wake_up_and_put;
	}

	err = rtrs_clt_query(sess->rtrs, &attrs);
	if (err)
		goto close_rtrs;

	sess->max_io_size = attrs.max_io_size;
	sess->queue_depth = attrs.queue_depth;
	sess->nr_poll_queues = nr_poll_queues;
	sess->max_segments = attrs.max_segments;

	err = setup_mq_tags(sess);
	if (err)

Annotation

Implementation Notes