mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	new helpers: no_seek_end_llseek{,_size}()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									b808b1d632
								
							
						
					
					
						commit
						b25472f9b9
					
				
					 13 changed files with 54 additions and 222 deletions
				
			
		| 
						 | 
				
			
			@ -1033,25 +1033,9 @@ static ssize_t mdesc_read(struct file *file, char __user *buf,
 | 
			
		|||
 | 
			
		||||
static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence)
 | 
			
		||||
{
 | 
			
		||||
	struct mdesc_handle *hp;
 | 
			
		||||
	struct mdesc_handle *hp = file->private_data;
 | 
			
		||||
 | 
			
		||||
	switch (whence) {
 | 
			
		||||
	case SEEK_CUR:
 | 
			
		||||
		offset += file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case SEEK_SET:
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hp = file->private_data;
 | 
			
		||||
	if (offset > hp->handle_size)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	else
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
 | 
			
		||||
	return offset;
 | 
			
		||||
	return no_seek_end_llseek_size(file, offset, whence, hp->handle_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* mdesc_close() - /dev/mdesc is being closed, release the reference to
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,28 +58,6 @@ static void cpuid_smp_cpuid(void *cmd_block)
 | 
			
		|||
		    &cmd->eax, &cmd->ebx, &cmd->ecx, &cmd->edx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
 | 
			
		||||
{
 | 
			
		||||
	loff_t ret;
 | 
			
		||||
	struct inode *inode = file->f_mapping->host;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&inode->i_mutex);
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	mutex_unlock(&inode->i_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t cpuid_read(struct file *file, char __user *buf,
 | 
			
		||||
			  size_t count, loff_t *ppos)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +110,7 @@ static int cpuid_open(struct inode *inode, struct file *file)
 | 
			
		|||
 */
 | 
			
		||||
static const struct file_operations cpuid_fops = {
 | 
			
		||||
	.owner = THIS_MODULE,
 | 
			
		||||
	.llseek = cpuid_seek,
 | 
			
		||||
	.llseek = no_seek_end_llseek,
 | 
			
		||||
	.read = cpuid_read,
 | 
			
		||||
	.open = cpuid_open,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,28 +45,6 @@
 | 
			
		|||
 | 
			
		||||
static struct class *msr_class;
 | 
			
		||||
 | 
			
		||||
static loff_t msr_seek(struct file *file, loff_t offset, int orig)
 | 
			
		||||
{
 | 
			
		||||
	loff_t ret;
 | 
			
		||||
	struct inode *inode = file_inode(file);
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&inode->i_mutex);
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case SEEK_SET:
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case SEEK_CUR:
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	mutex_unlock(&inode->i_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t msr_read(struct file *file, char __user *buf,
 | 
			
		||||
			size_t count, loff_t *ppos)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +172,7 @@ static int msr_open(struct inode *inode, struct file *file)
 | 
			
		|||
 */
 | 
			
		||||
static const struct file_operations msr_fops = {
 | 
			
		||||
	.owner = THIS_MODULE,
 | 
			
		||||
	.llseek = msr_seek,
 | 
			
		||||
	.llseek = no_seek_end_llseek,
 | 
			
		||||
	.read = msr_read,
 | 
			
		||||
	.write = msr_write,
 | 
			
		||||
	.open = msr_open,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,36 +277,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
 | 
			
		|||
		printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
 | 
			
		||||
		       (unsigned int) offset, orig);
 | 
			
		||||
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		if (offset < 0) {
 | 
			
		||||
			ret = -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ((unsigned int) offset > gbFlashSize) {
 | 
			
		||||
			ret = -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		file->f_pos = (unsigned int) offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		if ((file->f_pos + offset) > gbFlashSize) {
 | 
			
		||||
			ret = -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if ((file->f_pos + offset) < 0) {
 | 
			
		||||
			ret = -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize);
 | 
			
		||||
	mutex_unlock(&flash_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1205,26 +1205,11 @@ static ssize_t dev_mem_write(struct file *file, const char __user *user_buf,
 | 
			
		|||
 | 
			
		||||
static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig)
 | 
			
		||||
{
 | 
			
		||||
	loff_t ret;
 | 
			
		||||
 | 
			
		||||
	/* only requests of dword-aligned size and offset are supported */
 | 
			
		||||
	if (offset % 4)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case SEEK_SET:
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case SEEK_CUR:
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	return no_seek_end_llseek(file, offset, orig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct file_operations dev_mem_ops = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -782,24 +782,11 @@ static int ur_release(struct inode *inode, struct file *file)
 | 
			
		|||
 | 
			
		||||
static loff_t ur_llseek(struct file *file, loff_t offset, int whence)
 | 
			
		||||
{
 | 
			
		||||
	loff_t newpos;
 | 
			
		||||
 | 
			
		||||
	if ((file->f_flags & O_ACCMODE) != O_RDONLY)
 | 
			
		||||
		return -ESPIPE; /* seek allowed only for reader */
 | 
			
		||||
	if (offset % PAGE_SIZE)
 | 
			
		||||
		return -ESPIPE; /* only multiples of 4K allowed */
 | 
			
		||||
	switch (whence) {
 | 
			
		||||
	case 0: /* SEEK_SET */
 | 
			
		||||
		newpos = offset;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1: /* SEEK_CUR */
 | 
			
		||||
		newpos = file->f_pos + offset;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	file->f_pos = newpos;
 | 
			
		||||
	return newpos;
 | 
			
		||||
	return no_seek_end_llseek(file, offset, whence);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct file_operations ur_fops = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -385,18 +385,7 @@ static loff_t zcore_lseek(struct file *file, loff_t offset, int orig)
 | 
			
		|||
	loff_t rc;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&zcore_mutex);
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
		rc = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		rc = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		rc = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	rc = no_seek_end_llseek(file, offset, orig);
 | 
			
		||||
	mutex_unlock(&zcore_mutex);
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -661,32 +661,8 @@ static unsigned int usb_device_poll(struct file *file,
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)
 | 
			
		||||
{
 | 
			
		||||
	loff_t ret;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&file_inode(file)->i_mutex);
 | 
			
		||||
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mutex_unlock(&file_inode(file)->i_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const struct file_operations usbfs_devices_fops = {
 | 
			
		||||
	.llseek =	usb_device_lseek,
 | 
			
		||||
	.llseek =	no_seek_end_llseek,
 | 
			
		||||
	.read =		usb_device_read,
 | 
			
		||||
	.poll =		usb_device_poll,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,30 +157,6 @@ static int connected(struct usb_dev_state *ps)
 | 
			
		|||
			ps->dev->state != USB_STATE_NOTATTACHED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
 | 
			
		||||
{
 | 
			
		||||
	loff_t ret;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&file_inode(file)->i_mutex);
 | 
			
		||||
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		file->f_pos = offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		file->f_pos += offset;
 | 
			
		||||
		ret = file->f_pos;
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mutex_unlock(&file_inode(file)->i_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes,
 | 
			
		||||
			   loff_t *ppos)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -2366,7 +2342,7 @@ static unsigned int usbdev_poll(struct file *file,
 | 
			
		|||
 | 
			
		||||
const struct file_operations usbdev_file_operations = {
 | 
			
		||||
	.owner =	  THIS_MODULE,
 | 
			
		||||
	.llseek =	  usbdev_lseek,
 | 
			
		||||
	.llseek =	  no_seek_end_llseek,
 | 
			
		||||
	.read =		  usbdev_read,
 | 
			
		||||
	.poll =		  usbdev_poll,
 | 
			
		||||
	.unlocked_ioctl = usbdev_ioctl,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -584,27 +584,8 @@ static int uhci_debug_open(struct inode *inode, struct file *file)
 | 
			
		|||
 | 
			
		||||
static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence)
 | 
			
		||||
{
 | 
			
		||||
	struct uhci_debug *up;
 | 
			
		||||
	loff_t new = -1;
 | 
			
		||||
 | 
			
		||||
	up = file->private_data;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * XXX: atomic 64bit seek access, but that needs to be fixed in the VFS
 | 
			
		||||
	 */
 | 
			
		||||
	switch (whence) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		new = off;
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		new = file->f_pos + off;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (new < 0 || new > up->size)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return (file->f_pos = new);
 | 
			
		||||
	struct uhci_debug *up = file->private_data;
 | 
			
		||||
	return no_seek_end_llseek_size(file, off, whence, up->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t uhci_debug_read(struct file *file, char __user *buf,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2825,21 +2825,7 @@ sisusb_lseek(struct file *file, loff_t offset, int orig)
 | 
			
		|||
		return -ENODEV;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (orig) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			file->f_pos = offset;
 | 
			
		||||
			ret = file->f_pos;
 | 
			
		||||
			/* never negative, no force_successful_syscall needed */
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			file->f_pos += offset;
 | 
			
		||||
			ret = file->f_pos;
 | 
			
		||||
			/* never negative, no force_successful_syscall needed */
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* seeking relative to "end of file" is not supported */
 | 
			
		||||
			ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	ret = no_seek_end_llseek(file, offset, orig);
 | 
			
		||||
 | 
			
		||||
	mutex_unlock(&sisusb->lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,6 +170,45 @@ loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t si
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(fixed_size_llseek);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * no_seek_end_llseek - llseek implementation for fixed-sized devices
 | 
			
		||||
 * @file:	file structure to seek on
 | 
			
		||||
 * @offset:	file offset to seek to
 | 
			
		||||
 * @whence:	type of seek
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
loff_t no_seek_end_llseek(struct file *file, loff_t offset, int whence)
 | 
			
		||||
{
 | 
			
		||||
	switch (whence) {
 | 
			
		||||
	case SEEK_SET: case SEEK_CUR:
 | 
			
		||||
		return generic_file_llseek_size(file, offset, whence,
 | 
			
		||||
						~0ULL, 0);
 | 
			
		||||
	default:
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(no_seek_end_llseek);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * no_seek_end_llseek_size - llseek implementation for fixed-sized devices
 | 
			
		||||
 * @file:	file structure to seek on
 | 
			
		||||
 * @offset:	file offset to seek to
 | 
			
		||||
 * @whence:	type of seek
 | 
			
		||||
 * @size:	maximal offset allowed
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
loff_t no_seek_end_llseek_size(struct file *file, loff_t offset, int whence, loff_t size)
 | 
			
		||||
{
 | 
			
		||||
	switch (whence) {
 | 
			
		||||
	case SEEK_SET: case SEEK_CUR:
 | 
			
		||||
		return generic_file_llseek_size(file, offset, whence,
 | 
			
		||||
						size, 0);
 | 
			
		||||
	default:
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(no_seek_end_llseek_size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * noop_llseek - No Operation Performed llseek implementation
 | 
			
		||||
 * @file:	file structure to seek on
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2660,6 +2660,8 @@ extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
 | 
			
		|||
		int whence, loff_t maxsize, loff_t eof);
 | 
			
		||||
extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
 | 
			
		||||
		int whence, loff_t size);
 | 
			
		||||
extern loff_t no_seek_end_llseek_size(struct file *, loff_t, int, loff_t);
 | 
			
		||||
extern loff_t no_seek_end_llseek(struct file *, loff_t, int);
 | 
			
		||||
extern int generic_file_open(struct inode * inode, struct file * filp);
 | 
			
		||||
extern int nonseekable_open(struct inode * inode, struct file * filp);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue