patch-2.1.85 linux/fs/sysv/inode.c
Next file: linux/fs/sysv/namei.c
Previous file: linux/fs/sysv/INTRO
Back to the patch index
Back to the overall index
- Lines: 286
- Date:
Mon Feb 2 13:03:14 1998
- Orig file:
v2.1.84/linux/fs/sysv/inode.c
- Orig date:
Fri Jan 30 11:28:09 1998
diff -u --recursive --new-file v2.1.84/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
@@ -34,6 +34,27 @@
#include <asm/uaccess.h>
+#if 0
+void sysv_print_inode(struct inode * inode)
+{
+ printk("ino %lu mode 0%6.6o lk %d uid %d gid %d"
+ " sz %lu blks %lu cnt %u\n",
+ inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,
+ inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count);
+ printk(" db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"
+ " 0x%lx 0x%lx>\n",
+ inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],
+ inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],
+ inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],
+ inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],
+ inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);
+ printk(" ib <0x%lx 0x%lx 0x%lx>\n",
+ inode->u.sysv_i.i_data[10],
+ inode->u.sysv_i.i_data[11],
+ inode->u.sysv_i.i_data[12]);
+}
+#endif
+
void sysv_put_inode(struct inode *inode)
{
if (inode->i_nlink)
@@ -65,58 +86,35 @@
* the time stamp is not < 01-01-1980.
*/
-static void detected_bs512 (struct super_block *sb)
+static void detected_bs (u_char type, struct super_block *sb)
{
- sb->sv_block_size = 512;
- sb->sv_block_size_1 = 512-1;
- sb->sv_block_size_bits = 9;
- sb->sv_block_size_ratio = 2;
- sb->sv_block_size_ratio_bits = 1;
- sb->sv_inodes_per_block = 512/64;
- sb->sv_inodes_per_block_1 = 512/64-1;
- sb->sv_inodes_per_block_bits = 9-6;
+ u_char n_bits = type+8;
+ int bsize = 1 << n_bits;
+ int bsize_4 = bsize >> 2;
+
+ sb->sv_block_size = bsize;
+ sb->sv_block_size_1 = bsize-1;
+ sb->sv_block_size_bits = n_bits;
+ sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
+ sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
+ sb->sv_inodes_per_block = bsize >> 6;
+ sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
+ sb->sv_inodes_per_block_bits = n_bits-6;
sb->sv_toobig_block = 10 +
- (sb->sv_ind_per_block = 512/4) +
- (sb->sv_ind_per_block_2 = (512/4)*(512/4)) +
- (sb->sv_ind_per_block_3 = (512/4)*(512/4)*(512/4));
- sb->sv_ind_per_block_1 = 512/4-1;
- sb->sv_ind_per_block_2_1 = (512/4)*(512/4)-1;
+ (sb->sv_ind_per_block = bsize_4) +
+ (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
+ (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
+ sb->sv_ind_per_block_1 = bsize_4-1;
+ sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
sb->sv_ind_per_block_2_bits = 2 *
- (sb->sv_ind_per_block_bits = 9-2);
- sb->sv_ind_per_block_block_size_1 = (512/4)*512-1;
- sb->sv_ind_per_block_block_size_bits = (9-2)+9;
- sb->sv_ind_per_block_2_block_size_1 = (512/4)*(512/4)*512-1;
- sb->sv_ind_per_block_2_block_size_bits = (9-2)+(9-2)+9;
- sb->sv_ind0_size = 10 * 512;
- sb->sv_ind1_size = (10 + (512/4))* 512;
- sb->sv_ind2_size = (10 + (512/4) + (512/4)*(512/4)) * 512;
-}
-
-static void detected_bs1024 (struct super_block *sb)
-{
- sb->sv_block_size = 1024;
- sb->sv_block_size_1 = 1024-1;
- sb->sv_block_size_bits = 10;
- sb->sv_block_size_ratio = 1;
- sb->sv_block_size_ratio_bits = 0;
- sb->sv_inodes_per_block = 1024/64;
- sb->sv_inodes_per_block_1 = 1024/64-1;
- sb->sv_inodes_per_block_bits = 10-6;
- sb->sv_toobig_block = 10 +
- (sb->sv_ind_per_block = 1024/4) +
- (sb->sv_ind_per_block_2 = (1024/4)*(1024/4)) +
- (sb->sv_ind_per_block_3 = (1024/4)*(1024/4)*(1024/4));
- sb->sv_ind_per_block_1 = 1024/4-1;
- sb->sv_ind_per_block_2_1 = (1024/4)*(1024/4)-1;
- sb->sv_ind_per_block_2_bits = 2 *
- (sb->sv_ind_per_block_bits = 10-2);
- sb->sv_ind_per_block_block_size_1 = (1024/4)*1024-1;
- sb->sv_ind_per_block_block_size_bits = (10-2)+10;
- sb->sv_ind_per_block_2_block_size_1 = (1024/4)*(1024/4)*1024-1;
- sb->sv_ind_per_block_2_block_size_bits = (10-2)+(10-2)+10;
- sb->sv_ind0_size = 10 * 1024;
- sb->sv_ind1_size = (10 + (1024/4))* 1024;
- sb->sv_ind2_size = (10 + (1024/4) + (1024/4)*(1024/4)) * 1024;
+ (sb->sv_ind_per_block_bits = n_bits-2);
+ sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
+ sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
+ sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
+ sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
+ sb->sv_ind0_size = 10 * bsize;
+ sb->sv_ind1_size = (10 + bsize_4)* bsize;
+ sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
}
static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
@@ -126,11 +124,9 @@
sbd = (struct xenix_super_block *) bh->b_data;
if (sbd->s_magic != 0x2b5544)
return NULL;
- switch (sbd->s_type) {
- case 1: detected_bs512(sb); break;
- case 2: detected_bs1024(sb); break;
- default: return NULL;
- }
+ if (sbd->s_type > 2 || sbd->s_type < 1)
+ return NULL;
+ detected_bs(sbd->s_type, sb);
sb->sv_type = FSTYPE_XENIX;
return "Xenix";
}
@@ -139,8 +135,8 @@
struct xenix_super_block * sbd1;
struct xenix_super_block * sbd2;
- if (sb->sv_block_size == BLOCK_SIZE)
- /* block size = 1024, so bh1 = bh2 */
+ if (sb->sv_block_size >= BLOCK_SIZE)
+ /* block size >= 1024, so bh1 = bh2 */
sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
else {
/* block size = 512, so bh1 != bh2 */
@@ -184,11 +180,9 @@
return NULL;
if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
return NULL;
- switch (sbd->s_type) {
- case 1: detected_bs512(sb); break;
- case 2: detected_bs1024(sb); break;
- default: return NULL;
- }
+ if (sbd->s_type > 3 || sbd->s_type < 1)
+ return NULL;
+ detected_bs(sbd->s_type, sb);
sb->sv_type = FSTYPE_SYSV4;
return "SystemV";
}
@@ -196,7 +190,7 @@
{
struct sysv4_super_block * sbd;
- if (sb->sv_block_size == BLOCK_SIZE)
+ if (sb->sv_block_size >= BLOCK_SIZE)
sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
else {
sbd = (struct sysv4_super_block *) bh->b_data;
@@ -241,11 +235,9 @@
return NULL;
if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
return NULL;
- switch (sbd->s_type) {
- case 1: detected_bs512(sb); break;
- case 2: detected_bs1024(sb); break;
- default: return NULL;
- }
+ if (sbd->s_type > 3 || sbd->s_type < 1)
+ return NULL;
+ detected_bs(sbd->s_type, sb);
sb->sv_type = FSTYPE_SYSV2;
return "SystemV Release 2";
}
@@ -253,7 +245,7 @@
{
struct sysv2_super_block * sbd;
- if (sb->sv_block_size == BLOCK_SIZE)
+ if (sb->sv_block_size >= BLOCK_SIZE)
sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
else {
sbd = (struct sysv2_super_block *) bh->b_data;
@@ -297,7 +289,7 @@
if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
|| (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
return NULL;
- detected_bs512(sb);
+ detected_bs(1, sb);
sb->sv_type = FSTYPE_COH;
return "Coherent";
}
@@ -342,7 +334,8 @@
const char *found;
kdev_t dev = sb->s_dev;
struct inode *root_inode;
-
+ unsigned long blocknr;
+
if (1024 != sizeof (struct xenix_super_block))
panic("Xenix FS: bad super-block size");
if ((512 != sizeof (struct sysv4_super_block))
@@ -376,22 +369,29 @@
}
/* Try to recognize SystemV superblock */
/* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
+ /* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
+ /* Maybe we should also check the device geometry ? */
{ static int offsets[] = { 9, 15, 18, };
int i;
for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
/* Try to recognize SystemV superblock */
if ((found = detect_sysv4(sb,bh)) != NULL) {
- sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
+ if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
+ goto bad_shift;
+ sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
goto ok;
}
if ((found = detect_sysv2(sb,bh)) != NULL) {
- sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
+ if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
+ goto bad_shift;
+ sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
goto ok;
}
brelse(bh);
}
}
+ bad_shift:
sb->s_dev = 0;
unlock_super(sb);
if (!silent)
@@ -402,7 +402,14 @@
return NULL;
ok:
- if (sb->sv_block_size == BLOCK_SIZE) {
+ if (sb->sv_block_size >= BLOCK_SIZE) {
+ if (sb->sv_block_size != BLOCK_SIZE) {
+ brelse(bh);
+ set_blocksize(dev, sb->sv_block_size);
+ blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
+ if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
+ goto bad_superblock;
+ }
switch (sb->sv_type) {
case FSTYPE_XENIX:
if (!detected_xenix(sb,bh,bh))
@@ -416,19 +423,21 @@
if (!detected_sysv2(sb,bh))
goto bad_superblock;
break;
- default:
- bad_superblock:
- brelse(bh);
- sb->s_dev = 0;
- unlock_super(sb);
- printk("SysV FS: cannot read superblock in 1024 byte mode\n");
- goto failed;
+ default: goto bad_superblock;
+ goto superblock_ok;
+ bad_superblock:
+ brelse(bh);
+ sb->s_dev = 0;
+ unlock_super(sb);
+ printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
+ goto failed;
+ superblock_ok:
}
} else {
- /* Switch to another block size. Unfortunately, we have to
- release the 1 KB block bh and read it in two parts again. */
+ /* Switch to 512 block size. Unfortunately, we have to
+ release the block bh and read it again. */
struct buffer_head *bh1, *bh2;
- unsigned long blocknr = bh->b_blocknr << sb->sv_block_size_ratio_bits;
+ unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
brelse(bh);
set_blocksize(dev,sb->sv_block_size);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov