mtd/fs/jffs2 proc.c, NONE, 1.1 Makefile.common, 1.2, 1.3 compr.c, 1.35, 1.36 compr.h, 1.1, 1.2 super-v24.c, 1.78, 1.79 super.c, 1.94, 1.95

havasi at infradead.org havasi at infradead.org
Tue May 25 07:25:27 EDT 2004


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/home/havasi/mtd/fs/jffs2

Modified Files:
	Makefile.common compr.c compr.h super-v24.c super.c 
Added Files:
	proc.c 
Log Message:
Optional proc interface support:
- enable/disable compressors
- set compression mode
- change the priority of compressors
- get compression stats




--- NEW FILE proc.c ---
/*
 * JFFS2 -- Journalling Flash File System, Version 2.
 *
 * Copyright (C) 2004 Ferenc Havasi <havasi at inf.u-szeged.hu>,
 *                    University of Szeged, Hungary
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: proc.c,v 1.1 2004/05/25 11:25:25 havasi Exp $
 *
 * Files in /proc/fs/jffs2 directory:
 *   compr_list
 *         read:  shows the list of the loaded compressors 
 *                (name, priority, enadbled/disabled)
 *         write: compressors can be enabled/disabled and
 *                the priority of them can be changed,
 *                required formats:
 *                    enable COMPRESSOR_NAME
 *                    disble COMPRESSOR_NAME
 *                    priority NEW_PRIORITY COMPRESSOR_NAME
 *   compr_mode
 *         read:  shows the name of the actual compression mode
 *         write: sets the actual comperession mode
 *   compr_stat
 *         read:  shows compression statistics
 */

#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/jffs.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include "compr.h"

extern struct proc_dir_entry *jffs_proc_root;

/* Structure for top-level entry in '/proc/fs' directory */
static struct proc_dir_entry *jffs2_proc_root;

/* Structure for files in /proc/fs/jffs2 directory */
static struct proc_dir_entry *jffs2_proc_compr_stat;
static struct proc_dir_entry *jffs2_proc_compr_mode;

/* Read the JFFS2 'compr_stat' file */

static int jffs2_proc_stat_read (char *page, char **start, off_t off,
		int count, int *eof, void *data)
{
	int len = 0,i;
        char *stat = jffs2_stats();
        
        if (strlen(stat)<off) {
	        *eof = 1;
                JFFS2_FREE(stat);
	        return len;
        }        
        for (i=off;((stat[i]!=0)&&(len<count));i++,len++) {
                page[len]=stat[i];
        }
        if (off+len>=strlen(stat)) *eof = 1;
        else *eof = 0;
        JFFS2_FREE(stat);
	return len;
}


/* Read the JFFS2 'compr_mode' file */

static int jffs2_proc_mode_read (char *page, char **start, off_t off,
		int count, int *eof, void *data)
{
	int len = 0;
        if (strlen(jffs2_get_compression_mode_name())+1>count) {
                /* it should not happen */
	        *eof = 1;
                return 0;
        }
	len += sprintf(page, "%s\n",jffs2_get_compression_mode_name());
	*eof = 1;
	return len;
}

/* Write the JFFS2 'compr_mode' file
 *   sets the actual compression mode
 */

static int jffs2_proc_mode_write(struct file *file, const char *buffer,
                           unsigned long count, void *data)
{
        char *compr_name;

        /* collect the name of the compression mode and set it */
        compr_name = JFFS2_MALLOC(count+1);
        if (sscanf(buffer,"%s",compr_name)>0) {
                if (jffs2_set_compression_mode_name(compr_name)) {
                        printk("JFFS2: error switching compression mode. Invalid parameter (%s)?\n",compr_name);
                }
        }
        else {
                printk("JFFS2: error: parameter missing\n");
        }
        JFFS2_FREE(compr_name);
        return count;
}

/* Read the JFFS2 'compr_list' file */

static int jffs2_proc_list_read (char *page, char **start, off_t off,
		int count, int *eof, void *data)
{
	int len = 0;
        char *list = jffs2_list_compressors();
        if (strlen(list)+1>count) {
                /* it should not happen */
	        *eof = 1;
                JFFS2_FREE(list);
                return 0;
        }
	len += sprintf(page,"%s",list);
	*eof = 1;
        JFFS2_FREE(list);
	return len;
}

/* Write the JFFS2 'compr_list' file 
 *   enable/disable a compressor or set the priority of it
 */

