commit bd57571967bfa7cc1bf665b00531a79551d69ec7
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Wed Mar 14 16:37:59 2007 -0400

    skeleton for an asynchronous odf thread

diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 19e26a3..4eb2cfd 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -9,6 +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;
        int err = 0;
        
        err = odf_parse_options(options, &odffile);
@@ -59,6 +60,18 @@ 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) {
+               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);
+
        osi->mnt = nd.mnt;
        mntget(osi->mnt);
        dget(osi->mnt->mnt_sb->s_root);
@@ -92,6 +105,10 @@ 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_process(osi->sioq->reclaim.process);
+       wait_for_completion(&osi->sioq->comp);
+       kfree(osi->sioq);
 }
 
 /*
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index bc6b152..c0f3e74 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -39,6 +39,9 @@
 
 #define ODF_DIRENT_MAGIC 0x0DFD1300
 
+/* Reclaim thread timeout */
+#define ODF_RC_TIMEOUT 1000
+
 /* super */
 struct odf_sb_info* odf_read_super(char *options);
 void odf_put_super(struct odf_sb_info *osi);
diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
index 06c13be..9c39b73 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)
+void __run_sioq(work_func_t func, struct sioq_args *args, int async)
 {
        INIT_WORK(&args->work, func);
 
@@ -55,9 +55,25 @@ void run_sioq(work_func_t func, struct sioq_args *args)
                /* TODO: do accounting if needed */
                schedule();
        }
-       wait_for_completion(&args->comp);
+       if (!async)
+               wait_for_completion(&args->comp);
 }
 
+void __unionfs_reclaim(struct work_struct *work)
+{
+       struct sioq_args *args = container_of(work, struct sioq_args, work);
+       struct reclaim_args *rc = &args->reclaim;
+
+       rc->process = current;
+       do {
+
+               /* do work */
+
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(rc->timeout);
+       } while (rc->odf && rc->odf->odi_rc);
+       complete(&args->comp);
+}
 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 24d171b..510905a 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -33,6 +33,11 @@ struct unlink_args {
        struct dentry *dentry;
 };
 
+struct reclaim_args {
+       struct odf_sb_info *odf;
+       struct task_struct *process;
+       signed long timeout;
+};
 
 struct sioq_args {
        struct completion comp;
@@ -46,12 +51,21 @@ struct sioq_args {
                struct mknod_args mknod;
                struct symlink_args symlink;
                struct unlink_args unlink;
+               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);
+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 definitions for our privlege escalation helpers */
 extern void __unionfs_create(struct work_struct *work);
@@ -59,6 +73,7 @@ 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);
 
 #endif /* _SIOQ_H */
 
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index 71b7eb2..b74116e 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -106,6 +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;
 };
 
 /* 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