From f777fd146f465c89b0bfda6ba865ee2b2bff2e93 Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Wed, 25 Jun 2014 22:37:16 -0400 Subject: [PATCH] Wrapfs: fix ->llseek to update upper and lower offsets Fixes bug: xfstests generic/257. f_pos consistently is required by and only by dir_ops->wrapfs_readdir, main_ops is not affected. Signed-off-by: Erez Zadok Signed-off-by: Mengyang Li --- fs/wrapfs/file.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/fs/wrapfs/file.c b/fs/wrapfs/file.c index fac2d4c05a06..4c89f6087dfb 100644 --- a/fs/wrapfs/file.c +++ b/fs/wrapfs/file.c @@ -307,6 +307,28 @@ static ssize_t wrapfs_aio_write(struct kiocb *iocb, const struct iovec *iov, return err; } +/* + * Wrapfs cannot use generic_file_llseek as ->llseek, because it would + * only set the offset of the upper file. So we have to implement our + * own method to set both the upper and lower file offsets + * consistently. + */ +static loff_t wrapfs_file_llseek(struct file *file, loff_t offset, int whence) +{ + int err; + struct file *lower_file; + + err = generic_file_llseek(file, offset, whence); + if (err < 0) + goto out; + + lower_file = wrapfs_lower_file(file); + err = generic_file_llseek(lower_file, offset, whence); + +out: + return err; +} + const struct file_operations wrapfs_main_fops = { .llseek = generic_file_llseek, .read = wrapfs_read, @@ -327,7 +349,7 @@ const struct file_operations wrapfs_main_fops = { /* trimmed directory options */ const struct file_operations wrapfs_dir_fops = { - .llseek = generic_file_llseek, + .llseek = wrapfs_file_llseek, .read = generic_read_dir, .iterate = wrapfs_readdir, .unlocked_ioctl = wrapfs_unlocked_ioctl, -- 2.43.0