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

📄 ialloc.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
		return ERR_PTR(-EPERM);	sb = dir->i_sb;	inode = new_inode(sb);	if (!inode)		return ERR_PTR(-ENOMEM);	lock_super (sb);	es = sb->u.ext2_sb.s_es;repeat:	gdp = NULL; i=0;		if (S_ISDIR(mode)) {		avefreei = le32_to_cpu(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 = ext2_get_group_desc (sb, i, &bh2);			if (tmp &&			    (le16_to_cpu(tmp->bg_used_dirs_count) << 8) < 			     le16_to_cpu(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 = ext2_get_group_desc (sb, j, &bh2);				if (tmp &&				    le16_to_cpu(tmp->bg_free_inodes_count) &&				    le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) {					if (!gdp || 					    (le16_to_cpu(tmp->bg_free_blocks_count) >					     le16_to_cpu(gdp->bg_free_blocks_count))) {						i = j;						gdp = tmp;					}				}			}		}	}	else 	{		/*		 * Try to place the inode in its parent directory		 */		i = dir->u.ext2_i.i_block_group;		tmp = ext2_get_group_desc (sb, i, &bh2);		if (tmp && le16_to_cpu(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 = ext2_get_group_desc (sb, i, &bh2);				if (tmp &&				    le16_to_cpu(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 = ext2_get_group_desc (sb, i, &bh2);				if (tmp &&				    le16_to_cpu(tmp->bg_free_inodes_count)) {					gdp = tmp;					break;				}			}		}	}	err = -ENOSPC;	if (!gdp)		goto fail;	err = -EIO;	bitmap_nr = load_inode_bitmap (sb, i);	if (bitmap_nr < 0)		goto fail;	bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr];	if ((j = ext2_find_first_zero_bit ((unsigned long *) bh->b_data,				      EXT2_INODES_PER_GROUP(sb))) <	    EXT2_INODES_PER_GROUP(sb)) {		if (ext2_set_bit (j, bh->b_data)) {			ext2_error (sb, "ext2_new_inode",				      "bit already set for inode %d", j);			goto repeat;		}		mark_buffer_dirty(bh);		if (sb->s_flags & MS_SYNCHRONOUS) {			ll_rw_block (WRITE, 1, &bh);			wait_on_buffer (bh);		}	} else {		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {			ext2_error (sb, "ext2_new_inode",				    "Free inodes count corrupted in group %d",				    i);			/* Is it really ENOSPC? */			err = -ENOSPC;			if (sb->s_flags & MS_RDONLY)				goto fail;			gdp->bg_free_inodes_count = 0;			mark_buffer_dirty(bh2);		}		goto repeat;	}	j += i * EXT2_INODES_PER_GROUP(sb) + 1;	if (j < EXT2_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {		ext2_error (sb, "ext2_new_inode",			    "reserved inode or inode > inodes count - "			    "block_group = %d,inode=%d", i, j);		err = -EIO;		goto fail;	}	gdp->bg_free_inodes_count =		cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);	if (S_ISDIR(mode))		gdp->bg_used_dirs_count =			cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);	mark_buffer_dirty(bh2);	es->s_free_inodes_count =		cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);	mark_buffer_dirty(sb->u.ext2_sb.s_sbh);	sb->s_dirt = 1;	inode->i_mode = mode;	inode->i_uid = current->fsuid;	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->fsgid;	inode->i_ino = j;	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */	inode->i_blocks = 0;	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;	inode->u.ext2_i.i_new_inode = 1;	inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;	if (S_ISLNK(mode))		inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FL | EXT2_APPEND_FL);	inode->u.ext2_i.i_faddr = 0;	inode->u.ext2_i.i_frag_no = 0;	inode->u.ext2_i.i_frag_size = 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;	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)		inode->i_flags |= S_SYNC;	insert_inode_hash(inode);	inode->i_generation = event++;	mark_inode_dirty(inode);	unlock_super (sb);	if(DQUOT_ALLOC_INODE(sb, inode)) {		sb->dq_op->drop(inode);		inode->i_nlink = 0;		iput(inode);		return ERR_PTR(-EDQUOT);	}	ext2_debug ("allocating inode %lu\n", inode->i_ino);	return inode;fail:	unlock_super(sb);	iput(inode);	return ERR_PTR(err);}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 = ext2_get_group_desc (sb, i, NULL);		if (!gdp)			continue;		desc_count += le16_to_cpu(gdp->bg_free_inodes_count);		bitmap_nr = load_inode_bitmap (sb, i);		if (bitmap_nr < 0)			continue;		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, le16_to_cpu(gdp->bg_free_inodes_count), x);		bitmap_count += x;	}	printk("ext2_count_free_inodes: stored = %lu, computed = %lu, %lu\n",		le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);	unlock_super (sb);	return desc_count;#else	return le32_to_cpu(sb->u.ext2_sb.s_es->s_free_inodes_count);#endif}#ifdef CONFIG_EXT2_CHECK/* Called at mount-time, super-block is locked */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;	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_inodes_count);		bitmap_nr = load_inode_bitmap (sb, i);		if (bitmap_nr < 0)			continue;				x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr],				     EXT2_INODES_PER_GROUP(sb) / 8);		if (le16_to_cpu(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,				    le16_to_cpu(gdp->bg_free_inodes_count), x);		bitmap_count += x;	}	if (le32_to_cpu(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",			    (unsigned long) le32_to_cpu(es->s_free_inodes_count),			    bitmap_count);}#endif

⌨️ 快捷键说明

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