GIT: unionfs2-2.6.27.y: mmap: file revalidation and fanout invariant validation
Erez Zadok
ezk at fsl.cs.sunysb.edu
Thu Aug 12 23:16:23 EDT 2010
commit 352e1cfc2c8a8a874d126846b0c21faac2fbaa9e
Author: Erez_Zadok <ezk at cs.sunysb.edu>
Date: Sat May 19 19:59:13 2007 -0400
mmap: file revalidation and fanout invariant validation
Added the newer checks to file revalidation and fanout invariants to the
newly merged mmap code. Also minor mmap related comments added.
diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index b0ec71b..0ae465a 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -609,13 +609,6 @@ int unionfs_file_release(struct inode *inode, struct file *file)
int bindex, bstart, bend;
int fgen, err = 0;
- unionfs_read_lock(sb);
- if ((err = unionfs_file_revalidate(file, 1)))
- goto out;
- fileinfo = UNIONFS_F(file);
- BUG_ON(file->f_dentry->d_inode != inode);
- inodeinfo = UNIONFS_I(inode);
-
unionfs_check_file(file);
unionfs_read_lock(sb);
/*
@@ -625,6 +618,9 @@ int unionfs_file_release(struct inode *inode, struct file *file)
*/
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
+ fileinfo = UNIONFS_F(file);
+ BUG_ON(file->f_dentry->d_inode != inode);
+ inodeinfo = UNIONFS_I(inode);
/* fput all the hidden files */
fgen = atomic_read(&fileinfo->generation);
diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
index ea8f24e..18203a3 100644
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -275,7 +275,8 @@ static int __copyup_reg_data(struct dentry *dentry,
kfree(buf);
if (!err)
- err = output_file->f_op->fsync(output_file, new_hidden_dentry, 0);
+ err = output_file->f_op->fsync(output_file,
+ new_hidden_dentry, 0);
if (err)
goto out_close_out;
diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
index 1c20844..59b1c91 100644
--- a/fs/unionfs/file.c
+++ b/fs/unionfs/file.c
@@ -28,6 +28,7 @@ static ssize_t unionfs_read(struct file *file, char __user *buf,
int err;
unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
if ((err = unionfs_file_revalidate(file, 0)))
goto out;
@@ -46,30 +47,35 @@ out:
static ssize_t unionfs_aio_read(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
- int err;
-#error fixme fxn check_file? read_unlock?
+ int err = 0;
+ struct file *file = iocb->ki_filp;
+
+ unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
+ if ((err = unionfs_file_revalidate(file, 0)))
+ goto out;
+
err = generic_file_aio_read(iocb, iov, nr_segs, pos);
if (err == -EIOCBQUEUED)
err = wait_on_sync_kiocb(iocb);
if (err >= 0)
- touch_atime(unionfs_lower_mnt(iocb->ki_filp->f_path.dentry),
- unionfs_lower_dentry(iocb->ki_filp->f_path.dentry));
+ touch_atime(unionfs_lower_mnt(file->f_path.dentry),
+ unionfs_lower_dentry(file->f_path.dentry));
-#if 0
out:
unionfs_read_unlock(file->f_dentry->d_sb);
unionfs_check_file(file);
-#endif
return err;
}
static ssize_t unionfs_write(struct file * file, const char __user * buf,
- size_t count, loff_t * ppos)
+ size_t count, loff_t *ppos)
{
int err = 0;
unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
@@ -93,6 +99,10 @@ static int unionfs_mmap(struct file *file, struct vm_area_struct *vma)
int willwrite;
unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
+ if ((err = unionfs_file_revalidate(file, 1)))
+ goto out;
+
/* This might be deferred to mmap's writepage */
willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
if ((err = unionfs_file_revalidate(file, willwrite)))
diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index 79abe8a..d3e0a4f 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -1084,6 +1084,7 @@ static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
break;
}
+ /* for mmap */
if (ia->ia_valid & ATTR_SIZE) {
if (ia->ia_size != i_size_read(inode)) {
err = vmtruncate(inode, ia->ia_size);
diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c
index 93aba3a..ccad33f 100644
--- a/fs/unionfs/mmap.c
+++ b/fs/unionfs/mmap.c
@@ -163,8 +163,9 @@ int unionfs_readpage(struct file *file, struct page *page)
int err;
unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
if ((err = unionfs_file_revalidate(file, 0)))
- goto out_err;
+ goto out;
err = unionfs_do_readpage(file, page);
@@ -177,9 +178,9 @@ int unionfs_readpage(struct file *file, struct page *page)
* page. but we no longer have to wakeup on our page here, b/c
* UnlockPage does it
*/
-
-out_err:
+out:
unlock_page(page);
+ unionfs_check_file(file);
unionfs_read_unlock(file->f_dentry->d_sb);
return err;
@@ -191,7 +192,9 @@ int unionfs_prepare_write(struct file *file, struct page *page, unsigned from,
int err;
unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
err = unionfs_file_revalidate(file, 1);
+ unionfs_check_file(file);
unionfs_read_unlock(file->f_dentry->d_sb);
return err;
@@ -211,6 +214,7 @@ int unionfs_commit_write(struct file *file, struct page *page, unsigned from,
BUG_ON(file == NULL);
unionfs_read_lock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
@@ -220,7 +224,8 @@ int unionfs_commit_write(struct file *file, struct page *page, unsigned from,
if (UNIONFS_F(file) != NULL)
lower_file = unionfs_lower_file(file);
- BUG_ON(lower_file == NULL); /* FIXME: is this assertion right here? */
+ /* FIXME: is this assertion right here? */
+ BUG_ON(lower_file == NULL);
page_data = (char *)kmap(page);
lower_file->f_pos = (page->index << PAGE_CACHE_SHIFT) + from;
@@ -261,6 +266,7 @@ out:
ClearPageUptodate(page);
unionfs_read_unlock(file->f_dentry->d_sb);
+ unionfs_check_file(file);
return err; /* assume all is ok */
}
@@ -281,6 +287,10 @@ void unionfs_sync_page(struct page *page)
/* do the actual sync */
mapping = lower_page->mapping;
+ /*
+ * XXX: can we optimize ala RAIF and set the lower page to be
+ * discarded after a successful sync_page?
+ */
if (mapping && mapping->a_ops && mapping->a_ops->sync_page)
mapping->a_ops->sync_page(lower_page);
More information about the unionfs-cvs
mailing list