forked from mirrors/linux
		
	iov_iter: separate direction from flavour
Instead of having them mixed in iter->type, use separate ->iter_type and ->data_source (u8 and bool resp.) And don't bother with (pseudo-) bitmap for the former - microoptimizations from being able to check if the flavour is one of two values are not worth the confusion for optimizer. It can't prove that we never get e.g. ITER_IOVEC | ITER_PIPE, so we end up with extra headache. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									556351c1c0
								
							
						
					
					
						commit
						8cd54c1c84
					
				
					 2 changed files with 58 additions and 51 deletions
				
			
		|  | @ -19,21 +19,17 @@ struct kvec { | ||||||
| 
 | 
 | ||||||
| enum iter_type { | enum iter_type { | ||||||
| 	/* iter types */ | 	/* iter types */ | ||||||
| 	ITER_IOVEC = 4, | 	ITER_IOVEC, | ||||||
| 	ITER_KVEC = 8, | 	ITER_KVEC, | ||||||
| 	ITER_BVEC = 16, | 	ITER_BVEC, | ||||||
| 	ITER_PIPE = 32, | 	ITER_PIPE, | ||||||
| 	ITER_DISCARD = 64, | 	ITER_XARRAY, | ||||||
| 	ITER_XARRAY = 128, | 	ITER_DISCARD, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct iov_iter { | struct iov_iter { | ||||||
| 	/*
 | 	u8 iter_type; | ||||||
| 	 * Bit 0 is the read/write bit, set if we're writing. | 	bool data_source; | ||||||
| 	 * Bit 1 is the BVEC_FLAG_NO_REF bit, set if type is a bvec and |  | ||||||
| 	 * the caller isn't expecting to drop a page reference when done. |  | ||||||
| 	 */ |  | ||||||
| 	unsigned int type; |  | ||||||
| 	size_t iov_offset; | 	size_t iov_offset; | ||||||
| 	size_t count; | 	size_t count; | ||||||
| 	union { | 	union { | ||||||
|  | @ -55,7 +51,7 @@ struct iov_iter { | ||||||
| 
 | 
 | ||||||
| static inline enum iter_type iov_iter_type(const struct iov_iter *i) | static inline enum iter_type iov_iter_type(const struct iov_iter *i) | ||||||
| { | { | ||||||
| 	return i->type & ~(READ | WRITE); | 	return i->iter_type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline bool iter_is_iovec(const struct iov_iter *i) | static inline bool iter_is_iovec(const struct iov_iter *i) | ||||||
|  | @ -90,7 +86,7 @@ static inline bool iov_iter_is_xarray(const struct iov_iter *i) | ||||||
| 
 | 
 | ||||||
| static inline unsigned char iov_iter_rw(const struct iov_iter *i) | static inline unsigned char iov_iter_rw(const struct iov_iter *i) | ||||||
| { | { | ||||||
| 	return i->type & (READ | WRITE); | 	return i->data_source ? WRITE : READ; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  |  | ||||||
|  | @ -489,19 +489,15 @@ void iov_iter_init(struct iov_iter *i, unsigned int direction, | ||||||
| 			size_t count) | 			size_t count) | ||||||
| { | { | ||||||
| 	WARN_ON(direction & ~(READ | WRITE)); | 	WARN_ON(direction & ~(READ | WRITE)); | ||||||
| 	direction &= READ | WRITE; | 	WARN_ON_ONCE(uaccess_kernel()); | ||||||
| 
 | 	*i = (struct iov_iter) { | ||||||
| 	/* It will get better.  Eventually... */ | 		.iter_type = ITER_IOVEC, | ||||||
| 	if (uaccess_kernel()) { | 		.data_source = direction, | ||||||
| 		i->type = ITER_KVEC | direction; | 		.iov = iov, | ||||||
| 		i->kvec = (struct kvec *)iov; | 		.nr_segs = nr_segs, | ||||||
| 	} else { | 		.iov_offset = 0, | ||||||
| 		i->type = ITER_IOVEC | direction; | 		.count = count | ||||||
| 		i->iov = iov; | 	}; | ||||||
| 	} |  | ||||||
| 	i->nr_segs = nr_segs; |  | ||||||
| 	i->iov_offset = 0; |  | ||||||
| 	i->count = count; |  | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(iov_iter_init); | EXPORT_SYMBOL(iov_iter_init); | ||||||
| 
 | 
 | ||||||
|  | @ -1218,11 +1214,14 @@ void iov_iter_kvec(struct iov_iter *i, unsigned int direction, | ||||||
| 			size_t count) | 			size_t count) | ||||||
| { | { | ||||||
| 	WARN_ON(direction & ~(READ | WRITE)); | 	WARN_ON(direction & ~(READ | WRITE)); | ||||||
| 	i->type = ITER_KVEC | (direction & (READ | WRITE)); | 	*i = (struct iov_iter){ | ||||||
| 	i->kvec = kvec; | 		.iter_type = ITER_KVEC, | ||||||
| 	i->nr_segs = nr_segs; | 		.data_source = direction, | ||||||
| 	i->iov_offset = 0; | 		.kvec = kvec, | ||||||
| 	i->count = count; | 		.nr_segs = nr_segs, | ||||||
|  | 		.iov_offset = 0, | ||||||
|  | 		.count = count | ||||||
|  | 	}; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(iov_iter_kvec); | EXPORT_SYMBOL(iov_iter_kvec); | ||||||
| 
 | 
 | ||||||
|  | @ -1231,11 +1230,14 @@ void iov_iter_bvec(struct iov_iter *i, unsigned int direction, | ||||||
| 			size_t count) | 			size_t count) | ||||||
| { | { | ||||||
| 	WARN_ON(direction & ~(READ | WRITE)); | 	WARN_ON(direction & ~(READ | WRITE)); | ||||||
| 	i->type = ITER_BVEC | (direction & (READ | WRITE)); | 	*i = (struct iov_iter){ | ||||||
| 	i->bvec = bvec; | 		.iter_type = ITER_BVEC, | ||||||
| 	i->nr_segs = nr_segs; | 		.data_source = direction, | ||||||
| 	i->iov_offset = 0; | 		.bvec = bvec, | ||||||
| 	i->count = count; | 		.nr_segs = nr_segs, | ||||||
|  | 		.iov_offset = 0, | ||||||
|  | 		.count = count | ||||||
|  | 	}; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(iov_iter_bvec); | EXPORT_SYMBOL(iov_iter_bvec); | ||||||
| 
 | 
 | ||||||
|  | @ -1245,12 +1247,15 @@ void iov_iter_pipe(struct iov_iter *i, unsigned int direction, | ||||||
| { | { | ||||||
| 	BUG_ON(direction != READ); | 	BUG_ON(direction != READ); | ||||||
| 	WARN_ON(pipe_full(pipe->head, pipe->tail, pipe->ring_size)); | 	WARN_ON(pipe_full(pipe->head, pipe->tail, pipe->ring_size)); | ||||||
| 	i->type = ITER_PIPE | READ; | 	*i = (struct iov_iter){ | ||||||
| 	i->pipe = pipe; | 		.iter_type = ITER_PIPE, | ||||||
| 	i->head = pipe->head; | 		.data_source = false, | ||||||
| 	i->iov_offset = 0; | 		.pipe = pipe, | ||||||
| 	i->count = count; | 		.head = pipe->head, | ||||||
| 	i->start_head = i->head; | 		.start_head = pipe->head, | ||||||
|  | 		.iov_offset = 0, | ||||||
|  | 		.count = count | ||||||
|  | 	}; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(iov_iter_pipe); | EXPORT_SYMBOL(iov_iter_pipe); | ||||||
| 
 | 
 | ||||||
|  | @ -1271,11 +1276,14 @@ void iov_iter_xarray(struct iov_iter *i, unsigned int direction, | ||||||
| 		     struct xarray *xarray, loff_t start, size_t count) | 		     struct xarray *xarray, loff_t start, size_t count) | ||||||
| { | { | ||||||
| 	BUG_ON(direction & ~1); | 	BUG_ON(direction & ~1); | ||||||
| 	i->type = ITER_XARRAY | (direction & (READ | WRITE)); | 	*i = (struct iov_iter) { | ||||||
| 	i->xarray = xarray; | 		.iter_type = ITER_XARRAY, | ||||||
| 	i->xarray_start = start; | 		.data_source = direction, | ||||||
| 	i->count = count; | 		.xarray = xarray, | ||||||
| 	i->iov_offset = 0; | 		.xarray_start = start, | ||||||
|  | 		.count = count, | ||||||
|  | 		.iov_offset = 0 | ||||||
|  | 	}; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(iov_iter_xarray); | EXPORT_SYMBOL(iov_iter_xarray); | ||||||
| 
 | 
 | ||||||
|  | @ -1291,9 +1299,12 @@ EXPORT_SYMBOL(iov_iter_xarray); | ||||||
| void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count) | void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count) | ||||||
| { | { | ||||||
| 	BUG_ON(direction != READ); | 	BUG_ON(direction != READ); | ||||||
| 	i->type = ITER_DISCARD | READ; | 	*i = (struct iov_iter){ | ||||||
| 	i->count = count; | 		.iter_type = ITER_DISCARD, | ||||||
| 	i->iov_offset = 0; | 		.data_source = false, | ||||||
|  | 		.count = count, | ||||||
|  | 		.iov_offset = 0 | ||||||
|  | 	}; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(iov_iter_discard); | EXPORT_SYMBOL(iov_iter_discard); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Al Viro
						Al Viro