xfs
[Top] [All Lists]

[PATCH RESEND] vfs: Return EINVAL for default SEEK_HOLE, SEEK_DATA imple

To: linux-fsdevel@xxxxxxxxxxxxxxx
Subject: [PATCH RESEND] vfs: Return EINVAL for default SEEK_HOLE, SEEK_DATA implementation
From: Jan Kara <jack@xxxxxxx>
Date: Fri, 10 Oct 2014 16:23:40 +0200
Cc: linux-ext4@xxxxxxxxxxxxxxx, Dave Chinner <david@xxxxxxxxxxxxx>, xfs@xxxxxxxxxxx, cluster-devel@xxxxxxxxxx, Steven Whitehouse <swhiteho@xxxxxxxxxx>, Mark Fasheh <mfasheh@xxxxxxxx>, Joel Becker <jlbec@xxxxxxxxxxxx>, ocfs2-devel@xxxxxxxxxxxxxx, reiserfs-devel@xxxxxxxxxxxxxxx, Jeff Mahoney <jeffm@xxxxxxx>, Dave Kleikamp <shaggy@xxxxxxxxxx>, jfs-discussion@xxxxxxxxxxxxxxxxxxxxx, tytso@xxxxxxx, viro@xxxxxxxxxxxxxxxxxx, Jan Kara <jack@xxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1412951028-4085-1-git-send-email-jack@xxxxxxx>
References: <1412951028-4085-1-git-send-email-jack@xxxxxxx>
Generic implementation of SEEK_HOLE & SEEK_DATA in
generic_file_llseek_size() and default_llseek() behaved as if everything
within i_size is data and everything beyond i_size is a hole. That makes
sense at the first sight (and definitely is a valid implementation of
the spec) but at the second sight it isn't very useful. If anyone
bothers with looking for holes / data, he should be better told we don't
really know so that he can fall back to his chosen backup strategy
(think of e.g. cp(1)).

This is a userspace API change however the kernel interface is there
only for two years so hopefully userspace is still prepared to handle
EINVAL return value.

Signed-off-by: Jan Kara <jack@xxxxxxx>
---
 fs/read_write.c | 38 ++------------------------------------
 1 file changed, 2 insertions(+), 36 deletions(-)

Al, what do you think about this change?

diff --git a/fs/read_write.c b/fs/read_write.c
index edc5746a902a..71525d75742f 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -111,22 +111,8 @@ generic_file_llseek_size(struct file *file, loff_t offset, 
int whence,
                spin_unlock(&file->f_lock);
                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 (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 (offset >= eof)
-                       return -ENXIO;
-               offset = eof;
-               break;
+               return -EINVAL;
        }
 
        return vfs_setpos(file, offset, maxsize);
@@ -214,28 +200,8 @@ loff_t default_llseek(struct file *file, loff_t offset, 
int whence)
                        offset += file->f_pos;
                        break;
                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 (offset >= inode->i_size) {
-                               retval = -ENXIO;
-                               goto out;
-                       }
-                       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 (offset >= inode->i_size) {
-                               retval = -ENXIO;
-                               goto out;
-                       }
-                       offset = inode->i_size;
-                       break;
+                       return -EINVAL;
        }
        retval = -EINVAL;
        if (offset >= 0 || unsigned_offsets(file)) {
-- 
1.8.1.4

<Prev in Thread] Current Thread [Next in Thread>