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

📄 inode.c

📁 嵌入式系统开发的必备工具,有嵌入式系统开发的瑞士军刀之功能,属于最新版本,更是制作文件系统很重要的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/*	 * This is done outside the above if statement so that the	 * check can be done for block group #0.	 */	if (scan->current_block == 0) {		if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {			goto force_new_group;		} else			return EXT2_ET_MISSING_INODE_TABLE;	}	/*	 * Have we run out of space in the inode buffer?  If so, we	 * need to read in more blocks.	 */	if (scan->bytes_left < scan->inode_size) {		memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);		extra_bytes = scan->bytes_left;		retval = get_next_blocks(scan);		if (retval)			return retval;#if 0		/*		 * XXX test  Need check for used inode somehow.		 * (Note: this is hard.)		 */		if (is_empty_scan(scan))			goto force_new_group;#endif	}	retval = 0;	if (extra_bytes) {		memcpy(scan->temp_buffer+extra_bytes, scan->ptr,		       scan->inode_size - extra_bytes);		scan->ptr += scan->inode_size - extra_bytes;		scan->bytes_left -= scan->inode_size - extra_bytes;#if BB_BIG_ENDIAN		if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||		    (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))			ext2fs_swap_inode_full(scan->fs,				(struct ext2_inode_large *) inode,				(struct ext2_inode_large *) scan->temp_buffer,				0, bufsize);		else#endif			*inode = *((struct ext2_inode *) scan->temp_buffer);		if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)			retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;		scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;	} else {#if BB_BIG_ENDIAN		if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||		    (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))			ext2fs_swap_inode_full(scan->fs,				(struct ext2_inode_large *) inode,				(struct ext2_inode_large *) scan->ptr,				0, bufsize);		else#endif			memcpy(inode, scan->ptr, bufsize);		scan->ptr += scan->inode_size;		scan->bytes_left -= scan->inode_size;		if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)			retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;	}	scan->inodes_left--;	scan->current_inode++;	*ino = scan->current_inode;	return retval;}errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,				struct ext2_inode *inode){	return ext2fs_get_next_inode_full(scan, ino, inode,						sizeof(struct ext2_inode));}/* * Functions to read and write a single inode. */errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,				 struct ext2_inode * inode, int bufsize){	unsigned long	group, block, block_nr, offset;	char		*ptr;	errcode_t	retval;	int		clen, i, inodes_per_block, length;	io_channel	io;	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);	/* Check to see if user has an override function */	if (fs->read_inode) {		retval = (fs->read_inode)(fs, ino, inode);		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)			return retval;	}	/* Create inode cache if not present */	if (!fs->icache) {		retval = create_icache(fs);		if (retval)			return retval;	}	/* Check to see if it's in the inode cache */	if (bufsize == sizeof(struct ext2_inode)) {		/* only old good inode can be retrieve from the cache */		for (i=0; i < fs->icache->cache_size; i++) {			if (fs->icache->cache[i].ino == ino) {				*inode = fs->icache->cache[i].inode;				return 0;			}		}	}	if ((ino == 0) || (ino > fs->super->s_inodes_count))		return EXT2_ET_BAD_INODE_NUM;	if (fs->flags & EXT2_FLAG_IMAGE_FILE) {		inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);		block_nr = fs->image_header->offset_inode / fs->blocksize;		block_nr += (ino - 1) / inodes_per_block;		offset = ((ino - 1) % inodes_per_block) *			EXT2_INODE_SIZE(fs->super);		io = fs->image_io;	} else {		group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);		offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *			EXT2_INODE_SIZE(fs->super);		block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);		if (!fs->group_desc[(unsigned)group].bg_inode_table)			return EXT2_ET_MISSING_INODE_TABLE;		block_nr = fs->group_desc[(unsigned)group].bg_inode_table +			block;		io = fs->io;	}	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);	length = EXT2_INODE_SIZE(fs->super);	if (bufsize < length)		length = bufsize;	ptr = (char *) inode;	while (length) {		clen = length;		if ((offset + length) > fs->blocksize)			clen = fs->blocksize - offset;		if (block_nr != fs->icache->buffer_blk) {			retval = io_channel_read_blk(io, block_nr, 1,						     fs->icache->buffer);			if (retval)				return retval;			fs->icache->buffer_blk = block_nr;		}		memcpy(ptr, ((char *) fs->icache->buffer) + (unsigned) offset,		       clen);		offset = 0;		length -= clen;		ptr += clen;		block_nr++;	}#if BB_BIG_ENDIAN	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||	    (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))		ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) inode,				       (struct ext2_inode_large *) inode,				       0, length);#endif	/* Update the inode cache */	fs->icache->cache_last = (fs->icache->cache_last + 1) %		fs->icache->cache_size;	fs->icache->cache[fs->icache->cache_last].ino = ino;	fs->icache->cache[fs->icache->cache_last].inode = *inode;	return 0;}errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,			    struct ext2_inode * inode){	return ext2fs_read_inode_full(fs, ino, inode,					sizeof(struct ext2_inode));}errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,				  struct ext2_inode * inode, int bufsize){	unsigned long group, block, block_nr, offset;	errcode_t retval = 0;	struct ext2_inode_large temp_inode, *w_inode;	char *ptr;	int clen, i, length;	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);	/* Check to see if user provided an override function */	if (fs->write_inode) {		retval = (fs->write_inode)(fs, ino, inode);		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)			return retval;	}	/* Check to see if the inode cache needs to be updated */	if (fs->icache) {		for (i=0; i < fs->icache->cache_size; i++) {			if (fs->icache->cache[i].ino == ino) {				fs->icache->cache[i].inode = *inode;				break;			}		}	} else {		retval = create_icache(fs);		if (retval)			return retval;	}	if (!(fs->flags & EXT2_FLAG_RW))		return EXT2_ET_RO_FILSYS;	if ((ino == 0) || (ino > fs->super->s_inodes_count))		return EXT2_ET_BAD_INODE_NUM;	length = bufsize;	if (length < EXT2_INODE_SIZE(fs->super))		length = EXT2_INODE_SIZE(fs->super);	if (length > (int) sizeof(struct ext2_inode_large)) {		w_inode = xmalloc(length);	} else		w_inode = &temp_inode;	memset(w_inode, 0, length);#if BB_BIG_ENDIAN	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))		ext2fs_swap_inode_full(fs, w_inode,				       (struct ext2_inode_large *) inode,				       1, bufsize);	else#endif		memcpy(w_inode, inode, bufsize);	group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *		EXT2_INODE_SIZE(fs->super);	block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);	if (!fs->group_desc[(unsigned) group].bg_inode_table)		return EXT2_ET_MISSING_INODE_TABLE;	block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);	length = EXT2_INODE_SIZE(fs->super);	if (length > bufsize)		length = bufsize;	ptr = (char *) w_inode;	while (length) {		clen = length;		if ((offset + length) > fs->blocksize)			clen = fs->blocksize - offset;		if (fs->icache->buffer_blk != block_nr) {			retval = io_channel_read_blk(fs->io, block_nr, 1,						     fs->icache->buffer);			if (retval)				goto errout;			fs->icache->buffer_blk = block_nr;		}		memcpy((char *) fs->icache->buffer + (unsigned) offset,		       ptr, clen);		retval = io_channel_write_blk(fs->io, block_nr, 1,					      fs->icache->buffer);		if (retval)			goto errout;		offset = 0;		ptr += clen;		length -= clen;		block_nr++;	}	fs->flags |= EXT2_FLAG_CHANGED;errout:	if (w_inode && w_inode != &temp_inode)		free(w_inode);	return retval;}errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,			     struct ext2_inode *inode){	return ext2fs_write_inode_full(fs, ino, inode,				       sizeof(struct ext2_inode));}/* * This function should be called when writing a new inode.  It makes * sure that extra part of large inodes is initialized properly. */errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,				 struct ext2_inode *inode){	struct ext2_inode	*buf;	int			size = EXT2_INODE_SIZE(fs->super);	struct ext2_inode_large	*large_inode;	if (size == sizeof(struct ext2_inode))		return ext2fs_write_inode_full(fs, ino, inode,					       sizeof(struct ext2_inode));	buf = xmalloc(size);	memset(buf, 0, size);	*buf = *inode;	large_inode = (struct ext2_inode_large *) buf;	large_inode->i_extra_isize = sizeof(struct ext2_inode_large) -		EXT2_GOOD_OLD_INODE_SIZE;	return ext2fs_write_inode_full(fs, ino, buf, size);}errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks){	struct ext2_inode	inode;	int			i;	errcode_t		retval;	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);	if (ino > fs->super->s_inodes_count)		return EXT2_ET_BAD_INODE_NUM;	if (fs->get_blocks) {		if (!(*fs->get_blocks)(fs, ino, blocks))			return 0;	}	retval = ext2fs_read_inode(fs, ino, &inode);	if (retval)		return retval;	for (i=0; i < EXT2_N_BLOCKS; i++)		blocks[i] = inode.i_block[i];	return 0;}errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino){	struct	ext2_inode	inode;	errcode_t		retval;	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);	if (ino > fs->super->s_inodes_count)		return EXT2_ET_BAD_INODE_NUM;	if (fs->check_directory) {		retval = (fs->check_directory)(fs, ino);		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)			return retval;	}	retval = ext2fs_read_inode(fs, ino, &inode);	if (retval)		return retval;	if (!LINUX_S_ISDIR(inode.i_mode))		return EXT2_ET_NO_DIRECTORY;	return 0;}

⌨️ 快捷键说明

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