[PATCH] fuse: more flexible caching
[linux-2.6-block.git] / fs / fuse / file.c
index 224453557cf657698700aafd0630038cba00172a..a8dc88527fbe61421c5d199c40fa9d3254cebc73 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 
+static struct file_operations fuse_direct_io_file_operations;
+
 int fuse_open_common(struct inode *inode, struct file *file, int isdir)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
@@ -70,12 +72,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
        else
                request_send(fc, req);
        err = req->out.h.error;
-       if (!err && !(fc->flags & FUSE_KERNEL_CACHE))
-               invalidate_inode_pages(inode->i_mapping);
        if (err) {
                fuse_request_free(ff->release_req);
                kfree(ff);
        } else {
+               if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
+                       file->f_op = &fuse_direct_io_file_operations;
+               if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
+                       invalidate_inode_pages(inode->i_mapping);
                ff->fh = outarg.fh;
                file->private_data = ff;
        }
@@ -544,12 +548,6 @@ static struct address_space_operations fuse_file_aops  = {
 
 void fuse_init_file_inode(struct inode *inode)
 {
-       struct fuse_conn *fc = get_fuse_conn(inode);
-
-       if (fc->flags & FUSE_DIRECT_IO)
-               inode->i_fop = &fuse_direct_io_file_operations;
-       else {
-               inode->i_fop = &fuse_file_operations;
-               inode->i_data.a_ops = &fuse_file_aops;
-       }
+       inode->i_fop = &fuse_file_operations;
+       inode->i_data.a_ops = &fuse_file_aops;
 }