diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 6 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 14 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 6 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 29 |
4 files changed, 42 insertions, 13 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index b4a0cccfdd7c..b0727f91454e 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -235,6 +235,7 @@ struct ecryptfs_crypt_stat { | |||
235 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 | 235 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 |
236 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 | 236 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 |
237 | #define ECRYPTFS_KEY_SET 0x00000400 | 237 | #define ECRYPTFS_KEY_SET 0x00000400 |
238 | #define ECRYPTFS_DELAY_PERSISTENT 0x00000800 | ||
238 | u32 flags; | 239 | u32 flags; |
239 | unsigned int file_version; | 240 | unsigned int file_version; |
240 | size_t iv_bytes; | 241 | size_t iv_bytes; |
@@ -574,9 +575,11 @@ struct ecryptfs_open_req { | |||
574 | struct list_head kthread_ctl_list; | 575 | struct list_head kthread_ctl_list; |
575 | }; | 576 | }; |
576 | 577 | ||
578 | #define ECRYPTFS_INTERPOSE_FLAG_D_ADD 0x00000001 | ||
579 | #define ECRYPTFS_INTERPOSE_FLAG_DELAY_PERSISTENT_FILE 0x00000002 | ||
577 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 580 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
578 | struct dentry *this_dentry, struct super_block *sb, | 581 | struct dentry *this_dentry, struct super_block *sb, |
579 | int flag); | 582 | u32 flags); |
580 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); | 583 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); |
581 | int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, | 584 | int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, |
582 | const char *name, int length, | 585 | const char *name, int length, |
@@ -709,5 +712,6 @@ void ecryptfs_destroy_kthread(void); | |||
709 | int ecryptfs_privileged_open(struct file **lower_file, | 712 | int ecryptfs_privileged_open(struct file **lower_file, |
710 | struct dentry *lower_dentry, | 713 | struct dentry *lower_dentry, |
711 | struct vfsmount *lower_mnt); | 714 | struct vfsmount *lower_mnt); |
715 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | ||
712 | 716 | ||
713 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 717 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index f0be29051528..2c2d60df3f60 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -199,6 +199,20 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
199 | "file must hence be opened RO\n", __func__); | 199 | "file must hence be opened RO\n", __func__); |
200 | goto out; | 200 | goto out; |
201 | } | 201 | } |
202 | if (!ecryptfs_inode_to_private(inode)->lower_file) { | ||
203 | BUG_ON(!(crypt_stat->flags & ECRYPTFS_DELAY_PERSISTENT)); | ||
204 | mutex_lock(&crypt_stat->cs_mutex); | ||
205 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
206 | mutex_unlock(&crypt_stat->cs_mutex); | ||
207 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | ||
208 | if (rc) { | ||
209 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
210 | "the persistent file for the dentry with name " | ||
211 | "[%s]; rc = [%d]\n", __func__, | ||
212 | ecryptfs_dentry->d_name.name, rc); | ||
213 | goto out; | ||
214 | } | ||
215 | } | ||
202 | ecryptfs_set_file_lower( | 216 | ecryptfs_set_file_lower( |
203 | file, ecryptfs_inode_to_private(inode)->lower_file); | 217 | file, ecryptfs_inode_to_private(inode)->lower_file); |
204 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 218 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 7315547193ea..26090878c930 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -308,7 +308,8 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
308 | d_add(dentry, NULL); | 308 | d_add(dentry, NULL); |
309 | goto out; | 309 | goto out; |
310 | } | 310 | } |
311 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 1); | 311 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, |
312 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | ||
312 | if (rc) { | 313 | if (rc) { |
313 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); | 314 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); |
314 | goto out_dput; | 315 | goto out_dput; |
@@ -537,7 +538,8 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
537 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); | 538 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); |
538 | if (rc || !lower_dentry->d_inode) | 539 | if (rc || !lower_dentry->d_inode) |
539 | goto out; | 540 | goto out; |
540 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 541 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, |
542 | ECRYPTFS_INTERPOSE_FLAG_DELAY_PERSISTENT_FILE); | ||
541 | if (rc) | 543 | if (rc) |
542 | goto out; | 544 | goto out; |
543 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 545 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 10475d93ff53..ee4f84b20410 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -117,7 +117,7 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
117 | * | 117 | * |
118 | * Returns zero on success; non-zero otherwise | 118 | * Returns zero on success; non-zero otherwise |
119 | */ | 119 | */ |
120 | static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 120 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) |
121 | { | 121 | { |
122 | struct ecryptfs_inode_info *inode_info = | 122 | struct ecryptfs_inode_info *inode_info = |
123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
@@ -149,14 +149,14 @@ static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
149 | * @lower_dentry: Existing dentry in the lower filesystem | 149 | * @lower_dentry: Existing dentry in the lower filesystem |
150 | * @dentry: ecryptfs' dentry | 150 | * @dentry: ecryptfs' dentry |
151 | * @sb: ecryptfs's super_block | 151 | * @sb: ecryptfs's super_block |
152 | * @flag: If set to true, then d_add is called, else d_instantiate is called | 152 | * @flags: flags to govern behavior of interpose procedure |
153 | * | 153 | * |
154 | * Interposes upper and lower dentries. | 154 | * Interposes upper and lower dentries. |
155 | * | 155 | * |
156 | * Returns zero on success; non-zero otherwise | 156 | * Returns zero on success; non-zero otherwise |
157 | */ | 157 | */ |
158 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | 158 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, |
159 | struct super_block *sb, int flag) | 159 | struct super_block *sb, u32 flags) |
160 | { | 160 | { |
161 | struct inode *lower_inode; | 161 | struct inode *lower_inode; |
162 | struct inode *inode; | 162 | struct inode *inode; |
@@ -193,7 +193,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
193 | init_special_inode(inode, lower_inode->i_mode, | 193 | init_special_inode(inode, lower_inode->i_mode, |
194 | lower_inode->i_rdev); | 194 | lower_inode->i_rdev); |
195 | dentry->d_op = &ecryptfs_dops; | 195 | dentry->d_op = &ecryptfs_dops; |
196 | if (flag) | 196 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) |
197 | d_add(dentry, inode); | 197 | d_add(dentry, inode); |
198 | else | 198 | else |
199 | d_instantiate(dentry, inode); | 199 | d_instantiate(dentry, inode); |
@@ -201,12 +201,21 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
201 | /* This size will be overwritten for real files w/ headers and | 201 | /* This size will be overwritten for real files w/ headers and |
202 | * other metadata */ | 202 | * other metadata */ |
203 | fsstack_copy_inode_size(inode, lower_inode); | 203 | fsstack_copy_inode_size(inode, lower_inode); |
204 | rc = ecryptfs_init_persistent_file(dentry); | 204 | if (!(flags & ECRYPTFS_INTERPOSE_FLAG_DELAY_PERSISTENT_FILE)) { |
205 | if (rc) { | 205 | rc = ecryptfs_init_persistent_file(dentry); |
206 | printk(KERN_ERR "%s: Error attempting to initialize the " | 206 | if (rc) { |
207 | "persistent file for the dentry with name [%s]; " | 207 | printk(KERN_ERR "%s: Error attempting to initialize " |
208 | "rc = [%d]\n", __func__, dentry->d_name.name, rc); | 208 | "the persistent file for the dentry with name " |
209 | goto out; | 209 | "[%s]; rc = [%d]\n", __func__, |
210 | dentry->d_name.name, rc); | ||
211 | goto out; | ||
212 | } | ||
213 | } else { | ||
214 | struct ecryptfs_inode_info *inode_info = | ||
215 | ecryptfs_inode_to_private(dentry->d_inode); | ||
216 | |||
217 | inode_info->lower_file = NULL; | ||
218 | inode_info->crypt_stat.flags |= ECRYPTFS_DELAY_PERSISTENT; | ||
210 | } | 219 | } |
211 | out: | 220 | out: |
212 | return rc; | 221 | return rc; |