tipc: Avoid recomputation of outgoing message length

Rework TIPC's message sending routines to take advantage of the total
amount of data value passed to it by the kernel socket infrastructure.
This change eliminates the need for TIPC to compute the size of outgoing
messages itself, as well as the check for an oversize message in
tipc_msg_build().  In addition, this change warrants an explanation:

   -     res = send_packet(NULL, sock, &my_msg, 0);
   +     res = send_packet(NULL, sock, &my_msg, bytes_to_send);

Previously, the final argument to send_packet() was ignored (since the
amount of data being sent was recalculated by a lower-level routine)
and we could just pass in a dummy value (0). Now that the
recalculation is being eliminated, the argument value being passed to
send_packet() is significant and we have to supply the actual amount
of data we want to send.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 9f2ff12..c68dc95 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -74,7 +74,8 @@
  */
 
 int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
-		   u32 num_sect, struct iovec const *msg_sect)
+		   u32 num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len)
 {
 	struct tipc_msg *hdr;
 	struct sk_buff *buf;
@@ -98,7 +99,7 @@
 	msg_set_namelower(hdr, seq->lower);
 	msg_set_nameupper(hdr, seq->upper);
 	msg_set_hdr_sz(hdr, MCAST_H_SIZE);
-	res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
+	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
 			!oport->user_port, &buf);
 	if (unlikely(!buf))
 		return res;
@@ -418,12 +419,12 @@
 
 int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
 			      struct iovec const *msg_sect, u32 num_sect,
-			      int err)
+			      unsigned int total_len, int err)
 {
 	struct sk_buff *buf;
 	int res;
 
-	res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
+	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE,
 			!p_ptr->user_port, &buf);
 	if (!buf)
 		return res;
@@ -1163,12 +1164,13 @@
  */
 
 static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
-				   struct iovec const *msg_sect)
+				   struct iovec const *msg_sect,
+				   unsigned int total_len)
 {
 	struct sk_buff *buf;
 	int res;
 
-	res = tipc_msg_build(&sender->phdr, msg_sect, num_sect,
+	res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len,
 			MAX_MSG_SIZE, !sender->user_port, &buf);
 	if (likely(buf))
 		tipc_port_recv_msg(buf);
@@ -1179,7 +1181,8 @@
  * tipc_send - send message sections on connection
  */
 
-int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
+int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
+	      unsigned int total_len)
 {
 	struct tipc_port *p_ptr;
 	u32 destnode;
@@ -1194,9 +1197,10 @@
 		destnode = port_peernode(p_ptr);
 		if (likely(destnode != tipc_own_addr))
 			res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
-							   destnode);
+							   total_len, destnode);
 		else
-			res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+			res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
+						      total_len);
 
 		if (likely(res != -ELINKCONG)) {
 			p_ptr->congested = 0;
@@ -1207,8 +1211,7 @@
 	}
 	if (port_unreliable(p_ptr)) {
 		p_ptr->congested = 0;
-		/* Just calculate msg length and return */
-		return tipc_msg_calc_data_size(msg_sect, num_sect);
+		return total_len;
 	}
 	return -ELINKCONG;
 }
@@ -1218,7 +1221,8 @@
  */
 
 int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
-	   unsigned int num_sect, struct iovec const *msg_sect)
+		   unsigned int num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len)
 {
 	struct tipc_port *p_ptr;
 	struct tipc_msg *msg;
@@ -1245,23 +1249,23 @@
 	if (likely(destport)) {
 		if (likely(destnode == tipc_own_addr))
 			res = tipc_port_recv_sections(p_ptr, num_sect,
-						      msg_sect);
+						      msg_sect, total_len);
 		else
 			res = tipc_link_send_sections_fast(p_ptr, msg_sect,
-							   num_sect, destnode);
+							   num_sect, total_len,
+							   destnode);
 		if (likely(res != -ELINKCONG)) {
 			if (res > 0)
 				p_ptr->sent++;
 			return res;
 		}
 		if (port_unreliable(p_ptr)) {
-			/* Just calculate msg length and return */
-			return tipc_msg_calc_data_size(msg_sect, num_sect);
+			return total_len;
 		}
 		return -ELINKCONG;
 	}
 	return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect,
-					 TIPC_ERR_NO_NAME);
+					 total_len, TIPC_ERR_NO_NAME);
 }
 
 /**
@@ -1269,7 +1273,8 @@
  */
 
 int tipc_send2port(u32 ref, struct tipc_portid const *dest,
-	   unsigned int num_sect, struct iovec const *msg_sect)
+		   unsigned int num_sect, struct iovec const *msg_sect,
+		   unsigned int total_len)
 {
 	struct tipc_port *p_ptr;
 	struct tipc_msg *msg;
@@ -1289,18 +1294,18 @@
 	msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
 
 	if (dest->node == tipc_own_addr)
-		res =  tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+		res =  tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
+					       total_len);
 	else
 		res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
-						   dest->node);
+						   total_len, dest->node);
 	if (likely(res != -ELINKCONG)) {
 		if (res > 0)
 			p_ptr->sent++;
 		return res;
 	}
 	if (port_unreliable(p_ptr)) {
-		/* Just calculate msg length and return */
-		return tipc_msg_calc_data_size(msg_sect, num_sect);
+		return total_len;
 	}
 	return -ELINKCONG;
 }