[PATCH] eCryptfs: Generalize metadata read/write
Generalize the metadata reading and writing mechanisms, with two targets for now: metadata in file header and metadata in the user.ecryptfs xattr of the lower file. [akpm@osdl.org: printk warning fix] [bunk@stusta.de: make some needlessly global code static] Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
17398957aa
commit
dd2a3b7ad9
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1997-2004 Erez Zadok
|
||||
* Copyright (C) 2001-2004 Stony Brook University
|
||||
* Copyright (C) 2004-2006 International Business Machines Corp.
|
||||
* Copyright (C) 2004-2007 International Business Machines Corp.
|
||||
* Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
|
||||
* Michael C. Thompsion <mcthomps@us.ibm.com>
|
||||
*
|
||||
@@ -169,7 +169,9 @@ static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file,
|
||||
goto out;
|
||||
}
|
||||
i_size_write(inode, 0);
|
||||
ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode);
|
||||
ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, inode,
|
||||
ecryptfs_dentry,
|
||||
ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
|
||||
ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags,
|
||||
ECRYPTFS_NEW_FILE);
|
||||
out:
|
||||
@@ -225,7 +227,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
|
||||
"context\n");
|
||||
goto out_fput;
|
||||
}
|
||||
rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file);
|
||||
rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file);
|
||||
if (rc) {
|
||||
ecryptfs_printk(KERN_DEBUG, "Error writing headers\n");
|
||||
goto out_fput;
|
||||
@@ -362,32 +364,33 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
}
|
||||
/* Released in this function */
|
||||
page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2,
|
||||
GFP_USER);
|
||||
GFP_USER);
|
||||
if (!page_virt) {
|
||||
rc = -ENOMEM;
|
||||
ecryptfs_printk(KERN_ERR,
|
||||
"Cannot ecryptfs_kmalloc a page\n");
|
||||
goto out_dput;
|
||||
}
|
||||
|
||||
rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt);
|
||||
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
|
||||
if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
|
||||
ecryptfs_set_default_sizes(crypt_stat);
|
||||
rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry,
|
||||
nd->mnt);
|
||||
if (rc) {
|
||||
rc = 0;
|
||||
ecryptfs_printk(KERN_WARNING, "Error reading header region;"
|
||||
" assuming unencrypted\n");
|
||||
} else {
|
||||
if (!contains_ecryptfs_marker(page_virt
|
||||
+ ECRYPTFS_FILE_SIZE_BYTES)) {
|
||||
rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry);
|
||||
if (rc) {
|
||||
printk(KERN_DEBUG "Valid metadata not found in header "
|
||||
"region or xattr region; treating file as "
|
||||
"unencrypted\n");
|
||||
rc = 0;
|
||||
kmem_cache_free(ecryptfs_header_cache_2, page_virt);
|
||||
goto out;
|
||||
}
|
||||
memcpy(&file_size, page_virt, sizeof(file_size));
|
||||
file_size = be64_to_cpu(file_size);
|
||||
i_size_write(dentry->d_inode, (loff_t)file_size);
|
||||
crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
|
||||
}
|
||||
memcpy(&file_size, page_virt, sizeof(file_size));
|
||||
file_size = be64_to_cpu(file_size);
|
||||
i_size_write(dentry->d_inode, (loff_t)file_size);
|
||||
kmem_cache_free(ecryptfs_header_cache_2, page_virt);
|
||||
goto out;
|
||||
|
||||
@@ -781,20 +784,26 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
|
||||
goto out_fput;
|
||||
}
|
||||
i_size_write(inode, new_length);
|
||||
rc = ecryptfs_write_inode_size_to_header(lower_file,
|
||||
lower_dentry->d_inode,
|
||||
inode);
|
||||
rc = ecryptfs_write_inode_size_to_metadata(
|
||||
lower_file, lower_dentry->d_inode, inode, dentry,
|
||||
ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
|
||||
if (rc) {
|
||||
ecryptfs_printk(KERN_ERR,
|
||||
"Problem with ecryptfs_write"
|
||||
"_inode_size\n");
|
||||
printk(KERN_ERR "Problem with "
|
||||
"ecryptfs_write_inode_size_to_metadata; "
|
||||
"rc = [%d]\n", rc);
|
||||
goto out_fput;
|
||||
}
|
||||
} else { /* new_length < i_size_read(inode) */
|
||||
vmtruncate(inode, new_length);
|
||||
ecryptfs_write_inode_size_to_header(lower_file,
|
||||
lower_dentry->d_inode,
|
||||
inode);
|
||||
rc = ecryptfs_write_inode_size_to_metadata(
|
||||
lower_file, lower_dentry->d_inode, inode, dentry,
|
||||
ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "Problem with "
|
||||
"ecryptfs_write_inode_size_to_metadata; "
|
||||
"rc = [%d]\n", rc);
|
||||
goto out_fput;
|
||||
}
|
||||
/* We are reducing the size of the ecryptfs file, and need to
|
||||
* know if we need to reduce the size of the lower file. */
|
||||
lower_size_before_truncate =
|
||||
@@ -881,7 +890,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
||||
size_t size, int flags)
|
||||
{
|
||||
@@ -901,7 +910,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ssize_t
|
||||
ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
|
||||
size_t size)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user