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/file.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/file.c')
-rw-r--r-- | fs/ecryptfs/file.c | 59 |
1 files changed, 1 insertions, 58 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 9881b5c5de59..59288d817078 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -33,63 +33,6 @@ | |||
33 | #include "ecryptfs_kernel.h" | 33 | #include "ecryptfs_kernel.h" |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * ecryptfs_llseek | ||
37 | * @file: File we are seeking in | ||
38 | * @offset: The offset to seek to | ||
39 | * @origin: 2 - offset from i_size; 1 - offset from f_pos | ||
40 | * | ||
41 | * Returns the position we have seeked to, or negative on error | ||
42 | */ | ||
43 | static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin) | ||
44 | { | ||
45 | loff_t rv; | ||
46 | loff_t new_end_pos; | ||
47 | int rc; | ||
48 | int expanding_file = 0; | ||
49 | struct inode *inode = file->f_mapping->host; | ||
50 | |||
51 | /* If our offset is past the end of our file, we're going to | ||
52 | * need to grow it so we have a valid length of 0's */ | ||
53 | new_end_pos = offset; | ||
54 | switch (origin) { | ||
55 | case 2: | ||
56 | new_end_pos += i_size_read(inode); | ||
57 | expanding_file = 1; | ||
58 | break; | ||
59 | case 1: | ||
60 | new_end_pos += file->f_pos; | ||
61 | if (new_end_pos > i_size_read(inode)) { | ||
62 | ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) " | ||
63 | "> i_size_read(inode)(=[0x%.16x])\n", | ||
64 | new_end_pos, i_size_read(inode)); | ||
65 | expanding_file = 1; | ||
66 | } | ||
67 | break; | ||
68 | default: | ||
69 | if (new_end_pos > i_size_read(inode)) { | ||
70 | ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) " | ||
71 | "> i_size_read(inode)(=[0x%.16x])\n", | ||
72 | new_end_pos, i_size_read(inode)); | ||
73 | expanding_file = 1; | ||
74 | } | ||
75 | } | ||
76 | ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos); | ||
77 | if (expanding_file) { | ||
78 | rc = ecryptfs_truncate(file->f_path.dentry, new_end_pos); | ||
79 | if (rc) { | ||
80 | rv = rc; | ||
81 | ecryptfs_printk(KERN_ERR, "Error on attempt to " | ||
82 | "truncate to (higher) offset [0x%.16x];" | ||
83 | " rc = [%d]\n", new_end_pos, rc); | ||
84 | goto out; | ||
85 | } | ||
86 | } | ||
87 | rv = generic_file_llseek(file, offset, origin); | ||
88 | out: | ||
89 | return rv; | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * ecryptfs_read_update_atime | 36 | * ecryptfs_read_update_atime |
94 | * | 37 | * |
95 | * generic_file_read updates the atime of upper layer inode. But, it | 38 | * generic_file_read updates the atime of upper layer inode. But, it |
@@ -425,7 +368,7 @@ const struct file_operations ecryptfs_dir_fops = { | |||
425 | }; | 368 | }; |
426 | 369 | ||
427 | const struct file_operations ecryptfs_main_fops = { | 370 | const struct file_operations ecryptfs_main_fops = { |
428 | .llseek = ecryptfs_llseek, | 371 | .llseek = generic_file_llseek, |
429 | .read = do_sync_read, | 372 | .read = do_sync_read, |
430 | .aio_read = ecryptfs_read_update_atime, | 373 | .aio_read = ecryptfs_read_update_atime, |
431 | .write = do_sync_write, | 374 | .write = do_sync_write, |