return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
 }
 
-static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
+void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
 {
        set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
 }
 
 void fuse_update_ctime(struct inode *inode)
 {
-       fuse_invalidate_attr(inode);
+       fuse_invalidate_attr_mask(inode, STATX_CTIME);
        fuse_update_ctime_in_cache(inode);
 }
 
 
                i_size_write(inode, 0);
                spin_unlock(&fi->lock);
                truncate_pagecache(inode, 0);
-               fuse_invalidate_attr(inode);
+               fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
                if (fc->writeback_cache)
                        file_update_time(file);
        } else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) {
         * enabled, i_blocks from cached attr may not be accurate.
         */
        if (!err && fm->fc->writeback_cache)
-               fuse_invalidate_attr(inode);
+               fuse_invalidate_attr_mask(inode, STATX_BLOCKS);
        return err;
 }
 
                fuse_write_update_size(inode, pos);
 
        clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
-       fuse_invalidate_attr(inode);
+       fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
 
        return res > 0 ? res : err;
 }
                                             FUSE_DIO_WRITE);
                }
        }
-       fuse_invalidate_attr(inode);
+       fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
        if (res > 0)
                fuse_write_update_size(inode, iocb->ki_pos);
        inode_unlock(inode);
         * is enabled, we trust local ctime/mtime.
         */
        if (!fc->writeback_cache)
-               fuse_invalidate_attr(inode);
+               fuse_invalidate_attr_mask(inode, FUSE_STATX_MODIFY);
        spin_lock(&fi->lock);
        rb_erase(&wpa->writepages_entry, &fi->writepages);
        while (wpa->next) {
 
        if (iov_iter_rw(iter) == WRITE) {
                ret = fuse_direct_io(io, iter, &pos, FUSE_DIO_WRITE);
-               fuse_invalidate_attr(inode);
+               fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
        } else {
                ret = __fuse_direct_read(io, iter, &pos);
        }
        if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
                truncate_pagecache_range(inode, offset, offset + length - 1);
 
-       fuse_invalidate_attr(inode);
+       fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
 
 out:
        if (!(mode & FALLOC_FL_KEEP_SIZE))
                file_update_time(file_out);
        }
 
-       fuse_invalidate_attr(inode_out);
+       fuse_invalidate_attr_mask(inode_out, FUSE_STATX_MODSIZE);
 
        err = outarg.size;
 out:
 
 /**
  * Invalidate inode attributes
  */
+
+/* Attributes possibly changed on data modification */
+#define FUSE_STATX_MODIFY      (STATX_MTIME | STATX_CTIME | STATX_BLOCKS)
+
+/* Attributes possibly changed on data and/or size modification */
+#define FUSE_STATX_MODSIZE     (FUSE_STATX_MODIFY | STATX_SIZE)
+
 void fuse_invalidate_attr(struct inode *inode);
+void fuse_invalidate_attr_mask(struct inode *inode, u32 mask);
 
 void fuse_invalidate_entry_cache(struct dentry *entry);