ecryptfs: don't reinvent the wheels, please - use struct completion
... and keep the sodding requests on stack - they are small enough. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8fc37ec54c
commit
3b8b487114
3 changed files with 26 additions and 65 deletions
|
@ -550,20 +550,6 @@ extern struct kmem_cache *ecryptfs_key_record_cache;
|
|||
extern struct kmem_cache *ecryptfs_key_sig_cache;
|
||||
extern struct kmem_cache *ecryptfs_global_auth_tok_cache;
|
||||
extern struct kmem_cache *ecryptfs_key_tfm_cache;
|
||||
extern struct kmem_cache *ecryptfs_open_req_cache;
|
||||
|
||||
struct ecryptfs_open_req {
|
||||
#define ECRYPTFS_REQ_PROCESSED 0x00000001
|
||||
#define ECRYPTFS_REQ_DROPPED 0x00000002
|
||||
#define ECRYPTFS_REQ_ZOMBIE 0x00000004
|
||||
u32 flags;
|
||||
struct file **lower_file;
|
||||
struct dentry *lower_dentry;
|
||||
struct vfsmount *lower_mnt;
|
||||
wait_queue_head_t wait;
|
||||
struct mutex mux;
|
||||
struct list_head kthread_ctl_list;
|
||||
};
|
||||
|
||||
struct inode *ecryptfs_get_inode(struct inode *lower_inode,
|
||||
struct super_block *sb);
|
||||
|
|
|
@ -27,7 +27,13 @@
|
|||
#include <linux/mount.h>
|
||||
#include "ecryptfs_kernel.h"
|
||||
|
||||
struct kmem_cache *ecryptfs_open_req_cache;
|
||||
struct ecryptfs_open_req {
|
||||
struct file **lower_file;
|
||||
struct dentry *lower_dentry;
|
||||
struct vfsmount *lower_mnt;
|
||||
struct completion done;
|
||||
struct list_head kthread_ctl_list;
|
||||
};
|
||||
|
||||
static struct ecryptfs_kthread_ctl {
|
||||
#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
|
||||
|
@ -67,18 +73,13 @@ static int ecryptfs_threadfn(void *ignored)
|
|||
req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
|
||||
struct ecryptfs_open_req,
|
||||
kthread_ctl_list);
|
||||
mutex_lock(&req->mux);
|
||||
list_del(&req->kthread_ctl_list);
|
||||
if (!(req->flags & ECRYPTFS_REQ_ZOMBIE)) {
|
||||
dget(req->lower_dentry);
|
||||
mntget(req->lower_mnt);
|
||||
(*req->lower_file) = dentry_open(
|
||||
req->lower_dentry, req->lower_mnt,
|
||||
(O_RDWR | O_LARGEFILE), current_cred());
|
||||
req->flags |= ECRYPTFS_REQ_PROCESSED;
|
||||
}
|
||||
wake_up(&req->wait);
|
||||
mutex_unlock(&req->mux);
|
||||
dget(req->lower_dentry);
|
||||
mntget(req->lower_mnt);
|
||||
(*req->lower_file) = dentry_open(
|
||||
req->lower_dentry, req->lower_mnt,
|
||||
(O_RDWR | O_LARGEFILE), current_cred());
|
||||
complete(&req->done);
|
||||
}
|
||||
mutex_unlock(&ecryptfs_kthread_ctl.mux);
|
||||
}
|
||||
|
@ -111,10 +112,9 @@ void ecryptfs_destroy_kthread(void)
|
|||
ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
|
||||
list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list,
|
||||
kthread_ctl_list) {
|
||||
mutex_lock(&req->mux);
|
||||
req->flags |= ECRYPTFS_REQ_ZOMBIE;
|
||||
wake_up(&req->wait);
|
||||
mutex_unlock(&req->mux);
|
||||
list_del(&req->kthread_ctl_list);
|
||||
*req->lower_file = ERR_PTR(-EIO);
|
||||
complete(&req->done);
|
||||
}
|
||||
mutex_unlock(&ecryptfs_kthread_ctl.mux);
|
||||
kthread_stop(ecryptfs_kthread);
|
||||
|
@ -136,7 +136,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
|||
struct vfsmount *lower_mnt,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct ecryptfs_open_req *req;
|
||||
struct ecryptfs_open_req req;
|
||||
int flags = O_LARGEFILE;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -153,17 +153,10 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
|||
rc = PTR_ERR((*lower_file));
|
||||
goto out;
|
||||
}
|
||||
req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
|
||||
if (!req) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
mutex_init(&req->mux);
|
||||
req->lower_file = lower_file;
|
||||
req->lower_dentry = lower_dentry;
|
||||
req->lower_mnt = lower_mnt;
|
||||
init_waitqueue_head(&req->wait);
|
||||
req->flags = 0;
|
||||
init_completion(&req.done);
|
||||
req.lower_file = lower_file;
|
||||
req.lower_dentry = lower_dentry;
|
||||
req.lower_mnt = lower_mnt;
|
||||
mutex_lock(&ecryptfs_kthread_ctl.mux);
|
||||
if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
|
||||
rc = -EIO;
|
||||
|
@ -171,27 +164,14 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
|||
printk(KERN_ERR "%s: We are in the middle of shutting down; "
|
||||
"aborting privileged request to open lower file\n",
|
||||
__func__);
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
list_add_tail(&req->kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
|
||||
list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
|
||||
mutex_unlock(&ecryptfs_kthread_ctl.mux);
|
||||
wake_up(&ecryptfs_kthread_ctl.wait);
|
||||
wait_event(req->wait, (req->flags != 0));
|
||||
mutex_lock(&req->mux);
|
||||
BUG_ON(req->flags == 0);
|
||||
if (req->flags & ECRYPTFS_REQ_DROPPED
|
||||
|| req->flags & ECRYPTFS_REQ_ZOMBIE) {
|
||||
rc = -EIO;
|
||||
printk(KERN_WARNING "%s: Privileged open request dropped\n",
|
||||
__func__);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (IS_ERR(*req->lower_file))
|
||||
rc = PTR_ERR(*req->lower_file);
|
||||
out_unlock:
|
||||
mutex_unlock(&req->mux);
|
||||
out_free:
|
||||
kmem_cache_free(ecryptfs_open_req_cache, req);
|
||||
wait_for_completion(&req.done);
|
||||
if (IS_ERR(*lower_file))
|
||||
rc = PTR_ERR(*lower_file);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -681,11 +681,6 @@ static struct ecryptfs_cache_info {
|
|||
.name = "ecryptfs_key_tfm_cache",
|
||||
.size = sizeof(struct ecryptfs_key_tfm),
|
||||
},
|
||||
{
|
||||
.cache = &ecryptfs_open_req_cache,
|
||||
.name = "ecryptfs_open_req_cache",
|
||||
.size = sizeof(struct ecryptfs_open_req),
|
||||
},
|
||||
};
|
||||
|
||||
static void ecryptfs_free_kmem_caches(void)
|
||||
|
|
Loading…
Reference in a new issue