diff options
Diffstat (limited to 'fs/ecryptfs/file.c')
| -rw-r--r-- | fs/ecryptfs/file.c | 90 | 
1 files changed, 40 insertions, 50 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 2b17f2f9b121..44ce5c6a541d 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -138,29 +138,50 @@ out:  	return rc;  } -static void ecryptfs_vma_close(struct vm_area_struct *vma) -{ -	filemap_write_and_wait(vma->vm_file->f_mapping); -} - -static const struct vm_operations_struct ecryptfs_file_vm_ops = { -	.close		= ecryptfs_vma_close, -	.fault		= filemap_fault, -}; +struct kmem_cache *ecryptfs_file_info_cache; -static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) +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; -	rc = generic_file_mmap(file, vma); +	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) -		vma->vm_ops = &ecryptfs_file_vm_ops; +		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;  } -struct kmem_cache *ecryptfs_file_info_cache; -  /**   * ecryptfs_open   * @inode: inode speciying file to open @@ -236,32 +257,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)); @@ -292,15 +290,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file)  static int  ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)  { -	int rc = 0; - -	rc = generic_file_fsync(file, start, end, datasync); -	if (rc) -		goto out; -	rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end, -			     datasync); -out: -	return rc; +	return vfs_fsync(ecryptfs_file_to_lower(file), datasync);  }  static int ecryptfs_fasync(int fd, struct file *file, int flag) @@ -369,7 +359,7 @@ const struct file_operations ecryptfs_main_fops = {  #ifdef CONFIG_COMPAT  	.compat_ioctl = ecryptfs_compat_ioctl,  #endif -	.mmap = ecryptfs_file_mmap, +	.mmap = generic_file_mmap,  	.open = ecryptfs_open,  	.flush = ecryptfs_flush,  	.release = ecryptfs_release,  | 
