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

Commit 46a1c2c7 authored by Jie Liu's avatar Jie Liu Committed by Al Viro
Browse files

vfs: export lseek_execute() to modules



For those file systems(btrfs/ext4/ocfs2/tmpfs) that support
SEEK_DATA/SEEK_HOLE functions, we end up handling the similar
matter in lseek_execute() to update the current file offset
to the desired offset if it is valid, ceph also does the
simliar things at ceph_llseek().

To reduce the duplications, this patch make lseek_execute()
public accessible so that we can call it directly from the
underlying file systems.

Thanks Dave Chinner for this suggestion.

[AV: call it vfs_setpos(), don't bring the removed 'inode' argument back]

v2->v1:
- Add kernel-doc comments for lseek_execute()
- Call lseek_execute() in ceph->llseek()

Signed-off-by: default avatarJie Liu <jeff.liu@oracle.com>
Cc: Dave Chinner <dchinner@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Chris Mason <chris.mason@fusionio.com>
Cc: Josef Bacik <jbacik@fusionio.com>
Cc: Ben Myers <bpm@sgi.com>
Cc: Ted Tso <tytso@mit.edu>
Cc: Hugh Dickins <hughd@google.com>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Sage Weil <sage@inktank.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2142914e
Loading
Loading
Loading
Loading
+1 −14
Original line number Original line Diff line number Diff line
@@ -2425,20 +2425,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)
		}
		}
	}
	}


	if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
	offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
		offset = -EINVAL;
		goto out;
	}
	if (offset > inode->i_sb->s_maxbytes) {
		offset = -EINVAL;
		goto out;
	}

	/* Special lock needed here? */
	if (offset != file->f_pos) {
		file->f_pos = offset;
		file->f_version = 0;
	}
out:
out:
	mutex_unlock(&inode->i_mutex);
	mutex_unlock(&inode->i_mutex);
	return offset;
	return offset;
+1 −10
Original line number Original line Diff line number Diff line
@@ -866,16 +866,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
		break;
		break;
	}
	}


	if (offset < 0 || offset > inode->i_sb->s_maxbytes) {
	offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
		offset = -EINVAL;
		goto out;
	}

	/* Special lock needed here? */
	if (offset != file->f_pos) {
		file->f_pos = offset;
		file->f_version = 0;
	}


out:
out:
	mutex_unlock(&inode->i_mutex);
	mutex_unlock(&inode->i_mutex);
+2 −22
Original line number Original line Diff line number Diff line
@@ -494,17 +494,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
	if (dataoff > isize)
	if (dataoff > isize)
		return -ENXIO;
		return -ENXIO;


	if (dataoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
	return vfs_setpos(file, dataoff, maxsize);
		return -EINVAL;
	if (dataoff > maxsize)
		return -EINVAL;

	if (dataoff != file->f_pos) {
		file->f_pos = dataoff;
		file->f_version = 0;
	}

	return dataoff;
}
}


/*
/*
@@ -580,17 +570,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
	if (holeoff > isize)
	if (holeoff > isize)
		holeoff = isize;
		holeoff = isize;


	if (holeoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
	return vfs_setpos(file, holeoff, maxsize);
		return -EINVAL;
	if (holeoff > maxsize)
		return -EINVAL;

	if (holeoff != file->f_pos) {
		file->f_pos = holeoff;
		file->f_version = 0;
	}

	return holeoff;
}
}


/*
/*
+1 −11
Original line number Original line Diff line number Diff line
@@ -2646,17 +2646,7 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence)
		goto out;
		goto out;
	}
	}


	if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
	offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
		ret = -EINVAL;
	if (!ret && offset > inode->i_sb->s_maxbytes)
		ret = -EINVAL;
	if (ret)
		goto out;

	if (offset != file->f_pos) {
		file->f_pos = offset;
		file->f_version = 0;
	}


out:
out:
	mutex_unlock(&inode->i_mutex);
	mutex_unlock(&inode->i_mutex);
+16 −3
Original line number Original line Diff line number Diff line
@@ -41,7 +41,19 @@ static inline int unsigned_offsets(struct file *file)
	return file->f_mode & FMODE_UNSIGNED_OFFSET;
	return file->f_mode & FMODE_UNSIGNED_OFFSET;
}
}


static loff_t lseek_execute(struct file *file, loff_t offset, loff_t maxsize)
/**
 * vfs_setpos - update the file offset for lseek
 * @file:	file structure in question
 * @offset:	file offset to seek to
 * @maxsize:	maximum file size
 *
 * This is a low-level filesystem helper for updating the file offset to
 * the value specified by @offset if the given offset is valid and it is
 * not equal to the current file offset.
 *
 * Return the specified offset on success and -EINVAL on invalid offset.
 */
loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize)
{
{
	if (offset < 0 && !unsigned_offsets(file))
	if (offset < 0 && !unsigned_offsets(file))
		return -EINVAL;
		return -EINVAL;
@@ -54,6 +66,7 @@ static loff_t lseek_execute(struct file *file, loff_t offset, loff_t maxsize)
	}
	}
	return offset;
	return offset;
}
}
EXPORT_SYMBOL(vfs_setpos);


/**
/**
 * generic_file_llseek_size - generic llseek implementation for regular files
 * generic_file_llseek_size - generic llseek implementation for regular files
@@ -94,7 +107,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence,
		 * like SEEK_SET.
		 * like SEEK_SET.
		 */
		 */
		spin_lock(&file->f_lock);
		spin_lock(&file->f_lock);
		offset = lseek_execute(file, file->f_pos + offset, maxsize);
		offset = vfs_setpos(file, file->f_pos + offset, maxsize);
		spin_unlock(&file->f_lock);
		spin_unlock(&file->f_lock);
		return offset;
		return offset;
	case SEEK_DATA:
	case SEEK_DATA:
@@ -116,7 +129,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence,
		break;
		break;
	}
	}


	return lseek_execute(file, offset, maxsize);
	return vfs_setpos(file, offset, maxsize);
}
}
EXPORT_SYMBOL(generic_file_llseek_size);
EXPORT_SYMBOL(generic_file_llseek_size);


Loading