commit c8c8416f309a160ba09f49689fb4136fb1cb769e
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Wed Mar 14 18:19:22 2007 -0400

    separated asynchronous threads from sioq, so they don't enter the workqueue
    
    sioa is now responsible for running asynchronous threads

diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 4eb2cfd..bd8285a 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -9,7 +9,7 @@ struct odf_sb_info* odf_read_super(char *options)
        struct nameidata nd;
        struct odf_sb_info *osi;
        char *odffile = NULL;
-       struct sioq_args *sioq;
+       struct sioa_args *sioa;
        int err = 0;
        
        err = odf_parse_options(options, &odffile);
@@ -60,17 +60,15 @@ struct odf_sb_info* odf_read_super(char *options)
                goto out_free;
        }       
        
-       /* start the reclaim sioq */
-       sioq = kmalloc(sizeof(struct sioq_args), GFP_KERNEL);
-       if (!sioq) {
+       /* start the reclaim sioa */
+       sioa = kmalloc(sizeof(struct sioa_args), GFP_KERNEL);
+       if (!sioa) {
                err = -ENOMEM;
                goto out_free;
        }
-       sioq->reclaim.process = NULL;
-       sioq->reclaim.odf = osi;
-       sioq->reclaim.timeout = ODF_RC_TIMEOUT;
-       osi->sioq = sioq;
-       run_sioq_async(__unionfs_reclaim, sioq);
+       sioa->reclaim.odf = osi;
+       osi->sioa = sioa;
+       run_sioa(sioa, __unionfs_reclaim_w, __unionfs_reclaim_d, 
ODF_RC_TIMEOUT);
 
        osi->mnt = nd.mnt;
        mntget(osi->mnt);
@@ -106,9 +104,9 @@ void odf_put_super(struct odf_sb_info *osi)
        dput(osi->mnt->mnt_sb->s_root);
        mntput(osi->mnt);
        osi->odi_rc = NULL;
-       wake_up_process(osi->sioq->reclaim.process);
-       wait_for_completion(&osi->sioq->comp);
-       kfree(osi->sioq);
+       wake_up_process(osi->sioa->process);
+       wait_for_completion(&osi->sioa->comp);
+       kfree(osi->sioa);
 }
 
 /*
diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
index 9c39b73..6b90bf3 100644
--- a/fs/unionfs/sioq.c
+++ b/fs/unionfs/sioq.c
@@ -46,7 +46,7 @@ void stop_sioq(void)
                destroy_workqueue(superio_workqueue);
 }
 
-void __run_sioq(work_func_t func, struct sioq_args *args, int async)
+void run_sioq(work_func_t func, struct sioq_args *args)
 {
        INIT_WORK(&args->work, func);
 
@@ -55,25 +55,54 @@ void __run_sioq(work_func_t func, struct sioq_args *args, 
int async)
                /* TODO: do accounting if needed */
                schedule();
        }
-       if (!async)
-               wait_for_completion(&args->comp);
+       wait_for_completion(&args->comp);
 }
 
-void __unionfs_reclaim(struct work_struct *work)
+int __run_sioa(void *args)
 {
-       struct sioq_args *args = container_of(work, struct sioq_args, work);
-       struct reclaim_args *rc = &args->reclaim;
-
-       rc->process = current;
+       struct sioa_args *sioa_args = (struct sioa_args *)args;
+       sioa_args->process = current;
        do {
+               sioa_args->work(args);
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(sioa_args->timeout);
+       } while (!sioa_args->done(args));
+       complete(&sioa_args->comp);
+       return 0;
+}
 
-               /* do work */
+/* Creates an asynchronous thread. Calling process is responsible
+ * for calling wait_for_completion. The thread executes the work function,
+ * then sleeps for timeout time. When it wakes up it runs the done function
+ * and terminates if done, otherwise repeats the loop.
+ * The done function should return 0 if not done.
+ */
+void run_sioa(struct sioa_args *args, void (*work) (void*), 
+                       int (*done) (void*), signed long timeout)
+{
+       init_completion(&args->comp);
+       args->process = NULL;
+       args->timeout = timeout;
+       args->work = work;
+       args->done = done;
+       kernel_thread(__run_sioa, args, 0);
+}
 
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(rc->timeout);
-       } while (rc->odf && rc->odf->odi_rc);
-       complete(&args->comp);
+void __unionfs_reclaim_w(void *args)
+{
+       struct sioa_args *sioa_args = (struct sioa_args *)args;
+       struct reclaim_args *rc = &sioa_args->reclaim;
+       
+       /* do work */
 }
+
+int __unionfs_reclaim_d(void *args)
+{
+       struct sioa_args *sioa_args = (struct sioa_args *)args;
+       struct reclaim_args *rc = &sioa_args->reclaim;
+       return !(rc->odf && rc->odf->odi_rc);
+}
+
 void __unionfs_create(struct work_struct *work)
 {
        struct sioq_args *args = container_of(work, struct sioq_args, work);
diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
index 510905a..1896dd0 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -35,8 +35,6 @@ struct unlink_args {
 
 struct reclaim_args {
        struct odf_sb_info *odf;
-       struct task_struct *process;
-       signed long timeout;
 };
 
 struct sioq_args {
@@ -51,21 +49,25 @@ struct sioq_args {
                struct mknod_args mknod;
                struct symlink_args symlink;
                struct unlink_args unlink;
+       };
+};
+
+struct sioa_args {
+       struct completion comp;
+       struct task_struct *process;
+       signed long timeout;
+       void (*work) (void*);
+       int (*done) (void*);
+
+       union {
                struct reclaim_args reclaim;
        };
 };
 
 extern int __init init_sioq(void);
 extern __exit void stop_sioq(void);
-extern void __run_sioq(work_func_t func, struct sioq_args *args, int async);
-static inline void run_sioq(work_func_t func, struct sioq_args *args)
-{
-       __run_sioq(func, args, 0);
-};
-static inline void run_sioq_async(work_func_t func, struct sioq_args *args)
-{
-       __run_sioq(func, args, 1);
-};
+extern void run_sioq(work_func_t func, struct sioq_args *args);
+extern void run_sioa(struct sioa_args *args, void (*work) (void*), int (*done) 
(void*), signed long timeout);
 
 /* Extern definitions for our privlege escalation helpers */
 extern void __unionfs_create(struct work_struct *work);
@@ -73,7 +75,8 @@ extern void __unionfs_mkdir(struct work_struct *work);
 extern void __unionfs_mknod(struct work_struct *work);
 extern void __unionfs_symlink(struct work_struct *work);
 extern void __unionfs_unlink(struct work_struct *work);
-extern void __unionfs_reclaim(struct work_struct *work);
+extern void __unionfs_reclaim_w(void *args);
+extern int __unionfs_reclaim_d(void *args);
 
 #endif /* _SIOQ_H */
 
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index b74116e..0b7e078 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -106,7 +106,7 @@ struct odf_sb_info {
        struct odf_dentry_info *odi_sb;
        struct odf_dentry_info *odi_rc;
        struct odf_dentry_info *odi_ic;
-       struct sioq_args *sioq;
+       struct sioa_args *sioa;
 };
 
 /* unionfs inode data in memory */
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to