From: Maxim Patlasov <mpatlasov@parallels.com>
To: miklos@szeredi.hu
Cc: dev@parallels.com, xemul@parallels.com,
fuse-devel@lists.sourceforge.net, bfoster@redhat.com,
linux-kernel@vger.kernel.org, devel@openvz.org
Subject: [PATCH 1/3] fuse: make request allocations for background processing explicit
Date: Wed, 26 Dec 2012 16:44:45 +0400 [thread overview]
Message-ID: <20121226124431.24502.72951.stgit@maximpc.sw.ru> (raw)
In-Reply-To: <20121226124319.24502.41536.stgit@maximpc.sw.ru>
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>
---
fs/fuse/cuse.c | 2 +-
fs/fuse/dev.c | 22 +++++++++++++++++++---
fs/fuse/file.c | 5 +++--
fs/fuse/fuse_i.h | 3 +++
fs/fuse/inode.c | 1 +
5 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index ee8d550..37e18dc 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -411,7 +411,7 @@ static int cuse_send_init(struct cuse_conn *cc)
BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE);
- req = fuse_get_req(fc);
+ req = fuse_get_req_for_background(fc);
if (IS_ERR(req)) {
rc = PTR_ERR(req);
goto err;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 8c23fa7..0b6b9d1 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -55,8 +55,10 @@ EXPORT_SYMBOL_GPL(fuse_request_alloc);
struct fuse_req *fuse_request_alloc_nofs(void)
{
struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_NOFS);
- if (req)
+ if (req) {
fuse_request_init(req);
+ req->background = 1; /* writeback always goes to bg_queue */
+ }
return req;
}
@@ -97,7 +99,8 @@ static void fuse_req_init_context(struct fuse_req *req)
req->in.h.pid = current->pid;
}
-struct fuse_req *fuse_get_req(struct fuse_conn *fc)
+struct fuse_req *fuse_get_req_internal(struct fuse_conn *fc,
+ bool for_background)
{
struct fuse_req *req;
sigset_t oldset;
@@ -123,14 +126,26 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc)
fuse_req_init_context(req);
req->waiting = 1;
+ req->background = for_background;
return req;
out:
atomic_dec(&fc->num_waiting);
return ERR_PTR(err);
}
+
+struct fuse_req *fuse_get_req(struct fuse_conn *fc)
+{
+ return fuse_get_req_internal(fc, 0);
+}
EXPORT_SYMBOL_GPL(fuse_get_req);
+struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc)
+{
+ return fuse_get_req_internal(fc, 1);
+}
+EXPORT_SYMBOL_GPL(fuse_get_req_for_background);
+
/*
* Return request in fuse_file->reserved_req. However that may
* currently be in use. If that is the case, wait for it to become
@@ -408,6 +423,7 @@ __acquires(fc->lock)
void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
{
+ BUG_ON(req->background);
req->isreply = 1;
spin_lock(&fc->lock);
if (!fc->connected)
@@ -430,7 +446,7 @@ EXPORT_SYMBOL_GPL(fuse_request_send);
static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
struct fuse_req *req)
{
- req->background = 1;
+ BUG_ON(!req->background);
fc->num_background++;
if (fc->num_background == fc->max_background)
fc->blocked = 1;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 78d2837..86101ce 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -131,6 +131,7 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
fuse_put_request(ff->fc, req);
} else {
req->end = fuse_release_end;
+ req->background = 1;
fuse_request_send_background(ff->fc, req);
}
kfree(ff);
@@ -657,7 +658,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
(req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
req->pages[req->num_pages - 1]->index + 1 != page->index)) {
fuse_send_readpages(req, data->file);
- data->req = req = fuse_get_req(fc);
+ data->req = req = fuse_get_req_internal(fc, fc->async_read);
if (IS_ERR(req)) {
unlock_page(page);
return PTR_ERR(req);
@@ -683,7 +684,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
data.file = file;
data.inode = inode;
- data.req = fuse_get_req(fc);
+ data.req = fuse_get_req_internal(fc, fc->async_read);
err = PTR_ERR(data.req);
if (IS_ERR(data.req))
goto out;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index e24dd74..70362e9 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -671,6 +671,9 @@ void fuse_request_free(struct fuse_req *req);
* Get a request, may fail with -ENOMEM
*/
struct fuse_req *fuse_get_req(struct fuse_conn *fc);
+struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc);
+struct fuse_req *fuse_get_req_internal(struct fuse_conn *fc,
+ bool for_background);
/**
* Gets a requests for a file operation, always succeeds
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index f0eda12..c0f0eba 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1032,6 +1032,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
init_req = fuse_request_alloc();
if (!init_req)
goto err_put_root;
+ init_req->background = 1;
if (is_bdev) {
fc->destroy_req = fuse_request_alloc();
next prev parent reply other threads:[~2012-12-26 12:44 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-26 12:44 [PATCH 0/3] fuse: fix accounting background requests Maxim Patlasov
2012-12-26 12:44 ` Maxim Patlasov [this message]
2012-12-26 12:44 ` [PATCH 2/3] fuse: skip blocking on allocations of synchronous requests Maxim Patlasov
2012-12-26 12:45 ` [PATCH 3/3] fuse: implement exclusive wakeup for blocked_waitq Maxim Patlasov
2013-02-06 17:12 ` [PATCH 0/3] fuse: fix accounting background requests Miklos Szeredi
2013-03-21 13:04 ` Maxim V. Patlasov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121226124431.24502.72951.stgit@maximpc.sw.ru \
--to=mpatlasov@parallels.com \
--cc=bfoster@redhat.com \
--cc=dev@parallels.com \
--cc=devel@openvz.org \
--cc=fuse-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=xemul@parallels.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®