Esempio n. 1
0
static int affs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct affs_sb_info	*sbi;
	struct buffer_head	*root_bh = NULL;
	struct buffer_head	*boot_bh;
	struct inode		*root_inode = NULL;
	s32			 root_block;
	int			 size, blocksize;
	u32			 chksum;
	int			 num_bm;
	int			 i, j;
	s32			 key;
	uid_t			 uid;
	gid_t			 gid;
	int			 reserved;
	unsigned long		 mount_flags;

	pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");

	sb->s_magic             = AFFS_SUPER_MAGIC;
	sb->s_op                = &affs_sops;

	sbi = kmalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	sb->s_fs_info = sbi;
	memset(sbi, 0, sizeof(*sbi));
	init_MUTEX(&sbi->s_bmlock);

	if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
				&blocksize,&sbi->s_prefix,
				sbi->s_volume, &mount_flags)) {
		printk(KERN_ERR "AFFS: Error parsing options\n");
		return -EINVAL;
	}
	/* N.B. after this point s_prefix must be released */

	sbi->s_flags   = mount_flags;
	sbi->s_mode    = i;
	sbi->s_uid     = uid;
	sbi->s_gid     = gid;
	sbi->s_reserved= reserved;

	/* Get the size of the device in 512-byte blocks.
	 * If we later see that the partition uses bigger
	 * blocks, we will have to change it.
	 */

	size = sb->s_bdev->bd_inode->i_size >> 9;
	pr_debug("AFFS: initial blocksize=%d, #blocks=%d\n", 512, size);

	affs_set_blocksize(sb, PAGE_SIZE);
	/* Try to find root block. Its location depends on the block size. */

	i = 512;
	j = 4096;
	if (blocksize > 0) {
		i = j = blocksize;
		size = size / (blocksize / 512);
	}
	for (blocksize = i, key = 0; blocksize <= j; blocksize <<= 1, size >>= 1) {
		sbi->s_root_block = root_block;
		if (root_block < 0)
			sbi->s_root_block = (reserved + size - 1) / 2;
		pr_debug("AFFS: setting blocksize to %d\n", blocksize);
		affs_set_blocksize(sb, blocksize);
		sbi->s_partition_size = size;

		/* The root block location that was calculated above is not
		 * correct if the partition size is an odd number of 512-
		 * byte blocks, which will be rounded down to a number of
		 * 1024-byte blocks, and if there were an even number of
		 * reserved blocks. Ideally, all partition checkers should
		 * report the real number of blocks of the real blocksize,
		 * but since this just cannot be done, we have to try to
		 * find the root block anyways. In the above case, it is one
		 * block behind the calculated one. So we check this one, too.
		 */
		for (num_bm = 0; num_bm < 2; num_bm++) {
			pr_debug("AFFS: Dev %s, trying root=%u, bs=%d, "
				"size=%d, reserved=%d\n",
				sb->s_id,
				sbi->s_root_block + num_bm,
				blocksize, size, reserved);
			root_bh = affs_bread(sb, sbi->s_root_block + num_bm);
			if (!root_bh)
				continue;
			if (!affs_checksum_block(sb, root_bh) &&
			    be32_to_cpu(AFFS_ROOT_HEAD(root_bh)->ptype) == T_SHORT &&
			    be32_to_cpu(AFFS_ROOT_TAIL(sb, root_bh)->stype) == ST_ROOT) {
				sbi->s_hashsize    = blocksize / 4 - 56;
				sbi->s_root_block += num_bm;
				key                        = 1;
				goto got_root;
			}
			affs_brelse(root_bh);
			root_bh = NULL;
		}
	}
	if (!silent)
		printk(KERN_ERR "AFFS: No valid root block on device %s\n",
			sb->s_id);
	goto out_error;

	/* N.B. after this point bh must be released */
got_root:
	root_block = sbi->s_root_block;

	/* Find out which kind of FS we have */
	boot_bh = sb_bread(sb, 0);
	if (!boot_bh) {
		printk(KERN_ERR "AFFS: Cannot read boot block\n");
		goto out_error;
	}
	chksum = be32_to_cpu(*(u32 *)boot_bh->b_data);
	brelse(boot_bh);

	/* Dircache filesystems are compatible with non-dircache ones
	 * when reading. As long as they aren't supported, writing is
	 * not recommended.
	 */
	if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS
	     || chksum == MUFS_DCOFS) && !(sb->s_flags & MS_RDONLY)) {
		printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",
			sb->s_id);
		sb->s_flags |= MS_RDONLY;
		sbi->s_flags |= SF_READONLY;
	}
	switch (chksum) {
		case MUFS_FS:
		case MUFS_INTLFFS:
		case MUFS_DCFFS:
			sbi->s_flags |= SF_MUFS;
			/* fall thru */
		case FS_INTLFFS:
		case FS_DCFFS:
			sbi->s_flags |= SF_INTL;
			break;
		case MUFS_FFS:
			sbi->s_flags |= SF_MUFS;
			break;
		case FS_FFS:
			break;
		case MUFS_OFS:
			sbi->s_flags |= SF_MUFS;
			/* fall thru */
		case FS_OFS:
			sbi->s_flags |= SF_OFS;
			sb->s_flags |= MS_NOEXEC;
			break;
		case MUFS_DCOFS:
		case MUFS_INTLOFS:
			sbi->s_flags |= SF_MUFS;
		case FS_DCOFS:
		case FS_INTLOFS:
			sbi->s_flags |= SF_INTL | SF_OFS;
			sb->s_flags |= MS_NOEXEC;
			break;
		default:
			printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n",
				sb->s_id, chksum);
			goto out_error;
	}

	if (mount_flags & SF_VERBOSE) {
		chksum = cpu_to_be32(chksum);
		printk(KERN_NOTICE "AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",
			AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0],
			AFFS_ROOT_TAIL(sb, root_bh)->disk_name + 1,
			(char *)&chksum,((char *)&chksum)[3] + '0',blocksize);
	}

	sb->s_flags |= MS_NODEV | MS_NOSUID;

	sbi->s_data_blksize = sb->s_blocksize;
	if (sbi->s_flags & SF_OFS)
		sbi->s_data_blksize -= 24;

	/* Keep super block in cache */
	sbi->s_root_bh = root_bh;
	/* N.B. after this point s_root_bh must be released */

	if (affs_init_bitmap(sb))
		goto out_error;

	/* set up enough so that it can read an inode */

	root_inode = iget(sb, root_block);
	sb->s_root = d_alloc_root(root_inode);
	if (!sb->s_root) {
		printk(KERN_ERR "AFFS: Get root inode failed\n");
		goto out_error;
	}
	sb->s_root->d_op = &affs_dentry_operations;

	pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
	return 0;

	/*
	 * Begin the cascaded cleanup ...
	 */
