lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <20121226124431.24502.72951.stgit@maximpc.sw.ru> Date: Wed, 26 Dec 2012 16:44:45 +0400 From: Maxim Patlasov <mpatlasov@...allels.com> To: miklos@...redi.hu Cc: dev@...allels.com, xemul@...allels.com, fuse-devel@...ts.sourceforge.net, bfoster@...hat.com, linux-kernel@...r.kernel.org, devel@...nvz.org Subject: [PATCH 1/3] 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@...allels.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(); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists