diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 10:43:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 10:43:54 -0500 |
commit | 7d44b0440147d83a65270205b22e7d365de28948 (patch) | |
tree | 0adc818f569f45912a19482773dabbf71b191b9d /fs/fuse/inode.c | |
parent | 0dc1488527a3c01383a50e5df7187219567586a3 (diff) | |
parent | 1baa26b2be92fe9917e2f7ef46d423b5dfa4da71 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: fix ioctl ABI
fuse: allow batching of FORGET requests
fuse: separate queue for FORGET requests
fuse: ioctl cleanup
Fix up trivial conflict in fs/fuse/inode.c due to RCU lookup having done
the RCU-freeing of the inode in fuse_destroy_inode().
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index a8b31da19b93..f62b32cffea9 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 | ||
74 | struct fuse_forget_link *fuse_alloc_forget() | ||
75 | { | ||
76 | return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL); | ||
77 | } | ||
78 | |||
74 | static struct inode *fuse_alloc_inode(struct super_block *sb) | 79 | static 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 | } |
@@ -111,24 +116,10 @@ static void fuse_destroy_inode(struct inode *inode) | |||
111 | struct fuse_inode *fi = get_fuse_inode(inode); | 116 | struct fuse_inode *fi = get_fuse_inode(inode); |
112 | BUG_ON(!list_empty(&fi->write_files)); | 117 | BUG_ON(!list_empty(&fi->write_files)); |
113 | BUG_ON(!list_empty(&fi->queued_writes)); | 118 | BUG_ON(!list_empty(&fi->queued_writes)); |
114 | if (fi->forget_req) | 119 | kfree(fi->forget); |
115 | fuse_request_free(fi->forget_req); | ||
116 | call_rcu(&inode->i_rcu, fuse_i_callback); | 120 | call_rcu(&inode->i_rcu, fuse_i_callback); |
117 | } | 121 | } |
118 | 122 | ||
119 | void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | ||
120 | u64 nodeid, u64 nlookup) | ||
121 | { | ||
122 | struct fuse_forget_in *inarg = &req->misc.forget_in; | ||
123 | inarg->nlookup = nlookup; | ||
124 | req->in.h.opcode = FUSE_FORGET; | ||
125 | req->in.h.nodeid = nodeid; | ||
126 | req->in.numargs = 1; | ||
127 | req->in.args[0].size = sizeof(struct fuse_forget_in); | ||
128 | req->in.args[0].value = inarg; | ||
129 | fuse_request_send_noreply(fc, req); | ||
130 | } | ||
131 | |||
132 | static void fuse_evict_inode(struct inode *inode) | 123 | static void fuse_evict_inode(struct inode *inode) |
133 | { | 124 | { |
134 | truncate_inode_pages(&inode->i_data, 0); | 125 | truncate_inode_pages(&inode->i_data, 0); |
@@ -136,8 +127,8 @@ static void fuse_evict_inode(struct inode *inode) | |||
136 | if (inode->i_sb->s_flags & MS_ACTIVE) { | 127 | if (inode->i_sb->s_flags & MS_ACTIVE) { |
137 | struct fuse_conn *fc = get_fuse_conn(inode); | 128 | struct fuse_conn *fc = get_fuse_conn(inode); |
138 | struct fuse_inode *fi = get_fuse_inode(inode); | 129 | struct fuse_inode *fi = get_fuse_inode(inode); |
139 | fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup); | 130 | fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup); |
140 | fi->forget_req = NULL; | 131 | fi->forget = NULL; |
141 | } | 132 | } |
142 | } | 133 | } |
143 | 134 | ||
@@ -541,6 +532,7 @@ void fuse_conn_init(struct fuse_conn *fc) | |||
541 | INIT_LIST_HEAD(&fc->interrupts); | 532 | INIT_LIST_HEAD(&fc->interrupts); |
542 | INIT_LIST_HEAD(&fc->bg_queue); | 533 | INIT_LIST_HEAD(&fc->bg_queue); |
543 | INIT_LIST_HEAD(&fc->entry); | 534 | INIT_LIST_HEAD(&fc->entry); |
535 | fc->forget_list_tail = &fc->forget_list_head; | ||
544 | atomic_set(&fc->num_waiting, 0); | 536 | atomic_set(&fc->num_waiting, 0); |
545 | fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; | 537 | fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; |
546 | fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; | 538 | fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; |