[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MinixFS: completed support for V2 filesystem



The v2 filesystem support in MinixFS is not complete: it lacks
handling of the triple indirection block.  This will allow for an
unlimited file size, but due to a bug in m_seek (signed comparison) it
cannot be greater than 0x7fffffff.


diff -ur orig/fsck/common.c ./fsck/common.c
--- orig/fsck/common.c	Fri May 13 06:13:18 1994
+++ ./fsck/common.c	Sun Jul 17 10:56:54 1994
@@ -103,7 +103,7 @@
 	long i;
 	int j;
 
-	for(i=0;i<(limit+15/16);i++)
+	for(i=0;i<(limit+15)/16;i++)
 	{
 		if(map[i]!=0xffff)
 		{
diff -ur orig/fsck/fs.h ./fsck/fs.h
--- orig/fsck/fs.h	Sat May  7 15:51:34 1994
+++ ./fsck/fs.h	Wed Dec 14 22:07:48 1994
@@ -85,7 +85,9 @@
 /* Macros for zone counts */
 
 #define	NO_IND(x)	(((x)-NDIR+NINDIR-1)/NINDIR)
-#define NO_DBL(x)	( (x > NDIR + NINDIR) ? 1 : 0)
+#define NO_DBL(x)	(((x) - NDIR - NINDIR + (long)NINDIR*NINDIR - 1) \
+			 / ((long)NINDIR*NINDIR))
+#define NO_TRPL(x)	((x) > NDIR + NINDIR + (long)NINDIR*NINDIR ? 1 : 0)
 
 #define ROOT_INODE  1	/* inode number for root directory */
 
diff -ur orig/fsck/fsck.c ./fsck/fsck.c
--- orig/fsck/fsck.c	Fri May 13 02:54:56 1994
+++ ./fsck/fsck.c	Thu Dec 15 20:57:58 1994
@@ -342,11 +342,14 @@
 		printf("Zone Bitmap : %ld Errors\n",berr);
 		if(ask("Install A New Map?","Fixed"))
 		{
+			int maxbit = Super->s_zmap_blks * BLOCKSIZE * 8;
 			for(i=1;i<=maxzone-minzone+1;i++)
 			{
 				if(isset(i,szbitmap)) setbit(i,zbitmap);
 				else clrbit(i,zbitmap);
 			}
+			for (; i < maxbit; i++)
+			  setbit (i, zbitmap);
 			write_blocks(2+Super->s_imap_blks,Super->s_zmap_blks,zbitmap);
 		}
 	}
@@ -371,12 +374,15 @@
 		printf("Inode Bitmap : %ld Errors\n",berr);
 		if(ask("Install A New Map?","Fixed"))
 		{
+			int maxbit = Super->s_imap_blks * BLOCKSIZE * 8;
 			ist=inode_status;
 			for(i=ROOT_INODE;i<=maxino;i++,ist++)
 			{
 				if(ist->flag & I_FREE) clrbit(i,ibitmap);
 				else setbit(i,ibitmap);
 			}
+			for (; i < maxbit; i++)
+			  setbit (i, ibitmap);
 			write_blocks(2,Super->s_imap_blks,ibitmap);
 		}
 	}
@@ -389,7 +395,8 @@
 /* traverse_zones passes pointers of the zone numbers of inode 'rip' to the 
  * function argument, if the value returned is non-zero then number was altered.
  * Also pass a 'level' parameter, this is zero for zone numbers, 1 for 
- * indirection blocks and 2 for double indirection blocks.
+ * indirection blocks, 2 for double indirection blocks and 3 for
+ * triple indirection blocks.
  */
 
 static void traverse_zones(func)
@@ -401,6 +408,9 @@
 	zonecount=(rip->i_size+BLOCKSIZE-1)/BLOCKSIZE;
 	indcount=NO_IND(zonecount);
 	dindcount=NO_DBL(zonecount);
+#ifdef V2
+	tindcount = NO_TRPL (zonecount);
+#endif
 
 	if(trunc!=2) trunc=0; /* 2 means silently truncate (directory) */
 	done_trunc=0;
