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