mtd/fs/jffs2/ecos/src dir-ecos.c,1.5,1.6 fs-ecos.c,1.14,1.15 jffs2port.h,1.6,1.7

David Woodhouse dwmw2 at infradead.org
Mon Nov 24 09:54:42 EST 2003


Update of /home/cvs/mtd/fs/jffs2/ecos/src
In directory phoenix.infradead.org:/tmp/cvs-serv2185

Modified Files:
	dir-ecos.c fs-ecos.c jffs2port.h 
Log Message:
clean up icache some more

Index: dir-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/dir-ecos.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- dir-ecos.c	24 Nov 2003 13:49:38 -0000	1.5
+++ dir-ecos.c	24 Nov 2003 14:54:39 -0000	1.6
@@ -96,8 +96,7 @@
 			      d_name->name, d_name->len);
 
 	if (ret) {
-		jffs2_clear_inode(inode);
-		make_bad_inode(inode);
+		inode->i_nlink = 0;
 		iput(inode);
 		jffs2_free_raw_inode(ri);
 		return ret;
@@ -204,7 +203,8 @@
 		/* Eeek. Wave bye bye */
 		up(&f->sem);
 		jffs2_complete_reservation(c);
-		jffs2_clear_inode(inode);
+		inode->i_nlink = 0;
+		iput(inode);
 		return PTR_ERR(fn);
 	}
 	/* No data here. Only a metadata node, which will be 
@@ -217,7 +217,8 @@
 	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
 	if (ret) {
 		/* Eep. */
-		jffs2_clear_inode(inode);
+		inode->i_nlink = 0;
+		iput(inode);
 		return ret;
 	}
 	
@@ -225,7 +226,8 @@
 	if (!rd) {
 		/* Argh. Now we treat it like a normal delete */
 		jffs2_complete_reservation(c);
-		jffs2_clear_inode(inode);
+		inode->i_nlink = 0;
+		iput(inode);
 		return -ENOMEM;
 	}
 
@@ -255,7 +257,8 @@
 		/* dirent failed to write. Delete the inode normally 
 		   as if it were the final unlink() */
 		up(&dir_f->sem);
-		jffs2_clear_inode(inode);
+		inode->i_nlink = 0;
+		iput(inode);
 		return PTR_ERR(fd);
 	}
 

Index: fs-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/fs-ecos.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- fs-ecos.c	24 Nov 2003 13:54:17 -0000	1.14
+++ fs-ecos.c	24 Nov 2003 14:54:39 -0000	1.15
@@ -144,7 +144,7 @@
 // STATIC VARIABLES !!!
 
 static char read_write_buffer[PAGE_CACHE_SIZE];	//avoids malloc when user may be under memory pressure
-static char gc_buffer[PAGE_CACHE_SIZE];	//avoids malloc when user may be under memory pressure
+static unsigned char gc_buffer[PAGE_CACHE_SIZE];	//avoids malloc when user may be under memory pressure
 static unsigned char n_fs_mounted = 0;  // a counter to track the number of jffs2 instances mounted
 
 //==========================================================================
