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

📄 balloc.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
		goto out;	}	while (prealloc_goal && DQUOT_PREALLOC_BLOCK(inode, prealloc_goal))		prealloc_goal--;	dq_alloc = prealloc_goal + 1;	es_alloc = reserve_blocks(sb, dq_alloc);	if (!es_alloc) {		*err = -ENOSPC;		goto out_dquot;	}	ext2_debug ("goal=%lu.\n", goal);	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);	group_no = (goal - le32_to_cpu(es->s_first_data_block)) / group_size;	desc = ext2_get_group_desc (sb, group_no, &gdp_bh);	if (!desc) {		/*		 * gdp_bh may still be uninitialised.  But group_release_blocks		 * will not touch it because group_alloc is zero.		 */		goto io_error;	}	group_alloc = group_reserve_blocks(sbi, group_no, desc,					gdp_bh, es_alloc);	if (group_alloc) {		ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %					group_size);		brelse(bitmap_bh);		bitmap_bh = read_block_bitmap(sb, group_no);		if (!bitmap_bh)			goto io_error;				ext2_debug("goal is at %d:%d.\n", group_no, ret_block);		ret_block = grab_block(sb_bgl_lock(sbi, group_no),				bitmap_bh->b_data, group_size, ret_block);		if (ret_block >= 0)			goto got_block;		group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);		group_alloc = 0;	}	ext2_debug ("Bit not found in block group %d.\n", group_no);	/*	 * Now search the rest of the groups.  We assume that 	 * i and desc correctly point to the last group visited.	 */	nr_scanned_groups = 0;retry:	for (group_idx = 0; !group_alloc &&			group_idx < sbi->s_groups_count; group_idx++) {		group_no++;		if (group_no >= sbi->s_groups_count)			group_no = 0;		desc = ext2_get_group_desc(sb, group_no, &gdp_bh);		if (!desc)			goto io_error;		group_alloc = group_reserve_blocks(sbi, group_no, desc,						gdp_bh, es_alloc);	}	if (!group_alloc) {		*err = -ENOSPC;		goto out_release;	}	brelse(bitmap_bh);	bitmap_bh = read_block_bitmap(sb, group_no);	if (!bitmap_bh)		goto io_error;	ret_block = grab_block(sb_bgl_lock(sbi, group_no), bitmap_bh->b_data,				group_size, 0);	if (ret_block < 0) {		/*		 * If a free block counter is corrupted we can loop inifintely.		 * Detect that here.		 */		nr_scanned_groups++;		if (nr_scanned_groups > 2 * sbi->s_groups_count) {			ext2_error(sb, "ext2_new_block",				"corrupted free blocks counters");			goto io_error;		}		/*		 * Someone else grabbed the last free block in this blockgroup		 * before us.  Retry the scan.		 */		group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);		group_alloc = 0;		goto retry;	}got_block:	ext2_debug("using block group %d(%d)\n",		group_no, desc->bg_free_blocks_count);	target_block = ret_block + group_no * group_size +			le32_to_cpu(es->s_first_data_block);	if (target_block == le32_to_cpu(desc->bg_block_bitmap) ||	    target_block == le32_to_cpu(desc->bg_inode_bitmap) ||	    in_range(target_block, le32_to_cpu(desc->bg_inode_table),		      sbi->s_itb_per_group))		ext2_error (sb, "ext2_new_block",			    "Allocating block in system zone - "			    "block = %u", target_block);	if (target_block >= le32_to_cpu(es->s_blocks_count)) {		ext2_error (sb, "ext2_new_block",			    "block(%d) >= blocks count(%d) - "			    "block_group = %d, es == %p ", ret_block,			le32_to_cpu(es->s_blocks_count), group_no, es);		goto io_error;	}	block = target_block;	/* OK, we _had_ allocated something */	ext2_debug("found bit %d\n", ret_block);	dq_alloc--;	es_alloc--;	group_alloc--;	/*	 * Do block preallocation now if required.	 */	write_lock(&EXT2_I(inode)->i_meta_lock);	if (group_alloc && !*prealloc_count) {		unsigned n;		for (n = 0; n < group_alloc && ++ret_block < group_size; n++) {			if (ext2_set_bit_atomic(sb_bgl_lock(sbi, group_no),						ret_block,						(void*) bitmap_bh->b_data)) 				break;		}		*prealloc_block = block + 1;		*prealloc_count = n;		es_alloc -= n;		dq_alloc -= n;		group_alloc -= n;	}	write_unlock(&EXT2_I(inode)->i_meta_lock);	mark_buffer_dirty(bitmap_bh);	if (sb->s_flags & MS_SYNCHRONOUS)		sync_dirty_buffer(bitmap_bh);	ext2_debug ("allocating block %d. ", block);	*err = 0;out_release:	group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);	release_blocks(sb, es_alloc);out_dquot:	DQUOT_FREE_BLOCK(inode, dq_alloc);out:	brelse(bitmap_bh);	return block;io_error:	*err = -EIO;	goto out_release;}unsigned long ext2_count_free_blocks (struct super_block * sb){	struct ext2_group_desc * desc;	unsigned long desc_count = 0;	int i;#ifdef EXT2FS_DEBUG	unsigned long bitmap_count, x;	struct ext2_super_block *es;	lock_super (sb);	es = EXT2_SB(sb)->s_es;	desc_count = 0;	bitmap_count = 0;	desc = NULL;	for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {		struct buffer_head *bitmap_bh;		desc = ext2_get_group_desc (sb, i, NULL);		if (!desc)			continue;		desc_count += le16_to_cpu(desc->bg_free_blocks_count);		bitmap_bh = read_block_bitmap(sb, i);		if (!bitmap_bh)			continue;				x = ext2_count_free(bitmap_bh, sb->s_blocksize);		printk ("group %d: stored = %d, counted = %lu\n",			i, le16_to_cpu(desc->bg_free_blocks_count), x);		bitmap_count += x;		brelse(bitmap_bh);	}	printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",		(long)le32_to_cpu(es->s_free_blocks_count),		desc_count, bitmap_count);	unlock_super (sb);	return bitmap_count;#else        for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {                desc = ext2_get_group_desc (sb, i, NULL);                if (!desc)                        continue;                desc_count += le16_to_cpu(desc->bg_free_blocks_count);	}	return desc_count;#endif}static inline intblock_in_use(unsigned long block, struct super_block *sb, unsigned char *map){	return ext2_test_bit ((block - le32_to_cpu(EXT2_SB(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;	}}static 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 *bitmap_bh = NULL;	struct ext2_super_block * es;	unsigned long desc_count, bitmap_count, x, j;	unsigned long desc_blocks;	struct ext2_group_desc * desc;	int i;	es = EXT2_SB(sb)->s_es;	desc_count = 0;	bitmap_count = 0;	desc = NULL;	for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {		desc = ext2_get_group_desc (sb, i, NULL);		if (!desc)			continue;		desc_count += le16_to_cpu(desc->bg_free_blocks_count);		brelse(bitmap_bh);		bitmap_bh = read_block_bitmap(sb, i);		if (!bitmap_bh)			continue;		if (ext2_bg_has_super(sb, i) &&				!ext2_test_bit(0, bitmap_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, bitmap_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(desc->bg_block_bitmap),					sb, bitmap_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(desc->bg_inode_bitmap),					sb, bitmap_bh->b_data))			ext2_error(sb, "ext2_check_blocks_bitmap",				    "Inode bitmap for group %d is marked free",				    i);		for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++)			if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j,						sb, bitmap_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(bitmap_bh, sb->s_blocksize);		if (le16_to_cpu(desc->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(desc->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);	brelse(bitmap_bh);}#endif

⌨️ 快捷键说明

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