@@ -440,9 +450,59 @@
 			}
 			else zonecount-=NINDIR;
 
-			if(zdirty) write_zone(rip->i_zone[NDIR+1],tmp1);
 		}
+		if(zdirty) write_zone(rip->i_zone[NDIR+1],tmp1);
 	}
+#ifdef V2
+	else
+	  zonecount -= (long) NINDIR * NINDIR;
+	if (chk_range (rip->i_zone[NDIR + 2]))
+	  {
+	    int zdirty = 0;
+	    read_zone (rip->i_zone[NDIR + 2], tmp1);
+	    for (i = 0; i < NINDIR; i++)
+	      {
+		if (func (&tmp1[i], 2))
+		  {
+		    zdirty = 1;
+		    continue;
+		  }
+		if  (chk_range (tmp1[i]))
+		  {
+		    int zdirty2 = 0;
+		    read_zone (tmp1[i], tmp2);
+		    for (j = 0; j < NINDIR; j++)
+		      {
+			if (func (&tmp2[j], 1))
+			  {
+			    zdirty2 = 1;
+			    continue;
+			  }
+			if (chk_range (tmp2[j]))
+			  {
+			    int zdirty3 = 0;
+			    int k;
+			    zone_nr tmp3[NINDIR];
+			    read_zone (tmp2[j], tmp3);
+			    for (k = 0; k < NINDIR; k++)
+			      if (func (&tmp3[k], 0))
+				zdirty3 = 1;
+			    if (zdirty3)
+			      write_zone (tmp2[j], tmp3);
+			  }
+			else
+			  zonecount -= NINDIR;
+		      }
+		    if (zdirty2)
+		      write_zone (tmp1[i], tmp2);
+		  }
+		else
+		  zonecount -= (long) NINDIR * NINDIR;
+	      }
+	    if (zdirty)
+	      write_zone (rip->i_zone[NDIR + 2], tmp1);
+	  }
+#endif
 }
 
 /* Pass 1 zone traversal , check zone range and note in bitmap, do truncation
@@ -494,6 +554,21 @@
 			}
 			else dindcount--;
 			break;
+
+#ifdef V2
+		      case 3:
+			if (tindcount == 0)
+			  {
+			    if (*zone && (trunc || do_trunc()))
+			      {
+				*zone = 0;
+				return 1;
+			      }
+			  }
+			else
+			  tindcount--;
+			break;
+#endif
 		}
 	}
 
diff -ur orig/fsck/global.h ./fsck/global.h
--- orig/fsck/global.h	Fri May 13 03:31:06 1994
+++ ./fsck/global.h	Wed Dec 14 20:34:07 1994
@@ -50,7 +50,8 @@
 
 EXTERN long zonecount;			/* Maximum Zone Count */
 EXTERN long indcount;			/* Number of indirection blocks */
-EXTERN char dindcount;			/* '1' If double indirection block */
+EXTERN char dindcount;			/* Number of double indirection blocks */
+EXTERN char tindcount;			/* '1' If triple indirection block */
 
 EXTERN char trunc,done_trunc;		/* Flags for truncation of files */
 
diff -ur orig/minit.c ./minit.c
--- orig/minit.c	Sat May  7 21:29:36 1994
+++ ./minit.c	Thu Dec 15 00:27:24 1994
@@ -516,7 +516,7 @@
 		sblk->s_firstdatazn=2+sblk->s_imap_blks+sblk->s_zmap_blks
 			+ ( v2 ? ((numinodes+15)/16) : ((numinodes+31)/32)) ;
 		sblk->s_log_zsize=0;
-		sblk->s_max_size= v2 ? 0x4041c00l : 0x10081c00l;
+		sblk->s_max_size= v2 ? 0x7fffffffl : 0x10081c00l;
 		if(v2) sblk->s_magic=0x2468;
 		else
 		{
diff -ur orig/minixfs/inode.c ./minixfs/inode.c
--- orig/minixfs/inode.c	Tue Apr 19 15:09:42 1994
+++ ./minixfs/inode.c	Wed Dec 14 22:02:34 1994
@@ -182,7 +182,8 @@
 	}
 	else count-=psblk->zpind;
 	/* Handle double indirect ... */