out_error:
	if (root_inode)
		iput(root_inode);
	if (sbi->s_bitmap)
		kfree(sbi->s_bitmap);
	affs_brelse(root_bh);
	if (sbi->s_prefix)
		kfree(sbi->s_prefix);
	kfree(sbi);
	sb->s_fs_info = NULL;
	return -EINVAL;
}
Esempio n. 2
0
void
affs_read_inode(struct inode *inode)
{
	struct buffer_head	*bh;
	struct file_front	*file_front;
	struct file_end		*file_end;
	s32			 block;
	unsigned long		 prot;
	s32			 ptype, stype;
	unsigned short		 id;

	pr_debug("AFFS: read_inode(%lu)\n",inode->i_ino);

	block = inode->i_ino;
	if (!(bh = affs_bread(inode->i_dev,block,AFFS_I2BSIZE(inode)))) {
		affs_error(inode->i_sb,"read_inode","Cannot read block %d",block);
		return;
	}
	if (affs_checksum_block(AFFS_I2BSIZE(inode),bh->b_data,&ptype,&stype) || ptype != T_SHORT) {
		affs_error(inode->i_sb,"read_inode",
			   "Checksum or type (ptype=%d) error on inode %d",ptype,block);
		affs_brelse(bh);
		return;
	}

	file_front = (struct file_front *)bh->b_data;
	file_end   = GET_END_PTR(struct file_end, bh->b_data,AFFS_I2BSIZE(inode));
	prot       = (be32_to_cpu(file_end->protect) & ~0x10) ^ FIBF_OWNER;

	inode->u.affs_i.i_protect      = prot;
	inode->u.affs_i.i_parent       = be32_to_cpu(file_end->parent);
	inode->u.affs_i.i_original     = 0;
	inode->u.affs_i.i_zone         = 0;
	inode->u.affs_i.i_hlink        = 0;
	inode->u.affs_i.i_pa_cnt       = 0;
	inode->u.affs_i.i_pa_next      = 0;
	inode->u.affs_i.i_pa_last      = 0;
	inode->u.affs_i.i_ec           = NULL;
	inode->u.affs_i.i_lastblock    = -1;
	inode->i_nlink                 = 1;
	inode->i_mode                  = 0;

	if (inode->i_sb->u.affs_sb.s_flags & SF_SETMODE)
		inode->i_mode = inode->i_sb->u.affs_sb.s_mode;
	else
		inode->i_mode = prot_to_mode(prot);

	if (inode->i_sb->u.affs_sb.s_flags & SF_SETUID)
		inode->i_uid = inode->i_sb->u.affs_sb.s_uid;
	id = be16_to_cpu(file_end->owner_uid);
	if (id == 0 || inode->i_sb->u.affs_sb.s_flags & SF_SETUID)
		inode->i_uid = inode->i_sb->u.affs_sb.s_uid;
	else if (id == 0xFFFF && inode->i_sb->u.affs_sb.s_flags & SF_MUFS)
		inode->i_uid = 0;
	else 
		inode->i_uid = id;

	id = be16_to_cpu(file_end->owner_gid);
	if (id == 0 || inode->i_sb->u.affs_sb.s_flags & SF_SETGID)
		inode->i_gid = inode->i_sb->u.affs_sb.s_gid;
	else if (id == 0xFFFF && inode->i_sb->u.affs_sb.s_flags & SF_MUFS)
		inode->i_gid = 0;
	else
		inode->i_gid = id;

	switch (be32_to_cpu(file_end->secondary_type)) {
		case ST_ROOT:
			inode->i_uid   = inode->i_sb->u.affs_sb.s_uid;
			inode->i_gid   = inode->i_sb->u.affs_sb.s_gid;
		case ST_USERDIR:
			if (be32_to_cpu(file_end->secondary_type) == ST_USERDIR ||
			    inode->i_sb->u.affs_sb.s_flags & SF_SETMODE) {
				if (inode->i_mode & S_IRUSR)
					inode->i_mode |= S_IXUSR;
				if (inode->i_mode & S_IRGRP)
					inode->i_mode |= S_IXGRP;
				if (inode->i_mode & S_IROTH)
					inode->i_mode |= S_IXOTH;
				inode->i_mode |= S_IFDIR;
			} else
				inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
			inode->i_size  = 0;
			break;
		case ST_LINKDIR:
			affs_error(inode->i_sb,"read_inode","inode is LINKDIR");
			affs_brelse(bh);
			return;
		case ST_LINKFILE:
			affs_error(inode->i_sb,"read_inode","inode is LINKFILE");
			affs_brelse(bh);
			return;
		case ST_FILE:
			inode->i_mode |= S_IFREG;
			inode->i_size  = be32_to_cpu(file_end->byte_size);
			if (inode->i_sb->u.affs_sb.s_flags & SF_OFS)
				block = AFFS_I2BSIZE(inode) - 24;
			else
				block = AFFS_I2BSIZE(inode);
			inode->u.affs_i.i_lastblock = ((inode->i_size + block - 1) / block) - 1;
			break;
		case ST_SOFTLINK:
			inode->i_mode |= S_IFLNK;
			inode->i_size  = 0;
			break;
	}

	inode->i_mtime = inode->i_atime = inode->i_ctime
		       = (be32_to_cpu(file_end->created.ds_Days) * (24 * 60 * 60) +
		         be32_to_cpu(file_end->created.ds_Minute) * 60 +
			 be32_to_cpu(file_end->created.ds_Tick) / 50 +
			 ((8 * 365 + 2) * 24 * 60 * 60)) +
			 sys_tz.tz_minuteswest * 60;
	affs_brelse(bh);

	inode->i_op = NULL;
	if (S_ISREG(inode->i_mode)) {
		if (inode->i_sb->u.affs_sb.s_flags & SF_OFS) {
			inode->i_op = &affs_file_inode_operations_ofs;
		} else {
			inode->i_op = &affs_file_inode_operations;
		}
	} else if (S_ISDIR(inode->i_mode)) {
		/* Maybe it should be controlled by mount parameter? */
		inode->i_mode |= S_ISVTX;
		inode->i_op = &affs_dir_inode_operations;
	}
	else if (S_ISLNK(inode->i_mode))
		inode->i_op = &affs_symlink_inode_operations;
}
Esempio n. 3
0
struct inode *affs_iget(struct super_block *sb, unsigned long ino)
{
	struct affs_sb_info	*sbi = AFFS_SB(sb);
	struct buffer_head	*bh;
	struct affs_head	*head;
	struct affs_tail	*tail;
	struct inode		*inode;
	u32			 block;
	u32			 size;
	u32			 prot;
	u16			 id;

