commit 1b9c214f46415489ad6ffc99331d120964a5eadc
Author: Yiannis Pericleous <[EMAIL PROTECTED]>
Date: Fri Apr 6 17:51:04 2007 -0400
added hysterisis for cleanup thread, two more configfs attributes (for
blocks & inodes)
for when to stop cleaning
diff --git a/fs/unionfs/config.c b/fs/unionfs/config.c
index 5875b12..b59dbec 100644
--- a/fs/unionfs/config.c
+++ b/fs/unionfs/config.c
@@ -3,28 +3,47 @@
/* our configurable variables */
static struct unionfs_attribute unionfs_attr_timeout = {
+ .name = TIMEOUT,
.min = TIMEOUT_MIN,
.max = TIMEOUT_MAX,
.val = TIMEOUT_DEF,
};
-static struct unionfs_attribute unionfs_attr_thresh_b = {
- .min = THRESH_B_MIN,
- .max = THRESH_B_MAX,
- .val = THRESH_B_DEF,
+static struct unionfs_attribute unionfs_attr_thresh_b_high = {
+ .name = THRESH_BH,
+ .min = THRESH_BH_MIN,
+ .max = THRESH_BH_MAX,
+ .val = THRESH_BH_DEF,
};
-static struct unionfs_attribute unionfs_attr_thresh_i = {
- .min = THRESH_I_MIN,
- .max = THRESH_I_MAX,
- .val = THRESH_I_DEF,
+static struct unionfs_attribute unionfs_attr_thresh_b_low = {
+ .name = THRESH_BL,
+ .min = THRESH_BL_MIN,
+ .max = THRESH_BL_MAX,
+ .val = THRESH_BL_DEF,
+};
+
+static struct unionfs_attribute unionfs_attr_thresh_i_high = {
+ .name = THRESH_IH,
+ .min = THRESH_IH_MIN,
+ .max = THRESH_IH_MAX,
+ .val = THRESH_IH_DEF,
+};
+
+static struct unionfs_attribute unionfs_attr_thresh_i_low = {
+ .name = THRESH_IL,
+ .min = THRESH_IL_MIN,
+ .max = THRESH_IL_MAX,
+ .val = THRESH_IL_DEF,
};
/* group them for easy acces by all unionfs mounts */
static struct unionfs_attributes unionfs_attributes = {
.timeout = &unionfs_attr_timeout,
- .thresh_b = &unionfs_attr_thresh_b,
- .thresh_i = &unionfs_attr_thresh_i,
+ .thresh_b_high = &unionfs_attr_thresh_b_high,
+ .thresh_b_low = &unionfs_attr_thresh_b_low,
+ .thresh_i_high = &unionfs_attr_thresh_i_high,
+ .thresh_i_low = &unionfs_attr_thresh_i_low,
};
extern struct unionfs_attributes *get_attributes()
@@ -42,31 +61,40 @@ int unionfs_config_init(void) {return 0;};
#include <linux/configfs.h>
+#define DEPEND_MAX 1
+#define DEPEND_MIN 2
+
struct unionfs_config_attr {
struct configfs_attribute attr;
struct unionfs_attribute *unionfs_attr;
- ssize_t (*show)(struct unionfs_attribute *, char *);
- ssize_t (*store)(struct unionfs_attribute *, const char *, size_t);
+ ssize_t (*show)(struct unionfs_config_attr*, char *);
+ ssize_t (*store)(struct unionfs_config_attr *, const char *, size_t);
+ struct unionfs_attribute *depended;
+ int depend_mode;
};
/* reads a number */
-static ssize_t unionfs_read_num(struct unionfs_attribute *attr, char *page)
+static ssize_t unionfs_read_num(struct unionfs_config_attr *attr, char *page)
{
- return sprintf(page, "%d\n", attr->val);
+ return sprintf(page, "%d\n", attr->unionfs_attr->val);
}
/* prints out information about the variables */
-static ssize_t unionfs_read_help(struct unionfs_attribute *attr, char *page)
+static ssize_t unionfs_read_help(struct unionfs_config_attr *attr, char *page)
{
- return sprintf(page, "\n%s",
+ return sprintf(page, "\n"
TIMEOUT ": " TIMEOUT_INFO "\n\n"
- THRESH_B ": " THRESH_B_INFO "\n\n"
- THRESH_I ": " THRESH_I_INFO "\n\n"
+ THRESH_BH ": " THRESH_BH_INFO "\n\n"
+ THRESH_BL ": " THRESH_BL_INFO "\n\n"
+ THRESH_IH ": " THRESH_IH_INFO "\n\n"
+ THRESH_IL ": " THRESH_IL_INFO "\n\n",
+ TIMEOUT_DEF, THRESH_BH_DEF, THRESH_BL_DEF,
+ THRESH_IH_DEF, THRESH_IL_DEF
);
}
/* writes numbers within a range */
-static ssize_t unionfs_write_num(struct unionfs_attribute *attr,
+static ssize_t unionfs_write_num(struct unionfs_config_attr *attr,
const char *page, size_t count)
{
unsigned long tmp;
@@ -76,13 +104,29 @@ static ssize_t unionfs_write_num(struct unionfs_attribute
*attr,
if (!p || (*p && (*p != '\n')))
return -EINVAL;
- if (tmp > attr->max || tmp < attr->min) {
+ if (tmp > attr->unionfs_attr->max || tmp < attr->unionfs_attr->min) {
printk("unionfs: attribute out of range (%d - %d)\n",
- attr->min, attr->max);
+ attr->unionfs_attr->min,
attr->unionfs_attr->max);
return -ERANGE;
}
+ if (attr->depended) {
+ if (attr->depend_mode == DEPEND_MAX) {
+ if (tmp >= attr->depended->val) {
+ printk("unionfs: the value must be lower than
the value of %s\n",
+ attr->depended->name);
+ return -ERANGE;
+ }
+ }
+ else if (attr->depend_mode == DEPEND_MIN) {
+ if (tmp <= attr->depended->val) {
+ printk("unionfs: the value must be higher than
the value of %s\n",
+ attr->depended->name);
+ return -ERANGE;
+ }
+ }
+ }
- attr->val = tmp;
+ attr->unionfs_attr->val = tmp;
return count;
}
@@ -93,23 +137,44 @@ static struct unionfs_config_attr unionfs_config_timeout =
{
.store = unionfs_write_num,
};
-static struct unionfs_config_attr unionfs_config_thresh_b = {
- .attr = { .ca_owner = THIS_MODULE, .ca_name = THRESH_B, .ca_mode =
S_IRUGO | S_IWUSR },
- .unionfs_attr = &unionfs_attr_thresh_b,
+static struct unionfs_config_attr unionfs_config_thresh_b_high = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = THRESH_BH, .ca_mode =
S_IRUGO | S_IWUSR },
+ .unionfs_attr = &unionfs_attr_thresh_b_high,
+ .show = unionfs_read_num,
+ .store = unionfs_write_num,
+ .depended = &unionfs_attr_thresh_b_low,
+ .depend_mode = DEPEND_MIN,
+};
+
+static struct unionfs_config_attr unionfs_config_thresh_b_low = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = THRESH_BL, .ca_mode =
S_IRUGO | S_IWUSR },
+ .unionfs_attr = &unionfs_attr_thresh_b_low,
+ .show = unionfs_read_num,
+ .store = unionfs_write_num,
+ .depended = &unionfs_attr_thresh_b_high,
+ .depend_mode = DEPEND_MAX,
+};
+
+static struct unionfs_config_attr unionfs_config_thresh_i_high = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = THRESH_IH, .ca_mode =
S_IRUGO | S_IWUSR },
+ .unionfs_attr = &unionfs_attr_thresh_i_high,
.show = unionfs_read_num,
.store = unionfs_write_num,
+ .depended = &unionfs_attr_thresh_i_low,
+ .depend_mode = DEPEND_MIN,
};
-static struct unionfs_config_attr unionfs_config_thresh_i = {
- .attr = { .ca_owner = THIS_MODULE, .ca_name = THRESH_I, .ca_mode =
S_IRUGO | S_IWUSR },
- .unionfs_attr = &unionfs_attr_thresh_i,
+static struct unionfs_config_attr unionfs_config_thresh_i_low = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = THRESH_IL, .ca_mode =
S_IRUGO | S_IWUSR },
+ .unionfs_attr = &unionfs_attr_thresh_i_low,
.show = unionfs_read_num,
.store = unionfs_write_num,
+ .depended = &unionfs_attr_thresh_i_high,
+ .depend_mode = DEPEND_MAX,
};
static struct unionfs_config_attr unionfs_config_help = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = HELP_NAME, .ca_mode =
S_IRUGO | S_IWUSR },
- .unionfs_attr = &unionfs_attr_thresh_i,
.show = unionfs_read_help,
};
@@ -121,7 +186,7 @@ static ssize_t unionfs_attr_show(struct config_item *item,
struct unionfs_config_attr *config_attr =
container_of(attr, struct unionfs_config_attr, attr);
if (config_attr->show)
- return config_attr->show(config_attr->unionfs_attr, page);
+ return config_attr->show(config_attr, page);
return 0;
}
@@ -132,15 +197,17 @@ static ssize_t unionfs_attr_store(struct config_item
*item,
struct unionfs_config_attr *config_attr =
container_of(attr, struct unionfs_config_attr, attr);
if (config_attr->store)
- return config_attr->store(config_attr->unionfs_attr, page,
count);
+ return config_attr->store(config_attr, page, count);
return -EINVAL;
}
/* what we want to be visible at /config/unionfs */
static struct configfs_attribute *unionfs_global_attrs[] = {
&unionfs_config_timeout.attr,
- &unionfs_config_thresh_b.attr,
- &unionfs_config_thresh_i.attr,
+ &unionfs_config_thresh_b_high.attr,
+ &unionfs_config_thresh_b_low.attr,
+ &unionfs_config_thresh_i_high.attr,
+ &unionfs_config_thresh_i_low.attr,
&unionfs_config_help.attr,
NULL,
};
diff --git a/fs/unionfs/config.h b/fs/unionfs/config.h
index bb9e5fe..b0429d2 100644
--- a/fs/unionfs/config.h
+++ b/fs/unionfs/config.h
@@ -5,24 +5,39 @@
#define TIMEOUT_MIN 1
#define TIMEOUT_MAX 1000000
#define TIMEOUT_DEF 30
-#define TIMEOUT_INFO "defaults to 30 seconds. Controls the interval when the
ODF\n" \
+#define TIMEOUT_INFO "defaults to %d seconds. Controls the interval when the
ODF\n" \
"cleanup thread will wake up."
-#define THRESH_B "block_thresh"
-#define THRESH_B_MIN 1
-#define THRESH_B_MAX 99
-#define THRESH_B_DEF 80
-#define THRESH_B_INFO "defaults to 80%. The threshold of consumed disk blocks
in\n" \
- "/odf, above which we begin cleaning, to bring the system below
this\n" \
- "threshold."
-#define THRESH_I "inode_thresh"
-#define THRESH_I_MIN 1
-#define THRESH_I_MAX 99
-#define THRESH_I_DEF 80
-#define THRESH_I_INFO " defaults to 80%. The threshold of consumed inodes in
/odf,\n" \
- "above which we begin cleaning, to bring the system below this
threshold."
+#define THRESH_BH "block_high_thresh"
+#define THRESH_BH_MIN 1
+#define THRESH_BH_MAX 99
+#define THRESH_BH_DEF 80
+#define THRESH_BH_INFO "defaults to %d%%. The threshold of consumed disk
blocks in\n" \
+ "/odf, above which we begin cleaning. Must be higher than the
value of\n" \
+ THRESH_BL
+#define THRESH_BL "block_low_thresh"
+#define THRESH_BL_MIN 1
+#define THRESH_BL_MAX 99
+#define THRESH_BL_DEF 70
+#define THRESH_BL_INFO "defaults to %d%%. The threshold of consumed disk
blocks in\n" \
+ "/odf, we try to bring the system to after we begin cleaning.
Must be\n" \
+ "lower the value of " THRESH_BH
+#define THRESH_IH "inode_high_thresh"
+#define THRESH_IH_MIN 1
+#define THRESH_IH_MAX 99
+#define THRESH_IH_DEF 80
+#define THRESH_IH_INFO "defaults to %d%%. The threshold of consumed inodes in
/odf,\n" \
+ "above which we begin cleaning. Must be higher than the value
of " THRESH_IL
+#define THRESH_IL "inode_low_thresh"
+#define THRESH_IL_MIN 1
+#define THRESH_IL_MAX 99
+#define THRESH_IL_DEF 70
+#define THRESH_IL_INFO "defaults to %d%%. The threshold of consumed inodes in
/odf,\n" \
+ "we try to bring the system to after we begin cleaning. Must be
lower than\n" \
+ "the value of " THRESH_IH
#define HELP_NAME "help"
-struct unionfs_attribute {
+struct unionfs_attribute {
+ char *name;
int val;
int min;
int max;
@@ -30,8 +45,10 @@ struct unionfs_attribute {
struct unionfs_attributes {
struct unionfs_attribute *timeout;
- struct unionfs_attribute *thresh_b;
- struct unionfs_attribute *thresh_i;
+ struct unionfs_attribute *thresh_b_high;
+ struct unionfs_attribute *thresh_b_low;
+ struct unionfs_attribute *thresh_i_high;
+ struct unionfs_attribute *thresh_i_low;
};
extern void unionfs_config_exit(void);
diff --git a/fs/unionfs/odf.c b/fs/unionfs/odf.c
index 2b8db07..0da094c 100644
--- a/fs/unionfs/odf.c
+++ b/fs/unionfs/odf.c
@@ -1859,19 +1859,16 @@ void __odf_cleanup(void *args)
if (cl->force) {
cl->force = 0;
cleanup = ODF_CLEAN_CACHE;
-// printk("unionfs cleanup thread: forced cleanup\n");
}
- else if (stat.f_bavail * 100 < stat.f_blocks * (100 -
cl->attr->thresh_b->val)) {
+ else if (stat.f_bavail * 100 < stat.f_blocks * (100 -
cl->attr->thresh_b_high->val)) {
cleanup = ODF_CLEAN_BLOCKS;
- size = stat.f_blocks * (100 - cl->attr->thresh_b->val) -
+ size = stat.f_blocks * (100 - cl->attr->thresh_b_low->val) -
(stat.f_bavail * 100);
-// printk("unionfs cleanup thread: free blocks below critical
size\n");
}
- else if (stat.f_ffree * 100 < stat.f_files * (100 -
cl->attr->thresh_i->val)) {
+ else if (stat.f_ffree * 100 < stat.f_files * (100 -
cl->attr->thresh_i_high->val)) {
cleanup = ODF_CLEAN_INODES;
- size = stat.f_files * (100 - cl->attr->thresh_i->val) -
+ size = stat.f_files * (100 - cl->attr->thresh_i_low->val) -
(stat.f_ffree * 100);
-// printk("unionfs cleanup thread: free inodes below critical
size\n");
}
if (cleanup)
err = odf_cleanup(cl->odf, cleanup, size);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs