mtd/fs/jffs2/ecos/src dir-ecos.c,1.6,1.7 fs-ecos.c,1.16,1.17 jffs2port.h,1.7,1.8

David Woodhouse dwmw2 at infradead.org
Tue Nov 25 06:25:51 EST 2003


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

Modified Files:
	dir-ecos.c fs-ecos.c jffs2port.h 
Log Message:
fix inode use counts

Index: dir-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/dir-ecos.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- dir-ecos.c	24 Nov 2003 14:54:39 -0000	1.6
+++ dir-ecos.c	25 Nov 2003 11:25:48 -0000	1.7
@@ -150,7 +150,7 @@
 	return ret;
 }
 
-int jffs2_mkdir (struct _inode *dir_i, struct qstr *d_name, int mode, struct _inode **new_i)
+int jffs2_mkdir (struct _inode *dir_i, struct qstr *d_name, int mode)
 {
 	struct jffs2_inode_info *f, *dir_f;
 	struct jffs2_sb_info *c;
@@ -267,7 +267,7 @@
 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
 	up(&dir_f->sem);
 
-	*new_i = inode;
+	iput(inode);
 	return 0;
 }
 

Index: fs-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/fs-ecos.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- fs-ecos.c	24 Nov 2003 16:09:21 -0000	1.16
+++ fs-ecos.c	25 Nov 2003 11:25:48 -0000	1.17
@@ -171,6 +171,7 @@
 {
 	struct _inode *this = root_i, *next;
 
+ restart:
 	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 
@@ -178,13 +179,19 @@
 	while (this) {
 		next = this->i_cache_next;
 		if (this != i && this->i_count == 0) {
-
+			struct _inode *parent = this->i_parent;
 			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);
+			memset(this, 0x5a, sizeof(*this));
 			free(this);
+			if (parent && parent != this) {
+				parent->i_count--;
+				this = root_i;
+				goto restart;
+			}
 		}
 		this = next;
 	}
@@ -203,7 +210,6 @@
 	D2(printf("init_dirsearch name = %s\n", name));
 	D2(printf("init_dirsearch dir = %x\n", dir));
 
-	/* Increase inode refcount since find_entry will decrease it again */
 	dir->i_count++;
 	ds->dir = dir;
 	ds->path = name;
@@ -260,16 +266,15 @@
 			// Dot Dot 
 			// Move back up the search path
 			D2(printf("find_entry found ..\n"));
+			ds->dir = ds->node;
 			ds->node = ds->dir->i_parent;
-			if (ds->dir->i_count == 0) {
-				iput(ds->dir);	// This inode may be evicted
-				ds->dir = NULL;
-			}
+			ds->node->i_count++;
 			return ENOERR;
 		case 1:
 			// Dot is consumed
 			D2(printf("find_entry found .\n"));
 			ds->node = ds->dir;
+			ds->dir->i_count++;
 			return ENOERR;
 		}
 	// Here we have the name and its length set up.
@@ -295,11 +300,14 @@
 	if (d == NULL)
 		return ENOENT;
 
-	// The back path for dotdot to follow
-	d->i_parent = dir;
+	// If it's a new directory inode, increase refcount on its parent
+	if (S_ISDIR(d->i_mode) && !d->i_parent) {
+		d->i_parent = dir;
+		dir->i_count++;
+	}
+
 	// pass back the node we have found
 	ds->node = d;
-
 	return ENOERR;
 
 }
@@ -310,15 +318,18 @@
 // level operations to locate the object named by the pathname.
 
 // Returns with use count incremented on both the sought object and 