static int jffs2_proc_list_write(struct file *file, const char *buffer,
                           unsigned long count, void *data)
{
        int prior;
        char *compr_name,*compr_cmd;

        compr_name = JFFS2_MALLOC(count+1);
        compr_cmd = JFFS2_MALLOC(count+1);
        if (!compr_name) {
                printk("JFFS2: unable to allocate memory\n");
                goto list_write_end;
        }
        compr_name[0] = 0;

        if (sscanf(buffer,"priority %d %s",&prior,compr_name)>1) {
                jffs2_set_compressor_priority(compr_name, prior);
                goto list_write_end;
        }
        if (sscanf(buffer,"enable %s",compr_name)>0) {
                jffs2_enable_compressor_name(compr_name);
                goto list_write_end;
        }
        if (sscanf(buffer,"disable %s",compr_name)>0) {
                jffs2_disable_compressor_name(compr_name);
                goto list_write_end;
        }
        printk("JFFS2: usage of /proc/fs/jffs2/compr_list:\n"
               "  echo \"enable COMPRESSOR_NAME\"  >/proc/fs/jffs2/compr_list\n"
               "  echo \"disable COMPRESSOR_NAME\" >/proc/fs/jffs2/compr_list\n"
               "  echo \"priority NEW_PRIORITY COMPRESSOR_NAME\" >/proc/fs/jffs2/compr_list\n");
list_write_end:
        JFFS2_FREE(compr_cmd);
        JFFS2_FREE(compr_name);
	return count;
}

/* Register a JFFS2 proc directory */

int jffs2_proc_init(void)
{
	jffs2_proc_root = proc_mkdir("jffs2", proc_root_fs);

	/* create entry for 'compr_stat' file */
	if ((jffs2_proc_compr_stat = create_proc_entry ("compr_stat", 0, jffs2_proc_root))) {
		jffs2_proc_compr_stat->read_proc = jffs2_proc_stat_read;
	}
	else {
		return -ENOMEM;
	}
	/* create entry for 'compr_mode' file */
	if ((jffs2_proc_compr_mode = create_proc_entry ("compr_mode", 0, jffs2_proc_root))) {
	        jffs2_proc_compr_mode->read_proc  = jffs2_proc_mode_read;
	        jffs2_proc_compr_mode->write_proc = jffs2_proc_mode_write;
	}
	else {
		return -ENOMEM;
	}
	/* create entry for 'compr_list' file */
	if ((jffs2_proc_compr_mode = create_proc_entry ("compr_list", 0, jffs2_proc_root))) {
	        jffs2_proc_compr_mode->read_proc  = jffs2_proc_list_read;
	        jffs2_proc_compr_mode->write_proc = jffs2_proc_list_write;
	}
	else {
		return -ENOMEM;
	}
	return 0;
}


/* Unregister a JFFS2 proc directory */

int jffs2_proc_exit(void)
{
#if LINUX_VERSION_CODE < 0x020300
	remove_proc_entry ("compr_stat", &jffs2_proc_root);
	remove_proc_entry ("compr_mode", &jffs2_proc_root);
	remove_proc_entry ("compr_list", &jffs2_proc_root);
	remove_proc_entry ("jffs2", &proc_root_fs);
#else
	remove_proc_entry ("compr_stat", jffs2_proc_root);
	remove_proc_entry ("compr_mode", jffs2_proc_root);
	remove_proc_entry ("compr_list", jffs2_proc_root);
	remove_proc_entry ("jffs2", proc_root_fs);
#endif
        return 0;
}

Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/Makefile.common,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile.common	25 May 2004 11:12:31 -0000	1.2
+++ Makefile.common	25 May 2004 11:25:25 -0000	1.3
@@ -15,6 +15,7 @@
 JRUBIN_OBJS-$(CONFIG_JFFS2_RUBIN) := compr_rubin.o
 JRTIME_OBJS-$(CONFIG_JFFS2_RTIME) := compr_rtime.o
 JZLIB_OBJS-$(CONFIG_JFFS2_ZLIB)  := compr_zlib.o
+JPROC_OBJS-$(CONFIG_JFFS2_PROC)  := proc.o
 JFFS2_OBJS	:= compr.o dir.o file.o ioctl.o nodelist.o malloc.o \
 	read.o nodemgmt.o readinode.o write.o scan.o gc.o \
 	symlink.o build.o erase.o background.o fs.o writev.o
@@ -30,7 +31,8 @@
 NAND_OBJS-$(CONFIG_JFFS2_FS_NAND)	:= wbuf.o
 
 jffs2-objs := $(COMPR_OBJS) $(JFFS2_OBJS) $(VERS_OBJS) $(NAND_OBJS-y) \
