diff --git regops.c regops.c
index ecf5af8..fdc1d13 100644
--- regops.c
+++ regops.c
@@ -91,6 +91,58 @@ static int sf_reg_write_aux(const char *caller, struct sf_glob_info *sf_g,
     return 0;
 }
 
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+
+#include <linux/nfs_fs.h>
+static ssize_t
+sf_file_read(struct kiocb *iocb, struct iov_iter *iov)
+{
+   int err;
+   struct dentry *dentry;
+
+   dentry = iocb->ki_filp->f_path.dentry;
+   err = sf_inode_revalidate(dentry);
+   if (err)
+       return err;
+   return generic_file_read_iter(iocb, iov);
+}
+
+static int sf_need_sync_write(struct file *file, struct inode *inode)
+{
+    // >= kernel version 2.6.33
+    if (IS_SYNC(inode) || file->f_flags & O_DSYNC) {
+       return 1;
+    }
+    return 0;
+}
+
+static ssize_t
+sf_file_write(struct kiocb *iocb, struct iov_iter *iov)
+{
+   int err;
+   ssize_t result;
+   struct file *file = iocb->ki_filp;
+   struct dentry *dentry = file->f_path.dentry;
+   struct inode *inode = dentry->d_inode;
+
+   err = sf_inode_revalidate(dentry);
+   if (err)
+       return err;
+
+   result = generic_file_write_iter(iocb, iov);
+
+   if (result >= 0 && sf_need_sync_write(file, inode)) {
+      err = vfs_fsync(file, 0);
+      if (err < 0) {
+         result = err;
+      }
+   }
+   return result;
+}
+
+#else /* KERNEL_VERSION >= 3.16.0 */
+
 /**
  * Read from a regular file.
  *
@@ -265,6 +317,35 @@ fail:
     free_bounce_buffer(tmp);
     return err;
 }
+#endif /* KERNEL_VERSION >= 3.16.0 */
+
+static loff_t
+sf_file_llseek(struct file *file, loff_t offset, int origin)
+{
+   int err;
+   struct dentry *dentry;
+
+   dentry = file->f_path.dentry;
+   err = sf_inode_revalidate(dentry);
+   if (err)
+       return err;
+   return generic_file_llseek(file, offset, origin);
+}
+
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
+static ssize_t
+sf_file_splice_read(struct file *file, loff_t *offset, struct pipe_inode_info *pipe, size_t len, unsigned int flags)
+{
+   int err;
+   struct dentry *dentry;
+
+   dentry = file->f_path.dentry;
+   err = sf_inode_revalidate(dentry);
+   if (err)
+       return err;
+   return generic_file_splice_read(file, offset, pipe, len, flags);
+}
+# endif
 
 /**
  * Open a regular file.
@@ -563,30 +644,32 @@ static int sf_reg_mmap(struct file *file, struct vm_area_struct *vma)
 
 struct file_operations sf_reg_fops =
 {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    .read        = new_sync_read,
+    .write       = new_sync_write,
+    .read_iter   = sf_file_read,
+    .write_iter  = sf_file_write,
+#else
     .read        = sf_reg_read,
-    .open        = sf_reg_open,
     .write       = sf_reg_write,
+    .aio_read    = generic_file_aio_read,
+    .aio_write   = generic_file_aio_write,
+#endif
+    .open        = sf_reg_open,
     .release     = sf_reg_release,
     .mmap        = sf_reg_mmap,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-    .splice_read = generic_file_splice_read,
+    .splice_read = sf_file_splice_read,
 # else
     .sendfile    = generic_file_sendfile,
 # endif
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
-    .read_iter   = generic_file_read_iter,
-    .write_iter  = generic_file_write_iter,
-# else
-    .aio_read    = generic_file_aio_read,
-    .aio_write   = generic_file_aio_write,
-# endif
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
     .fsync       = noop_fsync,
 # else
     .fsync       = simple_sync_file,
 # endif
-    .llseek      = generic_file_llseek,
+    .llseek      = sf_file_llseek,
 #endif
 };
 
diff --git utils.c utils.c
index 674af7a..70511e0 100644
--- utils.c
+++ utils.c
@@ -217,6 +217,7 @@ int sf_inode_revalidate(struct dentry *dentry)
     struct sf_glob_info *sf_g;
     struct sf_inode_info *sf_i;
     SHFLFSOBJINFO info;
+    time_t old_time;
 
     TRACE();
     if (!dentry || !dentry->d_inode)
@@ -240,7 +241,7 @@ int sf_inode_revalidate(struct dentry *dentry)
 
     if (!sf_i->force_restat)
     {
-        if (jiffies - dentry->d_time < sf_g->ttl)
+        if (jiffies - dentry->d_time <= sf_g->ttl)
             return 0;
     }
 
@@ -249,7 +250,17 @@ int sf_inode_revalidate(struct dentry *dentry)
         return err;
 
     dentry->d_time = jiffies;
+
+    old_time = dentry->d_inode->i_mtime.tv_sec;
+    sf_ftime_from_timespec(&dentry->d_inode->i_mtime, &info.ModificationTime);
+
+    if ( info.cbObject != dentry->d_inode->i_size ||
+              old_time != dentry->d_inode->i_mtime.tv_sec){
+        invalidate_inode_pages2(dentry->d_inode->i_mapping);
+    }
+
     sf_init_inode(sf_g, dentry->d_inode, &info);
+    sf_i->force_restat = 0;
     return 0;
 }
 
