summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-02-12 00:53:48 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 09:48:37 -0800
commit70456600f42f85cfcbdd9d7a6029c03b6f9c5d1e (patch)
tree1b47957d59bfe3b4e5e5244106678f5542f8f295 /fs
parente77a56ddceeec87575a13a60fc1a394af6a1f4bc (diff)
downloadlinux-70456600f42f85cfcbdd9d7a6029c03b6f9c5d1e.tar.gz
linux-70456600f42f85cfcbdd9d7a6029c03b6f9c5d1e.tar.bz2
linux-70456600f42f85cfcbdd9d7a6029c03b6f9c5d1e.zip
[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>
Diffstat (limited to 'fs')
-rw-r--r--fs/ecryptfs/crypto.c27
-rw-r--r--fs/ecryptfs/inode.c2
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
mm_segment_t oldfs;
int current_header_page;
int header_pages;
+ ssize_t size;
+ int rc = 0;
lower_file->f_pos = 0;
oldfs = get_fs();
set_fs(get_ds());
- lower_file->f_op->write(lower_file, (char __user *)page_virt,
- PAGE_CACHE_SIZE, &lower_file->f_pos);
+ size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE,
+ &lower_file->f_pos);
+ if (size < 0) {
+ rc = (int)size;
+ printk(KERN_ERR "Error attempting to write lower page; "
+ "rc = [%d]\n", rc);
+ set_fs(oldfs);
+ goto out;
+ }
header_pages = ((crypt_stat->header_extent_size
* crypt_stat->num_header_extents_at_front)
/ PAGE_CACHE_SIZE);
memset(page_virt, 0, PAGE_CACHE_SIZE);
current_header_page = 1;
while (current_header_page < header_pages) {
- lower_file->f_op->write(lower_file, (char __user *)page_virt,
- PAGE_CACHE_SIZE, &lower_file->f_pos);
+ size = vfs_write(lower_file, (char __user *)page_virt,
+ PAGE_CACHE_SIZE, &lower_file->f_pos);
+ if (size < 0) {
+ rc = (int)size;
+ printk(KERN_ERR "Error attempting to write lower page; "
+ "rc = [%d]\n", rc);
+ set_fs(oldfs);
+ goto out;
+ }
current_header_page++;
}
set_fs(oldfs);
- return 0;
+out:
+ return rc;
}
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)
lower_dentry->d_name.name);
inode = ecryptfs_dentry->d_inode;
crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
- lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
+ lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR;
#if BITS_PER_LONG != 32
lower_flags |= O_LARGEFILE;
#endif