[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: