patch-2.4.11-dontuse linux/fs/jffs/inode-v23.c

Next file: linux/fs/jffs/intrep.c
Previous file: linux/fs/jffs/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.10/linux/fs/jffs/inode-v23.c linux/fs/jffs/inode-v23.c
@@ -10,8 +10,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: inode-v23.c,v 1.43.2.6 2001/01/09 00:32:48 dwmw2 Exp $
- * + sb_maxbytes / generic_file_open() fixes for 2.4.0-ac4
+ * $Id: inode-v23.c,v 1.70 2001/10/02 09:16:02 dwmw2 Exp $
  *
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -52,8 +51,12 @@
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
+
 #include "jffs_fm.h"
 #include "intrep.h"
+#if CONFIG_JFFS_PROC_FS
+#include "jffs_proc.h"
+#endif
 
 static int jffs_remove(struct inode *dir, struct dentry *dentry, int type);
 
@@ -64,6 +67,8 @@
 static struct inode_operations jffs_dir_inode_operations;
 static struct address_space_operations jffs_address_operations;
 
+kmem_cache_t     *node_cache = NULL;
+kmem_cache_t     *fm_cache = NULL;
 
 /* Called by the VFS at mount time to initialize the whole file system.  */
 static struct super_block *
@@ -109,6 +114,15 @@
 
 	c = (struct jffs_control *) sb->u.generic_sbp;
 
+#ifdef CONFIG_JFFS_PROC_FS
+	/* Set up the jffs proc file system.  */
+	if (jffs_register_jffs_proc_dir(dev, c) < 0) {
+		printk(KERN_WARNING "JFFS: Failed to initialize the JFFS "
+			"proc file system for device %s.\n",
+			kdevname(dev));
+	}
+#endif
+
 	/* Set the Garbage Collection thresholds */
 
 	/* GC if free space goes below 5% of the total size */
@@ -153,6 +167,10 @@
 
 	D2(printk("jffs_put_super()\n"));
 
+#ifdef CONFIG_JFFS_PROC_FS
+	jffs_unregister_jffs_proc_dir(c);
+#endif
+
 	if (c->gc_task) {
 		D1(printk (KERN_NOTICE "jffs_put_super(): Telling gc thread to die.\n"));
 		send_sig(SIGKILL, c->gc_task, 1);
@@ -215,15 +233,13 @@
 		recoverable = 1;
         }
 
-	if (!(new_node = (struct jffs_node *)
-			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
+	if (!(new_node = jffs_alloc_node())) {
 		D(printk("jffs_setattr(): Allocation failed!\n"));
 		D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
 		up(&fmc->biglock);
 		return -ENOMEM;
 	}
 
-	DJM(no_jffs_node++);
 	new_node->data_offset = 0;
 	new_node->removed_size = 0;
 	raw_inode.magic = JFFS_MAGIC_BITMASK;
@@ -304,8 +320,7 @@
 	/* Write this node to the flash.  */
 	if ((res = jffs_write_node(c, new_node, &raw_inode, f->name, 0, recoverable, f)) < 0) {
 		D(printk("jffs_notify_change(): The write failed!\n"));
-		kfree(new_node);
-		DJM(no_jffs_node--);
+		jffs_free_node(new_node);
 		D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
 		up(&c->fmc->biglock);
 		return res;
@@ -373,9 +388,9 @@
 	buf->f_bsize = PAGE_CACHE_SIZE;
 	buf->f_blocks = (fmc->flash_size / PAGE_CACHE_SIZE)
 		       - (fmc->min_free_size / PAGE_CACHE_SIZE);
-	buf->f_bfree = (jffs_free_size1(fmc) / PAGE_CACHE_SIZE
-		       + jffs_free_size2(fmc) / PAGE_CACHE_SIZE)
-		      - (fmc->min_free_size / PAGE_CACHE_SIZE);
+	buf->f_bfree = (jffs_free_size1(fmc) + jffs_free_size2(fmc) +
+		       fmc->dirty_size - fmc->min_free_size)
+			       >> PAGE_CACHE_SHIFT;
 	buf->f_bavail = buf->f_bfree;
 
 	/* Find out how many files there are in the filesystem.  */
@@ -404,7 +419,7 @@
 	__u32 rename_data = 0;
 
 	D2(printk("***jffs_rename()\n"));
-	
+
 	D(printk("jffs_rename(): old_dir: 0x%p, old name: 0x%p, "
 		 "new_dir: 0x%p, new name: 0x%p\n",
 		 old_dir, old_dentry->d_name.name,
@@ -440,12 +455,10 @@
 	down(&c->fmc->biglock);
 	/* Create a node and initialize as much as needed.  */
 	result = -ENOMEM;
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_rename(): Allocation failed: node == 0\n"));
 		goto jffs_rename_end;
 	}
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -487,8 +500,7 @@
 				      new_dentry->d_name.name,
 				      (unsigned char*)&rename_data, 0, f)) < 0) {
 		D(printk("jffs_rename(): Failed to write node to flash.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_rename_end;
 	}
 	raw_inode.dsize = 0;
@@ -557,7 +569,7 @@
 	if (filp->f_pos == 0) {
 		D3(printk("jffs_readdir(): \".\" %lu\n", inode->i_ino));
 		if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
-		  D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
+			D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
 			up(&c->fmc->biglock);
 			return 0;
 		}
@@ -573,7 +585,7 @@
 		}
 		D3(printk("jffs_readdir(): \"..\" %u\n", ddino));
 		if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) {
-		  D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
+			D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
 			up(&c->fmc->biglock);
 			return 0;
 		}
@@ -581,7 +593,7 @@
 	}
 	f = ((struct jffs_file *)inode->u.generic_ip)->children;
 
