aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/kthread.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/ecryptfs/kthread.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/ecryptfs/kthread.c')
-rw-r--r--fs/ecryptfs/kthread.c81
1 files changed, 53 insertions, 28 deletions
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index f1ea610362c..69f994a7d52 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -27,12 +27,7 @@
27#include <linux/mount.h> 27#include <linux/mount.h>
28#include "ecryptfs_kernel.h" 28#include "ecryptfs_kernel.h"
29 29
30struct ecryptfs_open_req { 30struct kmem_cache *ecryptfs_open_req_cache;
31 struct file **lower_file;
32 struct path path;
33 struct completion done;
34 struct list_head kthread_ctl_list;
35};
36 31
37static struct ecryptfs_kthread_ctl { 32static struct ecryptfs_kthread_ctl {
38#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001 33#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
@@ -72,10 +67,18 @@ static int ecryptfs_threadfn(void *ignored)
72 req = list_first_entry(&ecryptfs_kthread_ctl.req_list, 67 req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
73 struct ecryptfs_open_req, 68 struct ecryptfs_open_req,
74 kthread_ctl_list); 69 kthread_ctl_list);
70 mutex_lock(&req->mux);
75 list_del(&req->kthread_ctl_list); 71 list_del(&req->kthread_ctl_list);
76 *req->lower_file = dentry_open(&req->path, 72 if (!(req->flags & ECRYPTFS_REQ_ZOMBIE)) {
77 (O_RDWR | O_LARGEFILE), current_cred()); 73 dget(req->lower_dentry);
78 complete(&req->done); 74 mntget(req->lower_mnt);
75 (*req->lower_file) = dentry_open(
76 req->lower_dentry, req->lower_mnt,
77 (O_RDWR | O_LARGEFILE), current_cred());
78 req->flags |= ECRYPTFS_REQ_PROCESSED;
79 }
80 wake_up(&req->wait);
81 mutex_unlock(&req->mux);
79 } 82 }
80 mutex_unlock(&ecryptfs_kthread_ctl.mux); 83 mutex_unlock(&ecryptfs_kthread_ctl.mux);
81 } 84 }
@@ -102,15 +105,16 @@ int __init ecryptfs_init_kthread(void)
102 105
103void ecryptfs_destroy_kthread(void) 106void ecryptfs_destroy_kthread(void)
104{ 107{
105 struct ecryptfs_open_req *req, *tmp; 108 struct ecryptfs_open_req *req;
106 109
107 mutex_lock(&ecryptfs_kthread_ctl.mux); 110 mutex_lock(&ecryptfs_kthread_ctl.mux);
108 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE; 111 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
109 list_for_each_entry_safe(req, tmp, &ecryptfs_kthread_ctl.req_list, 112 list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list,
110 kthread_ctl_list) { 113 kthread_ctl_list) {
111 list_del(&req->kthread_ctl_list); 114 mutex_lock(&req->mux);
112 *req->lower_file = ERR_PTR(-EIO); 115 req->flags |= ECRYPTFS_REQ_ZOMBIE;
113 complete(&req->done); 116 wake_up(&req->wait);
117 mutex_unlock(&req->mux);
114 } 118 }
115 mutex_unlock(&ecryptfs_kthread_ctl.mux); 119 mutex_unlock(&ecryptfs_kthread_ctl.mux);
116 kthread_stop(ecryptfs_kthread); 120 kthread_stop(ecryptfs_kthread);
@@ -132,26 +136,34 @@ int ecryptfs_privileged_open(struct file **lower_file,
132 struct vfsmount *lower_mnt, 136 struct vfsmount *lower_mnt,
133 const struct cred *cred) 137 const struct cred *cred)
134{ 138{
135 struct ecryptfs_open_req req; 139 struct ecryptfs_open_req *req;
136 int flags = O_LARGEFILE; 140 int flags = O_LARGEFILE;
137 int rc = 0; 141 int rc = 0;
138 142
139 init_completion(&req.done);
140 req.lower_file = lower_file;
141 req.path.dentry = lower_dentry;
142 req.path.mnt = lower_mnt;
143
144 /* Corresponding dput() and mntput() are done when the 143 /* Corresponding dput() and mntput() are done when the
145 * lower file is fput() when all eCryptfs files for the inode are 144 * lower file is fput() when all eCryptfs files for the inode are
146 * released. */ 145 * released. */
146 dget(lower_dentry);
147 mntget(lower_mnt);
147 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; 148 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
148 (*lower_file) = dentry_open(&req.path, flags, cred); 149 (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred);
149 if (!IS_ERR(*lower_file)) 150 if (!IS_ERR(*lower_file))
150 goto out; 151 goto out;
151 if ((flags & O_ACCMODE) == O_RDONLY) { 152 if (flags & O_RDONLY) {
152 rc = PTR_ERR((*lower_file)); 153 rc = PTR_ERR((*lower_file));
153 goto out; 154 goto out;
154 } 155 }
156 req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
157 if (!req) {
158 rc = -ENOMEM;
159 goto out;
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;
155 mutex_lock(&ecryptfs_kthread_ctl.mux); 167 mutex_lock(&ecryptfs_kthread_ctl.mux);
156 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { 168 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
157 rc = -EIO; 169 rc = -EIO;
@@ -159,14 +171,27 @@ int ecryptfs_privileged_open(struct file **lower_file,
159 printk(KERN_ERR "%s: We are in the middle of shutting down; " 171 printk(KERN_ERR "%s: We are in the middle of shutting down; "
160 "aborting privileged request to open lower file\n", 172 "aborting privileged request to open lower file\n",
161 __func__); 173 __func__);
162 goto out; 174 goto out_free;
163 } 175 }
164 list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list); 176 list_add_tail(&req->kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
165 mutex_unlock(&ecryptfs_kthread_ctl.mux); 177 mutex_unlock(&ecryptfs_kthread_ctl.mux);
166 wake_up(&ecryptfs_kthread_ctl.wait); 178 wake_up(&ecryptfs_kthread_ctl.wait);
167 wait_for_completion(&req.done); 179 wait_event(req->wait, (req->flags != 0));
168 if (IS_ERR(*lower_file)) 180 mutex_lock(&req->mux);
169 rc = PTR_ERR(*lower_file); 181 BUG_ON(req->flags == 0);
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);
170out: 195out:
171 return rc; 196 return rc;
172} 197}