aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2008-02-06 04:38:32 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:12 -0500
commitcc11beffdf80ca31dff21422fa2a5e54d25f1494 (patch)
tree3b0e28d18f493a7c59b089c4c6fc59c79945937e /fs
parent7896b631823c6e8f1a520d89390624a51445840e (diff)
eCryptfs: track header bytes rather than extents
Remove internal references to header extents; just keep track of header bytes instead. Headers can easily span multiple pages with the recent persistent file changes. 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')
-rw-r--r--fs/ecryptfs/crypto.c98
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h3
-rw-r--r--fs/ecryptfs/inode.c8
-rw-r--r--fs/ecryptfs/main.c5
-rw-r--r--fs/ecryptfs/mmap.c21
5 files changed, 51 insertions, 84 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 5e7d018a3486..4d1b2b4eb79e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -379,8 +379,7 @@ out:
379static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, 379static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
380 struct ecryptfs_crypt_stat *crypt_stat) 380 struct ecryptfs_crypt_stat *crypt_stat)
381{ 381{
382 (*offset) = ((crypt_stat->extent_size 382 (*offset) = (crypt_stat->num_header_bytes_at_front
383 * crypt_stat->num_header_extents_at_front)
384 + (crypt_stat->extent_size * extent_num)); 383 + (crypt_stat->extent_size * extent_num));
385} 384}
386 385
@@ -842,15 +841,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
842 set_extent_mask_and_shift(crypt_stat); 841 set_extent_mask_and_shift(crypt_stat);
843 crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; 842 crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
844 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 843 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
845 crypt_stat->num_header_extents_at_front = 0; 844 crypt_stat->num_header_bytes_at_front = 0;
846 else { 845 else {
847 if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) 846 if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
848 crypt_stat->num_header_extents_at_front = 847 crypt_stat->num_header_bytes_at_front =
849 (ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 848 ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
850 / crypt_stat->extent_size);
851 else 849 else
852 crypt_stat->num_header_extents_at_front = 850 crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE;
853 (PAGE_CACHE_SIZE / crypt_stat->extent_size);
854 } 851 }
855} 852}
856 853
@@ -1236,7 +1233,8 @@ ecryptfs_write_header_metadata(char *virt,
1236 1233
1237 header_extent_size = (u32)crypt_stat->extent_size; 1234 header_extent_size = (u32)crypt_stat->extent_size;
1238 num_header_extents_at_front = 1235 num_header_extents_at_front =
1239 (u16)crypt_stat->num_header_extents_at_front; 1236 (u16)(crypt_stat->num_header_bytes_at_front
1237 / crypt_stat->extent_size);
1240 header_extent_size = cpu_to_be32(header_extent_size); 1238 header_extent_size = cpu_to_be32(header_extent_size);
1241 memcpy(virt, &header_extent_size, 4); 1239 memcpy(virt, &header_extent_size, 4);
1242 virt += 4; 1240 virt += 4;
@@ -1311,40 +1309,16 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size,
1311static int 1309static int
1312ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, 1310ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
1313 struct dentry *ecryptfs_dentry, 1311 struct dentry *ecryptfs_dentry,
1314 char *page_virt) 1312 char *virt)
1315{ 1313{
1316 int current_header_page;
1317 int header_pages;
1318 int rc; 1314 int rc;
1319 1315
1320 rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, page_virt, 1316 rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
1321 0, PAGE_CACHE_SIZE); 1317 0, crypt_stat->num_header_bytes_at_front);
1322 if (rc) { 1318 if (rc)
1323 printk(KERN_ERR "%s: Error attempting to write header " 1319 printk(KERN_ERR "%s: Error attempting to write header "
1324 "information to lower file; rc = [%d]\n", __FUNCTION__, 1320 "information to lower file; rc = [%d]\n", __FUNCTION__,
1325 rc); 1321 rc);
1326 goto out;
1327 }
1328 header_pages = ((crypt_stat->extent_size
1329 * crypt_stat->num_header_extents_at_front)
1330 / PAGE_CACHE_SIZE);
1331 memset(page_virt, 0, PAGE_CACHE_SIZE);
1332 current_header_page = 1;
1333 while (current_header_page < header_pages) {
1334 loff_t offset;
1335
1336 offset = (((loff_t)current_header_page) << PAGE_CACHE_SHIFT);
1337 if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode,
1338 page_virt, offset,
1339 PAGE_CACHE_SIZE))) {
1340 printk(KERN_ERR "%s: Error attempting to write header "
1341 "information to lower file; rc = [%d]\n",
1342 __FUNCTION__, rc);
1343 goto out;
1344 }
1345 current_header_page++;
1346 }
1347out:
1348 return rc; 1322 return rc;
1349} 1323}
1350 1324
@@ -1370,15 +1344,13 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
1370 * retrieved via a prompt. Exactly what happens at this point should 1344 * retrieved via a prompt. Exactly what happens at this point should
1371 * be policy-dependent. 1345 * be policy-dependent.
1372 * 1346 *
1373 * TODO: Support header information spanning multiple pages
1374 *
1375 * Returns zero on success; non-zero on error 1347 * Returns zero on success; non-zero on error
1376 */ 1348 */
1377int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) 1349int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
1378{ 1350{
1379 struct ecryptfs_crypt_stat *crypt_stat = 1351 struct ecryptfs_crypt_stat *crypt_stat =
1380 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; 1352 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
1381 char *page_virt; 1353 char *virt;
1382 size_t size = 0; 1354 size_t size = 0;
1383 int rc = 0; 1355 int rc = 0;
1384 1356
@@ -1389,40 +1361,39 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
1389 goto out; 1361 goto out;
1390 } 1362 }
1391 } else { 1363 } else {
1364 printk(KERN_WARNING "%s: Encrypted flag not set\n",
1365 __FUNCTION__);
1392 rc = -EINVAL; 1366 rc = -EINVAL;
1393 ecryptfs_printk(KERN_WARNING,
1394 "Called with crypt_stat->encrypted == 0\n");
1395 goto out; 1367 goto out;
1396 } 1368 }
1397 /* Released in this function */ 1369 /* Released in this function */
1398 page_virt = kmem_cache_zalloc(ecryptfs_header_cache_0, GFP_USER); 1370 virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL);
1399 if (!page_virt) { 1371 if (!virt) {
1400 ecryptfs_printk(KERN_ERR, "Out of memory\n"); 1372 printk(KERN_ERR "%s: Out of memory\n", __FUNCTION__);
1401 rc = -ENOMEM; 1373 rc = -ENOMEM;
1402 goto out; 1374 goto out;
1403 } 1375 }
1404 rc = ecryptfs_write_headers_virt(page_virt, &size, crypt_stat, 1376 rc = ecryptfs_write_headers_virt(virt, &size, crypt_stat,
1405 ecryptfs_dentry); 1377 ecryptfs_dentry);
1406 if (unlikely(rc)) { 1378 if (unlikely(rc)) {
1407 ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); 1379 printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n",
1408 memset(page_virt, 0, PAGE_CACHE_SIZE); 1380 __FUNCTION__, rc);
1409 goto out_free; 1381 goto out_free;
1410 } 1382 }
1411 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 1383 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
1412 rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, 1384 rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry,
1413 crypt_stat, page_virt, 1385 crypt_stat, virt, size);
1414 size);
1415 else 1386 else
1416 rc = ecryptfs_write_metadata_to_contents(crypt_stat, 1387 rc = ecryptfs_write_metadata_to_contents(crypt_stat,
1417 ecryptfs_dentry, 1388 ecryptfs_dentry, virt);
1418 page_virt);
1419 if (rc) { 1389 if (rc) {
1420 printk(KERN_ERR "Error writing metadata out to lower file; " 1390 printk(KERN_ERR "%s: Error writing metadata out to lower file; "
1421 "rc = [%d]\n", rc); 1391 "rc = [%d]\n", __FUNCTION__, rc);
1422 goto out_free; 1392 goto out_free;
1423 } 1393 }
1424out_free: 1394out_free:
1425 kmem_cache_free(ecryptfs_header_cache_0, page_virt); 1395 memset(virt, 0, crypt_stat->num_header_bytes_at_front);
1396 kfree(virt);
1426out: 1397out:
1427 return rc; 1398 return rc;
1428} 1399}
@@ -1442,16 +1413,16 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
1442 virt += sizeof(u32); 1413 virt += sizeof(u32);
1443 memcpy(&num_header_extents_at_front, virt, sizeof(u16)); 1414 memcpy(&num_header_extents_at_front, virt, sizeof(u16));
1444 num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); 1415 num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front);
1445 crypt_stat->num_header_extents_at_front = 1416 crypt_stat->num_header_bytes_at_front =
1446 (int)num_header_extents_at_front; 1417 (((size_t)num_header_extents_at_front
1418 * (size_t)header_extent_size));
1447 (*bytes_read) = (sizeof(u32) + sizeof(u16)); 1419 (*bytes_read) = (sizeof(u32) + sizeof(u16));
1448 if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) 1420 if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
1449 && ((crypt_stat->extent_size 1421 && (crypt_stat->num_header_bytes_at_front
1450 * crypt_stat->num_header_extents_at_front)
1451 < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { 1422 < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
1452 rc = -EINVAL; 1423 rc = -EINVAL;
1453 printk(KERN_WARNING "Invalid number of header extents: [%zd]\n", 1424 printk(KERN_WARNING "Invalid header size: [%zd]\n",
1454 crypt_stat->num_header_extents_at_front); 1425 crypt_stat->num_header_bytes_at_front);
1455 } 1426 }
1456 return rc; 1427 return rc;
1457} 1428}
@@ -1466,7 +1437,8 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
1466 */ 1437 */
1467static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) 1438static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
1468{ 1439{
1469 crypt_stat->num_header_extents_at_front = 2; 1440 crypt_stat->num_header_bytes_at_front =
1441 ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
1470} 1442}
1471 1443
1472/** 1444/**
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 466661c9fb21..3d637e9ca36a 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -237,7 +237,7 @@ struct ecryptfs_crypt_stat {
237 u32 flags; 237 u32 flags;
238 unsigned int file_version; 238 unsigned int file_version;
239 size_t iv_bytes; 239 size_t iv_bytes;
240 size_t num_header_extents_at_front; 240 size_t num_header_bytes_at_front;
241 size_t extent_size; /* Data extent size; default is 4096 */ 241 size_t extent_size; /* Data extent size; default is 4096 */
242 size_t key_size; 242 size_t key_size;
243 size_t extent_shift; 243 size_t extent_shift;
@@ -518,7 +518,6 @@ extern struct kmem_cache *ecryptfs_file_info_cache;
518extern struct kmem_cache *ecryptfs_dentry_info_cache; 518extern struct kmem_cache *ecryptfs_dentry_info_cache;
519extern struct kmem_cache *ecryptfs_inode_info_cache; 519extern struct kmem_cache *ecryptfs_inode_info_cache;
520extern struct kmem_cache *ecryptfs_sb_info_cache; 520extern struct kmem_cache *ecryptfs_sb_info_cache;
521extern struct kmem_cache *ecryptfs_header_cache_0;
522extern struct kmem_cache *ecryptfs_header_cache_1; 521extern struct kmem_cache *ecryptfs_header_cache_1;
523extern struct kmem_cache *ecryptfs_header_cache_2; 522extern struct kmem_cache *ecryptfs_header_cache_2;
524extern struct kmem_cache *ecryptfs_xattr_cache; 523extern struct kmem_cache *ecryptfs_xattr_cache;
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index ed0ed849ee28..a2bc9df546bd 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -365,8 +365,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
365 dentry->d_sb)->mount_crypt_stat; 365 dentry->d_sb)->mount_crypt_stat;
366 if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { 366 if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
367 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 367 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
368 file_size = ((crypt_stat->extent_size 368 file_size = (crypt_stat->num_header_bytes_at_front
369 * crypt_stat->num_header_extents_at_front)
370 + i_size_read(lower_dentry->d_inode)); 369 + i_size_read(lower_dentry->d_inode));
371 else 370 else
372 file_size = i_size_read(lower_dentry->d_inode); 371 file_size = i_size_read(lower_dentry->d_inode);
@@ -685,7 +684,7 @@ ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
685 * @crypt_stat: Crypt_stat associated with file 684 * @crypt_stat: Crypt_stat associated with file
686 * @upper_size: Size of the upper file 685 * @upper_size: Size of the upper file
687 * 686 *
688 * Calculate the requried size of the lower file based on the 687 * Calculate the required size of the lower file based on the
689 * specified size of the upper file. This calculation is based on the 688 * specified size of the upper file. This calculation is based on the
690 * number of headers in the underlying file and the extent size. 689 * number of headers in the underlying file and the extent size.
691 * 690 *
@@ -697,8 +696,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
697{ 696{
698 loff_t lower_size; 697 loff_t lower_size;
699 698
700 lower_size = (crypt_stat->extent_size 699 lower_size = crypt_stat->num_header_bytes_at_front;
701 * crypt_stat->num_header_extents_at_front);
702 if (upper_size != 0) { 700 if (upper_size != 0) {
703 loff_t num_extents; 701 loff_t num_extents;
704 702
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index d9f53c331a27..b67ce83da9fc 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -654,11 +654,6 @@ static struct ecryptfs_cache_info {
654 .size = sizeof(struct ecryptfs_sb_info), 654 .size = sizeof(struct ecryptfs_sb_info),
655 }, 655 },
656 { 656 {
657 .cache = &ecryptfs_header_cache_0,
658 .name = "ecryptfs_headers_0",
659 .size = PAGE_CACHE_SIZE,
660 },
661 {
662 .cache = &ecryptfs_header_cache_1, 657 .cache = &ecryptfs_header_cache_1,
663 .name = "ecryptfs_headers_1", 658 .name = "ecryptfs_headers_1",
664 .size = PAGE_CACHE_SIZE, 659 .size = PAGE_CACHE_SIZE,
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 9a5e0d17f1c5..dc74b186145d 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -100,13 +100,14 @@ static void set_header_info(char *page_virt,
100 struct ecryptfs_crypt_stat *crypt_stat) 100 struct ecryptfs_crypt_stat *crypt_stat)
101{ 101{
102 size_t written; 102 size_t written;
103 int save_num_header_extents_at_front = 103 size_t save_num_header_bytes_at_front =
104 crypt_stat->num_header_extents_at_front; 104 crypt_stat->num_header_bytes_at_front;
105 105
106 crypt_stat->num_header_extents_at_front = 1; 106 crypt_stat->num_header_bytes_at_front =
107 ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
107 ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); 108 ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
108 crypt_stat->num_header_extents_at_front = 109 crypt_stat->num_header_bytes_at_front =
109 save_num_header_extents_at_front; 110 save_num_header_bytes_at_front;
110} 111}
111 112
112/** 113/**
@@ -132,8 +133,11 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
132 loff_t view_extent_num = ((((loff_t)page->index) 133 loff_t view_extent_num = ((((loff_t)page->index)
133 * num_extents_per_page) 134 * num_extents_per_page)
134 + extent_num_in_page); 135 + extent_num_in_page);
136 size_t num_header_extents_at_front =
137 (crypt_stat->num_header_bytes_at_front
138 / crypt_stat->extent_size);
135 139
136 if (view_extent_num < crypt_stat->num_header_extents_at_front) { 140 if (view_extent_num < num_header_extents_at_front) {
137 /* This is a header extent */ 141 /* This is a header extent */
138 char *page_virt; 142 char *page_virt;
139 143
@@ -155,9 +159,8 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
155 } else { 159 } else {
156 /* This is an encrypted data extent */ 160 /* This is an encrypted data extent */
157 loff_t lower_offset = 161 loff_t lower_offset =
158 ((view_extent_num - 162 ((view_extent_num * crypt_stat->extent_size)
159 crypt_stat->num_header_extents_at_front) 163 - crypt_stat->num_header_bytes_at_front);
160 * crypt_stat->extent_size);
161 164
162 rc = ecryptfs_read_lower_page_segment( 165 rc = ecryptfs_read_lower_page_segment(
163 page, (lower_offset >> PAGE_CACHE_SHIFT), 166 page, (lower_offset >> PAGE_CACHE_SHIFT),