-	j=2;
+	j = 2;
 	while(f && (f->deleted || j++ < filp->f_pos )) {
 		f = f->sibling_next;
 	}
@@ -649,11 +661,11 @@
 
 	/* iget calls jffs_read_inode, so we need to drop the biglock
            before calling iget.  Unfortunately, the GC has a tendency
-           to sneak in here, because iget sometimes calls schedule (). 
-         */
+           to sneak in here, because iget sometimes calls schedule ().
+	*/
 
 	if ((len == 1) && (name[0] == '.')) {
-                D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
+		D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
 		up(&c->fmc->biglock);
 		if (!(inode = iget(dir->i_sb, d->ino))) {
 			D(printk("jffs_lookup(): . iget() ==> NULL\n"));
@@ -702,12 +714,12 @@
 
 /* Try to read a page of data from a file.  */
 static int
-jffs_readpage(struct file *file, struct page *page)
+jffs_do_readpage_nolock(struct file *file, struct page *page)
 {
 	void *buf;
 	unsigned long read_len;
-	int result = -EIO;
-	struct inode *inode = page->mapping->host;
+	int result;
+	struct inode *inode = (struct inode*)page->mapping->host;
 	struct jffs_file *f = (struct jffs_file *)inode->u.generic_ip;
 	struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
 	int r;
@@ -725,43 +737,51 @@
 	D3(printk (KERN_NOTICE "readpage(): down biglock\n"));
 	down(&c->fmc->biglock);
 
+	read_len = 0;
+	result = 0;
+
 	offset = page->index << PAGE_CACHE_SHIFT;
 	if (offset < inode->i_size) {
 		read_len = min_t(long, inode->i_size - offset, PAGE_SIZE);
 		r = jffs_read_data(f, buf, offset, read_len);
-		if (r == read_len) {
-			if (read_len < PAGE_SIZE) {
-				memset(buf + read_len, 0,
-				       PAGE_SIZE - read_len);
-			}
-			SetPageUptodate(page);
-			result = 0;
+		if (r != read_len) {
+			result = -EIO;
+			D(
+			        printk("***jffs_readpage(): Read error! "
+				       "Wanted to read %lu bytes but only "
+				       "read %d bytes.\n", read_len, r);
+			  );
 		}
-		D(else {
-			printk("***jffs_readpage(): Read error! "
-			       "Wanted to read %lu bytes but only "
-			       "read %d bytes.\n", read_len, r);
-		});
+
 	}
 
+	/* This handles the case of partial or no read in above */
+	if(read_len < PAGE_SIZE)
+	        memset(buf + read_len, 0, PAGE_SIZE - read_len);
+
 	D3(printk (KERN_NOTICE "readpage(): up biglock\n"));
 	up(&c->fmc->biglock);
-	
+
 	if (result) {
-		memset(buf, 0, PAGE_SIZE);
 	        SetPageError(page);
+	}else {
+	        SetPageUptodate(page);	        
 	}
 	flush_dcache_page(page);
 
-	UnlockPage(page);
-
 	put_page(page);
 
 	D3(printk("jffs_readpage(): Leaving...\n"));
 
 	return result;
-} /* jffs_readpage()  */
+} /* jffs_do_readpage_nolock()  */
 
+static int jffs_readpage(struct file *file, struct page *page)
+{
+	int ret = jffs_do_readpage_nolock(file, page);
+	UnlockPage(page);
+	return ret;
+}
 
 /* Create a new directory.  */
 static int
@@ -805,13 +825,11 @@
 	}
 
 	/* Create a node and initialize it as much as needed.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_mkdir(): Allocation failed: node == 0\n"));
 		result = -ENOMEM;
 		goto jffs_mkdir_end;
 	}
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -840,8 +858,7 @@
 	if ((result = jffs_write_node(c, node, &raw_inode,
 				      dentry->d_name.name, 0, 0, NULL)) < 0) {
 		D(printk("jffs_mkdir(): jffs_write_node() failed.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_mkdir_end;
 	}
 
@@ -918,8 +935,8 @@
 	int result = 0;
 
 	D1({
-	        int len = dentry->d_name.len;
-	        const char *name = dentry->d_name.name;
+		int len = dentry->d_name.len;
+		const char *name = dentry->d_name.name;
 		char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
 		memcpy(_name, name, len);
 		_name[len] = '\0';
@@ -968,12 +985,10 @@
 
 	/* Create a node for the deletion.  */
 	result = -ENOMEM;
-	if (!(del_node = (struct jffs_node *)
-			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
+	if (!(del_node = jffs_alloc_node())) {
 		D(printk("jffs_remove(): Allocation failed!\n"));
 		goto jffs_remove_end;
 	}
-	DJM(no_jffs_node++);
 	del_node->data_offset = 0;
 	del_node->removed_size = 0;
 
@@ -999,8 +1014,7 @@
 
 	/* Write the new node to the flash memory.  */
 	if (jffs_write_node(c, del_node, &raw_inode, 0, 0, 1, del_f) < 0) {
-		kfree(del_node);
-		DJM(no_jffs_node--);
+		jffs_free_node(del_node);
 		result = -EIO;
 		goto jffs_remove_end;
 	}
@@ -1045,13 +1059,11 @@
 	down(&c->fmc->biglock);
 
 	/* Create and initialize a new node.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_mknod(): Allocation failed!\n"));
 		result = -ENOMEM;
 		goto jffs_mknod_err;
 	}
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -1078,7 +1090,7 @@
 
 	/* Write the new node to the flash.  */
 	if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,
-				  (unsigned char *)&dev, 0, NULL)) < 0) {
+				   (unsigned char *)&dev, 0, NULL)) < 0) {
 		D(printk("jffs_mknod(): jffs_write_node() failed.\n"));
 		result = err;
 		goto jffs_mknod_err;
@@ -1105,8 +1117,7 @@
 
 jffs_mknod_err:
 	if (node) {
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 	}
 
 jffs_mknod_end:
@@ -1129,7 +1140,7 @@
 	int err;
 
 	D1({
-	        int len = dentry->d_name.len;
+		int len = dentry->d_name.len; 
 		char *_name = (char *)kmalloc(len + 1, GFP_KERNEL);
 		char *_symname = (char *)kmalloc(symname_len + 1, GFP_KERNEL);
 		memcpy(_name, dentry->d_name.name, len);
@@ -1153,15 +1164,13 @@
 	c = dir_f->c;
 
 	/* Create a node and initialize it as much as needed.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_symlink(): Allocation failed: node = NULL\n"));
 		return -ENOMEM;
 	}
 	D3(printk (KERN_NOTICE "symlink(): down biglock\n"));
 	down(&c->fmc->biglock);
 
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -1189,8 +1198,7 @@
 	if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,
 				   (const unsigned char *)symname, 0, NULL)) < 0) {
 		D(printk("jffs_symlink(): jffs_write_node() failed.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_symlink_end;
 	}
 
@@ -1236,7 +1244,7 @@
 	int err;
 
 	D1({
-	        int len = dentry->d_name.len;
+		int len = dentry->d_name.len;
 		char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
 		memcpy(s, dentry->d_name.name, len);
 		s[len] = '\0';
@@ -1254,15 +1262,13 @@
 	c = dir_f->c;
 
 	/* Create a node and initialize as much as needed.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_create(): Allocation failed: node == 0\n"));
 		return -ENOMEM;
 	}
 	D3(printk (KERN_NOTICE "create(): down biglock\n"));
 	down(&c->fmc->biglock);
 
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -1290,8 +1296,7 @@
 	if ((err = jffs_write_node(c, node, &raw_inode,
 				   dentry->d_name.name, 0, 0, NULL)) < 0) {
 		D(printk("jffs_create(): jffs_write_node() failed.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_create_end;
 	}
 
@@ -1349,32 +1354,32 @@
 		err = -EROFS;
 		goto out_isem;
 	}
-#endif
+#endif	
 	err = -EINVAL;
 
 	if (!S_ISREG(inode->i_mode)) {
 		D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
-			 inode->i_mode));
+				inode->i_mode));
 		goto out_isem;
 	}
 
 	if (!(f = (struct jffs_file *)inode->u.generic_ip)) {
 		D(printk("jffs_file_write(): inode->u.generic_ip = 0x%p\n",
-			 inode->u.generic_ip));
+				inode->u.generic_ip));
 		goto out_isem;
 	}
 
 	c = f->c;
 
 	/*
-	 * This will never trigger with sane page sizes.  leave it in anyway,
-	 * since I'm thinking about how to merge larger writes (the current idea
-	 * is to poke a thread that does the actual I/O and starts by doing a
-	 * down(&inode->i_sem).  then we would need to get the page cache pages
-	 * and have a list of I/O requests and do write-merging here.
+	 * This will never trigger with sane page sizes.  leave it in
+	 * anyway, since I'm thinking about how to merge larger writes
+	 * (the current idea is to poke a thread that does the actual
+	 * I/O and starts by doing a down(&inode->i_sem).  then we
+	 * would need to get the page cache pages and have a list of
+	 * I/O requests and do write-merging here.
 	 * -- prumpf
 	 */
-	
 	thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
 
 	D3(printk (KERN_NOTICE "file_write(): down biglock\n"));
@@ -1389,24 +1394,22 @@
 	while (count) {
 		/* Things are going to be written so we could allocate and
 		   initialize the necessary data structures now.  */
-		if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-							  GFP_KERNEL))) {
+		if (!(node = jffs_alloc_node())) {
 			D(printk("jffs_file_write(): node == 0\n"));
 			err = -ENOMEM;
 			goto out;
 		}
-		DJM(no_jffs_node++);
-		
+
 		node->data_offset = pos;
 		node->removed_size = 0;
-		
+
 		/* Initialize the raw inode.  */
 		raw_inode.magic = JFFS_MAGIC_BITMASK;
 		raw_inode.ino = f->ino;
 		raw_inode.pino = f->pino;
 
 		raw_inode.mode = f->mode;
-		
+
 		raw_inode.uid = f->uid;
 		raw_inode.gid = f->gid;
 		raw_inode.atime = CURRENT_TIME;
@@ -1420,14 +1423,13 @@
 		raw_inode.spare = 0;
 		raw_inode.rename = 0;
 		raw_inode.deleted = 0;
-		
+
 		if (pos < f->size) {
-			node->removed_size = raw_inode.rsize =
-				min_t(unsigned int, thiscount, f->size - pos);
-			
-			/* If this node is going entirely over the top of old data, 
-			   we can allow it to go into the reserved space, because 
-			   we can that GC can reclaim the space later.
+			node->removed_size = raw_inode.rsize = min(thiscount, (__u32)(f->size - pos));
+
+			/* If this node is going entirely over the top of old data,
+			   we can allow it to go into the reserved space, because
+			   we know that GC can reclaim the space later.
 			*/
 			if (pos + thiscount < f->size) {
 				/* If all the data we're overwriting are _real_,
@@ -1436,21 +1438,20 @@
 				*/
 			}
 		}
-		
+
 		/* Write the new node to the flash.  */
-		/* NOTE: We would be quite happy if jffs_write_node() wrote a 
-		   smaller node than we were expecting. There's no need for it 
-		   to waste the space at the end of the flash just because it's 
+		/* NOTE: We would be quite happy if jffs_write_node() wrote a
+		   smaller node than we were expecting. There's no need for it
+		   to waste the space at the end of the flash just because it's
 		   a little smaller than what we asked for. But that's a whole
-		   new can of worms which I'm not going to open this week.
+		   new can of worms which I'm not going to open this week. 
 		   -- dwmw2.
 		*/
 		if ((err = jffs_write_node(c, node, &raw_inode, f->name,
 					   (const unsigned char *)buf,
 					   recoverable, f)) < 0) {
 			D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
-			kfree(node);
-			DJM(no_jffs_node--);
+			jffs_free_node(node);
 			goto out;
 		}
 
@@ -1466,7 +1467,7 @@
 
 		D3(printk("jffs_file_write(): new f_pos %ld.\n", (long)pos));
 
-		thiscount = min_t(unsigned int, c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
+		thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
 	}
  out:
 	D3(printk (KERN_NOTICE "file_write(): up biglock\n"));
@@ -1487,22 +1488,26 @@
 
 static ssize_t
 jffs_prepare_write(struct file *filp, struct page *page,
-		   unsigned from, unsigned to)
+                  unsigned from, unsigned to)
 {
 	/* FIXME: we should detect some error conditions here */
-	
+
+	/* Bugger that. We should make sure the page is uptodate */
+	if (!Page_Uptodate(page) && (from || to < PAGE_CACHE_SIZE))
+		return jffs_do_readpage_nolock(filp, page);
+
 	return 0;
 } /* jffs_prepare_write() */
 
 static ssize_t
 jffs_commit_write(struct file *filp, struct page *page,
-		  unsigned from, unsigned to)
+                 unsigned from, unsigned to)
 {
-	void *addr = page_address(page) + from;
-	/* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
-	loff_t pos = (page->index<<PAGE_CACHE_SHIFT) + from;
-	
-	return jffs_file_write(filp, addr, to-from, &pos);
+       void *addr = page_address(page) + from;
+       /* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
+       loff_t pos = (page->index<<PAGE_CACHE_SHIFT) + from;
+
+       return jffs_file_write(filp, addr, to-from, &pos);
 } /* jffs_commit_write() */
 
 /* This is our ioctl() routine.  */
@@ -1556,7 +1561,7 @@
 			if (copy_to_user((struct jffs_flash_status *)arg,
 					 &fst,
 					 sizeof(struct jffs_flash_status))) {
-			  ret = -EFAULT;
+				ret = -EFAULT;
 			}
 		}
 		break;
