]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fs: use must_set_pos()
authorChristian Brauner <brauner@kernel.org>
Fri, 30 Aug 2024 13:04:48 +0000 (15:04 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 9 Sep 2024 09:58:07 +0000 (11:58 +0200)
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>
fs/read_write.c

index 5434467f5c052470696aaac73a9cbfe4c95af5df..b07e48cd81d1ce7ff7503578d6f31e61a3094bf4 100644 (file)
@@ -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:
-               /*
-                * 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.
-                */
-               if ((unsigned long long)offset >= eof)
-                       return -ENXIO;
-               break;
-       case SEEK_HOLE:
+
+       if (whence == SEEK_CUR) {
                /*
-                * 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.
+                * 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;
-               offset = eof;
-               break;
+               guard(spinlock)(&file->f_lock);
+               return vfs_setpos(file, file->f_pos + offset, maxsize);
        }
 
        return vfs_setpos(file, offset, maxsize);