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

📄 balloc.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 2 页
字号:
		    unsigned long * prealloc_block){	struct buffer_head * bh;	struct buffer_head * bh2;	char * p, * r;	int i, j, k, tmp;	unsigned long lmap;	int bitmap_nr;	struct ext2_group_desc * gdp;	struct ext2_super_block * es;#ifdef EXT2FS_DEBUG	static int goal_hits = 0, goal_attempts = 0;#endif	if (!sb) {		printk ("ext2_new_block: nonexistent device");		return 0;	}	lock_super (sb);	es = sb->u.ext2_sb.s_es;	if (es->s_free_blocks_count <= es->s_r_blocks_count && !suser()) {		unlock_super (sb);		return 0;	}	ext2_debug ("goal=%lu.\n", goal);repeat:	/*	 * First, test whether the goal block is free.	 */	if (goal < es->s_first_data_block || goal >= es->s_blocks_count)		goal = es->s_first_data_block;	i = (goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb);	gdp = get_group_desc (sb, i, &bh2);	if (gdp->bg_free_blocks_count > 0) {		j = ((goal - 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);		bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];		ext2_debug ("goal is at %d:%d.\n", i, j);		if (!test_bit(j, bh->b_data)) {#ifdef EXT2FS_DEBUG			goal_hits++;			ext2_debug ("goal bit allocated.\n");#endif			goto got_block;		}		if (j) {			/*			 * The goal was occupied; search forward for a free 			 * block within the next 32 blocks			 */			lmap = ((((unsigned long *) bh->b_data)[j >> 5]) >>				((j & 31) + 1));			if (j < EXT2_BLOCKS_PER_GROUP(sb) - 32)				lmap |= (((unsigned long *) bh->b_data)[(j >> 5) + 1]) <<				 (31 - (j & 31));			else				lmap |= 0xffffffff << (31 - (j & 31));			if (lmap != 0xffffffffl) {				__asm__ ("bsfl %1,%0"					 : "=r" (k)					 : "r" (~lmap));				k++;				if ((j + k) < EXT2_BLOCKS_PER_GROUP(sb)) {					j += k;					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 throught the rest of the groups.		 */		p = ((char *) bh->b_data) + (j >> 3);		r = find_first_zero_byte (p, 					  (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 = 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 = get_group_desc (sb, i, &bh2);		if (gdp->bg_free_blocks_count > 0)			break;	}	if (k >= sb->u.ext2_sb.s_groups_count) {		unlock_super (sb);		return 0;	}	bitmap_nr = load_block_bitmap (sb, i);	bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];	r = find_first_zero_byte (bh->b_data, 				  EXT2_BLOCKS_PER_GROUP(sb) >> 3);	j = (r - bh->b_data) << 3;	if (j < EXT2_BLOCKS_PER_GROUP(sb))		goto search_back;	else		j = 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);		unlock_super (sb);		return 0;	}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 && !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);	tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block;	if (test_opt (sb, CHECK_STRICT) &&	    (tmp == gdp->bg_block_bitmap ||	     tmp == gdp->bg_inode_bitmap ||	     in_range (tmp, gdp->bg_inode_table, sb->u.ext2_sb.s_itb_per_group)))		ext2_panic (sb, "ext2_new_block",			    "Allocating block in system zone\n"			    "block = %u", tmp);	if (set_bit (j, bh->b_data)) {		ext2_warning (sb, "ext2_new_block",			      "bit already set for block %d", j);		goto repeat;	}	ext2_debug ("found bit %d\n", j);	/*	 * Do block preallocation now if required.	 */#ifdef EXT2_PREALLOCATE	if (prealloc_block) {		*prealloc_count = 0;		*prealloc_block = tmp + 1;		for (k = 1;		     k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {			if (set_bit (j + k, bh->b_data))				break;			(*prealloc_count)++;		}			gdp->bg_free_blocks_count -= *prealloc_count;		es->s_free_blocks_count -= *prealloc_count;		ext2_debug ("Preallocated a further %lu bits.\n",			    *prealloc_count);	}#endif	j = tmp;	bh->b_dirt = 1;	if (sb->s_flags & MS_SYNC) {		ll_rw_block (WRITE, 1, &bh);		wait_on_buffer (bh);	}	if (j >= es->s_blocks_count) {		ext2_error (sb, "ext2_new_block",			    "block >= blocks count\n"			    "block_group = %d, block=%d", i, j);		unlock_super (sb);		return 0;	}	if (!(bh = getblk (sb->s_dev, j, sb->s_blocksize))) {		ext2_error (sb, "ext2_new_block", "cannot get block %d", j);		unlock_super (sb);		return 0;	}	clear_block (bh->b_data, sb->s_blocksize);	bh->b_uptodate = 1;	bh->b_dirt = 1;	brelse (bh);	ext2_debug ("allocating block %d. "		    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);	gdp->bg_free_blocks_count--;	bh2->b_dirt = 1;	es->s_free_blocks_count--;	sb->u.ext2_sb.s_sbh->b_dirt = 1;	sb->s_dirt = 1;	unlock_super (sb);	return j;}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 = get_group_desc (sb, i, NULL);		desc_count += gdp->bg_free_blocks_count;		bitmap_nr = load_block_bitmap (sb, i);		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, gdp->bg_free_blocks_count, x);		bitmap_count += x;	}	printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",	       es->s_free_blocks_count, desc_count, bitmap_count);	unlock_super (sb);	return bitmap_count;#else	return 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 test_bit ((block - sb->u.ext2_sb.s_es->s_first_data_block) %			 EXT2_BLOCKS_PER_GROUP(sb), map);}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;	unsigned long desc_blocks;	int bitmap_nr;	struct ext2_group_desc * gdp;	int i, j;	lock_super (sb);	es = sb->u.ext2_sb.s_es;	desc_count = 0;	bitmap_count = 0;	gdp = NULL;	desc_blocks = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /		      EXT2_DESC_PER_BLOCK(sb);	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {		gdp = get_group_desc (sb, i, NULL);		desc_count += gdp->bg_free_blocks_count;		bitmap_nr = load_block_bitmap (sb, i);		bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];		if (!test_bit (0, bh->b_data))			ext2_error (sb, "ext2_check_blocks_bitmap",				    "Superblock in group %d is marked free", i);		for (j = 0; j < desc_blocks; j++)			if (!test_bit (j + 1, bh->b_data))				ext2_error (sb, "ext2_check_blocks_bitmap",					    "Descriptor block #%d in group "					    "%d is marked free", j, i);		if (!block_in_use (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 (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 (gdp->bg_inode_table + j, sb, bh->b_data))				ext2_error (sb, "ext2_check_blocks_bitmap",					    "Block #%d of the inode table in "					    "group %d is marked free", j, i);		x = ext2_count_free (bh, sb->s_blocksize);		if (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,				    gdp->bg_free_blocks_count, x);		bitmap_count += x;	}	if (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",			    es->s_free_blocks_count, bitmap_count);	unlock_super (sb);}

⌨️ 快捷键说明

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