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

📄 inode.c

📁 这是Linux系统下的对UDF文件系统新增的功能
💻 C
📖 第 1 页 / 共 4 页
字号:
{	struct fileEntry *fe;	struct extendedFileEntry *efe;	time_t convtime;	long convtime_usec;	int offset;	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) & ICBTAG_FLAG_AD_MASK;	UDF_I_UNIQUE(inode) = 0;	UDF_I_LENEATTR(inode) = 0;	UDF_I_LENEXTENTS(inode) = 0;	UDF_I_LENALLOC(inode) = 0;	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;	UDF_I_NEXT_ALLOC_GOAL(inode) = 0;	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)	{		UDF_I_EFE(inode) = 1;		UDF_I_USE(inode) = 0;		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));	}	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)	{		UDF_I_EFE(inode) = 0;		UDF_I_USE(inode) = 0;		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry));	}	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)	{		UDF_I_EFE(inode) = 0;		UDF_I_USE(inode) = 1;		UDF_I_LENALLOC(inode) =			le32_to_cpu(				((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry), GFP_KERNEL);		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));		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;	if (UDF_I_EFE(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.tv_sec = convtime;			inode->i_atime.tv_nsec = convtime_usec * 1000;		}		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.tv_sec = convtime;			inode->i_mtime.tv_nsec = convtime_usec * 1000;		}		else		{			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);		}		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(fe->attrTime)) )		{			inode->i_ctime.tv_sec = convtime;			inode->i_ctime.tv_nsec = convtime_usec * 1000;		}		else		{			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);		}		UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);		UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);		UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);		offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);	}	else	{		inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << 			(inode->i_sb->s_blocksize_bits - 9);		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(efe->accessTime)) )		{			inode->i_atime.tv_sec = convtime;			inode->i_atime.tv_nsec = convtime_usec * 1000;		}		else		{			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);		}		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(efe->modificationTime)) )		{			inode->i_mtime.tv_sec = convtime;			inode->i_mtime.tv_nsec = convtime_usec * 1000;		}		else		{			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);		}		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(efe->createTime)) )		{			UDF_I_CRTIME(inode).tv_sec = convtime;			UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;		}		else		{			UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);		}		if ( udf_stamp_to_time(&convtime, &convtime_usec,			lets_to_cpu(efe->attrTime)) )		{			inode->i_ctime.tv_sec = convtime;			inode->i_ctime.tv_nsec = convtime_usec * 1000;		}		else		{			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);		}		UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);		UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);		UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);		offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);	}	switch (fe->icbTag.fileType)	{		case ICBTAG_FILE_TYPE_DIRECTORY:		{			inode->i_op = &udf_dir_inode_operations;			inode->i_fop = &udf_dir_operations;			inode->i_mode |= S_IFDIR;			inode->i_nlink ++;			break;		}		case ICBTAG_FILE_TYPE_REALTIME:		case ICBTAG_FILE_TYPE_REGULAR:		case ICBTAG_FILE_TYPE_UNDEF:		{			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)				inode->i_data.a_ops = &udf_adinicb_aops;			else				inode->i_data.a_ops = &udf_aops;			inode->i_op = &udf_file_inode_operations;			inode->i_fop = &udf_file_operations;			inode->i_mode |= S_IFREG;			break;		}		case ICBTAG_FILE_TYPE_BLOCK:		{			inode->i_mode |= S_IFBLK;			break;		}		case ICBTAG_FILE_TYPE_CHAR:		{			inode->i_mode |= S_IFCHR;			break;		}		case ICBTAG_FILE_TYPE_FIFO:		{			init_special_inode(inode, inode->i_mode | S_IFIFO, 0);			break;		}		case ICBTAG_FILE_TYPE_SOCKET:		{			init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);			break;		}		case ICBTAG_FILE_TYPE_SYMLINK:		{			inode->i_data.a_ops = &udf_symlink_aops;			inode->i_op = &page_symlink_inode_operations;			inode->i_mode = S_IFLNK|S_IRWXUGO;			break;		}		default:		{			printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",				inode->i_ino, fe->icbTag.fileType);			make_bad_inode(inode);			return;		}	}	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))	{		struct deviceSpec *dsea =			(struct deviceSpec *)				udf_get_extendedattr(inode, 12, 1);		if (dsea)		{			init_special_inode(inode, inode->i_mode, MKDEV(				le32_to_cpu(dsea->majorDeviceIdent),				le32_to_cpu(dsea->minorDeviceIdent)));			/* Developer ID ??? */		}		else		{			make_bad_inode(inode);		}	}}static mode_tudf_convert_permissions(struct fileEntry *fe){	mode_t mode;	uint32_t permissions;	uint32_t flags;	permissions = le32_to_cpu(fe->permissions);	flags = le16_to_cpu(fe->icbTag.flags);	mode =	(( permissions      ) & S_IRWXO) |		(( permissions >> 2 ) & S_IRWXG) |		(( permissions >> 4 ) & S_IRWXU) |		(( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |		(( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |		(( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);	return mode;}/* * udf_write_inode * * PURPOSE *	Write out the specified inode. * * DESCRIPTION *	This routine is called whenever an inode is synced. *	Currently this routine is just a placeholder. * * HISTORY *	July 1, 1997 - Andrew E. Mileski *	Written, tested, and released. */void udf_write_inode(struct inode * inode, int sync){	lock_kernel();	udf_update_inode(inode, sync);	unlock_kernel();}int udf_sync_inode(struct inode * inode){	return udf_update_inode(inode, 1);}static intudf_update_inode(struct inode *inode, int do_sync){	struct buffer_head *bh = NULL;	struct fileEntry *fe;	struct extendedFileEntry *efe;	uint32_t udfperms;	uint16_t icbflags;	uint16_t crclen;	int i;	timestamp cpu_time;	int err = 0;	bh = udf_tread(inode->i_sb,		udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));	if (!bh)	{		udf_debug("bread failure\n");		return -EIO;	}	memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);	fe = (struct fileEntry *)bh->b_data;	efe = (struct extendedFileEntry *)bh->b_data;	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)	{		struct unallocSpaceEntry *use =			(struct unallocSpaceEntry *)bh->b_data;		use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));		crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -			sizeof(tag);		use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);		use->descTag.descCRCLength = cpu_to_le16(crclen);		use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));		use->descTag.tagChecksum = 0;		for (i=0; i<16; i++)			if (i != 4)				use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];		mark_buffer_dirty(bh);		udf_release_data(bh);		return err;	}	if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)		fe->uid = cpu_to_le32(inode->i_uid);	if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)		fe->gid = cpu_to_le32(inode->i_gid);	udfperms =	((inode->i_mode & S_IRWXO)     ) |			((inode->i_mode & S_IRWXG) << 2) |			((inode->i_mode & S_IRWXU) << 4);	udfperms |=	(le32_to_cpu(fe->permissions) &			(FE_PERM_O_DELETE | FE_PERM_O_CHATTR |			 FE_PERM_G_DELETE | FE_PERM_G_CHATTR |			 FE_PERM_U_DELETE | FE_PERM_U_CHATTR));	fe->permissions = cpu_to_le32(udfperms);	if (S_ISDIR(inode->i_mode))		fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);	else		fe->fileLinkCount = cpu_to_le16(inode->i_nlink);	fe->informationLength = cpu_to_le64(inode->i_size);	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))	{		regid *eid;		struct deviceSpec *dsea =			(struct deviceSpec *)				udf_get_extendedattr(inode, 12, 1);			if (!dsea)		{			dsea = (struct deviceSpec *)				udf_add_extendedattr(inode,					sizeof(struct deviceSpec) +					sizeof(regid), 12, 0x3);			dsea->attrType = 12;			dsea->attrSubtype = 1;			dsea->attrLength = sizeof(struct deviceSpec) +				sizeof(regid);			dsea->impUseLength = sizeof(regid);		}		eid = (regid *)dsea->impUse;		memset(eid, 0, sizeof(regid));		strcpy(eid->ident, UDF_ID_DEVELOPER);		eid->identSuffix[0] = UDF_OS_CLASS_UNIX;		eid->identSuffix[1] = UDF_OS_ID_LINUX;		dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));		dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));	}	if (UDF_I_EFE(inode) == 0)	{		memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry));		fe->logicalBlocksRecorded = cpu_to_le64(			(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>			(inode->i_sb->s_blocksize_bits - 9));		if (udf_time_to_stamp(&cpu_time, inode->i_atime))			fe->accessTime = cpu_to_lets(cpu_time);		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))			fe->modificationTime = cpu_to_lets(cpu_time);		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))			fe->attrTime = cpu_to_lets(cpu_time);		memset(&(fe->impIdent), 0, sizeof(regid));		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;		fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));		fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));		fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));		fe->descTag.tagIdent = le16_to_cpu(TAG_IDENT_FE);		crclen = sizeof(struct fileEntry);	}	else	{		memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));		efe->objectSize = cpu_to_le64(inode->i_size);		efe->logicalBlocksRecorded = cpu_to_le64(			(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>			(inode->i_sb->s_blocksize_bits - 9));		if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||			(UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&			 UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec))		{			UDF_I_CRTIME(inode) = inode->i_atime;		}		if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||			(UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&			 UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec))		{			UDF_I_CRTIME(inode) = inode->i_mtime;		}		if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||			(UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&			 UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec))		{			UDF_I_CRTIME(inode) = inode->i_ctime;		}		if (udf_time_to_stamp(&cpu_time, inode->i_atime))			efe->accessTime = cpu_to_lets(cpu_time);		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))			efe->modificationTime = cpu_to_lets(cpu_time);		if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))			efe->createTime = cpu_to_lets(cpu_time);		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))			efe->attrTime = cpu_to_lets(cpu_time);		memset(&(efe->impIdent), 0, sizeof(regid));		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;		efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));		efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));		efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));		efe->descTag.tagIdent = le16_to_cpu(TAG_IDENT_EFE);		crclen = sizeof(struct extendedFileEntry);	}	if (UDF_I_STRAT4096(inode))	{		fe->icbTag.strategyType = cpu_to_le16(4096);		fe->icbTag.strategyParameter = cpu_to_le16(1);		fe->icbTag.numEntries = cpu_to_le16(2);	}	else	{		fe->icbTag.strategyType = cpu_to_le16(4);		fe->icbTag.numEntries = cpu_to_le16(1);	}	if (S_ISDIR(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;	else if (S_ISREG(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;	else if (S_ISLNK(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;	else if (S_ISBLK(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;	else if (S_ISCHR(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;	else if (S_ISFIFO(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;	else if (S_ISSOCK(inode->i_mode))		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;	icbflags =	UDF_I_ALLOCTYPE(inode) |			((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |			((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |			((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |			(le16_to_cpu(fe->icbTag.flags) &				~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |				ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));	fe->icbTag.flags = cpu_to_le16(icbflags);	if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)		fe->descTag.descVersion = cpu_to_le16(3);	else		fe->descTag.descVersion = cpu_to_le16(2);	fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));	fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);	crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);	fe->descTag.descCRCLength = cpu_to_le16(crclen);	fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));	fe->descTag.tagChecksum = 0;	for (i=0; i<16; i++)		if (i != 4)			fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];	/* write the data blocks */	mark_buffer_dirty(bh);	if (do_sync)	{		sync_dirty_buffer(bh);		if (buffer_req(bh) && !buffer_uptodate(bh))		{			printk("IO error syncing udf inode [%s:%08lx]\n",				inode->i_sb->s_id, inode->i_ino);			err = -EIO;		}	}

⌨️ 快捷键说明

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