Support for larger disks.
- MFS, df(1), fsck(1), badblocks(8), de(1x) now compute the superblock's s_firstdatazone value if the on-disk value is zero - mkfs(1) sets s_firstdatazone in the superblock to zero if the on-disk field is too small to store the actual value - more agressive mkfs(1) inode number heuristic, copied from r5261
This commit is contained in:
parent
6aa43dc9e4
commit
d5dee93bee
8 changed files with 97 additions and 46 deletions
|
@ -188,13 +188,14 @@ void Read_Super_Block( s )
|
||||||
|
|
||||||
s->inode_blocks = (s->inodes + inodes_per_block - 1) / inodes_per_block;
|
s->inode_blocks = (s->inodes + inodes_per_block - 1) / inodes_per_block;
|
||||||
s->first_data = 2 + s->inode_maps + s->zone_maps + s->inode_blocks;
|
s->first_data = 2 + s->inode_maps + s->zone_maps + s->inode_blocks;
|
||||||
if ( s->first_data != super->s_firstdatazone )
|
if ( super->s_firstdatazone_old != 0 &&
|
||||||
|
s->first_data != super->s_firstdatazone_old )
|
||||||
{
|
{
|
||||||
if ( s->first_data > super->s_firstdatazone )
|
if ( s->first_data > super->s_firstdatazone_old )
|
||||||
Error( "Corrupted first data zone offset or inode count in super block" );
|
Error( "Corrupted first data zone offset or inode count in super block" );
|
||||||
else
|
else
|
||||||
Warning( "First data zone in super block suspiciously high" );
|
Warning( "First data zone in super block suspiciously high" );
|
||||||
s->first_data = super->s_firstdatazone;
|
s->first_data = super->s_firstdatazone_old;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->inodes_in_map = s->inodes + 1;
|
s->inodes_in_map = s->inodes + 1;
|
||||||
|
|
|
@ -170,7 +170,7 @@ int rw_mode;
|
||||||
|
|
||||||
i_num = stat_ptr->st_ino;
|
i_num = stat_ptr->st_ino;
|
||||||
|
|
||||||
blk = (block_t) (2 + sp->s_imap_blocks + sp->s_zmap_blocks);
|
blk = (block_t) (START_BLOCK + sp->s_imap_blocks + sp->s_zmap_blocks);
|
||||||
blk += (block_t) ((i_num - 1) / inodes_per_block);
|
blk += (block_t) ((i_num - 1) / inodes_per_block);
|
||||||
blk *= (block_t) (BLOCK_SIZE);/* this block */
|
blk *= (block_t) (BLOCK_SIZE);/* this block */
|
||||||
|
|
||||||
|
@ -334,6 +334,14 @@ char *argv[];
|
||||||
inode_size = V2_INODE_SIZE;
|
inode_size = V2_INODE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the s_firstdatazone_old field is zero, we have to compute the value. */
|
||||||
|
if (sp->s_firstdatazone_old == 0)
|
||||||
|
sp->s_firstdatazone =
|
||||||
|
START_BLOCK + sp->s_imap_blocks + sp->s_zmap_blocks +
|
||||||
|
(sp->s_ninodes + inodes_per_block - 1) / inodes_per_block;
|
||||||
|
else
|
||||||
|
sp->s_firstdatazone = sp->s_firstdatazone_old;
|
||||||
|
|
||||||
get_inode(&stat_buf);
|
get_inode(&stat_buf);
|
||||||
|
|
||||||
for (finished = 0; !finished;) {
|
for (finished = 0; !finished;) {
|
||||||
|
@ -481,7 +489,7 @@ block_t num;
|
||||||
offset = z_num - (blk << BIT_MAP_SHIFT); /* offset */
|
offset = z_num - (blk << BIT_MAP_SHIFT); /* offset */
|
||||||
words = z_num / INT_BITS; /* which word */
|
words = z_num / INT_BITS; /* which word */
|
||||||
|
|
||||||
blk_offset = (block_t) (2 + sp->s_imap_blocks); /* zone map */
|
blk_offset = (block_t) (START_BLOCK + sp->s_imap_blocks); /* zone map */
|
||||||
blk_offset *= (block_t) BLOCK_SIZE; /* of course in block */
|
blk_offset *= (block_t) BLOCK_SIZE; /* of course in block */
|
||||||
blk_offset += (block_t) (words * SIZE_OF_INT); /* offset */
|
blk_offset += (block_t) (words * SIZE_OF_INT); /* offset */
|
||||||
|
|
||||||
|
@ -520,7 +528,7 @@ zone_t num;
|
||||||
offset = z_num - (blk << BIT_MAP_SHIFT); /* offset in block */
|
offset = z_num - (blk << BIT_MAP_SHIFT); /* offset in block */
|
||||||
words = z_num / INT_BITS; /* which word */
|
words = z_num / INT_BITS; /* which word */
|
||||||
|
|
||||||
blk_offset = (long) (2 + sp->s_imap_blocks);
|
blk_offset = (long) (START_BLOCK + sp->s_imap_blocks);
|
||||||
blk_offset *= (long) BLOCK_SIZE;
|
blk_offset *= (long) BLOCK_SIZE;
|
||||||
blk_offset += (long) (words * SIZE_OF_INT);
|
blk_offset += (long) (words * SIZE_OF_INT);
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ int df(const struct mtab *mt)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
bit_t i_count, z_count;
|
bit_t i_count, z_count;
|
||||||
block_t totblocks, busyblocks;
|
block_t totblocks, busyblocks, offset;
|
||||||
int n, block_size;
|
int n, block_size;
|
||||||
struct v12_super_block super, *sp;
|
struct v12_super_block super, *sp;
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ int df(const struct mtab *mt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sp->s_magic != SUPER_V3) block_size = _STATIC_BLOCK_SIZE;
|
if(sp->s_magic != SUPER_V3) block_size = _STATIC_BLOCK_SIZE;
|
||||||
else block_size = super.s_block_size;
|
else block_size = sp->s_block_size;
|
||||||
|
|
||||||
if(block_size < _MIN_BLOCK_SIZE) {
|
if(block_size < _MIN_BLOCK_SIZE) {
|
||||||
fprintf(stderr, "df: %s: funny block size (%d)\n",
|
fprintf(stderr, "df: %s: funny block size (%d)\n",
|
||||||
|
@ -309,7 +309,24 @@ int df(const struct mtab *mt)
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp->s_magic == SUPER_V1) sp->s_zones= sp->s_nzones;
|
if (sp->s_magic == SUPER_V1) {
|
||||||
|
sp->s_zones = sp->s_nzones;
|
||||||
|
sp->s_inodes_per_block = V1_INODES_PER_BLOCK;
|
||||||
|
} else {
|
||||||
|
sp->s_inodes_per_block = V2_INODES_PER_BLOCK(block_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the s_firstdatazone_old field is zero, we have to compute the value. */
|
||||||
|
if (sp->s_firstdatazone_old == 0) {
|
||||||
|
offset = START_BLOCK + sp->s_imap_blocks + sp->s_zmap_blocks;
|
||||||
|
offset += (sp->s_ninodes + sp->s_inodes_per_block - 1) /
|
||||||
|
sp->s_inodes_per_block;
|
||||||
|
|
||||||
|
sp->s_firstdatazone = (offset + (1 << sp->s_log_zone_size) - 1) >>
|
||||||
|
sp->s_log_zone_size;
|
||||||
|
} else {
|
||||||
|
sp->s_firstdatazone = sp->s_firstdatazone_old;
|
||||||
|
}
|
||||||
|
|
||||||
lseek(fd, (off_t) block_size * 2L, SEEK_SET); /* skip rest of super block */
|
lseek(fd, (off_t) block_size * 2L, SEEK_SET); /* skip rest of super block */
|
||||||
|
|
||||||
|
|
|
@ -528,8 +528,8 @@ void lsuper()
|
||||||
if (input(buf, 80)) sb.s_imap_blocks = atol(buf);
|
if (input(buf, 80)) sb.s_imap_blocks = atol(buf);
|
||||||
printf("zmap_blocks = %u", sb.s_zmap_blocks);
|
printf("zmap_blocks = %u", sb.s_zmap_blocks);
|
||||||
if (input(buf, 80)) sb.s_zmap_blocks = atol(buf);
|
if (input(buf, 80)) sb.s_zmap_blocks = atol(buf);
|
||||||
printf("firstdatazone = %u", sb.s_firstdatazone);
|
printf("firstdatazone = %u", sb.s_firstdatazone_old);
|
||||||
if (input(buf, 80)) sb.s_firstdatazone = atol(buf);
|
if (input(buf, 80)) sb.s_firstdatazone_old = atol(buf);
|
||||||
printf("log_zone_size = %u", sb.s_log_zone_size);
|
printf("log_zone_size = %u", sb.s_log_zone_size);
|
||||||
if (input(buf, 80)) sb.s_log_zone_size = atol(buf);
|
if (input(buf, 80)) sb.s_log_zone_size = atol(buf);
|
||||||
printf("maxsize = %ld", sb.s_max_size);
|
printf("maxsize = %ld", sb.s_max_size);
|
||||||
|
@ -569,12 +569,12 @@ void getsuper()
|
||||||
if (sb.s_zones <= 0) fatal("no zones");
|
if (sb.s_zones <= 0) fatal("no zones");
|
||||||
if (sb.s_imap_blocks <= 0) fatal("no imap");
|
if (sb.s_imap_blocks <= 0) fatal("no imap");
|
||||||
if (sb.s_zmap_blocks <= 0) fatal("no zmap");
|
if (sb.s_zmap_blocks <= 0) fatal("no zmap");
|
||||||
if (sb.s_firstdatazone <= 4) fatal("first data zone too small");
|
if (sb.s_firstdatazone != 0 && sb.s_firstdatazone <= 4)
|
||||||
|
fatal("first data zone too small");
|
||||||
if (sb.s_log_zone_size < 0) fatal("zone size < block size");
|
if (sb.s_log_zone_size < 0) fatal("zone size < block size");
|
||||||
if (sb.s_max_size <= 0) {
|
if (sb.s_max_size <= 0) {
|
||||||
printf("max file size %ld ", sb.s_max_size);
|
printf("warning: invalid max file size %ld\n", sb.s_max_size);
|
||||||
sb.s_max_size = LONG_MAX;
|
sb.s_max_size = LONG_MAX;
|
||||||
printf("set to %ld\n", sb.s_max_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,17 +602,22 @@ void chksuper()
|
||||||
pr("warning: expected %d zmap_block%s", n, "", "s");
|
pr("warning: expected %d zmap_block%s", n, "", "s");
|
||||||
printf(" instead of %d\n", sb.s_zmap_blocks);
|
printf(" instead of %d\n", sb.s_zmap_blocks);
|
||||||
}
|
}
|
||||||
if (sb.s_firstdatazone >= sb.s_zones)
|
|
||||||
fatal("first data zone too large");
|
|
||||||
if (sb.s_log_zone_size >= 8 * sizeof(block_nr))
|
if (sb.s_log_zone_size >= 8 * sizeof(block_nr))
|
||||||
fatal("log_zone_size too large");
|
fatal("log_zone_size too large");
|
||||||
if (sb.s_log_zone_size > 8) printf("warning: large log_zone_size (%d)\n",
|
if (sb.s_log_zone_size > 8) printf("warning: large log_zone_size (%d)\n",
|
||||||
sb.s_log_zone_size);
|
sb.s_log_zone_size);
|
||||||
n = (BLK_ILIST + N_ILIST + SCALE - 1) >> sb.s_log_zone_size;
|
sb.s_firstdatazone = (BLK_ILIST + N_ILIST + SCALE - 1) >> sb.s_log_zone_size;
|
||||||
if (sb.s_firstdatazone < n) fatal("first data zone too small");
|
if (sb.s_firstdatazone_old != 0) {
|
||||||
if (sb.s_firstdatazone != n) {
|
if (sb.s_firstdatazone_old >= sb.s_zones)
|
||||||
printf("warning: expected first data zone to be %d ", n);
|
fatal("first data zone too large");
|
||||||
printf("instead of %u\n", sb.s_firstdatazone);
|
if (sb.s_firstdatazone_old < sb.s_firstdatazone)
|
||||||
|
fatal("first data zone too small");
|
||||||
|
if (sb.s_firstdatazone_old != sb.s_firstdatazone) {
|
||||||
|
printf("warning: expected first data zone to be %u ",
|
||||||
|
sb.s_firstdatazone);
|
||||||
|
printf("instead of %u\n", sb.s_firstdatazone_old);
|
||||||
|
sb.s_firstdatazone = sb.s_firstdatazone_old;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
maxsize = MAX_FILE_POS;
|
maxsize = MAX_FILE_POS;
|
||||||
if (((maxsize - 1) >> sb.s_log_zone_size) / block_size >= MAX_ZONES)
|
if (((maxsize - 1) >> sb.s_log_zone_size) / block_size >= MAX_ZONES)
|
||||||
|
|
|
@ -270,12 +270,9 @@ char *argv[];
|
||||||
if (blocks == 0) pexit("Can't open prototype file");
|
if (blocks == 0) pexit("Can't open prototype file");
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
i = blocks / 2;
|
u32_t kb = div64u(mul64u(blocks, block_size), 1024);
|
||||||
if (blocks >= 20000) i = blocks / 3;
|
i = kb / 2;
|
||||||
if (blocks >= 40000) i = blocks / 4;
|
if (kb >= 100000) i = kb / 4;
|
||||||
if (blocks >= 60000) i = blocks / 5;
|
|
||||||
if (blocks >= 80000) i = blocks / 6;
|
|
||||||
if (blocks >= 100000) i = blocks / 7;
|
|
||||||
|
|
||||||
/* round up to fill inode block */
|
/* round up to fill inode block */
|
||||||
i += inodes_per_block - 1;
|
i += inodes_per_block - 1;
|
||||||
|
@ -462,15 +459,21 @@ ino_t inodes;
|
||||||
fprintf(stderr, "mkfs: too many block bitmap blocks.\n" BIGGERBLOCKS);
|
fprintf(stderr, "mkfs: too many block bitmap blocks.\n" BIGGERBLOCKS);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
inode_offset = sup->s_imap_blocks + sup->s_zmap_blocks + 2;
|
inode_offset = START_BLOCK + sup->s_imap_blocks + sup->s_zmap_blocks;
|
||||||
inodeblks = (inodes + inodes_per_block - 1) / inodes_per_block;
|
inodeblks = (inodes + inodes_per_block - 1) / inodes_per_block;
|
||||||
initblks = inode_offset + inodeblks;
|
initblks = inode_offset + inodeblks;
|
||||||
sup->s_firstdatazone = nb = (initblks + (1 << zone_shift) - 1) >> zone_shift;
|
sup->s_firstdatazone_old = nb =
|
||||||
|
(initblks + (1 << zone_shift) - 1) >> zone_shift;
|
||||||
if(nb >= zones) pexit("bit maps too large");
|
if(nb >= zones) pexit("bit maps too large");
|
||||||
if(nb != sup->s_firstdatazone) {
|
if(nb != sup->s_firstdatazone_old) {
|
||||||
fprintf(stderr, "mkfs: too much bitmap and inode data.\n" BIGGERBLOCKS);
|
/* The field is too small to store the value. Fortunately, the value
|
||||||
exit(1);
|
* can be computed from other fields. We set the on-disk field to zero
|
||||||
|
* to indicate that it must not be used. Eventually, we can always set
|
||||||
|
* the on-disk field to zero, and stop using it.
|
||||||
|
*/
|
||||||
|
sup->s_firstdatazone_old = 0;
|
||||||
}
|
}
|
||||||
|
sup->s_firstdatazone = nb;
|
||||||
zoff = sup->s_firstdatazone - 1;
|
zoff = sup->s_firstdatazone - 1;
|
||||||
sup->s_log_zone_size = zone_shift;
|
sup->s_log_zone_size = zone_shift;
|
||||||
if (fs_version == 1) {
|
if (fs_version == 1) {
|
||||||
|
@ -508,7 +511,7 @@ ino_t inodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear maps and inodes. */
|
/* Clear maps and inodes. */
|
||||||
for (i = 2; i < initblks; i++) put_block((block_t) i, zero);
|
for (i = START_BLOCK; i < initblks; i++) put_block((block_t) i, zero);
|
||||||
|
|
||||||
next_zone = sup->s_firstdatazone;
|
next_zone = sup->s_firstdatazone;
|
||||||
next_inode = 1;
|
next_inode = 1;
|
||||||
|
|
|
@ -385,7 +385,7 @@ int rw_flag; /* READING or WRITING */
|
||||||
/* Get the block where the inode resides. */
|
/* Get the block where the inode resides. */
|
||||||
sp = get_super(rip->i_dev); /* get pointer to super block */
|
sp = get_super(rip->i_dev); /* get pointer to super block */
|
||||||
rip->i_sp = sp; /* inode must contain super block pointer */
|
rip->i_sp = sp; /* inode must contain super block pointer */
|
||||||
offset = sp->s_imap_blocks + sp->s_zmap_blocks + 2;
|
offset = START_BLOCK + sp->s_imap_blocks + sp->s_zmap_blocks;
|
||||||
b = (block_t) (rip->i_num - 1)/sp->s_inodes_per_block + offset;
|
b = (block_t) (rip->i_num - 1)/sp->s_inodes_per_block + offset;
|
||||||
bp = get_block(rip->i_dev, b, NORMAL);
|
bp = get_block(rip->i_dev, b, NORMAL);
|
||||||
dip = bp->b_v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
|
dip = bp->b_v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
|
||||||
|
|
|
@ -183,6 +183,7 @@ register struct super_block *sp; /* pointer to a superblock */
|
||||||
int magic;
|
int magic;
|
||||||
int version, native, r;
|
int version, native, r;
|
||||||
static char *sbbuf;
|
static char *sbbuf;
|
||||||
|
block_t offset;
|
||||||
|
|
||||||
STATICINIT(sbbuf, _MIN_BLOCK_SIZE);
|
STATICINIT(sbbuf, _MIN_BLOCK_SIZE);
|
||||||
|
|
||||||
|
@ -219,7 +220,7 @@ register struct super_block *sp; /* pointer to a superblock */
|
||||||
sp->s_nzones = conv2(native, (int) sp->s_nzones);
|
sp->s_nzones = conv2(native, (int) sp->s_nzones);
|
||||||
sp->s_imap_blocks = conv2(native, (int) sp->s_imap_blocks);
|
sp->s_imap_blocks = conv2(native, (int) sp->s_imap_blocks);
|
||||||
sp->s_zmap_blocks = conv2(native, (int) sp->s_zmap_blocks);
|
sp->s_zmap_blocks = conv2(native, (int) sp->s_zmap_blocks);
|
||||||
sp->s_firstdatazone = conv2(native, (int) sp->s_firstdatazone);
|
sp->s_firstdatazone_old = conv2(native, (int) sp->s_firstdatazone_old);
|
||||||
sp->s_log_zone_size = conv2(native, (int) sp->s_log_zone_size);
|
sp->s_log_zone_size = conv2(native, (int) sp->s_log_zone_size);
|
||||||
sp->s_max_size = conv4(native, sp->s_max_size);
|
sp->s_max_size = conv4(native, sp->s_max_size);
|
||||||
sp->s_zones = conv4(native, sp->s_zones);
|
sp->s_zones = conv4(native, sp->s_zones);
|
||||||
|
@ -252,6 +253,21 @@ register struct super_block *sp; /* pointer to a superblock */
|
||||||
sp->s_nindirs = V2_INDIRECTS(sp->s_block_size);
|
sp->s_nindirs = V2_INDIRECTS(sp->s_block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For even larger disks, a similar problem occurs with s_firstdatazone.
|
||||||
|
* If the on-disk field contains zero, we assume that the value was too
|
||||||
|
* large to fit, and compute it on the fly.
|
||||||
|
*/
|
||||||
|
if (sp->s_firstdatazone_old == 0) {
|
||||||
|
offset = START_BLOCK + sp->s_imap_blocks + sp->s_zmap_blocks;
|
||||||
|
offset += (sp->s_ninodes + sp->s_inodes_per_block - 1) /
|
||||||
|
sp->s_inodes_per_block;
|
||||||
|
|
||||||
|
sp->s_firstdatazone = (offset + (1 << sp->s_log_zone_size) - 1) >>
|
||||||
|
sp->s_log_zone_size;
|
||||||
|
} else {
|
||||||
|
sp->s_firstdatazone = sp->s_firstdatazone_old;
|
||||||
|
}
|
||||||
|
|
||||||
if (sp->s_block_size < _MIN_BLOCK_SIZE)
|
if (sp->s_block_size < _MIN_BLOCK_SIZE)
|
||||||
return(EINVAL);
|
return(EINVAL);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ EXTERN struct super_block {
|
||||||
zone1_t s_nzones; /* total device size, including bit maps etc */
|
zone1_t s_nzones; /* total device size, including bit maps etc */
|
||||||
short s_imap_blocks; /* # of blocks used by inode bit map */
|
short s_imap_blocks; /* # of blocks used by inode bit map */
|
||||||
short s_zmap_blocks; /* # of blocks used by zone bit map */
|
short s_zmap_blocks; /* # of blocks used by zone bit map */
|
||||||
zone1_t s_firstdatazone; /* number of first data zone */
|
zone1_t s_firstdatazone_old; /* number of first data zone (small) */
|
||||||
short s_log_zone_size; /* log2 of blocks/zone */
|
short s_log_zone_size; /* log2 of blocks/zone */
|
||||||
short s_pad; /* try to avoid compiler-dependent padding */
|
short s_pad; /* try to avoid compiler-dependent padding */
|
||||||
off_t s_max_size; /* maximum file size on this device */
|
off_t s_max_size; /* maximum file size on this device */
|
||||||
|
@ -45,6 +45,7 @@ EXTERN struct super_block {
|
||||||
/*struct inode *s_isup;*/ /* inode for root dir of mounted file sys */
|
/*struct inode *s_isup;*/ /* inode for root dir of mounted file sys */
|
||||||
/*struct inode *s_imount;*/ /* inode mounted on */
|
/*struct inode *s_imount;*/ /* inode mounted on */
|
||||||
unsigned s_inodes_per_block; /* precalculated from magic number */
|
unsigned s_inodes_per_block; /* precalculated from magic number */
|
||||||
|
zone_t s_firstdatazone; /* number of first data zone (big) */
|
||||||
dev_t s_dev; /* whose super block is this? */
|
dev_t s_dev; /* whose super block is this? */
|
||||||
int s_rd_only; /* set to 1 iff file sys mounted read only */
|
int s_rd_only; /* set to 1 iff file sys mounted read only */
|
||||||
int s_native; /* set to 1 iff not byte swapped file system */
|
int s_native; /* set to 1 iff not byte swapped file system */
|
||||||
|
|
Loading…
Reference in a new issue