mtd/fs/jffs2/ecos/src fs-ecos.c,1.42,1.43

lunn at infradead.org lunn at infradead.org
Fri Feb 25 15:26:51 EST 2005


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

Modified Files:
	fs-ecos.c 
Log Message:
Fix the handling of O_TRUNC when opening a file with eCos. We did not
create new meta information which resulted in a missing inode.


Index: fs-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/fs-ecos.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- fs-ecos.c	8 Feb 2005 19:36:27 -0000	1.42
+++ fs-ecos.c	25 Feb 2005 20:26:47 -0000	1.43
@@ -78,6 +78,7 @@
 
 static int jffs2_read_inode (struct _inode *inode);
 static void jffs2_clear_inode (struct _inode *inode);
+static int jffs2_truncate_file (struct _inode *inode);
 
 //==========================================================================
 // Filesystem table entries
@@ -738,18 +739,20 @@
 		return EISDIR;
 	}
 
-#ifdef CYGOPT_FS_JFFS2_WRITE
+             // If the O_TRUNC bit is set we must clean out the file data.
 	if (mode & O_TRUNC) {
-		struct jffs2_inode_info *f = JFFS2_INODE_INFO(node);
-		struct jffs2_sb_info *c = JFFS2_SB_INFO(node->i_sb);
-		// If the O_TRUNC bit is set we must clean out the file data.
-
-		node->i_size = 0;
-		jffs2_truncate_fraglist(c, &f->fragtree, 0);
-		// Update file times
-		node->i_ctime = node->i_mtime = cyg_timestamp();
-	}
+#ifdef CYGOPT_FS_JFFS2_WRITE
+             err = jffs2_truncate_file(node);
+             if (err) {
+                  jffs2_iput(node);
+                  return err;
+             }
+#else
+             jffs2_iput(node);
+             return EROFS;
 #endif
+        }
+        
 	// Initialise the file object
 	file->f_flag |= mode & CYG_FILE_MODE_MASK;
 	file->f_type = CYG_FILE_TYPE_FILE;
@@ -1320,6 +1323,74 @@
 	return 0;
 }
 
+// jffs2_fo_open()
+// Truncate a file
+static int jffs2_truncate_file (struct _inode *inode)
+{
+     struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+     struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+     struct jffs2_full_dnode *new_metadata, * old_metadata;
+     struct jffs2_raw_inode *ri;
+     uint32_t phys_ofs, alloclen;
+     int err;
+     
+     ri = jffs2_alloc_raw_inode();
+     if (!ri) {
+          return ENOMEM;
+     }
+     err = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
+     
+     if (err) {
+          jffs2_free_raw_inode(ri);
+          return err;
+     }
+     down(&f->sem);
+     ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+     ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
+     ri->totlen = cpu_to_je32(sizeof(*ri));
+     ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
+     
+     ri->ino = cpu_to_je32(inode->i_ino);
+     ri->version = cpu_to_je32(++f->highest_version);
+     
+     ri->uid = cpu_to_je16(inode->i_uid);
+     ri->gid = cpu_to_je16(inode->i_gid);
+     ri->mode = cpu_to_jemode(inode->i_mode);
+     ri->isize = cpu_to_je32(0);
+     ri->atime = cpu_to_je32(inode->i_atime);
+     ri->mtime = cpu_to_je32(cyg_timestamp());
+     ri->offset = cpu_to_je32(0);
+     ri->csize = ri->dsize = cpu_to_je32(0);
+     ri->compr = JFFS2_COMPR_NONE;
+     ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
+     ri->data_crc = cpu_to_je32(0);
+     new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0, 
+                                      phys_ofs, ALLOC_NORMAL);
+     if (IS_ERR(new_metadata)) {
+          jffs2_complete_reservation(c);
+          jffs2_free_raw_inode(ri);
+          up(&f->sem);
+          return PTR_ERR(new_metadata);
+     }
+     
+     /* It worked. Update the inode */
+     inode->i_mtime = cyg_timestamp();
+     inode->i_size = 0;
+     old_metadata = f->metadata;
+     jffs2_truncate_fraglist (c, &f->fragtree, 0);
+     f->metadata = new_metadata;
+     if (old_metadata) {
+          jffs2_mark_node_obsolete(c, old_metadata->raw);
+          jffs2_free_full_dnode(old_metadata);
+     }
+     jffs2_free_raw_inode(ri);
+     
+     up(&f->sem);
+     jffs2_complete_reservation(c);
+     
+     return 0;
+}
+
 static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
 {
 	struct _inode *inode = (struct _inode *) fp->f_data;





More information about the linux-mtd-cvs mailing list