diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-02-12 03:53:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:37 -0500 |
commit | 70456600f42f85cfcbdd9d7a6029c03b6f9c5d1e (patch) | |
tree | 1b47957d59bfe3b4e5e5244106678f5542f8f295 | |
parent | e77a56ddceeec87575a13a60fc1a394af6a1f4bc (diff) |
[PATCH] eCryptfs: convert f_op->write() to vfs_write()
sys_write() takes a local copy of f_pos and writes that back
into the struct file. It does this so that two concurrent write()
callers don't make a mess of f_pos, and of the file contents.
ecryptfs should be calling vfs_write(). That way we also get the fsnotify
notifications, which ecryptfs presently appears to have subverted.
Convert direct calls to f_op->write() into calls to vfs_write().
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.c | 27 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 2 |
2 files changed, 23 insertions, 6 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 44c2ec2e9e6a..2d7db61b9d6c 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1344,24 +1344,41 @@ static int ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt | |||
1344 | mm_segment_t oldfs; | 1344 | mm_segment_t oldfs; |
1345 | int current_header_page; | 1345 | int current_header_page; |
1346 | int header_pages; | 1346 | int header_pages; |
1347 | ssize_t size; | ||
1348 | int rc = 0; | ||
1347 | 1349 | ||
1348 | lower_file->f_pos = 0; | 1350 | lower_file->f_pos = 0; |
1349 | oldfs = get_fs(); | 1351 | oldfs = get_fs(); |
1350 | set_fs(get_ds()); | 1352 | set_fs(get_ds()); |
1351 | lower_file->f_op->write(lower_file, (char __user *)page_virt, | 1353 | size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE, |
1352 | PAGE_CACHE_SIZE, &lower_file->f_pos); | 1354 | &lower_file->f_pos); |
1355 | if (size < 0) { | ||
1356 | rc = (int)size; | ||
1357 | printk(KERN_ERR "Error attempting to write lower page; " | ||
1358 | "rc = [%d]\n", rc); | ||
1359 | set_fs(oldfs); | ||
1360 | goto out; | ||
1361 | } | ||
1353 | header_pages = ((crypt_stat->header_extent_size | 1362 | header_pages = ((crypt_stat->header_extent_size |
1354 | * crypt_stat->num_header_extents_at_front) | 1363 | * crypt_stat->num_header_extents_at_front) |
1355 | / PAGE_CACHE_SIZE); | 1364 | / PAGE_CACHE_SIZE); |
1356 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1365 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
1357 | current_header_page = 1; | 1366 | current_header_page = 1; |
1358 | while (current_header_page < header_pages) { | 1367 | while (current_header_page < header_pages) { |
1359 | lower_file->f_op->write(lower_file, (char __user *)page_virt, | 1368 | size = vfs_write(lower_file, (char __user *)page_virt, |
1360 | PAGE_CACHE_SIZE, &lower_file->f_pos); | 1369 | PAGE_CACHE_SIZE, &lower_file->f_pos); |
1370 | if (size < 0) { | ||
1371 | rc = (int)size; | ||
1372 | printk(KERN_ERR "Error attempting to write lower page; " | ||
1373 | "rc = [%d]\n", rc); | ||
1374 | set_fs(oldfs); | ||
1375 | goto out; | ||
1376 | } | ||
1361 | current_header_page++; | 1377 | current_header_page++; |
1362 | } | 1378 | } |
1363 | set_fs(oldfs); | 1379 | set_fs(oldfs); |
1364 | return 0; | 1380 | out: |
1381 | return rc; | ||
1365 | } | 1382 | } |
1366 | 1383 | ||
1367 | static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | 1384 | static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index bbc1b4f666fe..7d3391712027 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -201,7 +201,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
201 | lower_dentry->d_name.name); | 201 | lower_dentry->d_name.name); |
202 | inode = ecryptfs_dentry->d_inode; | 202 | inode = ecryptfs_dentry->d_inode; |
203 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 203 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
204 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; | 204 | lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR; |
205 | #if BITS_PER_LONG != 32 | 205 | #if BITS_PER_LONG != 32 |
206 | lower_flags |= O_LARGEFILE; | 206 | lower_flags |= O_LARGEFILE; |
207 | #endif | 207 | #endif |