[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:
Родитель
e77a56ddce
Коммит
70456600f4
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче