lkml.org 
[lkml]   [2007]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 17/22] fuse: writable shared mmap support
From: Miklos Szeredi <mszeredi@suse.cz>

Change fuse_file_mmap() to allow shared writable mappings. Change the
->set_page_dirty address space operation to __set_page_dirty_nobuffers.

In fuse_fsync() sync the inode's dirty data.

It is important, that after all writable file are closed, no more
dirty pages remain for the inode. So write back dirty pages from
munmap().

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
---

Index: linux/fs/fuse/file.c
===================================================================
--- linux.orig/fs/fuse/file.c 2007-02-27 14:41:12.000000000 +0100
+++ linux/fs/fuse/file.c 2007-02-27 14:41:12.000000000 +0100
@@ -253,6 +253,11 @@ int fuse_fsync_common(struct file *file,
if (is_bad_inode(inode))
return -EIO;

+ /* Wait for all outstanding writes, before sending the FSYNC request */
+ err = write_inode_now(de->d_inode, 0);
+ if (err)
+ return err;
+
if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
return 0;

@@ -764,21 +769,39 @@ static int fuse_launder_page(struct page
return err;
}

-static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
+static void fuse_vma_close(struct vm_area_struct *vma)
{
- if ((vma->vm_flags & VM_SHARED)) {
- if ((vma->vm_flags & VM_WRITE))
- return -ENODEV;
- else
- vma->vm_flags &= ~VM_MAYWRITE;
- }
- return generic_file_mmap(file, vma);
+ /*
+ * Write back dirty pages now, because there may not
+ * be any suitable open files later
+ */
+ filemap_write_and_wait(vma->vm_file->f_mapping);
}

-static int fuse_set_page_dirty(struct page *page)
+static struct vm_operations_struct fuse_file_vm_ops = {
+ .close = fuse_vma_close,
+ .nopage = filemap_nopage,
+ .populate = filemap_populate,
+};
+
+static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
{
- printk("fuse_set_page_dirty: should not happen\n");
- dump_stack();
+ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
+ struct inode *inode = file->f_dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ struct fuse_file *ff = file->private_data;
+ /*
+ * file may be written through mmap, so chain it onto the
+ * inodes's write_file list
+ */
+ spin_lock(&fc->lock);
+ if (list_empty(&ff->write_entry))
+ list_add(&ff->write_entry, &fi->write_files);
+ spin_unlock(&fc->lock);
+ }
+ file_accessed(file);
+ vma->vm_ops = &fuse_file_vm_ops;
return 0;
}

@@ -972,7 +995,7 @@ static const struct address_space_operat
.prepare_write = fuse_prepare_write,
.commit_write = fuse_commit_write,
.readpages = fuse_readpages,
- .set_page_dirty = fuse_set_page_dirty,
+ .set_page_dirty = __set_page_dirty_nobuffers,
.bmap = fuse_bmap,
};

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2007-02-28 00:25    [W:0.168 / U:0.044 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site