-// the directory it was found in.
+// the directory it was found in
 static int jffs2_find(jffs2_dirsearch * d)
 {
 	int err;
 
 	D2(printf("jffs2_find for path =%s\n", d->path));
+
 	// Short circuit empty paths
-	if (*(d->path) == '\0')
+	if (*(d->path) == '\0') {
+		d->node->i_count++;
 		return ENOERR;
+	}
 
 	// iterate down directory tree until we find the object
 	// we want.
@@ -331,7 +342,8 @@
 		if (d->last)
 			return ENOERR;
 
-		// Drop the directory we were using.
+		/* We're done with it, although it we found a subdir that
+		   will have caused the refcount to have been increased */
 		iput(d->dir);
 
 		// Update dirsearch object to search next directory.
@@ -486,7 +498,7 @@
 
 static int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte)
 {
-	extern cyg_mtab_entry mtab[], mtab_end;
+	extern cyg_mtab_entry cyg_mtab[], cyg_mtab_end;
 	struct super_block *jffs2_sb = NULL;
 	struct jffs2_sb_info *c;
 	cyg_mtab_entry *m;
@@ -502,10 +514,10 @@
 	// Iterate through the mount table to see if we're mounted
 	// FIXME: this should be done better - perhaps if the superblock
 	// can be stored as an inode in the icache.
-	for (m = &mtab[0]; m != &mtab_end; m++) {
+	for (m = &cyg_mtab[0]; m != &cyg_mtab_end; m++) {
 		// stop if there are more than the configured maximum
-		if (m - &mtab[0] >= CYGNUM_FILEIO_MTAB_MAX) {
-			m = &mtab_end;
+		if (m - &cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX) {
+			m = &cyg_mtab_end;
 			break;
 		}
 		if (m->valid && strcmp(m->fsname, "jffs2") == 0 &&
@@ -577,7 +589,7 @@
 	if (jffs2_sb->s_mount_count == 1) {
 		icache_evict(root, NULL);
 		if (root->i_cache_next != NULL)	{
-			struct _inode *inode = root->i_cache_next;
+			struct _inode *inode = root;
 			printf("Refuse to unmount.\n");
 			while (inode) {
 				printf("Ino #%u has use count %d\n",
@@ -587,6 +599,11 @@
 			// root icount was set to 1 on mount
 			return EBUSY;
                 }
+		if (root->i_count != 1) {
+			printf("Ino #1 has use count %d\n",
+			       root->i_count);
+			return EBUSY;
+		}
 		iput(root);	// Time to free the root inode
 
 		//Clear root inode
@@ -768,7 +785,6 @@
 static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
 {
 	jffs2_dirsearch ds;
-	struct _inode *node = NULL;
 	int err;
 
 	D2(printf("jffs2_ops_mkdir\n"));
@@ -799,7 +815,7 @@
 			this.len = hashname - (const char *) this.name;
 			this.hash = end_name_hash(hash);
 
-			err = -jffs2_mkdir(ds.dir, &this, 0, &node);
+			err = -jffs2_mkdir(ds.dir, &this, S_IRUGO|S_IXUGO|S_IWUSR);
 		}
 		// If this was not the last element, then an intermediate
 		// directory does not exist.
@@ -1128,7 +1144,6 @@
 
 		err = jffs2_find(&ds);
 		iput(ds.dir);
-		iput((struct _inode *)dir);
 
 		if (err != ENOERR)
 			return err;
@@ -1382,8 +1397,9 @@
 	ri.atime = ri.ctime = ri.mtime = cpu_to_je32(cyg_timestamp());
 
 	if (pos > inode->i_size) {
+		int err;
 		ri.version = cpu_to_je32(++f->highest_version);
-		int err = jffs2_extend_file(inode, &ri, pos);
+		err = jffs2_extend_file(inode, &ri, pos);
 		if (err)
 			return -err;
 	}
@@ -1733,8 +1749,7 @@
 	memset(inode, 0, sizeof (struct _inode));
 	inode->i_sb = sb;
 	inode->i_ino = 1;
-	inode->i_count = 0;	//1; // Let ecos manage the open count
-
+	inode->i_count = 1;
 	inode->i_nlink = 1;	// Let JFFS2 manage the link count
 	inode->i_size = 0;
 
@@ -1792,7 +1807,6 @@
 		return 0;
 
 	inode->i_ino = ino;
-	inode->i_count = 1;
 
 	err = jffs2_read_inode(inode);
 	if (err) {
@@ -1810,31 +1824,43 @@
 
 void iput(struct _inode *i)
 {
-
 	// Called in jffs2_find 
 	// (and jffs2_open and jffs2_ops_mkdir?)
 	// super.c jffs2_read_super,
 	// and gc.c jffs2_garbage_collect_pass
-
+ recurse:
 	if (!i) {
 		printf("iput() called with NULL inode\n");
 		// and let it fault... 
 	}
-	     
+
 	i->i_count--;
 
+	if (i->i_count < 0)
+		BUG();
+
 	if (i->i_count)
 		return;
 
 	if (!i->i_nlink) {
+		struct _inode *parent;
+
 		// 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;
 
+		parent = i->i_parent;
 		jffs2_clear_inode(i);
+		memset(i, 0x5a, sizeof(*i));
 		free(i);
+
+		if (parent && parent != i) {
+			i = parent;
+			goto recurse;
+		}
+
 	} else {
 		// Evict some _other_ inode with i_count zero, leaving
 		// this latest one in the cache for a while 

Index: jffs2port.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/jffs2port.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- jffs2port.h	24 Nov 2003 14:54:39 -0000	1.7
+++ jffs2port.h	25 Nov 2003 11:25:48 -0000	1.8
@@ -188,7 +188,7 @@
 struct _inode *jffs2_lookup(struct _inode *dir_i, struct qstr *name);
 int jffs2_readdir (struct _inode *d_inode, unsigned long f_pos, char *nbuf, int nlen);
 int jffs2_create(struct _inode *dir_i, struct qstr *d_name, int mode, struct _inode **new_i);
-int jffs2_mkdir (struct _inode *dir_i, struct qstr *d_name, int mode, struct _inode **new_i);
+int jffs2_mkdir (struct _inode *dir_i, struct qstr *d_name, int mode);
 int jffs2_link (struct _inode *old_d_inode, struct _inode *dir_i, struct qstr *d_name);
 int jffs2_unlink(struct _inode *dir_i, struct _inode *d_inode, struct qstr *d_name);
 int jffs2_rmdir (struct _inode *dir_i, struct _inode *d_inode, struct qstr *d_name);




More information about the linux-mtd-cvs mailing list