commit 20b9fdfd3d11cace5c32d2151a95e2f75247a285
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date:   Wed Mar 28 00:25:54 2007 -0400

    allow configuration of cleanup thread vars using configfs

diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile
index 3ec63a8..3a52717 100644
--- a/fs/unionfs/Makefile
+++ b/fs/unionfs/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_UNION_FS) += unionfs.o
 
 unionfs-y := subr.o dentry.o file.o inode.o main.o super.o \
        branchman.o rdstate.o copyup.o dirhelper.o rename.o \
-       unlink.o lookup.o commonfops.o dirfops.o sioq.o odf.o ../ext2/ext2.o
+       unlink.o lookup.o commonfops.o dirfops.o sioq.o odf.o \
+       config.o ../ext2/ext2.o
 
 unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o
diff --git a/fs/unionfs/config.c b/fs/unionfs/config.c
new file mode 100644
index 0000000..a734e43
--- /dev/null
+++ b/fs/unionfs/config.c
@@ -0,0 +1,136 @@
+#include <linux/module.h>
+#include "config.h"
+
+
+#define TIMEOUT "timeout"
+#define TIMEOUT_MIN 1
+#define TIMEOUT_MAX 1000
+#define TIMEOUT_DEF 30
+#define THRESH_B "block_thresh"
+#define THRESH_B_MIN 1
+#define THRESH_B_MAX 99
+#define THRESH_B_DEF 80
+#define THRESH_I "inode_thresh"
+#define THRESH_I_MIN 1
+#define THRESH_I_MAX 99
+#define THRESH_I_DEF 80
+
+static struct unionfs_attribute unionfs_attr_timeout = {
+       .attr   = { .ca_owner = THIS_MODULE, .ca_name = TIMEOUT, .ca_mode = 
S_IRUGO | S_IWUSR },
+       .min = TIMEOUT_MIN,
+       .max = TIMEOUT_MAX,
+       .val = TIMEOUT_DEF,
+};
+
+static struct unionfs_attribute unionfs_attr_thresh_b = {
+       .attr   = { .ca_owner = THIS_MODULE, .ca_name = THRESH_B, .ca_mode = 
S_IRUGO | S_IWUSR },
+       .min = THRESH_B_MIN,
+       .max = THRESH_B_MAX,
+       .val = THRESH_B_DEF,
+};
+
+static struct unionfs_attribute unionfs_attr_thresh_i = {
+       .attr   = { .ca_owner = THIS_MODULE, .ca_name = THRESH_I, .ca_mode = 
S_IRUGO | S_IWUSR },
+       .min = THRESH_I_MIN,
+       .max = THRESH_I_MAX,
+       .val = THRESH_I_DEF,
+};
+
+static struct unionfs_attributes unionfs_attributes = {
+       .timeout = &unionfs_attr_timeout,
+       .thresh_b = &unionfs_attr_thresh_b,
+       .thresh_i = &unionfs_attr_thresh_i,
+};
+
+extern struct unionfs_attributes *get_attributes()
+{
+       return &unionfs_attributes;
+}
+
+static ssize_t unionfs_attr_show(struct config_item *item,
+               struct configfs_attribute *attr,
+               char *page)
+{
+       struct unionfs_attribute *unionfs_attr =
+               container_of(attr, struct unionfs_attribute, attr);
+       return sprintf(page, "%d\n", unionfs_attr->val);
+}
+
+static ssize_t unionfs_attr_store(struct config_item *item,
+               struct configfs_attribute *attr,
+               const char *page, size_t count)
+{
+       struct unionfs_attribute *unionfs_attr =
+               container_of(attr, struct unionfs_attribute, attr);
+       unsigned long tmp;
+       char *p = (char *) page;        
+       tmp = simple_strtoul(p, &p, 10);
+
+       if (!p || (*p && (*p != '\n')))
+               return -EINVAL;
+
+       if (tmp > unionfs_attr->max || tmp < unionfs_attr->min) {
+               printk("unionfs: attribute out of range (%d - %d)\n",
+                               unionfs_attr->min, unionfs_attr->max);
+               return -ERANGE;
+       }
+
+       unionfs_attr->val = tmp;
+       return count;
+}
+
+static struct configfs_attribute *unionfs_global_attrs[] = {
+       &unionfs_attr_timeout.attr,
+       &unionfs_attr_thresh_b.attr,
+       &unionfs_attr_thresh_i.attr,
+       NULL,
+};
+
+static struct configfs_item_operations unionfs_global_item_ops = {
+       .show_attribute = unionfs_attr_show, 
+       .store_attribute = unionfs_attr_store, 
+};
+
+static struct config_item_type unionfs_global_type = {
+       .ct_item_ops    = &unionfs_global_item_ops,
+       .ct_attrs       = unionfs_global_attrs,
+       .ct_owner       = THIS_MODULE,
+};
+
+static struct configfs_subsystem unionfs_subsys = {
+       .su_group = {
+               .cg_item = {
+                       .ci_namebuf = "unionfs",
+                       .ci_type = &unionfs_global_type,
+               },
+       },
+};
+
+int unionfs_config_init(void)
+{
+       int ret;
+       struct configfs_subsystem *subsys;
+
+       subsys = &unionfs_subsys;
+
+       config_group_init(&subsys->su_group);
+       init_MUTEX(&subsys->su_sem);
+       ret = configfs_register_subsystem(subsys);
+       if (ret) {
+               printk(KERN_ERR "Error %d while registering subsystem %s\n",
+                               ret,
+                               subsys->su_group.cg_item.ci_namebuf);
+               goto out_unregister;
+       }
+       return 0;
+
+out_unregister:
+       configfs_unregister_subsystem(subsys);
+
+       return ret;
+}
+
+void unionfs_config_exit(void)
+{
+       configfs_unregister_subsystem(&unionfs_subsys);
+}
diff --git a/fs/unionfs/config.h b/fs/unionfs/config.h
new file mode 100644
index 0000000..5a10c77
--- /dev/null
+++ b/fs/unionfs/config.h
@@ -0,0 +1,23 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#include <linux/configfs.h>
+
+struct unionfs_attribute  { 
+       struct configfs_attribute attr;    
+       int val;    
+       int min;
+       int max;
+};
+
+struct unionfs_attributes {
+       struct unionfs_attribute *timeout;
+       struct unionfs_attribute *thresh_b;
+       struct unionfs_attribute *thresh_i;
+};
+extern void unionfs_config_exit(void);
+extern int unionfs_config_init(void);
+
+extern struct unionfs_attributes *get_attributes(void);
+
+#endif
diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
index 5ec7c82..a261736 100644
--- a/fs/unionfs/main.c
+++ b/fs/unionfs/main.c
@@ -766,6 +766,8 @@ static int __init init_unionfs_fs(void)
                goto out;
        if ((err = init_sioq()))
                goto out;
