+struct raid5_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(raid5_conf_t *, char *);
+ ssize_t (*store)(raid5_conf_t *, const char *, ssize_t);
+};
+
+static ssize_t
+raid5_show_stripe_cache_size(raid5_conf_t *conf, char *page)
+{
+ return sprintf(page, "%d\n", conf->max_nr_stripes);
+}
+
+static ssize_t
+raid5_store_stripe_cache_size(raid5_conf_t *conf, const char *page, ssize_t len)
+{
+ char *end;
+ int new;
+ if (len >= PAGE_SIZE)
+ return -EINVAL;
+
+ new = simple_strtoul(page, &end, 10);
+ if (!*page || (*end && *end != '\n') )
+ return -EINVAL;
+ if (new <= 16 || new > 32768)
+ return -EINVAL;
+ while (new < conf->max_nr_stripes) {
+ if (drop_one_stripe(conf))
+ conf->max_nr_stripes--;
+ else
+ break;
+ }
+ while (new > conf->max_nr_stripes) {
+ if (grow_one_stripe(conf))
+ conf->max_nr_stripes++;
+ else break;
+ }
+ return len;
+}
+static struct raid5_sysfs_entry raid5_stripecache_size = {
+ .attr = {.name = "stripe_cache_size", .mode = S_IRUGO | S_IWUSR },
+ .show = raid5_show_stripe_cache_size,
+ .store = raid5_store_stripe_cache_size,
+};
+
+static ssize_t
+raid5_show_stripe_cache_active(raid5_conf_t *conf, char *page)
+{
+ return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
+}
+
+static struct raid5_sysfs_entry raid5_stripecache_active = {
+ .attr = {.name = "stripe_cache_active", .mode = S_IRUGO},
+ .show = raid5_show_stripe_cache_active,
+};
+
+static struct attribute *raid5_default_attrs[] = {
+ &raid5_stripecache_size.attr,
+ &raid5_stripecache_active.attr,
+ NULL,
+};
+
+static ssize_t
+raid5_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+ struct raid5_sysfs_entry *entry = container_of(attr, struct raid5_sysfs_entry, attr);
+ raid5_conf_t *conf = container_of(kobj, raid5_conf_t, kobj);
+
+ if (!entry->show)
+ return -EIO;
+ return entry->show(conf, page);
+}
+
+static ssize_t
+raid5_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *page, size_t length)
+{
+ struct raid5_sysfs_entry *entry = container_of(attr, struct raid5_sysfs_entry, attr);
+ raid5_conf_t *conf = container_of(kobj, raid5_conf_t, kobj);
+
+ if (!entry->store)
+ return -EIO;
+ return entry->store(conf, page, length);
+}
+
+static void raid5_free(struct kobject *ko)
+{
+ raid5_conf_t *conf = container_of(ko, raid5_conf_t, kobj);
+ kfree(conf);
+}
+
+
+static struct sysfs_ops raid5_sysfs_ops = {
+ .show = raid5_attr_show,
+ .store = raid5_attr_store,
+};
+
+static struct kobj_type raid5_ktype = {
+ .release = raid5_free,
+ .sysfs_ops = &raid5_sysfs_ops,
+ .default_attrs = raid5_default_attrs,
+};
+