commit 272bd19ac1efb401553f829cd5c4318beb6d8506
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Wed Mar 21 17:59:25 2007 -0400

    removed done function from sioa struct and added a complete_sioa function 
to terminate threads
    
    fixed bug where the odf was umounted before the cleanup thread was 
initialized

diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index aff86f7..c695498 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -68,7 +68,7 @@ struct odf_sb_info* odf_read_super(char *options)
        }
        sioa->cleanup.odf = osi;
        osi->cleanup = sioa;
-       run_sioa(sioa, __odf_cleanup_w, __odf_cleanup_d, ODF_CL_TIMEOUT);
+       run_sioa(sioa, __odf_cleanup, ODF_CL_TIMEOUT);
 
        osi->mnt = nd.mnt;
        mntget(osi->mnt);
@@ -103,9 +103,7 @@ void odf_put_super(struct odf_sb_info *osi)
        odf_put_info(osi->odi_ic);
        dput(osi->mnt->mnt_sb->s_root);
        mntput(osi->mnt);
-       osi->odi_rc = NULL;
-       wake_up_sioa(osi->cleanup);
-       wait_for_sioa(osi->cleanup);
+       complete_sioa(osi->cleanup);
        kfree(osi->cleanup);
 }
 
@@ -1190,7 +1188,7 @@ void odf_put_info(struct odf_dentry_info *odi)
  * Worker function for the cleanup thread. It recursively removes all entries 
  * in the reclaim directory
  */
-void __odf_cleanup_w(void *args)
+void __odf_cleanup(void *args)
 {
        struct sioa_args *sioa_args = (struct sioa_args *)args;
        struct cleanup_args *cl = &sioa_args->cleanup;
@@ -1221,14 +1219,3 @@ void __odf_cleanup_w(void *args)
        unionfs_force_rmdir(cl->odf->mnt, odi_rc->dentry, FRMV_NOTPARENT);
        odf_unlock(odi_rc);
 }
-
-/*
- * done function for the cleanup thread. It returns true if the odf is umounted
- */
-int __odf_cleanup_d(void *args)
-{
-       struct sioa_args *sioa_args = (struct sioa_args *)args;
-       struct cleanup_args *cl = &sioa_args->cleanup;
-       return !(cl->odf && cl->odf->odi_rc);
-}
-
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 445169e..50dc681 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -96,8 +96,7 @@ int __odf_get_opaque(struct inode *i);
 int __odf_set_opaque(struct inode *i, int branch);
 
 /* cleanup thread functions */
-extern void __odf_cleanup_w(void *args);
-extern int __odf_cleanup_d(void *args);
+extern void __odf_cleanup(void *args);
 
 /* Macros for locking an odf dentry info. */
 static inline void odf_lock(struct odf_dentry_info *odi)
diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
index aaa4144..91413c7 100644
--- a/fs/unionfs/sioq.c
+++ b/fs/unionfs/sioq.c
@@ -62,7 +62,7 @@ int __run_sioa(void *args)
 {
        struct sioa_args *sioa_args = (struct sioa_args *)args;
        sioa_args->process = current;
-       do {
+       while (!sioa_args->complete){
                sioa_args->work(args);
                if (sioa_args->waiting) {
                        complete(&sioa_args->comp_work);
@@ -71,7 +71,7 @@ int __run_sioa(void *args)
                }
                current->state = TASK_INTERRUPTIBLE;
                schedule_timeout(sioa_args->timeout);
-       } while (!sioa_args->done(args));
+       }
 
        if (sioa_args->waiting) {
                complete(&sioa_args->comp_work);
@@ -88,16 +88,15 @@ int __run_sioa(void *args)
  * 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)
+void run_sioa(struct sioa_args *args, void (*work) (void*), signed long 
timeout)
 {
        init_completion(&args->comp_thread);
        mutex_init(&args->lock);
+       args->complete = 0;
        args->waiting = 0;
        args->process = NULL;
        args->timeout = timeout;
        args->work = work;
-       args->done = done;
        kernel_thread(__run_sioa, args, 0);
 }
 
diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
index f58fc50..078bf0f 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -58,9 +58,9 @@ struct sioa_args {
        struct task_struct *process;
        signed long timeout;
        void (*work) (void*);
-       int (*done) (void*);
        struct mutex lock;
        int waiting;
+       int complete;
 
        union {
                struct cleanup_args cleanup;
@@ -70,7 +70,7 @@ struct sioa_args {
 extern int __init init_sioq(void);
 extern __exit void stop_sioq(void);
 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 void run_sioa(struct sioa_args *args, void (*work) (void*), signed long 
timeout);
 
 /* wakes up the process and makes sure it resumes before we do */
 static inline void wake_up_and_wait_sioa(struct sioa_args *args)
@@ -78,7 +78,8 @@ static inline void wake_up_and_wait_sioa(struct sioa_args 
*args)
        mutex_lock(&args->lock);
        args->waiting = 1;
        init_completion(&args->comp_work);
-       wake_up_process(args->process);
+       if (args->process)
+               wake_up_process(args->process);
        schedule();
        wait_for_completion(&args->comp_work);
        mutex_unlock(&args->lock);
@@ -90,6 +91,20 @@ static inline void wake_up_sioa(struct sioa_args *args)
        schedule();
        mutex_unlock(&args->lock);
 }
+
+static inline void complete_sioa(struct sioa_args *args)
+{
+       mutex_lock(&args->lock);
+       args->complete = 1;
+
+       /* there might be the case that this is called before the */
+       /* thread actually runs and process is initialized */
+       if (args->process)
+               wake_up_process(args->process);
+       schedule();
+       wait_for_completion(&args->comp_thread);
+       mutex_unlock(&args->lock);
+}
 static inline void wait_for_sioa(struct sioa_args *args)
 {
        wait_for_completion(&args->comp_thread);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to