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

Reply via email to