aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-10-16 04:28:14 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:12 -0400
commit16a72c455a67bb23eed7292a31c6ba17729e78e6 (patch)
treed2cc7d116730348375ce0d06ad45e24744cd0b5f
parentecbdc93639f69c1f237ccce6a9aaff1e83f1182f (diff)
ecryptfs: clean up page flag handling
The functions that eventually call down to ecryptfs_read_lower(), ecryptfs_decrypt_page(), and ecryptfs_copy_up_encrypted_with_header() should have the responsibility of managing the page Uptodate status. This patch gets rid of some of the ugliness that resulted from trying to push some of the page flag setting too far down the stack. 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>
-rw-r--r--fs/ecryptfs/crypto.c12
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h2
-rw-r--r--fs/ecryptfs/mmap.c28
-rw-r--r--fs/ecryptfs/read_write.c30
4 files changed, 39 insertions, 33 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index e890d596da7e..1ae90ef2c74d 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -605,14 +605,14 @@ int ecryptfs_decrypt_page(struct page *page)
605 printk(KERN_ERR "%s: Error attempting to copy " 605 printk(KERN_ERR "%s: Error attempting to copy "
606 "page at index [%ld]\n", __FUNCTION__, 606 "page at index [%ld]\n", __FUNCTION__,
607 page->index); 607 page->index);
608 goto out_clear_uptodate; 608 goto out;
609 } 609 }
610 enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); 610 enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
611 if (!enc_extent_virt) { 611 if (!enc_extent_virt) {
612 rc = -ENOMEM; 612 rc = -ENOMEM;
613 ecryptfs_printk(KERN_ERR, "Error allocating memory for " 613 ecryptfs_printk(KERN_ERR, "Error allocating memory for "
614 "encrypted extent\n"); 614 "encrypted extent\n");
615 goto out_clear_uptodate; 615 goto out;
616 } 616 }
617 enc_extent_page = virt_to_page(enc_extent_virt); 617 enc_extent_page = virt_to_page(enc_extent_virt);
618 for (extent_offset = 0; 618 for (extent_offset = 0;
@@ -631,21 +631,17 @@ int ecryptfs_decrypt_page(struct page *page)
631 ecryptfs_printk(KERN_ERR, "Error attempting " 631 ecryptfs_printk(KERN_ERR, "Error attempting "
632 "to read lower page; rc = [%d]" 632 "to read lower page; rc = [%d]"
633 "\n", rc); 633 "\n", rc);
634 goto out_clear_uptodate; 634 goto out;
635 } 635 }
636 rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page, 636 rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page,
637 extent_offset); 637 extent_offset);
638 if (rc) { 638 if (rc) {
639 printk(KERN_ERR "%s: Error encrypting extent; " 639 printk(KERN_ERR "%s: Error encrypting extent; "
640 "rc = [%d]\n", __FUNCTION__, rc); 640 "rc = [%d]\n", __FUNCTION__, rc);
641 goto out_clear_uptodate; 641 goto out;
642 } 642 }
643 extent_offset++; 643 extent_offset++;
644 } 644 }
645 SetPageUptodate(page);
646 goto out;
647out_clear_uptodate:
648 ClearPageUptodate(page);
649out: 645out:
650 kfree(enc_extent_virt); 646 kfree(enc_extent_virt);
651 return rc; 647 return rc;
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index bb92b74d66e9..ce7a5d4aec36 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -648,6 +648,6 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
648 struct inode *ecryptfs_inode); 648 struct inode *ecryptfs_inode);
649int ecryptfs_read(char *data, loff_t offset, size_t size, 649int ecryptfs_read(char *data, loff_t offset, size_t size,
650 struct file *ecryptfs_file); 650 struct file *ecryptfs_file);
651struct page *ecryptfs_get1page(struct file *file, loff_t index); 651struct page *ecryptfs_get_locked_page(struct file *file, loff_t index);
652 652
653#endif /* #ifndef ECRYPTFS_KERNEL_H */ 653#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 4eb09c1753c6..16a7a555f392 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -37,23 +37,27 @@
37struct kmem_cache *ecryptfs_lower_page_cache; 37struct kmem_cache *ecryptfs_lower_page_cache;
38 38
39/** 39/**
40 * ecryptfs_get1page 40 * ecryptfs_get_locked_page
41 * 41 *
42 * Get one page from cache or lower f/s, return error otherwise. 42 * Get one page from cache or lower f/s, return error otherwise.
43 * 43 *
44 * Returns unlocked and up-to-date page (if ok), with increased 44 * Returns locked and up-to-date page (if ok), with increased
45 * refcnt. 45 * refcnt.
46 */ 46 */
47struct page *ecryptfs_get1page(struct file *file, loff_t index) 47struct page *ecryptfs_get_locked_page(struct file *file, loff_t index)
48{ 48{
49 struct dentry *dentry; 49 struct dentry *dentry;
50 struct inode *inode; 50 struct inode *inode;
51 struct address_space *mapping; 51 struct address_space *mapping;
52 struct page *page;
52 53
53 dentry = file->f_path.dentry; 54 dentry = file->f_path.dentry;
54 inode = dentry->d_inode; 55 inode = dentry->d_inode;
55 mapping = inode->i_mapping; 56 mapping = inode->i_mapping;
56 return read_mapping_page(mapping, index, (void *)file); 57 page = read_mapping_page(mapping, index, (void *)file);
58 if (!IS_ERR(page))
59 lock_page(page);
60 return page;
57} 61}
58 62
59/** 63/**
@@ -146,12 +150,10 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
146 kunmap_atomic(page_virt, KM_USER0); 150 kunmap_atomic(page_virt, KM_USER0);
147 flush_dcache_page(page); 151 flush_dcache_page(page);
148 if (rc) { 152 if (rc) {
149 ClearPageUptodate(page);
150 printk(KERN_ERR "%s: Error reading xattr " 153 printk(KERN_ERR "%s: Error reading xattr "
151 "region; rc = [%d]\n", __FUNCTION__, rc); 154 "region; rc = [%d]\n", __FUNCTION__, rc);
152 goto out; 155 goto out;
153 } 156 }
154 SetPageUptodate(page);
155 } else { 157 } else {
156 /* This is an encrypted data extent */ 158 /* This is an encrypted data extent */
157 loff_t lower_offset = 159 loff_t lower_offset =
@@ -232,6 +234,10 @@ static int ecryptfs_readpage(struct file *file, struct page *page)
232 } 234 }
233 } 235 }
234out: 236out:
237 if (rc)
238 ClearPageUptodate(page);
239 else
240 SetPageUptodate(page);
235 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", 241 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
236 page->index); 242 page->index);
237 unlock_page(page); 243 unlock_page(page);
@@ -265,10 +271,18 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
265 if (from == 0 && to == PAGE_CACHE_SIZE) 271 if (from == 0 && to == PAGE_CACHE_SIZE)
266 goto out; /* If we are writing a full page, it will be 272 goto out; /* If we are writing a full page, it will be
267 up to date. */ 273 up to date. */
268 if (!PageUptodate(page)) 274 if (!PageUptodate(page)) {
269 rc = ecryptfs_read_lower_page_segment(page, page->index, 0, 275 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
270 PAGE_CACHE_SIZE, 276 PAGE_CACHE_SIZE,
271 page->mapping->host); 277 page->mapping->host);
278 if (rc) {
279 printk(KERN_ERR "%s: Error attemping to read lower "
280 "page segment; rc = [%d]\n", __FUNCTION__, rc);
281 ClearPageUptodate(page);
282 goto out;
283 } else
284 SetPageUptodate(page);
285 }
272 if (page->index != 0) { 286 if (page->index != 0) {
273 loff_t end_of_prev_pg_pos = 287 loff_t end_of_prev_pg_pos =
274 (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); 288 (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index 272eaeb9a738..2150edf9a58e 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -142,8 +142,8 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
142 if (num_bytes > total_remaining_zeros) 142 if (num_bytes > total_remaining_zeros)
143 num_bytes = total_remaining_zeros; 143 num_bytes = total_remaining_zeros;
144 } 144 }
145 ecryptfs_page = ecryptfs_get1page(ecryptfs_file, 145 ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file,
146 ecryptfs_page_idx); 146 ecryptfs_page_idx);
147 if (IS_ERR(ecryptfs_page)) { 147 if (IS_ERR(ecryptfs_page)) {
148 rc = PTR_ERR(ecryptfs_page); 148 rc = PTR_ERR(ecryptfs_page);
149 printk(KERN_ERR "%s: Error getting page at " 149 printk(KERN_ERR "%s: Error getting page at "
@@ -161,6 +161,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
161 printk(KERN_ERR "%s: Error decrypting " 161 printk(KERN_ERR "%s: Error decrypting "
162 "page; rc = [%d]\n", 162 "page; rc = [%d]\n",
163 __FUNCTION__, rc); 163 __FUNCTION__, rc);
164 ClearPageUptodate(ecryptfs_page);
164 page_cache_release(ecryptfs_page); 165 page_cache_release(ecryptfs_page);
165 goto out; 166 goto out;
166 } 167 }
@@ -180,14 +181,15 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
180 } 181 }
181 kunmap_atomic(ecryptfs_page_virt, KM_USER0); 182 kunmap_atomic(ecryptfs_page_virt, KM_USER0);
182 flush_dcache_page(ecryptfs_page); 183 flush_dcache_page(ecryptfs_page);
184 SetPageUptodate(ecryptfs_page);
185 unlock_page(ecryptfs_page);
183 rc = ecryptfs_encrypt_page(ecryptfs_page); 186 rc = ecryptfs_encrypt_page(ecryptfs_page);
187 page_cache_release(ecryptfs_page);
184 if (rc) { 188 if (rc) {
185 printk(KERN_ERR "%s: Error encrypting " 189 printk(KERN_ERR "%s: Error encrypting "
186 "page; rc = [%d]\n", __FUNCTION__, rc); 190 "page; rc = [%d]\n", __FUNCTION__, rc);
187 page_cache_release(ecryptfs_page);
188 goto out; 191 goto out;
189 } 192 }
190 page_cache_release(ecryptfs_page);
191 pos += num_bytes; 193 pos += num_bytes;
192 } 194 }
193 if ((offset + size) > ecryptfs_file_size) { 195 if ((offset + size) > ecryptfs_file_size) {
@@ -225,7 +227,6 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
225 ecryptfs_inode_to_private(ecryptfs_inode); 227 ecryptfs_inode_to_private(ecryptfs_inode);
226 ssize_t octets_read; 228 ssize_t octets_read;
227 mm_segment_t fs_save; 229 mm_segment_t fs_save;
228 size_t i;
229 int rc = 0; 230 int rc = 0;
230 231
231 mutex_lock(&inode_info->lower_file_mutex); 232 mutex_lock(&inode_info->lower_file_mutex);
@@ -242,16 +243,6 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
242 rc = -EINVAL; 243 rc = -EINVAL;
243 } 244 }
244 mutex_unlock(&inode_info->lower_file_mutex); 245 mutex_unlock(&inode_info->lower_file_mutex);
245 for (i = 0; i < size; i += PAGE_CACHE_SIZE) {
246 struct page *data_page;
247
248 data_page = virt_to_page(data + i);
249 flush_dcache_page(data_page);
250 if (rc)
251 ClearPageUptodate(data_page);
252 else
253 SetPageUptodate(data_page);
254 }
255 return rc; 246 return rc;
256} 247}
257 248
@@ -283,6 +274,7 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
283 virt = kmap(page_for_ecryptfs); 274 virt = kmap(page_for_ecryptfs);
284 rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); 275 rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);
285 kunmap(page_for_ecryptfs); 276 kunmap(page_for_ecryptfs);
277 flush_dcache_page(page_for_ecryptfs);
286 return rc; 278 return rc;
287} 279}
288 280
@@ -331,8 +323,8 @@ int ecryptfs_read(char *data, loff_t offset, size_t size,
331 323
332 if (num_bytes > total_remaining_bytes) 324 if (num_bytes > total_remaining_bytes)
333 num_bytes = total_remaining_bytes; 325 num_bytes = total_remaining_bytes;
334 ecryptfs_page = ecryptfs_get1page(ecryptfs_file, 326 ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file,
335 ecryptfs_page_idx); 327 ecryptfs_page_idx);
336 if (IS_ERR(ecryptfs_page)) { 328 if (IS_ERR(ecryptfs_page)) {
337 rc = PTR_ERR(ecryptfs_page); 329 rc = PTR_ERR(ecryptfs_page);
338 printk(KERN_ERR "%s: Error getting page at " 330 printk(KERN_ERR "%s: Error getting page at "
@@ -345,6 +337,7 @@ int ecryptfs_read(char *data, loff_t offset, size_t size,
345 if (rc) { 337 if (rc) {
346 printk(KERN_ERR "%s: Error decrypting " 338 printk(KERN_ERR "%s: Error decrypting "
347 "page; rc = [%d]\n", __FUNCTION__, rc); 339 "page; rc = [%d]\n", __FUNCTION__, rc);
340 ClearPageUptodate(ecryptfs_page);
348 page_cache_release(ecryptfs_page); 341 page_cache_release(ecryptfs_page);
349 goto out; 342 goto out;
350 } 343 }
@@ -353,6 +346,9 @@ int ecryptfs_read(char *data, loff_t offset, size_t size,
353 ((char *)ecryptfs_page_virt + start_offset_in_page), 346 ((char *)ecryptfs_page_virt + start_offset_in_page),
354 num_bytes); 347 num_bytes);
355 kunmap_atomic(ecryptfs_page_virt, KM_USER0); 348 kunmap_atomic(ecryptfs_page_virt, KM_USER0);
349 flush_dcache_page(ecryptfs_page);
350 SetPageUptodate(ecryptfs_page);
351 unlock_page(ecryptfs_page);
356 page_cache_release(ecryptfs_page); 352 page_cache_release(ecryptfs_page);
357 pos += num_bytes; 353 pos += num_bytes;
358 data_offset += num_bytes; 354 data_offset += num_bytes;