|
@@ -81,13 +81,18 @@ u64 entry_attr_timeout(struct fuse_entry_out *o)
|
|
|
return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
|
|
|
}
|
|
|
|
|
|
+static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
|
|
|
+{
|
|
|
+ set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Mark the attributes as stale, so that at the next call to
|
|
|
* ->getattr() they will be fetched from userspace
|
|
|
*/
|
|
|
void fuse_invalidate_attr(struct inode *inode)
|
|
|
{
|
|
|
- get_fuse_inode(inode)->i_time = 0;
|
|
|
+ fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
|
|
|
}
|
|
|
|
|
|
static void fuse_dir_changed(struct inode *dir)
|
|
@@ -103,7 +108,7 @@ static void fuse_dir_changed(struct inode *dir)
|
|
|
void fuse_invalidate_atime(struct inode *inode)
|
|
|
{
|
|
|
if (!IS_RDONLY(inode))
|
|
|
- fuse_invalidate_attr(inode);
|
|
|
+ fuse_invalidate_attr_mask(inode, STATX_ATIME);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -917,7 +922,8 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
|
|
|
}
|
|
|
|
|
|
static int fuse_update_get_attr(struct inode *inode, struct file *file,
|
|
|
- struct kstat *stat, unsigned int flags)
|
|
|
+ struct kstat *stat, u32 request_mask,
|
|
|
+ unsigned int flags)
|
|
|
{
|
|
|
struct fuse_inode *fi = get_fuse_inode(inode);
|
|
|
int err = 0;
|
|
@@ -927,6 +933,8 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
|
|
|
sync = true;
|
|
|
else if (flags & AT_STATX_DONT_SYNC)
|
|
|
sync = false;
|
|
|
+ else if (request_mask & READ_ONCE(fi->inval_mask))
|
|
|
+ sync = true;
|
|
|
else
|
|
|
sync = time_before64(fi->i_time, get_jiffies_64());
|
|
|
|
|
@@ -944,7 +952,7 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
|
|
|
|
|
|
int fuse_update_attributes(struct inode *inode, struct file *file)
|
|
|
{
|
|
|
- return fuse_update_get_attr(inode, file, NULL, 0);
|
|
|
+ return fuse_update_get_attr(inode, file, NULL, STATX_BASIC_STATS, 0);
|
|
|
}
|
|
|
|
|
|
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
|
|
@@ -1566,7 +1574,7 @@ static int fuse_getattr(const struct path *path, struct kstat *stat,
|
|
|
if (!fuse_allow_current_process(fc))
|
|
|
return -EACCES;
|
|
|
|
|
|
- return fuse_update_get_attr(inode, NULL, stat, flags);
|
|
|
+ return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
|
|
|
}
|
|
|
|
|
|
static const struct inode_operations fuse_dir_inode_operations = {
|