GIT: unionfs2-2.6.27.y: bugfix: handle lower file systems that do not support writeable mappings
Erez Zadok
ezk at fsl.cs.sunysb.edu
Thu Aug 12 23:16:25 EDT 2010
commit 1344039aec46038cfb826e2cd12600564b53736d
Author: Erez_Zadok <ezk at cs.sunysb.edu>
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 <ezk at cs.sunysb.edu>
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);
More information about the unionfs-cvs
mailing list