new helpers: no_seek_end_llseek{,_size}()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 6 Dec 2015 03:04:48 +0000 (22:04 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 23 Dec 2015 15:41:31 +0000 (10:41 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
13 files changed:
arch/sparc/kernel/mdesc.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/msr.c
drivers/char/nwflash.c
drivers/net/wireless/ti/wlcore/debugfs.c
drivers/s390/char/vmur.c
drivers/s390/char/zcore.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/host/uhci-debug.c
drivers/usb/misc/sisusbvga/sisusb.c
fs/read_write.c
include/linux/fs.h

index 6f80936..1122886 100644 (file)
@@ -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;
-
-       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;
+       struct mdesc_handle *hp = file->private_data;
 
-       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
index bd3507d..2836de3 100644 (file)
@@ -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,
 };
index 113e707..64f9616 100644 (file)
 
 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,
index e371480..dbe598d 100644 (file)
@@ -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;
 }
index eb43f94..be72306 100644 (file)
@@ -1205,26 +1205,11 @@ err_out:
 
 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 = {
index 0efb27f..6c30e93 100644 (file)
@@ -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 = {
index 823f41f..3339b86 100644 (file)
@@ -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;
 }
index 2a3bbdf..cffa0a0 100644 (file)
@@ -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,
 };
index 38ae877..dbc3e14 100644 (file)
@@ -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,
index 1b28a00..9c6635d 100644 (file)
@@ -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,
index 306d685..8efbaba 100644 (file)
@@ -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;
index 819ef3f..acb1713 100644 (file)
@@ -171,6 +171,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
  * @offset:    file offset to seek to
index bd14476..fb0fa22 100644 (file)
@@ -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);