示例#1
0
/*
 * Print contents of ufs2 ufs_super_block, useful for debugging
 */
void ufs2_print_super_stuff(
     struct super_block *sb,
      struct ufs_super_block *usb)
{
	printk("ufs_print_super_stuff\n");
	printk("size of usb:     %u\n", sizeof(struct ufs_super_block));
	printk("  magic:         0x%x\n", fs32_to_cpu(sb, usb->fs_magic));
	printk("  fs_size:   %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_size));
	printk("  fs_dsize:  %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_dsize));
	printk("  bsize:         %u\n", fs32_to_cpu(usb, usb->fs_bsize));
	printk("  fsize:         %u\n", fs32_to_cpu(usb, usb->fs_fsize));
	printk("  fs_volname:  %s\n", usb->fs_u11.fs_u2.fs_volname);
	printk("  fs_fsmnt:  %s\n", usb->fs_u11.fs_u2.fs_fsmnt);
	printk("  fs_sblockloc: %u\n",fs64_to_cpu(sb,
			usb->fs_u11.fs_u2.fs_sblockloc));
	printk("  cs_ndir(No of dirs):  %u\n",fs64_to_cpu(sb,
			usb->fs_u11.fs_u2.fs_cstotal.cs_ndir));
	printk("  cs_nbfree(No of free blocks):  %u\n",fs64_to_cpu(sb,
			usb->fs_u11.fs_u2.fs_cstotal.cs_nbfree));
	printk("\n");
}
/**
 * befs_bt_read_super - read in btree superblock convert to cpu byteorder
 * @sb: Filesystem superblock
 * @ds: Datastream to read from
 * @sup: Buffer in which to place the btree superblock
 *
 * Calls befs_read_datastream to read in the btree superblock and
 * makes sure it is in cpu byteorder, byteswapping if necessary.
 *
 * On success, returns BEFS_OK and *@sup contains the btree superblock,
 * in cpu byte order.
 *
 * On failure, BEFS_ERR is returned.
 */
static int
befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
		   befs_btree_super * sup)
{
	struct buffer_head *bh = NULL;
	befs_disk_btree_super *od_sup = NULL;

	befs_debug(sb, "---> befs_btree_read_super()");

	bh = befs_read_datastream(sb, ds, 0, NULL);

	if (!bh) {
		befs_error(sb, "Couldn't read index header.");
		goto error;
	}
	od_sup = (befs_disk_btree_super *) bh->b_data;
	befs_dump_index_entry(sb, od_sup);

	sup->magic = fs32_to_cpu(sb, od_sup->magic);
	sup->node_size = fs32_to_cpu(sb, od_sup->node_size);
	sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth);
	sup->data_type = fs32_to_cpu(sb, od_sup->data_type);
	sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr);
	sup->free_node_ptr = fs64_to_cpu(sb, od_sup->free_node_ptr);
	sup->max_size = fs64_to_cpu(sb, od_sup->max_size);

	brelse(bh);
	if (sup->magic != BEFS_BTREE_MAGIC) {
		befs_error(sb, "Index header has bad magic.");
		goto error;
	}

	befs_debug(sb, "<--- befs_btree_read_super()");
	return BEFS_OK;

      error:
	befs_debug(sb, "<--- befs_btree_read_super() ERROR");
	return BEFS_ERR;
}
示例#3
0
文件: inode.c 项目: 020gzh/linux
/*
	Validates the correctness of the befs inode
	Returns BEFS_OK if the inode should be used, otherwise
	returns BEFS_BAD_INODE
*/
int
befs_check_inode(struct super_block *sb, befs_inode * raw_inode,
		 befs_blocknr_t inode)
{
	u32 magic1 = fs32_to_cpu(sb, raw_inode->magic1);
	befs_inode_addr ino_num = fsrun_to_cpu(sb, raw_inode->inode_num);
	u32 flags = fs32_to_cpu(sb, raw_inode->flags);

	/* check magic header. */
	if (magic1 != BEFS_INODE_MAGIC1) {
		befs_error(sb,
			   "Inode has a bad magic header - inode = %lu",
			   (unsigned long)inode);
		return BEFS_BAD_INODE;
	}

	/*
	 * Sanity check2: inodes store their own block address. Check it.
	 */
	if (inode != iaddr2blockno(sb, &ino_num)) {
		befs_error(sb, "inode blocknr field disagrees with vfs "
			   "VFS: %lu, Inode %lu", (unsigned long)
			   inode, (unsigned long)iaddr2blockno(sb, &ino_num));
		return BEFS_BAD_INODE;
	}

	/*
	 * check flag
	 */

	if (!(flags & BEFS_INODE_IN_USE)) {
		befs_error(sb, "inode is not used - inode = %lu",
			   (unsigned long)inode);
		return BEFS_BAD_INODE;
	}

	return BEFS_OK;
}
static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh)
{
	struct super_block *sb = sbi->s_sb;
	/* All relevant fields are at the same offsets in R2 and R4 */
	struct sysv4_super_block * sbd;

	sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
	if (sbd->s_magic == cpu_to_le32(0xfd187e20))
		sbi->s_bytesex = BYTESEX_LE;
	else if (sbd->s_magic == cpu_to_be32(0xfd187e20))
		sbi->s_bytesex = BYTESEX_BE;
	else
		return 0;
 
 	if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) {
 		sbi->s_type = FSTYPE_AFS;
		sbi->s_forced_ro = 1;
 		if (!(sb->s_flags & MS_RDONLY)) {
 			printk("SysV FS: SCO EAFS on %s detected, " 
 				"forcing read-only mode.\n", 
 				sb->s_id);
 		}
 		return sbd->s_type;
 	}
 
	if (fs32_to_cpu(sbi, sbd->s_time) < JAN_1_1980) {
		/* this is likely to happen on SystemV2 FS */
		if (sbd->s_type > 3 || sbd->s_type < 1)
			return 0;
		sbi->s_type = FSTYPE_SYSV2;
		return sbd->s_type;
	}
	if ((sbd->s_type > 3 || sbd->s_type < 1) &&
	    (sbd->s_type > 0x30 || sbd->s_type < 0x10))
		return 0;

	/* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
	   0x20 or 0x30 indicates that symbolic links and the 14-character
	   filename limit is gone. Due to lack of information about this
           feature read-only mode seems to be a reasonable approach... -KGB */

	if (sbd->s_type >= 0x10) {
		printk("SysV FS: can't handle long file names on %s, "
		       "forcing read-only mode.\n", sb->s_id);
		sbi->s_forced_ro = 1;
	}

	sbi->s_type = FSTYPE_SYSV4;
	return sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type;
}
示例#5
0
/*
 * befs_load_sb -- Read from disk and properly byteswap all the fields
 * of the befs superblock
 */
int
befs_load_sb(struct super_block *sb, befs_super_block *disk_sb)
{
	struct befs_sb_info *befs_sb = BEFS_SB(sb);

	/* Check the byte order of the filesystem */
	if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE)
		befs_sb->byte_order = BEFS_BYTESEX_LE;
	else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE)
		befs_sb->byte_order = BEFS_BYTESEX_BE;

	befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1);
	befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2);
	befs_sb->magic3 = fs32_to_cpu(sb, disk_sb->magic3);
	befs_sb->block_size = fs32_to_cpu(sb, disk_sb->block_size);
	befs_sb->block_shift = fs32_to_cpu(sb, disk_sb->block_shift);
	befs_sb->num_blocks = fs64_to_cpu(sb, disk_sb->num_blocks);
	befs_sb->used_blocks = fs64_to_cpu(sb, disk_sb->used_blocks);
	befs_sb->inode_size = fs32_to_cpu(sb, disk_sb->inode_size);

	befs_sb->blocks_per_ag = fs32_to_cpu(sb, disk_sb->blocks_per_ag);
	befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift);
	befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags);

	befs_sb->flags = fs32_to_cpu(sb, disk_sb->flags);

	befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks);
	befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start);
	befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end);

	befs_sb->root_dir = fsrun_to_cpu(sb, disk_sb->root_dir);
	befs_sb->indices = fsrun_to_cpu(sb, disk_sb->indices);
	befs_sb->nls = NULL;

	return BEFS_OK;
}
示例#6
0
/* This is only called on sync() and umount(), when s_dirt=1. */
static void sysv_write_super(struct super_block *sb)
{
	if (!(sb->s_flags & MS_RDONLY)) {
		/* If we are going to write out the super block,
		   then attach current time stamp.
		   But if the filesystem was marked clean, keep it clean. */
		unsigned long time = CURRENT_TIME;
		unsigned long old_time = fs32_to_cpu(sb, *sb->sv_sb_time);
		if (sb->sv_type == FSTYPE_SYSV4)
			if (*sb->sv_sb_state == cpu_to_fs32(sb, 0x7c269d38 - old_time))
				*sb->sv_sb_state = cpu_to_fs32(sb, 0x7c269d38 - time);
		*sb->sv_sb_time = cpu_to_fs32(sb, time);
		mark_buffer_dirty(sb->sv_bh2);
	}
	sb->s_dirt = 0;
}
示例#7
0
/**
 * vxfs_inode_by_name - find inode number for dentry
 * @dip:	directory to search in
 * @dp:		dentry we search for
 *
 * Description:
 *   vxfs_inode_by_name finds out the inode number of
 *   the path component described by @dp in @dip.
 *
 * Returns:
 *   The wanted inode number on success, else Zero.
 */
static ino_t
vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
{
	struct vxfs_direct		*de;
	struct page			*pp;
	ino_t				ino = 0;

	de = vxfs_find_entry(dip, dp, &pp);
	if (de) {
		ino = fs32_to_cpu(VXFS_SBI(dip->i_sb), de->d_ino);
		kunmap(pp);
		put_page(pp);
	}
	
	return (ino);
}
static void detected_v7(struct sysv_sb_info *sbi)
{
	struct buffer_head *bh2 = sbi->s_bh2;
	struct v7_super_block *sbd = (struct v7_super_block *)bh2->b_data;

	sbi->s_link_max = V7_LINK_MAX;
	sbi->s_fic_size = V7_NICINOD;
	sbi->s_flc_size = V7_NICFREE;
	sbi->s_sbd1 = (char *)sbd;
	sbi->s_sbd2 = (char *)sbd;
	sbi->s_sb_fic_count = &sbd->s_ninode;
	sbi->s_sb_fic_inodes = &sbd->s_inode[0];
	sbi->s_sb_total_free_inodes = &sbd->s_tinode;
	sbi->s_bcache_count = &sbd->s_nfree;
	sbi->s_bcache = &sbd->s_free[0];
	sbi->s_free_blocks = &sbd->s_tfree;
	sbi->s_sb_time = &sbd->s_time;
	sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize);
	sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
}
示例#9
0
static int detect_xenix(struct sysv_sb_info *sbi, struct buffer_head *bh)
{
	struct xenix_super_block *sbd = (struct xenix_super_block *)bh->b_data;
	if (*(__le32 *)&sbd->s_magic == cpu_to_le32(0x2b5544))
		sbi->s_bytesex = BYTESEX_LE;
	else if (*(__be32 *)&sbd->s_magic == cpu_to_be32(0x2b5544))
		sbi->s_bytesex = BYTESEX_BE;
	else
		return 0;
	switch (fs32_to_cpu(sbi, sbd->s_type)) {
	case 1:
		sbi->s_type = FSTYPE_XENIX;
		return 1;
	case 2:
		sbi->s_type = FSTYPE_XENIX;
		return 2;
	default:
		return 0;
	}
}
示例#10
0
static void detected_coherent(struct sysv_sb_info *sbi, unsigned *max_links)
{
	struct coh_super_block * sbd;
	struct buffer_head *bh1 = sbi->s_bh1;

	sbd = (struct coh_super_block *) bh1->b_data;

	*max_links = COH_LINK_MAX;
	sbi->s_fic_size = COH_NICINOD;
	sbi->s_flc_size = COH_NICFREE;
	sbi->s_sbd1 = (char *)sbd;
	sbi->s_sbd2 = (char *)sbd;
	sbi->s_sb_fic_count = &sbd->s_ninode;
	sbi->s_sb_fic_inodes = &sbd->s_inode[0];
	sbi->s_sb_total_free_inodes = &sbd->s_tinode;
	sbi->s_bcache_count = &sbd->s_nfree;
	sbi->s_bcache = &sbd->s_free[0];
	sbi->s_free_blocks = &sbd->s_tfree;
	sbi->s_sb_time = &sbd->s_time;
	sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize);
	sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
}
static int sysv_sync_fs(struct super_block *sb, int wait)
{
	struct sysv_sb_info *sbi = SYSV_SB(sb);
	unsigned long time = get_seconds(), old_time;

	mutex_lock(&sbi->s_lock);

	/*
	 * If we are going to write out the super block,
	 * then attach current time stamp.
	 * But if the filesystem was marked clean, keep it clean.
	 */
	old_time = fs32_to_cpu(sbi, *sbi->s_sb_time);
	if (sbi->s_type == FSTYPE_SYSV4) {
		if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time))
			*sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38 - time);
		*sbi->s_sb_time = cpu_to_fs32(sbi, time);
		mark_buffer_dirty(sbi->s_bh2);
	}

	mutex_unlock(&sbi->s_lock);

	return 0;
}
示例#12
0
static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
{
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	struct ufs_super_block_third * usb3;
	unsigned new_mount_opt, ufstype;
	unsigned flags;

	sync_filesystem(sb);
	mutex_lock(&UFS_SB(sb)->s_lock);
	uspi = UFS_SB(sb)->s_uspi;
	flags = UFS_SB(sb)->s_flags;
	usb1 = ubh_get_usb_first(uspi);
	usb3 = ubh_get_usb_third(uspi);
	
	/*
	 * Allow the "check" option to be passed as a remount option.
	 * It is not possible to change ufstype option during remount
	 */
	ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
	new_mount_opt = 0;
	ufs_set_opt (new_mount_opt, ONERROR_LOCK);
	if (!ufs_parse_options (data, &new_mount_opt)) {
		mutex_unlock(&UFS_SB(sb)->s_lock);
		return -EINVAL;
	}
	if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
		new_mount_opt |= ufstype;
	} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
		pr_err("ufstype can't be changed during remount\n");
		mutex_unlock(&UFS_SB(sb)->s_lock);
		return -EINVAL;
	}

	if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
		UFS_SB(sb)->s_mount_opt = new_mount_opt;
		mutex_unlock(&UFS_SB(sb)->s_lock);
		return 0;
	}
	
	/*
	 * fs was mouted as rw, remounting ro
	 */
	if (*mount_flags & MS_RDONLY) {
		ufs_put_super_internal(sb);
		usb1->fs_time = cpu_to_fs32(sb, get_seconds());
		if ((flags & UFS_ST_MASK) == UFS_ST_SUN
		  || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
		  || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 
			ufs_set_fs_state(sb, usb1, usb3,
				UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
		ubh_mark_buffer_dirty (USPI_UBH(uspi));
		sb->s_flags |= MS_RDONLY;
	} else {
	/*
	 * fs was mounted as ro, remounting rw
	 */
#ifndef CONFIG_UFS_FS_WRITE
		pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n");
		mutex_unlock(&UFS_SB(sb)->s_lock);
		return -EINVAL;
#else
		if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
		    ufstype != UFS_MOUNT_UFSTYPE_SUNOS &&
		    ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
		    ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
		    ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
			pr_err("this ufstype is read-only supported\n");
			mutex_unlock(&UFS_SB(sb)->s_lock);
			return -EINVAL;
		}
		if (!ufs_read_cylinder_structures(sb)) {
			pr_err("failed during remounting\n");
			mutex_unlock(&UFS_SB(sb)->s_lock);
			return -EPERM;
		}
		sb->s_flags &= ~MS_RDONLY;
#endif
	}
	UFS_SB(sb)->s_mount_opt = new_mount_opt;
	mutex_unlock(&UFS_SB(sb)->s_lock);
	return 0;
}
/*
 * This is blatantly stolen from ext2fs
 */
static int
ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
{
	struct inode *inode = filp->f_dentry->d_inode;
	int error = 0;
	unsigned long offset, lblk;
	int i, stored;
	struct buffer_head * bh;
	struct ufs_dir_entry * de;
	struct super_block * sb;
	int de_reclen;
	unsigned flags;
	u64     blk= 0L;

	lock_kernel();

	sb = inode->i_sb;
	flags = UFS_SB(sb)->s_flags;

	UFSD(("ENTER, ino %lu  f_pos %lu\n", inode->i_ino, (unsigned long) filp->f_pos))

	stored = 0;
	bh = NULL;
	offset = filp->f_pos & (sb->s_blocksize - 1);

	while (!error && !stored && filp->f_pos < inode->i_size) {
		lblk = (filp->f_pos) >> sb->s_blocksize_bits;
		blk = ufs_frag_map(inode, lblk);
		if (!blk || !(bh = sb_bread(sb, blk))) {
			/* XXX - error - skip to the next block */
			printk("ufs_readdir: "
			       "dir inode %lu has a hole at offset %lu\n",
			       inode->i_ino, (unsigned long int)filp->f_pos);
			filp->f_pos += sb->s_blocksize - offset;
			continue;
		}

revalidate:
		/* If the dir block has changed since the last call to
		 * readdir(2), then we might be pointing to an invalid
		 * dirent right now.  Scan from the start of the block
		 * to make sure. */
		if (filp->f_version != inode->i_version) {
			for (i = 0; i < sb->s_blocksize && i < offset; ) {
				de = (struct ufs_dir_entry *)(bh->b_data + i);
				/* It's too expensive to do a full
				 * dirent test each time round this
				 * loop, but we do have to test at
				 * least that it is non-zero.  A
				 * failure will be detected in the
				 * dirent test below. */
				de_reclen = fs16_to_cpu(sb, de->d_reclen);
				if (de_reclen < 1)
					break;
				i += de_reclen;
			}
			offset = i;
			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
				| offset;
			filp->f_version = inode->i_version;
		}

		while (!error && filp->f_pos < inode->i_size
		       && offset < sb->s_blocksize) {
			de = (struct ufs_dir_entry *) (bh->b_data + offset);
			/* XXX - put in a real ufs_check_dir_entry() */
			if ((de->d_reclen == 0) || (ufs_get_de_namlen(sb, de) == 0)) {
				filp->f_pos = (filp->f_pos &
				              (sb->s_blocksize - 1)) +
				               sb->s_blocksize;
				brelse(bh);
				unlock_kernel();
				return stored;
			}
			if (!ufs_check_dir_entry ("ufs_readdir", inode, de,
						   bh, offset)) {
				/* On error, skip the f_pos to the
				   next block. */
				filp->f_pos = (filp->f_pos |
				              (sb->s_blocksize - 1)) +
					       1;
				brelse (bh);
				unlock_kernel();
				return stored;
			}
			offset += fs16_to_cpu(sb, de->d_reclen);
			if (de->d_ino) {
				/* We might block in the next section
				 * if the data destination is
				 * currently swapped out.  So, use a
				 * version stamp to detect whether or
				 * not the directory has been modified
				 * during the copy operation. */
				unsigned long version = filp->f_version;
				unsigned char d_type = DT_UNKNOWN;

				UFSD(("filldir(%s,%u)\n", de->d_name,
							fs32_to_cpu(sb, de->d_ino)))
				UFSD(("namlen %u\n", ufs_get_de_namlen(sb, de)))

				if ((flags & UFS_DE_MASK) == UFS_DE_44BSD)
					d_type = de->d_u.d_44.d_type;
				error = filldir(dirent, de->d_name,
						ufs_get_de_namlen(sb, de), filp->f_pos,
						fs32_to_cpu(sb, de->d_ino), d_type);
				if (error)
					break;
				if (version != filp->f_version)
					goto revalidate;
				stored ++;
			}
			filp->f_pos += fs16_to_cpu(sb, de->d_reclen);
		}
		offset = 0;
		brelse (bh);
	}
示例#14
0
文件: cylinder.c 项目: 020gzh/linux
/*
 * Read cylinder group into cache. The memory space for ufs_cg_private_info
 * structure is already allocated during ufs_read_super.
 */
static void ufs_read_cylinder (struct super_block * sb,
	unsigned cgno, unsigned bitmap_nr)
{
	struct ufs_sb_info * sbi = UFS_SB(sb);
	struct ufs_sb_private_info * uspi;
	struct ufs_cg_private_info * ucpi;
	struct ufs_cylinder_group * ucg;
	unsigned i, j;

	UFSD("ENTER, cgno %u, bitmap_nr %u\n", cgno, bitmap_nr);
	uspi = sbi->s_uspi;
	ucpi = sbi->s_ucpi[bitmap_nr];
	ucg = (struct ufs_cylinder_group *)sbi->s_ucg[cgno]->b_data;

	UCPI_UBH(ucpi)->fragment = ufs_cgcmin(cgno);
	UCPI_UBH(ucpi)->count = uspi->s_cgsize >> sb->s_blocksize_bits;
	/*
	 * We have already the first fragment of cylinder group block in buffer
	 */
	UCPI_UBH(ucpi)->bh[0] = sbi->s_ucg[cgno];
	for (i = 1; i < UCPI_UBH(ucpi)->count; i++)
		if (!(UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i)))
			goto failed;
	sbi->s_cgno[bitmap_nr] = cgno;
			
	ucpi->c_cgx	= fs32_to_cpu(sb, ucg->cg_cgx);
	ucpi->c_ncyl	= fs16_to_cpu(sb, ucg->cg_ncyl);
	ucpi->c_niblk	= fs16_to_cpu(sb, ucg->cg_niblk);
	ucpi->c_ndblk	= fs32_to_cpu(sb, ucg->cg_ndblk);
	ucpi->c_rotor	= fs32_to_cpu(sb, ucg->cg_rotor);
	ucpi->c_frotor	= fs32_to_cpu(sb, ucg->cg_frotor);
	ucpi->c_irotor	= fs32_to_cpu(sb, ucg->cg_irotor);
	ucpi->c_btotoff	= fs32_to_cpu(sb, ucg->cg_btotoff);
	ucpi->c_boff	= fs32_to_cpu(sb, ucg->cg_boff);
	ucpi->c_iusedoff = fs32_to_cpu(sb, ucg->cg_iusedoff);
	ucpi->c_freeoff	= fs32_to_cpu(sb, ucg->cg_freeoff);
	ucpi->c_nextfreeoff = fs32_to_cpu(sb, ucg->cg_nextfreeoff);
	ucpi->c_clustersumoff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clustersumoff);
	ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff);
	ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks);
	UFSD("EXIT\n");
	return;	
	
failed:
	for (j = 1; j < i; j++)
		brelse (sbi->s_ucg[j]);
	sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
	ufs_error (sb, "ufs_read_cylinder", "can't read cylinder group block %u", cgno);
}
示例#15
0
/**
 * vxfs_readdir - read a directory
 * @fp:		the directory to read
 * @retp:	return buffer
 * @filler:	filldir callback
 *
 * Description:
 *   vxfs_readdir fills @retp with directory entries from @fp
 *   using the VFS supplied callback @filler.
 *
 * Returns:
 *   Zero.
 */
