aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r--fs/ecryptfs/dentry.c20
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h14
-rw-r--r--fs/ecryptfs/inode.c9
-rw-r--r--fs/ecryptfs/kthread.c73
-rw-r--r--fs/ecryptfs/main.c8
5 files changed, 33 insertions, 91 deletions
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index 534c1d46e69e..1b5d9af937df 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -32,7 +32,7 @@
32/** 32/**
33 * ecryptfs_d_revalidate - revalidate an ecryptfs dentry 33 * ecryptfs_d_revalidate - revalidate an ecryptfs dentry
34 * @dentry: The ecryptfs dentry 34 * @dentry: The ecryptfs dentry
35 * @nd: The associated nameidata 35 * @flags: lookup flags
36 * 36 *
37 * Called when the VFS needs to revalidate a dentry. This 37 * Called when the VFS needs to revalidate a dentry. This
38 * is called whenever a name lookup finds a dentry in the 38 * is called whenever a name lookup finds a dentry in the
@@ -42,32 +42,20 @@
42 * Returns 1 if valid, 0 otherwise. 42 * Returns 1 if valid, 0 otherwise.
43 * 43 *
44 */ 44 */
45static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) 45static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
46{ 46{
47 struct dentry *lower_dentry; 47 struct dentry *lower_dentry;
48 struct vfsmount *lower_mnt; 48 struct vfsmount *lower_mnt;
49 struct dentry *dentry_save = NULL;
50 struct vfsmount *vfsmount_save = NULL;
51 int rc = 1; 49 int rc = 1;
52 50
53 if (nd && nd->flags & LOOKUP_RCU) 51 if (flags & LOOKUP_RCU)
54 return -ECHILD; 52 return -ECHILD;
55 53
56 lower_dentry = ecryptfs_dentry_to_lower(dentry); 54 lower_dentry = ecryptfs_dentry_to_lower(dentry);
57 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); 55 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
58 if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) 56 if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
59 goto out; 57 goto out;
60 if (nd) { 58 rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
61 dentry_save = nd->path.dentry;
62 vfsmount_save = nd->path.mnt;
63 nd->path.dentry = lower_dentry;
64 nd->path.mnt = lower_mnt;
65 }
66 rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
67 if (nd) {
68 nd->path.dentry = dentry_save;
69 nd->path.mnt = vfsmount_save;
70 }
71 if (dentry->d_inode) { 59 if (dentry->d_inode) {
72 struct inode *lower_inode = 60 struct inode *lower_inode =
73 ecryptfs_inode_to_lower(dentry->d_inode); 61 ecryptfs_inode_to_lower(dentry->d_inode);
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/inode.c b/fs/ecryptfs/inode.c
index a07441a0a878..ffa2be57804d 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -173,7 +173,7 @@ ecryptfs_do_create(struct inode *directory_inode,
173 inode = ERR_CAST(lower_dir_dentry); 173 inode = ERR_CAST(lower_dir_dentry);
174 goto out; 174 goto out;
175 } 175 }
176 rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, NULL); 176 rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, true);
177 if (rc) { 177 if (rc) {
178 printk(KERN_ERR "%s: Failure to create dentry in lower fs; " 178 printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
179 "rc = [%d]\n", __func__, rc); 179 "rc = [%d]\n", __func__, rc);
@@ -240,7 +240,6 @@ out:
240 * @dir: The inode of the directory in which to create the file. 240 * @dir: The inode of the directory in which to create the file.
241 * @dentry: The eCryptfs dentry 241 * @dentry: The eCryptfs dentry
242 * @mode: The mode of the new file. 242 * @mode: The mode of the new file.
243 * @nd: nameidata
244 * 243 *
245 * Creates a new file. 244 * Creates a new file.
246 * 245 *
@@ -248,7 +247,7 @@ out:
248 */ 247 */
249static int 248static int
250ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, 249ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
251 umode_t mode, struct nameidata *nd) 250 umode_t mode, bool excl)
252{ 251{
253 struct inode *ecryptfs_inode; 252 struct inode *ecryptfs_inode;
254 int rc; 253 int rc;
@@ -270,8 +269,8 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
270 iput(ecryptfs_inode); 269 iput(ecryptfs_inode);
271 goto out; 270 goto out;
272 } 271 }
273 d_instantiate(ecryptfs_dentry, ecryptfs_inode);
274 unlock_new_inode(ecryptfs_inode); 272 unlock_new_inode(ecryptfs_inode);
273 d_instantiate(ecryptfs_dentry, ecryptfs_inode);
275out: 274out:
276 return rc; 275 return rc;
277} 276}
@@ -374,7 +373,7 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry,
374 */ 373 */
375static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, 374static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
376 struct dentry *ecryptfs_dentry, 375 struct dentry *ecryptfs_dentry,
377 struct nameidata *ecryptfs_nd) 376 unsigned int flags)
378{ 377{
379 char *encrypted_and_encoded_name = NULL; 378 char *encrypted_and_encoded_name = NULL;
380 size_t encrypted_and_encoded_name_size; 379 size_t encrypted_and_encoded_name_size;
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index 0dbe58a8b172..809e67d05ca3 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -27,7 +27,12 @@
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 path path;
33 struct completion done;
34 struct list_head kthread_ctl_list;
35};
31 36
32static struct ecryptfs_kthread_ctl { 37static struct ecryptfs_kthread_ctl {
33#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001 38#define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
@@ -67,18 +72,10 @@ static int ecryptfs_threadfn(void *ignored)
67 req = list_first_entry(&ecryptfs_kthread_ctl.req_list, 72 req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
68 struct ecryptfs_open_req, 73 struct ecryptfs_open_req,
69 kthread_ctl_list); 74 kthread_ctl_list);
70 mutex_lock(&req->mux);
71 list_del(&req->kthread_ctl_list); 75 list_del(&req->kthread_ctl_list);
72 if (!(req->flags & ECRYPTFS_REQ_ZOMBIE)) { 76 *req->lower_file = dentry_open(&req->path,
73 dget(req->lower_dentry); 77 (O_RDWR | O_LARGEFILE), current_cred());
74 mntget(req->lower_mnt); 78 complete(&req->done);
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);
82 } 79 }
83 mutex_unlock(&ecryptfs_kthread_ctl.mux); 80 mutex_unlock(&ecryptfs_kthread_ctl.mux);
84 } 81 }
@@ -111,10 +108,9 @@ void ecryptfs_destroy_kthread(void)
111 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE; 108 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
112 list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list, 109 list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list,
113 kthread_ctl_list) { 110 kthread_ctl_list) {
114 mutex_lock(&req->mux); 111 list_del(&req->kthread_ctl_list);
115 req->flags |= ECRYPTFS_REQ_ZOMBIE; 112 *req->lower_file = ERR_PTR(-EIO);
116 wake_up(&req->wait); 113 complete(&req->done);
117 mutex_unlock(&req->mux);
118 } 114 }
119 mutex_unlock(&ecryptfs_kthread_ctl.mux); 115 mutex_unlock(&ecryptfs_kthread_ctl.mux);
120 kthread_stop(ecryptfs_kthread); 116 kthread_stop(ecryptfs_kthread);
@@ -136,34 +132,26 @@ int ecryptfs_privileged_open(struct file **lower_file,
136 struct vfsmount *lower_mnt, 132 struct vfsmount *lower_mnt,
137 const struct cred *cred) 133 const struct cred *cred)
138{ 134{
139 struct ecryptfs_open_req *req; 135 struct ecryptfs_open_req req;
140 int flags = O_LARGEFILE; 136 int flags = O_LARGEFILE;
141 int rc = 0; 137 int rc = 0;
142 138
139 init_completion(&req.done);
140 req.lower_file = lower_file;
141 req.path.dentry = lower_dentry;
142 req.path.mnt = lower_mnt;
143
143 /* Corresponding dput() and mntput() are done when the 144 /* Corresponding dput() and mntput() are done when the
144 * lower file is fput() when all eCryptfs files for the inode are 145 * lower file is fput() when all eCryptfs files for the inode are
145 * released. */ 146 * released. */
146 dget(lower_dentry);
147 mntget(lower_mnt);
148 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; 147 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
149 (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); 148 (*lower_file) = dentry_open(&req.path, flags, cred);
150 if (!IS_ERR(*lower_file)) 149 if (!IS_ERR(*lower_file))
151 goto out; 150 goto out;
152 if ((flags & O_ACCMODE) == O_RDONLY) { 151 if ((flags & O_ACCMODE) == O_RDONLY) {
153 rc = PTR_ERR((*lower_file)); 152 rc = PTR_ERR((*lower_file));
154 goto out; 153 goto out;
155 } 154 }
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;
167 mutex_lock(&ecryptfs_kthread_ctl.mux); 155 mutex_lock(&ecryptfs_kthread_ctl.mux);
168 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { 156 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
169 rc = -EIO; 157 rc = -EIO;
@@ -171,27 +159,14 @@ int ecryptfs_privileged_open(struct file **lower_file,
171 printk(KERN_ERR "%s: We are in the middle of shutting down; " 159 printk(KERN_ERR "%s: We are in the middle of shutting down; "
172 "aborting privileged request to open lower file\n", 160 "aborting privileged request to open lower file\n",
173 __func__); 161 __func__);
174 goto out_free; 162 goto out;
175 } 163 }
176 list_add_tail(&req->kthread_ctl_list, &ecryptfs_kthread_ctl.req_list); 164 list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
177 mutex_unlock(&ecryptfs_kthread_ctl.mux); 165 mutex_unlock(&ecryptfs_kthread_ctl.mux);
178 wake_up(&ecryptfs_kthread_ctl.wait); 166 wake_up(&ecryptfs_kthread_ctl.wait);
179 wait_event(req->wait, (req->flags != 0)); 167 wait_for_completion(&req.done);
180 mutex_lock(&req->mux); 168 if (IS_ERR(*lower_file))
181 BUG_ON(req->flags == 0); 169 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: 170out:
196 return rc; 171 return rc;
197} 172}
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 68954937a071..1c0b3b6b75c6 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -499,13 +499,12 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
499 goto out; 499 goto out;
500 } 500 }
501 501
502 s = sget(fs_type, NULL, set_anon_super, NULL); 502 s = sget(fs_type, NULL, set_anon_super, flags, NULL);
503 if (IS_ERR(s)) { 503 if (IS_ERR(s)) {
504 rc = PTR_ERR(s); 504 rc = PTR_ERR(s);
505 goto out; 505 goto out;
506 } 506 }
507 507
508 s->s_flags = flags;
509 rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); 508 rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY);
510 if (rc) 509 if (rc)
511 goto out1; 510 goto out1;
@@ -682,11 +681,6 @@ static struct ecryptfs_cache_info {
682 .name = "ecryptfs_key_tfm_cache", 681 .name = "ecryptfs_key_tfm_cache",
683 .size = sizeof(struct ecryptfs_key_tfm), 682 .size = sizeof(struct ecryptfs_key_tfm),
684 }, 683 },
685 {
686 .cache = &ecryptfs_open_req_cache,
687 .name = "ecryptfs_open_req_cache",
688 .size = sizeof(struct ecryptfs_open_req),
689 },
690}; 684};
691 685
692static void ecryptfs_free_kmem_caches(void) 686static void ecryptfs_free_kmem_caches(void)