forked from mirrors/linux
		
	rds: refactor zcopy code into rds_message_zcopy_from_user
Move the large block of code predicated on zcopy from rds_message_copy_from_user into a new function, rds_message_zcopy_from_user() Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> Acked-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									c33b3b9fcf
								
							
						
					
					
						commit
						d40a126b16
					
				
					 1 changed files with 59 additions and 47 deletions
				
			
		|  | @ -333,14 +333,14 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in | |||
| 	return rm; | ||||
| } | ||||
| 
 | ||||
| int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from, | ||||
| 			       bool zcopy) | ||||
| int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from) | ||||
| { | ||||
| 	unsigned long to_copy, nbytes; | ||||
| 	unsigned long sg_off; | ||||
| 	struct scatterlist *sg; | ||||
| 	int ret = 0; | ||||
| 	int length = iov_iter_count(from); | ||||
| 	int total_copied = 0; | ||||
| 	struct sk_buff *skb; | ||||
| 
 | ||||
| 	rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from)); | ||||
| 
 | ||||
|  | @ -350,54 +350,66 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from, | |||
| 	sg = rm->data.op_sg; | ||||
| 	sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ | ||||
| 
 | ||||
| 	if (zcopy) { | ||||
| 		int total_copied = 0; | ||||
| 		struct sk_buff *skb; | ||||
| 	skb = alloc_skb(0, GFP_KERNEL); | ||||
| 	if (!skb) | ||||
| 		return -ENOMEM; | ||||
| 	BUILD_BUG_ON(sizeof(skb->cb) < max_t(int, sizeof(struct rds_znotifier), | ||||
| 					     sizeof(struct rds_zcopy_cookies))); | ||||
| 	rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb); | ||||
| 	if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp, | ||||
| 				    length)) { | ||||
| 		ret = -ENOMEM; | ||||
| 		goto err; | ||||
| 	} | ||||
| 	while (iov_iter_count(from)) { | ||||
| 		struct page *pages; | ||||
| 		size_t start; | ||||
| 		ssize_t copied; | ||||
| 
 | ||||
| 		skb = alloc_skb(0, GFP_KERNEL); | ||||
| 		if (!skb) | ||||
| 			return -ENOMEM; | ||||
| 		BUILD_BUG_ON(sizeof(skb->cb) < | ||||
| 			     max_t(int, sizeof(struct rds_znotifier), | ||||
| 				   sizeof(struct rds_zcopy_cookies))); | ||||
| 		rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb); | ||||
| 		if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp, | ||||
| 					    length)) { | ||||
| 			ret = -ENOMEM; | ||||
| 		copied = iov_iter_get_pages(from, &pages, PAGE_SIZE, | ||||
| 					    1, &start); | ||||
| 		if (copied < 0) { | ||||
| 			struct mmpin *mmp; | ||||
| 			int i; | ||||
| 
 | ||||
| 			for (i = 0; i < rm->data.op_nents; i++) | ||||
| 				put_page(sg_page(&rm->data.op_sg[i])); | ||||
| 			mmp = &rm->data.op_mmp_znotifier->z_mmp; | ||||
| 			mm_unaccount_pinned_pages(mmp); | ||||
| 			ret = -EFAULT; | ||||
| 			goto err; | ||||
| 		} | ||||
| 		while (iov_iter_count(from)) { | ||||
| 			struct page *pages; | ||||
| 			size_t start; | ||||
| 			ssize_t copied; | ||||
| 
 | ||||
| 			copied = iov_iter_get_pages(from, &pages, PAGE_SIZE, | ||||
| 						    1, &start); | ||||
| 			if (copied < 0) { | ||||
| 				struct mmpin *mmp; | ||||
| 				int i; | ||||
| 
 | ||||
| 				for (i = 0; i < rm->data.op_nents; i++) | ||||
| 					put_page(sg_page(&rm->data.op_sg[i])); | ||||
| 				mmp = &rm->data.op_mmp_znotifier->z_mmp; | ||||
| 				mm_unaccount_pinned_pages(mmp); | ||||
| 				ret = -EFAULT; | ||||
| 				goto err; | ||||
| 			} | ||||
| 			total_copied += copied; | ||||
| 			iov_iter_advance(from, copied); | ||||
| 			length -= copied; | ||||
| 			sg_set_page(sg, pages, copied, start); | ||||
| 			rm->data.op_nents++; | ||||
| 			sg++; | ||||
| 		} | ||||
| 		WARN_ON_ONCE(length != 0); | ||||
| 		return ret; | ||||
| 		total_copied += copied; | ||||
| 		iov_iter_advance(from, copied); | ||||
| 		length -= copied; | ||||
| 		sg_set_page(sg, pages, copied, start); | ||||
| 		rm->data.op_nents++; | ||||
| 		sg++; | ||||
| 	} | ||||
| 	WARN_ON_ONCE(length != 0); | ||||
| 	return ret; | ||||
| err: | ||||
| 		consume_skb(skb); | ||||
| 		rm->data.op_mmp_znotifier = NULL; | ||||
| 		return ret; | ||||
| 	} /* zcopy */ | ||||
| 	consume_skb(skb); | ||||
| 	rm->data.op_mmp_znotifier = NULL; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from, | ||||
| 			       bool zcopy) | ||||
| { | ||||
| 	unsigned long to_copy, nbytes; | ||||
| 	unsigned long sg_off; | ||||
| 	struct scatterlist *sg; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from)); | ||||
| 
 | ||||
| 	/* now allocate and copy in the data payload.  */ | ||||
| 	sg = rm->data.op_sg; | ||||
| 	sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ | ||||
| 
 | ||||
| 	if (zcopy) | ||||
| 		return rds_message_zcopy_from_user(rm, from); | ||||
| 
 | ||||
| 	while (iov_iter_count(from)) { | ||||
| 		if (!sg_page(sg)) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Sowmini Varadhan
						Sowmini Varadhan