mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
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>
This commit is contained in:
parent
4c82456eeb
commit
8b41e6715e
@ -422,7 +422,7 @@ static int cuse_send_init(struct cuse_conn *cc)
|
|||||||
|
|
||||||
BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE);
|
BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE);
|
||||||
|
|
||||||
req = fuse_get_req(fc, 1);
|
req = fuse_get_req_for_background(fc, 1);
|
||||||
if (IS_ERR(req)) {
|
if (IS_ERR(req)) {
|
||||||
rc = PTR_ERR(req);
|
rc = PTR_ERR(req);
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -130,7 +130,8 @@ static void fuse_req_init_context(struct fuse_req *req)
|
|||||||
req->in.h.pid = current->pid;
|
req->in.h.pid = current->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
|
static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
|
||||||
|
bool for_background)
|
||||||
{
|
{
|
||||||
struct fuse_req *req;
|
struct fuse_req *req;
|
||||||
sigset_t oldset;
|
sigset_t oldset;
|
||||||
@ -156,14 +157,27 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
|
|||||||
|
|
||||||
fuse_req_init_context(req);
|
fuse_req_init_context(req);
|
||||||
req->waiting = 1;
|
req->waiting = 1;
|
||||||
|
req->background = for_background;
|
||||||
return req;
|
return req;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
atomic_dec(&fc->num_waiting);
|
atomic_dec(&fc->num_waiting);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
|
||||||
|
{
|
||||||
|
return __fuse_get_req(fc, npages, false);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(fuse_get_req);
|
EXPORT_SYMBOL_GPL(fuse_get_req);
|
||||||
|
|
||||||
|
struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
|
||||||
|
unsigned npages)
|
||||||
|
{
|
||||||
|
return __fuse_get_req(fc, npages, true);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(fuse_get_req_for_background);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return request in fuse_file->reserved_req. However that may
|
* Return request in fuse_file->reserved_req. However that may
|
||||||
* currently be in use. If that is the case, wait for it to become
|
* 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,
|
|||||||
|
|
||||||
fuse_req_init_context(req);
|
fuse_req_init_context(req);
|
||||||
req->waiting = 1;
|
req->waiting = 1;
|
||||||
|
req->background = 0;
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,6 +457,7 @@ __acquires(fc->lock)
|
|||||||
|
|
||||||
static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
|
static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
|
||||||
{
|
{
|
||||||
|
BUG_ON(req->background);
|
||||||
spin_lock(&fc->lock);
|
spin_lock(&fc->lock);
|
||||||
if (!fc->connected)
|
if (!fc->connected)
|
||||||
req->out.h.error = -ENOTCONN;
|
req->out.h.error = -ENOTCONN;
|
||||||
@ -469,7 +485,7 @@ EXPORT_SYMBOL_GPL(fuse_request_send);
|
|||||||
static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
|
static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
|
||||||
struct fuse_req *req)
|
struct fuse_req *req)
|
||||||
{
|
{
|
||||||
req->background = 1;
|
BUG_ON(!req->background);
|
||||||
fc->num_background++;
|
fc->num_background++;
|
||||||
if (fc->num_background == fc->max_background)
|
if (fc->num_background == fc->max_background)
|
||||||
fc->blocked = 1;
|
fc->blocked = 1;
|
||||||
|
@ -126,11 +126,13 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
|
|||||||
struct fuse_req *req = ff->reserved_req;
|
struct fuse_req *req = ff->reserved_req;
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
|
req->background = 0;
|
||||||
fuse_request_send(ff->fc, req);
|
fuse_request_send(ff->fc, req);
|
||||||
path_put(&req->misc.release.path);
|
path_put(&req->misc.release.path);
|
||||||
fuse_put_request(ff->fc, req);
|
fuse_put_request(ff->fc, req);
|
||||||
} else {
|
} else {
|
||||||
req->end = fuse_release_end;
|
req->end = fuse_release_end;
|
||||||
|
req->background = 1;
|
||||||
fuse_request_send_background(ff->fc, req);
|
fuse_request_send_background(ff->fc, req);
|
||||||
}
|
}
|
||||||
kfree(ff);
|
kfree(ff);
|
||||||
@ -282,6 +284,7 @@ void fuse_sync_release(struct fuse_file *ff, int flags)
|
|||||||
WARN_ON(atomic_read(&ff->count) > 1);
|
WARN_ON(atomic_read(&ff->count) > 1);
|
||||||
fuse_prepare_release(ff, flags, FUSE_RELEASE);
|
fuse_prepare_release(ff, flags, FUSE_RELEASE);
|
||||||
ff->reserved_req->force = 1;
|
ff->reserved_req->force = 1;
|
||||||
|
ff->reserved_req->background = 0;
|
||||||
fuse_request_send(ff->fc, ff->reserved_req);
|
fuse_request_send(ff->fc, ff->reserved_req);
|
||||||
fuse_put_request(ff->fc, ff->reserved_req);
|
fuse_put_request(ff->fc, ff->reserved_req);
|
||||||
kfree(ff);
|
kfree(ff);
|
||||||
@ -661,7 +664,12 @@ static int fuse_readpages_fill(void *_data, struct page *page)
|
|||||||
int nr_alloc = min_t(unsigned, data->nr_pages,
|
int nr_alloc = min_t(unsigned, data->nr_pages,
|
||||||
FUSE_MAX_PAGES_PER_REQ);
|
FUSE_MAX_PAGES_PER_REQ);
|
||||||
fuse_send_readpages(req, data->file);
|
fuse_send_readpages(req, data->file);
|
||||||
data->req = req = fuse_get_req(fc, nr_alloc);
|
if (fc->async_read)
|
||||||
|
req = fuse_get_req_for_background(fc, nr_alloc);
|
||||||
|
else
|
||||||
|
req = fuse_get_req(fc, nr_alloc);
|
||||||
|
|
||||||
|
data->req = req;
|
||||||
if (IS_ERR(req)) {
|
if (IS_ERR(req)) {
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
return PTR_ERR(req);
|
return PTR_ERR(req);
|
||||||
@ -696,7 +704,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
|
|||||||
|
|
||||||
data.file = file;
|
data.file = file;
|
||||||
data.inode = inode;
|
data.inode = inode;
|
||||||
data.req = fuse_get_req(fc, nr_alloc);
|
if (fc->async_read)
|
||||||
|
data.req = fuse_get_req_for_background(fc, nr_alloc);
|
||||||
|
else
|
||||||
|
data.req = fuse_get_req(fc, nr_alloc);
|
||||||
data.nr_pages = nr_pages;
|
data.nr_pages = nr_pages;
|
||||||
err = PTR_ERR(data.req);
|
err = PTR_ERR(data.req);
|
||||||
if (IS_ERR(data.req))
|
if (IS_ERR(data.req))
|
||||||
@ -1375,6 +1386,7 @@ static int fuse_writepage_locked(struct page *page)
|
|||||||
if (!req)
|
if (!req)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
req->background = 1; /* writeback always goes to bg_queue */
|
||||||
tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
|
tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
|
||||||
if (!tmp_page)
|
if (!tmp_page)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
@ -708,6 +708,8 @@ void fuse_request_free(struct fuse_req *req);
|
|||||||
* caller should specify # elements in req->pages[] explicitly
|
* caller should specify # elements in req->pages[] explicitly
|
||||||
*/
|
*/
|
||||||
struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages);
|
struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages);
|
||||||
|
struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
|
||||||
|
unsigned npages);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a request, may fail with -ENOMEM,
|
* Get a request, may fail with -ENOMEM,
|
||||||
|
@ -346,6 +346,7 @@ static void fuse_send_destroy(struct fuse_conn *fc)
|
|||||||
fc->destroy_req = NULL;
|
fc->destroy_req = NULL;
|
||||||
req->in.h.opcode = FUSE_DESTROY;
|
req->in.h.opcode = FUSE_DESTROY;
|
||||||
req->force = 1;
|
req->force = 1;
|
||||||
|
req->background = 0;
|
||||||
fuse_request_send(fc, req);
|
fuse_request_send(fc, req);
|
||||||
fuse_put_request(fc, req);
|
fuse_put_request(fc, req);
|
||||||
}
|
}
|
||||||
@ -1043,6 +1044,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
init_req = fuse_request_alloc(0);
|
init_req = fuse_request_alloc(0);
|
||||||
if (!init_req)
|
if (!init_req)
|
||||||
goto err_put_root;
|
goto err_put_root;
|
||||||
|
init_req->background = 1;
|
||||||
|
|
||||||
if (is_bdev) {
|
if (is_bdev) {
|
||||||
fc->destroy_req = fuse_request_alloc(0);
|
fc->destroy_req = fuse_request_alloc(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user