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) |
