mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-04-13 09:59:31 +00:00
fs: use must_set_pos()
Make generic_file_llseek_size() use must_set_pos(). We'll use must_set_pos() in another helper in a minutes. Remove __maybe_unused from must_set_pos() now that it's used. Link: https://lore.kernel.org/r/20240830-vfs-file-f_version-v1-7-6d3e4816aa7b@kernel.org Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
b8c7451928
commit
ed904935c3
1 changed files with 14 additions and 38 deletions
|
@ -98,8 +98,7 @@ EXPORT_SYMBOL(vfs_setpos);
|
|||
* Return: 0 if f_pos doesn't need to be updated, 1 if f_pos has to be
|
||||
* updated, and negative error code on failure.
|
||||
*/
|
||||
static __maybe_unused int must_set_pos(struct file *file, loff_t *offset,
|
||||
int whence, loff_t eof)
|
||||
static int must_set_pos(struct file *file, loff_t *offset, int whence, loff_t eof)
|
||||
{
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
|
@ -159,45 +158,22 @@ loff_t
|
|||
generic_file_llseek_size(struct file *file, loff_t offset, int whence,
|
||||
loff_t maxsize, loff_t eof)
|
||||
{
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
offset += eof;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
/*
|
||||
* Here we special-case the lseek(fd, 0, SEEK_CUR)
|
||||
* position-querying operation. Avoid rewriting the "same"
|
||||
* f_pos value back to the file because a concurrent read(),
|
||||
* write() or lseek() might have altered it
|
||||
*/
|
||||
if (offset == 0)
|
||||
return file->f_pos;
|
||||
/*
|
||||
* f_lock protects against read/modify/write race with other
|
||||
* SEEK_CURs. Note that parallel writes and reads behave
|
||||
* like SEEK_SET.
|
||||
*/
|
||||
spin_lock(&file->f_lock);
|
||||
offset = vfs_setpos(file, file->f_pos + offset, maxsize);
|
||||
spin_unlock(&file->f_lock);
|
||||
int ret;
|
||||
|
||||
ret = must_set_pos(file, &offset, whence, eof);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
return offset;
|
||||
case SEEK_DATA:
|
||||
|
||||
if (whence == SEEK_CUR) {
|
||||
/*
|
||||
* In the generic case the entire file is data, so as long as
|
||||
* offset isn't at the end of the file then the offset is data.
|
||||
* f_lock protects against read/modify/write race with
|
||||
* other SEEK_CURs. Note that parallel writes and reads
|
||||
* behave like SEEK_SET.
|
||||
*/
|
||||
if ((unsigned long long)offset >= eof)
|
||||
return -ENXIO;
|
||||
break;
|
||||
case SEEK_HOLE:
|
||||
/*
|
||||
* There is a virtual hole at the end of the file, so as long as
|
||||
* offset isn't i_size or larger, return i_size.
|
||||
*/
|
||||
if ((unsigned long long)offset >= eof)
|
||||
return -ENXIO;
|
||||
offset = eof;
|
||||
break;
|
||||
guard(spinlock)(&file->f_lock);
|
||||
return vfs_setpos(file, file->f_pos + offset, maxsize);
|
||||
}
|
||||
|
||||
return vfs_setpos(file, offset, maxsize);
|
||||
|
|
Loading…
Add table
Reference in a new issue