mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	xfs: only return -errno or success from attr ->put_listent
Today, the put_listent formatters return either 1 or 0; if they return 1, some callers treat this as an error and return it up the stack, despite "1" not being a valid (negative) error code. The intent seems to be that if the input buffer is full, we set seen_enough or set count = -1, and return 1; but some callers check the return before checking the seen_enough or count fields of the context. Fix this by only returning non-zero for actual errors encountered, and rely on the caller to first check the return value, then check the values in the context to decide what to do. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
		
							parent
							
								
									f55532a0c0
								
							
						
					
					
						commit
						2a6fba6d23
					
				
					 3 changed files with 14 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -112,6 +112,7 @@ typedef struct attrlist_cursor_kern {
 | 
			
		|||
 *========================================================================*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Return 0 on success, or -errno; other state communicated via *context */
 | 
			
		||||
typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int,
 | 
			
		||||
			      unsigned char *, int, int, unsigned char *);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,16 +108,14 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
 | 
			
		|||
					   (int)sfe->namelen,
 | 
			
		||||
					   (int)sfe->valuelen,
 | 
			
		||||
					   &sfe->nameval[sfe->namelen]);
 | 
			
		||||
 | 
			
		||||
			if (error)
 | 
			
		||||
				return error;
 | 
			
		||||
			/*
 | 
			
		||||
			 * Either search callback finished early or
 | 
			
		||||
			 * didn't fit it all in the buffer after all.
 | 
			
		||||
			 */
 | 
			
		||||
			if (context->seen_enough)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			if (error)
 | 
			
		||||
				return error;
 | 
			
		||||
			sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
 | 
			
		||||
		}
 | 
			
		||||
		trace_xfs_attr_list_sf_all(context);
 | 
			
		||||
| 
						 | 
				
			
			@ -581,7 +579,7 @@ xfs_attr_put_listent(
 | 
			
		|||
		trace_xfs_attr_list_full(context);
 | 
			
		||||
		alist->al_more = 1;
 | 
			
		||||
		context->seen_enough = 1;
 | 
			
		||||
		return 1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	aep = (attrlist_ent_t *)&context->alist[context->firstu];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ __xfs_xattr_put_listent(
 | 
			
		|||
	arraytop = context->count + prefix_len + namelen + 1;
 | 
			
		||||
	if (arraytop > context->firstu) {
 | 
			
		||||
		context->count = -1;	/* insufficient space */
 | 
			
		||||
		return 1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	offset = (char *)context->alist + context->count;
 | 
			
		||||
	strncpy(offset, prefix, prefix_len);
 | 
			
		||||
| 
						 | 
				
			
			@ -221,11 +221,15 @@ xfs_xattr_put_listent(
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
 | 
			
		||||
xfs_vn_listxattr(
 | 
			
		||||
	struct dentry	*dentry,
 | 
			
		||||
	char		*data,
 | 
			
		||||
	size_t		size)
 | 
			
		||||
{
 | 
			
		||||
	struct xfs_attr_list_context context;
 | 
			
		||||
	struct attrlist_cursor_kern cursor = { 0 };
 | 
			
		||||
	struct inode		*inode = d_inode(dentry);
 | 
			
		||||
	struct inode	*inode = d_inode(dentry);
 | 
			
		||||
	int		error;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * First read the regular on-disk attributes.
 | 
			
		||||
| 
						 | 
				
			
			@ -239,7 +243,9 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
 | 
			
		|||
	context.firstu = context.bufsize;
 | 
			
		||||
	context.put_listent = xfs_xattr_put_listent;
 | 
			
		||||
 | 
			
		||||
	xfs_attr_list_int(&context);
 | 
			
		||||
	error = xfs_attr_list_int(&context);
 | 
			
		||||
	if (error)
 | 
			
		||||
		return error;
 | 
			
		||||
	if (context.count < 0)
 | 
			
		||||
		return -ERANGE;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue