Wrapfs: fix ->llseek to update upper and lower offsets
authorErez Zadok <ezk@cs.sunysb.edu>
Thu, 26 Jun 2014 02:37:16 +0000 (22:37 -0400)
committerErez Zadok <ezk@cs.sunysb.edu>
Sun, 3 Apr 2016 19:23:34 +0000 (15:23 -0400)
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 <ezk@cs.sunysb.edu>
Signed-off-by: Mengyang Li <li.mengyang@stonybrook.edu>
fs/wrapfs/file.c

index fac2d4c05a06025665288444a8206128e61d38bd..4c89f6087dfbe716d9c226db0473477a5c83f4a9 100644 (file)
@@ -307,6 +307,28 @@ out:
        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,