diff -ruN linux-2.6.20.3/fs/ext3cow/CHANGELOG linux-2.6.20.3-ext3cow/fs/ext3cow/CHANGELOG
--- linux-2.6.20.3/fs/ext3cow/CHANGELOG	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.20.3-ext3cow/fs/ext3cow/CHANGELOG	2008-03-09 11:27:12.000000000 -0400
@@ -0,0 +1,12 @@
+3-9-08
+- Fixed a bug that resulted in the first block in a newly allocated indirect block to be allocated over and over again.
+- Fixed a bug that resulted in COW bitmaps not to be reset after truncate.
+- Bug e2fsprogs that caused aborting journal fixed.
+
+6-20-97
+- Finished the rollback code for inode chains in case of error.
+
+6-18-07
+- Added support for 32-bit uid's and gid's back in again
+- Took out support for block fragmentation
+- Hopefully fixed the non-sticking uid/gid bug.
\ No newline at end of file
diff -ruN linux-2.6.20.3/fs/ext3cow/dir.c linux-2.6.20.3-ext3cow/fs/ext3cow/dir.c
--- linux-2.6.20.3/fs/ext3cow/dir.c	2008-03-09 12:01:18.000000000 -0400
+++ linux-2.6.20.3-ext3cow/fs/ext3cow/dir.c	2008-03-09 11:14:49.000000000 -0400
@@ -109,7 +109,7 @@
 		 * of recovering data when there's a bad sector
 		 */
     if (!bh) {
-      ext3cow_error (sb, "ext3cow_readdir",
+      ext3cow_error (sb, "ext3cow_versions",
                      "directory #%lu contains a hole at offset %lu",
                      dir->i_ino, (unsigned long)filp->f_pos);
       /* corrupt size?  Maybe no more blocks to read */
@@ -148,7 +148,7 @@
     while (!error && filp->f_pos < dir->i_size 
            && offset < sb->s_blocksize) {
       de = (struct ext3cow_dir_entry_2 *) (bh->b_data + offset);
-      if (!ext3cow_check_dir_entry ("ext3cow_readdir", dir, de,
+      if (!ext3cow_check_dir_entry ("ext3cow_readversions", dir, de,
                                     bh, offset)) {
 				/* On error, skip the f_pos to the
            next block. */
diff -ruN linux-2.6.20.3/fs/ext3cow/ialloc.c linux-2.6.20.3-ext3cow/fs/ext3cow/ialloc.c
--- linux-2.6.20.3/fs/ext3cow/ialloc.c	2008-03-09 12:01:18.000000000 -0400
+++ linux-2.6.20.3-ext3cow/fs/ext3cow/ialloc.c	2008-03-09 11:14:48.000000000 -0400
@@ -578,9 +578,10 @@
 	if (!S_ISDIR(mode))
 		ei->i_flags &= ~EXT3COW_DIRSYNC_FL;
 #ifdef EXT3COW_FRAGMENTS
-	ei->i_faddr = 0;
-	ei->i_frag_no = 0;
-	ei->i_frag_size = 0;
+  /* Taken out for versioning -znjp */
+	//ei->i_faddr = 0;
+	//ei->i_frag_no = 0;
+	//ei->i_frag_size = 0;
 #endif
 	ei->i_file_acl = 0;
 	ei->i_dir_acl = 0;
diff -ruN linux-2.6.20.3/fs/ext3cow/inode.c linux-2.6.20.3-ext3cow/fs/ext3cow/inode.c
--- linux-2.6.20.3/fs/ext3cow/inode.c	2008-03-09 12:01:18.000000000 -0400
+++ linux-2.6.20.3-ext3cow/fs/ext3cow/inode.c	2008-03-09 11:14:48.000000000 -0400
@@ -387,25 +387,28 @@
 {
 	struct super_block *sb = inode->i_sb;
 	Indirect *p = chain;
-	struct buffer_head *bh;
-  u32* bitmap_w;
+	struct buffer_head *bh = NULL;
+  u32 *bitmap_w = NULL;
   int ptrs = EXT3COW_ADDR_PER_BLOCK(inode->i_sb);
   int nbitsperword = (sizeof(u32) * 8);
 
 	*err = 0;
   *cow = 0;
+
+
 	/* i_data is not going away, no lock needed */
 	add_chain (chain, NULL, EXT3COW_I(inode)->i_data + *offsets);
 	if (!p->key){
     /* Set the bitmap on allocation - znjp */
-    if(create)
+    if(create){
       EXT3COW_I(inode)->i_cow_bitmap |= (1UL << *offsets);
+    }
 		goto no_block;
   }
 
-  /* Are we COWing any direct blocks? -znjp */
+  /* Are we writing and COWing any direct blocks? -znjp */
   if(create && !(EXT3COW_I(inode)->i_cow_bitmap & (1UL << *offsets))){    
-    printk(KERN_INFO "COWing direct block\n");
+    //printk(KERN_INFO "COWing direct block\n");
     *(p->p) = 0;
     p->key = 0;
     /* Set the bitamp when COWing -znjp */
@@ -415,6 +418,7 @@
   }
 
 	while (--depth) {
+
 		bh = sb_bread(sb, le32_to_cpu(p->key));
 		if (!bh)
 			goto failure;
@@ -424,23 +428,23 @@
 			goto changed;
 		add_chain(++p, bh, (__le32*)bh->b_data + *++offsets);
 		/* Reader: end */
-    /* Find correct bitamp word */
+    /* Find correct bitmap word */
     bitmap_w = (u32*)bh->b_data + ptrs + (*offsets/nbitsperword);
 		if (!p->key){
       /* Set the bitmap when allocating -znjp */
-      if(create)
-       *bitmap_w = (u32)*bitmap_w | (u32)(1UL << (int)(*offsets%nbitsperword));
+      if(create){
+       *bitmap_w |= (u32)(1UL << (int)(*offsets%nbitsperword));
+      }
 			goto no_block;
     }
 
     /* Are we COWing any indirect blocks? -znjp */
-    if(create && !((1UL << (int)(*offsets%nbitsperword)) & 
-         le32_to_cpu((u32)*bitmap_w))){
-      printk(KERN_INFO "COWing indirect block\n");
+    if(create && !(*bitmap_w & (1UL << (int)(*offsets%nbitsperword)))){
+      //printk(KERN_INFO "COWing indirect block\n");
       *(p->p) = 0;
       p->key = 0;
       /* Set the bitmap -znjp */
-      *bitmap_w = (u32)*bitmap_w | (u32)(1UL << (int)(*offsets%nbitsperword));
+      *bitmap_w |= (u32)(1UL << (int)(*offsets%nbitsperword));
       *cow = 1;
       goto no_block;
     }
@@ -672,6 +676,10 @@
 	ext3cow_fsblk_t new_blocks[4];
 	ext3cow_fsblk_t current_block;
 
+  u32 *bitmap_w = NULL;
+  int ptrs = EXT3COW_ADDR_PER_BLOCK(inode->i_sb);
+  int nbitsperword = (sizeof(u32) * 8);
+
 	num = ext3cow_alloc_blocks(handle, inode, goal, indirect_blks,
 				*blks, new_blocks, &err);
 	if (err)
@@ -681,6 +689,7 @@
 	/*
 	 * metadata blocks and data blocks are allocated.
 	 */
+
 	for (n = 1; n <= indirect_blks;  n++) {
 		/*
 		 * Get buffer_head for parent block, zero it out
@@ -699,6 +708,13 @@
 		}
 
 		memset(bh->b_data, 0, blocksize);
+    /* Mark the cow bitmap for each new indirect block allocated.
+     * We had to put this here, because get_branch was insufficient
+     * when allocating an indirect block. -znjp
+     */
+    bitmap_w = (u32*)bh->b_data + ptrs + (offsets[n]/nbitsperword);
+    *bitmap_w |= (u32)(1UL << (int)(offsets[n]%nbitsperword));
+
 		branch[n].p = (__le32 *) bh->b_data + offsets[n];
 		branch[n].key = cpu_to_le32(new_blocks[n]);
 		*branch[n].p = branch[n].key;
@@ -2277,6 +2293,7 @@
 				continue;
 			}
       /* Only free the branches that have been newly allocated - znjp */
+      /* Also, set the bits back to 0 in the bitmap -znjp */
       cur = 0;
       count = 0;
       bitmap_word = (u32*)bh->b_data + addr_per_block;
@@ -2299,6 +2316,8 @@
               first_block = (u32*)bh->b_data + cur;
               count = 1;
             }
+            /* Set the bit in the bitmap back to 0 */
+            *bitmap_word ^= (1UL << i);
           }
         }
         (u32*)bitmap_word++;
@@ -2510,6 +2529,9 @@
 
     /* We only want to remove blocks that were allocated in this
      * epoch, i.e., have 1 bit in the bitmap. -znjp */
+    /* If we're going to truncate a block, we should its
+     * corresponding bit in the bitmap back to 0, meaning,
+     * it needs to be allocated - znjp */ 
     for(b = offsets[0]; b < EXT3COW_NDIR_BLOCKS; b++){
       if(EXT3COW_I(inode)->i_cow_bitmap & (1UL << b)){
         if(count == 0){
@@ -2523,6 +2545,8 @@
           block_to_free = b;
           count = 1;
         }
+        /* Turn off the bit in the bitmap */
+        EXT3COW_I(inode)->i_cow_bitmap ^= (1UL << b);
       }
     }
     if(count > 0)
@@ -2573,6 +2597,8 @@
        ext3cow_free_branches(handle, inode, NULL, &nr, &nr+1, 1);
        i_data[EXT3COW_IND_BLOCK] = 0;
      }
+     /* And set bitmap back to 0 */
+     EXT3COW_I(inode)->i_cow_bitmap ^= (1UL << EXT3COW_IND_BLOCK);
    }
 	case EXT3COW_IND_BLOCK:
    if(EXT3COW_I(inode)->i_cow_bitmap & (1UL << EXT3COW_DIND_BLOCK)){
@@ -2581,6 +2607,7 @@
        ext3cow_free_branches(handle, inode, NULL, &nr, &nr+1, 2);
        i_data[EXT3COW_DIND_BLOCK] = 0;
      }
+     EXT3COW_I(inode)->i_cow_bitmap ^= (1UL << EXT3COW_DIND_BLOCK);
    }
 	case EXT3COW_DIND_BLOCK:
    if(EXT3COW_I(inode)->i_cow_bitmap & (1UL << EXT3COW_TIND_BLOCK)){
@@ -2589,6 +2616,7 @@
        ext3cow_free_branches(handle, inode, NULL, &nr, &nr+1, 3);
        i_data[EXT3COW_TIND_BLOCK] = 0;
      }
+     EXT3COW_I(inode)->i_cow_bitmap ^= (1UL << EXT3COW_TIND_BLOCK);
    }
 	case EXT3COW_TIND_BLOCK:
 		;
@@ -2825,12 +2853,10 @@
 	inode->i_mode = le16_to_cpu(raw_inode->i_mode);
 	inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
 	inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
-  /* Taken out for versioning -znjp
 	if(!(test_opt (inode->i_sb, NO_UID32))) {
 		inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
 		inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
 	}
-  */
 	inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
 	inode->i_size = le32_to_cpu(raw_inode->i_size);
 	inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
@@ -2866,9 +2892,10 @@
   ei->i_next_inode   = le32_to_cpu(raw_inode->i_nxt_inode);
   
 #ifdef EXT3COW_FRAGMENTS
-	ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
-	ei->i_frag_no = raw_inode->i_frag;
-	ei->i_frag_size = raw_inode->i_fsize;
+  /* Taken out for versioning -znjp */
+	//ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
+	//ei->i_frag_no = raw_inode->i_frag;
+	//ei->i_frag_size = raw_inode->i_fsize;
 #endif
 	ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
 	if (!S_ISREG(inode->i_mode)) {
@@ -2968,15 +2995,15 @@
 
 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
 
-  /* Taken out for versioning  -znjp
+
 	if(!(test_opt(inode->i_sb, NO_UID32))) {
 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
 		raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
-*
- * Fix up interoperability with old kernels. Otherwise, old inodes get
- * re-used with the upper 16 bits of the uid/gid intact
- *
-
+    
+    /* Fix up interoperability with old kernels. Otherwise, old inodes get
+     * re-used with the upper 16 bits of the uid/gid intact
+     */
+    
 		if(!ei->i_dtime) {
 			raw_inode->i_uid_high =
 				cpu_to_le16(high_16_bits(inode->i_uid));
@@ -2995,7 +3022,7 @@
 		raw_inode->i_uid_high = 0;
 		raw_inode->i_gid_high = 0;
 	}
-  */
+ 
 	raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
 	raw_inode->i_size = cpu_to_le32(ei->i_disksize);
 	raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
@@ -3010,9 +3037,10 @@
   raw_inode->i_nxt_inode   = cpu_to_le32(EXT3COW_I(inode)->i_next_inode);
 
 #ifdef EXT3COW_FRAGMENTS
-	raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
-	raw_inode->i_frag = ei->i_frag_no;
-	raw_inode->i_fsize = ei->i_frag_size;
+  /* Taken out for versioning -znjp */
+	//raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
+	//raw_inode->i_frag = ei->i_frag_no;
+	//raw_inode->i_fsize = ei->i_frag_size;
 #endif
 	raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
 	if (!S_ISREG(inode->i_mode)) {
diff -ruN linux-2.6.20.3/fs/ext3cow/namei.c linux-2.6.20.3-ext3cow/fs/ext3cow/namei.c
--- linux-2.6.20.3/fs/ext3cow/namei.c	2008-03-09 12:01:18.000000000 -0400
+++ linux-2.6.20.3-ext3cow/fs/ext3cow/namei.c	2008-03-09 11:14:48.000000000 -0400
@@ -1569,7 +1569,6 @@
 
   if(EXT3COW_S_EPOCHNUMBER(sb) > EXT3COW_I_EPOCHNUMBER(dir)){   
     if(ext3cow_dup_inode(dentry->d_parent->d_parent->d_inode, dir))
-      //if(ext3cow_dup_inode(NULL, dir))
       return -1;
   }
 
@@ -1778,7 +1777,6 @@
       
       if(EXT3COW_S_EPOCHNUMBER(dir->i_sb) > EXT3COW_I_EPOCHNUMBER(dir)){
         if(ext3cow_dup_inode(dentry->d_parent->d_parent->d_inode, dir))
-          //if(ext3cow_dup_inode(NULL, dir))
           return -1;
       }
 
@@ -2655,11 +2653,6 @@
     fake_inode->i_uid  = inode->i_uid;
     fake_inode->i_gid  = inode->i_gid;
 
-    /* uid_high and gid_high code would go here -znjp 
-       fake_inode->i_uid_high = inode->i_uid_high;
-       fake_inode->i_gid_high = inode->i_gid_high;
-    */
-
     atomic_set(&fake_inode->i_count, 1);
 
     fake_inode->i_nlink         = inode->i_nlink;
@@ -2678,9 +2671,10 @@
     fake_inode->i_blocks  = inode->i_blocks;
     fake_ini->i_flags     = ini->i_flags;
 #ifdef EXT3COW_FRAGMENTS
-    fake_ini->i_faddr     = ini->i_faddr;
-    fake_ini->i_frag_no   = ini->i_frag_no;
-    fake_ini->i_frag_size = ini->i_frag_size;
+    /* Taken out for versioning -znjp */
+    //fake_ini->i_faddr     = ini->i_faddr;
+    //fake_ini->i_frag_no   = ini->i_frag_no;
+    //fake_ini->i_frag_size = ini->i_frag_size;
 #endif
     fake_ini->i_file_acl = ini->i_file_acl;
     if (!S_ISREG(fake_inode->i_mode)) {
@@ -2810,11 +2804,6 @@
     cow_inode->i_mode = inode->i_mode;
     cow_inode->i_uid  = inode->i_uid;
     cow_inode->i_gid  = inode->i_gid;
-    
-    /* uid_high and gid_high code would go here -znjp 
-       cow_inode->i_uid_high = inode->i_uid_high;
-       cow_inode->i_gid_high = inode->i_gid_high;
-    */
 
     cow_inode->i_nlink         = inode->i_nlink;
     cow_inode->i_size          = inode->i_size;
@@ -2832,9 +2821,10 @@
     cow_inode->i_blocks  = inode->i_blocks;
     cow_ini->i_flags     = ini->i_flags;
 #ifdef EXT3COW_FRAGMENTS
-    cow_ini->i_faddr     = ini->i_faddr;
-    cow_ini->i_frag_no   = ini->i_frag_no;
-    cow_ini->i_frag_size = ini->i_frag_size;
+    /* Taken out for versioning -znjp */
+    //cow_ini->i_faddr     = ini->i_faddr;
+    //cow_ini->i_frag_no   = ini->i_frag_no;
+    //cow_ini->i_frag_size = ini->i_frag_size;
 #endif
     cow_ini->i_file_acl = ini->i_file_acl;
     if (!S_ISREG(cow_inode->i_mode)) {
@@ -2915,14 +2905,43 @@
  * be used for removing versions.  */
 int ext3cow_reclaim_dup_inode(struct inode *dir, struct inode *inode)
 {
-  //  handle_t *handle = NULL;
+  handle_t *handle = NULL;
+  int err = 0;
+  struct inode *old_inode = NULL;
+  struct inode *parent = dir;
+
+  if(!parent)
+    parent = inode;
 
   if(is_bad_inode(inode))
-    goto no_delete;
+    return -1;
+  
+  handle = ext3cow_journal_start(parent, 
+                                 EXT3COW_DELETE_TRANS_BLOCKS(parent->i_sb));
+  if(IS_ERR(handle))
+    return PTR_ERR(handle);
+
+  if(IS_DIRSYNC(parent))
+    handle->h_sync = 1;
+
+  old_inode = iget(parent->i_sb, EXT3COW_I_NEXT_INODE(inode));
+  err = PTR_ERR(old_inode);
+  if (!IS_ERR(old_inode)){
+
+    EXT3COW_I(inode)->i_epoch_number = EXT3COW_I_EPOCHNUMBER(old_inode);
+    EXT3COW_I(inode)->i_cow_bitmap   = EXT3COW_I(old_inode)->i_cow_bitmap;
+    EXT3COW_I(inode)->i_next_inode   = EXT3COW_I(old_inode)->i_next_inode;
+    old_inode->i_nlink = 0;
 
+    iput(old_inode);
+    ext3cow_mark_inode_dirty(handle, inode);
+  }else
+    ext3cow_error(inode->i_sb, "ext3cow_reclaim_dup_inode", 
+                  "Couldn't remove dup'd inode.");
+  
+  ext3cow_journal_stop(handle);
+  
   return 0;
- no_delete:
-  return -1;
 }
 
 /*
diff -ruN linux-2.6.20.3/include/linux/ext3cow_fs.h linux-2.6.20.3-ext3cow/include/linux/ext3cow_fs.h
--- linux-2.6.20.3/include/linux/ext3cow_fs.h	2008-03-09 12:01:18.000000000 -0400
+++ linux-2.6.20.3-ext3cow/include/linux/ext3cow_fs.h	2008-03-09 11:10:57.000000000 -0400
@@ -28,6 +28,7 @@
  */
 #undef EXT3COWFS_DEBUG
 
+
 /*
  * Define EXT3COW_RESERVATION to reserve data blocks for expanding files
  */
@@ -321,11 +322,11 @@
 	__le32	i_faddr;	/* Fragment address */
 	union {
 		struct {
-			__u8	l_i_frag;	/* Fragment number */
-			__u8	l_i_fsize;	/* Fragment size */
-			__u16	i_pad1;
-			//__le16	l_i_uid_high;	/* these 2 fields    */
-			//__le16	l_i_gid_high;	/* were reserved2[0] */
+			//__u8	l_i_frag;	/* Fragment number */
+			//__u8	l_i_fsize;	/* Fragment size */
+			//__u16	i_pad1;
+			__le16	l_i_uid_high;	/* these 2 fields    */
+			__le16	l_i_gid_high;	/* were reserved2[0] */
 			//__u32	l_i_reserved2;
       /* Epoch number for versioning -znjp */
       __le32 l_i_epoch_number;
@@ -356,13 +357,13 @@
 /* For versioning -znjp */
 //#define i_reserved1	osd1.linux1.l_i_reserved1
 #define i_cowbitmap osd1.linux1.l_i_direct_cow_bitmap
-#define i_frag		osd2.linux2.l_i_frag
-#define i_fsize		osd2.linux2.l_i_fsize
+//#define i_frag		osd2.linux2.l_i_frag
+//#define i_fsize		osd2.linux2.l_i_fsize
 #define i_uid_low	i_uid
 #define i_gid_low	i_gid
 /* For versioning -znjp */
-//#define i_uid_high	osd2.linux2.l_i_uid_high
-//#define i_gid_high	osd2.linux2.l_i_gid_high
+#define i_uid_high	osd2.linux2.l_i_uid_high
+#define i_gid_high	osd2.linux2.l_i_gid_high
 //#define i_reserved2	osd2.linux2.l_i_reserved2
 #define i_epch_number osd2.linux2.l_i_epoch_number
 #define i_nxt_inode osd2.linux2.l_i_next_inode


