fuse: llseek optimize SEEK_CUR and SEEK_SET
authorMiklos Szeredi <mszeredi@suse.cz>
Tue, 13 Dec 2011 10:58:48 +0000 (11:58 +0100)
committerMiklos Szeredi <mszeredi@suse.cz>
Tue, 13 Dec 2011 10:58:48 +0000 (11:58 +0100)
Use generic_file_llseek() instead of open coding the seek function.

i_mutex protection is only necessary for SEEK_END (and SEEK_HOLE, SEEK_DATA), so
move SEEK_CUR and SEEK_SET out from under i_mutex.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
fs/fuse/file.c

index 0c84100..e0b60ac 100644 (file)
@@ -1555,48 +1555,16 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
        loff_t retval;
        struct inode *inode = file->f_path.dentry->d_inode;
 
-       mutex_lock(&inode->i_mutex);
-       if (origin != SEEK_CUR && origin != SEEK_SET) {
-               retval = fuse_update_attributes(inode, NULL, file, NULL);
-               if (retval)
-                       goto exit;
-       }
+       /* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */
+       if (origin == SEEK_CUR || origin == SEEK_SET)
+               return generic_file_llseek(file, offset, origin);
 
-       switch (origin) {
-       case SEEK_END:
-               offset += i_size_read(inode);
-               break;
-       case SEEK_CUR:
-               if (offset == 0) {
-                       retval = file->f_pos;
-                       goto exit;
-               }
-               offset += file->f_pos;
-               break;
-       case SEEK_DATA:
-               if (offset >= i_size_read(inode)) {
-                       retval = -ENXIO;
-                       goto exit;
-               }
-               break;
-       case SEEK_HOLE:
-               if (offset >= i_size_read(inode)) {
-                       retval = -ENXIO;
-                       goto exit;
-               }
-               offset = i_size_read(inode);
-               break;
-       }
-       retval = -EINVAL;
-       if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
-               if (offset != file->f_pos) {
-                       file->f_pos = offset;
-                       file->f_version = 0;
-               }
-               retval = offset;
-       }
-exit:
+       mutex_lock(&inode->i_mutex);
+       retval = fuse_update_attributes(inode, NULL, file, NULL);
+       if (!retval)
+               retval = generic_file_llseek(file, offset, origin);
        mutex_unlock(&inode->i_mutex);
+
        return retval;
 }