@@ -182,7 +182,10 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
inode->i_atime.tv_sec = attr->atime;
inode->i_atime.tv_nsec = attr->atimensec;
/* mtime from server may be stale due to local buffered write */
- if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
+ if (!fc->writeback_cache || !S_ISREG(inode->i_mode)
+ || (attr->mtime >= inode->i_mtime.tv_sec)
+ || ((attr->mtime == inode->i_mtime.tv_sec)
+ && (attr->mtimensec >= inode->i_mtime.tv_nsec))) {
inode->i_mtime.tv_sec = attr->mtime;
inode->i_mtime.tv_nsec = attr->mtimensec;
inode->i_ctime.tv_sec = attr->ctime;
@@ -241,8 +244,12 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
* extend local i_size without keeping userspace server in sync. So,
* attr->size coming from server can be stale. We cannot trust it.
*/
- if (!is_wb || !S_ISREG(inode->i_mode))
+ if (!is_wb || !S_ISREG(inode->i_mode)
+ || (attr->mtime >= inode->i_mtime.tv_sec)
+ || ((attr->mtime == inode->i_mtime.tv_sec)
+ && (attr->mtimensec >= inode->i_mtime.tv_nsec))) {
i_size_write(inode, attr->size);
+ }
spin_unlock(&fi->lock);
if (!is_wb && S_ISREG(inode->i_mode)) {