aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/dev.c')
-rw-r--r--fs/fuse/dev.c128
1 files changed, 96 insertions, 32 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index e83351aa5bad..e9bdec0b16d9 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -34,34 +34,67 @@ static struct fuse_conn *fuse_get_conn(struct file *file)
34 return file->private_data; 34 return file->private_data;
35} 35}
36 36
37static void fuse_request_init(struct fuse_req *req) 37static void fuse_request_init(struct fuse_req *req, struct page **pages,
38 struct fuse_page_desc *page_descs,
39 unsigned npages)
38{ 40{
39 memset(req, 0, sizeof(*req)); 41 memset(req, 0, sizeof(*req));
42 memset(pages, 0, sizeof(*pages) * npages);
43 memset(page_descs, 0, sizeof(*page_descs) * npages);
40 INIT_LIST_HEAD(&req->list); 44 INIT_LIST_HEAD(&req->list);
41 INIT_LIST_HEAD(&req->intr_entry); 45 INIT_LIST_HEAD(&req->intr_entry);
42 init_waitqueue_head(&req->waitq); 46 init_waitqueue_head(&req->waitq);
43 atomic_set(&req->count, 1); 47 atomic_set(&req->count, 1);
48 req->pages = pages;
49 req->page_descs = page_descs;
50 req->max_pages = npages;
44} 51}
45 52
46struct fuse_req *fuse_request_alloc(void) 53static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
47{ 54{
48 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL); 55 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags);
49 if (req) 56 if (req) {
50 fuse_request_init(req); 57 struct page **pages;
58 struct fuse_page_desc *page_descs;
59
60 if (npages <= FUSE_REQ_INLINE_PAGES) {
61 pages = req->inline_pages;
62 page_descs = req->inline_page_descs;
63 } else {
64 pages = kmalloc(sizeof(struct page *) * npages, flags);
65 page_descs = kmalloc(sizeof(struct fuse_page_desc) *
66 npages, flags);
67 }
68
69 if (!pages || !page_descs) {
70 kfree(pages);
71 kfree(page_descs);
72 kmem_cache_free(fuse_req_cachep, req);
73 return NULL;
74 }
75
76 fuse_request_init(req, pages, page_descs, npages);
77 }
51 return req; 78 return req;
52} 79}
80
81struct fuse_req *fuse_request_alloc(unsigned npages)
82{
83 return __fuse_request_alloc(npages, GFP_KERNEL);
84}
53EXPORT_SYMBOL_GPL(fuse_request_alloc); 85EXPORT_SYMBOL_GPL(fuse_request_alloc);
54 86
55struct fuse_req *fuse_request_alloc_nofs(void) 87struct fuse_req *fuse_request_alloc_nofs(unsigned npages)
56{ 88{
57 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_NOFS); 89 return __fuse_request_alloc(npages, GFP_NOFS);
58 if (req)
59 fuse_request_init(req);
60 return req;
61} 90}
62 91
63void fuse_request_free(struct fuse_req *req) 92void fuse_request_free(struct fuse_req *req)
64{ 93{
94 if (req->pages != req->inline_pages) {
95 kfree(req->pages);
96 kfree(req->page_descs);
97 }
65 kmem_cache_free(fuse_req_cachep, req); 98 kmem_cache_free(fuse_req_cachep, req);
66} 99}
67 100
@@ -97,7 +130,7 @@ static void fuse_req_init_context(struct fuse_req *req)
97 req->in.h.pid = current->pid; 130 req->in.h.pid = current->pid;
98} 131}
99 132
100struct fuse_req *fuse_get_req(struct fuse_conn *fc) 133struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
101{ 134{
102 struct fuse_req *req; 135 struct fuse_req *req;
103 sigset_t oldset; 136 sigset_t oldset;
@@ -116,7 +149,7 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc)
116 if (!fc->connected) 149 if (!fc->connected)
117 goto out; 150 goto out;
118 151
119 req = fuse_request_alloc(); 152 req = fuse_request_alloc(npages);
120 err = -ENOMEM; 153 err = -ENOMEM;
121 if (!req) 154 if (!req)
122 goto out; 155 goto out;
@@ -165,7 +198,7 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
165 struct fuse_file *ff = file->private_data; 198 struct fuse_file *ff = file->private_data;
166 199
167 spin_lock(&fc->lock); 200 spin_lock(&fc->lock);
168 fuse_request_init(req); 201 fuse_request_init(req, req->pages, req->page_descs, req->max_pages);
169 BUG_ON(ff->reserved_req); 202 BUG_ON(ff->reserved_req);
170 ff->reserved_req = req; 203 ff->reserved_req = req;
171 wake_up_all(&fc->reserved_req_waitq); 204 wake_up_all(&fc->reserved_req_waitq);
@@ -186,13 +219,14 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
186 * filesystem should not have it's own file open. If deadlock is 219 * filesystem should not have it's own file open. If deadlock is
187 * intentional, it can still be broken by "aborting" the filesystem. 220 * intentional, it can still be broken by "aborting" the filesystem.
188 */ 221 */
189struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file) 222struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
223 struct file *file)
190{ 224{
191 struct fuse_req *req; 225 struct fuse_req *req;
192 226
193 atomic_inc(&fc->num_waiting); 227 atomic_inc(&fc->num_waiting);
194 wait_event(fc->blocked_waitq, !fc->blocked); 228 wait_event(fc->blocked_waitq, !fc->blocked);
195 req = fuse_request_alloc(); 229 req = fuse_request_alloc(0);
196 if (!req) 230 if (!req)
197 req = get_reserved_req(fc, file); 231 req = get_reserved_req(fc, file);
198 232
@@ -406,9 +440,8 @@ __acquires(fc->lock)
406 } 440 }
407} 441}
408 442
409void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 443static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
410{ 444{
411 req->isreply = 1;
412 spin_lock(&fc->lock); 445 spin_lock(&fc->lock);
413 if (!fc->connected) 446 if (!fc->connected)
414 req->out.h.error = -ENOTCONN; 447 req->out.h.error = -ENOTCONN;
@@ -425,6 +458,12 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
425 } 458 }
426 spin_unlock(&fc->lock); 459 spin_unlock(&fc->lock);
427} 460}
461
462void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
463{
464 req->isreply = 1;
465 __fuse_request_send(fc, req);
466}
428EXPORT_SYMBOL_GPL(fuse_request_send); 467EXPORT_SYMBOL_GPL(fuse_request_send);
429 468
430static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 469static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
@@ -491,6 +530,27 @@ void fuse_request_send_background_locked(struct fuse_conn *fc,
491 fuse_request_send_nowait_locked(fc, req); 530 fuse_request_send_nowait_locked(fc, req);
492} 531}
493 532
533void fuse_force_forget(struct file *file, u64 nodeid)
534{
535 struct inode *inode = file->f_path.dentry->d_inode;
536 struct fuse_conn *fc = get_fuse_conn(inode);
537 struct fuse_req *req;
538 struct fuse_forget_in inarg;
539
540 memset(&inarg, 0, sizeof(inarg));
541 inarg.nlookup = 1;
542 req = fuse_get_req_nofail_nopages(fc, file);
543 req->in.h.opcode = FUSE_FORGET;
544 req->in.h.nodeid = nodeid;
545 req->in.numargs = 1;
546 req->in.args[0].size = sizeof(inarg);
547 req->in.args[0].value = &inarg;
548 req->isreply = 0;
549 __fuse_request_send(fc, req);
550 /* ignore errors */
551 fuse_put_request(fc, req);
552}
553
494/* 554/*
495 * Lock the request. Up to the next unlock_request() there mustn't be 555 * Lock the request. Up to the next unlock_request() there mustn't be
496 * anything that could cause a page-fault. If the request was already 556 * anything that could cause a page-fault. If the request was already
@@ -850,11 +910,11 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
850{ 910{
851 unsigned i; 911 unsigned i;
852 struct fuse_req *req = cs->req; 912 struct fuse_req *req = cs->req;
853 unsigned offset = req->page_offset;
854 unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
855 913