aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h2
-rw-r--r--fs/ecryptfs/file.c71
-rw-r--r--fs/ecryptfs/inode.c4
3 files changed, 49 insertions, 28 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 0deb4f24957a..9f77ff818173 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -563,6 +563,8 @@ struct ecryptfs_open_req {
563struct inode *ecryptfs_get_inode(struct inode *lower_inode, 563struct inode *ecryptfs_get_inode(struct inode *lower_inode,
564 struct super_block *sb); 564 struct super_block *sb);
565void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); 565void ecryptfs_i_size_init(const char *page_virt, struct inode *inode);
566int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
567 struct inode *ecryptfs_inode);
566int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, 568int ecryptfs_decode_and_decrypt_filename(char **decrypted_name,
567 size_t *decrypted_name_size, 569 size_t *decrypted_name_size,
568 struct dentry *ecryptfs_dentry, 570 struct dentry *ecryptfs_dentry,
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 2b17f2f9b121..baf8b0550391 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -161,6 +161,48 @@ static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma)
161 161
162struct kmem_cache *ecryptfs_file_info_cache; 162struct kmem_cache *ecryptfs_file_info_cache;
163 163
164static int read_or_initialize_metadata(struct dentry *dentry)
165{
166 struct inode *inode = dentry->d_inode;
167 struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
168 struct ecryptfs_crypt_stat *crypt_stat;
169 int rc;
170
171 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
172 mount_crypt_stat = &ecryptfs_superblock_to_private(
173 inode->i_sb)->mount_crypt_stat;
174 mutex_lock(&crypt_stat->cs_mutex);
175
176 if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED &&
177 crypt_stat->flags & ECRYPTFS_KEY_VALID) {
178 rc = 0;
179 goto out;
180 }
181
182 rc = ecryptfs_read_metadata(dentry);
183 if (!rc)
184 goto out;
185
186 if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) {
187 crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
188 | ECRYPTFS_ENCRYPTED);
189 rc = 0;
190 goto out;
191 }
192
193 if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) &&
194 !i_size_read(ecryptfs_inode_to_lower(inode))) {
195 rc = ecryptfs_initialize_file(dentry, inode);
196 if (!rc)
197 goto out;
198 }
199
200 rc = -EIO;
201out:
202 mutex_unlock(&crypt_stat->cs_mutex);
203 return rc;
204}
205
164/** 206/**
165 * ecryptfs_open 207 * ecryptfs_open
166 * @inode: inode speciying file to open 208 * @inode: inode speciying file to open
@@ -236,32 +278,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
236 rc = 0; 278 rc = 0;
237 goto out; 279 goto out;
238 } 280 }
239 mutex_lock(&crypt_stat->cs_mutex); 281 rc = read_or_initialize_metadata(ecryptfs_dentry);
240 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) 282 if (rc)
241 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { 283 goto out_put;
242 rc = ecryptfs_read_metadata(ecryptfs_dentry);
243 if (rc) {
244 ecryptfs_printk(KERN_DEBUG,
245 "Valid headers not found\n");
246 if (!(mount_crypt_stat->flags
247 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
248 rc = -EIO;
249 printk(KERN_WARNING "Either the lower file "
250 "is not in a valid eCryptfs format, "
251 "or the key could not be retrieved. "
252 "Plaintext passthrough mode is not "
253 "enabled; returning -EIO\n");
254 mutex_unlock(&crypt_stat->cs_mutex);
255 goto out_put;
256 }
257 rc = 0;
258 crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
259 | ECRYPTFS_ENCRYPTED);
260 mutex_unlock(&crypt_stat->cs_mutex);
261 goto out;
262 }
263 }
264 mutex_unlock(&crypt_stat->cs_mutex);
265 ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " 284 ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = "
266 "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, 285 "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino,
267 (unsigned long long)i_size_read(inode)); 286 (unsigned long long)i_size_read(inode));
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 65efe5fa687c..2d4143f8f5c9 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -227,8 +227,8 @@ out:
227 * 227 *
228 * Returns zero on success 228 * Returns zero on success
229 */ 229 */
230static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, 230int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
231 struct inode *ecryptfs_inode) 231 struct inode *ecryptfs_inode)
232{ 232{
233 struct ecryptfs_crypt_stat *crypt_stat = 233 struct ecryptfs_crypt_stat *crypt_stat =
234 &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; 234 &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;