⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 balloc.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (goal < le32_to_cpu(es->s_first_data_block) ||	    goal >= le32_to_cpu(es->s_blocks_count))		goal = le32_to_cpu(es->s_first_data_block);	i = (goal - le32_to_cpu(es->s_first_data_block)) / EXT2_BLOCKS_PER_GROUP(sb);	gdp = ext2_get_group_desc (sb, i, &bh2);	if (!gdp)		goto io_error;	if (le16_to_cpu(gdp->bg_free_blocks_count) > 0) {		j = ((goal - le32_to_cpu(es->s_first_data_block)) % EXT2_BLOCKS_PER_GROUP(sb));#ifdef EXT2FS_DEBUG		if (j)			goal_attempts++;#endif		bitmap_nr = load_block_bitmap (sb, i);		if (bitmap_nr < 0)			goto io_error;				bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];		ext2_debug ("goal is at %d:%d.\n", i, j);		if (!ext2_test_bit(j, bh->b_data)) {			ext2_debug("goal bit allocated, %d hits\n",++goal_hits);			goto got_block;		}		if (j) {			/*			 * The goal was occupied; search forward for a free 			 * block within the next XX blocks.			 *			 * end_goal is more or less random, but it has to be			 * less than EXT2_BLOCKS_PER_GROUP. Aligning up to the			 * next 64-bit boundary is simple..			 */			int end_goal = (j + 63) & ~63;			j = ext2_find_next_zero_bit(bh->b_data, end_goal, j);			if (j < end_goal)				goto got_block;		}			ext2_debug ("Bit not found near goal\n");		/*		 * There has been no free block found in the near vicinity		 * of the goal: do a search forward through the block groups,		 * searching in each group first for an entire free byte in		 * the bitmap and then for any free bit.		 * 		 * Search first in the remainder of the current group; then,		 * cyclicly search through the rest of the groups.		 */		p = ((char *) bh->b_data) + (j >> 3);		r = memscan(p, 0, (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);		k = (r - ((char *) bh->b_data)) << 3;		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {			j = k;			goto search_back;		}		k = ext2_find_next_zero_bit ((unsigned long *) bh->b_data, 					EXT2_BLOCKS_PER_GROUP(sb),					j);		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {			j = k;			goto got_block;		}	}	ext2_debug ("Bit not found in block group %d.\n", i);	/*	 * Now search the rest of the groups.  We assume that 	 * i and gdp correctly point to the last group visited.	 */	for (k = 0; k < sb->u.ext2_sb.s_groups_count; k++) {		i++;		if (i >= sb->u.ext2_sb.s_groups_count)			i = 0;		gdp = ext2_get_group_desc (sb, i, &bh2);		if (!gdp)			goto io_error;		if (le16_to_cpu(gdp->bg_free_blocks_count) > 0)			break;	}	if (k >= sb->u.ext2_sb.s_groups_count)		goto out;	bitmap_nr = load_block_bitmap (sb, i);	if (bitmap_nr < 0)		goto io_error;		bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];	r = memscan(bh->b_data, 0, EXT2_BLOCKS_PER_GROUP(sb) >> 3);	j = (r - bh->b_data) << 3;	if (j < EXT2_BLOCKS_PER_GROUP(sb))		goto search_back;	else		j = ext2_find_first_zero_bit ((unsigned long *) bh->b_data,					 EXT2_BLOCKS_PER_GROUP(sb));	if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {		ext2_error (sb, "ext2_new_block",			    "Free blocks count corrupted for block group %d", i);		goto out;	}search_back:	/* 	 * We have succeeded in finding a free byte in the block	 * bitmap.  Now search backwards up to 7 bits to find the	 * start of this group of free blocks.	 */	for (k = 0; k < 7 && j > 0 && !ext2_test_bit (j - 1, bh->b_data); k++, j--);	got_block:	ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);	/*	 * Check quota for allocation of this block.	 */	if(DQUOT_ALLOC_BLOCK(inode, 1)) {		*err = -EDQUOT;		goto out;	}	tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + le32_to_cpu(es->s_first_data_block);	if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||	    tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||	    in_range (tmp, le32_to_cpu(gdp->bg_inode_table),		      sb->u.ext2_sb.s_itb_per_group))		ext2_error (sb, "ext2_new_block",			    "Allocating block in system zone - "			    "block = %u", tmp);	if (ext2_set_bit (j, bh->b_data)) {		ext2_warning (sb, "ext2_new_block",			      "bit already set for block %d", j);		DQUOT_FREE_BLOCK(inode, 1);		goto repeat;	}	ext2_debug ("found bit %d\n", j);	/*	 * Do block preallocation now if required.	 */#ifdef EXT2_PREALLOCATE	/* Writer: ->i_prealloc* */	if (prealloc_count && !*prealloc_count) {		int	prealloc_goal;		unsigned long next_block = tmp + 1;		prealloc_goal = es->s_prealloc_blocks ?			es->s_prealloc_blocks : EXT2_DEFAULT_PREALLOC_BLOCKS;		*prealloc_block = next_block;		/* Writer: end */		for (k = 1;		     k < prealloc_goal && (j + k) < EXT2_BLOCKS_PER_GROUP(sb);		     k++, next_block++) {			if (DQUOT_PREALLOC_BLOCK(inode, 1))				break;			/* Writer: ->i_prealloc* */			if (*prealloc_block + *prealloc_count != next_block ||			    ext2_set_bit (j + k, bh->b_data)) {				/* Writer: end */				DQUOT_FREE_BLOCK(inode, 1); 				break;			}			(*prealloc_count)++;			/* Writer: end */		}			/*		 * As soon as we go for per-group spinlocks we'll need these		 * done inside the loop above.		 */		gdp->bg_free_blocks_count =			cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) -			       (k - 1));		es->s_free_blocks_count =			cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) -			       (k - 1));		ext2_debug ("Preallocated a further %lu bits.\n",			       (k - 1));	}#endif	j = tmp;	mark_buffer_dirty(bh);	if (sb->s_flags & MS_SYNCHRONOUS) {		ll_rw_block (WRITE, 1, &bh);		wait_on_buffer (bh);	}	if (j >= le32_to_cpu(es->s_blocks_count)) {		ext2_error (sb, "ext2_new_block",			    "block(%d) >= blocks count(%d) - "			    "block_group = %d, es == %p ",j,			le32_to_cpu(es->s_blocks_count), i, es);		goto out;	}	ext2_debug ("allocating block %d. "		    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);	gdp->bg_free_blocks_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - 1);	mark_buffer_dirty(bh2);	es->s_free_blocks_count = cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) - 1);	mark_buffer_dirty(sb->u.ext2_sb.s_sbh);	sb->s_dirt = 1;	unlock_super (sb);	*err = 0;	return j;	io_error:	*err = -EIO;out:	unlock_super (sb);	return 0;	}unsigned long ext2_count_free_blocks (struct super_block * sb){#ifdef EXT2FS_DEBUG	struct ext2_super_block * es;	unsigned long desc_count, bitmap_count, x;	int bitmap_nr;	struct ext2_group_desc * gdp;	int i;		lock_super (sb);	es = sb->u.ext2_sb.s_es;	desc_count = 0;	bitmap_count = 0;	gdp = NULL;	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {		gdp = ext2_get_group_desc (sb, i, NULL);		if (!gdp)			continue;		desc_count += le16_to_cpu(gdp->bg_free_blocks_count);		bitmap_nr = load_block_bitmap (sb, i);		if (bitmap_nr < 0)			continue;				x = ext2_count_free (sb->u.ext2_sb.s_block_bitmap[bitmap_nr],				     sb->s_blocksize);		printk ("group %d: stored = %d, counted = %lu\n",			i, le16_to_cpu(gdp->bg_free_blocks_count), x);		bitmap_count += x;	}	printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",	       le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);	unlock_super (sb);	return bitmap_count;#else	return le32_to_cpu(sb->u.ext2_sb.s_es->s_free_blocks_count);#endif}static inline int block_in_use (unsigned long block,				struct super_block * sb,				unsigned char * map){	return ext2_test_bit ((block - le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block)) %			 EXT2_BLOCKS_PER_GROUP(sb), map);}static inline int test_root(int a, int b){	if (a == 0)		return 1;	while (1) {		if (a == 1)			return 1;		if (a % b)			return 0;		a = a / b;	}}int ext2_group_sparse(int group){	return (test_root(group, 3) || test_root(group, 5) ||		test_root(group, 7));}/** *	ext2_bg_has_super - number of blocks used by the superblock in group *	@sb: superblock for filesystem *	@group: group number to check * *	Return the number of blocks used by the superblock (primary or backup) *	in this group.  Currently this will be only 0 or 1. */int ext2_bg_has_super(struct super_block *sb, int group){	if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&&	    !ext2_group_sparse(group))		return 0;	return 1;}/** *	ext2_bg_num_gdb - number of blocks used by the group table in group *	@sb: superblock for filesystem *	@group: group number to check * *	Return the number of blocks used by the group descriptor table *	(primary or backup) in this group.  In the future there may be a *	different number of descriptor blocks in each group. */unsigned long ext2_bg_num_gdb(struct super_block *sb, int group){	if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&&	    !ext2_group_sparse(group))		return 0;	return EXT2_SB(sb)->s_gdb_count;}#ifdef CONFIG_EXT2_CHECK/* Called at mount-time, super-block is locked */void ext2_check_blocks_bitmap (struct super_block * sb){	struct buffer_head * bh;	struct ext2_super_block * es;	unsigned long desc_count, bitmap_count, x, j;	unsigned long desc_blocks;	int bitmap_nr;	struct ext2_group_desc * gdp;	int i;	es = sb->u.ext2_sb.s_es;	desc_count = 0;	bitmap_count = 0;	gdp = NULL;	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {		gdp = ext2_get_group_desc (sb, i, NULL);		if (!gdp)			continue;		desc_count += le16_to_cpu(gdp->bg_free_blocks_count);		bitmap_nr = load_block_bitmap (sb, i);		if (bitmap_nr < 0)			continue;		bh = EXT2_SB(sb)->s_block_bitmap[bitmap_nr];		if (ext2_bg_has_super(sb, i) && !ext2_test_bit(0, bh->b_data))			ext2_error(sb, __FUNCTION__,				   "Superblock in group %d is marked free", i);		desc_blocks = ext2_bg_num_gdb(sb, i);		for (j = 0; j < desc_blocks; j++)			if (!ext2_test_bit(j + 1, bh->b_data))				ext2_error(sb, __FUNCTION__,					   "Descriptor block #%ld in group "					   "%d is marked free", j, i);		if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap), sb, bh->b_data))			ext2_error (sb, "ext2_check_blocks_bitmap",				    "Block bitmap for group %d is marked free",				    i);		if (!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap), sb, bh->b_data))			ext2_error (sb, "ext2_check_blocks_bitmap",				    "Inode bitmap for group %d is marked free",				    i);		for (j = 0; j < sb->u.ext2_sb.s_itb_per_group; j++)			if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j, sb, bh->b_data))				ext2_error (sb, "ext2_check_blocks_bitmap",					    "Block #%ld of the inode table in "					    "group %d is marked free", j, i);		x = ext2_count_free (bh, sb->s_blocksize);		if (le16_to_cpu(gdp->bg_free_blocks_count) != x)			ext2_error (sb, "ext2_check_blocks_bitmap",				    "Wrong free blocks count for group %d, "				    "stored = %d, counted = %lu", i,				    le16_to_cpu(gdp->bg_free_blocks_count), x);		bitmap_count += x;	}	if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)		ext2_error (sb, "ext2_check_blocks_bitmap",			    "Wrong free blocks count in super block, "			    "stored = %lu, counted = %lu",			    (unsigned long) le32_to_cpu(es->s_free_blocks_count), bitmap_count);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -