EXPORT_SYMBOL(update_atime);
 
 /**
- *     inode_update_time       -       update mtime and ctime time
- *     @inode: inode accessed
- *     @ctime_too: update ctime too
+ *     file_update_time        -       update mtime and ctime time
+ *     @file: file accessed
  *
- *     Update the mtime time on an inode and mark it for writeback.
- *     When ctime_too is specified update the ctime too.
+ *     Update the mtime and ctime members of an inode and mark the inode
+ *     for writeback.  Note that this function is meant exclusively for
+ *     usage in the file write path of filesystems, and filesystems may
+ *     choose to explicitly ignore update via this function with the
+ *     S_NOCTIME inode flag, e.g. for network filesystem where these
+ *     timestamps are handled by the server.
  */
 
-void inode_update_time(struct inode *inode, int ctime_too)
+void file_update_time(struct file *file)
 {
+       struct inode *inode = file->f_dentry->d_inode;
        struct timespec now;
        int sync_it = 0;
 
                sync_it = 1;
        inode->i_mtime = now;
 
-       if (ctime_too) {
-               if (!timespec_equal(&inode->i_ctime, &now))
-                       sync_it = 1;
-               inode->i_ctime = now;
-       }
+       if (!timespec_equal(&inode->i_ctime, &now))
+               sync_it = 1;
+       inode->i_ctime = now;
+
        if (sync_it)
                mark_inode_dirty_sync(inode);
 }
 
-EXPORT_SYMBOL(inode_update_time);
+EXPORT_SYMBOL(file_update_time);
 
 int inode_needs_sync(struct inode *inode)
 {
 
        }
        vfree(bouncebuffer);
 
-       inode_update_time(inode, 1);
+       file_update_time(file);
 
        *ppos = pos;
 
 
        err = remove_suid(file->f_dentry);
        if (err)
                goto out;
-       inode_update_time(inode, 1);
+       file_update_time(file);
        written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos,
                        count);
 out:
 
        up_write(&ni->runlist.lock);
 done:
        /* Update the mtime and ctime on the base inode. */
-       inode_update_time(VFS_I(base_ni), 1);
+       /* normally ->truncate shouldn't update ctime or mtime,
+        * but ntfs did before so it got a copy & paste version
+        * of file_update_time.  one day someone should fix this
+        * for real.
+        */
+       if (!IS_NOCMTIME(VFS_I(base_ni)) && !IS_RDONLY(VFS_I(base_ni))) {
+               struct timespec now = current_fs_time(VFS_I(base_ni)->i_sb);
+               int sync_it = 0;
+
+               if (!timespec_equal(&VFS_I(base_ni)->i_mtime, &now) ||
+                   !timespec_equal(&VFS_I(base_ni)->i_ctime, &now))
+                       sync_it = 1;
+               VFS_I(base_ni)->i_mtime = now;
+               VFS_I(base_ni)->i_ctime = now;
+
+               if (sync_it)
+                       mark_inode_dirty_sync(VFS_I(base_ni));
+       }
+
        if (likely(!err)) {
                NInoClearTruncateFailed(ni);
                ntfs_debug("Done.");
 
        .nopage = ocfs2_nopage,
 };
 
-int ocfs2_mmap(struct file *file,
-              struct vm_area_struct *vma)
+int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-       struct inode *inode = mapping->host;
-
        /* We don't want to support shared writable mappings yet. */
        if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE))
            && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
                return -EINVAL;
        }
 
-       update_atime(inode);
+       file_accessed(file);
        vma->vm_ops = &ocfs2_file_vm_ops;
        return 0;
 }
 
                kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
        }
        if (ret > 0)
-               inode_update_time(inode, 1);    /* mtime and ctime */
+               file_update_time(filp);
        return ret;
 }
 
 
        if (res)
                goto out;
 
-       inode_update_time(inode, 1);    /* Both mtime and ctime */
+       file_update_time(file);
 
        // Ok, we are done with all the checks.
 
 
        }
 
        if (likely(!(ioflags & IO_INVIS))) {
-               inode_update_time(inode, 1);
+               file_update_time(file);
                xfs_ichgtime_fast(xip, inode,
                                  XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
        }
 
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern int __must_check inode_setattr(struct inode *, struct iattr *);
 
-extern void inode_update_time(struct inode *inode, int ctime_too);
+extern void file_update_time(struct file *file);
 
 static inline ino_t parent_ino(struct dentry *dentry)
 {
 
        if (err)
                goto out;
 
-       inode_update_time(inode, 1);
+       file_update_time(file);
 
        /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
        if (unlikely(file->f_flags & O_DIRECT)) {
 
        if (ret)
                goto out_backing;
 
-       inode_update_time(inode, 1);
+       file_update_time(filp);
 
        ret = __xip_file_write (filp, buf, count, pos, ppos);