diff options
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r-- | fs/ecryptfs/mmap.c | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 6ae0afb238d1..4eb09c1753c6 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -57,113 +57,6 @@ struct page *ecryptfs_get1page(struct file *file, loff_t index) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * ecryptfs_fill_zeros | ||
61 | * @file: The ecryptfs file | ||
62 | * @new_length: The new length of the data in the underlying file; | ||
63 | * everything between the prior end of the file and the | ||
64 | * new end of the file will be filled with zero's. | ||
65 | * new_length must be greater than current length | ||
66 | * | ||
67 | * Function for handling lseek-ing past the end of the file. | ||
68 | * | ||
69 | * This function does not support shrinking, only growing a file. | ||
70 | * | ||
71 | * Returns zero on success; non-zero otherwise. | ||
72 | */ | ||
73 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | ||
74 | { | ||
75 | int rc = 0; | ||
76 | struct dentry *dentry = file->f_path.dentry; | ||
77 | struct inode *inode = dentry->d_inode; | ||
78 | pgoff_t old_end_page_index = 0; | ||
79 | pgoff_t index = old_end_page_index; | ||
80 | int old_end_pos_in_page = -1; | ||
81 | pgoff_t new_end_page_index; | ||
82 | int new_end_pos_in_page; | ||
83 | loff_t cur_length = i_size_read(inode); | ||
84 | |||
85 | if (cur_length != 0) { | ||
86 | index = old_end_page_index = | ||
87 | ((cur_length - 1) >> PAGE_CACHE_SHIFT); | ||
88 | old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK); | ||
89 | } | ||
90 | new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT); | ||
91 | new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK); | ||
92 | ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; " | ||
93 | "old_end_pos_in_page = [%d]; " | ||
94 | "new_end_page_index = [0x%.16x]; " | ||
95 | "new_end_pos_in_page = [%d]\n", | ||
96 | old_end_page_index, old_end_pos_in_page, | ||
97 | new_end_page_index, new_end_pos_in_page); | ||
98 | if (old_end_page_index == new_end_page_index) { | ||
99 | /* Start and end are in the same page; we just need to | ||
100 | * set a portion of the existing page to zero's */ | ||
101 | rc = ecryptfs_write_zeros(file, index, | ||
102 | (old_end_pos_in_page + 1), | ||
103 | (new_end_pos_in_page | ||
104 | - old_end_pos_in_page)); | ||
105 | if (rc) | ||
106 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" | ||
107 | "file=[%p], " | ||
108 | "index=[0x%.16x], " | ||
109 | "old_end_pos_in_page=[d], " | ||
110 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | ||
111 | "=[%d]" | ||
112 | ")=[d]) returned [%d]\n", file, index, | ||
113 | old_end_pos_in_page, | ||
114 | new_end_pos_in_page, | ||
115 | (PAGE_CACHE_SIZE - new_end_pos_in_page), | ||
116 | rc); | ||
117 | goto out; | ||
118 | } | ||
119 | /* Fill the remainder of the previous last page with zeros */ | ||
120 | rc = ecryptfs_write_zeros(file, index, (old_end_pos_in_page + 1), | ||
121 | ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); | ||
122 | if (rc) { | ||
123 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=[%p], " | ||
124 | "index=[0x%.16x], old_end_pos_in_page=[d], " | ||
125 | "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " | ||
126 | "returned [%d]\n", file, index, | ||
127 | old_end_pos_in_page, | ||
128 | (PAGE_CACHE_SIZE - old_end_pos_in_page), rc); | ||
129 | goto out; | ||
130 | } | ||
131 | index++; | ||
132 | while (index < new_end_page_index) { | ||
133 | /* Fill all intermediate pages with zeros */ | ||
134 | rc = ecryptfs_write_zeros(file, index, 0, PAGE_CACHE_SIZE); | ||
135 | if (rc) { | ||
136 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" | ||
137 | "file=[%p], " | ||
138 | "index=[0x%.16x], " | ||
139 | "old_end_pos_in_page=[d], " | ||
140 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | ||
141 | "=[%d]" | ||
142 | ")=[d]) returned [%d]\n", file, index, | ||
143 | old_end_pos_in_page, | ||
144 | new_end_pos_in_page, | ||
145 | (PAGE_CACHE_SIZE - new_end_pos_in_page), | ||
146 | rc); | ||
147 | goto out; | ||
148 | } | ||
149 | index++; | ||
150 | } | ||
151 | /* Fill the portion at the beginning of the last new page with | ||
152 | * zero's */ | ||
153 | rc = ecryptfs_write_zeros(file, index, 0, (new_end_pos_in_page + 1)); | ||
154 | if (rc) { | ||
155 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=" | ||
156 | "[%p], index=[0x%.16x], 0, " | ||
157 | "new_end_pos_in_page=[%d]" | ||
158 | "returned [%d]\n", file, index, | ||
159 | new_end_pos_in_page, rc); | ||
160 | goto out; | ||
161 | } | ||
162 | out: | ||
163 | return rc; | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * ecryptfs_writepage | 60 | * ecryptfs_writepage |
168 | * @page: Page that is locked before this call is made | 61 | * @page: Page that is locked before this call is made |
169 | * | 62 | * |
@@ -187,58 +80,6 @@ out: | |||
187 | } | 80 | } |
188 | 81 | ||
189 | /** | 82 | /** |
190 | * Reads the data from the lower file file at index lower_page_index | ||
191 | * and copies that data into page. | ||
192 | * | ||
193 | * @param page Page to fill | ||
194 | * @param lower_page_index Index of the page in the lower file to get | ||
195 | */ | ||
196 | int ecryptfs_do_readpage(struct file *file, struct page *page, | ||
197 | pgoff_t lower_page_index) | ||
198 | { | ||
199 | int rc; | ||
200 | struct dentry *dentry; | ||
201 | struct file *lower_file; | ||
202 | struct dentry *lower_dentry; | ||
203 | struct inode *inode; | ||
204 | struct inode *lower_inode; | ||
205 | char *page_data; | ||
206 | struct page *lower_page = NULL; | ||
207 | char *lower_page_data; | ||
208 | const struct address_space_operations *lower_a_ops; | ||
209 | |||
210 | dentry = file->f_path.dentry; | ||
211 | lower_file = ecryptfs_file_to_lower(file); | ||
212 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
213 | inode = dentry->d_inode; | ||
214 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
215 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
216 | lower_page = read_cache_page(lower_inode->i_mapping, lower_page_index, | ||
217 | (filler_t *)lower_a_ops->readpage, | ||
218 | (void *)lower_file); | ||
219 | if (IS_ERR(lower_page)) { | ||
220 | rc = PTR_ERR(lower_page); | ||
221 | lower_page = NULL; | ||
222 | ecryptfs_printk(KERN_ERR, "Error reading from page cache\n"); | ||
223 | goto out; | ||
224 | } | ||
225 | page_data = kmap_atomic(page, KM_USER0); | ||
226 | lower_page_data = kmap_atomic(lower_page, KM_USER1); | ||
227 | memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); | ||
228 | kunmap_atomic(lower_page_data, KM_USER1); | ||
229 | kunmap_atomic(page_data, KM_USER0); | ||
230 | flush_dcache_page(page); | ||
231 | rc = 0; | ||
232 | out: | ||
233 | if (likely(lower_page)) | ||
234 | page_cache_release(lower_page); | ||
235 | if (rc == 0) | ||
236 | SetPageUptodate(page); | ||
237 | else | ||
238 | ClearPageUptodate(page); | ||
239 | return rc; | ||
240 | } | ||
241 | /** | ||
242 | * Header Extent: | 83 | * Header Extent: |
243 | * Octets 0-7: Unencrypted file size (big-endian) | 84 | * Octets 0-7: Unencrypted file size (big-endian) |
244 | * Octets 8-15: eCryptfs special marker | 85 | * Octets 8-15: eCryptfs special marker |
@@ -416,27 +257,6 @@ out: | |||
416 | return 0; | 257 | return 0; |
417 | } | 258 | } |
418 | 259 | ||
419 | /** | ||
420 | * eCryptfs does not currently support holes. When writing after a | ||
421 | * seek past the end of the file, eCryptfs fills in 0's through to the | ||
422 | * current location. The code to fill in the 0's to all the | ||
423 | * intermediate pages calls ecryptfs_prepare_write_no_truncate(). | ||
424 | */ | ||
425 | static int | ||
426 | ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page, | ||
427 | unsigned from, unsigned to) | ||
428 | { | ||
429 | int rc = 0; | ||
430 | |||
431 | if (from == 0 && to == PAGE_CACHE_SIZE) | ||
432 | goto out; /* If we are writing a full page, it will be | ||
433 | up to date. */ | ||
434 | if (!PageUptodate(page)) | ||
435 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
436 | out: | ||
437 | return rc; | ||
438 | } | ||
439 | |||
440 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 260 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
441 | unsigned from, unsigned to) | 261 | unsigned from, unsigned to) |
442 | { | 262 | { |
@@ -470,30 +290,6 @@ out: | |||
470 | return rc; | 290 | return rc; |
471 | } | 291 | } |
472 | 292 | ||
473 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, | ||
474 | struct inode *lower_inode, | ||
475 | struct writeback_control *wbc) | ||
476 | { | ||
477 | int rc = 0; | ||
478 | |||
479 | rc = lower_inode->i_mapping->a_ops->writepage(lower_page, wbc); | ||
480 | if (rc) { | ||
481 | ecryptfs_printk(KERN_ERR, "Error calling lower writepage(); " | ||
482 | "rc = [%d]\n", rc); | ||
483 | goto out; | ||
484 | } | ||
485 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
486 | page_cache_release(lower_page); | ||
487 | out: | ||
488 | return rc; | ||
489 | } | ||
490 | |||
491 | static void ecryptfs_release_lower_page(struct page *lower_page) | ||
492 | { | ||
493 | unlock_page(lower_page); | ||
494 | page_cache_release(lower_page); | ||
495 | } | ||
496 | |||
497 | /** | 293 | /** |
498 | * ecryptfs_write_inode_size_to_header | 294 | * ecryptfs_write_inode_size_to_header |
499 | * | 295 | * |
@@ -580,90 +376,6 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode) | |||
580 | return ecryptfs_write_inode_size_to_header(ecryptfs_inode); | 376 | return ecryptfs_write_inode_size_to_header(ecryptfs_inode); |
581 | } | 377 | } |
582 | 378 | ||
583 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | ||
584 | struct file *lower_file, | ||
585 | unsigned long lower_page_index, int byte_offset, | ||
586 | int region_bytes) | ||
587 | { | ||
588 | int rc = 0; | ||
589 | |||
590 | *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index); | ||
591 | if (!(*lower_page)) { | ||
592 | rc = -EINVAL; | ||
593 | ecryptfs_printk(KERN_ERR, "Error attempting to grab " | ||
594 | "lower page with index [0x%.16x]\n", | ||
595 | lower_page_index); | ||
596 | goto out; | ||
597 | } | ||
598 | rc = lower_inode->i_mapping->a_ops->prepare_write(lower_file, | ||
599 | (*lower_page), | ||
600 | byte_offset, | ||
601 | region_bytes); | ||
602 | if (rc) { | ||
603 | ecryptfs_printk(KERN_ERR, "prepare_write for " | ||
604 | "lower_page_index = [0x%.16x] failed; rc = " | ||
605 | "[%d]\n", lower_page_index, rc); | ||
606 | ecryptfs_release_lower_page(*lower_page); | ||
607 | (*lower_page) = NULL; | ||
608 | } | ||
609 | out: | ||
610 | return rc; | ||
611 | } | ||
612 | |||
613 | /** | ||
614 | * ecryptfs_commit_lower_page | ||
615 | * | ||
616 | * Returns zero on success; non-zero on error | ||
617 | */ | ||
618 | int | ||
619 | ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode, | ||
620 | struct file *lower_file, int byte_offset, | ||
621 | int region_size) | ||
622 | { | ||
623 | int rc = 0; | ||
624 | |||
625 | rc = lower_inode->i_mapping->a_ops->commit_write( | ||
626 | lower_file, lower_page, byte_offset, region_size); | ||
627 | if (rc < 0) { | ||
628 | ecryptfs_printk(KERN_ERR, | ||
629 | "Error committing write; rc = [%d]\n", rc); | ||
630 | } else | ||
631 | rc = 0; | ||
632 | ecryptfs_release_lower_page(lower_page); | ||
633 | return rc; | ||
634 | } | ||
635 | |||
636 | /** | ||
637 | * ecryptfs_copy_page_to_lower | ||
638 | * | ||
639 | * Used for plaintext pass-through; no page index interpolation | ||
640 | * required. | ||
641 | */ | ||
642 | int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode, | ||
643 | struct file *lower_file) | ||
644 | { | ||
645 | int rc = 0; | ||
646 | struct page *lower_page; | ||
647 | |||
648 | rc = ecryptfs_get_lower_page(&lower_page, lower_inode, lower_file, | ||
649 | page->index, 0, PAGE_CACHE_SIZE); | ||
650 | if (rc) { | ||
651 | ecryptfs_printk(KERN_ERR, "Error attempting to get page " | ||
652 | "at index [0x%.16x]\n", page->index); | ||
653 | goto out; | ||
654 | } | ||
655 | /* TODO: aops */ | ||
656 | memcpy((char *)page_address(lower_page), page_address(page), | ||
657 | PAGE_CACHE_SIZE); | ||
658 | rc = ecryptfs_commit_lower_page(lower_page, lower_inode, lower_file, | ||
659 | 0, PAGE_CACHE_SIZE); | ||
660 | if (rc) | ||
661 | ecryptfs_printk(KERN_ERR, "Error attempting to commit page " | ||
662 | "at index [0x%.16x]\n", page->index); | ||
663 | out: | ||
664 | return rc; | ||
665 | } | ||
666 | |||
667 | /** | 379 | /** |
668 | * ecryptfs_commit_write | 380 | * ecryptfs_commit_write |
669 | * @file: The eCryptfs file object | 381 | * @file: The eCryptfs file object |
@@ -721,54 +433,6 @@ out: | |||
721 | return rc; | 433 | return rc; |
722 | } | 434 | } |
723 | 435 | ||
724 | /** | ||
725 | * ecryptfs_write_zeros | ||
726 | * @file: The ecryptfs file | ||
727 | * @index: The index in which we are writing | ||
728 | * @start: The position after the last block of data | ||
729 | * @num_zeros: The number of zeros to write | ||
730 | * | ||
731 | * Write a specified number of zero's to a page. | ||
732 | * | ||
733 | * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE | ||
734 | */ | ||
735 | int | ||
736 | ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | ||
737 | { | ||
738 | int rc = 0; | ||
739 | struct page *tmp_page; | ||
740 | |||
741 | tmp_page = ecryptfs_get1page(file, index); | ||
742 | if (IS_ERR(tmp_page)) { | ||
743 | ecryptfs_printk(KERN_ERR, "Error getting page at index " | ||
744 | "[0x%.16x]\n", index); | ||
745 | rc = PTR_ERR(tmp_page); | ||
746 | goto out; | ||
747 | } | ||
748 | rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start, | ||
749 | (start + num_zeros)); | ||
750 | if (rc) { | ||
751 | ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " | ||
752 | "to page at index [0x%.16x]\n", | ||
753 | index); | ||
754 | page_cache_release(tmp_page); | ||
755 | goto out; | ||
756 | } | ||
757 | zero_user_page(tmp_page, start, num_zeros, KM_USER0); | ||
758 | rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros); | ||
759 | if (rc < 0) { | ||
760 | ecryptfs_printk(KERN_ERR, "Error attempting to write zero's " | ||
761 | "to remainder of page at index [0x%.16x]\n", | ||
762 | index); | ||
763 | page_cache_release(tmp_page); | ||
764 | goto out; | ||
765 | } | ||
766 | rc = 0; | ||
767 | page_cache_release(tmp_page); | ||
768 | out: | ||
769 | return rc; | ||
770 | } | ||
771 | |||
772 | static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block) | 436 | static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block) |
773 | { | 437 | { |
774 | int rc = 0; | 438 | int rc = 0; |