[rds-commits] zab commits r88 - in trunk: . linux/net/rds man

svn-commits@oss.oracle.com svn-commits at oss.oracle.com
Wed May 31 18:27:13 CDT 2006


Author: zab
Date: 2006-05-31 18:27:10 -0500 (Wed, 31 May 2006)
New Revision: 88

Modified:
   trunk/TODO
   trunk/linux/net/rds/loop.c
   trunk/linux/net/rds/message.c
   trunk/linux/net/rds/rds.h
   trunk/linux/net/rds/recv.c
   trunk/linux/net/rds/send.c
   trunk/linux/net/rds/tcp_recv.c
   trunk/man/rds.7
Log:
Support sending and receiving messages with no data payload.

incs get an saddr field so that transports can pass in the appropriate sender
address.

Fix a fantastic bug in recvmsg where the user saw the senders port and address
reversed.

Stop sendmsg and recvmsg from just returning 0 when given a 0 size.

The sending vec iterator has to notice that a message was only built of
a frag header.

sendmsg had to be updated to allocate a frag header for 0 bytes and to
reserve 0 bytes from the flow's send buffer.

Finally, the TODO file and man page are updated.


Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/TODO	2006-05-31 23:27:10 UTC (rev 88)
@@ -37,10 +37,6 @@
 	- generic and per-transport
 	- how to discover what transports are registered?
 
-0 length messages are awkwardly handled.  We should probably support
-them like udp?  recvmsg will fill in the peer address but there will
-be no data?
-
 get a reserved port from iana
 
 What's the story with the NET_RDS define?

Modified: trunk/linux/net/rds/loop.c
===================================================================
--- trunk/linux/net/rds/loop.c	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/linux/net/rds/loop.c	2006-05-31 23:27:10 UTC (rev 88)
@@ -75,7 +75,7 @@
 		 * as part of the minor header refactoring.
 		 */
 		rm->m_inc.i_hdr.h_flags = RDS_HEAD_FLAG_EOM; /* !ack, !frag */
-		rds_inc_init(&rm->m_inc, conn);
+		rds_inc_init(&rm->m_inc, conn, conn->c_laddr);
 		rds_message_addref(rm); /* for the inc */
 
 		rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr,

Modified: trunk/linux/net/rds/message.c
===================================================================
--- trunk/linux/net/rds/message.c	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/linux/net/rds/message.c	2006-05-31 23:27:10 UTC (rev 88)
@@ -156,8 +156,7 @@
 }
 
 /*
- * XXX figure out what we do with 0 len messages, currently the caller
- * stops them.
+ * for zero length messages the caller passes in nr_frags = 1 and total_len = 0
  */
 struct rds_message *rds_message_copy_from_user(struct iovec *first_iov,
 					       unsigned long nr_frags,

Modified: trunk/linux/net/rds/rds.h
===================================================================
--- trunk/linux/net/rds/rds.h	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/linux/net/rds/rds.h	2006-05-31 23:27:10 UTC (rev 88)
@@ -104,6 +104,7 @@
 	struct list_head	i_item;
 	struct rds_connection	*i_conn;
 	struct rds_header	i_hdr;
+	__be32			i_saddr;
 };
 
 struct rds_message {
@@ -242,7 +243,8 @@
 void rds_message_put(struct rds_message *rm);
 
 /* recv.c */
-void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn);
+void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
+		  __be32 saddr);
 void rds_inc_addref(struct rds_incoming *inc);
 void rds_inc_put(struct rds_incoming *inc);
 void rds_inc_ack(struct rds_incoming *inc, gfp_t gfp, enum km_type km);

Modified: trunk/linux/net/rds/recv.c
===================================================================
--- trunk/linux/net/rds/recv.c	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/linux/net/rds/recv.c	2006-05-31 23:27:10 UTC (rev 88)
@@ -23,11 +23,13 @@
 
 #include "rds.h"
 
-void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn)
+void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
+		  __be32 saddr)
 {
 	atomic_set(&inc->i_refcount, 1);
 	INIT_LIST_HEAD(&inc->i_item);
 	inc->i_conn = conn;
+	inc->i_saddr = saddr;
 }
 
 void rds_inc_addref(struct rds_incoming *inc)
@@ -242,9 +244,6 @@
 	struct sockaddr_in *sin;
 	struct rds_incoming *inc = NULL;
 
-	if (size == 0) /* XXX correct? */
-		goto out;
-
 	/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */
 	timeo = sock_rcvtimeo(sk, nonblock);
 
@@ -269,7 +268,9 @@
 			break;
 		}
 
-		pr_debug("copying inc %p to user\n", inc);
+		pr_debug("copying inc %p from %u.%u.%u.%u:%u to user\n", inc,
+			 NIPQUAD(inc->i_conn->c_faddr),
+			 ntohs(inc->i_hdr.h_sport));
 		ret = inc->i_conn->c_trans->inc_copy_to_user(inc, msg->msg_iov,
 							     size);
 		if (ret < 0)
