diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ecryptfs/mmap.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 245c2dc02d5c..04d7b3fa1ac6 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -265,22 +265,34 @@ out: | |||
265 | } | 265 | } |
266 | 266 | ||
267 | /** | 267 | /** |
268 | * ecryptfs_prepare_write | 268 | * ecryptfs_write_begin |
269 | * @file: The eCryptfs file | 269 | * @file: The eCryptfs file |
270 | * @page: The eCryptfs page | 270 | * @mapping: The eCryptfs object |
271 | * @from: The start byte from which we will write | 271 | * @pos: The file offset at which to start writing |
272 | * @to: The end byte to which we will write | 272 | * @len: Length of the write |
273 | * @flags: Various flags | ||
274 | * @pagep: Pointer to return the page | ||
275 | * @fsdata: Pointer to return fs data (unused) | ||
273 | * | 276 | * |
274 | * This function must zero any hole we create | 277 | * This function must zero any hole we create |
275 | * | 278 | * |
276 | * Returns zero on success; non-zero otherwise | 279 | * Returns zero on success; non-zero otherwise |
277 | */ | 280 | */ |
278 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 281 | static int ecryptfs_write_begin(struct file *file, |
279 | unsigned from, unsigned to) | 282 | struct address_space *mapping, |
283 | loff_t pos, unsigned len, unsigned flags, | ||
284 | struct page **pagep, void **fsdata) | ||
280 | { | 285 | { |
286 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | ||
287 | struct page *page; | ||
281 | loff_t prev_page_end_size; | 288 | loff_t prev_page_end_size; |
282 | int rc = 0; | 289 | int rc = 0; |
283 | 290 | ||
291 | page = __grab_cache_page(mapping, index); | ||
292 | if (!page) | ||
293 | return -ENOMEM; | ||
294 | *pagep = page; | ||
295 | |||
284 | if (!PageUptodate(page)) { | 296 | if (!PageUptodate(page)) { |
285 | struct ecryptfs_crypt_stat *crypt_stat = | 297 | struct ecryptfs_crypt_stat *crypt_stat = |
286 | &ecryptfs_inode_to_private( | 298 | &ecryptfs_inode_to_private( |
@@ -289,8 +301,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
289 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | 301 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
290 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | 302 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { |
291 | rc = ecryptfs_read_lower_page_segment( | 303 | rc = ecryptfs_read_lower_page_segment( |
292 | page, page->index, 0, PAGE_CACHE_SIZE, | 304 | page, index, 0, PAGE_CACHE_SIZE, mapping->host); |
293 | page->mapping->host); | ||
294 | if (rc) { | 305 | if (rc) { |
295 | printk(KERN_ERR "%s: Error attemping to read " | 306 | printk(KERN_ERR "%s: Error attemping to read " |
296 | "lower page segment; rc = [%d]\n", | 307 | "lower page segment; rc = [%d]\n", |
@@ -316,8 +327,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
316 | SetPageUptodate(page); | 327 | SetPageUptodate(page); |
317 | } else { | 328 | } else { |
318 | rc = ecryptfs_read_lower_page_segment( | 329 | rc = ecryptfs_read_lower_page_segment( |
319 | page, page->index, 0, PAGE_CACHE_SIZE, | 330 | page, index, 0, PAGE_CACHE_SIZE, |
320 | page->mapping->host); | 331 | mapping->host); |
321 | if (rc) { | 332 | if (rc) { |
322 | printk(KERN_ERR "%s: Error reading " | 333 | printk(KERN_ERR "%s: Error reading " |
323 | "page; rc = [%d]\n", | 334 | "page; rc = [%d]\n", |
@@ -339,10 +350,10 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
339 | SetPageUptodate(page); | 350 | SetPageUptodate(page); |
340 | } | 351 | } |
341 | } | 352 | } |
342 | prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); | 353 | prev_page_end_size = ((loff_t)index << PAGE_CACHE_SHIFT); |
343 | /* If creating a page or more of holes, zero them out via truncate. | 354 | /* If creating a page or more of holes, zero them out via truncate. |
344 | * Note, this will increase i_size. */ | 355 | * Note, this will increase i_size. */ |
345 | if (page->index != 0) { | 356 | if (index != 0) { |
346 | if (prev_page_end_size > i_size_read(page->mapping->host)) { | 357 | if (prev_page_end_size > i_size_read(page->mapping->host)) { |
347 | rc = ecryptfs_truncate(file->f_path.dentry, | 358 | rc = ecryptfs_truncate(file->f_path.dentry, |
348 | prev_page_end_size); | 359 | prev_page_end_size); |
@@ -357,8 +368,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
357 | } | 368 | } |
358 | /* Writing to a new page, and creating a small hole from start | 369 | /* Writing to a new page, and creating a small hole from start |
359 | * of page? Zero it out. */ | 370 | * of page? Zero it out. */ |
360 | if ((i_size_read(page->mapping->host) == prev_page_end_size) | 371 | if ((i_size_read(mapping->host) == prev_page_end_size) |
361 | && (from != 0)) | 372 | && (pos != 0)) |
362 | zero_user(page, 0, PAGE_CACHE_SIZE); | 373 | zero_user(page, 0, PAGE_CACHE_SIZE); |
363 | out: | 374 | out: |
364 | return rc; | 375 | return rc; |
@@ -445,21 +456,28 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode) | |||
445 | } | 456 | } |
446 | 457 | ||
447 | /** | 458 | /** |
448 | * ecryptfs_commit_write | 459 | * ecryptfs_write_end |
449 | * @file: The eCryptfs file object | 460 | * @file: The eCryptfs file object |
461 | * @mapping: The eCryptfs object | ||
462 | * @pos: The file position | ||
463 | * @len: The length of the data (unused) | ||
464 | * @copied: The amount of data copied | ||
450 | * @page: The eCryptfs page | 465 | * @page: The eCryptfs page |
451 | * @from: Ignored (we rotate the page IV on each write) | 466 | * @fsdata: The fsdata (unused) |
452 | * @to: Ignored | ||
453 | * | 467 | * |
454 | * This is where we encrypt the data and pass the encrypted data to | 468 | * This is where we encrypt the data and pass the encrypted data to |
455 | * the lower filesystem. In OpenPGP-compatible mode, we operate on | 469 | * the lower filesystem. In OpenPGP-compatible mode, we operate on |
456 | * entire underlying packets. | 470 | * entire underlying packets. |
457 | */ | 471 | */ |
458 | static int ecryptfs_commit_write(struct file *file, struct page *page, | 472 | static int ecryptfs_write_end(struct file *file, |
459 | unsigned from, unsigned to) | 473 | struct address_space *mapping, |
474 | loff_t pos, unsigned len, unsigned copied, | ||
475 | struct page *page, void *fsdata) | ||
460 | { | 476 | { |
461 | loff_t pos; | 477 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
462 | struct inode *ecryptfs_inode = page->mapping->host; | 478 | unsigned from = pos & (PAGE_CACHE_SIZE - 1); |
479 | unsigned to = from + copied; | ||
480 | struct inode *ecryptfs_inode = mapping->host; | ||
463 | struct ecryptfs_crypt_stat *crypt_stat = | 481 | struct ecryptfs_crypt_stat *crypt_stat = |
464 | &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat; | 482 | &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat; |
465 | int rc; | 483 | int rc; |
@@ -471,25 +489,22 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
471 | } else | 489 | } else |
472 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); | 490 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); |
473 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 491 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
474 | "(page w/ index = [0x%.16x], to = [%d])\n", page->index, | 492 | "(page w/ index = [0x%.16x], to = [%d])\n", index, to); |
475 | to); | ||
476 | /* Fills in zeros if 'to' goes beyond inode size */ | 493 | /* Fills in zeros if 'to' goes beyond inode size */ |
477 | rc = fill_zeros_to_end_of_page(page, to); | 494 | rc = fill_zeros_to_end_of_page(page, to); |
478 | if (rc) { | 495 | if (rc) { |
479 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill " | 496 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill " |
480 | "zeros in page with index = [0x%.16x]\n", | 497 | "zeros in page with index = [0x%.16x]\n", index); |
481 | page->index); | ||
482 | goto out; | 498 | goto out; |
483 | } | 499 | } |
484 | rc = ecryptfs_encrypt_page(page); | 500 | rc = ecryptfs_encrypt_page(page); |
485 | if (rc) { | 501 | if (rc) { |
486 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " | 502 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " |
487 | "index [0x%.16x])\n", page->index); | 503 | "index [0x%.16x])\n", index); |
488 | goto out; | 504 | goto out; |
489 | } | 505 | } |
490 | pos = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + to; | 506 | if (pos + copied > i_size_read(ecryptfs_inode)) { |
491 | if (pos > i_size_read(ecryptfs_inode)) { | 507 | i_size_write(ecryptfs_inode, pos + copied); |
492 | i_size_write(ecryptfs_inode, pos); | ||
493 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 508 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
494 | "[0x%.16x]\n", i_size_read(ecryptfs_inode)); | 509 | "[0x%.16x]\n", i_size_read(ecryptfs_inode)); |
495 | } | 510 | } |
@@ -497,7 +512,11 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
497 | if (rc) | 512 | if (rc) |
498 | printk(KERN_ERR "Error writing inode size to metadata; " | 513 | printk(KERN_ERR "Error writing inode size to metadata; " |
499 | "rc = [%d]\n", rc); | 514 | "rc = [%d]\n", rc); |
515 | else | ||
516 | rc = copied; | ||
500 | out: | 517 | out: |
518 | unlock_page(page); | ||
519 | page_cache_release(page); | ||
501 | return rc; | 520 | return rc; |
502 | } | 521 | } |
503 | 522 | ||
@@ -518,7 +537,7 @@ static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block) | |||
518 | struct address_space_operations ecryptfs_aops = { | 537 | struct address_space_operations ecryptfs_aops = { |
519 | .writepage = ecryptfs_writepage, | 538 | .writepage = ecryptfs_writepage, |
520 | .readpage = ecryptfs_readpage, | 539 | .readpage = ecryptfs_readpage, |
521 | .prepare_write = ecryptfs_prepare_write, | 540 | .write_begin = ecryptfs_write_begin, |
522 | .commit_write = ecryptfs_commit_write, | 541 | .write_end = ecryptfs_write_end, |
523 | .bmap = ecryptfs_bmap, | 542 | .bmap = ecryptfs_bmap, |
524 | }; | 543 | }; |