|
@@ -161,6 +161,48 @@ static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
|
|
|
|
|
struct kmem_cache *ecryptfs_file_info_cache;
|
|
|
|
|
|
+static int read_or_initialize_metadata(struct dentry *dentry)
|
|
|
+{
|
|
|
+ struct inode *inode = dentry->d_inode;
|
|
|
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
|
|
|
+ struct ecryptfs_crypt_stat *crypt_stat;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
|
|
|
+ mount_crypt_stat = &ecryptfs_superblock_to_private(
|
|
|
+ inode->i_sb)->mount_crypt_stat;
|
|
|
+ mutex_lock(&crypt_stat->cs_mutex);
|
|
|
+
|
|
|
+ if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED &&
|
|
|
+ crypt_stat->flags & ECRYPTFS_KEY_VALID) {
|
|
|
+ rc = 0;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = ecryptfs_read_metadata(dentry);
|
|
|
+ if (!rc)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) {
|
|
|
+ crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
|
|
|
+ | ECRYPTFS_ENCRYPTED);
|
|
|
+ rc = 0;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) &&
|
|
|
+ !i_size_read(ecryptfs_inode_to_lower(inode))) {
|
|
|
+ rc = ecryptfs_initialize_file(dentry, inode);
|
|
|
+ if (!rc)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = -EIO;
|
|
|
+out:
|
|
|
+ mutex_unlock(&crypt_stat->cs_mutex);
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* ecryptfs_open
|
|
|
* @inode: inode speciying file to open
|
|
@@ -236,32 +278,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
|
|
|
rc = 0;
|
|
|
goto out;
|
|
|
}
|
|
|
- mutex_lock(&crypt_stat->cs_mutex);
|
|
|
- if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
|
|
|
- || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
|
|
|
- rc = ecryptfs_read_metadata(ecryptfs_dentry);
|
|
|
- if (rc) {
|
|
|
- ecryptfs_printk(KERN_DEBUG,
|
|
|
- "Valid headers not found\n");
|
|
|
- if (!(mount_crypt_stat->flags
|
|
|
- & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
|
|
|
- rc = -EIO;
|
|
|
- printk(KERN_WARNING "Either the lower file "
|
|
|
- "is not in a valid eCryptfs format, "
|
|
|
- "or the key could not be retrieved. "
|
|
|
- "Plaintext passthrough mode is not "
|
|
|
- "enabled; returning -EIO\n");
|
|
|
- mutex_unlock(&crypt_stat->cs_mutex);
|
|
|
- goto out_put;
|
|
|
- }
|
|
|
- rc = 0;
|
|
|
- crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
|
|
|
- | ECRYPTFS_ENCRYPTED);
|
|
|
- mutex_unlock(&crypt_stat->cs_mutex);
|
|
|
- goto out;
|
|
|
- }
|
|
|
- }
|
|
|
- mutex_unlock(&crypt_stat->cs_mutex);
|
|
|
+ rc = read_or_initialize_metadata(ecryptfs_dentry);
|
|
|
+ if (rc)
|
|
|
+ goto out_put;
|
|
|
ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = "
|
|
|
"[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino,
|
|
|
(unsigned long long)i_size_read(inode));
|