static int
vxfs_readdir(struct file *fp, struct dir_context *ctx)
{
	struct inode		*ip = file_inode(fp);
	struct super_block	*sbp = ip->i_sb;
	u_long			bsize = sbp->s_blocksize;
	loff_t			pos, limit;
	struct vxfs_sb_info	*sbi = VXFS_SBI(sbp);

	if (ctx->pos == 0) {
		if (!dir_emit_dot(fp, ctx))
			goto out;
		ctx->pos++;
	}
	if (ctx->pos == 1) {
		if (!dir_emit(ctx, "..", 2, VXFS_INO(ip)->vii_dotdot, DT_DIR))
			goto out;
		ctx->pos++;
	}

	limit = VXFS_DIRROUND(ip->i_size);
	if (ctx->pos > limit)
		goto out;

	pos = ctx->pos & ~3L;

	while (pos < limit) {
		struct page *pp;
		char *kaddr;
		int pg_ofs = pos & ~PAGE_MASK;
		int rc = 0;

		pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_SHIFT);
		if (IS_ERR(pp))
			return -ENOMEM;

		kaddr = (char *)page_address(pp);

		while (pg_ofs < PAGE_SIZE && pos < limit) {
			struct vxfs_direct *de;

			if ((pos & (bsize - 1)) < 4) {
				struct vxfs_dirblk *dbp =
					(struct vxfs_dirblk *)
					 (kaddr + (pos & ~PAGE_MASK));
				int overhead = VXFS_DIRBLKOV(sbi, dbp);

				pos += overhead;
				pg_ofs += overhead;
			}
			de = (struct vxfs_direct *)(kaddr + pg_ofs);

			if (!de->d_reclen) {
				pos += bsize - 1;
				pos &= ~(bsize - 1);
				break;
			}

			pg_ofs += fs16_to_cpu(sbi, de->d_reclen);
			pos += fs16_to_cpu(sbi, de->d_reclen);
			if (!de->d_ino)
				continue;

			rc = dir_emit(ctx, de->d_name,
					fs16_to_cpu(sbi, de->d_namelen),
					fs32_to_cpu(sbi, de->d_ino),
					DT_UNKNOWN);
			if (!rc) {
				/* the dir entry was not read, fix pos. */
				pos -= fs16_to_cpu(sbi, de->d_reclen);
				break;
			}
		}
		vxfs_put_page(pp);
		if (!rc)
			break;
	}

	ctx->pos = pos | 2;

out:
	return 0;
}
struct qnx6_super_block *qnx6_mmi_fill_super(struct super_block *s, int silent)
{
    struct buffer_head *bh1, *bh2 = NULL;
    struct qnx6_mmi_super_block *sb1, *sb2;
    struct qnx6_super_block *qsb = NULL;
    struct qnx6_sb_info *sbi;
    __u64 offset;

    bh1 = sb_bread(s, 0);
    if (!bh1) {
        printk(KERN_ERR "qnx6: Unable to read first mmi superblock\n");
        return NULL;
    }
    sb1 = (struct qnx6_mmi_super_block *)bh1->b_data;
    sbi = QNX6_SB(s);
    if (fs32_to_cpu(sbi, sb1->sb_magic) != QNX6_SUPER_MAGIC) {
        if (!silent) {
            printk(KERN_ERR "qnx6: wrong signature (magic) in"
                   " superblock #1.\n");
            goto out;
        }
    }


    if (fs32_to_cpu(sbi, sb1->sb_checksum) !=
            crc32_be(0, (char *)(bh1->b_data + 8), 504)) {
        printk(KERN_ERR "qnx6: superblock #1 checksum error\n");
        goto out;
    }


    offset = fs32_to_cpu(sbi, sb1->sb_num_blocks) + QNX6_SUPERBLOCK_AREA /
             fs32_to_cpu(sbi, sb1->sb_blocksize);


    if (!sb_set_blocksize(s, fs32_to_cpu(sbi, sb1->sb_blocksize))) {
        printk(KERN_ERR "qnx6: unable to set blocksize\n");
        goto out;
    }

    brelse(bh1);
    bh1 = sb_bread(s, 0);
    if (!bh1)
        goto out;
    sb1 = (struct qnx6_mmi_super_block *)bh1->b_data;


    bh2 = sb_bread(s, offset);
    if (!bh2) {
        printk(KERN_ERR "qnx6: unable to read the second superblock\n");
        goto out;
    }
    sb2 = (struct qnx6_mmi_super_block *)bh2->b_data;
    if (fs32_to_cpu(sbi, sb2->sb_magic) != QNX6_SUPER_MAGIC) {
        if (!silent)
            printk(KERN_ERR "qnx6: wrong signature (magic) in"
                   " superblock #2.\n");
        goto out;
    }


    if (fs32_to_cpu(sbi, sb2->sb_checksum)
            != crc32_be(0, (char *)(bh2->b_data + 8), 504)) {
        printk(KERN_ERR "qnx6: superblock #1 checksum error\n");
        goto out;
    }

    qsb = kmalloc(sizeof(*qsb), GFP_KERNEL);
    if (!qsb) {
        printk(KERN_ERR "qnx6: unable to allocate memory.\n");
        goto out;
    }

    if (fs64_to_cpu(sbi, sb1->sb_serial) >
            fs64_to_cpu(sbi, sb2->sb_serial)) {

        qnx6_mmi_copy_sb(qsb, sb1);
#ifdef CONFIG_QNX6FS_DEBUG
        qnx6_superblock_debug(qsb, s);
#endif
        memcpy(bh1->b_data, qsb, sizeof(struct qnx6_super_block));

        sbi->sb_buf = bh1;
        sbi->sb = (struct qnx6_super_block *)bh1->b_data;
        brelse(bh2);
        printk(KERN_INFO "qnx6: superblock #1 active\n");
    } else {

        qnx6_mmi_copy_sb(qsb, sb2);
#ifdef CONFIG_QNX6FS_DEBUG
        qnx6_superblock_debug(qsb, s);
#endif
        memcpy(bh2->b_data, qsb, sizeof(struct qnx6_super_block));

        sbi->sb_buf = bh2;
        sbi->sb = (struct qnx6_super_block *)bh2->b_data;
        brelse(bh1);
        printk(KERN_INFO "qnx6: superblock #2 active\n");
    }
    kfree(qsb);


    sbi->s_blks_off = QNX6_SUPERBLOCK_AREA / s->s_blocksize;


    return sbi->sb;

out:
    if (bh1 != NULL)
        brelse(bh1);
    if (bh2 != NULL)
        brelse(bh2);
    return NULL;
}
示例#17
0
/*
	Finds the block run that starts at file block number blockno
	in the file represented by the datastream data, if that 
	blockno is in the indirect region of the datastream.
	
	sb: the superblock
	data: the datastream
	blockno: the blocknumber to find
	run: The found run is passed back through this pointer
	
	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
	otherwise.
	
	Algorithm:
	For each block in the indirect run of the datastream, read
	it in and search through it for	search_blk.
	
	XXX:
	Really should check to make sure blockno is inside indirect
	region.
	
	2001-11-15 Will Dyson
*/
static int
befs_find_brun_indirect(struct super_block *sb,
			befs_data_stream * data, befs_blocknr_t blockno,
			befs_block_run * run)
{
	int i, j;
	befs_blocknr_t sum = 0;
	befs_blocknr_t indir_start_blk;
	befs_blocknr_t search_blk;
	struct buffer_head *indirblock;
	befs_disk_block_run *array;

	befs_block_run indirect = data->indirect;
	befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect);
	int arraylen = befs_iaddrs_per_block(sb);

	befs_debug(sb, "---> befs_find_brun_indirect(), find %lu", blockno);

	indir_start_blk = data->max_direct_range >> BEFS_SB(sb)->block_shift;
	search_blk = blockno - indir_start_blk;

	/* Examine blocks of the indirect run one at a time */
	for (i = 0; i < indirect.len; i++) {
		indirblock = befs_bread(sb, indirblockno + i);
		if (indirblock == NULL) {
			befs_debug(sb,
				   "---> befs_find_brun_indirect() failed to "
				   "read disk block %lu from the indirect brun",
				   indirblockno + i);
			return BEFS_ERR;
		}

		array = (befs_disk_block_run *) indirblock->b_data;

		for (j = 0; j < arraylen; ++j) {
			int len = fs16_to_cpu(sb, array[j].len);

			if (search_blk >= sum && search_blk < sum + len) {
				int offset = search_blk - sum;
				run->allocation_group =
				    fs32_to_cpu(sb, array[j].allocation_group);
				run->start =
				    fs16_to_cpu(sb, array[j].start) + offset;
				run->len =
				    fs16_to_cpu(sb, array[j].len) - offset;

				brelse(indirblock);
				befs_debug(sb,
					   "<--- befs_find_brun_indirect() found "
					   "file block %lu at indirect[%d]",
					   blockno, j + (i * arraylen));
				return BEFS_OK;
			}
			sum += len;
		}

		brelse(indirblock);
	}

	/* Only fallthrough is an error */
	befs_error(sb, "BeFS: befs_find_brun_indirect() failed to find "
		   "file block %lu", blockno);

	befs_debug(sb, "<--- befs_find_brun_indirect() ERROR");
	return BEFS_ERR;
}
示例#18
0
static int ufs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct ufs_sb_info * sbi;
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	struct ufs_super_block_second * usb2;
	struct ufs_super_block_third * usb3;
	struct ufs_buffer_head * ubh;	
	struct inode *inode;
	unsigned block_size, super_block_size;
	unsigned flags;
	unsigned super_block_offset;
	unsigned maxsymlen;
	int ret = -EINVAL;

	uspi = NULL;
	ubh = NULL;
	flags = 0;
	
	UFSD("ENTER\n");

#ifndef CONFIG_UFS_FS_WRITE
	if (!(sb->s_flags & MS_RDONLY)) {
		pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n");
		return -EROFS;
	}
