diff options
Diffstat (limited to 'fs/ecryptfs/mmap.c')
| -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 | }; |
