[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:
Michael Halcrow
2007-02-12 00:53:46 -08:00
committed by Linus Torvalds
parent 17398957aa
commit dd2a3b7ad9
7 changed files with 348 additions and 146 deletions

View File

@@ -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)
{