#endif
		
	sbi = kzalloc(sizeof(struct ufs_sb_info), GFP_KERNEL);
	if (!sbi)
		goto failed_nomem;
	sb->s_fs_info = sbi;
	sbi->sb = sb;

	UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY));
	
	mutex_init(&sbi->s_lock);
	spin_lock_init(&sbi->work_lock);
	INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs);
	/*
	 * Set default mount options
	 * Parse mount options
	 */
	sbi->s_mount_opt = 0;
	ufs_set_opt (sbi->s_mount_opt, ONERROR_LOCK);
	if (!ufs_parse_options ((char *) data, &sbi->s_mount_opt)) {
		pr_err("wrong mount options\n");
		goto failed;
	}
	if (!(sbi->s_mount_opt & UFS_MOUNT_UFSTYPE)) {
		if (!silent)
			pr_err("You didn't specify the type of your ufs filesystem\n\n"
			"mount -t ufs -o ufstype="
			"sun|sunx86|44bsd|ufs2|5xbsd|old|hp|nextstep|nextstep-cd|openstep ...\n\n"
			">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
			"default is ufstype=old\n");
		ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);
	}

	uspi = kzalloc(sizeof(struct ufs_sb_private_info), GFP_KERNEL);
	sbi->s_uspi = uspi;
	if (!uspi)
		goto failed;
	uspi->s_dirblksize = UFS_SECTOR_SIZE;
	super_block_offset=UFS_SBLOCK;

	/* Keep 2Gig file limit. Some UFS variants need to override 
	   this but as I don't know which I'll let those in the know loosen
	   the rules */
	switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {
	case UFS_MOUNT_UFSTYPE_44BSD:
		UFSD("ufstype=44bsd\n");
		uspi->s_fsize = block_size = 512;
		uspi->s_fmask = ~(512 - 1);
		uspi->s_fshift = 9;
		uspi->s_sbsize = super_block_size = 1536;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
		break;
	case UFS_MOUNT_UFSTYPE_UFS2:
		UFSD("ufstype=ufs2\n");
		super_block_offset=SBLOCK_UFS2;
		uspi->s_fsize = block_size = 512;
		uspi->s_fmask = ~(512 - 1);
		uspi->s_fshift = 9;
		uspi->s_sbsize = super_block_size = 1536;
		uspi->s_sbbase =  0;
		flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
		break;
		
	case UFS_MOUNT_UFSTYPE_SUN:
		UFSD("ufstype=sun\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_maxsymlinklen = 0; /* Not supported on disk */
		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
		break;

	case UFS_MOUNT_UFSTYPE_SUNOS:
		UFSD("ufstype=sunos\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = 2048;
		super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_maxsymlinklen = 0; /* Not supported on disk */
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_SUNOS | UFS_CG_SUN;
		break;

	case UFS_MOUNT_UFSTYPE_SUNx86:
		UFSD("ufstype=sunx86\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_maxsymlinklen = 0; /* Not supported on disk */
		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;
		break;

	case UFS_MOUNT_UFSTYPE_OLD:
		UFSD("ufstype=old\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			if (!silent)
				pr_info("ufstype=old is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_NEXTSTEP:
		UFSD("ufstype=nextstep\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_dirblksize = 1024;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			if (!silent)
				pr_info("ufstype=nextstep is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD:
		UFSD("ufstype=nextstep-cd\n");
		uspi->s_fsize = block_size = 2048;
		uspi->s_fmask = ~(2048 - 1);
		uspi->s_fshift = 11;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_dirblksize = 1024;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			if (!silent)
				pr_info("ufstype=nextstep-cd is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_OPENSTEP:
		UFSD("ufstype=openstep\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_dirblksize = 1024;
		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
		if (!(sb->s_flags & MS_RDONLY)) {
			if (!silent)
				pr_info("ufstype=openstep is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_HP:
		UFSD("ufstype=hp\n");
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			if (!silent)
				pr_info("ufstype=hp is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
 		}
 		break;
	default:
		if (!silent)
			pr_err("unknown ufstype\n");
		goto failed;
	}
	
again:	
	if (!sb_set_blocksize(sb, block_size)) {
		pr_err("failed to set blocksize\n");
		goto failed;
	}

	/*
	 * read ufs super block from device
	 */

	ubh = ubh_bread_uspi(uspi, sb, uspi->s_sbbase + super_block_offset/block_size, super_block_size);
	
	if (!ubh) 
            goto failed;

	usb1 = ubh_get_usb_first(uspi);
	usb2 = ubh_get_usb_second(uspi);
	usb3 = ubh_get_usb_third(uspi);

	/* Sort out mod used on SunOS 4.1.3 for fs_state */
	uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
	if (((flags & UFS_ST_MASK) == UFS_ST_SUNOS) &&
	    (uspi->s_postblformat != UFS_42POSTBLFMT)) {
		flags &= ~UFS_ST_MASK;
		flags |=  UFS_ST_SUN;
	}

	/*
	 * Check ufs magic number
	 */
	sbi->s_bytesex = BYTESEX_LE;
	switch ((uspi->fs_magic = fs32_to_cpu(sb, usb3->fs_magic))) {
		case UFS_MAGIC:
		case UFS_MAGIC_BW:
		case UFS2_MAGIC:
		case UFS_MAGIC_LFN:
	        case UFS_MAGIC_FEA:
	        case UFS_MAGIC_4GB:
			goto magic_found;
	}
	sbi->s_bytesex = BYTESEX_BE;
	switch ((uspi->fs_magic = fs32_to_cpu(sb, usb3->fs_magic))) {
		case UFS_MAGIC:
		case UFS_MAGIC_BW:
		case UFS2_MAGIC:
		case UFS_MAGIC_LFN:
	        case UFS_MAGIC_FEA:
	        case UFS_MAGIC_4GB:
			goto magic_found;
	}

	if ((((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) 
	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) 
	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) 
	  && uspi->s_sbbase < 256) {
		ubh_brelse_uspi(uspi);
		ubh = NULL;
		uspi->s_sbbase += 8;
		goto again;
	}
	if (!silent)
		pr_err("%s(): bad magic number\n", __func__);
	goto failed;

magic_found:
	/*
	 * Check block and fragment sizes
	 */
	uspi->s_bsize = fs32_to_cpu(sb, usb1->fs_bsize);
	uspi->s_fsize = fs32_to_cpu(sb, usb1->fs_fsize);
	uspi->s_sbsize = fs32_to_cpu(sb, usb1->fs_sbsize);
	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);

	if (!is_power_of_2(uspi->s_fsize)) {
		pr_err("%s(): fragment size %u is not a power of 2\n",
		       __func__, uspi->s_fsize);
		goto failed;
	}
	if (uspi->s_fsize < 512) {
		pr_err("%s(): fragment size %u is too small\n",
		       __func__, uspi->s_fsize);
		goto failed;
	}
	if (uspi->s_fsize > 4096) {
		pr_err("%s(): fragment size %u is too large\n",
		       __func__, uspi->s_fsize);
		goto failed;
	}
	if (!is_power_of_2(uspi->s_bsize)) {
		pr_err("%s(): block size %u is not a power of 2\n",
		       __func__, uspi->s_bsize);
		goto failed;
	}
	if (uspi->s_bsize < 4096) {
		pr_err("%s(): block size %u is too small\n",
		       __func__, uspi->s_bsize);
		goto failed;
	}
	if (uspi->s_bsize / uspi->s_fsize > 8) {
		pr_err("%s(): too many fragments per block (%u)\n",
		       __func__, uspi->s_bsize / uspi->s_fsize);
		goto failed;
	}
	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
		ubh_brelse_uspi(uspi);
		ubh = NULL;
		block_size = uspi->s_fsize;
		super_block_size = uspi->s_sbsize;
		UFSD("another value of block_size or super_block_size %u, %u\n", block_size, super_block_size);
		goto again;
	}

	sbi->s_flags = flags;/*after that line some functions use s_flags*/
	ufs_print_super_stuff(sb, usb1, usb2, usb3);

	/*
	 * Check, if file system was correctly unmounted.
	 * If not, make it read only.
	 */
	if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
	  ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
	  (((flags & UFS_ST_MASK) == UFS_ST_SUN ||
	    (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
	  (flags & UFS_ST_MASK) == UFS_ST_SUNx86) &&
	  (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {
		switch(usb1->fs_clean) {
		case UFS_FSCLEAN:
			UFSD("fs is clean\n");
			break;
		case UFS_FSSTABLE:
			UFSD("fs is stable\n");
			break;
		case UFS_FSLOG:
			UFSD("fs is logging fs\n");
			break;
		case UFS_FSOSF1:
			UFSD("fs is DEC OSF/1\n");
			break;
		case UFS_FSACTIVE:
			pr_err("%s(): fs is active\n", __func__);
			sb->s_flags |= MS_RDONLY;
			break;
		case UFS_FSBAD:
			pr_err("%s(): fs is bad\n", __func__);
			sb->s_flags |= MS_RDONLY;
			break;
		default:
			pr_err("%s(): can't grok fs_clean 0x%x\n",
			       __func__, usb1->fs_clean);
			sb->s_flags |= MS_RDONLY;
			break;
		}
	} else {
		pr_err("%s(): fs needs fsck\n", __func__);
		sb->s_flags |= MS_RDONLY;
	}

	/*
	 * Read ufs_super_block into internal data structures
	 */
	sb->s_op = &ufs_super_ops;
	sb->s_export_op = &ufs_export_ops;

	sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);

	uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
	uspi->s_cblkno = fs32_to_cpu(sb, usb1->fs_cblkno);
	uspi->s_iblkno = fs32_to_cpu(sb, usb1->fs_iblkno);
	uspi->s_dblkno = fs32_to_cpu(sb, usb1->fs_dblkno);
	uspi->s_cgoffset = fs32_to_cpu(sb, usb1->fs_cgoffset);
	uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask);

	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
		uspi->s_u2_size  = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size);
		uspi->s_u2_dsize = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
	} else {
		uspi->s_size  =  fs32_to_cpu(sb, usb1->fs_size);
		uspi->s_dsize =  fs32_to_cpu(sb, usb1->fs_dsize);
	}

	uspi->s_ncg = fs32_to_cpu(sb, usb1->fs_ncg);
	/* s_bsize already set */
	/* s_fsize already set */
	uspi->s_fpb = fs32_to_cpu(sb, usb1->fs_frag);
	uspi->s_minfree = fs32_to_cpu(sb, usb1->fs_minfree);
	uspi->s_bmask = fs32_to_cpu(sb, usb1->fs_bmask);
	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
	uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift);
	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
	UFSD("uspi->s_bshift = %d,uspi->s_fshift = %d", uspi->s_bshift,
		uspi->s_fshift);
	uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift);
	uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb);
	/* s_sbsize already set */
	uspi->s_csmask = fs32_to_cpu(sb, usb1->fs_csmask);
	uspi->s_csshift = fs32_to_cpu(sb, usb1->fs_csshift);
	uspi->s_nindir = fs32_to_cpu(sb, usb1->fs_nindir);
	uspi->s_inopb = fs32_to_cpu(sb, usb1->fs_inopb);
	uspi->s_nspf = fs32_to_cpu(sb, usb1->fs_nspf);
	uspi->s_npsect = ufs_get_fs_npsect(sb, usb1, usb3);
	uspi->s_interleave = fs32_to_cpu(sb, usb1->fs_interleave);
	uspi->s_trackskew = fs32_to_cpu(sb, usb1->fs_trackskew);

	if (uspi->fs_magic == UFS2_MAGIC)
		uspi->s_csaddr = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_csaddr);
	else
		uspi->s_csaddr = fs32_to_cpu(sb, usb1->fs_csaddr);

	uspi->s_cssize = fs32_to_cpu(sb, usb1->fs_cssize);
	uspi->s_cgsize = fs32_to_cpu(sb, usb1->fs_cgsize);
	uspi->s_ntrak = fs32_to_cpu(sb, usb1->fs_ntrak);
	uspi->s_nsect = fs32_to_cpu(sb, usb1->fs_nsect);
	uspi->s_spc = fs32_to_cpu(sb, usb1->fs_spc);
	uspi->s_ipg = fs32_to_cpu(sb, usb1->fs_ipg);
	uspi->s_fpg = fs32_to_cpu(sb, usb1->fs_fpg);
	uspi->s_cpc = fs32_to_cpu(sb, usb2->fs_un.fs_u1.fs_cpc);
	uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_contigsumsize);
	uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3);
	uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3);
	uspi->s_nrpos = fs32_to_cpu(sb, usb3->fs_nrpos);
	uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
	uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);

	/*
	 * Compute another frequently used values
	 */
	uspi->s_fpbmask = uspi->s_fpb - 1;
	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
		uspi->s_apbshift = uspi->s_bshift - 3;
	else
		uspi->s_apbshift = uspi->s_bshift - 2;

	uspi->s_2apbshift = uspi->s_apbshift * 2;
	uspi->s_3apbshift = uspi->s_apbshift * 3;
	uspi->s_apb = 1 << uspi->s_apbshift;
	uspi->s_2apb = 1 << uspi->s_2apbshift;
	uspi->s_3apb = 1 << uspi->s_3apbshift;
	uspi->s_apbmask = uspi->s_apb - 1;
	uspi->s_nspfshift = uspi->s_fshift - UFS_SECTOR_BITS;
	uspi->s_nspb = uspi->s_nspf << uspi->s_fpbshift;
	uspi->s_inopf = uspi->s_inopb >> uspi->s_fpbshift;
	uspi->s_bpf = uspi->s_fsize << 3;
	uspi->s_bpfshift = uspi->s_fshift + 3;
	uspi->s_bpfmask = uspi->s_bpf - 1;
	if ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_44BSD ||
	    (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_UFS2)
		uspi->s_maxsymlinklen =
		    fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen);

	if (uspi->fs_magic == UFS2_MAGIC)
		maxsymlen = 2 * 4 * (UFS_NDADDR + UFS_NINDIR);
	else
		maxsymlen = 4 * (UFS_NDADDR + UFS_NINDIR);
	if (uspi->s_maxsymlinklen > maxsymlen) {
		ufs_warning(sb, __func__, "ufs_read_super: excessive maximum "
			    "fast symlink size (%u)\n", uspi->s_maxsymlinklen);
		uspi->s_maxsymlinklen = maxsymlen;
	}
	sb->s_max_links = UFS_LINK_MAX;

	inode = ufs_iget(sb, UFS_ROOTINO);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		goto failed;
	}
	sb->s_root = d_make_root(inode);
	if (!sb->s_root) {
		ret = -ENOMEM;
		goto failed;
	}

	ufs_setup_cstotal(sb);
	/*
	 * Read cylinder group structures
	 */
	if (!(sb->s_flags & MS_RDONLY))
		if (!ufs_read_cylinder_structures(sb))
			goto failed;

	UFSD("EXIT\n");
	return 0;

failed:
	if (ubh)
		ubh_brelse_uspi (uspi);
	kfree (uspi);
	kfree(sbi);
	sb->s_fs_info = NULL;
	UFSD("EXIT (FAILED)\n");
	return ret;

