[Devel,RHEL7,COMMIT] ms/tmpfs: fix SEEK_DATA/SEEK_HOLE regression

Submitted by Konstantin Khorenko on Nov. 9, 2016, 1:54 p.m.

Details

Message ID 201611091354.uA9DskY1002300@finist_cl7.x64_64.work.ct
State New
Series "ms/tmpfs: fix SEEK_DATA/SEEK_HOLE regression"
Headers show

Commit Message

Konstantin Khorenko Nov. 9, 2016, 1:54 p.m.
The commit is pushed to "branch-rh7-3.10.0-327.36.1.vz7.19.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.36.1.vz7.19.6
------>
commit 57c05b17081e03cdad7b8199273b80d34fc55c1d
Author: Hugh Dickins <hughd@google.com>
Date:   Wed Nov 9 17:54:46 2016 +0400

    ms/tmpfs: fix SEEK_DATA/SEEK_HOLE regression
    
    Fixes a problem in shmem criu test and friends on VZ7 after criu
    commit 51554fa59eed ("shmem: use lseek(SEEK_DATA) instead of mincore"):
    
    https://ci.openvz.org/job/CRIU/job/CRIU-virtuozzo/branch/criu-dev/861/
    ============ Run zdtm/transition/shmem in h ===============
    Start test
    ./shmem --pidfile=shmem.pid --outfile=shmem.out
    Run criu dump
    =[log]=> dump/zdtm/transition/shmem/24/1/dump.log
      Commit 46a1c2c7ae53 ("vfs: export lseek_execute() to modules") broke the
      tmpfs SEEK_DATA/SEEK_HOLE implementation, because vfs_setpos() converts
      the carefully prepared -ENXIO to -EINVAL.  Other filesystems avoid it in
      error cases: do the same in tmpfs.
    
      Signed-off-by: Hugh Dickins <hughd@google.com>
      Cc: Jie Liu <jeff.liu@oracle.com>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    
    https://jira.sw.ru/browse/PSBM-54804
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
    Acked-by: Andrew Vagin <avagin@virtuozzo.com>
---
 mm/shmem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/mm/shmem.c b/mm/shmem.c
index 827347d..00d7273 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1897,7 +1897,8 @@  static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
 		}
 	}
 
-	offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE);
+	if (offset >= 0)
+		offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE);
 	mutex_unlock(&inode->i_mutex);
 	return offset;
 }