summaryrefslogtreecommitdiff
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2020-08-20 01:19:51 +0300
committerMiklos Szeredi <mszeredi@redhat.com>2020-09-10 12:39:23 +0300
commitc2d0ad00d948de73c78f05d2b3e5bdfa605035cc (patch)
treedbc7decd77eb124264832633bb77b1b3396b8a27 /fs/fuse/inode.c
parentceec02d4354a317cacce4b053a580ea3c7fc6cdc (diff)
downloadlinux-c2d0ad00d948de73c78f05d2b3e5bdfa605035cc.tar.xz
virtiofs: implement dax read/write operations
This patch implements basic DAX support. mmap() is not implemented yet and will come in later patches. This patch looks into implemeting read/write. We make use of interval tree to keep track of per inode dax mappings. Do not use dax for file extending writes, instead just send WRITE message to daemon (like we do for direct I/O path). This will keep write and i_size change atomic w.r.t crash. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com> Signed-off-by: Peng Tao <tao.peng@linux.alibaba.com> Cc: Dave Chinner <david@fromorbit.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 67e99cee5a4f..cab4239bd78a 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -87,12 +87,19 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
mutex_init(&fi->mutex);
spin_lock_init(&fi->lock);
fi->forget = fuse_alloc_forget();
- if (!fi->forget) {
- kmem_cache_free(fuse_inode_cachep, fi);
- return NULL;
- }
+ if (!fi->forget)
+ goto out_free;
+
+ if (IS_ENABLED(CONFIG_FUSE_DAX) && !fuse_dax_inode_alloc(sb, fi))
+ goto out_free_forget;
return &fi->inode;
+
+out_free_forget:
+ kfree(fi->forget);
+out_free:
+ kmem_cache_free(fuse_inode_cachep, fi);
+ return NULL;
}
static void fuse_free_inode(struct inode *inode)
@@ -101,6 +108,9 @@ static void fuse_free_inode(struct inode *inode)
mutex_destroy(&fi->mutex);
kfree(fi->forget);
+#ifdef CONFIG_FUSE_DAX
+ kfree(fi->dax);
+#endif
kmem_cache_free(fuse_inode_cachep, fi);
}
@@ -112,6 +122,9 @@ static void fuse_evict_inode(struct inode *inode)
clear_inode(inode);
if (inode->i_sb->s_flags & SB_ACTIVE) {
struct fuse_conn *fc = get_fuse_conn(inode);
+
+ if (FUSE_IS_DAX(inode))
+ fuse_dax_inode_cleanup(inode);
fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
fi->forget = NULL;
}