[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>
This commit is contained in:
Michael Halcrow 2007-02-12 00:53:48 -08:00 коммит произвёл Linus Torvalds
Родитель e77a56ddce
Коммит 70456600f4
2 изменённых файлов: 23 добавлений и 6 удалений

Просмотреть файл

@ -1344,24 +1344,41 @@ static int ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt
mm_segment_t oldfs; mm_segment_t oldfs;
int current_header_page; int current_header_page;
int header_pages; int header_pages;
ssize_t size;
int rc = 0;
lower_file->f_pos = 0; lower_file->f_pos = 0;
oldfs = get_fs(); oldfs = get_fs();
set_fs(get_ds()); set_fs(get_ds());
lower_file->f_op->write(lower_file, (char __user *)page_virt, size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE,
PAGE_CACHE_SIZE, &lower_file->f_pos); &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 header_pages = ((crypt_stat->header_extent_size
* crypt_stat->num_header_extents_at_front) * crypt_stat->num_header_extents_at_front)
/ PAGE_CACHE_SIZE); / PAGE_CACHE_SIZE);
memset(page_virt, 0, PAGE_CACHE_SIZE); memset(page_virt, 0, PAGE_CACHE_SIZE);
current_header_page = 1; current_header_page = 1;
while (current_header_page < header_pages) { while (current_header_page < header_pages) {
lower_file->f_op->write(lower_file, (char __user *)page_virt, size = vfs_write(lower_file, (char __user *)page_virt,
PAGE_CACHE_SIZE, &lower_file->f_pos); 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++; current_header_page++;
} }
set_fs(oldfs); set_fs(oldfs);
return 0; out:
return rc;
} }
static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,

Просмотреть файл

@ -201,7 +201,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
lower_dentry->d_name.name); lower_dentry->d_name.name);
inode = ecryptfs_dentry->d_inode; inode = ecryptfs_dentry->d_inode;
crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; 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 #if BITS_PER_LONG != 32
lower_flags |= O_LARGEFILE; lower_flags |= O_LARGEFILE;
#endif #endif