[PATCH] eCryptfs: convert f_op->write() to vfs_write()
authorMichael Halcrow <mhalcrow@us.ibm.com>
Mon, 12 Feb 2007 08:53:48 +0000 (00:53 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 12 Feb 2007 17:48:37 +0000 (09:48 -0800)
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>
fs/ecryptfs/crypto.c
fs/ecryptfs/inode.c

index 44c2ec2e9e6af524c248f5ee96290b84ac3e4d17..2d7db61b9d6cc77ca926cd7e92d03013229ec46a 100644 (file)
@@ -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,
index bbc1b4f666fe04ccfe3e3fd8331924216fcfec0b..7d33917120278b95fc895cae40fd0c4f619161fe 100644 (file)
@@ -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