Unionfs: support splice(2)
authorErez Zadok <ezk@cs.sunysb.edu>
Tue, 27 Nov 2007 00:53:43 +0000 (19:53 -0500)
committerErez Zadok <ezk@cs.sunysb.edu>
Tue, 27 Nov 2007 00:53:43 +0000 (19:53 -0500)
Also remove redundant variable from unionfs_readpage (saves a bit on stack
space).

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
fs/unionfs/mmap.c

index 369204508498428bb35a974c9b92b622d5c35159..ff2f006e29e899677346d798ea4093e99d8edc40 100644 (file)
@@ -174,7 +174,7 @@ static int unionfs_readpage(struct file *file, struct page *page)
        struct inode *inode;
        mm_segment_t old_fs;
        char *page_data = NULL;
-       loff_t offset;
+       mode_t orig_mode;
 
        unionfs_read_lock(file->f_dentry->d_sb);
        err = unionfs_file_revalidate(file, false);
@@ -202,11 +202,17 @@ static int unionfs_readpage(struct file *file, struct page *page)
         * the necessary magic for us.
         */
        lower_file->f_pos = page_offset(page);
-       offset = page_offset(page);
        old_fs = get_fs();
        set_fs(KERNEL_DS);
+       /*
+        * generic_file_splice_write may call us on a file not opened for
+        * reading, so temporarily allow reading.
+        */
+       orig_mode = lower_file->f_mode;
+       lower_file->f_mode |= FMODE_READ;
        err = vfs_read(lower_file, page_data, PAGE_CACHE_SIZE,
                       &lower_file->f_pos);
+       lower_file->f_mode = orig_mode;
        set_fs(old_fs);
        if (err >= 0 && err < PAGE_CACHE_SIZE)
                memset(page_data + err, 0, PAGE_CACHE_SIZE - err);