Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
[cascardo/linux.git] / fs / fuse / inode.c
index a8b31da..9e3f68c 100644 (file)
@@ -71,6 +71,11 @@ struct fuse_mount_data {
        unsigned blksize;
 };
 
+struct fuse_forget_link *fuse_alloc_forget()
+{
+       return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL);
+}
+
 static struct inode *fuse_alloc_inode(struct super_block *sb)
 {
        struct inode *inode;
@@ -90,8 +95,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
        INIT_LIST_HEAD(&fi->queued_writes);
        INIT_LIST_HEAD(&fi->writepages);
        init_waitqueue_head(&fi->page_waitq);
-       fi->forget_req = fuse_request_alloc();
-       if (!fi->forget_req) {
+       fi->forget = fuse_alloc_forget();
+       if (!fi->forget) {
                kmem_cache_free(fuse_inode_cachep, inode);
                return NULL;
        }
@@ -111,24 +116,10 @@ static void fuse_destroy_inode(struct inode *inode)
        struct fuse_inode *fi = get_fuse_inode(inode);
        BUG_ON(!list_empty(&fi->write_files));
        BUG_ON(!list_empty(&fi->queued_writes));
-       if (fi->forget_req)
-               fuse_request_free(fi->forget_req);
+       kfree(fi->forget);
        call_rcu(&inode->i_rcu, fuse_i_callback);
 }
 
-void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
-                     u64 nodeid, u64 nlookup)
-{
-       struct fuse_forget_in *inarg = &req->misc.forget_in;
-       inarg->nlookup = nlookup;
-       req->in.h.opcode = FUSE_FORGET;
-       req->in.h.nodeid = nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(struct fuse_forget_in);
-       req->in.args[0].value = inarg;
-       fuse_request_send_noreply(fc, req);
-}
-
 static void fuse_evict_inode(struct inode *inode)
 {
        truncate_inode_pages(&inode->i_data, 0);
@@ -136,8 +127,8 @@ static void fuse_evict_inode(struct inode *inode)
        if (inode->i_sb->s_flags & MS_ACTIVE) {
                struct fuse_conn *fc = get_fuse_conn(inode);
                struct fuse_inode *fi = get_fuse_inode(inode);
-               fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
-               fi->forget_req = NULL;
+               fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
+               fi->forget = NULL;
        }
 }
 
@@ -541,6 +532,7 @@ void fuse_conn_init(struct fuse_conn *fc)
        INIT_LIST_HEAD(&fc->interrupts);
        INIT_LIST_HEAD(&fc->bg_queue);
        INIT_LIST_HEAD(&fc->entry);
+       fc->forget_list_tail = &fc->forget_list_head;
        atomic_set(&fc->num_waiting, 0);
        fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
        fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
@@ -625,10 +617,8 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
                goto out_iput;
 
        entry = d_obtain_alias(inode);
-       if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
-               d_set_d_op(entry, &fuse_dentry_operations);
+       if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID)
                fuse_invalidate_entry_cache(entry);
-       }
 
        return entry;
 
@@ -727,10 +717,8 @@ static struct dentry *fuse_get_parent(struct dentry *child)
        }
 
        parent = d_obtain_alias(inode);
-       if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
-               d_set_d_op(parent, &fuse_dentry_operations);
+       if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID)
                fuse_invalidate_entry_cache(parent);
-       }
 
        return parent;
 }
@@ -997,6 +985,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
                iput(root);
                goto err_put_conn;
        }
+       /* only now - we want root dentry with NULL ->d_op */
+       sb->s_d_op = &fuse_dentry_operations;
 
        init_req = fuse_request_alloc();
        if (!init_req)