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

📄 inode.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 4 页
字号:
		aed = (struct AllocExtDesc *)(nbh->b_data);		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);		if (*extoffset + adsize > inode->i_sb->s_blocksize)		{			loffset = *extoffset;			aed->lengthAllocDescs = cpu_to_le32(adsize);			sptr = (*bh)->b_data + *extoffset - adsize;			dptr = nbh->b_data + sizeof(struct AllocExtDesc);			memcpy(dptr, sptr, adsize);			*extoffset = sizeof(struct AllocExtDesc) + adsize;		}		else		{			loffset = *extoffset + adsize;			aed->lengthAllocDescs = cpu_to_le32(0);			sptr = (*bh)->b_data + *extoffset;			*extoffset = sizeof(struct AllocExtDesc);			if (memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))			{				aed = (struct AllocExtDesc *)(*bh)->b_data;				aed->lengthAllocDescs =					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);			}			else			{				UDF_I_LENALLOC(inode) += adsize;				mark_inode_dirty(inode);			}		}		udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1,			bloc->logicalBlockNum, sizeof(tag));		switch (UDF_I_ALLOCTYPE(inode))		{			case ICB_FLAG_AD_SHORT:			{				sad = (short_ad *)sptr;				sad->extLength = cpu_to_le32(					EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |					inode->i_sb->s_blocksize);				sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);				break;			}			case ICB_FLAG_AD_LONG:			{				lad = (long_ad *)sptr;				lad->extLength = cpu_to_le32(					EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |					inode->i_sb->s_blocksize);				lad->extLocation = cpu_to_lelb(*bloc);				memset(lad->impUse, 0x00, sizeof(lad->impUse));				break;			}		}		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)			udf_update_tag((*bh)->b_data, loffset);		else			udf_update_tag((*bh)->b_data, sizeof(struct AllocExtDesc));		mark_buffer_dirty_inode(*bh, inode);		udf_release_data(*bh);		*bh = nbh;	}	ret = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))	{		UDF_I_LENALLOC(inode) += adsize;		mark_inode_dirty(inode);	}	else	{		aed = (struct AllocExtDesc *)(*bh)->b_data;		aed->lengthAllocDescs =			cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)			udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));		else			udf_update_tag((*bh)->b_data, sizeof(struct AllocExtDesc));		mark_buffer_dirty_inode(*bh, inode);	}	return ret;}Sint8 udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,    lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc){	int adsize;	short_ad *sad = NULL;	long_ad *lad = NULL;	if (!(bh))	{		if (!(bh = udf_tread(inode->i_sb,			udf_get_lb_pblock(inode->i_sb, bloc, 0))))		{			udf_debug("reading block %d failed!\n",				udf_get_lb_pblock(inode->i_sb, bloc, 0));			return -1;		}	}	else		atomic_inc(&bh->b_count);	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)		adsize = sizeof(short_ad);	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)		adsize = sizeof(long_ad);	else		return -1;	switch (UDF_I_ALLOCTYPE(inode))	{		case ICB_FLAG_AD_SHORT:		{			sad = (short_ad *)((bh)->b_data + *extoffset);			sad->extLength = cpu_to_le32(elen);			sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);			break;		}		case ICB_FLAG_AD_LONG:		{			lad = (long_ad *)((bh)->b_data + *extoffset);			lad->extLength = cpu_to_le32(elen);			lad->extLocation = cpu_to_lelb(eloc);			memset(lad->impUse, 0x00, sizeof(lad->impUse));			break;		}	}	if (memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))	{		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)		{			struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh)->b_data;			udf_update_tag((bh)->b_data,				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct AllocExtDesc));		}		mark_buffer_dirty_inode(bh, inode);	}	else	{		mark_inode_dirty(inode);		mark_buffer_dirty(bh);	}	if (inc)		*extoffset += adsize;	udf_release_data(bh);	return (elen >> 30);}Sint8 udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc){	Uint16 tagIdent;	int pos, alen;	Sint8 etype;	if (!(*bh))	{		if (!(*bh = udf_tread(inode->i_sb,			udf_get_lb_pblock(inode->i_sb, *bloc, 0))))		{			udf_debug("reading block %d failed!\n",				udf_get_lb_pblock(inode->i_sb, *bloc, 0));			return -1;		}	}	tagIdent = ((tag *)(*bh)->b_data)->tagIdent;	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))	{		if (tagIdent == TID_FILE_ENTRY || tagIdent == TID_EXTENDED_FILE_ENTRY ||			UDF_I_NEW_INODE(inode))		{			pos = udf_file_entry_alloc_offset(inode);			alen = UDF_I_LENALLOC(inode) + pos;		}		else if (tagIdent == TID_UNALLOCATED_SPACE_ENTRY)		{			pos = sizeof(struct UnallocatedSpaceEntry);			alen = UDF_I_LENALLOC(inode) + pos;		}		else			return -1;	}	else if (tagIdent == TID_ALLOC_EXTENT_DESC)	{		struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;		pos = sizeof(struct AllocExtDesc);		alen = le32_to_cpu(aed->lengthAllocDescs) + pos;	}	else		return -1;	if (!(*extoffset))		*extoffset = pos;	switch (UDF_I_ALLOCTYPE(inode))	{		case ICB_FLAG_AD_SHORT:		{			short_ad *sad;			if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc)))				return -1;			if ((etype = le32_to_cpu(sad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS)			{				bloc->logicalBlockNum = le32_to_cpu(sad->extPosition);				*extoffset = 0;				udf_release_data(*bh);				*bh = NULL;				return udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, inc);			}			else			{				eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);				eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;				*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;			}			break;		}		case ICB_FLAG_AD_LONG:		{			long_ad *lad;			if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc)))				return -1;			if ((etype = le32_to_cpu(lad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS)			{				*bloc = lelb_to_cpu(lad->extLocation);				*extoffset = 0;				udf_release_data(*bh);				*bh = NULL;				return udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, inc);			}			else			{				*eloc = lelb_to_cpu(lad->extLocation);				*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;			}			break;		}		case ICB_FLAG_AD_IN_ICB:		{			if (UDF_I_LENALLOC(inode) == 0)				return -1;			etype = EXTENT_RECORDED_ALLOCATED;			*eloc = UDF_I_LOCATION(inode);			*elen = UDF_I_LENALLOC(inode);			break;		}		default:		{			udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));			return -1;		}	}	if (*elen)		return etype;	udf_debug("Empty Extent, inode=%ld, alloctype=%d, eloc=%d, elen=%d, etype=%d, extoffset=%d\n",		inode->i_ino, UDF_I_ALLOCTYPE(inode), eloc->logicalBlockNum, *elen, etype, *extoffset);	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)		*extoffset -= sizeof(short_ad);	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)		*extoffset -= sizeof(long_ad);	return -1;}Sint8 udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc){	int pos, alen;	Sint8 etype;	if (!(*bh))	{		if (!(*bh = udf_tread(inode->i_sb,			udf_get_lb_pblock(inode->i_sb, *bloc, 0))))		{			udf_debug("reading block %d failed!\n",				udf_get_lb_pblock(inode->i_sb, *bloc, 0));			return -1;		}	}	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))	{		if (!(UDF_I_EXTENDED_FE(inode)))			pos = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode);		else			pos = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode);		alen = UDF_I_LENALLOC(inode) + pos;	}	else	{		struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;		pos = sizeof(struct AllocExtDesc);		alen = le32_to_cpu(aed->lengthAllocDescs) + pos;	}	if (!(*extoffset))		*extoffset = pos;	switch (UDF_I_ALLOCTYPE(inode))	{		case ICB_FLAG_AD_SHORT:		{			short_ad *sad;			if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc)))				return -1;			etype = le32_to_cpu(sad->extLength) >> 30;			eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);			eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;			*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;			break;		}		case ICB_FLAG_AD_LONG:		{			long_ad *lad;			if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc)))				return -1;			etype = le32_to_cpu(lad->extLength) >> 30;			*eloc = lelb_to_cpu(lad->extLocation);			*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;			break;		}		default:		{			udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));			return -1;		}	}	if (*elen)		return etype;	udf_debug("Empty Extent!\n");	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)		*extoffset -= sizeof(short_ad);	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)		*extoffset -= sizeof(long_ad);	return -1;}Sint8 udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,	lb_addr neloc, Uint32 nelen, struct buffer_head *bh){	lb_addr oeloc;	Uint32 oelen;	Sint8 etype;	if (!bh)	{		if (!(bh = udf_tread(inode->i_sb,			udf_get_lb_pblock(inode->i_sb, bloc, 0))))		{			udf_debug("reading block %d failed!\n",				udf_get_lb_pblock(inode->i_sb, bloc, 0));			return -1;		}	}	else		atomic_inc(&bh->b_count);	while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)	{		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);		neloc = oeloc;		nelen = (etype << 30) | oelen;	}	udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);	udf_release_data(bh);	return (nelen >> 30);}Sint8 udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,	lb_addr eloc, Uint32 elen, struct buffer_head *nbh){	struct buffer_head *obh;	lb_addr obloc;	int oextoffset, adsize;	Sint8 etype;	struct AllocExtDesc *aed;	if (!(nbh))	{		if (!(nbh = udf_tread(inode->i_sb,			udf_get_lb_pblock(inode->i_sb, nbloc, 0))))		{			udf_debug("reading block %d failed!\n",				udf_get_lb_pblock(inode->i_sb, nbloc, 0));			return -1;		}	}	else		atomic_inc(&nbh->b_count);	atomic_inc(&nbh->b_count);	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)		adsize = sizeof(short_ad);	else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)		adsize = sizeof(long_ad);	else		adsize = 0;	obh = nbh;	obloc = nbloc;	oextoffset = nextoffset;	if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)		return -1;	while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)	{		udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);		if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))		{			obloc = nbloc;			udf_release_data(obh);			atomic_inc(&nbh->b_count);			obh = nbh;			oextoffset = nextoffset - adsize;		}	}	memset(&eloc, 0x00, sizeof(lb_addr));	elen = 0;	if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))	{		udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);		if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))		{			UDF_I_LENALLOC(inode) -= (adsize * 2);			mark_inode_dirty(inode);		}		else		{			aed = (struct AllocExtDesc *)(obh)->b_data;			aed->lengthAllocDescs =				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)				udf_update_tag((obh)->b_data, oextoffset - (2*adsize));			else				udf_update_tag((obh)->b_data, sizeof(struct AllocExtDesc));			mark_buffer_dirty_inode(obh, inode);		}	}	else	{		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);		if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))		{			UDF_I_LENALLOC(inode) -= adsize;			mark_inode_dirty(inode);		}		else		{			aed = (struct AllocExtDesc *)(obh)->b_data;			aed->lengthAllocDescs =				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)				udf_update_tag((obh)->b_data, oextoffset - adsize);			else				udf_update_tag((obh)->b_data, sizeof(struct AllocExtDesc));			mark_buffer_dirty_inode(obh, inode);		}	}		udf_release_data(nbh);	udf_release_data(obh);	return (elen >> 30);}Sint8 inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,	lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh){	Uint64 lbcount = 0, bcount = (Uint64)block << inode->i_sb->s_blocksize_bits;	Sint8 etype;	if (block < 0)	{		printk(KERN_ERR "udf: inode_bmap: block < 0\n");		return -1;	}	if (!inode)	{		printk(KERN_ERR "udf: inode_bmap: NULL inode\n");		return -1;	}	*extoffset = 0;	*elen = 0;	*bloc = UDF_I_LOCATION(inode);	do	{		if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)		{			*offset = bcount - lbcount;			UDF_I_LENEXTENTS(inode) = lbcount;			return -1;		}		lbcount += *elen;	} while (lbcount <= bcount);	*offset = bcount + *elen - lbcount;	return etype;}long udf_block_map(struct inode *inode, long block){	lb_addr eloc, bloc;	Uint32 offset, extoffset, elen;	struct buffer_head *bh = NULL;	int ret;	lock_kernel();	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);	else		ret = 0;	unlock_kernel();	if (bh)		udf_release_data(bh);	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))		return udf_fixed_to_variable(ret);	else		return ret;}

⌨️ 快捷键说明

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