	inode = iget_locked(sb, ino);
	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
		return inode;

	pr_debug("AFFS: affs_iget(%lu)\n", inode->i_ino);

	block = inode->i_ino;
	bh = affs_bread(sb, block);
	if (!bh) {
		affs_warning(sb, "read_inode", "Cannot read block %d", block);
		goto bad_inode;
	}
	if (affs_checksum_block(sb, bh) || be32_to_cpu(AFFS_HEAD(bh)->ptype) != T_SHORT) {
		affs_warning(sb,"read_inode",
			   "Checksum or type (ptype=%d) error on inode %d",
			   AFFS_HEAD(bh)->ptype, block);
		goto bad_inode;
	}

	head = AFFS_HEAD(bh);
	tail = AFFS_TAIL(sb, bh);
	prot = be32_to_cpu(tail->protect);

	inode->i_size = 0;
	set_nlink(inode, 1);
	inode->i_mode = 0;
	AFFS_I(inode)->i_extcnt = 1;
	AFFS_I(inode)->i_ext_last = ~1;
	AFFS_I(inode)->i_protect = prot;
	atomic_set(&AFFS_I(inode)->i_opencnt, 0);
	AFFS_I(inode)->i_blkcnt = 0;
	AFFS_I(inode)->i_lc = NULL;
	AFFS_I(inode)->i_lc_size = 0;
	AFFS_I(inode)->i_lc_shift = 0;
	AFFS_I(inode)->i_lc_mask = 0;
	AFFS_I(inode)->i_ac = NULL;
	AFFS_I(inode)->i_ext_bh = NULL;
	AFFS_I(inode)->mmu_private = 0;
	AFFS_I(inode)->i_lastalloc = 0;
	AFFS_I(inode)->i_pa_cnt = 0;

	if (sbi->s_flags & SF_SETMODE)
		inode->i_mode = sbi->s_mode;
	else
		inode->i_mode = prot_to_mode(prot);

	id = be16_to_cpu(tail->uid);
	if (id == 0 || sbi->s_flags & SF_SETUID)
		inode->i_uid = sbi->s_uid;
	else if (id == 0xFFFF && sbi->s_flags & SF_MUFS)
		inode->i_uid = 0;
	else
		inode->i_uid = id;

	id = be16_to_cpu(tail->gid);
	if (id == 0 || sbi->s_flags & SF_SETGID)
		inode->i_gid = sbi->s_gid;
	else if (id == 0xFFFF && sbi->s_flags & SF_MUFS)
		inode->i_gid = 0;
	else
		inode->i_gid = id;

