fuse: truncate pending writes on O_TRUNC
[linux-2.6-microblaze.git] / fs / fuse / file.c
index 56ed45e..6edf949 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/falloc.h>
 #include <linux/uio.h>
 
-struct page **fuse_pages_alloc(unsigned int npages, gfp_t flags,
-                              struct fuse_page_desc **desc)
+static struct page **fuse_pages_alloc(unsigned int npages, gfp_t flags,
+                                     struct fuse_page_desc **desc)
 {
        struct page **pages;
 
@@ -63,12 +63,13 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
 {
        struct fuse_file *ff;
 
-       ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
+       ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL_ACCOUNT);
        if (unlikely(!ff))
                return NULL;
 
        ff->fc = fc;
-       ff->release_args = kzalloc(sizeof(*ff->release_args), GFP_KERNEL);
+       ff->release_args = kzalloc(sizeof(*ff->release_args),
+                                  GFP_KERNEL_ACCOUNT);
        if (!ff->release_args) {
                kfree(ff);
                return NULL;
@@ -216,7 +217,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        int err;
-       bool lock_inode = (file->f_flags & O_TRUNC) &&
+       bool is_wb_truncate = (file->f_flags & O_TRUNC) &&
                          fc->atomic_o_trunc &&
                          fc->writeback_cache;
 
@@ -224,16 +225,20 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
        if (err)
                return err;
 
-       if (lock_inode)
+       if (is_wb_truncate) {
                inode_lock(inode);
+               fuse_set_nowrite(inode);
+       }
 
        err = fuse_do_open(fc, get_node_id(inode), file, isdir);
 
        if (!err)
                fuse_finish_open(inode, file);
 
-       if (lock_inode)
+       if (is_wb_truncate) {
+               fuse_release_nowrite(inode);
                inode_unlock(inode);
+       }
 
        return err;
 }
@@ -1861,6 +1866,7 @@ static int fuse_writepage(struct page *page, struct writeback_control *wbc)
                WARN_ON(wbc->sync_mode == WB_SYNC_ALL);
 
                redirty_page_for_writepage(wbc, page);
+               unlock_page(page);
                return 0;
        }