aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMaxim Patlasov <mpatlasov@parallels.com>2013-03-21 10:02:04 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2013-04-17 06:31:44 -0400
commit8b41e6715ed555e2d8e8dac52ec1f05a9f04dcb4 (patch)
treea3302435ed781462e1780b89e4ac5e9833158cb0 /fs
parent4c82456eeb4da081dd63dc69e91aa6deabd29e03 (diff)
fuse: make request allocations for background processing explicit
There are two types of processing requests in FUSE: synchronous (via fuse_request_send()) and asynchronous (via adding to fc->bg_queue). Fortunately, the type of processing is always known in advance, at the time of request allocation. This preparatory patch utilizes this fact making fuse_get_req() aware about the type. Next patches will use it. Signed-off-by: Maxim Patlasov <mpatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/fuse/cuse.c2
-rw-r--r--fs/fuse/dev.c20
-rw-r--r--fs/fuse/file.c16
-rw-r--r--fs/fuse/fuse_i.h2
-rw-r--r--fs/fuse/inode.c2
5 files changed, 37 insertions, 5 deletions
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 6f96a8def147..b7c7f3060635 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -422,7 +422,7 @@ static int cuse_send_init(struct cuse_conn *cc)
422 422
423 BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE); 423 BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE);
424 424
425 req = fuse_get_req(fc, 1); 425 req = fuse_get_req_for_background(fc, 1);
426 if (IS_ERR(req)) { 426 if (IS_ERR(req)) {
427 rc = PTR_ERR(req); 427 rc = PTR_ERR(req);
428 goto err; 428 goto err;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 11dfa0c3fb46..3b8301f5c0e1 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -130,7 +130,8 @@ static void fuse_req_init_context(struct fuse_req *req)
130 req->in.h.pid = current->pid; 130 req->in.h.pid = current->pid;
131} 131}
132 132
133struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) 133static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
134 bool for_background)
134{ 135{
135 struct fuse_req *req; 136 struct fuse_req *req;
136 sigset_t oldset; 137 sigset_t oldset;
@@ -156,14 +157,27 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
156 157
157 fuse_req_init_context(req); 158 fuse_req_init_context(req);
158 req->waiting = 1; 159 req->waiting = 1;
160 req->background = for_background;
159 return req; 161 return req;
160 162
161 out: 163 out:
162 atomic_dec(&fc->num_waiting); 164 atomic_dec(&fc->num_waiting);
163 return ERR_PTR(err); 165 return ERR_PTR(err);
164} 166}
167
168struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
169{
170 return __fuse_get_req(fc, npages, false);
171}
165EXPORT_SYMBOL_GPL(fuse_get_req); 172EXPORT_SYMBOL_GPL(fuse_get_req);
166 173
174struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
175 unsigned npages)
176{
177 return __fuse_get_req(fc, npages, true);
178}
179EXPORT_SYMBOL_GPL(fuse_get_req_for_background);
180
167/* 181/*
168 * Return request in fuse_file->reserved_req. However that may 182 * Return request in fuse_file->reserved_req. However that may
169 * currently be in use. If that is the case, wait for it to become 183 * currently be in use. If that is the case, wait for it to become
@@ -232,6 +246,7 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
232 246
233 fuse_req_init_context(req); 247 fuse_req_init_context(req);
234 req->waiting = 1; 248 req->waiting = 1;
249 req->background = 0;
235 return req; 250 return req;
236} 251}
237 252
@@ -442,6 +457,7 @@ __acquires(fc->lock)
442 457
443static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 458static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
444{ 459{
460 BUG_ON(req->background);
445 spin_lock(&fc->lock); 461 spin_lock(&fc->lock);
446 if (!fc->connected) 462 if (!fc->connected)
447 req->out.h.error = -ENOTCONN; 463 req->out.h.error = -ENOTCONN;
@@ -469,7 +485,7 @@ EXPORT_SYMBOL_GPL(fuse_request_send);
469static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 485static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
470 struct fuse_req *req) 486 struct fuse_req *req)
471{ 487{
472 req->background = 1; 488 BUG_ON(!req->background);
473 fc->num_background++; 489 fc->num_background++;
474 if (fc->num_background == fc->max_background) 490 if (fc->num_background == fc->max_background)
475 fc->blocked = 1; 491 fc->blocked = 1;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 34b80ba95bad..4884790b9639 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -126,11 +126,13 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
126 struct fuse_req *req = ff->reserved_req; 126 struct fuse_req *req = ff->reserved_req;
127 127
128 if (sync) { 128 if (sync) {
129 req->background = 0;
129 fuse_request_send(ff->fc, req); 130 fuse_request_send(ff->fc, req);
130 path_put(&req->misc.release.path); 131 path_put(&req->misc.release.path);
131 fuse_put_request(ff->fc, req); 132 fuse_put_request(ff->fc, req);
132 } else { 133 } else {
133 req->end = fuse_release_end; 134 req->end = fuse_release_end;
135 req->background = 1;
134 fuse_request_send_background(ff->fc, req); 136 fuse_request_send_background(ff->fc, req);
135 } 137 }
136 kfree(ff); 138 kfree(ff);
@@ -282,6 +284,7 @@ void fuse_sync_release(struct fuse_file *ff, int flags)
282 WARN_ON(atomic_read(&ff->count) > 1); 284 WARN_ON(atomic_read(&ff->count) > 1);
283 fuse_prepare_release(ff, flags, FUSE_RELEASE); 285 fuse_prepare_release(ff, flags, FUSE_RELEASE);
284 ff->reserved_req->force = 1; 286 ff->reserved_req->force = 1;
287 ff->reserved_req->background = 0;
285 fuse_request_send(ff->fc, ff->reserved_req); 288 fuse_request_send(ff->fc, ff->reserved_req);
286 fuse_put_request(ff->fc, ff->reserved_req); 289 fuse_put_request(ff->fc, ff->reserved_req);
287 kfree(ff); 290 kfree(ff);
@@ -661,7 +664,12 @@ static int fuse_readpages_fill(void *_data, struct page *page)
661 int nr_alloc = min_t(unsigned, data->nr_pages, 664 int nr_alloc = min_t(unsigned, data->nr_pages,
662 FUSE_MAX_PAGES_PER_REQ); 665 FUSE_MAX_PAGES_PER_REQ);
663 fuse_send_readpages(req, data->file); 666 fuse_send_readpages(req, data->file);
664 data->req = req = fuse_get_req(fc, nr_alloc); 667 if (fc->async_read)
668 req = fuse_get_req_for_background(fc, nr_alloc);
669 else
670 req = fuse_get_req(fc, nr_alloc);
671
672 data->req = req;
665 if (IS_ERR(req)) { 673 if (IS_ERR(req)) {
666 unlock_page(page); 674 unlock_page(page);
667 return PTR_ERR(req); 675 return PTR_ERR(req);
@@ -696,7 +704,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
696 704
697 data.file = file; 705 data.file = file;
698 data.inode = inode; 706 data.inode = inode;
699 data.req = fuse_get_req(fc, nr_alloc); 707 if (fc->async_read)
708 data.req = fuse_get_req_for_background(fc, nr_alloc);
709 else
710 data.req = fuse_get_req(fc, nr_alloc);
700 data.nr_pages = nr_pages; 711 data.nr_pages = nr_pages;
701 err = PTR_ERR(data.req); 712 err = PTR_ERR(data.req);
702 if (IS_ERR(data.req)) 713 if (IS_ERR(data.req))
@@ -1375,6 +1386,7 @@ static int fuse_writepage_locked(struct page *page)
1375 if (!req) 1386 if (!req)
1376 goto err; 1387 goto err;
1377 1388
1389 req->background = 1; /* writeback always goes to bg_queue */
1378 tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); 1390 tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
1379 if (!tmp_page) 1391 if (!tmp_page)
1380 goto err_free; 1392 goto err_free;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 6aeba864f070..47c94d28ff88 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -708,6 +708,8 @@ void fuse_request_free(struct fuse_req *req);
708 * caller should specify # elements in req->pages[] explicitly 708 * caller should specify # elements in req->pages[] explicitly
709 */ 709 */
710struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages); 710struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages);
711struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
712 unsigned npages);
711 713
712/** 714/**
713 * Get a request, may fail with -ENOMEM, 715 * Get a request, may fail with -ENOMEM,
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 137185c3884f..e26607df93df 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -346,6 +346,7 @@ static void fuse_send_destroy(struct fuse_conn *fc)
346 fc->destroy_req = NULL; 346 fc->destroy_req = NULL;
347 req->in.h.opcode = FUSE_DESTROY; 347 req->in.h.opcode = FUSE_DESTROY;
348 req->force = 1; 348 req->force = 1;
349 req->background = 0;
349 fuse_request_send(fc, req); 350 fuse_request_send(fc, req);
350 fuse_put_request(fc, req); 351 fuse_put_request(fc, req);
351 } 352 }
@@ -1043,6 +1044,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
1043 init_req = fuse_request_alloc(0); 1044 init_req = fuse_request_alloc(0);
1044 if (!init_req) 1045 if (!init_req)
1045 goto err_put_root; 1046 goto err_put_root;
1047 init_req->background = 1;
1046 1048
1047 if (is_bdev) { 1049 if (is_bdev) {
1048 fc->destroy_req = fuse_request_alloc(0); 1050 fc->destroy_req = fuse_request_alloc(0);