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