-	$(LINUX_OBJS) $(JRUBIN_OBJS-y) $(JRTIME_OBJS-y) $(JZLIB_OBJS-y)
+	$(LINUX_OBJS) $(JRUBIN_OBJS-y) $(JRTIME_OBJS-y) $(JZLIB_OBJS-y) \
+	$(JPROC_OBJS-y)
 
 # 2.4 build compatibility
 ifeq ($(BELOW25),y)

Index: compr.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/compr.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- compr.c	25 May 2004 11:12:31 -0000	1.35
+++ compr.c	25 May 2004 11:25:25 -0000	1.36
@@ -275,6 +275,144 @@
         return 0;
 }
 
+#ifdef CONFIG_JFFS2_PROC
+
+#define JFFS2_STAT_BUF_SIZE 16000
+
+char *jffs2_list_compressors(void)
+{
+        struct jffs2_compressor *this;
+        char *buf, *act_buf;
+
+        act_buf = buf = JFFS2_MALLOC(JFFS2_STAT_BUF_SIZE);
+        list_for_each_entry(this, &jffs2_compressor_list, list) {
+                act_buf += sprintf(act_buf, "%10s priority:%d ", this->name, this->priority);
+                if ((this->disabled)||(!this->compress))
+                        act_buf += sprintf(act_buf,"disabled");
+                else
+                        act_buf += sprintf(act_buf,"enabled");
+                act_buf += sprintf(act_buf,"\n");
+        }
+        return buf;
+}
+
+char *jffs2_stats(void)
+{
+        struct jffs2_compressor *this;
+        char *buf, *act_buf;
+
+        act_buf = buf = JFFS2_MALLOC(JFFS2_STAT_BUF_SIZE);
+
+        act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n");
+        act_buf += sprintf(act_buf,"%10s   ","none");
+        act_buf += sprintf(act_buf,"compr: %d blocks (%d)  decompr: %d blocks\n", none_stat_compr_blocks, 
+                           none_stat_compr_size, none_stat_decompr_blocks);
+        COMPRESSOR_LIST_LOCK;
+        list_for_each_entry(this, &jffs2_compressor_list, list) {
+                act_buf += sprintf(act_buf,"%10s ",this->name);
+                if ((this->disabled)||(!this->compress))
+                        act_buf += sprintf(act_buf,"- ");
+                else
+                        act_buf += sprintf(act_buf,"+ ");
+                act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d)  decompr: %d blocks ", this->stat_compr_blocks, 
+                                   this->stat_compr_new_size, this->stat_compr_orig_size, 
+                                   this->stat_decompr_blocks);
+                act_buf += sprintf(act_buf,"\n");
+        }
+        COMPRESSOR_LIST_UNLOCK;
+
+        return buf;
+}
+
+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";
+        }
+        return "unkown";
+}
+
+int jffs2_set_compression_mode_name(const char *name) 
+{
+        if (!strcmp("none",name)) {
+                jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
+                return 0;
+        }
+        if (!strcmp("priority",name)) {
+                jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY;
+                return 0;
+        }
+        if (!strcmp("size",name)) {
+                jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
+                return 0;
+        }
+        return 1;
+}
+
+static int jffs2_compressor_Xable(const char *name, int disabled)
+{
+        struct jffs2_compressor *this;
+        COMPRESSOR_LIST_LOCK;
+        list_for_each_entry(this, &jffs2_compressor_list, list) {
+                if (!strcmp(this->name, name)) {
+                        this->disabled = disabled;
+                        COMPRESSOR_LIST_UNLOCK;
+                        return 0;                        
+                }
+        }
+        COMPRESSOR_LIST_UNLOCK;
+        printk("JFFS2: compressor %s not found.\n",name);
+        return 1;
+}
+
+int jffs2_enable_compressor_name(const char *name)
+{
+        return jffs2_compressor_Xable(name, 0);
+}
+
+int jffs2_disable_compressor_name(const char *name)
+{
+        return jffs2_compressor_Xable(name, 1);
+}
+
+int jffs2_set_compressor_priority(const char *name, int priority)
+{
+        struct jffs2_compressor *this,*comp;
+        COMPRESSOR_LIST_LOCK;
+        list_for_each_entry(this, &jffs2_compressor_list, list) {
+                if (!strcmp(this->name, name)) {
+                        this->priority = priority;
+                        comp = this;
+                        goto reinsert;
+                }
+        }
+        COMPRESSOR_LIST_UNLOCK;
+        printk("JFFS2: compressor %s not found.\n",name);        
+        return 1;
+reinsert:
+        /* list is sorted in the order of priority, so if
+           we change it we have to reinsert it into the
+           good place */
+        list_del(&comp->list);
+        list_for_each_entry(this, &jffs2_compressor_list, list) {
+                if (this->priority < comp->priority) {
+                        list_add(&comp->list, this->list.prev);
+                        COMPRESSOR_LIST_UNLOCK;
+                        return 0;
+                }
+        }
+        list_add_tail(&comp->list, &jffs2_compressor_list);
+        COMPRESSOR_LIST_UNLOCK;
+        return 0;
+}
+
+#endif
+
 void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
 {
         if (orig != comprbuf)

Index: compr.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/compr.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- compr.h	25 May 2004 11:12:31 -0000	1.1
+++ compr.h	25 May 2004 11:25:25 -0000	1.2
@@ -82,6 +82,16 @@
 
 void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
 
+#ifdef CONFIG_JFFS2_PROC
+int jffs2_enable_compressor_name(const char *name);
+int jffs2_disable_compressor_name(const char *name);
+int jffs2_set_compression_mode_name(const char *mode_name);
+char *jffs2_get_compression_mode_name(void);
+int jffs2_set_compressor_priority(const char *mode_name, int priority);
+char *jffs2_list_compressors(void);
+char *jffs2_stats(void);
+#endif
+
 /* Compressor modules */
 /* These functions will be called by jffs2_compressors_init/exit */
 
@@ -99,5 +109,9 @@
 int jffs2_zlib_init(void);
 void jffs2_zlib_exit(void);
 #endif
+
+/* Prototypes from proc.c */
+int jffs2_proc_init(void);
+int jffs2_proc_exit(void);
 
 #endif /* __JFFS2_COMPR_H__ */

Index: super-v24.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/super-v24.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -r1.78 -r1.79
--- super-v24.c	25 May 2004 11:12:32 -0000	1.78
+++ super-v24.c	25 May 2004 11:25:25 -0000	1.79
@@ -126,6 +126,13 @@
 		return -EIO;
 	}
 #endif
