]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: mark inode DONT_CACHE when per inode DAX hint changes
authorJeffle Xu <jefflexu@linux.alibaba.com>
Thu, 25 Nov 2021 07:05:29 +0000 (15:05 +0800)
committerMiklos Szeredi <mszeredi@redhat.com>
Tue, 14 Dec 2021 10:09:37 +0000 (11:09 +0100)
When the per inode DAX hint changes while the file is still *opened*, it
is quite complicated and maybe fragile to dynamically change the DAX
state.

Hence mark the inode and corresponding dentries as DONE_CACHE once the
per inode DAX hint changes, so that the inode instance will be evicted
and freed as soon as possible once the file is closed and the last
reference to the inode is put. And then when the file gets reopened next
time, the new instantiated inode will reflect the new DAX state.

In summary, when the per inode DAX hint changes for an *opened* file, the
DAX state of the file won't be updated until this file is closed and
reopened later.

Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Reviewed-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/dax.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index 663270dc6e2010d8732768c2e94410a2c00cab1a..182b24a14804cadc3773f8fd7a69911efdffd1d0 100644 (file)
@@ -1361,6 +1361,15 @@ void fuse_dax_inode_init(struct inode *inode, unsigned int flags)
        inode->i_data.a_ops = &fuse_dax_file_aops;
 }
 
+void fuse_dax_dontcache(struct inode *inode, unsigned int flags)
+{
+       struct fuse_conn *fc = get_fuse_conn(inode);
+
+       if (fuse_is_inode_dax_mode(fc->dax_mode) &&
+           ((bool) IS_DAX(inode) != (bool) (flags & FUSE_ATTR_DAX)))
+               d_mark_dontcache(inode);
+}
+
 bool fuse_dax_check_alignment(struct fuse_conn *fc, unsigned int map_alignment)
 {
        if (fc->dax && (map_alignment > FUSE_DAX_SHIFT)) {
index 6d63bd403a43be3e916994c68e2f2747d29566a0..e8e59fbdefebe1e5deaa977ff3100e7bff6358ed 100644 (file)
@@ -1296,6 +1296,7 @@ void fuse_dax_conn_free(struct fuse_conn *fc);
 bool fuse_dax_inode_alloc(struct super_block *sb, struct fuse_inode *fi);
 void fuse_dax_inode_init(struct inode *inode, unsigned int flags);
 void fuse_dax_inode_cleanup(struct inode *inode);
+void fuse_dax_dontcache(struct inode *inode, unsigned int flags);
 bool fuse_dax_check_alignment(struct fuse_conn *fc, unsigned int map_alignment);
 void fuse_dax_cancel_work(struct fuse_conn *fc);
 
index c256fd82af3c65f29ff7a30b9badb9e9e1a16efb..ee846ce371d8fcfc1471e81b9cef08935e14037d 100644 (file)
@@ -301,6 +301,9 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
                if (inval)
                        invalidate_inode_pages2(inode->i_mapping);
        }
+
+       if (IS_ENABLED(CONFIG_FUSE_DAX))
+               fuse_dax_dontcache(inode, attr->flags);
 }
 
 static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)