Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c07c3d19 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

fuse: llseek optimize SEEK_CUR and SEEK_SET



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: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent 73104b6e
Loading
Loading
Loading
Loading
+8 −40
Original line number Diff line number Diff line
@@ -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;

	/* 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);

	mutex_lock(&inode->i_mutex);
	if (origin != SEEK_CUR && origin != SEEK_SET) {
	retval = fuse_update_attributes(inode, NULL, file, NULL);
		if (retval)
			goto exit;
	}

	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:
	if (!retval)
		retval = generic_file_llseek(file, offset, origin);
	mutex_unlock(&inode->i_mutex);

	return retval;
}