fs/smb/smbdirect/rw.c

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

File Facts

System
Linux kernel
Corpus path
fs/smb/smbdirect/rw.c
Extension
.c
Size
6379 bytes
Lines
256
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

if (desc_buf_len > buf_len) {
			desc_buf_len = buf_len;
			desc[i].length = cpu_to_le32(desc_buf_len);
			buf_len = 0;
		}

		credits_needed += smbdirect_connection_calc_rw_credits(sc,
								       desc_buf,
								       desc_buf_len);
		desc_buf += desc_buf_len;
		buf_len -= desc_buf_len;
		desc_num++;
	}

	smbdirect_log_rdma_rw(sc, SMBDIRECT_LOG_INFO,
		"RDMA %s, len %zu, needed credits %d\n",
		str_read_write(is_read), buf_len, credits_needed);

	ret = smbdirect_connection_wait_for_rw_credits(sc, credits_needed);
	if (ret < 0)
		return ret;

	/* build rdma_rw_ctx for each descriptor */
	desc_buf = buf;
	for (i = 0; i < desc_num; i++) {
		size_t page_count;

		msg = kzalloc_flex(*msg, sg_list, SG_CHUNK_SIZE,
				   sc->rw_io.mem.gfp_mask);
		if (!msg) {
			ret = -ENOMEM;
			goto out;
		}

		desc_buf_len = le32_to_cpu(desc[i].length);
		page_count = smbdirect_get_buf_page_count(desc_buf, desc_buf_len);

		msg->socket = sc;
		msg->cqe.done = is_read ?
			smbdirect_connection_rdma_read_done :
			smbdirect_connection_rdma_write_done;
		msg->completion = &completion;

		msg->sgt.sgl = &msg->sg_list[0];
		ret = sg_alloc_table_chained(&msg->sgt,
					     page_count,
					     msg->sg_list,
					     SG_CHUNK_SIZE);
		if (ret) {
			ret = -ENOMEM;
			goto free_msg;
		}

		ret = smbdirect_connection_rdma_get_sg_list(desc_buf,
							    desc_buf_len,
							    msg->sgt.sgl,
							    msg->sgt.orig_nents);
		if (ret < 0)
			goto free_table;

		ret = rdma_rw_ctx_init(&msg->rdma_ctx,
				       sc->ib.qp,
				       sc->ib.qp->port,
				       msg->sgt.sgl,
				       page_count,
				       0,
				       le64_to_cpu(desc[i].offset),
				       le32_to_cpu(desc[i].token),
				       direction);
		if (ret < 0) {
			pr_err("failed to init rdma_rw_ctx: %d\n", ret);
			goto free_table;
		}

		list_add_tail(&msg->list, &msg_list);
		desc_buf += desc_buf_len;
	}

	/* concatenate work requests of rdma_rw_ctxs */
	first_wr = NULL;
	list_for_each_entry_reverse(msg, &msg_list, list) {
		first_wr = rdma_rw_ctx_wrs(&msg->rdma_ctx,
					   sc->ib.qp,
					   sc->ib.qp->port,
					   &msg->cqe,
					   first_wr);
	}

	ret = ib_post_send(sc->ib.qp, first_wr, NULL);
	if (ret) {

Annotation

Implementation Notes