failed_nomem:
	UFSD("EXIT (NOMEM)\n");
	return -ENOMEM;
}
示例#19
0
static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno,
			       u64 goal, unsigned count, int *err)
{
	struct super_block * sb;
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	struct ufs_cg_private_info * ucpi;
	struct ufs_cylinder_group * ucg;
	unsigned oldcg, i, j, k, allocsize;
	u64 result;
	
	UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n",
	     inode->i_ino, cgno, (unsigned long long)goal, count);

	sb = inode->i_sb;
	uspi = UFS_SB(sb)->s_uspi;
	usb1 = ubh_get_usb_first(uspi);
	oldcg = cgno;
	
	/*
	 * 1. searching on preferred cylinder group
	 */
	UFS_TEST_FREE_SPACE_CG

	/*
	 * 2. quadratic rehash
	 */
	for (j = 1; j < uspi->s_ncg; j *= 2) {
		cgno += j;
		if (cgno >= uspi->s_ncg) 
			cgno -= uspi->s_ncg;
		UFS_TEST_FREE_SPACE_CG
	}

	/*
	 * 3. brute force search
	 * We start at i = 2 ( 0 is checked at 1.step, 1 at 2.step )
	 */
	cgno = (oldcg + 1) % uspi->s_ncg;
	for (j = 2; j < uspi->s_ncg; j++) {
		cgno++;
		if (cgno >= uspi->s_ncg)
			cgno = 0;
		UFS_TEST_FREE_SPACE_CG
	}
	
	UFSD("EXIT (FAILED)\n");
	return 0;

cg_found:
	ucpi = ufs_load_cylinder (sb, cgno);
	if (!ucpi)
		return 0;
	ucg = ubh_get_ucg (UCPI_UBH(ucpi));
	if (!ufs_cg_chkmagic(sb, ucg)) 
		ufs_panic (sb, "ufs_alloc_fragments",
			"internal error, bad magic number on cg %u", cgno);
	ucg->cg_time = cpu_to_fs32(sb, get_seconds());

	if (count == uspi->s_fpb) {
		result = ufs_alloccg_block (inode, ucpi, goal, err);
		if (result == INVBLOCK)
			return 0;
		goto succed;
	}

	for (allocsize = count; allocsize < uspi->s_fpb; allocsize++)
		if (fs32_to_cpu(sb, ucg->cg_frsum[allocsize]) != 0)
			break;
	
	if (allocsize == uspi->s_fpb) {
		result = ufs_alloccg_block (inode, ucpi, goal, err);
		if (result == INVBLOCK)
			return 0;
		goal = ufs_dtogd(uspi, result);
		for (i = count; i < uspi->s_fpb; i++)
			ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i);
		i = uspi->s_fpb - count;
		DQUOT_FREE_BLOCK(inode, i);

		fs32_add(sb, &ucg->cg_cs.cs_nffree, i);
		uspi->cs_total.cs_nffree += i;
		fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i);
		fs32_add(sb, &ucg->cg_frsum[i], 1);
		goto succed;
	}

	result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
	if (result == INVBLOCK)
		return 0;
	if(DQUOT_ALLOC_BLOCK(inode, count)) {
		*err = -EDQUOT;
		return 0;
	}
	for (i = 0; i < count; i++)
		ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i);
	
	fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);
	uspi->cs_total.cs_nffree -= count;
	fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
	fs32_sub(sb, &ucg->cg_frsum[allocsize], 1);

	if (count != allocsize)
		fs32_add(sb, &ucg->cg_frsum[allocsize - count], 1);

succed:
	ubh_mark_buffer_dirty (USPI_UBH(uspi));
	ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
	if (sb->s_flags & MS_SYNCHRONOUS) {
		ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
		ubh_wait_on_buffer (UCPI_UBH(ucpi));
	}
	mark_sb_dirty(sb);

	result += cgno * uspi->s_fpg;
	UFSD("EXIT3, result %llu\n", (unsigned long long)result);
	return result;
}
示例#20
0
文件: super.c 项目: xricson/knoppix
/*
 * Print contents of ufs_super_block, useful for debugging
 */
void ufs_print_super_stuff(struct super_block *sb,
	struct ufs_super_block_first * usb1,
	struct ufs_super_block_second * usb2, 
	struct ufs_super_block_third * usb3)
{
	printk("ufs_print_super_stuff\n");
	printk("size of usb:     %u\n", sizeof(struct ufs_super_block));
	printk("  magic:         0x%x\n", fs32_to_cpu(sb, usb3->fs_magic));
	printk("  sblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_sblkno));
	printk("  cblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_cblkno));
	printk("  iblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_iblkno));
	printk("  dblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_dblkno));
	printk("  cgoffset:      %u\n", fs32_to_cpu(sb, usb1->fs_cgoffset));
	printk("  ~cgmask:       0x%x\n", ~fs32_to_cpu(sb, usb1->fs_cgmask));
	printk("  size:          %u\n", fs32_to_cpu(sb, usb1->fs_size));
	printk("  dsize:         %u\n", fs32_to_cpu(sb, usb1->fs_dsize));
	printk("  ncg:           %u\n", fs32_to_cpu(sb, usb1->fs_ncg));
	printk("  bsize:         %u\n", fs32_to_cpu(sb, usb1->fs_bsize));
	printk("  fsize:         %u\n", fs32_to_cpu(sb, usb1->fs_fsize));
	printk("  frag:          %u\n", fs32_to_cpu(sb, usb1->fs_frag));
	printk("  fragshift:     %u\n", fs32_to_cpu(sb, usb1->fs_fragshift));
	printk("  ~fmask:        %u\n", ~fs32_to_cpu(sb, usb1->fs_fmask));
	printk("  fshift:        %u\n", fs32_to_cpu(sb, usb1->fs_fshift));
	printk("  sbsize:        %u\n", fs32_to_cpu(sb, usb1->fs_sbsize));
	printk("  spc:           %u\n", fs32_to_cpu(sb, usb1->fs_spc));
	printk("  cpg:           %u\n", fs32_to_cpu(sb, usb1->fs_cpg));
	printk("  ipg:           %u\n", fs32_to_cpu(sb, usb1->fs_ipg));
	printk("  fpg:           %u\n", fs32_to_cpu(sb, usb1->fs_fpg));
	printk("  csaddr:        %u\n", fs32_to_cpu(sb, usb1->fs_csaddr));
	printk("  cssize:        %u\n", fs32_to_cpu(sb, usb1->fs_cssize));
	printk("  cgsize:        %u\n", fs32_to_cpu(sb, usb1->fs_cgsize));
	printk("  fstodb:        %u\n", fs32_to_cpu(sb, usb1->fs_fsbtodb));
	printk("  contigsumsize: %d\n", fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize));
	printk("  postblformat:  %u\n", fs32_to_cpu(sb, usb3->fs_postblformat));
	printk("  nrpos:         %u\n", fs32_to_cpu(sb, usb3->fs_nrpos));
	printk("  ndir           %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir));
	printk("  nifree         %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree));
	printk("  nbfree         %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree));
	printk("  nffree         %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree));
	printk("\n");
}
示例#21
0
void
befs_dump_inode(const struct super_block *sb, befs_inode * inode)
{
#ifdef CONFIG_BEFS_DEBUG

	befs_block_run tmp_run;

	befs_debug(sb, "befs_inode information");

	befs_debug(sb, "  magic1 %08x", fs32_to_cpu(sb, inode->magic1));

	tmp_run = fsrun_to_cpu(sb, inode->inode_num);
	befs_debug(sb, "  inode_num %u, %hu, %hu",
		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);

	befs_debug(sb, "  uid %u", fs32_to_cpu(sb, inode->uid));
	befs_debug(sb, "  gid %u", fs32_to_cpu(sb, inode->gid));
	befs_debug(sb, "  mode %08x", fs32_to_cpu(sb, inode->mode));
	befs_debug(sb, "  flags %08x", fs32_to_cpu(sb, inode->flags));
	befs_debug(sb, "  create_time %Lu",
		   fs64_to_cpu(sb, inode->create_time));
	befs_debug(sb, "  last_modified_time %Lu",
		   fs64_to_cpu(sb, inode->last_modified_time));

	tmp_run = fsrun_to_cpu(sb, inode->parent);
	befs_debug(sb, "  parent [%u, %hu, %hu]",
		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);

	tmp_run = fsrun_to_cpu(sb, inode->attributes);
	befs_debug(sb, "  attributes [%u, %hu, %hu]",
		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);

	befs_debug(sb, "  type %08x", fs32_to_cpu(sb, inode->type));
	befs_debug(sb, "  inode_size %u", fs32_to_cpu(sb, inode->inode_size));

	if (S_ISLNK(inode->mode)) {
		befs_debug(sb, "  Symbolic link [%s]", inode->data.symlink);
	} else {
		int i;

		for (i = 0; i < BEFS_NUM_DIRECT_BLOCKS; i++) {
			tmp_run =
			    fsrun_to_cpu(sb, inode->data.datastream.direct[i]);
			befs_debug(sb, "  direct %d [%u, %hu, %hu]", i,
				   tmp_run.allocation_group, tmp_run.start,
				   tmp_run.len);
		}
		befs_debug(sb, "  max_direct_range %Lu",
			   fs64_to_cpu(sb,
				       inode->data.datastream.
				       max_direct_range));

		tmp_run = fsrun_to_cpu(sb, inode->data.datastream.indirect);
		befs_debug(sb, "  indirect [%u, %hu, %hu]",
			   tmp_run.allocation_group,
			   tmp_run.start, tmp_run.len);

		befs_debug(sb, "  max_indirect_range %Lu",
			   fs64_to_cpu(sb,
				       inode->data.datastream.
				       max_indirect_range));

		tmp_run =
		    fsrun_to_cpu(sb, inode->data.datastream.double_indirect);
		befs_debug(sb, "  double indirect [%u, %hu, %hu]",
			   tmp_run.allocation_group, tmp_run.start,
			   tmp_run.len);

		befs_debug(sb, "  max_double_indirect_range %Lu",
			   fs64_to_cpu(sb,
				       inode->data.datastream.
				       max_double_indirect_range));

		befs_debug(sb, "  size %Lu",
			   fs64_to_cpu(sb, inode->data.datastream.size));
	}

#endif				//CONFIG_BEFS_DEBUG
}
示例#22
0
文件: ialloc.c 项目: 274914765/C
/*
 * There are two policies for allocating an inode.  If the new inode is
 * a directory, then a forward search is made for a block group with both
 * free space and a low directory-to-inode ratio; if that fails, then of
 * the groups with above-average free space, that group with the fewest
 * directories already is chosen.
 *
 * For other inodes, search forward from the parent directory's block
 * group to find a free inode.
 */
struct inode * ufs_new_inode(struct inode * dir, int mode)
{
    struct super_block * sb;
    struct ufs_sb_info * sbi;
    struct ufs_sb_private_info * uspi;
    struct ufs_super_block_first * usb1;
    struct ufs_cg_private_info * ucpi;
    struct ufs_cylinder_group * ucg;
    struct inode * inode;
    unsigned cg, bit, i, j, start;
    struct ufs_inode_info *ufsi;
    int err = -ENOSPC;

    UFSD("ENTER\n");
    
    /* Cannot create files in a deleted directory */
    if (!dir || !dir->i_nlink)
        return ERR_PTR(-EPERM);
    sb = dir->i_sb;
    inode = new_inode(sb);
    if (!inode)
        return ERR_PTR(-ENOMEM);
    ufsi = UFS_I(inode);
    sbi = UFS_SB(sb);
    uspi = sbi->s_uspi;
    usb1 = ubh_get_usb_first(uspi);

    lock_super (sb);

    /*
     * Try to place the inode in its parent directory
     */
    i = ufs_inotocg(dir->i_ino);
    if (sbi->fs_cs(i).cs_nifree) {
        cg = i;
        goto cg_found;
    }

    /*
     * Use a quadratic hash to find a group with a free inode
     */
    for ( j = 1; j < uspi->s_ncg; j <<= 1 ) {
        i += j;
        if (i >= uspi->s_ncg)
            i -= uspi->s_ncg;
        if (sbi->fs_cs(i).cs_nifree) {
            cg = i;
            goto cg_found;
        }
    }

    /*
     * That failed: try linear search for a free inode
     */
    i = ufs_inotocg(dir->i_ino) + 1;
    for (j = 2; j < uspi->s_ncg; j++) {
        i++;
        if (i >= uspi->s_ncg)
            i = 0;
        if (sbi->fs_cs(i).cs_nifree) {
            cg = i;
            goto cg_found;
        }
    }

    goto failed;

cg_found:
    ucpi = ufs_load_cylinder (sb, cg);
    if (!ucpi) {
        err = -EIO;
        goto failed;
    }
    ucg = ubh_get_ucg(UCPI_UBH(ucpi));
    if (!ufs_cg_chkmagic(sb, ucg)) 
        ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number");

    start = ucpi->c_irotor;
    bit = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_iusedoff, uspi->s_ipg, start);
    if (!(bit < uspi->s_ipg)) {
        bit = ubh_find_first_zero_bit (UCPI_UBH(ucpi), ucpi->c_iusedoff, start);
        if (!(bit < start)) {
            ufs_error (sb, "ufs_new_inode",
                "cylinder group %u corrupted - error in inode bitmap\n", cg);
            err = -EIO;
            goto failed;
        }
    }
    UFSD("start = %u, bit = %u, ipg = %u\n", start, bit, uspi->s_ipg);
    if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit))
        ubh_setbit (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit);
    else {
        ufs_panic (sb, "ufs_new_inode", "internal error");
        err = -EIO;
        goto failed;
    }

    if (uspi->fs_magic == UFS2_MAGIC) {
        u32 initediblk = fs32_to_cpu(sb, ucg->cg_u.cg_u2.cg_initediblk);

        if (bit + uspi->s_inopb > initediblk &&
            initediblk < fs32_to_cpu(sb, ucg->cg_u.cg_u2.cg_niblk))
            ufs2_init_inodes_chunk(sb, ucpi, ucg);
    }

    fs32_sub(sb, &ucg->cg_cs.cs_nifree, 1);
    uspi->cs_total.cs_nifree--;
    fs32_sub(sb, &sbi->fs_cs(cg).cs_nifree, 1);
    
    if (S_ISDIR(mode)) {
        fs32_add(sb, &ucg->cg_cs.cs_ndir, 1);
        uspi->cs_total.cs_ndir++;
        fs32_add(sb, &sbi->fs_cs(cg).cs_ndir, 1);
    }
    ubh_mark_buffer_dirty (USPI_UBH(uspi));
    ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
    if (sb->s_flags & MS_SYNCHRONOUS) {
        ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
        ubh_wait_on_buffer (UCPI_UBH(ucpi));
    }
    sb->s_dirt = 1;

    inode->i_ino = cg * uspi->s_ipg + bit;
    inode->i_mode = mode;
    inode->i_uid = current->fsuid;
    if (dir->i_mode & S_ISGID) {
        inode->i_gid = dir->i_gid;
        if (S_ISDIR(mode))
            inode->i_mode |= S_ISGID;
    } else
        inode->i_gid = current->fsgid;

    inode->i_blocks = 0;
    inode->i_generation = 0;
    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
    ufsi->i_flags = UFS_I(dir)->i_flags;
    ufsi->i_lastfrag = 0;
    ufsi->i_shadow = 0;
    ufsi->i_osync = 0;
    ufsi->i_oeftflag = 0;
    ufsi->i_dir_start_lookup = 0;
    memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1));
    insert_inode_hash(inode);
    mark_inode_dirty(inode);

    if (uspi->fs_magic == UFS2_MAGIC) {
        struct buffer_head *bh;
        struct ufs2_inode *ufs2_inode;

        /*
         * setup birth date, we do it here because of there is no sense
         * to hold it in struct ufs_inode_info, and lose 64 bit
         */
        bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino));
        if (!bh) {
            ufs_warning(sb, "ufs_read_inode",
                    "unable to read inode %lu\n",
                    inode->i_ino);
            err = -EIO;
            goto fail_remove_inode;
        }
        lock_buffer(bh);
        ufs2_inode = (struct ufs2_inode *)bh->b_data;
        ufs2_inode += ufs_inotofsbo(inode->i_ino);
        ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec);
        ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, CURRENT_TIME.tv_nsec);
        mark_buffer_dirty(bh);
        unlock_buffer(bh);
        if (sb->s_flags & MS_SYNCHRONOUS)
            sync_dirty_buffer(bh);
        brelse(bh);
    }

    unlock_super (sb);

    if (DQUOT_ALLOC_INODE(inode)) {
        DQUOT_DROP(inode);
        err = -EDQUOT;
        goto fail_without_unlock;
    }

    UFSD("allocating inode %lu\n", inode->i_ino);
    UFSD("EXIT\n");
    return inode;

fail_remove_inode:
    unlock_super(sb);
fail_without_unlock:
    inode->i_flags |= S_NOQUOTA;
    inode->i_nlink = 0;
    iput(inode);
    UFSD("EXIT (FAILED): err %d\n", err);
    return ERR_PTR(err);
failed:
    unlock_super (sb);
    make_bad_inode(inode);
    iput (inode);
    UFSD("EXIT (FAILED): err %d\n", err);
    return ERR_PTR(err);
}
示例#23
0
/*
 * Print contents of ufs_super_block, useful for debugging
 */
static void ufs_print_super_stuff(struct super_block *sb,
				  struct ufs_super_block_first *usb1,
				  struct ufs_super_block_second *usb2,
				  struct ufs_super_block_third *usb3)
{
	u32 magic = fs32_to_cpu(sb, usb3->fs_magic);

	pr_debug("ufs_print_super_stuff\n");
	pr_debug("  magic:     0x%x\n", magic);
	if (fs32_to_cpu(sb, usb3->fs_magic) == UFS2_MAGIC) {
		pr_debug("  fs_size:   %llu\n", (unsigned long long)
			 fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size));
		pr_debug("  fs_dsize:  %llu\n", (unsigned long long)
			 fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize));
		pr_debug("  bsize:         %u\n",
			 fs32_to_cpu(sb, usb1->fs_bsize));
		pr_debug("  fsize:         %u\n",
			 fs32_to_cpu(sb, usb1->fs_fsize));
		pr_debug("  fs_volname:  %s\n", usb2->fs_un.fs_u2.fs_volname);
		pr_debug("  fs_sblockloc: %llu\n", (unsigned long long)
			 fs64_to_cpu(sb, usb2->fs_un.fs_u2.fs_sblockloc));
		pr_debug("  cs_ndir(No of dirs):  %llu\n", (unsigned long long)
			 fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir));
		pr_debug("  cs_nbfree(No of free blocks):  %llu\n",
			 (unsigned long long)
			 fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree));
		pr_info("  cs_nifree(Num of free inodes): %llu\n",
			(unsigned long long)
			fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree));
		pr_info("  cs_nffree(Num of free frags): %llu\n",
			(unsigned long long)
			fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree));
		pr_info("  fs_maxsymlinklen: %u\n",
			fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen));
	} else {
		pr_debug(" sblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_sblkno));
		pr_debug(" cblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_cblkno));
		pr_debug(" iblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_iblkno));
		pr_debug(" dblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_dblkno));
		pr_debug(" cgoffset:    %u\n",
			 fs32_to_cpu(sb, usb1->fs_cgoffset));
		pr_debug(" ~cgmask:     0x%x\n",
			 ~fs32_to_cpu(sb, usb1->fs_cgmask));
		pr_debug(" size:        %u\n", fs32_to_cpu(sb, usb1->fs_size));
		pr_debug(" dsize:       %u\n", fs32_to_cpu(sb, usb1->fs_dsize));
		pr_debug(" ncg:         %u\n", fs32_to_cpu(sb, usb1->fs_ncg));
		pr_debug(" bsize:       %u\n", fs32_to_cpu(sb, usb1->fs_bsize));
		pr_debug(" fsize:       %u\n", fs32_to_cpu(sb, usb1->fs_fsize));
		pr_debug(" frag:        %u\n", fs32_to_cpu(sb, usb1->fs_frag));
		pr_debug(" fragshift:   %u\n",
			 fs32_to_cpu(sb, usb1->fs_fragshift));
		pr_debug(" ~fmask:      %u\n", ~fs32_to_cpu(sb, usb1->fs_fmask));
		pr_debug(" fshift:      %u\n", fs32_to_cpu(sb, usb1->fs_fshift));
		pr_debug(" sbsize:      %u\n", fs32_to_cpu(sb, usb1->fs_sbsize));
		pr_debug(" spc:         %u\n", fs32_to_cpu(sb, usb1->fs_spc));
		pr_debug(" cpg:         %u\n", fs32_to_cpu(sb, usb1->fs_cpg));
		pr_debug(" ipg:         %u\n", fs32_to_cpu(sb, usb1->fs_ipg));
		pr_debug(" fpg:         %u\n", fs32_to_cpu(sb, usb1->fs_fpg));
		pr_debug(" csaddr:      %u\n", fs32_to_cpu(sb, usb1->fs_csaddr));
		pr_debug(" cssize:      %u\n", fs32_to_cpu(sb, usb1->fs_cssize));
		pr_debug(" cgsize:      %u\n", fs32_to_cpu(sb, usb1->fs_cgsize));
		pr_debug(" fstodb:      %u\n",
			 fs32_to_cpu(sb, usb1->fs_fsbtodb));
		pr_debug(" nrpos:       %u\n", fs32_to_cpu(sb, usb3->fs_nrpos));
		pr_debug(" ndir         %u\n",
			 fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir));
		pr_debug(" nifree       %u\n",
			 fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree));
		pr_debug(" nbfree       %u\n",
			 fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree));
		pr_debug(" nffree       %u\n",
			 fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree));
	}
	pr_debug("\n");
}
示例#24
0
static struct dentry *ufs_get_parent(struct dentry *child)
{
	struct qstr dot_dot = {
		.name	= "..",
		.len	= 2,
	};
	ino_t ino;

	ino = ufs_inode_by_name(child->d_inode, &dot_dot);
	if (!ino)
		return ERR_PTR(-ENOENT);
	return d_obtain_alias(ufs_iget(child->d_inode->i_sb, ino));
}

static const struct export_operations ufs_export_ops = {
	.fh_to_dentry	= ufs_fh_to_dentry,
	.fh_to_parent	= ufs_fh_to_parent,
	.get_parent	= ufs_get_parent,
};

#ifdef CONFIG_UFS_DEBUG
static void ufs_print_super_stuff(struct super_block *sb,
				  struct ufs_super_block_first *usb1,
				  struct ufs_super_block_second *usb2,
				  struct ufs_super_block_third *usb3)
{
	u32 magic = fs32_to_cpu(sb, usb3->fs_magic);

	printk("ufs_print_super_stuff\n");
	printk("  magic:     0x%x\n", magic);
	if (fs32_to_cpu(sb, usb3->fs_magic) == UFS2_MAGIC) {
		printk("  fs_size:   %llu\n", (unsigned long long)
		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size));
		printk("  fs_dsize:  %llu\n", (unsigned long long)
		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize));
		printk("  bsize:         %u\n",
		       fs32_to_cpu(sb, usb1->fs_bsize));
		printk("  fsize:         %u\n",
		       fs32_to_cpu(sb, usb1->fs_fsize));
		printk("  fs_volname:  %s\n", usb2->fs_un.fs_u2.fs_volname);
		printk("  fs_sblockloc: %llu\n", (unsigned long long)
		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.fs_sblockloc));
		printk("  cs_ndir(No of dirs):  %llu\n", (unsigned long long)
		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir));
		printk("  cs_nbfree(No of free blocks):  %llu\n",
		       (unsigned long long)
		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree));
		printk(KERN_INFO"  cs_nifree(Num of free inodes): %llu\n",
		       (unsigned long long)
		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree));
		printk(KERN_INFO"  cs_nffree(Num of free frags): %llu\n",
		       (unsigned long long)
		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree));
		printk(KERN_INFO"  fs_maxsymlinklen: %u\n",
		       fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen));
	} else {
		printk(" sblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_sblkno));
		printk(" cblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_cblkno));
		printk(" iblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_iblkno));
		printk(" dblkno:      %u\n", fs32_to_cpu(sb, usb1->fs_dblkno));
		printk(" cgoffset:    %u\n",
		       fs32_to_cpu(sb, usb1->fs_cgoffset));
		printk(" ~cgmask:     0x%x\n",
		       ~fs32_to_cpu(sb, usb1->fs_cgmask));
		printk(" size:        %u\n", fs32_to_cpu(sb, usb1->fs_size));
		printk(" dsize:       %u\n", fs32_to_cpu(sb, usb1->fs_dsize));
		printk(" ncg:         %u\n", fs32_to_cpu(sb, usb1->fs_ncg));
		printk(" bsize:       %u\n", fs32_to_cpu(sb, usb1->fs_bsize));
		printk(" fsize:       %u\n", fs32_to_cpu(sb, usb1->fs_fsize));
		printk(" frag:        %u\n", fs32_to_cpu(sb, usb1->fs_frag));
		printk(" fragshift:   %u\n",
		       fs32_to_cpu(sb, usb1->fs_fragshift));
		printk(" ~fmask:      %u\n", ~fs32_to_cpu(sb, usb1->fs_fmask));
		printk(" fshift:      %u\n", fs32_to_cpu(sb, usb1->fs_fshift));
		printk(" sbsize:      %u\n", fs32_to_cpu(sb, usb1->fs_sbsize));
		printk(" spc:         %u\n", fs32_to_cpu(sb, usb1->fs_spc));
		printk(" cpg:         %u\n", fs32_to_cpu(sb, usb1->fs_cpg));
		printk(" ipg:         %u\n", fs32_to_cpu(sb, usb1->fs_ipg));
		printk(" fpg:         %u\n", fs32_to_cpu(sb, usb1->fs_fpg));
		printk(" csaddr:      %u\n", fs32_to_cpu(sb, usb1->fs_csaddr));
		printk(" cssize:      %u\n", fs32_to_cpu(sb, usb1->fs_cssize));
		printk(" cgsize:      %u\n", fs32_to_cpu(sb, usb1->fs_cgsize));
		printk(" fstodb:      %u\n",
		       fs32_to_cpu(sb, usb1->fs_fsbtodb));
		printk(" nrpos:       %u\n", fs32_to_cpu(sb, usb3->fs_nrpos));
		printk(" ndir         %u\n",
		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir));
		printk(" nifree       %u\n",
		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree));
		printk(" nbfree       %u\n",
		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree));
		printk(" nffree       %u\n",
		       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree));
	}
	printk("\n");
}
示例#25
0
/*
 * Print contents of ufs_cylinder_group, useful for debugging
 */
static void ufs_print_cylinder_stuff(struct super_block *sb,
				     struct ufs_cylinder_group *cg)
{
	pr_debug("\nufs_print_cylinder_stuff\n");
	pr_debug("size of ucg: %zu\n", sizeof(struct ufs_cylinder_group));
	pr_debug("  magic:        %x\n", fs32_to_cpu(sb, cg->cg_magic));
	pr_debug("  time:         %u\n", fs32_to_cpu(sb, cg->cg_time));
	pr_debug("  cgx:          %u\n", fs32_to_cpu(sb, cg->cg_cgx));
	pr_debug("  ncyl:         %u\n", fs16_to_cpu(sb, cg->cg_ncyl));
	pr_debug("  niblk:        %u\n", fs16_to_cpu(sb, cg->cg_niblk));
	pr_debug("  ndblk:        %u\n", fs32_to_cpu(sb, cg->cg_ndblk));
	pr_debug("  cs_ndir:      %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_ndir));
	pr_debug("  cs_nbfree:    %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_nbfree));
	pr_debug("  cs_nifree:    %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_nifree));
	pr_debug("  cs_nffree:    %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_nffree));
	pr_debug("  rotor:        %u\n", fs32_to_cpu(sb, cg->cg_rotor));
	pr_debug("  frotor:       %u\n", fs32_to_cpu(sb, cg->cg_frotor));
	pr_debug("  irotor:       %u\n", fs32_to_cpu(sb, cg->cg_irotor));
	pr_debug("  frsum:        %u, %u, %u, %u, %u, %u, %u, %u\n",
	    fs32_to_cpu(sb, cg->cg_frsum[0]), fs32_to_cpu(sb, cg->cg_frsum[1]),
	    fs32_to_cpu(sb, cg->cg_frsum[2]), fs32_to_cpu(sb, cg->cg_frsum[3]),
	    fs32_to_cpu(sb, cg->cg_frsum[4]), fs32_to_cpu(sb, cg->cg_frsum[5]),
	    fs32_to_cpu(sb, cg->cg_frsum[6]), fs32_to_cpu(sb, cg->cg_frsum[7]));
	pr_debug("  btotoff:      %u\n", fs32_to_cpu(sb, cg->cg_btotoff));
	pr_debug("  boff:         %u\n", fs32_to_cpu(sb, cg->cg_boff));
	pr_debug("  iuseoff:      %u\n", fs32_to_cpu(sb, cg->cg_iusedoff));
	pr_debug("  freeoff:      %u\n", fs32_to_cpu(sb, cg->cg_freeoff));
	pr_debug("  nextfreeoff:  %u\n", fs32_to_cpu(sb, cg->cg_nextfreeoff));
	pr_debug("  clustersumoff %u\n",
		 fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clustersumoff));
	pr_debug("  clusteroff    %u\n",
		 fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clusteroff));
	pr_debug("  nclusterblks  %u\n",
		 fs32_to_cpu(sb, cg->cg_u.cg_44.cg_nclusterblks));
	pr_debug("\n");
}
示例#26
0
static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
{
	struct buffer_head *bh = NULL;
	befs_inode *raw_inode = NULL;

	befs_sb_info *befs_sb = BEFS_SB(sb);
	befs_inode_info *befs_ino = NULL;
	struct inode *inode;
	long ret = -EIO;

	befs_debug(sb, "---> befs_read_inode() " "inode = %lu", ino);

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

	befs_ino = BEFS_I(inode);

	/* convert from vfs's inode number to befs's inode number */
	befs_ino->i_inode_num = blockno2iaddr(sb, inode->i_ino);

	befs_debug(sb, "  real inode number [%u, %hu, %hu]",
		   befs_ino->i_inode_num.allocation_group,
		   befs_ino->i_inode_num.start, befs_ino->i_inode_num.len);

	bh = befs_bread(sb, inode->i_ino);
	if (!bh) {
		befs_error(sb, "unable to read inode block - "
			   "inode = %lu", inode->i_ino);
		goto unacquire_none;
	}

	raw_inode = (befs_inode *) bh->b_data;

	befs_dump_inode(sb, raw_inode);

	if (befs_check_inode(sb, raw_inode, inode->i_ino) != BEFS_OK) {
		befs_error(sb, "Bad inode: %lu", inode->i_ino);
		goto unacquire_bh;
	}

	inode->i_mode = (umode_t) fs32_to_cpu(sb, raw_inode->mode);

	/*
	 * set uid and gid.  But since current BeOS is single user OS, so
	 * you can change by "uid" or "gid" options.
	 */   

	inode->i_uid = befs_sb->mount_opts.use_uid ?
		befs_sb->mount_opts.uid :
		make_kuid(&init_user_ns, fs32_to_cpu(sb, raw_inode->uid));
	inode->i_gid = befs_sb->mount_opts.use_gid ?
		befs_sb->mount_opts.gid :
		make_kgid(&init_user_ns, fs32_to_cpu(sb, raw_inode->gid));

	set_nlink(inode, 1);

	/*
	 * BEFS's time is 64 bits, but current VFS is 32 bits...
	 * BEFS don't have access time. Nor inode change time. VFS
	 * doesn't have creation time.
	 * Also, the lower 16 bits of the last_modified_time and 
	 * create_time are just a counter to help ensure uniqueness
	 * for indexing purposes. (PFD, page 54)
	 */

	inode->i_mtime.tv_sec =
	    fs64_to_cpu(sb, raw_inode->last_modified_time) >> 16;
	inode->i_mtime.tv_nsec = 0;   /* lower 16 bits are not a time */	
	inode->i_ctime = inode->i_mtime;
	inode->i_atime = inode->i_mtime;

	befs_ino->i_inode_num = fsrun_to_cpu(sb, raw_inode->inode_num);
	befs_ino->i_parent = fsrun_to_cpu(sb, raw_inode->parent);
	befs_ino->i_attribute = fsrun_to_cpu(sb, raw_inode->attributes);
	befs_ino->i_flags = fs32_to_cpu(sb, raw_inode->flags);

	if (S_ISLNK(inode->i_mode) && !(befs_ino->i_flags & BEFS_LONG_SYMLINK)){
		inode->i_size = 0;
		inode->i_blocks = befs_sb->block_size / VFS_BLOCK_SIZE;
		strncpy(befs_ino->i_data.symlink, raw_inode->data.symlink,
			BEFS_SYMLINK_LEN - 1);
		befs_ino->i_data.symlink[BEFS_SYMLINK_LEN - 1] = '\0';
	} else {
		int num_blks;

		befs_ino->i_data.ds =
		    fsds_to_cpu(sb, &raw_inode->data.datastream);

		num_blks = befs_count_blocks(sb, &befs_ino->i_data.ds);
		inode->i_blocks =
		    num_blks * (befs_sb->block_size / VFS_BLOCK_SIZE);
		inode->i_size = befs_ino->i_data.ds.size;
	}

	inode->i_mapping->a_ops = &befs_aops;

	if (S_ISREG(inode->i_mode)) {
		inode->i_fop = &generic_ro_fops;
	} else if (S_ISDIR(inode->i_mode)) {
		inode->i_op = &befs_dir_inode_operations;
		inode->i_fop = &befs_dir_operations;
	} else if (S_ISLNK(inode->i_mode)) {
		if (befs_ino->i_flags & BEFS_LONG_SYMLINK)
			inode->i_op = &befs_symlink_inode_operations;
		else
			inode->i_op = &befs_fast_symlink_inode_operations;
	} else {
		befs_error(sb, "Inode %lu is not a regular file, "
			   "directory or symlink. THAT IS WRONG! BeFS has no "
			   "on disk special files", inode->i_ino);
		goto unacquire_bh;
	}

	brelse(bh);
	befs_debug(sb, "<--- befs_read_inode()");
	unlock_new_inode(inode);
	return inode;

      unacquire_bh:
	brelse(bh);

      unacquire_none:
	iget_failed(inode);
	befs_debug(sb, "<--- befs_read_inode() - Bad inode");
	return ERR_PTR(ret);
}
示例#27
0
u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
			   u64 goal, unsigned count, int *err,
			   struct page *locked_page)
{
	struct super_block * sb;
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	unsigned cgno, oldcount, newcount;
	u64 tmp, request, result;
	
	UFSD("ENTER, ino %lu, fragment %llu, goal %llu, count %u\n",
	     inode->i_ino, (unsigned long long)fragment,
	     (unsigned long long)goal, count);
	
	sb = inode->i_sb;
	uspi = UFS_SB(sb)->s_uspi;
	usb1 = ubh_get_usb_first(uspi);
	*err = -ENOSPC;

	lock_super (sb);
	tmp = ufs_data_ptr_to_cpu(sb, p);

	if (count + ufs_fragnum(fragment) > uspi->s_fpb) {
		ufs_warning(sb, "ufs_new_fragments", "internal warning"
			    " fragment %llu, count %u",
			    (unsigned long long)fragment, count);
		count = uspi->s_fpb - ufs_fragnum(fragment); 
	}
	oldcount = ufs_fragnum (fragment);
	newcount = oldcount + count;

	/*
	 * Somebody else has just allocated our fragments
	 */
	if (oldcount) {
		if (!tmp) {
			ufs_error(sb, "ufs_new_fragments", "internal error, "
				  "fragment %llu, tmp %llu\n",
				  (unsigned long long)fragment,
				  (unsigned long long)tmp);
			unlock_super(sb);
			return INVBLOCK;
		}
		if (fragment < UFS_I(inode)->i_lastfrag) {
			UFSD("EXIT (ALREADY ALLOCATED)\n");
			unlock_super (sb);
			return 0;
		}
	}
	else {
		if (tmp) {
			UFSD("EXIT (ALREADY ALLOCATED)\n");
			unlock_super(sb);
			return 0;
		}
	}

	/*
	 * There is not enough space for user on the device
	 */
	if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) {
		unlock_super (sb);
		UFSD("EXIT (FAILED)\n");
		return 0;
	}

	if (goal >= uspi->s_size) 
		goal = 0;
	if (goal == 0) 
		cgno = ufs_inotocg (inode->i_ino);
	else
		cgno = ufs_dtog(uspi, goal);
	 
