request allocation improvements
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 22 Jun 2004 18:46:02 +0000 (18:46 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Tue, 22 Jun 2004 18:46:02 +0000 (18:46 +0000)
ChangeLog
kernel/dev.c
kernel/dir.c
kernel/file.c
kernel/fuse_i.h
kernel/inode.c

index b6bb446e17f8e265a506a41bfe6ad22835224c5e..6a60661cc101c9bda8f90b08f2e2375a329e7910 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2004-06-22  Miklos Szeredi <mszeredi@inf.bme.hu>
+
+       * No request allocation needed on inode and file release
+       
 2004-06-21  Miklos Szeredi <mszeredi@inf.bme.hu>
 
        * Fix possible inode leak in userspace in case of unfinished
index 84d4d990569741f91ad15e2888f7797c40c56ab5..72fdba4dfd5bbabf1e9f473117135c7f32df5dbb 100644 (file)
@@ -109,6 +109,7 @@ static struct fuse_req *do_get_request(struct fuse_conn *fc)
        memset(req, 0, sizeof(*req));
        INIT_LIST_HEAD(&req->list);
        init_waitqueue_head(&req->waitq);
+       req->preallocated = 1;
 
        return req;
 }
@@ -139,20 +140,16 @@ struct fuse_req *fuse_get_request_nonblock(struct fuse_conn *fc)
        return req;
 }
 
-struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc)
-{
-       down(&fc->unused_sem);
-       
-       return do_get_request(fc);
-}
-
-
 void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
 {
-       spin_lock(&fuse_lock);
-       list_add(&req->list, &fc->unused_list);
-       spin_unlock(&fuse_lock);
-       up(&fc->unused_sem);
+       if (!req->preallocated)
+               fuse_request_free(req);
+       else {
+               spin_lock(&fuse_lock);
+               list_add(&req->list, &fc->unused_list);
+               spin_unlock(&fuse_lock);
+               up(&fc->unused_sem);
+       }
 }
 
 /* Must be called with fuse_lock held, and unlocks it */
index 59cab49a9e34956e65b0231a08242da868b67b11..af41ab5dba8ba435c8e10336b996529e960ee941 100644 (file)
@@ -78,8 +78,6 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
                                   new_decode_dev(attr->rdev));
        } else
                printk("fuse_init_inode: bad file type: %o\n", inode->i_mode);
-
-       inode->u.generic_ip = inode;
 }
 
 struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
@@ -90,6 +88,13 @@ struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
        inode = iget(sb, ino);
        if (inode) {
                if (!inode->u.generic_ip) {
+                       struct fuse_req *req = fuse_request_alloc();
+                       if (!req) {
+                               iput(inode);
+                               inode = NULL;
+                               goto out;
+                       }
+                       inode->u.generic_ip = req;
                        inode->i_generation = generation;
                        fuse_init_inode(inode, attr);
                } else if (inode->i_generation != generation)
@@ -98,6 +103,7 @@ struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
                change_attributes(inode, attr);
                inode->i_version = version;
        }
+ out:
 
        return inode;
 }
index 128c1b8dacab3c60760710525b594e17b9ac8fb6..78ce854829114e63510d0ae8b70a8bcdc156c314 100644 (file)
 
 #ifndef KERNEL_2_6
 #define PageUptodate(page) Page_Uptodate(page)
-#ifndef NO_MM
 #ifndef filemap_fdatawrite
+#ifndef NO_MM
 #define filemap_fdatawrite filemap_fdatasync
-#endif
 #else
 #define filemap_fdatawrite do {} while (0)
 #endif
 #endif
+#endif
 
 static int fuse_open(struct inode *inode, struct file *file)
 {
        struct fuse_conn *fc = INO_FC(inode);
        struct fuse_req *req;
+       struct fuse_req *req2;
        struct fuse_open_in inarg;
        int err;
 
@@ -48,6 +49,12 @@ static int fuse_open(struct inode *inode, struct file *file)
        if (!req)
                return -ERESTARTSYS;
 
+       req2 = fuse_request_alloc();
+       if (!req2) {
+               fuse_put_request(fc, req);
+               return -ENOMEM;
+       }
+
        memset(&inarg, 0, sizeof(inarg));
        inarg.flags = file->f_flags & ~O_EXCL;
        req->in.h.opcode = FUSE_OPEN;
@@ -64,6 +71,10 @@ static int fuse_open(struct inode *inode, struct file *file)
                invalidate_inode_pages(inode);
 #endif
        }
+       if (err)
+               fuse_request_free(req2);
+       else
+               file->private_data = req2;
        fuse_put_request(fc, req);
        return err;
 }
@@ -72,12 +83,11 @@ static int fuse_release(struct inode *inode, struct file *file)
 {
        struct fuse_conn *fc = INO_FC(inode);
        struct fuse_open_in *inarg;
-       struct fuse_req *req;
+       struct fuse_req *req = file->private_data;
        
        if (file->f_mode & FMODE_WRITE)
                filemap_fdatawrite(inode->i_mapping);
 
-       req = fuse_get_request_nonint(fc);
        inarg = &req->misc.open_in;
        inarg->flags = file->f_flags & ~O_EXCL;
        req->in.h.opcode = FUSE_RELEASE;
index 7055d1783a1e7edfdd881768db56b23c9054b5f5..f83ac6ab236b311f28a59e36cd31fe2125cf0968 100644 (file)
@@ -113,6 +113,9 @@ struct fuse_req {
        /* The request has been sent to the client */
        unsigned int sent:1;
 
+       /* The request is preallocated */
+       unsigned int preallocated:1;
+
        /* The request is finished */
        unsigned int finished;
 
@@ -266,18 +269,23 @@ int fuse_fs_init(void);
 void fuse_fs_cleanup(void);
 
 
+/** 
+ * Allocate a request
+ */
+struct fuse_req *fuse_request_alloc(void);
+
 /**
- * Reserve a request
+ * Free a request
  */
-struct fuse_req *fuse_get_request(struct fuse_conn *fc);
+void fuse_request_free(struct fuse_req *req);
 
 /**
- * Reserve a request, non-iterruptable
+ * Reserve a preallocated request
  */
-struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
+struct fuse_req *fuse_get_request(struct fuse_conn *fc);
 
 /**
- * Reserve a request, non-blocking
+ * Reserve a preallocated request, non-blocking
  */
 struct fuse_req *fuse_get_request_nonblock(struct fuse_conn *fc);
 
index 83ac407340c2b5e6e7bcd009ee9ec1570d4c2738..afee16d2c2dd553e7ce7cf655e79647c5eb6990d 100644 (file)
@@ -60,13 +60,15 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, ino_t ino,
 static void fuse_clear_inode(struct inode *inode)
 {
        struct fuse_conn *fc = INO_FC(inode);
-       struct fuse_req *req;
+       struct fuse_req *req = inode->u.generic_ip;
        
-       if (fc == NULL)
+       if (fc == NULL) {
+               if (req)
+                       fuse_request_free(req);
                return;
-
-       req = fuse_get_request_nonint(fc);
-       fuse_send_forget(fc, req, inode->i_ino, inode->i_version);
+       }
+       if (req != NULL)
+               fuse_send_forget(fc, req, inode->i_ino, inode->i_version);
 }
 
 static void fuse_put_super(struct super_block *sb)