@@ -1577,22 +1582,25 @@
 
 static int jffs_fsync(struct file *f, struct dentry *d, int datasync)
 {
-	/* We currently have O_SYNC operations at all times. 
-	   Do nothing
+	/* We currently have O_SYNC operations at all times.
+	   Do nothing.
 	*/
 	return 0;
 }
 
 
+extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
+extern loff_t generic_file_llseek(struct file *, loff_t, int) __attribute__((weak));
+
 static struct file_operations jffs_file_operations =
 {
-	llseek:	generic_file_llseek,  /* llseek */
-	read:  generic_file_read,    /* read */
-	write: generic_file_write,   /* write */
-	ioctl: jffs_ioctl,           /* ioctl */
-	mmap:  generic_file_mmap,    /* mmap */
-	open:  generic_file_open,
-	fsync: jffs_fsync,
+	open:	generic_file_open,
+	llseek:	generic_file_llseek,
+	read:	generic_file_read,
+	write:	generic_file_write,
+	ioctl:	jffs_ioctl,
+	mmap:	generic_file_mmap,
+	fsync:	jffs_fsync,
 };
 
 
@@ -1690,11 +1698,10 @@
 {
 	struct jffs_file *f;
 	struct jffs_control *c;
-	D1(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
+	D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
 		  inode->i_ino));
 
 	lock_kernel();
