[PATCH 4/5] jffs2: Allow selection of compression mode via a sysfs attribute
Richard Purdie
rpurdie at openedhand.com
Fri May 4 07:31:00 EDT 2007
Allow selection of the compression mode for jffs2 via a sysfs
attribute. This establishes a sysfs presence for jffs2 through
which other compression options could easily be exported too.
Signed-off-by: Richard Purdie <rpurdie at openedhand.com>
---
fs/Kconfig | 9 ++++++++
fs/jffs2/compr.c | 40 +++++++++++++++++++++++++++++++++++
fs/jffs2/compr.h | 6 +++++
fs/jffs2/super.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/fs/Kconfig b/fs/Kconfig
index b8d2c58..4b801ac 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1283,6 +1283,15 @@ config JFFS2_FS_SECURITY
If you are not using a security module that requires using
extended attributes for file security labels, say N.
+config JFFS2_SYSFS
+ bool "JFFS2 sysfs attributes"
+ depends on JFFS2_FS
+ default n
+ help
+ Enable control of jffs2 features through sysfs.
+
+ If unsure, say 'N'.
+
config JFFS2_COMPRESSION_OPTIONS
bool "Advanced compression options for JFFS2"
depends on JFFS2_FS
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index 477ec97..2e8e3c1 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -297,6 +297,46 @@ int jffs2_unregister_compressor(struct jffs2_compressor *comp)
return 0;
}
+#ifdef CONFIG_JFFS2_SYSFS
+
+char *jffs2_get_compression_mode_name(void)
+{
+ switch (jffs2_compression_mode) {
+ case JFFS2_COMPR_MODE_NONE:
+ return "none";
+ case JFFS2_COMPR_MODE_PRIORITY:
+ return "priority";
+ case JFFS2_COMPR_MODE_SIZE:
+ return "size";
+ case JFFS2_COMPR_MODE_FAVOURLZO:
+ return "favourlzo";
+ }
+ return "unkown";
+}
+
+int jffs2_set_compression_mode_name(const char *name)
+{
+ if (!strncmp("none", name, 4)) {
+ jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
+ return 0;
+ }
+ if (!strncmp("priority", name, 8)) {
+ jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY;
+ return 0;
+ }
+ if (!strncmp("size", name, 4)) {
+ jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
+ return 0;
+ }
+ if (!strncmp("favourlzo", name, 9)) {
+ jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+#endif
+
void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
{
if (orig != comprbuf)
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
index 2b66941..917f0d6 100644
--- a/fs/jffs2/compr.h
+++ b/fs/jffs2/compr.h
@@ -77,6 +77,12 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
+#ifdef CONFIG_JFFS2_SYSFS
+int jffs2_set_compression_mode_name(const char *mode_name);
+char *jffs2_get_compression_mode_name(void);
+#endif
+
+
/* Compressor modules */
/* These functions will be called by jffs2_compressors_init/exit */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index e51164a..9a67113 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -322,6 +322,54 @@ static struct file_system_type jffs2_fs_type = {
.kill_sb = jffs2_kill_sb,
};
+#ifdef CONFIG_JFFS2_SYSFS
+
+static struct attribute jffs2_attr_mode = {
+ .name = "compression_mode",
+ .mode = S_IRUGO | S_IWUSR,
+};
+
+static struct attribute *jffs2_attrs[] = {
+ &jffs2_attr_mode,
+ NULL,
+};
+
+static ssize_t jffs2_attr_show(struct kobject *kobj, struct attribute *attr,
+ char *page)
+{
+ if (!strcmp("compression_mode", attr->name))
+ return sprintf(page, "%s\n", jffs2_get_compression_mode_name());
+ return 0;
+}
+
+static ssize_t jffs2_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *page, size_t count)
+{
+ int ret = -EINVAL;
+
+ if (!strcmp("compression_mode", attr->name)) {
+ ret = jffs2_set_compression_mode_name(page);
+ if (ret >= 0)
+ return count;
+ }
+ return ret;
+}
+
+static struct sysfs_ops jffs2_sysfs_ops = {
+ .show = jffs2_attr_show,
+ .store = jffs2_attr_store,
+};
+
+static struct kobj_type jffs2_subsys_type = {
+ .default_attrs = jffs2_attrs,
+ .sysfs_ops = &jffs2_sysfs_ops,
+};
+
+/* gives us jffs2_subsys */
+static decl_subsys(jffs2, NULL, NULL);
+
+#endif
+
static int __init init_jffs2_fs(void)
{
int ret;
@@ -371,6 +419,16 @@ static int __init init_jffs2_fs(void)
printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n");
goto out_slab;
}
+
+#ifdef CONFIG_JFFS2_SYSFS
+ /* Errors here are not fatal */
+ kset_set_kset_s(&jffs2_subsys, fs_subsys);
+ jffs2_subsys.kset.kobj.ktype = &jffs2_subsys_type;
+ ret = subsystem_register(&jffs2_subsys);
+ if (ret)
+ printk(KERN_WARNING "Error registering JFFS2 sysfs attributes\n");
+#endif
+
return 0;
out_slab:
@@ -384,6 +442,9 @@ static int __init init_jffs2_fs(void)
static void __exit exit_jffs2_fs(void)
{
+#ifdef CONFIG_JFFS2_SYSFS
+ subsystem_unregister(&jffs2_subsys);
+#endif
unregister_filesystem(&jffs2_fs_type);
jffs2_destroy_slab_caches();
jffs2_compressors_exit();
More information about the linux-mtd
mailing list