diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-25 03:38:56 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-22 16:01:02 -0400 |
commit | 3b8b487114c95ef6db5fef708ef69bfb5209014e (patch) | |
tree | c5216f4440c67582c17287ca43ff7a3edf17e733 | |
parent | 8fc37ec54cd8e37193b0d42809b785ff19661c34 (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.h | 14 | ||||
-rw-r--r-- | fs/ecryptfs/kthread.c | 72 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 5 |
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; | |||
550 | extern struct kmem_cache *ecryptfs_key_sig_cache; | 550 | extern struct kmem_cache *ecryptfs_key_sig_cache; |
551 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; | 551 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; |
552 | extern struct kmem_cache *ecryptfs_key_tfm_cache; | 552 | extern struct kmem_cache *ecryptfs_key_tfm_cache; |
553 | extern struct kmem_cache *ecryptfs_open_req_cache; | ||
554 | |||
555 | struct 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 | ||
568 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, | 554 | struct 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 | ||
30 | struct kmem_cache *ecryptfs_open_req_cache; | 30 | struct 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 | ||
32 | static struct ecryptfs_kthread_ctl { | 38 | static 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); | ||
191 | out_unlock: | ||
192 | mutex_unlock(&req->mux); | ||
193 | out_free: | ||
194 | kmem_cache_free(ecryptfs_open_req_cache, req); | ||
195 | out: | 175 | out: |
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 | ||
691 | static void ecryptfs_free_kmem_caches(void) | 686 | static void ecryptfs_free_kmem_caches(void) |