-	if(rip->i_zone[8]) {
+	if (count < (long) psblk->zpind * psblk->zpind) {
+	    if(rip->i_zone[8]) {
 		some=0;
 		dirty=0;
 		read_zone(rip->i_zone[8],&temp,drive,&syscache);
@@ -204,7 +205,6 @@
 						free_zone(PIND(vers,tmp,j),drive);
 						if(zap)PIND(vers,tmp,j)=0;
 						ldirty=1;
-						dirty=1;
 					}
 				}
 				if(count)count--;
@@ -213,6 +213,7 @@
 				q->status=0;
 				free_zone(IND(vers,temp,i),drive);
 				if(zap)IND(vers,temp,i)=0;
+				dirty=1;
 			    }
 			    else if(ldirty)
 #if 1
@@ -234,7 +235,108 @@
 			if(zap)rip->i_zone[8]=0;
 		}
 		else if(dirty)write_zone(rip->i_zone[8],&temp,drive,&syscache);
+	    }
 	}
+	else
+	    count -= (long) psblk->zpind * psblk->zpind;
+	/* Handle triple indirect ... */
+	if (rip->i_zone[9])
+	  {
+	    some = 0;
+	    dirty = 0;
+	    read_zone (rip->i_zone[9], &temp, drive, &syscache);
+	    for (i = 0; i < psblk->zpind; i++)
+	      {
+		if (IND (vers, temp, i))
+		  {
+		    char lsome, ldirty; /* local some, dirty for inds */
+		    lsome = 0;
+		    ldirty = 0;
+		    q = cache_get (IND (vers, temp, i), drive, &syscache,
+				   NOGUESS);
+		    tmp = q->buffer;
+		    for (j = 0; j < psblk->zpind; j++)
+		      {
+			if (PIND (vers, tmp, j))
+			  {
+			    char lsome1, ldirty1;
+			    int k;
+			    bufr *tmp2;
+			    cache *r;
+			    lsome1 = 0;
+			    ldirty1 = 0;
+			    r = cache_get (PIND (vers, tmp, j), drive,
+					   &syscache, NOGUESS);
+			    tmp2 = q->buffer;
+			    for (k = 0; k < psblk->zpind; k++)
+			      {
+				if (PIND (vers, tmp2, k))
+				  {
+				    if (count)
+				      {
+					some = 1;
+					lsome = 1;
+					lsome1 = 1;
+				      }
+				    else
+				      {
+					p = in_cache (PIND (vers, tmp2, k),
+						      drive, control, &guess);
+					if (p)
+					  p->status = 0;
+					free_zone (PIND (vers, tmp2, k),
+						   drive);
+					if (zap)
+					  PIND (vers, tmp2, k) = 0;
+					ldirty1 = 1;
+				      }
+				  }
+				if (count)
+				  count--;
+			      }
+			    if (!lsome1)
+			      {
+				r->status = 0;
+				free_zone (PIND (vers, tmp, j), drive);
+				if (zap)
+				  PIND (vers, tmp, j) = 0;
+				ldirty = 1;
+			      }
+			    else if (ldirty1)
+			      r->status = 2;
+			  }
+		      }
+		    if (!lsome)
+		      {
+			q->status = 0;
+			free_zone (IND (vers, temp, i), drive);
+			if (zap)
+			  IND (vers, temp, i) = 0;
+			dirty = 1;
+		      }
+		    else if (ldirty)
+		      q->status = 2;
+		  }
+		else 
+		  {
+		    if (count >= psblk->zpind)
+		      count -= psblk->zpind;
+		    else
+		      count = 0;
+		  }
+	      }
+	    if (!some)
+	      {
+		p = in_cache (rip->i_zone[9], drive, &syscache, NOGUESS);
+		if (p)
+		  p->status = 0;
+		free_zone (rip->i_zone[9], drive);
+		if (zap)
+		  rip->i_zone[9] = 0;
+	      }
+	    else if (dirty)
+	      write_zone (rip->i_zone[9], &temp, drive, &syscache);
+	  }
 }
 
 /* Inode version of (f)truncate , truncates a file to size 'length'
diff -ur orig/minixfs/minixdev.c ./minixfs/minixdev.c
--- orig/minixfs/minixdev.c	Mon Jan 24 15:25:44 1994
+++ ./minixfs/minixdev.c	Thu Dec 15 00:31:28 1994
@@ -394,7 +394,7 @@
 int flag;
 {
 	d_inode rip;
-	long max_size = super_ptr[f->fc.dev]->sblk.s_max_size;
+	unsigned long max_size = super_ptr[f->fc.dev]->sblk.s_max_size;
 
 	switch(flag) {
 	case SEEK_SET :
diff -ur orig/minixfs/minixfs.c ./minixfs/minixfs.c
--- orig/minixfs/minixfs.c	Fri May 13 05:18:04 1994
+++ ./minixfs/minixfs.c	Wed Dec 14 20:02:14 1994
@@ -300,6 +300,7 @@
 {
         d_inode rip;
 	long time_tmp;
+	long extra;
 	super_info *psblk;
 	psblk=super_ptr[file->dev];
 	read_inode(file->index,&rip,file->dev);
@@ -340,13 +341,23 @@
  * matter ('du' will return values that are slightly too high)
  */
 	xattr->nblocks = (xattr->size + (BLOCK_SIZE-1)) / BLOCK_SIZE;
-	if (xattr->nblocks >= psblk->dzpi)
-		xattr->nblocks++;	/* correct for the indirection block */
+	extra = 0;
+	if (xattr->nblocks > psblk->dzpi)
+		extra++;	/* correct for the indirection block */
 	if (xattr->nblocks > psblk->ndbl) {
-		xattr->nblocks++;	/* correct for double indirection block */
-		xattr->nblocks += ((xattr->nblocks-(psblk->ndbl+2))/psblk->zpind);
+		extra++;	/* correct for double indirection block */
+		extra += (xattr->nblocks - psblk->ndbl) / psblk->zpind;
 				/* and single indirection blocks */
 	}
+	if (xattr->nblocks > psblk->ndbl + (long) psblk->zpind * psblk->zpind)
+	  {
+	    extra++;	/* correct for triple indir block */
+	    /* and double indirection blocks */
+	    extra += ((xattr->nblocks - psblk->ndbl
+		       - (long) psblk->zpind * psblk->zpind)
+		      / ((long) psblk->zpind * psblk->zpind));
+	  }
+	xattr->nblocks += extra;
 
 	time_tmp=Dostime(_corr(rip.i_mtime));
 	xattr->mtime=time_tmp >> 16;
diff -ur orig/minixfs/minixfs.h ./minixfs/minixfs.h
--- orig/minixfs/minixfs.h	Thu May 12 04:25:12 1994
+++ ./minixfs/minixfs.h	Wed Dec 14 19:55:48 1994
@@ -220,7 +220,7 @@
 #define NR_INDIRECTS2	(BLOCK_SIZE/ZONE_NUM_SIZE2)
 #define LNR_IND2	8
 #define NR_DBL2		(NR_DZONE_NUM2+NR_INDIRECTS2)
-#define MAX_ZONES2 (NR_DZONE_NUMS2+(NR_INDIRECTS2+1l)*NR_INDIRECTS2)
+#define MAX_ZONES2 (NR_DZONE_NUMS2+((NR_INDIRECTS2+1l)*NR_INDIRECTS2+1l)*NR_INDIRECTS2)
 
 #ifndef SEEK_SET
 /* lseek() origins */
diff -ur orig/minixfs/zone.c ./minixfs/zone.c
--- orig/minixfs/zone.c	Tue Apr 19 15:09:40 1994
+++ ./minixfs/zone.c	Thu Dec 15 23:10:23 1994
@@ -447,6 +447,86 @@
 		temp_zone = *zptr=alloc_zone(drive) ;
 		goto new_zone;
 	}
