diff options
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/dentry.c | 20 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 14 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 9 | ||||
-rw-r--r-- | fs/ecryptfs/kthread.c | 73 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 8 |
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 | */ |
45 | static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 45 | static 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; | |||
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/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 | */ |
249 | static int | 248 | static int |
250 | ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | 249 | ecryptfs_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); | ||
275 | out: | 274 | out: |
276 | return rc; | 275 | return rc; |
277 | } | 276 | } |
@@ -374,7 +373,7 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry, | |||
374 | */ | 373 | */ |
375 | static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | 374 | static 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 | ||
30 | struct kmem_cache *ecryptfs_open_req_cache; | 30 | struct 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 | ||
32 | static struct ecryptfs_kthread_ctl { | 37 | static 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); | ||
191 | out_unlock: | ||
192 | mutex_unlock(&req->mux); | ||
193 | out_free: | ||
194 | kmem_cache_free(ecryptfs_open_req_cache, req); | ||
195 | out: | 170 | out: |
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 | ||
692 | static void ecryptfs_free_kmem_caches(void) | 686 | static void ecryptfs_free_kmem_caches(void) |