aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index cfce3ad86a9..f62b32cffea 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -71,6 +71,11 @@ struct fuse_mount_data {
71 unsigned blksize; 71 unsigned blksize;
72}; 72};
73 73
74struct fuse_forget_link *fuse_alloc_forget()
75{
76 return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL);
77}
78
74static struct inode *fuse_alloc_inode(struct super_block *sb) 79static struct inode *fuse_alloc_inode(struct super_block *sb)
75{ 80{
76 struct inode *inode; 81 struct inode *inode;
@@ -90,8 +95,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
90 INIT_LIST_HEAD(&fi->queued_writes); 95 INIT_LIST_HEAD(&fi->queued_writes);
91 INIT_LIST_HEAD(&fi->writepages); 96 INIT_LIST_HEAD(&fi->writepages);
92 init_waitqueue_head(&fi->page_waitq); 97 init_waitqueue_head(&fi->page_waitq);
93 fi->forget_req = fuse_request_alloc(); 98 fi->forget = fuse_alloc_forget();
94 if (!fi->forget_req) { 99 if (!fi->forget) {
95 kmem_cache_free(fuse_inode_cachep, inode); 100 kmem_cache_free(fuse_inode_cachep, inode);
96 return NULL; 101 return NULL;
97 } 102 }
@@ -99,27 +104,20 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
99 return inode; 104 return inode;
100} 105}
101 106
102static void fuse_destroy_inode(struct inode *inode) 107static void fuse_i_callback(struct rcu_head *head)
103{ 108{
104 struct fuse_inode *fi = get_fuse_inode(inode); 109 struct inode *inode = container_of(head, struct inode, i_rcu);
105 BUG_ON(!list_empty(&fi->write_files)); 110 INIT_LIST_HEAD(&inode->i_dentry);
106 BUG_ON(!list_empty(&fi->queued_writes));
107 if (fi->forget_req)
108 fuse_request_free(fi->forget_req);
109 kmem_cache_free(fuse_inode_cachep, inode); 111 kmem_cache_free(fuse_inode_cachep, inode);
110} 112}
111 113
112void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, 114static void fuse_destroy_inode(struct inode *inode)
113 u64 nodeid, u64 nlookup)
114{ 115{
115 struct fuse_forget_in *inarg = &req->misc.forget_in; 116 struct fuse_inode *fi = get_fuse_inode(inode);
116 inarg->nlookup = nlookup; 117 BUG_ON(!list_empty(&fi->write_files));
117 req->in.h.opcode = FUSE_FORGET; 118 BUG_ON(!list_empty(&fi->queued_writes));
118 req->in.h.nodeid = nodeid; 119 kfree(fi->forget);
119 req->in.numargs = 1; 120 call_rcu(&inode->i_rcu, fuse_i_callback);
120 req->in.args[0].size = sizeof(struct fuse_forget_in);
121 req->in.args[0].value = inarg;
122 fuse_request_send_noreply(fc, req);
123} 121}
124 122
125static void fuse_evict_inode(struct inode *inode) 123static void fuse_evict_inode(struct inode *inode)
@@ -129,8 +127,8 @@ static void fuse_evict_inode(struct inode *inode)
129 if (inode->i_sb->s_flags & MS_ACTIVE) { 127 if (inode->i_sb->s_flags & MS_ACTIVE) {
130 struct fuse_conn *fc = get_fuse_conn(inode); 128 struct fuse_conn *fc = get_fuse_conn(inode);
131 struct fuse_inode *fi = get_fuse_inode(inode); 129 struct fuse_inode *fi = get_fuse_inode(inode);
132 fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup); 130 fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
133 fi->forget_req = NULL; 131 fi->forget = NULL;
134 } 132 }
135} 133}
136 134
@@ -534,6 +532,7 @@ void fuse_conn_init(struct fuse_conn *fc)
534 INIT_LIST_HEAD(&fc->interrupts); 532 INIT_LIST_HEAD(&fc->interrupts);
535 INIT_LIST_HEAD(&fc->bg_queue); 533 INIT_LIST_HEAD(&fc->bg_queue);
536 INIT_LIST_HEAD(&fc->entry); 534 INIT_LIST_HEAD(&fc->entry);
535 fc->forget_list_tail = &fc->forget_list_head;
537 atomic_set(&fc->num_waiting, 0); 536 atomic_set(&fc->num_waiting, 0);
538 fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; 537 fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
539 fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; 538 fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
@@ -619,7 +618,7 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
619 618
620 entry = d_obtain_alias(inode); 619 entry = d_obtain_alias(inode);
621 if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) { 620 if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
622 entry->d_op = &fuse_dentry_operations; 621 d_set_d_op(entry, &fuse_dentry_operations);
623 fuse_invalidate_entry_cache(entry); 622 fuse_invalidate_entry_cache(entry);
624 } 623 }
625 624
@@ -721,7 +720,7 @@ static struct dentry *fuse_get_parent(struct dentry *child)
721 720
722 parent = d_obtain_alias(inode); 721 parent = d_obtain_alias(inode);
723 if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) { 722 if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
724 parent->d_op = &fuse_dentry_operations; 723 d_set_d_op(parent, &fuse_dentry_operations);
725 fuse_invalidate_entry_cache(parent); 724 fuse_invalidate_entry_cache(parent);
726 } 725 }
727 726