aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/dev.c44
1 files changed, 18 insertions, 26 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 91b4ecf85dc7..fefb9dd8a2f4 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -44,9 +44,6 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages,
44 struct fuse_page_desc *page_descs, 44 struct fuse_page_desc *page_descs,
45 unsigned npages) 45 unsigned npages)
46{ 46{
47 memset(req, 0, sizeof(*req));
48 memset(pages, 0, sizeof(*pages) * npages);
49 memset(page_descs, 0, sizeof(*page_descs) * npages);
50 INIT_LIST_HEAD(&req->list); 47 INIT_LIST_HEAD(&req->list);
51 INIT_LIST_HEAD(&req->intr_entry); 48 INIT_LIST_HEAD(&req->intr_entry);
52 init_waitqueue_head(&req->waitq); 49 init_waitqueue_head(&req->waitq);
@@ -59,28 +56,22 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages,
59 56
60static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 57static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
61{ 58{
62 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); 59 struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
63 if (req) { 60 if (req) {
64 struct page **pages; 61 struct page **pages = NULL;
65 struct fuse_page_desc *page_descs; 62 struct fuse_page_desc *page_descs = NULL;
66 63
67 if (npages <= FUSE_REQ_INLINE_PAGES) { 64 if (npages > FUSE_REQ_INLINE_PAGES) {
65 pages = kzalloc(npages * (sizeof(*pages) +
66 sizeof(*page_descs)), flags);
67 if (!pages) {
68 kmem_cache_free(fuse_req_cachep, req);
69 return NULL;
70 }
71 page_descs = (void *) pages + npages * sizeof(*pages);
72 } else if (npages) {
68 pages = req->inline_pages; 73 pages = req->inline_pages;
69 page_descs = req->inline_page_descs; 74 page_descs = req->inline_page_descs;
70 } else {
71 pages = kmalloc_array(npages, sizeof(struct page *),
72 flags);
73 page_descs =
74 kmalloc_array(npages,
75 sizeof(struct fuse_page_desc),
76 flags);
77 }
78
79 if (!pages || !page_descs) {
80 kfree(pages);
81 kfree(page_descs);
82 kmem_cache_free(fuse_req_cachep, req);
83 return NULL;
84 } 75 }
85 76
86 fuse_request_init(req, pages, page_descs, npages); 77 fuse_request_init(req, pages, page_descs, npages);
@@ -101,10 +92,9 @@ struct fuse_req *fuse_request_alloc_nofs(unsigned npages)
101 92
102void fuse_request_free(struct fuse_req *req) 93void fuse_request_free(struct fuse_req *req)
103{ 94{
104 if (req->pages != req->inline_pages) { 95 if (req->pages != req->inline_pages)
105 kfree(req->pages); 96 kfree(req->pages);
106 kfree(req->page_descs); 97
107 }
108 kmem_cache_free(fuse_req_cachep, req); 98 kmem_cache_free(fuse_req_cachep, req);
109} 99}
110 100
@@ -239,8 +229,10 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
239 struct file *file = req->stolen_file; 229 struct file *file = req->stolen_file;
240 struct fuse_file *ff = file->private_data; 230 struct fuse_file *ff = file->private_data;
241 231
232 WARN_ON(req->max_pages);
242 spin_lock(&fc->lock); 233 spin_lock(&fc->lock);
243 fuse_request_init(req, req->pages, req->page_descs, req->max_pages); 234 memset(req, 0, sizeof(*req));
235 fuse_request_init(req, NULL, NULL, 0);
244 BUG_ON(ff->reserved_req); 236 BUG_ON(ff->reserved_req);
245 ff->reserved_req = req; 237 ff->reserved_req = req;
246 wake_up_all(&fc->reserved_req_waitq); 238 wake_up_all(&fc->reserved_req_waitq);