@@ -290,14 +291,13 @@
 		sin = (struct sockaddr_in *)msg->msg_name;
 		if (sin) {
 			sin->sin_family = AF_INET;
-			sin->sin_port = inc->i_conn->c_faddr;
-			sin->sin_addr.s_addr = inc->i_hdr.h_sport;
+			sin->sin_port = inc->i_hdr.h_sport;
+			sin->sin_addr.s_addr = inc->i_saddr;
 			memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 		}
 		break;
 	}
 
-out:
 	if (inc)
 		rds_inc_put(inc);
 	return ret;

Modified: trunk/linux/net/rds/send.c
===================================================================
--- trunk/linux/net/rds/send.c	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/linux/net/rds/send.c	2006-05-31 23:27:10 UTC (rev 88)
@@ -182,6 +182,16 @@
 	if (cur->v_len)
 		goto out;
 
+	/* 
+	 * special case messages with no payload so that for the rest
+	 * of the fucntion we can assume a non-zero vec array and
+	 * trust our data vec pointer.
+	 */
+	if (conn->c_cur_msg->m_nr_vecs == 0) {
+		rds_send_reset_vec(conn);
+		goto out;
+	}
+
 	data = &conn->c_cur_msg->m_vecs[conn->c_cur_data_vec];
 
 	/* finished a header, advance header and point to current payload */
@@ -250,7 +260,7 @@
 	spin_lock_irqsave(&flow->f_conn->c_lock, flags);
 
 	new = flow->f_message_bytes + rm->m_len;
-	if (new > flow->f_message_bytes && new <= flow->f_rs->rs_sndbuf) {
+	if (new >= flow->f_message_bytes && new <= flow->f_rs->rs_sndbuf) {
 		flow->f_message_bytes = new;
 
 		/* 
@@ -290,22 +300,20 @@
 	struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name;
 	struct rds_message *rm = NULL;
 	struct rds_flow *flow = NULL;
-	unsigned long nr_frags = ceil(payload_len, RDS_FRAG_SIZE);
+	unsigned long nr_frags;
 	int ret = 0;
 	int queued = 0;
 	int nonblock = msg->msg_flags & MSG_DONTWAIT;
 	long timeo = sock_rcvtimeo(sk, nonblock);
 
-	/* 
-	 * XXX need to figure out if we want to send a 0 len message like
-	 * udp would.
-	 */
-	if (payload_len == 0)
-		return 0;
-
 	rds_debug(rs, "sendmsg sock %p sk %p len %zu\n", sock, sk,
 		  payload_len);
 
+	if (payload_len == 0)
+		nr_frags = 1;
+	else
+		nr_frags = ceil(payload_len, RDS_FRAG_SIZE);
+
 	/* XXX fail non-unicast destination IPs? */
 	if (msg->msg_namelen < sizeof(*usin) || usin->sin_family != AF_INET ||
 	    usin->sin_port == 0) {

Modified: trunk/linux/net/rds/tcp_recv.c
===================================================================
--- trunk/linux/net/rds/tcp_recv.c	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/linux/net/rds/tcp_recv.c	2006-05-31 23:27:10 UTC (rev 88)
@@ -100,6 +100,9 @@
 	unsigned long to_copy, skb_off;
 	int ret = 0;
 
+	if (size == 0)
+		goto out;
+
 	tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
 	iov = first_iov;
 	tmp = *iov;
@@ -171,7 +174,8 @@
 			}
 			tc->t_tinc = tinc;
 			pr_debug("alloced tinc %p\n", tinc);
-			rds_inc_init(&tinc->ti_inc, tc->t_conn);
+			rds_inc_init(&tinc->ti_inc, tc->t_conn,
+				     tc->t_conn->c_faddr);
 			/*
 			 * XXX * we might be able to use the __ variants when
 			 * we've already serialized at a higher level.
@@ -192,9 +196,11 @@
 			left -= to_copy;
 			offset += to_copy;
 
-			if (tc->t_tinc_hdr_rem == 0)
+			if (tc->t_tinc_hdr_rem == 0) {
+				/* could be 0 for a 0 len message */
 				tc->t_tinc_data_rem = 
 					be16_to_cpu(tinc->ti_inc.i_hdr.h_len);
+			}
 		}
 
 		if (left && tc->t_tinc_data_rem) {

Modified: trunk/man/rds.7
===================================================================
--- trunk/man/rds.7	2006-05-31 21:36:50 UTC (rev 87)
+++ trunk/man/rds.7	2006-05-31 23:27:10 UTC (rev 88)
@@ -74,6 +74,11 @@
 .B SO_SNDBUF
 socket option is ignored.
 
+A message sent with no payload bytes will not consume any space in the
+destination's send buffer but will result in a message receipt on the
+destination.  The receiver will not get any payload data but will be able to
+see the sender's address.
+
 .SH MESSAGE RECEIPT
 
 Messages may be received with 
@@ -95,6 +100,13 @@
 .B SO_RCVBUF
 socket option is ignored.
 
+If the incoming message is too large to fit in the buffer provided then
+excess bytes will be discarded.  Providing a buffer with a length of zero
+bytes will result in no data from the message being copied but the address
+of the sender will still be reflected in 
+.B msg_name
+\&.
+
 .SH POLL
 
 RDS supports a limited 




More information about the rds-commits mailing list