예제 #1
0
static int v7_fill_super(struct super_block *sb, void *data, int silent)
{
	struct sysv_sb_info *sbi;
	struct buffer_head *bh;

	if (440 != sizeof (struct v7_super_block))
		panic("V7 FS: bad super-block size");
	if (64 != sizeof (struct sysv_inode))
		panic("sysv fs: bad i-node size");

	sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;

	sbi->s_sb = sb;
	sbi->s_block_base = 0;
	sbi->s_type = FSTYPE_V7;
	sb->s_fs_info = sbi;
	
	sb_set_blocksize(sb, 512);

	if ((bh = sb_bread(sb, 1)) == NULL) {
		if (!silent)
			printk("VFS: unable to read V7 FS superblock on "
			       "device %s.\n", sb->s_id);
		goto failed;
	}

	/* Try PDP-11 UNIX */
	sbi->s_bytesex = BYTESEX_PDP;
	if (v7_sanity_check(sb, bh))
		goto detected;

	/* Try PC/IX, v7/x86 */
	sbi->s_bytesex = BYTESEX_LE;
	if (v7_sanity_check(sb, bh))
		goto detected;

	goto failed;

detected:
	sbi->s_bh1 = bh;
	sbi->s_bh2 = bh;
	if (complete_read_super(sb, silent, 1))
		return 0;

failed:
	printk(KERN_ERR "VFS: could not find a valid V7 on %s.\n",
		sb->s_id);
	brelse(bh);
	kfree(sbi);
	return -EINVAL;
}
예제 #2
0
static int v7_fill_super(struct super_block *sb, void *data, int silent)
{
	struct sysv_sb_info *sbi;
	struct buffer_head *bh, *bh2 = NULL;
	struct v7_super_block *v7sb;
	struct sysv_inode *v7i;

	if (440 != sizeof (struct v7_super_block))
		panic("V7 FS: bad super-block size");
	if (64 != sizeof (struct sysv_inode))
		panic("sysv fs: bad i-node size");

	sbi = kmalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	memset(sbi, 0, sizeof(struct sysv_sb_info));

	sbi->s_sb = sb;
	sbi->s_block_base = 0;
	sbi->s_type = FSTYPE_V7;
	sbi->s_bytesex = BYTESEX_PDP;
	sb->s_fs_info = sbi;
	
	sb_set_blocksize(sb, 512);

	if ((bh = sb_bread(sb, 1)) == NULL) {
		if (!silent)
			printk("VFS: unable to read V7 FS superblock on "
			       "device %s.\n", sb->s_id);
		goto failed;
	}

	/* plausibility check on superblock */
	v7sb = (struct v7_super_block *) bh->b_data;
	if (fs16_to_cpu(sbi, v7sb->s_nfree) > V7_NICFREE ||
	    fs16_to_cpu(sbi, v7sb->s_ninode) > V7_NICINOD ||
	    fs32_to_cpu(sbi, v7sb->s_time) == 0)
		goto failed;

	/* plausibility check on root inode: it is a directory,
	   with a nonzero size that is a multiple of 16 */
	if ((bh2 = sb_bread(sb, 2)) == NULL)
		goto failed;
	v7i = (struct sysv_inode *)(bh2->b_data + 64);
	if ((fs16_to_cpu(sbi, v7i->i_mode) & ~0777) != S_IFDIR ||
	    (fs32_to_cpu(sbi, v7i->i_size) == 0) ||
	    (fs32_to_cpu(sbi, v7i->i_size) & 017) != 0)
		goto failed;
	brelse(bh2);
	bh2 = NULL;

	sbi->s_bh1 = bh;
	sbi->s_bh2 = bh;
	if (complete_read_super(sb, silent, 1))
		return 0;

failed:
	brelse(bh2);
	brelse(bh);
	kfree(sbi);
	return -EINVAL;
}
예제 #3
0
static int sysv_fill_super(struct super_block *sb, void *data, int silent)
{
	struct buffer_head *bh1, *bh = NULL;
	struct sysv_sb_info *sbi;
	unsigned long blocknr;
	int size = 0, i;
	
	if (1024 != sizeof (struct xenix_super_block))
		panic("Xenix FS: bad superblock size");
	if (512 != sizeof (struct sysv4_super_block))
		panic("SystemV FS: bad superblock size");
	if (512 != sizeof (struct sysv2_super_block))
		panic("SystemV FS: bad superblock size");
	if (500 != sizeof (struct coh_super_block))
		panic("Coherent FS: bad superblock size");
	if (64 != sizeof (struct sysv_inode))
		panic("sysv fs: bad inode size");

	sbi = kmalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	memset(sbi, 0, sizeof(struct sysv_sb_info));

	sbi->s_sb = sb;
	sbi->s_block_base = 0;
	sb->s_fs_info = sbi;
	
	sb_set_blocksize(sb, BLOCK_SIZE);

	for (i = 0; i < sizeof(flavours)/sizeof(flavours[0]) && !size; i++) {
		brelse(bh);
		bh = sb_bread(sb, flavours[i].block);
		if (!bh)
			continue;
		size = flavours[i].test(SYSV_SB(sb), bh);
	}

	if (!size)
		goto Eunknown;

	switch (size) {
		case 1:
			blocknr = bh->b_blocknr << 1;
			brelse(bh);
			sb_set_blocksize(sb, 512);
			bh1 = sb_bread(sb, blocknr);
			bh = sb_bread(sb, blocknr + 1);
			break;
		case 2:
			bh1 = bh;
			break;
		case 3:
			blocknr = bh->b_blocknr >> 1;
			brelse(bh);
			sb_set_blocksize(sb, 2048);
			bh1 = bh = sb_bread(sb, blocknr);
			break;
		default:
			goto Ebadsize;
	}

	if (bh && bh1) {
		sbi->s_bh1 = bh1;
		sbi->s_bh2 = bh;
		if (complete_read_super(sb, silent, size))
			return 0;
	}

	brelse(bh1);
	brelse(bh);
	sb_set_blocksize(sb, BLOCK_SIZE);
	printk("oldfs: cannot read superblock\n");
failed:
	kfree(sbi);
	return -EINVAL;

Eunknown:
	brelse(bh);
	if (!silent)
		printk("VFS: unable to find oldfs superblock on device %s\n",
			sb->s_id);
	goto failed;
Ebadsize:
	brelse(bh);
	if (!silent)
		printk("VFS: oldfs: unsupported block size (%dKb)\n",
			1<<(size-2));
	goto failed;
}