diff options
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index cfce3ad86a92..a8b31da19b93 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -99,6 +99,13 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
99 | return inode; | 99 | return inode; |
100 | } | 100 | } |
101 | 101 | ||
102 | static void fuse_i_callback(struct rcu_head *head) | ||
103 | { | ||
104 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
105 | INIT_LIST_HEAD(&inode->i_dentry); | ||
106 | kmem_cache_free(fuse_inode_cachep, inode); | ||
107 | } | ||
108 | |||
102 | static void fuse_destroy_inode(struct inode *inode) | 109 | static void fuse_destroy_inode(struct inode *inode) |
103 | { | 110 | { |
104 | struct fuse_inode *fi = get_fuse_inode(inode); | 111 | struct fuse_inode *fi = get_fuse_inode(inode); |
@@ -106,7 +113,7 @@ static void fuse_destroy_inode(struct inode *inode) | |||
106 | BUG_ON(!list_empty(&fi->queued_writes)); | 113 | BUG_ON(!list_empty(&fi->queued_writes)); |
107 | if (fi->forget_req) | 114 | if (fi->forget_req) |
108 | fuse_request_free(fi->forget_req); | 115 | fuse_request_free(fi->forget_req); |
109 | kmem_cache_free(fuse_inode_cachep, inode); | 116 | call_rcu(&inode->i_rcu, fuse_i_callback); |
110 | } | 117 | } |
111 | 118 | ||
112 | void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | 119 | void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, |
@@ -619,7 +626,7 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, | |||
619 | 626 | ||
620 | entry = d_obtain_alias(inode); | 627 | entry = d_obtain_alias(inode); |
621 | if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) { | 628 | if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) { |
622 | entry->d_op = &fuse_dentry_operations; | 629 | d_set_d_op(entry, &fuse_dentry_operations); |
623 | fuse_invalidate_entry_cache(entry); | 630 | fuse_invalidate_entry_cache(entry); |
624 | } | 631 | } |
625 | 632 | ||
@@ -721,7 +728,7 @@ static struct dentry *fuse_get_parent(struct dentry *child) | |||
721 | 728 | ||
722 | parent = d_obtain_alias(inode); | 729 | parent = d_obtain_alias(inode); |
723 | if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) { | 730 | if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) { |
724 | parent->d_op = &fuse_dentry_operations; | 731 | d_set_d_op(parent, &fuse_dentry_operations); |
725 | fuse_invalidate_entry_cache(parent); | 732 | fuse_invalidate_entry_cache(parent); |
726 | } | 733 | } |
727 | 734 | ||