	/*
	 * allocate new fragment
	 */
	if (oldcount == 0) {
		result = ufs_alloc_fragments (inode, cgno, goal, count, err);
		if (result) {
			ufs_cpu_to_data_ptr(sb, p, result);
			*err = 0;
			UFS_I(inode)->i_lastfrag =
				max_t(u32, UFS_I(inode)->i_lastfrag,
				      fragment + count);
			ufs_clear_frags(inode, result + oldcount,
					newcount - oldcount, locked_page != NULL);
		}
		unlock_super(sb);
		UFSD("EXIT, result %llu\n", (unsigned long long)result);
		return result;
	}

	/*
	 * resize block
	 */
	result = ufs_add_fragments (inode, tmp, oldcount, newcount, err);
	if (result) {
		*err = 0;
		UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
		ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
				locked_page != NULL);
		unlock_super(sb);
		UFSD("EXIT, result %llu\n", (unsigned long long)result);
		return result;
	}

	/*
	 * allocate new block and move data
	 */
	switch (fs32_to_cpu(sb, usb1->fs_optim)) {
	    case UFS_OPTSPACE:
		request = newcount;
		if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree
		    > uspi->s_dsize * uspi->s_minfree / (2 * 100))
			break;
		usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
		break;
	    default:
		usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
	
	    case UFS_OPTTIME:
		request = uspi->s_fpb;
		if (uspi->cs_total.cs_nffree < uspi->s_dsize *
		    (uspi->s_minfree - 2) / 100)
			break;
		usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
		break;
	}
	result = ufs_alloc_fragments (inode, cgno, goal, request, err);
	if (result) {
		ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
				locked_page != NULL);
		ufs_change_blocknr(inode, fragment - oldcount, oldcount,
				   uspi->s_sbbase + tmp,
				   uspi->s_sbbase + result, locked_page);
		ufs_cpu_to_data_ptr(sb, p, result);
		*err = 0;
		UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
		unlock_super(sb);
		if (newcount < request)
			ufs_free_fragments (inode, result + newcount, request - newcount);
		ufs_free_fragments (inode, tmp, oldcount);
		UFSD("EXIT, result %llu\n", (unsigned long long)result);
		return result;
	}

	unlock_super(sb);
	UFSD("EXIT (FAILED)\n");
	return 0;
}		
示例#28
0
文件: super.c 项目: xricson/knoppix
static int ufs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct ufs_sb_info * sbi;
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	struct ufs_super_block_second * usb2;
	struct ufs_super_block_third * usb3;
	struct ufs_buffer_head * ubh;	
	struct inode *inode;
	unsigned block_size, super_block_size;
	unsigned flags;

	uspi = NULL;
	ubh = NULL;
	flags = 0;
	
	UFSD(("ENTER\n"))
		
	sbi = kmalloc(sizeof(struct ufs_sb_info), GFP_KERNEL);
	if (!sbi)
		goto failed_nomem;
	sb->s_fs_info = sbi;
	memset(sbi, 0, sizeof(struct ufs_sb_info));

	UFSD(("flag %u\n", (int)(sb->s_flags & MS_RDONLY)))
	
#ifndef CONFIG_UFS_FS_WRITE
	if (!(sb->s_flags & MS_RDONLY)) {
		printk("ufs was compiled with read-only support, "
		"can't be mounted as read-write\n");
		goto failed;
	}
#endif
	/*
	 * Set default mount options
	 * Parse mount options
	 */
	sbi->s_mount_opt = 0;
	ufs_set_opt (sbi->s_mount_opt, ONERROR_LOCK);
	if (!ufs_parse_options ((char *) data, &sbi->s_mount_opt)) {
		printk("wrong mount options\n");
		goto failed;
	}
	if (!(sbi->s_mount_opt & UFS_MOUNT_UFSTYPE)) {
		printk("You didn't specify the type of your ufs filesystem\n\n"
		"mount -t ufs -o ufstype="
		"sun|sunx86|44bsd|old|hp|nextstep|netxstep-cd|openstep ...\n\n"
		">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
		"default is ufstype=old\n");
		ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);
	}

	sbi->s_uspi = uspi =
		kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL);
	if (!uspi)
		goto failed;

	/* Keep 2Gig file limit. Some UFS variants need to override 
	   this but as I don't know which I'll let those in the know loosen
	   the rules */
	   
	switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {
	case UFS_MOUNT_UFSTYPE_44BSD:
		UFSD(("ufstype=44bsd\n"))
		uspi->s_fsize = block_size = 512;
		uspi->s_fmask = ~(512 - 1);
		uspi->s_fshift = 9;
		uspi->s_sbsize = super_block_size = 1536;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
		break;
		
	case UFS_MOUNT_UFSTYPE_SUN:
		UFSD(("ufstype=sun\n"))
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_maxsymlinklen = 56;
		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
		break;

	case UFS_MOUNT_UFSTYPE_SUNx86:
		UFSD(("ufstype=sunx86\n"))
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		uspi->s_maxsymlinklen = 56;
		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;
		break;

	case UFS_MOUNT_UFSTYPE_OLD:
		UFSD(("ufstype=old\n"))
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			printk(KERN_INFO "ufstype=old is supported read-only\n"); 
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_NEXTSTEP:
		UFSD(("ufstype=nextstep\n"))
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			printk(KERN_INFO "ufstype=nextstep is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD:
		UFSD(("ufstype=nextstep-cd\n"))
		uspi->s_fsize = block_size = 2048;
		uspi->s_fmask = ~(2048 - 1);
		uspi->s_fshift = 11;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			printk(KERN_INFO "ufstype=nextstep-cd is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_OPENSTEP:
		UFSD(("ufstype=openstep\n"))
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
		if (!(sb->s_flags & MS_RDONLY)) {
			printk(KERN_INFO "ufstype=openstep is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
		}
		break;
	
	case UFS_MOUNT_UFSTYPE_HP:
		UFSD(("ufstype=hp\n"))
		uspi->s_fsize = block_size = 1024;
		uspi->s_fmask = ~(1024 - 1);
		uspi->s_fshift = 10;
		uspi->s_sbsize = super_block_size = 2048;
		uspi->s_sbbase = 0;
		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
		if (!(sb->s_flags & MS_RDONLY)) {
			printk(KERN_INFO "ufstype=hp is supported read-only\n");
			sb->s_flags |= MS_RDONLY;
 		}
 		break;
	default:
		printk("unknown ufstype\n");
		goto failed;
	}
	
again:	
	if (!sb_set_blocksize(sb, block_size)) {
		printk(KERN_ERR "UFS: failed to set blocksize\n");
		goto failed;
	}

	/*
	 * read ufs super block from device
	 */
	ubh = ubh_bread_uspi (uspi, sb, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size);
	if (!ubh) 
		goto failed;
	
	usb1 = ubh_get_usb_first(USPI_UBH);
	usb2 = ubh_get_usb_second(USPI_UBH);
	usb3 = ubh_get_usb_third(USPI_UBH);

	/*
	 * Check ufs magic number
	 */
	switch (__constant_le32_to_cpu(usb3->fs_magic)) {
		case UFS_MAGIC:
		case UFS_MAGIC_LFN:
	        case UFS_MAGIC_FEA:
	        case UFS_MAGIC_4GB:
			sbi->s_bytesex = BYTESEX_LE;
			goto magic_found;
	}
	switch (__constant_be32_to_cpu(usb3->fs_magic)) {
		case UFS_MAGIC:
		case UFS_MAGIC_LFN:
	        case UFS_MAGIC_FEA:
	        case UFS_MAGIC_4GB:
			sbi->s_bytesex = BYTESEX_BE;
			goto magic_found;
	}

	if ((((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) 
	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) 
	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) 
	  && uspi->s_sbbase < 256) {
		ubh_brelse_uspi(uspi);
		ubh = NULL;
		uspi->s_sbbase += 8;
		goto again;
	}
	printk("ufs_read_super: bad magic number\n");
	goto failed;

magic_found:
	/*
	 * Check block and fragment sizes
	 */
	uspi->s_bsize = fs32_to_cpu(sb, usb1->fs_bsize);
	uspi->s_fsize = fs32_to_cpu(sb, usb1->fs_fsize);
	uspi->s_sbsize = fs32_to_cpu(sb, usb1->fs_sbsize);
	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);

	if (uspi->s_fsize & (uspi->s_fsize - 1)) {
		printk(KERN_ERR "ufs_read_super: fragment size %u is not a power of 2\n",
			uspi->s_fsize);
			goto failed;
	}
	if (uspi->s_fsize < 512) {
		printk(KERN_ERR "ufs_read_super: fragment size %u is too small\n",
			uspi->s_fsize);
		goto failed;
	}
	if (uspi->s_fsize > 4096) {
		printk(KERN_ERR "ufs_read_super: fragment size %u is too large\n",
			uspi->s_fsize);
		goto failed;
	}
	if (uspi->s_bsize & (uspi->s_bsize - 1)) {
		printk(KERN_ERR "ufs_read_super: block size %u is not a power of 2\n",
			uspi->s_bsize);
		goto failed;
	}
	if (uspi->s_bsize < 4096) {
		printk(KERN_ERR "ufs_read_super: block size %u is too small\n",
			uspi->s_bsize);
		goto failed;
	}
	if (uspi->s_bsize / uspi->s_fsize > 8) {
		printk(KERN_ERR "ufs_read_super: too many fragments per block (%u)\n",
			uspi->s_bsize / uspi->s_fsize);
		goto failed;
	}
	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
		ubh_brelse_uspi(uspi);
		ubh = NULL;
		block_size = uspi->s_fsize;
		super_block_size = uspi->s_sbsize;
		UFSD(("another value of block_size or super_block_size %u, %u\n", block_size, super_block_size))
		goto again;
	}
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;
}
示例#30
0
static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
			     unsigned oldcount, unsigned newcount, int *err)
{
	struct super_block * sb;
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	struct ufs_cg_private_info * ucpi;
	struct ufs_cylinder_group * ucg;
	unsigned cgno, fragno, fragoff, count, fragsize, i;
	
	UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n",
	     (unsigned long long)fragment, oldcount, newcount);
	
	sb = inode->i_sb;
	uspi = UFS_SB(sb)->s_uspi;
	usb1 = ubh_get_usb_first (uspi);
	count = newcount - oldcount;
	
	cgno = ufs_dtog(uspi, fragment);
	if (fs32_to_cpu(sb, UFS_SB(sb)->fs_cs(cgno).cs_nffree) < count)
		return 0;
	if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb)
		return 0;
	ucpi = ufs_load_cylinder (sb, cgno);
	if (!ucpi)
		return 0;
	ucg = ubh_get_ucg (UCPI_UBH(ucpi));
	if (!ufs_cg_chkmagic(sb, ucg)) {
		ufs_panic (sb, "ufs_add_fragments",
			"internal error, bad magic number on cg %u", cgno);
		return 0;
	}

	fragno = ufs_dtogd(uspi, fragment);
	fragoff = ufs_fragnum (fragno);
	for (i = oldcount; i < newcount; i++)
		if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i))
			return 0;
	/*
	 * Block can be extended
	 */
	ucg->cg_time = cpu_to_fs32(sb, get_seconds());
	for (i = newcount; i < (uspi->s_fpb - fragoff); i++)
		if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i))
			break;
	fragsize = i - oldcount;
	if (!fs32_to_cpu(sb, ucg->cg_frsum[fragsize]))
		ufs_panic (sb, "ufs_add_fragments",
			"internal error or corrupted bitmap on cg %u", cgno);
	fs32_sub(sb, &ucg->cg_frsum[fragsize], 1);
	if (fragsize != count)
		fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1);
	for (i = oldcount; i < newcount; i++)
		ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i);
	if(DQUOT_ALLOC_BLOCK(inode, count)) {
		*err = -EDQUOT;
		return 0;
	}

	fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);
	fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
	uspi->cs_total.cs_nffree -= count;
	
	ubh_mark_buffer_dirty (USPI_UBH(uspi));
	ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
	if (sb->s_flags & MS_SYNCHRONOUS) {
		ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
		ubh_wait_on_buffer (UCPI_UBH(ucpi));
	}
	mark_sb_dirty(sb);

	UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment);
	
	return fragment;
}