aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-06-25 03:38:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-22 16:01:02 -0400
commit3b8b487114c95ef6db5fef708ef69bfb5209014e (patch)
treec5216f4440c67582c17287ca43ff7a3edf17e733
parent8fc37ec54cd8e37193b0d42809b785ff19661c34 (diff)
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>
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h14
-rw-r--r--fs/ecryptfs/kthread.c72
-rw-r--r--fs/ecryptfs/main.c5
3 files changed, 26 insertions, 65 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 867b64c5d84f..989e034f02bd 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -550,20 +550,6 @@ extern struct kmem_cache *ecryptfs_key_record_cache;
550extern struct kmem_cache *ecryptfs_key_sig_cache; 550extern struct kmem_cache *ecryptfs_key_sig_cache;
551extern struct kmem_cache *ecryptfs_global_auth_tok_cache; 551extern struct kmem_cache *ecryptfs_global_auth_tok_cache;
552extern struct kmem_cache *ecryptfs_key_tfm_cache; 552extern struct kmem_cache *ecryptfs_key_tfm_cache;
553extern struct kmem_cache *ecryptfs_open_req_cache;
554
555struct ecryptfs_open_req {
556#define ECRYPTFS_REQ_PROCESSED 0x00000001
557#define ECRYPTFS_REQ_DROPPED 0x00000002
558#define ECRYPTFS_REQ_ZOMBIE 0x00000004
559 u32 flags;
560 struct file **lower_file;
561 struct dentry *lower_dentry;
562 struct vfsmount *lower_mnt;
563 wait_queue_head_t wait;
564 struct mutex mux;
565 struct list_head kthread_ctl_list;
566};
567 553
568struct inode *ecryptfs_get_inode(struct inode *lower_inode, 554struct inode *ecryptfs_get_inode(struct inode *lower_inode,
569 struct super_block *sb); 555 struct super_block *sb);
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index 0dbe58a8b172..c7d199dc7d24 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -27,7 +27,13 @@
27#include <linux/mount.h> 27#include <linux/mount.h>
28#include "ecryptfs_kernel.h" 28#include "ecryptfs_kernel.h"
29 29
30struct kmem_cache *ecryptfs_open_req_cache; 30struct ecryptfs_open_req {
31 struct file **lower_file;
32 struct dentry *lower_dentry;
33 struct vfsmount *lower_mnt;
34 struct completion done;
35 struct list_head kthread_ctl_list;
36};
31 37
32static struct ecryptfs_kthread_ctl { 38static struct ecryptfs_kthread_ctl {
33#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001 39#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
@@ -67,18 +73,13 @@ static int ecryptfs_threadfn(void *ignored)
67 req = list_first_entry(&ecryptfs_kthread_ctl.req_list, 73 req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
68 struct ecryptfs_open_req, 74 struct ecryptfs_open_req,
69 kthread_ctl_list); 75 kthread_ctl_list);
70 mutex_lock(&req->mux);
71 list_del(&req->kthread_ctl_list); 76 list_del(&req->kthread_ctl_list);
72 if (!(req->flags & ECRYPTFS_REQ_ZOMBIE)) { 77 dget(req->lower_dentry);
73 dget(req->lower_dentry); 78 mntget(req->lower_mnt);
74 mntget(req->lower_mnt); 79 (*req->lower_file) = dentry_open(
75 (*req->lower_file) = dentry_open( 80 req->lower_dentry, req->lower_mnt,
76 req->lower_dentry, req->lower_mnt, 81 (O_RDWR | O_LARGEFILE), current_cred());
77 (O_RDWR | O_LARGEFILE), current_cred()); 82 complete(&req->done);
78 req->flags |= ECRYPTFS_REQ_PROCESSED;
79 }
80 wake_up(&req->wait);
81 mutex_unlock(&req->mux);
82 } 83 }
83 mutex_unlock(&ecryptfs_kthread_ctl.mux); 84 mutex_unlock(&ecryptfs_kthread_ctl.mux);
84 } 85 }
@@ -111,10 +112,9 @@ void ecryptfs_destroy_kthread(void)
111 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE; 112 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
112 list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list, 113 list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list,
113 kthread_ctl_list) { 114 kthread_ctl_list) {
114 mutex_lock(&req->mux); 115 list_del(&req->kthread_ctl_list);
115 req->flags |= ECRYPTFS_REQ_ZOMBIE; 116 *req->lower_file = ERR_PTR(-EIO);
116 wake_up(&req->wait); 117 complete(&req->done);
117 mutex_unlock(&req->mux);
118 } 118 }
119 mutex_unlock(&ecryptfs_kthread_ctl.mux); 119 mutex_unlock(&ecryptfs_kthread_ctl.mux);
120 kthread_stop(ecryptfs_kthread); 120 kthread_stop(ecryptfs_kthread);
@@ -136,7 +136,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
136 struct vfsmount *lower_mnt, 136 struct vfsmount *lower_mnt,
137 const struct cred *cred) 137 const struct cred *cred)
138{ 138{
139 struct ecryptfs_open_req *req; 139 struct ecryptfs_open_req req;
140 int flags = O_LARGEFILE; 140 int flags = O_LARGEFILE;
141 int rc = 0; 141 int rc = 0;
142 142
@@ -153,17 +153,10 @@ int ecryptfs_privileged_open(struct file **lower_file,
153 rc = PTR_ERR((*lower_file)); 153 rc = PTR_ERR((*lower_file));
154 goto out; 154 goto out;
155 } 155 }
156 req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); 156 init_completion(&req.done);
157 if (!req) { 157 req.lower_file = lower_file;
158 rc = -ENOMEM; 158 req.lower_dentry = lower_dentry;
159 goto out; 159 req.lower_mnt = lower_mnt;
160 }
161 mutex_init(&req->mux);
162 req->lower_file = lower_file;
163 req->lower_dentry = lower_dentry;
164 req->lower_mnt = lower_mnt;
165 init_waitqueue_head(&req->wait);
166 req->flags = 0;
167 mutex_lock(&ecryptfs_kthread_ctl.mux); 160 mutex_lock(&ecryptfs_kthread_ctl.mux);
168 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { 161 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
169 rc = -EIO; 162 rc = -EIO;
@@ -171,27 +164,14 @@ int ecryptfs_privileged_open(struct file **lower_file,
171 printk(KERN_ERR "%s: We are in the middle of shutting down; " 164 printk(KERN_ERR "%s: We are in the middle of shutting down; "
172 "aborting privileged request to open lower file\n", 165 "aborting privileged request to open lower file\n",
173 __func__); 166 __func__);
174 goto out_free; 167 goto out;
175 } 168 }
176 list_add_tail(&req->kthread_ctl_list, &ecryptfs_kthread_ctl.req_list); 169 list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
177 mutex_unlock(&ecryptfs_kthread_ctl.mux); 170 mutex_unlock(&ecryptfs_kthread_ctl.mux);
178 wake_up(&ecryptfs_kthread_ctl.wait); 171 wake_up(&ecryptfs_kthread_ctl.wait);
179 wait_event(req->wait, (req->flags != 0)); 172 wait_for_completion(&req.done);
180 mutex_lock(&req->mux); 173 if (IS_ERR(*lower_file))
181 BUG_ON(req->flags == 0); 174 rc = PTR_ERR(*lower_file);
182 if (req->flags & ECRYPTFS_REQ_DROPPED
183 || req->flags & ECRYPTFS_REQ_ZOMBIE) {
184 rc = -EIO;
185 printk(KERN_WARNING "%s: Privileged open request dropped\n",
186 __func__);
187 goto out_unlock;
188 }
189 if (IS_ERR(*req->lower_file))
190 rc = PTR_ERR(*req->lower_file);
191out_unlock:
192 mutex_unlock(&req->mux);
193out_free:
194 kmem_cache_free(ecryptfs_open_req_cache, req);
195out: 175out:
196 return rc; 176 return rc;
197} 177}
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 7edeb3d893c1..1c0b3b6b75c6 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -681,11 +681,6 @@ static struct ecryptfs_cache_info {
681 .name = "ecryptfs_key_tfm_cache", 681 .name = "ecryptfs_key_tfm_cache",
682 .size = sizeof(struct ecryptfs_key_tfm), 682 .size = sizeof(struct ecryptfs_key_tfm),
683 }, 683 },
684 {
685 .cache = &ecryptfs_open_req_cache,
686 .name = "ecryptfs_open_req_cache",
687 .size = sizeof(struct ecryptfs_open_req),
688 },
689}; 684};
690 685
691static void ecryptfs_free_kmem_caches(void) 686static void ecryptfs_free_kmem_caches(void)