+#ifdef CONFIG_JFFS2_PROC
+	ret = jffs2_proc_init();
+	if (ret) {
+		printk(KERN_ERR "JFFS2 error: Failed to initialise proc interface\n");
+		goto out;
+	}
+#endif
 	ret = jffs2_compressors_init();
 	if (ret) {
 		printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n");
@@ -147,6 +154,9 @@
 	jffs2_destroy_slab_caches();
  out_compressors:
 	jffs2_compressors_exit();
+#ifdef CONFIG_JFFS2_PROC
+        jffs2_proc_exit();
+#endif
  out:
 	return ret;
 }
@@ -155,6 +165,9 @@
 {
 	jffs2_destroy_slab_caches();
 	jffs2_compressors_exit();
+#ifdef CONFIG_JFFS2_PROC
+        jffs2_proc_exit();
+#endif
 	unregister_filesystem(&jffs2_fs_type);
 }
 

Index: super.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/super.c,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -r1.94 -r1.95
--- super.c	25 May 2004 11:12:32 -0000	1.94
+++ super.c	25 May 2004 11:25:25 -0000	1.95
@@ -308,6 +308,13 @@
 		printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n");
 		return -ENOMEM;
 	}
+#ifdef CONFIG_JFFS2_PROC
+	ret = jffs2_proc_init();
+	if (ret) {
+		printk(KERN_ERR "JFFS2 error: Failed to initialise proc interface\n");
+		goto out;
+	}
+#endif
 	ret = jffs2_compressors_init();
 	if (ret) {
 		printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n");
@@ -329,6 +336,9 @@
 	jffs2_destroy_slab_caches();
  out_compressors:
 	jffs2_compressors_exit();
+#ifdef CONFIG_JFFS2_PROC
+        jffs2_proc_exit();
+#endif
  out:
 	return ret;
 }
@@ -338,6 +348,9 @@
 	unregister_filesystem(&jffs2_fs_type);
 	jffs2_destroy_slab_caches();
 	jffs2_compressors_exit();
+#ifdef CONFIG_JFFS2_PROC
+        jffs2_proc_exit();
+#endif
 	kmem_cache_destroy(jffs2_inode_cachep);
 }
 





More information about the linux-mtd-cvs mailing list