diff options
author | Maxim Patlasov <mpatlasov@parallels.com> | 2013-03-21 10:02:04 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2013-04-17 06:31:44 -0400 |
commit | 8b41e6715ed555e2d8e8dac52ec1f05a9f04dcb4 (patch) | |
tree | a3302435ed781462e1780b89e4ac5e9833158cb0 /fs | |
parent | 4c82456eeb4da081dd63dc69e91aa6deabd29e03 (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.c | 2 | ||||
-rw-r--r-- | fs/fuse/dev.c | 20 | ||||
-rw-r--r-- | fs/fuse/file.c | 16 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 2 | ||||
-rw-r--r-- | fs/fuse/inode.c | 2 |
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 | ||
133 | struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) | 133 | static 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 | |||
168 | struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) | ||
169 | { | ||
170 | return __fuse_get_req(fc, npages, false); | ||
171 | } | ||
165 | EXPORT_SYMBOL_GPL(fuse_get_req); | 172 | EXPORT_SYMBOL_GPL(fuse_get_req); |
166 | 173 | ||
174 | struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, | ||
175 | unsigned npages) | ||
176 | { | ||
177 | return __fuse_get_req(fc, npages, true); | ||
178 | } | ||
179 | EXPORT_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 | ||
443 | static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) | 458 | static 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); | |||
469 | static void fuse_request_send_nowait_locked(struct fuse_conn *fc, | 485 | static 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 | */ |
710 | struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages); | 710 | struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages); |
711 | struct 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); |