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