diff options
| -rw-r--r-- | fs/fuse/dev.c | 44 |
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 | ||
| 60 | static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) | 57 | static 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 | ||
| 102 | void fuse_request_free(struct fuse_req *req) | 93 | void 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); |