@@ -169,28 +169,24 @@
 // right thing?
 static void icache_evict(struct _inode *root_i, struct _inode *i)
 {
-	struct _inode *cached_inode;
-	struct _inode *next_inode;
+	struct _inode *this = root_i, *next;
 
 	D2(printf("icache_evict\n"));
 	// If this is an absolute search path from the root,
 	// remove all cached inodes with i_count of zero (these are only 
 	// held where needed for dotdot filepaths)
-	if (i == root_i) {
-		for (cached_inode = root_i; cached_inode != NULL;
-		     cached_inode = next_inode) {
-			next_inode = cached_inode->i_cache_next;
-			if (cached_inode->i_count == 0) {
-				cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next;	// Previous entry points ahead of us
-				if (cached_inode->i_cache_next != NULL)
-					cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev;	// Next entry points behind us
-				jffs2_clear_inode(cached_inode);
-				D2(printf
-				   ("free icache_evict inode %x $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n",
-				    cached_inode));
-				free(cached_inode);
-			}
+	while (this) {
+		next = this->i_cache_next;
+		if (this != i && this->i_count == 0) {
+
+			if (this->i_cache_next)
+				this->i_cache_next->i_cache_prev = this->i_cache_prev;
+			if (this->i_cache_prev)
+				this->i_cache_prev->i_cache_next = this->i_cache_next;
+			jffs2_clear_inode(this);
+			free(this);
 		}
+		this = next;
 	}
 }
 
@@ -467,16 +463,12 @@
 
 	D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
 	sb->s_root = iget(sb, 1);
-	if (!sb->s_root) {
+	if (IS_ERR(sb->s_root)) {
 		D1(printk(KERN_WARNING "get root inode failed\n"));
-		err = -ENOMEM;
+		err = PTR_ERR(sb->s_root);
+		sb->s_root = NULL;
 		goto out_nodes;
 	}
-	if (is_bad_inode(sb->s_root)) {
-		D1(printk(KERN_WARNING "get root inode failed\n"));
-		err = EIO;
-		goto out_root_i;
-	}
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -484,8 +476,6 @@
 
 	return 0;
 
-      out_root_i:
-	iput(sb->s_root);
       out_nodes:
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
@@ -585,7 +575,7 @@
 
 	// Only really umount if this is the only mount
 	if (jffs2_sb->s_mount_count == 1) {
-
+		icache_evict(root, NULL);
 		if (root->i_cache_next != NULL)	{
 			struct _inode *inode = root->i_cache_next;
 			printf("Refuse to unmount.\n");
@@ -615,7 +605,7 @@
 		// That's all folks.
 		D2(printf("jffs2_umount No current mounts\n"));
 	} else {
-          jffs2_sb->s_mount_count--;
+		jffs2_sb->s_mount_count--;
         }
         if (--n_fs_mounted == 0)
                 jffs2_destroy_slab_caches();        
@@ -636,8 +626,6 @@
 
 	D2(printf("jffs2_open\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -735,8 +723,6 @@
 
 	D2(printf("jffs2_ops_unlink\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -787,8 +773,6 @@
 
 	D2(printf("jffs2_ops_mkdir\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -845,8 +829,6 @@
 
 	D2(printf("jffs2_ops_rmdir\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -1098,8 +1080,6 @@
 
 	D2(printf("jffs2_opendir\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -1144,8 +1124,6 @@
 		jffs2_dirsearch ds;
 		int err;
 
-		icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 		init_dirsearch(&ds, (struct _inode *) dir, name);
 
 		err = jffs2_find(&ds);
@@ -1187,8 +1165,6 @@
 
 	D2(printf("jffs2_stat\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -1226,8 +1202,6 @@
 
 	D2(printf("jffs2_getinfo\n"));
 
-	icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
 	init_dirsearch(&ds, (struct _inode *) dir, name);
 
 	err = jffs2_find(&ds);
@@ -1683,67 +1657,26 @@
 //
 //==========================================================================
 
-static struct page *read_cache_page(unsigned long index,
-			     int (*filler) (void *, struct page *), void *data)
-{
-	// Only called in gc.c jffs2_garbage_collect_dnode
-	// but gets a real page for the specified inode
-
-	int err;
-	struct page *gc_page = malloc(sizeof (struct page));
-
-	printf("read_cache_page\n");
-	memset(&gc_buffer, 0, PAGE_CACHE_SIZE);
-
-	if (gc_page != NULL) {
-		gc_page->virtual = &gc_buffer;
-		gc_page->index = index;
-
-		err = filler(data, gc_page);
-		if (err < 0) {
-			free(gc_page);
-			gc_page = NULL;
-		}
-	}
-
-	return gc_page;
-}
-
-static void page_cache_release(struct page *pg)
-{
-
-	// Only called in gc.c jffs2_garbage_collect_dnode
-	// but should free the page malloc'd by read_cache_page
-
-	printf("page_cache_release\n");
-	free(pg);
-}
-
 unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, 
 				   struct jffs2_inode_info *f, 
 				   unsigned long offset,
 				   unsigned long *priv)
 {
-	struct _inode *inode = OFNI_EDONI_2SFFJ(f);
-	struct page *pg;
+	/* FIXME: This works only with one file system mounted at a time */
+	int ret;
 
-	pg = read_cache_page(offset >> PAGE_CACHE_SHIFT, 
-			     (void *)jffs2_do_readpage_unlock, inode);
-	if (IS_ERR(pg))
-		return (void *)pg;
-	
-	*priv = (unsigned long)pg;
-	return kmap(pg);
+	ret = jffs2_read_inode_range(c, f, gc_buffer, offset, PAGE_CACHE_SIZE);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return gc_buffer;
 }
 
 void jffs2_gc_release_page(struct jffs2_sb_info *c,
 			   unsigned char *ptr,
 			   unsigned long *priv)
 {
-	struct page *pg = (void *)*priv;
-
-	kunmap(pg);
-	page_cache_release(pg);
+	/* Do nothing */
 }
 
 static struct _inode *new_inode(struct super_block *sb)
@@ -1785,6 +1718,7 @@
 
 	return inode;
 }
+
 struct _inode *ilookup(struct super_block *sb, cyg_uint32 ino)
 {
 	struct _inode *inode = NULL;
@@ -1810,6 +1744,7 @@
 	// If this fails let new_inode create one
 
 	struct _inode *inode;
+	int err;
 
 	D2(printf("iget\n"));
 
@@ -1824,10 +1759,13 @@
 
 	inode->i_ino = ino;
 	inode->i_count = 1;
-	if (jffs2_read_inode(inode)) {
+
+	err = jffs2_read_inode(inode);
+	if (err) {
 		printf("jffs2_read_inode() failed\n");
 		iput(inode);
 		inode = NULL;
+		return ERR_PTR(err);
 	}
 	return inode;
 }
@@ -1844,8 +1782,6 @@
 	// super.c jffs2_read_super,
 	// and gc.c jffs2_garbage_collect_pass
 
-	struct _inode *cached_inode;
-
 	if (!i) {
 		printf("iput() called with NULL inode\n");
 		// and let it fault... 
@@ -1856,60 +1792,22 @@
 	if (i->i_count)
 		return;
 
-	if (i != NULL) {
-		// Remove from the icache
-		for (cached_inode = i->i_sb->s_root; cached_inode != NULL;
-		     cached_inode = cached_inode->i_cache_next) {
-			if (cached_inode == i) {
-                                if(cached_inode->i_cache_prev != NULL) {
-				        cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next;	// Previous entry points ahead of us
-				        if (cached_inode->i_cache_next != NULL)
-					        cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev;	// Next entry points behind us
-                                }
-				break;
-			}
-		}
-		// inode has been seperated from the cache
+	if (!i->i_nlink) {
+		// Remove from the icache linked list and free immediately
+		if (i->i_cache_prev)
+			i->i_cache_prev->i_cache_next = i->i_cache_next;
+		if (i->i_cache_next)
+			i->i_cache_next->i_cache_prev = i->i_cache_prev;
+
 		jffs2_clear_inode(i);
 		free(i);
+	} else {
+		// Evict some _other_ inode with i_count zero, leaving
+		// this latest one in the cache for a while 
+		icache_evict(i->i_sb->s_root, i);
 	}
 }
 
-static int return_EIO(void)
-{
-	return -EIO;
-}
-
-#define EIO_ERROR ((void *) (return_EIO))
-
-void make_bad_inode(struct _inode *inode)
-{
-
-	// In readinode.c JFFS2 checks whether the inode has appropriate
-	// content for its marked type
-
-	D2(printf("make_bad_inode\n"));
-
-	inode->i_mode = S_IFREG;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = cyg_timestamp();
-	inode->i_op = EIO_ERROR;
-	inode->i_fop = EIO_ERROR;
-}
-
-int is_bad_inode(struct _inode *inode)
-{
-
-	// Called in super.c jffs2_read_super,
-	// and gc.c jffs2_garbage_collect_pass
-
-	D2(printf("is_bad_inode\n"));
-
-	return (inode->i_op == EIO_ERROR);
-	/*if(i == NULL)
-	   return 1;
-	   return 0; */
-}
-
 cyg_bool jffs2_flash_read(struct jffs2_sb_info * c,
 			  cyg_uint32 read_buffer_offset, const size_t size,
 			  size_t * return_size, char *write_buffer)
@@ -2098,7 +1996,6 @@
 	ri->mode =  cpu_to_jemode(mode);
 	ret = jffs2_do_new_inode (c, f, mode, ri);
 	if (ret) {
-		make_bad_inode(inode);
 		iput(inode);
 		return ERR_PTR(ret);
 	}
@@ -2133,7 +2030,6 @@
 	ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
 
 	if (ret) {
-		make_bad_inode(inode);
 		up(&f->sem);
 		return ret;
 	}
@@ -2208,15 +2104,8 @@
 		   Just iget() it, and if read_inode() is necessary that's OK.
 		*/
 		inode = iget(OFNI_BS_2SFFJ(c), inum);
-		if (!inode)
-			return ERR_PTR(-ENOMEM);
-	}
-	if (is_bad_inode(inode)) {
-		printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
-		       inum, nlink);
-		/* NB. This will happen again. We need to do something appropriate here. */
-		iput(inode);
-		return ERR_PTR(-EIO);
+		if (IS_ERR(inode))
+			return (void *)inode;
 	}
 
 	return JFFS2_INODE_INFO(inode);

Index: jffs2port.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/jffs2port.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- jffs2port.h	24 Nov 2003 13:49:38 -0000	1.6
+++ jffs2port.h	24 Nov 2003 14:54:39 -0000	1.7
@@ -172,8 +172,6 @@
 //static struct _inode * new_inode(struct super_block *sb);
 struct _inode * iget(struct super_block *sb, cyg_uint32 ino);
 void iput(struct _inode * i);
-void make_bad_inode(struct _inode * inode);
-int is_bad_inode(struct _inode * inode);
 
 struct jffs2_sb_info;
 struct jffs2_eraseblock;




More information about the linux-mtd-cvs mailing list