commit bba0458641bab8289048d8ce777d435da990ca46
Author: Erez_Zadok <[EMAIL PROTECTED]>
Date:   Wed May 23 21:26:01 2007 -0400

    bugfix: handle lower file systems that do not support writeable mappings
    
    File systems such as jffs2 (tested in 2.6.22-rc22) do not have a
    ->writepage.  Make sure unionfs detects that conditions and returns EINVAL
    when a user tries to mmap such a file with VM_WRITE.
    
    Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>

diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
index 59b1c91..24a14b3 100644
--- a/fs/unionfs/file.c
+++ b/fs/unionfs/file.c
@@ -97,6 +97,7 @@ static int unionfs_mmap(struct file *file, struct 
vm_area_struct *vma)
 {
        int err = 0;
        int willwrite;
+       struct file *lower_file;
 
        unionfs_read_lock(file->f_dentry->d_sb);
        unionfs_check_file(file);
@@ -108,9 +109,26 @@ static int unionfs_mmap(struct file *file, struct 
vm_area_struct *vma)
        if ((err = unionfs_file_revalidate(file, willwrite)))
                goto out;
 
-       err = generic_file_mmap(file, vma);
-       if (err)
-               printk("unionfs: generic_file_mmap failed %d\n", err);
+       /*
+        * File systems which do not implement ->writepage may use
+        * generic_file_readonly_mmap as their ->mmap op.  If you call
+        * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL.
+        * But we cannot call the lower ->mmap op, so we can't tell that
+        * writeable mappings won't work.  Therefore, our only choice is to
+        * check if the lower file system supports the ->writepage, and if
+        * not, return EINVAL (the same error that
+        * generic_file_readonly_mmap returns in that case).
+        */
+       lower_file = unionfs_lower_file(file);
+       if (willwrite && !lower_file->f_mapping->a_ops->writepage) {
+               err = -EINVAL;
+               printk("unionfs: branch %d file system does not support "
+                      "writeable mmap\n", fbstart(file));
+       } else {
+               err = generic_file_mmap(file, vma);
+               if (err)
+                       printk("unionfs: generic_file_mmap failed %d\n", err);
+       }
 
 out:
        unionfs_read_unlock(file->f_dentry->d_sb);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to