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

📄 ialloc.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 2 页
字号:
static void inc_inode_version (struct inode * inode,			       struct ext2_group_desc *gdp,			       int mode){	unsigned long inode_block;	struct buffer_head * bh;	struct ext2_inode * raw_inode;	inode_block = gdp->bg_inode_table + (((inode->i_ino - 1) %			EXT2_INODES_PER_GROUP(inode->i_sb)) /			EXT2_INODES_PER_BLOCK(inode->i_sb));	bh = bread (inode->i_sb->s_dev, inode_block, inode->i_sb->s_blocksize);	if (!bh) {		ext2_error (inode->i_sb, "inc_inode_version",			    "Cannot load inode table block"			    "inode=%lu, inode_block=%lu\n",			    inode->i_ino, inode_block);		inode->u.ext2_i.i_version = 1;		return;	}	raw_inode = ((struct ext2_inode *) bh->b_data) +			(((inode->i_ino - 1) %			EXT2_INODES_PER_GROUP(inode->i_sb)) %			EXT2_INODES_PER_BLOCK(inode->i_sb));	raw_inode->i_version++;	inode->u.ext2_i.i_version = raw_inode->i_version;	bh->b_dirt = 1;	brelse (bh);}/* * 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 * ext2_new_inode (const struct inode * dir, int mode){	struct super_block * sb;	struct buffer_head * bh;	struct buffer_head * bh2;	int i, j, avefreei;	struct inode * inode;	int bitmap_nr;	struct ext2_group_desc * gdp;	struct ext2_group_desc * tmp;	struct ext2_super_block * es;	if (!dir || !(inode = get_empty_inode ()))		return NULL;	sb = dir->i_sb;	inode->i_sb = sb;	inode->i_flags = sb->s_flags;	lock_super (sb);	es = sb->u.ext2_sb.s_es;repeat:	gdp = NULL; i=0;		if (S_ISDIR(mode)) {		avefreei = es->s_free_inodes_count /			sb->u.ext2_sb.s_groups_count;/* I am not yet convinced that this next bit is necessary.		i = dir->u.ext2_i.i_block_group;		for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) {			tmp = get_group_desc (sb, i, &bh2);			if ((tmp->bg_used_dirs_count << 8) < 			    tmp->bg_free_inodes_count) {				gdp = tmp;				break;			}			else			i = ++i % sb->u.ext2_sb.s_groups_count;		}*/		if (!gdp) {			for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) {				tmp = get_group_desc (sb, j, &bh2);				if (tmp->bg_free_inodes_count &&					tmp->bg_free_inodes_count >= avefreei) {					if (!gdp || 					    (tmp->bg_free_blocks_count >					     gdp->bg_free_blocks_count)) {						i = j;						gdp = tmp;					}				}			}		}	}	else 	{		/*		 * Try to place the inode in it's parent directory		 */		i = dir->u.ext2_i.i_block_group;		tmp = get_group_desc (sb, i, &bh2);		if (tmp->bg_free_inodes_count)			gdp = tmp;		else		{			/*			 * Use a quadratic hash to find a group with a			 * free inode			 */			for (j = 1; j < sb->u.ext2_sb.s_groups_count; j <<= 1) {				i += j;				if (i >= sb->u.ext2_sb.s_groups_count)					i -= sb->u.ext2_sb.s_groups_count;				tmp = get_group_desc (sb, i, &bh2);				if (tmp->bg_free_inodes_count) {					gdp = tmp;					break;				}			}		}		if (!gdp) {			/*			 * That failed: try linear search for a free inode			 */			i = dir->u.ext2_i.i_block_group + 1;			for (j = 2; j < sb->u.ext2_sb.s_groups_count; j++) {				if (++i >= sb->u.ext2_sb.s_groups_count)					i = 0;				tmp = get_group_desc (sb, i, &bh2);				if (tmp->bg_free_inodes_count) {					gdp = tmp;					break;				}			}		}	}	if (!gdp) {		unlock_super (sb);		iput(inode);		return NULL;	}	bitmap_nr = load_inode_bitmap (sb, i);	bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr];	if ((j = find_first_zero_bit ((unsigned long *) bh->b_data,				      EXT2_INODES_PER_GROUP(sb))) <	    EXT2_INODES_PER_GROUP(sb)) {		if (set_bit (j, bh->b_data)) {			ext2_warning (sb, "ext2_new_inode",				      "bit already set for inode %d", j);			goto repeat;		}		bh->b_dirt = 1;		if (sb->s_flags & MS_SYNC) {			ll_rw_block (WRITE, 1, &bh);			wait_on_buffer (bh);		}	} else {		if (gdp->bg_free_inodes_count != 0) {			ext2_error (sb, "ext2_new_inode",				    "Free inodes count corrupted in group %d",				    i);			unlock_super (sb);			iput (inode);			return NULL;		}		goto repeat;	}	j += i * EXT2_INODES_PER_GROUP(sb) + 1;	if (j < EXT2_FIRST_INO || j > es->s_inodes_count) {		ext2_error (sb, "ext2_new_inode",			    "reserved inode or inode > inodes count\n"			    "block_group = %d,inode=%d", i, j);		unlock_super (sb);		iput (inode);		return NULL;	}	gdp->bg_free_inodes_count--;	if (S_ISDIR(mode))		gdp->bg_used_dirs_count++;	bh2->b_dirt = 1;	es->s_free_inodes_count--;	sb->u.ext2_sb.s_sbh->b_dirt = 1;	sb->s_dirt = 1;	inode->i_mode = mode;	inode->i_sb = sb;	inode->i_count = 1;	inode->i_nlink = 1;	inode->i_dev = sb->s_dev;	inode->i_uid = current->euid;	if (test_opt (sb, GRPID))		inode->i_gid = dir->i_gid;	else if (dir->i_mode & S_ISGID) {		inode->i_gid = dir->i_gid;		if (S_ISDIR(mode))			mode |= S_ISGID;	} else		inode->i_gid = current->egid;	inode->i_dirt = 1;	inode->i_ino = j;	inode->i_blksize = sb->s_blocksize;	inode->i_blocks = 0;	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;	inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;	inode->u.ext2_i.i_faddr = 0;	inode->u.ext2_i.i_frag = 0;	inode->u.ext2_i.i_fsize = 0;	inode->u.ext2_i.i_file_acl = 0;	inode->u.ext2_i.i_dir_acl = 0;	inode->u.ext2_i.i_dtime = 0;	inode->u.ext2_i.i_block_group = i;	inode->i_op = NULL;	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)		inode->i_flags |= MS_SYNC;	insert_inode_hash(inode);	inc_inode_version (inode, gdp, mode);	ext2_debug ("allocating inode %lu\n", inode->i_ino);	unlock_super (sb);	return inode;}unsigned long ext2_count_free_inodes (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_inodes_count;		bitmap_nr = load_inode_bitmap (sb, i);		x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr],				     EXT2_INODES_PER_GROUP(sb) / 8);		printk ("group %d: stored = %d, counted = %lu\n",			i, gdp->bg_free_inodes_count, x);		bitmap_count += x;	}	printk("ext2_count_free_inodes: stored = %lu, computed = %lu, %lu\n",		es->s_free_inodes_count, desc_count, bitmap_count);	unlock_super (sb);	return desc_count;#else	return sb->u.ext2_sb.s_es->s_free_inodes_count;#endif}void ext2_check_inodes_bitmap (struct super_block * sb){	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_inodes_count;		bitmap_nr = load_inode_bitmap (sb, i);		x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr],				     EXT2_INODES_PER_GROUP(sb) / 8);		if (gdp->bg_free_inodes_count != x)			ext2_error (sb, "ext2_check_inodes_bitmap",				    "Wrong free inodes count in group %d, "				    "stored = %d, counted = %lu", i,				    gdp->bg_free_inodes_count, x);		bitmap_count += x;	}	if (es->s_free_inodes_count != bitmap_count)		ext2_error (sb, "ext2_check_inodes_bitmap",			    "Wrong free inodes count in super block, "			    "stored = %lu, counted = %lu",			    es->s_free_inodes_count, bitmap_count);	unlock_super (sb);}

⌨️ 快捷键说明

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