-
 	inode->i_size = 0;
 	inode->i_blocks = 0;
 	inode->u.generic_ip = 0;
@@ -1717,7 +1724,6 @@
 	jffs_garbage_collect_trigger(c);
 }
 
-
 static struct super_operations jffs_ops =
 {
 	read_inode:   jffs_read_inode,
@@ -1733,9 +1739,16 @@
 static int __init
 init_jffs_fs(void)
 {
-	printk("JFFS version "
-	       JFFS_VERSION_STRING
-	       ", (C) 1999, 2000  Axis Communications AB\n");
+	printk(KERN_INFO "JFFS version " JFFS_VERSION_STRING
+		", (C) 1999, 2000  Axis Communications AB\n");
+	
+#ifdef CONFIG_JFFS_PROC_FS
+	jffs_proc_root = proc_mkdir("jffs", proc_root_fs);
+#endif
+	fm_cache = kmem_cache_create("jffs_fm", sizeof(struct jffs_fm),
+				     0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	node_cache = kmem_cache_create("jffs_node",sizeof(struct jffs_node),
+				       0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 	return register_filesystem(&jffs_fs_type);
 }
 
@@ -1743,9 +1756,15 @@
 exit_jffs_fs(void)
 {
 	unregister_filesystem(&jffs_fs_type);
+	kmem_cache_destroy(fm_cache);
+	kmem_cache_destroy(node_cache);
 }
 
 EXPORT_NO_SYMBOLS;
 
 module_init(init_jffs_fs)
 module_exit(exit_jffs_fs)
+
+MODULE_DESCRIPTION("The Journalling Flash File System");
+MODULE_AUTHOR("Axis Communications AB.");
+MODULE_LICENSE("GPL");

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)