	switch (be32_to_cpu(tail->stype)) {
	case ST_ROOT:
		inode->i_uid = sbi->s_uid;
		inode->i_gid = sbi->s_gid;
		/*              */
	case ST_USERDIR:
		if (be32_to_cpu(tail->stype) == ST_USERDIR ||
		    sbi->s_flags & SF_SETMODE) {
			if (inode->i_mode & S_IRUSR)
				inode->i_mode |= S_IXUSR;
			if (inode->i_mode & S_IRGRP)
				inode->i_mode |= S_IXGRP;
			if (inode->i_mode & S_IROTH)
				inode->i_mode |= S_IXOTH;
			inode->i_mode |= S_IFDIR;
		} else
			inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
		/*                                                   */
		//                         
		inode->i_op = &affs_dir_inode_operations;
		inode->i_fop = &affs_dir_operations;
		break;
	case ST_LINKDIR:
#if 0
		affs_warning(sb, "read_inode", "inode is LINKDIR");
		goto bad_inode;
#else
		inode->i_mode |= S_IFDIR;
		/*                                                    */
		break;
#endif
	case ST_LINKFILE:
		affs_warning(sb, "read_inode", "inode is LINKFILE");
		goto bad_inode;
	case ST_FILE:
		size = be32_to_cpu(tail->size);
		inode->i_mode |= S_IFREG;
		AFFS_I(inode)->mmu_private = inode->i_size = size;
		if (inode->i_size) {
			AFFS_I(inode)->i_blkcnt = (size - 1) /
					       sbi->s_data_blksize + 1;
			AFFS_I(inode)->i_extcnt = (AFFS_I(inode)->i_blkcnt - 1) /
					       sbi->s_hashsize + 1;
		}
		if (tail->link_chain)
			set_nlink(inode, 2);
		inode->i_mapping->a_ops = (sbi->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops;
		inode->i_op = &affs_file_inode_operations;
		inode->i_fop = &affs_file_operations;
		break;
	case ST_SOFTLINK:
		inode->i_mode |= S_IFLNK;
		inode->i_op = &affs_symlink_inode_operations;
		inode->i_data.a_ops = &affs_symlink_aops;
		break;
	}

	inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec
		       = (be32_to_cpu(tail->change.days) * (24 * 60 * 60) +
		         be32_to_cpu(tail->change.mins) * 60 +
			 be32_to_cpu(tail->change.ticks) / 50 +
			 ((8 * 365 + 2) * 24 * 60 * 60)) +
			 sys_tz.tz_minuteswest * 60;
	inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
	affs_brelse(bh);
	unlock_new_inode(inode);
	return inode;

bad_inode:
	affs_brelse(bh);
	iget_failed(inode);
	return ERR_PTR(-EIO);
}
Esempio n. 4
0
struct super_block *
affs_read_super(struct super_block *s,void *data, int silent)
{
	struct buffer_head	*bh = NULL;
	struct buffer_head	*bb;
	kdev_t			 dev = s->s_dev;
	int			 root_block;
	int			 size;
	__u32			 chksum;
	__u32			*bm;
	int			 ptype, stype;
	int			 mapidx;
	int			 num_bm;
	int			 i, j;
	int			 key;
	int			 blocksize;
	uid_t			 uid;
	gid_t			 gid;
	int			 reserved;
	int			 az_no;
	unsigned long		 mount_flags;
	unsigned long		 offset;

	pr_debug("affs_read_super(%s)\n",data ? (const char *)data : "no options");

	MOD_INC_USE_COUNT;

	if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
	    &blocksize,&s->u.affs_sb.s_prefix,s->u.affs_sb.s_volume,&mount_flags)) {
		s->s_dev = 0;
		printk("AFFS: error parsing options.\n");
		MOD_DEC_USE_COUNT;
		return NULL;
	}
	lock_super(s);

	/* Get the size of the device in 512-byte blocks.
	 * If we later see that the partition uses bigger
	 * blocks, we will have to change it.
	 */

	size = blksize_size[MAJOR(dev)][MINOR(dev)];
	size = (size ? size : BLOCK_SIZE) / 512 * blk_size[MAJOR(dev)][MINOR(dev)];

	s->u.affs_sb.s_bitmap  = NULL;
	s->u.affs_sb.s_root_bh = NULL;
	s->u.affs_sb.s_flags   = mount_flags;
	s->u.affs_sb.s_mode    = i;
	s->u.affs_sb.s_uid     = uid;
	s->u.affs_sb.s_gid     = gid;

	if (size == 0) {
		s->s_dev = 0;
		unlock_super(s);
		printk("affs_read_super: could not determine device size\n");
		goto out;
	}
	s->u.affs_sb.s_partition_size = size;
	s->u.affs_sb.s_reserved       = reserved;

	/* Try to find root block. Its location may depend on the block size. */

	s->u.affs_sb.s_hashsize = 0;
	if (blocksize > 0) {
		chksum = blocksize;
		num_bm = blocksize;
	} else {
		chksum = 512;
		num_bm = 4096;
	}
	for (blocksize = chksum; blocksize <= num_bm; blocksize <<= 1, size >>= 1) {
		if (root_block < 0)
			s->u.affs_sb.s_root_block = (reserved + size - 1) / 2;
		else
			s->u.affs_sb.s_root_block = root_block;
		pr_debug("Trying bs=%d bytes, root at %d, size=%d blocks (%d reserved)\n",
			 blocksize,s->u.affs_sb.s_root_block,size,reserved);
		set_blocksize(dev,blocksize);
		bh = affs_bread(dev,s->u.affs_sb.s_root_block,blocksize);
		if (!bh) {
			printk("AFFS: unable to read root block\n");
			goto out;
		}
		if (!affs_checksum_block(blocksize,bh->b_data,&ptype,&stype) &&
		    ptype == T_SHORT && stype == ST_ROOT) {
			s->s_blocksize          = blocksize;
			s->u.affs_sb.s_hashsize = blocksize / 4 - 56;
			break;
		}
		affs_brelse(bh);
		bh = NULL;
	}
	if (!s->u.affs_sb.s_hashsize) {
		affs_brelse(bh);
		if (!silent)
			printk("AFFS: Can't find a valid root block on device %s\n",kdevname(dev));
		goto out;
	}
	root_block = s->u.affs_sb.s_root_block;

	s->u.affs_sb.s_partition_size   = size;
	s->s_blocksize_bits             = blocksize == 512 ? 9 :
					  blocksize == 1024 ? 10 :
					  blocksize == 2048 ? 11 : 12;

	/* Find out which kind of FS we have */
	bb = affs_bread(dev,0,s->s_blocksize);
	if (bb) {
		chksum = htonl(*(__u32 *)bb->b_data);
		switch (chksum) {
			case MUFS_FS:
			case MUFS_INTLFFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				/* fall thru */
			case FS_INTLFFS:
				s->u.affs_sb.s_flags |= SF_INTL;
				break;
			case MUFS_FFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				break;
			case FS_FFS:
				break;
			case MUFS_OFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				/* fall thru */
			case FS_OFS:
				s->u.affs_sb.s_flags |= SF_OFS;
				break;
			case MUFS_INTLOFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				/* fall thru */
			case FS_INTLOFS:
				s->u.affs_sb.s_flags |= SF_INTL | SF_OFS;
				break;
			case FS_DCOFS:
			case FS_DCFFS:
			case MUFS_DCOFS:
			case MUFS_DCFFS:
				if (!silent)
					printk("AFFS: Unsupported filesystem on device %s: %08X\n",
					        kdevname(dev),chksum);
				if (0)
			default:
				printk("AFFS: Unknown filesystem on device %s: %08X\n",
				       kdevname(dev),chksum);
				affs_brelse(bb);
				goto out;
		}
		affs_brelse(bb);
	} else {
		printk("AFFS: Can't get boot block.\n");
		goto out;
	}
	if (mount_flags & SF_VERBOSE) {
		chksum = ntohl(chksum);
		printk("AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",
		       GET_END_PTR(struct root_end,bh->b_data,blocksize)->disk_name[0],
		       &GET_END_PTR(struct root_end,bh->b_data,blocksize)->disk_name[1],
		       (char *)&chksum,((char *)&chksum)[3] + '0',blocksize);
	}