patch-2.4.19 linux-2.4.19/fs/jffs2/readinode.c

Next file: linux-2.4.19/fs/jffs2/scan.c
Previous file: linux-2.4.19/fs/jffs2/read.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/fs/jffs2/readinode.c linux-2.4.19/fs/jffs2/readinode.c
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: readinode.c,v 1.57 2001/12/27 22:49:46 dwmw2 Exp $
+ * $Id: readinode.c,v 1.58.2.5 2002/03/05 22:40:03 dwmw2 Exp $
  *
  */
 
@@ -173,12 +173,12 @@
 				jffs2_free_node_frag(newfrag);
 				return -ENOMEM;
 			}
-			printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
+			D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
 			if (this->node)
 				printk("phys 0x%08x\n", this->node->raw->flash_offset &~3);
 			else 
 				printk("hole\n");
-
+			   )
 			newfrag2->ofs = fn->ofs + fn->size;
 			newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
 			newfrag2->next = this->next;
@@ -251,6 +251,8 @@
 	struct jffs2_full_dnode *fn = NULL;
 	struct jffs2_sb_info *c;
 	struct jffs2_raw_inode latest_node;
+	__u32 latest_mctime, mctime_ver;
+	__u32 mdata_ver = 0;
 	int ret;
 	ssize_t retlen;
 
@@ -288,7 +290,7 @@
 	inode->i_nlink = f->inocache->nlink;
 
 	/* Grab all nodes relevant to this ino */
-	ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version);
+	ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
 
 	if (ret) {
 		printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
@@ -298,8 +300,6 @@
 	f->dents = fd_list;
 
 	while (tn_list) {
-		static __u32 mdata_ver = 0;
-
 		tn = tn_list;
 
 		fn = tn->fn;
@@ -335,6 +335,7 @@
 			printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");
 		}
 		inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
+		latest_node.version = 0;
 		inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 		inode->i_nlink = f->inocache->nlink;
 		inode->i_size = 0;
@@ -362,7 +363,7 @@
 		inode->i_uid = latest_node.uid;
 		inode->i_gid = latest_node.gid;
 		inode->i_size = latest_node.isize;
-		if ((inode->i_mode & S_IFMT) == S_IFREG)
+		if (S_ISREG(inode->i_mode))
 			jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);
 		inode->i_atime = latest_node.atime;
 		inode->i_mtime = latest_node.mtime;
@@ -372,9 +373,8 @@
 	/* OK, now the special cases. Certain inode types should
 	   have only one data node, and it's kept as the metadata
 	   node */
-	if ((inode->i_mode & S_IFMT) == S_IFBLK ||
-	    (inode->i_mode & S_IFMT) == S_IFCHR ||
-	    (inode->i_mode & S_IFMT) == S_IFLNK) {
+	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||
+	    S_ISLNK(inode->i_mode)) {
 		if (f->metadata) {
 			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode);
 			jffs2_clear_inode(inode);
@@ -389,7 +389,8 @@
 		}
 		/* ASSERT: f->fraglist != NULL */
 		if (f->fraglist->next) {
-			printk(KERN_WARNING "Argh. Special inode #%lu had more than one node\n", inode->i_ino);
+			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode);
+			/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
 			jffs2_clear_inode(inode);
 			make_bad_inode(inode);
 			return;
@@ -417,6 +418,12 @@
 		break;
 		
 	case S_IFDIR:
+		if (mctime_ver > latest_node.version) {
+			/* The times in the latest_node are actually older than
+			   mctime in the latest dirent. Cheat. */
+			inode->i_mtime = inode->i_ctime = inode->i_atime = 
+				latest_mctime;
+		}
 		inode->i_op = &jffs2_dir_inode_operations;
 		inode->i_fop = &jffs2_dir_operations;
 		break;
@@ -464,6 +471,8 @@
 
 	D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
 
+	down(&f->sem);
+
 	frags = f->fraglist;
 	fds = f->dents;
 	if (f->metadata) {
@@ -491,10 +500,7 @@
 		fds = fd->next;
 		jffs2_free_full_dirent(fd);
 	}
-	//	if (!f->inocache->nlink) {
-		//		D1(printk(KERN_DEBUG "jffs2_clear_inode() deleting inode #%lu\n", inode->i_ino));
-		//		jffs2_del_ino_cache(JFFS2_SB_INFO(inode->i_sb), f->inocache);
-		//		jffs2_free_inode_cache(f->inocache);
-	//	}
+
+	up(&f->sem);
 };
 

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