net/ceph/messenger_v1.c

Source file repositories/reference/linux-study-clean/net/ceph/messenger_v1.c

File Facts

System
Linux kernel
Corpus path
net/ceph/messenger_v1.c
Extension
.c
Size
41727 bytes
Lines
1621
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

while (ret >= con->v1.out_kvec_cur->iov_len) {
			BUG_ON(!con->v1.out_kvec_left);
			ret -= con->v1.out_kvec_cur->iov_len;
			con->v1.out_kvec_cur++;
			con->v1.out_kvec_left--;
		}
		/* and for a partially-consumed entry */
		if (ret) {
			con->v1.out_kvec_cur->iov_len -= ret;
			con->v1.out_kvec_cur->iov_base += ret;
		}
	}
	con->v1.out_kvec_left = 0;
	ret = 1;
out:
	dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con,
	     con->v1.out_kvec_bytes, con->v1.out_kvec_left, ret);
	return ret;  /* done! */
}

/*
 * Write as much message data payload as we can.  If we finish, queue
 * up the footer.
 *  1 -> done, footer is now queued in out_kvec[].
 *  0 -> socket full, but more to do
 * <0 -> error
 */
static int write_partial_message_data(struct ceph_connection *con,
				      struct ceph_msg *msg)
{
	struct ceph_msg_data_cursor *cursor = &msg->cursor;
	bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC);
	u32 crc;

	dout("%s %p msg %p\n", __func__, con, msg);

	if (!msg->num_data_items)
		return -EINVAL;

	/*
	 * Iterate through each page that contains data to be
	 * written, and send as much as possible for each.
	 *
	 * If we are calculating the data crc (the default), we will
	 * need to map the page.  If we have no pages, they have
	 * been revoked, so use the zero page.
	 */
	crc = do_datacrc ? le32_to_cpu(msg->footer.data_crc) : 0;
	while (cursor->total_resid) {
		struct page *page;
		size_t page_offset;
		size_t length;
		int ret;

		if (!cursor->resid) {
			ceph_msg_data_advance(cursor, 0);
			continue;
		}

		page = ceph_msg_data_next(cursor, &page_offset, &length);
		ret = ceph_tcp_sendpage(con->sock, page, page_offset, length,
					MSG_MORE);
		if (ret <= 0) {
			if (do_datacrc)
				msg->footer.data_crc = cpu_to_le32(crc);

			return ret;
		}
		if (do_datacrc && cursor->need_crc)
			crc = ceph_crc32c_page(crc, page, page_offset, length);
		ceph_msg_data_advance(cursor, (size_t)ret);
	}

	dout("%s %p msg %p done\n", __func__, con, msg);

	/* prepare and queue up footer, too */
	if (do_datacrc)
		msg->footer.data_crc = cpu_to_le32(crc);
	else
		msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
	con_out_kvec_reset(con);
	prepare_write_message_footer(con, msg);

	return 1;	/* must return > 0 to indicate success */
}

/*
 * write some zeros
 */
static int write_partial_skip(struct ceph_connection *con)

Annotation

Implementation Notes