diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-02-12 03:53:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:36 -0500 |
commit | dd2a3b7ad98f8482cae481cad89dfed5eee48365 (patch) | |
tree | 986c09754176ea4c6e8308c6e2cdbf3fc0658a0b /fs/ecryptfs/inode.c | |
parent | 17398957aa0a05ef62535060b41d103590dcc533 (diff) |
[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>
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index d4f02f3e18d7..6b45b2908f17 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1997-2004 Erez Zadok | 4 | * Copyright (C) 1997-2004 Erez Zadok |
5 | * Copyright (C) 2001-2004 Stony Brook University | 5 | * Copyright (C) 2001-2004 Stony Brook University |
6 | * Copyright (C) 2004-2006 International Business Machines Corp. | 6 | * Copyright (C) 2004-2007 International Business Machines Corp. |
7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
8 | * Michael C. Thompsion <mcthomps@us.ibm.com> | 8 | * Michael C. Thompsion <mcthomps@us.ibm.com> |
9 | * | 9 | * |
@@ -169,7 +169,9 @@ static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file, | |||
169 | goto out; | 169 | goto out; |
170 | } | 170 | } |
171 | i_size_write(inode, 0); | 171 | i_size_write(inode, 0); |
172 | ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); | 172 | ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, inode, |
173 | ecryptfs_dentry, | ||
174 | ECRYPTFS_LOWER_I_MUTEX_NOT_HELD); | ||
173 | ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags, | 175 | ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags, |
174 | ECRYPTFS_NEW_FILE); | 176 | ECRYPTFS_NEW_FILE); |
175 | out: | 177 | out: |
@@ -225,7 +227,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
225 | "context\n"); | 227 | "context\n"); |
226 | goto out_fput; | 228 | goto out_fput; |
227 | } | 229 | } |
228 | rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file); | 230 | rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file); |
229 | if (rc) { | 231 | if (rc) { |
230 | ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); | 232 | ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); |
231 | goto out_fput; | 233 | goto out_fput; |
@@ -362,32 +364,33 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
362 | } | 364 | } |
363 | /* Released in this function */ | 365 | /* Released in this function */ |
364 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, | 366 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, |
365 | GFP_USER); | 367 | GFP_USER); |
366 | if (!page_virt) { | 368 | if (!page_virt) { |
367 | rc = -ENOMEM; | 369 | rc = -ENOMEM; |
368 | ecryptfs_printk(KERN_ERR, | 370 | ecryptfs_printk(KERN_ERR, |
369 | "Cannot ecryptfs_kmalloc a page\n"); | 371 | "Cannot ecryptfs_kmalloc a page\n"); |
370 | goto out_dput; | 372 | goto out_dput; |
371 | } | 373 | } |
372 | |||
373 | rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt); | ||
374 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 374 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
375 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) | 375 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) |
376 | ecryptfs_set_default_sizes(crypt_stat); | 376 | ecryptfs_set_default_sizes(crypt_stat); |
377 | rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry, | ||
378 | nd->mnt); | ||
377 | if (rc) { | 379 | if (rc) { |
378 | rc = 0; | 380 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); |
379 | ecryptfs_printk(KERN_WARNING, "Error reading header region;" | 381 | if (rc) { |
380 | " assuming unencrypted\n"); | 382 | printk(KERN_DEBUG "Valid metadata not found in header " |
381 | } else { | 383 | "region or xattr region; treating file as " |
382 | if (!contains_ecryptfs_marker(page_virt | 384 | "unencrypted\n"); |
383 | + ECRYPTFS_FILE_SIZE_BYTES)) { | 385 | rc = 0; |
384 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 386 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
385 | goto out; | 387 | goto out; |
386 | } | 388 | } |
387 | memcpy(&file_size, page_virt, sizeof(file_size)); | 389 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
388 | file_size = be64_to_cpu(file_size); | ||
389 | i_size_write(dentry->d_inode, (loff_t)file_size); | ||
390 | } | 390 | } |
391 | memcpy(&file_size, page_virt, sizeof(file_size)); | ||
392 | file_size = be64_to_cpu(file_size); | ||
393 | i_size_write(dentry->d_inode, (loff_t)file_size); | ||
391 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 394 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
392 | goto out; | 395 | goto out; |
393 | 396 | ||
@@ -781,20 +784,26 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
781 | goto out_fput; | 784 | goto out_fput; |
782 | } | 785 | } |
783 | i_size_write(inode, new_length); | 786 | i_size_write(inode, new_length); |
784 | rc = ecryptfs_write_inode_size_to_header(lower_file, | 787 | rc = ecryptfs_write_inode_size_to_metadata( |
785 | lower_dentry->d_inode, | 788 | lower_file, lower_dentry->d_inode, inode, dentry, |
786 | inode); | 789 | ECRYPTFS_LOWER_I_MUTEX_NOT_HELD); |
787 | if (rc) { | 790 | if (rc) { |
788 | ecryptfs_printk(KERN_ERR, | 791 | printk(KERN_ERR "Problem with " |
789 | "Problem with ecryptfs_write" | 792 | "ecryptfs_write_inode_size_to_metadata; " |
790 | "_inode_size\n"); | 793 | "rc = [%d]\n", rc); |
791 | goto out_fput; | 794 | goto out_fput; |
792 | } | 795 | } |
793 | } else { /* new_length < i_size_read(inode) */ | 796 | } else { /* new_length < i_size_read(inode) */ |
794 | vmtruncate(inode, new_length); | 797 | vmtruncate(inode, new_length); |
795 | ecryptfs_write_inode_size_to_header(lower_file, | 798 | rc = ecryptfs_write_inode_size_to_metadata( |
796 | lower_dentry->d_inode, | 799 | lower_file, lower_dentry->d_inode, inode, dentry, |
797 | inode); | 800 | ECRYPTFS_LOWER_I_MUTEX_NOT_HELD); |
801 | if (rc) { | ||
802 | printk(KERN_ERR "Problem with " | ||
803 | "ecryptfs_write_inode_size_to_metadata; " | ||
804 | "rc = [%d]\n", rc); | ||
805 | goto out_fput; | ||
806 | } | ||
798 | /* We are reducing the size of the ecryptfs file, and need to | 807 | /* We are reducing the size of the ecryptfs file, and need to |
799 | * know if we need to reduce the size of the lower file. */ | 808 | * know if we need to reduce the size of the lower file. */ |
800 | lower_size_before_truncate = | 809 | lower_size_before_truncate = |
@@ -881,7 +890,7 @@ out: | |||
881 | return rc; | 890 | return rc; |
882 | } | 891 | } |
883 | 892 | ||
884 | static int | 893 | int |
885 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 894 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
886 | size_t size, int flags) | 895 | size_t size, int flags) |
887 | { | 896 | { |
@@ -901,7 +910,7 @@ out: | |||
901 | return rc; | 910 | return rc; |
902 | } | 911 | } |
903 | 912 | ||
904 | static ssize_t | 913 | ssize_t |
905 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | 914 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, |
906 | size_t size) | 915 | size_t size) |
907 | { | 916 | { |