+	/* Triple indirect */
+	numr -= NR_INDIRECTS2 * NR_INDIRECTS2;
+	if (numr < NR_INDIRECTS2 * NR_INDIRECTS2 * NR_INDIRECTS2)
+	  {
+	    long *zptr3;
+	    cache *tmp3;
+	    if (rip->i_zone[9])
+	      {
+		tmp3 = cget_zone (rip->i_zone[9], drive, &syscache, NOGUESS);
+		zptr3 = &tmp3->buffer->bind[numr >> (LNR_IND2 * 2)];
+		if (*zptr3)
+		  {
+		    tmp2 = cget_zone (*zptr3, drive, &syscache,
+				      &fch->dizguess);
+		    zptr2 = &tmp2->buffer->bind[(numr >> LNR_IND2)
+						& (NR_INDIRECTS2 - 1)];
+		    if (*zptr2)
+		      {
+			tmp = cget_zone (*zptr2, drive, &syscache,
+					 &fch->izguess);
+			zptr = &tmp->buffer->bind[numr & (NR_INDIRECTS2-1)];
+			if (*zptr || !flag)
+			  return *zptr;
+			if ((*zptr = alloc_zone (drive)) != 0)
+			  tmp->status = 2;
+			temp_zone = *zptr;
+			goto new_zone;
+		      }
+		    else
+		      {
+			if (!flag || !(*zptr2 = alloc_zone (drive)))
+			  return 0;
+			tmp2->status = 2;
+			tmp = cput_zone (*zptr2, drive, &syscache);
+			bzero (tmp->buffer, (size_t) BLOCK_SIZE);
+			zptr = &tmp->buffer->bind[numr & (NR_INDIRECTS2 - 1)];
+			temp_zone = *zptr = alloc_zone (drive);
+			goto new_zone;
+		      }
+		  }
+		else
+		  {
+		    if (!flag || !(*zptr3 = alloc_zone (drive)))
+		      return 0;
+		    tmp3->status = 2;
+		    tmp2 = cput_zone (*zptr3, drive, &syscache);
+		    bzero (tmp2->buffer, (size_t) BLOCK_SIZE);
+		    zptr2 = &tmp2->buffer->bind[(numr >> LNR_IND2)
+						& (NR_INDIRECTS2 - 1)];
+		    if (!(*zptr2 = alloc_zone (drive)))
+		      return 0;
+		    tmp = cput_zone (*zptr2, drive, &syscache);
+		    bzero (tmp->buffer, (size_t) BLOCK_SIZE);
+		    zptr = &tmp->buffer->bind[numr & (NR_INDIRECTS2 - 1)];
+		    temp_zone = *zptr = alloc_zone (drive);
+		    goto new_zone;
+		  }
+	      }
+	    if (!flag || !(rip->i_zone[9] = alloc_zone (drive)))
+	      return 0;
+
+	    tmp3 = cput_zone (rip->i_zone[9], drive, &syscache);
+	    bzero (tmp3->buffer, (size_t) BLOCK_SIZE);
+	    zptr3 = &tmp3->buffer->bind[numr >> (LNR_IND2 * 2)];
+	    if (!(*zptr3 = alloc_zone (drive)))
+	      return 0;
+
+	    tmp2 = cput_zone (*zptr3, drive, &syscache);
+	    bzero (tmp2->buffer, (size_t) BLOCK_SIZE);
+	    zptr2 = &tmp2->buffer->bind[(numr >> LNR_IND2)
+					& (NR_INDIRECTS2 - 1)];
+	    if (!(*zptr2 = alloc_zone (drive)))
+	      return 0;
+
+	    tmp = cput_zone (*zptr2, drive, &syscache);
+	    bzero (tmp->buffer, (size_t) BLOCK_SIZE);
+	    zptr = &tmp->buffer->bind[numr & (NR_INDIRECTS2 - 1)];
+	    temp_zone = *zptr = alloc_zone (drive);
+	    goto new_zone;
+	  }
 	return 0;
 
       new_zone: