diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-05-23 16:58:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-23 23:14:15 -0400 |
commit | 53a2731f9310a66beaf55677229ab067c85ce4fa (patch) | |
tree | 6166f49b9205541a96696f648217c606cc9d9a0a /fs/ecryptfs/mmap.c | |
parent | 4acb3e2f97f41cf9b53182b494384467d3ceb304 (diff) |
eCryptfs: delay writing 0's after llseek until write
Delay writing 0's out in eCryptfs after a seek past the end of the file
until data is actually written.
http://www.opengroup.org/onlinepubs/009695399/functions/lseek.html
``The lseek() function shall not, by itself, extend the size of a
file.''
Without this fix, applications that lseek() past the end of the file without
writing will experience unexpected behavior.
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>
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r-- | fs/ecryptfs/mmap.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 88ea6697908f..55cec98a84e7 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -376,9 +376,31 @@ out: | |||
376 | return 0; | 376 | return 0; |
377 | } | 377 | } |
378 | 378 | ||
379 | /** | ||
380 | * eCryptfs does not currently support holes. When writing after a | ||
381 | * seek past the end of the file, eCryptfs fills in 0's through to the | ||
382 | * current location. The code to fill in the 0's to all the | ||
383 | * intermediate pages calls ecryptfs_prepare_write_no_truncate(). | ||
384 | */ | ||
385 | static int | ||
386 | ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page, | ||
387 | unsigned from, unsigned to) | ||
388 | { | ||
389 | int rc = 0; | ||
390 | |||
391 | if (from == 0 && to == PAGE_CACHE_SIZE) | ||
392 | goto out; /* If we are writing a full page, it will be | ||
393 | up to date. */ | ||
394 | if (!PageUptodate(page)) | ||
395 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
396 | out: | ||
397 | return rc; | ||
398 | } | ||
399 | |||
379 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 400 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
380 | unsigned from, unsigned to) | 401 | unsigned from, unsigned to) |
381 | { | 402 | { |
403 | loff_t pos; | ||
382 | int rc = 0; | 404 | int rc = 0; |
383 | 405 | ||
384 | if (from == 0 && to == PAGE_CACHE_SIZE) | 406 | if (from == 0 && to == PAGE_CACHE_SIZE) |
@@ -386,6 +408,16 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
386 | up to date. */ | 408 | up to date. */ |
387 | if (!PageUptodate(page)) | 409 | if (!PageUptodate(page)) |
388 | rc = ecryptfs_do_readpage(file, page, page->index); | 410 | rc = ecryptfs_do_readpage(file, page, page->index); |
411 | pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; | ||
412 | if (pos > i_size_read(page->mapping->host)) { | ||
413 | rc = ecryptfs_truncate(file->f_path.dentry, pos); | ||
414 | if (rc) { | ||
415 | printk(KERN_ERR "Error on attempt to " | ||
416 | "truncate to (higher) offset [%lld];" | ||
417 | " rc = [%d]\n", pos, rc); | ||
418 | goto out; | ||
419 | } | ||
420 | } | ||
389 | out: | 421 | out: |
390 | return rc; | 422 | return rc; |
391 | } | 423 | } |
@@ -744,10 +776,10 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | |||
744 | rc = PTR_ERR(tmp_page); | 776 | rc = PTR_ERR(tmp_page); |
745 | goto out; | 777 | goto out; |
746 | } | 778 | } |
747 | rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros); | 779 | if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start, |
748 | if (rc) { | 780 | (start + num_zeros)))) { |
749 | ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " | 781 | ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " |
750 | "to remainder of page at index [0x%.16x]\n", | 782 | "to page at index [0x%.16x]\n", |
751 | index); | 783 | index); |
752 | page_cache_release(tmp_page); | 784 | page_cache_release(tmp_page); |
753 | goto out; | 785 | goto out; |