aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r--fs/ecryptfs/mmap.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 16a7a555f39..32c5711d79a 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -263,14 +263,13 @@ out:
263 return 0; 263 return 0;
264} 264}
265 265
266/* This function must zero any hole we create */
266static int ecryptfs_prepare_write(struct file *file, struct page *page, 267static int ecryptfs_prepare_write(struct file *file, struct page *page,
267 unsigned from, unsigned to) 268 unsigned from, unsigned to)
268{ 269{
269 int rc = 0; 270 int rc = 0;
271 loff_t prev_page_end_size;
270 272
271 if (from == 0 && to == PAGE_CACHE_SIZE)
272 goto out; /* If we are writing a full page, it will be
273 up to date. */
274 if (!PageUptodate(page)) { 273 if (!PageUptodate(page)) {
275 rc = ecryptfs_read_lower_page_segment(page, page->index, 0, 274 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
276 PAGE_CACHE_SIZE, 275 PAGE_CACHE_SIZE,
@@ -283,22 +282,32 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
283 } else 282 } else
284 SetPageUptodate(page); 283 SetPageUptodate(page);
285 } 284 }
286 if (page->index != 0) {
287 loff_t end_of_prev_pg_pos =
288 (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
289 285
290 if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { 286 prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
287
288 /*
289 * If creating a page or more of holes, zero them out via truncate.
290 * Note, this will increase i_size.
291 */
292 if (page->index != 0) {
293 if (prev_page_end_size > i_size_read(page->mapping->host)) {
291 rc = ecryptfs_truncate(file->f_path.dentry, 294 rc = ecryptfs_truncate(file->f_path.dentry,
292 end_of_prev_pg_pos); 295 prev_page_end_size);
293 if (rc) { 296 if (rc) {
294 printk(KERN_ERR "Error on attempt to " 297 printk(KERN_ERR "Error on attempt to "
295 "truncate to (higher) offset [%lld];" 298 "truncate to (higher) offset [%lld];"
296 " rc = [%d]\n", end_of_prev_pg_pos, rc); 299 " rc = [%d]\n", prev_page_end_size, rc);
297 goto out; 300 goto out;
298 } 301 }
299 } 302 }
300 if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host)) 303 }
301 zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); 304 /*
305 * Writing to a new page, and creating a small hole from start of page?
306 * Zero it out.
307 */
308 if ((i_size_read(page->mapping->host) == prev_page_end_size) &&
309 (from != 0)) {
310 zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
302 } 311 }
303out: 312out:
304 return rc; 313 return rc;