+       if ((err = unionfs_config_init()))
+               goto out;
        err = register_filesystem(&unionfs_fs_type);
 out:
        if (err) {
@@ -783,6 +785,7 @@ static void __exit exit_unionfs_fs(void)
        unionfs_destroy_filldir_cache();
        unionfs_destroy_inode_cache();
        unionfs_destroy_dentry_cache();
+       unionfs_config_exit();
        unregister_filesystem(&unionfs_fs_type);
        printk("Completed unionfs module unload.\n");
 }
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 0c92939..81b2479 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1,5 +1,4 @@
 #include "union.h"
-
 /*
  * Initialize any odf data we might need
  * Reads the odf file from the options
@@ -67,9 +66,10 @@ struct odf_sb_info* odf_read_super(char *options)
                goto out_free;
        }
        sioa->cleanup.odf = osi;
+       sioa->cleanup.attr = get_attributes();
        osi->cleanup = sioa;
-       run_sioa(sioa, __odf_cleanup, msecs_to_jiffies(ODF_CL_TIMEOUT*1000));
-
+       run_sioa(sioa, __odf_cleanup, 
+               msecs_to_jiffies(sioa->cleanup.attr->timeout->val));
        osi->mnt = nd.mnt;
        mntget(osi->mnt);
        dget(osi->mnt->mnt_sb->s_root);
@@ -1337,14 +1337,17 @@ void __odf_cleanup(void *args)
        int cleanup = 0;
        int err = 0;
 
+       /* update timeout */
+       sioa_args->timeout = msecs_to_jiffies(cl->attr->timeout->val * 1000);
+
        odi_ic = cl->odf->odi_ic;
        odf_lock(odi_ic);
        vfs_statfs(cl->odf->odi_sb->dentry, &stat);
-       if (stat.f_bavail * 100 < stat.f_blocks * ODF_CL_PCNT_B) {
+       if (stat.f_bavail * 100 < stat.f_blocks * (100 - 
cl->attr->thresh_b->val)) {
                cleanup = 1;
                printk("unionfs cleanup thread: free blocks below critical 
size\n");
        }
-       else if (stat.f_ffree * 100 < stat.f_ffree * ODF_CL_PCNT_I) {
+       else if (stat.f_ffree * 100 < stat.f_ffree * (100 - 
cl->attr->thresh_i->val)) {
                cleanup = 1;
                printk("unionfs cleanup thread: free inodes below critical 
size\n");
        }
diff --git a/fs/unionfs/odf.h b/fs/unionfs/odf.h
index 0d6e66c..f954dec 100644
--- a/fs/unionfs/odf.h
+++ b/fs/unionfs/odf.h
@@ -38,11 +38,6 @@
 
 #define ODF_DIRENT_MAGIC 0x0DFD1300
 
-/* Reclaim thread timeout */
-#define ODF_CL_TIMEOUT 30 /* seconds */
-#define ODF_CL_PCNT_I 25 /* cleanup ic when % of free inodes goes below this 
val */
-#define ODF_CL_PCNT_B 30 /* cleanup ic when % of free blocks goes below this 
val */
-
 #define ODF_CONTENT "content"
 #define ODF_CONTENT_LEN 7
 
diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
index d83bf45..16ff555 100644
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -35,6 +35,7 @@ struct unlink_args {
 
 struct cleanup_args {
        struct odf_sb_info *odf;
+       struct unionfs_attributes *attr;
 };
 
 struct sioq_args {
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index d5fc263..430a472 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -48,6 +48,8 @@
 
 #include <linux/union_fs.h>
 
+#include "config.h"
+
 /* the file system name */
 #define UNIONFS_NAME "unionfs"
 
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to