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

📄 inode.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 4 页
字号:
		{			udf_release_data(pbh);			*err = -ENOSPC;			return NULL;		}		UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;	}	/* if the extent the requsted block is located in contains multiple blocks,       split the extent into at most three extents. blocks prior to requested       block, requested block, and blocks after requested block */	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);#ifdef UDF_PREALLOCATE	/* preallocate blocks */	udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);#endif	/* merge any continuous blocks in laarr */	udf_merge_extents(inode, laarr, &endnum);	/* write back the new extents, inserting new extents if the new number       of extents is greater than the old number, and deleting extents if       the new number of extents is less than the old number */	udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);	udf_release_data(pbh);	if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,		UDF_I_LOCATION(inode).partitionReferenceNum, 0)))	{		return NULL;	}	*phys = newblock;	*err = 0;	*new = 1;	UDF_I_NEXT_ALLOC_BLOCK(inode) = block;	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;	inode->i_ctime = CURRENT_TIME;	UDF_I_UCTIME(inode) = CURRENT_UTIME;	if (IS_SYNC(inode))		udf_sync_inode(inode);	else		mark_inode_dirty(inode);	return result;}static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,	long_ad laarr[EXTENT_MERGE_SIZE], int *endnum){	if ((laarr[*c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED ||		(laarr[*c].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)	{		int curr = *c;		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;		int type = laarr[curr].extLength & ~UDF_EXTENT_LENGTH_MASK;		if (blen == 1)			;		else if (!offset || blen == offset + 1)		{			laarr[curr+2] = laarr[curr+1];			laarr[curr+1] = laarr[curr];		}		else		{			laarr[curr+3] = laarr[curr+1];			laarr[curr+2] = laarr[curr+1] = laarr[curr];		}		if (offset)		{			if ((type >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)			{				udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);				laarr[curr].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |					(offset << inode->i_sb->s_blocksize_bits);				laarr[curr].extLocation.logicalBlockNum = 0;				laarr[curr].extLocation.partitionReferenceNum = 0;			}			else				laarr[curr].extLength = type |					(offset << inode->i_sb->s_blocksize_bits);			curr ++;			(*c) ++;			(*endnum) ++;		}				laarr[curr].extLocation.logicalBlockNum = newblocknum;		if ((type >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)			laarr[curr].extLocation.partitionReferenceNum =				UDF_I_LOCATION(inode).partitionReferenceNum;		laarr[curr].extLength = (EXTENT_RECORDED_ALLOCATED << 30) |			inode->i_sb->s_blocksize;		curr ++;		if (blen != offset + 1)		{			if ((type >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)				laarr[curr].extLocation.logicalBlockNum += (offset + 1);			laarr[curr].extLength = type |				((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);			curr ++;			(*endnum) ++;		}	}}static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,	 long_ad laarr[EXTENT_MERGE_SIZE], int *endnum){	int start, length = 0, currlength = 0, i;	if (*endnum >= (c+1))	{		if (!lastblock)			return;		else			start = c;	}	else	{		if ((laarr[c+1].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)		{			start = c+1;			length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);		}		else			start = c;	}	for (i=start+1; i<=*endnum; i++)	{		if (i == *endnum)		{			if (lastblock)				length += UDF_DEFAULT_PREALLOC_BLOCKS;		}		else if ((laarr[i].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)			length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);		else			break;	}	if (length)	{		int next = laarr[start].extLocation.logicalBlockNum +			(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,			laarr[start].extLocation.partitionReferenceNum,			next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :				UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);		if (numalloc)		{			UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;			if (start == (c+1))				laarr[start].extLength +=					(numalloc << inode->i_sb->s_blocksize_bits);			else			{				memmove(&laarr[c+2], &laarr[c+1],					sizeof(long_ad) * (*endnum - (c+1)));				(*endnum) ++;				laarr[c+1].extLocation.logicalBlockNum = next;				laarr[c+1].extLocation.partitionReferenceNum =					laarr[c].extLocation.partitionReferenceNum;				laarr[c+1].extLength = (EXTENT_NOT_RECORDED_ALLOCATED << 30) |					(numalloc << inode->i_sb->s_blocksize_bits);				start = c+1;			}			for (i=start+1; numalloc && i<*endnum; i++)			{				int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +					inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;				if (elen > numalloc)				{					laarr[c+1].extLength -=						(numalloc << inode->i_sb->s_blocksize_bits);					numalloc = 0;				}				else				{					numalloc -= elen;					if (*endnum > (i+1))						memmove(&laarr[i], &laarr[i+1], 							sizeof(long_ad) * (*endnum - (i+1)));					i --;					(*endnum) --;				}			}		}	}}static void udf_merge_extents(struct inode *inode,	 long_ad laarr[EXTENT_MERGE_SIZE], int *endnum){	int i;	for (i=0; i<(*endnum-1); i++)	{		if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))		{			if (((laarr[i].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED) ||				((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==				(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))			{				if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +					(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +					inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)				{					laarr[i+1].extLength = (laarr[i+1].extLength -						(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +						UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);					laarr[i].extLength = (UDF_EXTENT_LENGTH_MASK + 1) -						inode->i_sb->s_blocksize;					laarr[i+1].extLocation.logicalBlockNum =						laarr[i].extLocation.logicalBlockNum +						((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>							inode->i_sb->s_blocksize_bits);				}				else				{					laarr[i].extLength = laarr[i+1].extLength +						(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +						inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));					if (*endnum > (i+2))						memmove(&laarr[i+1], &laarr[i+2],							sizeof(long_ad) * (*endnum - (i+2)));					i --;					(*endnum) --;				}			}		}	}}static void udf_update_extents(struct inode *inode,	long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,	lb_addr pbloc, Uint32 pextoffset, struct buffer_head **pbh){	int start = 0, i;	lb_addr tmploc;	Uint32 tmplen;	if (startnum > endnum)	{		for (i=0; i<(startnum-endnum); i++)		{			udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,				laarr[i].extLength, *pbh);		}	}	else if (startnum < endnum)	{		for (i=0; i<(endnum-startnum); i++)		{			udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,				laarr[i].extLength, *pbh);			udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,				&laarr[i].extLength, pbh, 1);			start ++;		}	}	for (i=start; i<endnum; i++)	{		udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);		udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,			laarr[i].extLength, *pbh, 1);	}}struct buffer_head * udf_bread(struct inode * inode, int block,	int create, int * err){	struct buffer_head * bh = NULL;	bh = udf_getblk(inode, block, create, err);	if (!bh)		return NULL;	if (buffer_uptodate(bh))		return bh;	ll_rw_block(READ, 1, &bh);	wait_on_buffer(bh);	if (buffer_uptodate(bh))		return bh;	brelse(bh);	*err = -EIO;	return NULL;}void udf_truncate(struct inode * inode){	int offset;	struct buffer_head *bh;	int err;	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||			S_ISLNK(inode->i_mode)))		return;	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))		return;	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)	{		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +			inode->i_size))		{			udf_expand_file_adinicb(inode, inode->i_size, &err);			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)			{				inode->i_size = UDF_I_LENALLOC(inode);				return;			}			else				udf_truncate_extents(inode);		}		else		{			offset = (inode->i_size & (inode->i_sb->s_blocksize - 1)) +				udf_file_entry_alloc_offset(inode);			if ((bh = udf_tread(inode->i_sb,				udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0))))			{				memset(bh->b_data + offset, 0x00, inode->i_sb->s_blocksize - offset);				mark_buffer_dirty(bh);				udf_release_data(bh);			}			UDF_I_LENALLOC(inode) = inode->i_size;		}	}	else	{		block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);		udf_truncate_extents(inode);	}		inode->i_mtime = inode->i_ctime = CURRENT_TIME;	UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME;	if (IS_SYNC(inode))		udf_sync_inode (inode);	else		mark_inode_dirty(inode);}/* * udf_read_inode * * PURPOSE *	Read an inode. * * DESCRIPTION *	This routine is called by iget() [which is called by udf_iget()] *      (clean_inode() will have been called first) *	when an inode is first read into memory. * * HISTORY *	July 1, 1997 - Andrew E. Mileski *	Written, tested, and released. * * 12/19/98 dgb  Updated to fix size problems. */voidudf_read_inode(struct inode *inode){	memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(lb_addr));}void__udf_read_inode(struct inode *inode){	struct buffer_head *bh = NULL;	struct FileEntry *fe;	Uint16 ident;	/*	 * Set defaults, but the inode is still incomplete!	 * Note: get_new_inode() sets the following on a new inode:	 *      i_sb = sb	 *      i_dev = sb->s_dev;	 *      i_no = ino	 *      i_flags = sb->s_flags	 *      i_state = 0	 * clean_inode(): zero fills and sets	 *      i_count = 1	 *      i_nlink = 1	 *      i_op = NULL;	 */	inode->i_blksize = PAGE_SIZE;	bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);	if (!bh)	{		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",			inode->i_ino);		make_bad_inode(inode);		return;	}	if (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY &&		ident != TID_UNALLOCATED_SPACE_ENTRY)	{		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",			inode->i_ino, ident);		udf_release_data(bh);		make_bad_inode(inode);		return;	}	fe = (struct FileEntry *)bh->b_data;	if (le16_to_cpu(fe->icbTag.strategyType) == 4096)	{		struct buffer_head *ibh = NULL, *nbh = NULL;		struct IndirectEntry *ie;		ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);		if (ident == TID_INDIRECT_ENTRY)		{			if (ibh)			{				lb_addr loc;				ie = (struct IndirectEntry *)ibh->b_data;					loc = lelb_to_cpu(ie->indirectICB.extLocation);					if (ie->indirectICB.extLength && 					(nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))				{					if (ident == TID_FILE_ENTRY ||						ident == TID_EXTENDED_FILE_ENTRY)					{						memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(lb_addr));						udf_release_data(bh);						udf_release_data(ibh);						udf_release_data(nbh);						__udf_read_inode(inode);						return;					}					else					{						udf_release_data(nbh);						udf_release_data(ibh);					}				}				else					udf_release_data(ibh);			}		}		else			udf_release_data(ibh);	}	else if (le16_to_cpu(fe->icbTag.strategyType) != 4)	{		printk(KERN_ERR "udf: unsupported strategy type: %d\n",			le16_to_cpu(fe->icbTag.strategyType));		udf_release_data(bh);		make_bad_inode(inode);		return;	}	udf_fill_inode(inode, bh);	udf_release_data(bh);}static void udf_fill_inode(struct inode *inode, struct buffer_head *bh){	struct FileEntry *fe;	struct ExtendedFileEntry *efe;	time_t convtime;	long convtime_usec;	int offset, alen;	inode->i_version = ++event;	UDF_I_NEW_INODE(inode) = 0;	fe = (struct FileEntry *)bh->b_data;	efe = (struct ExtendedFileEntry *)bh->b_data;	if (le16_to_cpu(fe->icbTag.strategyType) == 4)		UDF_I_STRAT4096(inode) = 0;	else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */		UDF_I_STRAT4096(inode) = 1;	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICB_FLAG_ALLOC_MASK;	if (fe->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY)		UDF_I_EXTENDED_FE(inode) = 1;	else if (fe->descTag.tagIdent == TID_FILE_ENTRY)		UDF_I_EXTENDED_FE(inode) = 0;	else if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)	{		UDF_I_LENALLOC(inode) =			le32_to_cpu(				((struct UnallocatedSpaceEntry *)bh->b_data)->lengthAllocDescs);		return;	}	inode->i_uid = le32_to_cpu(fe->uid);	if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;	inode->i_gid = le32_to_cpu(fe->gid);	if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;	inode->i_nlink = le16_to_cpu(fe->fileLinkCount);	if (!inode->i_nlink)		inode->i_nlink = 1;		inode->i_size = le64_to_cpu(fe->informationLength);	UDF_I_LENEXTENTS(inode) = inode->i_size;	inode->i_mode = udf_convert_permissions(fe);	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;	UDF_I_NEXT_ALLOC_GOAL(inode) = 0;	if (UDF_I_EXTENDED_FE(inode) == 0)	{		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<			(inode->i_sb->s_blocksize_bits - 9);		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(fe->accessTime)) )		{			inode->i_atime = convtime;		}		else		{			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);		}		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(fe->modificationTime)) )		{			inode->i_mtime = convtime;			UDF_I_UMTIME(inode) = convtime_usec;		}		else		{			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);

⌨️ 快捷键说明

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