|
@@ -168,19 +168,18 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
|
|
|
"context; rc = [%d]\n", rc);
|
|
|
goto out;
|
|
|
}
|
|
|
- rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
|
|
|
+ rc = ecryptfs_get_lower_file(ecryptfs_dentry);
|
|
|
if (rc) {
|
|
|
printk(KERN_ERR "%s: Error attempting to initialize "
|
|
|
- "the persistent file for the dentry with name "
|
|
|
+ "the lower file for the dentry with name "
|
|
|
"[%s]; rc = [%d]\n", __func__,
|
|
|
ecryptfs_dentry->d_name.name, rc);
|
|
|
goto out;
|
|
|
}
|
|
|
rc = ecryptfs_write_metadata(ecryptfs_dentry);
|
|
|
- if (rc) {
|
|
|
+ if (rc)
|
|
|
printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ ecryptfs_put_lower_file(ecryptfs_dentry->d_inode);
|
|
|
out:
|
|
|
return rc;
|
|
|
}
|
|
@@ -226,11 +225,9 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
|
|
|
struct dentry *lower_dir_dentry;
|
|
|
struct vfsmount *lower_mnt;
|
|
|
struct inode *lower_inode;
|
|
|
- struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
|
|
|
struct ecryptfs_crypt_stat *crypt_stat;
|
|
|
char *page_virt = NULL;
|
|
|
- u64 file_size;
|
|
|
- int rc = 0;
|
|
|
+ int put_lower = 0, rc = 0;
|
|
|
|
|
|
lower_dir_dentry = lower_dentry->d_parent;
|
|
|
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(
|
|
@@ -277,14 +274,15 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
|
|
|
rc = -ENOMEM;
|
|
|
goto out;
|
|
|
}
|
|
|
- rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
|
|
|
+ rc = ecryptfs_get_lower_file(ecryptfs_dentry);
|
|
|
if (rc) {
|
|
|
printk(KERN_ERR "%s: Error attempting to initialize "
|
|
|
- "the persistent file for the dentry with name "
|
|
|
+ "the lower file for the dentry with name "
|
|
|
"[%s]; rc = [%d]\n", __func__,
|
|
|
ecryptfs_dentry->d_name.name, rc);
|
|
|
goto out_free_kmem;
|
|
|
}
|
|
|
+ put_lower = 1;
|
|
|
crypt_stat = &ecryptfs_inode_to_private(
|
|
|
ecryptfs_dentry->d_inode)->crypt_stat;
|
|
|
/* TODO: lock for crypt_stat comparison */
|
|
@@ -302,18 +300,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
|
|
|
}
|
|
|
crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
|
|
|
}
|
|
|
- mount_crypt_stat = &ecryptfs_superblock_to_private(
|
|
|
- ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
|
|
- if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
|
|
|
- if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
|
|
- file_size = (crypt_stat->metadata_size
|
|
|
- + i_size_read(lower_dentry->d_inode));
|
|
|
- else
|
|
|
- file_size = i_size_read(lower_dentry->d_inode);
|
|
|
- } else {
|
|
|
- file_size = get_unaligned_be64(page_virt);
|
|
|
- }
|
|
|
- i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size);
|
|
|
+ ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
|
|
|
out_free_kmem:
|
|
|
kmem_cache_free(ecryptfs_header_cache_2, page_virt);
|
|
|
goto out;
|
|
@@ -322,6 +309,8 @@ out_put:
|
|
|
mntput(lower_mnt);
|
|
|
d_drop(ecryptfs_dentry);
|
|
|
out:
|
|
|
+ if (put_lower)
|
|
|
+ ecryptfs_put_lower_file(ecryptfs_dentry->d_inode);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -538,8 +527,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
|
|
|
dget(lower_dentry);
|
|
|
rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
|
|
|
dput(lower_dentry);
|
|
|
- if (!rc)
|
|
|
- d_delete(lower_dentry);
|
|
|
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
|
|
|
dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
|
|
|
unlock_dir(lower_dir_dentry);
|
|
@@ -610,8 +597,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
|
fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
|
|
|
out_lock:
|
|
|
unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
|
|
|
- dput(lower_new_dentry->d_parent);
|
|
|
- dput(lower_old_dentry->d_parent);
|
|
|
+ dput(lower_new_dir_dentry);
|
|
|
+ dput(lower_old_dir_dentry);
|
|
|
dput(lower_new_dentry);
|
|
|
dput(lower_old_dentry);
|
|
|
return rc;
|
|
@@ -759,8 +746,11 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
|
|
|
|
|
if (unlikely((ia->ia_size == i_size))) {
|
|
|
lower_ia->ia_valid &= ~ATTR_SIZE;
|
|
|
- goto out;
|
|
|
+ return 0;
|
|
|
}
|
|
|
+ rc = ecryptfs_get_lower_file(dentry);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
|
|
|
/* Switch on growing or shrinking file */
|
|
|
if (ia->ia_size > i_size) {
|
|
@@ -838,6 +828,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
|
|
lower_ia->ia_valid &= ~ATTR_SIZE;
|
|
|
}
|
|
|
out:
|
|
|
+ ecryptfs_put_lower_file(inode);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -913,7 +904,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
|
|
|
|
|
|
mount_crypt_stat = &ecryptfs_superblock_to_private(
|
|
|
dentry->d_sb)->mount_crypt_stat;
|
|
|
+ rc = ecryptfs_get_lower_file(dentry);
|
|
|
+ if (rc) {
|
|
|
+ mutex_unlock(&crypt_stat->cs_mutex);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
rc = ecryptfs_read_metadata(dentry);
|
|
|
+ ecryptfs_put_lower_file(inode);
|
|
|
if (rc) {
|
|
|
if (!(mount_crypt_stat->flags
|
|
|
& ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
|
|
@@ -927,10 +924,17 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
|
|
|
goto out;
|
|
|
}
|
|
|
rc = 0;
|
|
|
- crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
|
|
|
+ crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
|
|
|
+ | ECRYPTFS_ENCRYPTED);
|
|
|
}
|
|
|
}
|
|
|
mutex_unlock(&crypt_stat->cs_mutex);
|
|
|
+ if (S_ISREG(inode->i_mode)) {
|
|
|
+ rc = filemap_write_and_wait(inode->i_mapping);
|
|
|
+ if (rc)
|
|
|
+ goto out;
|
|
|
+ fsstack_copy_attr_all(inode, lower_inode);
|
|
|
+ }
|
|
|
memcpy(&lower_ia, ia, sizeof(lower_ia));
|
|
|
if (ia->ia_valid & ATTR_FILE)
|
|
|
lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
|