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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;					udf_debug("unallocSpaceTable (part %d) @ %ld\n",						  i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);				}				if (phd->unallocSpaceBitmap.extLength) {					UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);					if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL) {						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =							le32_to_cpu(phd->unallocSpaceBitmap.extLength);						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =							le32_to_cpu(phd->unallocSpaceBitmap.extPosition);						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;						udf_debug("unallocSpaceBitmap (part %d) @ %d\n",							  i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);					}				}				if (phd->partitionIntegrityTable.extLength)					udf_debug("partitionIntegrityTable (part %d)\n", i);				if (phd->freedSpaceTable.extLength) {					kernel_lb_addr loc = {						.logicalBlockNum = le32_to_cpu(phd->freedSpaceTable.extPosition),						.partitionReferenceNum = i,					};					UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =						udf_iget(sb, loc);					if (!UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table) {						udf_debug("cannot load freedSpaceTable (part %d)\n", i);						return 1;					}					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;					udf_debug("freedSpaceTable (part %d) @ %ld\n",						  i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);				}				if (phd->freedSpaceBitmap.extLength) {					UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);					if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL) {						UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =							le32_to_cpu(phd->freedSpaceBitmap.extLength);						UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =							le32_to_cpu(phd->freedSpaceBitmap.extPosition);						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;						udf_debug("freedSpaceBitmap (part %d) @ %d\n",							  i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);					}				}			}			break;		}	}	if (i == UDF_SB_NUMPARTS(sb)) {		udf_debug("Partition (%d) not found in partition map\n",			  le16_to_cpu(p->partitionNumber));	} else {		udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n",			  le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),			  UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));	}	return 0;}static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,			       kernel_lb_addr *fileset){	struct logicalVolDesc *lvd;	int i, j, offset;	uint8_t type;	lvd = (struct logicalVolDesc *)bh->b_data;	UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));	for (i = 0, offset = 0;	     i < UDF_SB_NUMPARTS(sb) && offset < le32_to_cpu(lvd->mapTableLength);	     i++, offset += ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength) {		type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;		if (type == 1) {			struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]);			UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;			UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);			UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);			UDF_SB_PARTFUNC(sb,i) = NULL;		} else if (type == 2) {			struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);			if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL))) {				if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0150) {					UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;					UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;				} else if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0200) {					UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;					UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;				}			} else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE))) {				uint32_t loc;				uint16_t ident;				struct sparingTable *st;				struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]);				UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;				UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);				for (j = 0; j < spm->numSparingTables; j++) {					loc = le32_to_cpu(spm->locSparingTable[j]);					UDF_SB_TYPESPAR(sb,i).s_spar_map[j] =						udf_read_tagged(sb, loc, loc, &ident);					if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) {						st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;						if (ident != 0 ||						    strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) {							brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);							UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;						}					}				}				UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;			} else {				udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);				continue;			}			UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);			UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);		}		udf_debug("Partition (%d:%d) type %d on volume %d\n",			  i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));	}	if (fileset) {		long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);		*fileset = lelb_to_cpu(la->extLocation);		udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",			  fileset->logicalBlockNum,			  fileset->partitionReferenceNum);	}	if (lvd->integritySeqExt.extLength)		udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));	return 0;}/* * udf_load_logicalvolint * */static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc){	struct buffer_head *bh = NULL;	uint16_t ident;	while (loc.extLength > 0 &&	       (bh = udf_read_tagged(sb, loc.extLocation,				     loc.extLocation, &ident)) &&	       ident == TAG_IDENT_LVID) {		UDF_SB_LVIDBH(sb) = bh;		if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)			udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));		if (UDF_SB_LVIDBH(sb) != bh)			brelse(bh);		loc.extLength -= sb->s_blocksize;		loc.extLocation++;	}	if (UDF_SB_LVIDBH(sb) != bh)		brelse(bh);}/* * udf_process_sequence * * PURPOSE *	Process a main/reserve volume descriptor sequence. * * PRE-CONDITIONS *	sb			Pointer to _locked_ superblock. *	block			First block of first extent of the sequence. *	lastblock		Lastblock of first extent of the sequence. * * HISTORY *	July 1, 1997 - Andrew E. Mileski *	Written, tested, and released. */static int udf_process_sequence(struct super_block *sb, long block, long lastblock,				 kernel_lb_addr *fileset){	struct buffer_head *bh = NULL;	struct udf_vds_record vds[VDS_POS_LENGTH];	struct generic_desc *gd;	struct volDescPtr *vdp;	int done = 0;	int i, j;	uint32_t vdsn;	uint16_t ident;	long next_s = 0, next_e = 0;	memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);	/* Read the main descriptor sequence */	for (; (!done && block <= lastblock); block++) {		bh = udf_read_tagged(sb, block, block, &ident);		if (!bh)			break;		/* Process each descriptor (ISO 13346 3/8.3-8.4) */		gd = (struct generic_desc *)bh->b_data;		vdsn = le32_to_cpu(gd->volDescSeqNum);		switch (ident) {		case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */			if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum) {				vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;				vds[VDS_POS_PRIMARY_VOL_DESC].block = block;			}			break;		case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */			if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum) {				vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;				vds[VDS_POS_VOL_DESC_PTR].block = block;				vdp = (struct volDescPtr *)bh->b_data;				next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);				next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);				next_e = next_e >> sb->s_blocksize_bits;				next_e += next_s;			}			break;		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */			if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum) {				vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;				vds[VDS_POS_IMP_USE_VOL_DESC].block = block;			}			break;		case TAG_IDENT_PD: /* ISO 13346 3/10.5 */			if (!vds[VDS_POS_PARTITION_DESC].block)				vds[VDS_POS_PARTITION_DESC].block = block;			break;		case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */			if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum) {				vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;				vds[VDS_POS_LOGICAL_VOL_DESC].block = block;			}			break;		case TAG_IDENT_USD: /* ISO 13346 3/10.8 */			if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum) {				vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;				vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;			}			break;		case TAG_IDENT_TD: /* ISO 13346 3/10.9 */			vds[VDS_POS_TERMINATING_DESC].block = block;			if (next_e) {				block = next_s;				lastblock = next_e;				next_s = next_e = 0;			} else {				done = 1;			}			break;		}		brelse(bh);	}	for (i = 0; i < VDS_POS_LENGTH; i++) {		if (vds[i].block) {			bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);			if (i == VDS_POS_PRIMARY_VOL_DESC) {				udf_load_pvoldesc(sb, bh);			} else if (i == VDS_POS_LOGICAL_VOL_DESC) {				udf_load_logicalvol(sb, bh, fileset);			} else if (i == VDS_POS_PARTITION_DESC) {				struct buffer_head *bh2 = NULL;				if (udf_load_partdesc(sb, bh)) {					brelse(bh);					return 1;				}				for (j = vds[i].block + 1; j <  vds[VDS_POS_TERMINATING_DESC].block; j++) {					bh2 = udf_read_tagged(sb, j, j, &ident);					gd = (struct generic_desc *)bh2->b_data;					if (ident == TAG_IDENT_PD)						if (udf_load_partdesc(sb, bh2)) {							brelse(bh);							brelse(bh2);							return 1;						}					brelse(bh2);				}			}			brelse(bh);		}	}	return 0;}/* * udf_check_valid() */static int udf_check_valid(struct super_block *sb, int novrs, int silent){	long block;	if (novrs) {		udf_debug("Validity check skipped because of novrs option\n");		return 0;	}	/* Check that it is NSR02 compliant */	/* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */	else if ((block = udf_vrs(sb, silent)) == -1) {		udf_debug("Failed to read byte 32768. Assuming open disc. "			  "Skipping validity check\n");		if (!UDF_SB_LASTBLOCK(sb))			UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);		return 0;	} else {		return !block;	}}static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset){	struct anchorVolDescPtr *anchor;	uint16_t ident;	struct buffer_head *bh;	long main_s, main_e, reserve_s, reserve_e;	int i, j;	if (!sb)		return 1;	for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {		if (UDF_SB_ANCHOR(sb)[i] &&		    (bh = udf_read_tagged(sb, UDF_SB_ANCHOR(sb)[i],					  UDF_SB_ANCHOR(sb)[i], &ident))) {			anchor = (struct anchorVolDescPtr *)bh->b_data;			/* Locate the main sequence */			main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);			main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength );			main_e = main_e >> sb->s_blocksize_bits;			main_e += main_s;			/* Locate the reserve sequence */			reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);			reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);			reserve_e = reserve_e >> sb->s_blocksize_bits;			reserve_e += reserve_s;			brelse(bh);			/* Process the main & reserve sequences */			/* responsible for finding the PartitionDesc(s) */			if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&			      udf_process_sequence(sb, reserve_s, reserve_e, fileset))) {				break;			}		}	}	if (i == ARRAY_SIZE(UDF_SB_ANCHOR(sb))) {		udf_debug("No Anchor block found\n");		return 1;	} else		udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);	for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {		kernel_lb_addr uninitialized_var(ino);		switch (UDF_SB_PARTTYPE(sb, i)) {		case UDF_VIRTUAL_MAP15:		case UDF_VIRTUAL_MAP20:			if (!UDF_SB_LASTBLOCK(sb)) {				UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);				udf_find_anchor(sb);			}			if (!UDF_SB_LASTBLOCK(sb)) {				udf_debug("Unable to determine Lastblock (For "					  "Virtual Partition)\n");				return 1;			}			for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) {				if (j != i &&				    UDF_SB_PARTVSN(sb, i) == UDF_SB_PARTVSN(sb, j) &&				    UDF_SB_PARTNUM(sb, i) == UDF_SB_PARTNUM(sb, j)) {					ino.partitionReferenceNum = j;					ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) - UDF_SB_PARTROOT(sb, j);					break;				}			}			if (j == UDF_SB_NUMPARTS(sb))				return 1;			if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))				return 1;			if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) {				UDF_SB_TYPEVIRT(sb, i).s_start_offset =					udf_ext0_offset(UDF_SB_VAT(sb));				UDF_SB_TYPEVIRT(sb, i).s_num_entries =					(UDF_SB_VAT(sb)->i_size - 36) >> 2;			} else if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP20) {				struct buffer_head *bh = NULL;				uint32_t pos;				pos = udf_block_map(UDF_SB_VAT(sb), 0);				bh = sb_bread(sb, pos);				if (!bh)					return 1;				UDF_SB_TYPEVIRT(sb, i).s_start_offset =					le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data +						     udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +					udf_ext0_offset(UDF_SB_VAT(sb));				UDF_SB_TYPEVIRT(sb, i).s_num_entries = (UDF_SB_VAT(sb)->i_size -									UDF_SB_TYPEVIRT(sb, i).s_start_offset) >> 2;				brelse(bh);			}			UDF_SB_PARTROOT(sb, i) = udf_get_pblock(sb, 0, i, 0);			UDF_SB_PARTLEN(sb, i) = UDF_SB_PARTLEN(sb, ino.partitionReferenceNum);		}	}	return 0;}static void udf_open_lvid(struct super_block *sb){	if (UDF_SB_LVIDBH(sb)) {		int i;		kernel_timestamp cpu_time;		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;		if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))			UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);		UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;		UDF_SB_LVID(sb)->descTag.descCRC = cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),								       le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));		UDF_SB_LVID(sb)->descTag.tagChecksum = 0;		for (i = 0; i < 16; i++)			if (i != 4)				UDF_SB_LVID(sb)->descTag.tagChecksum +=					((uint8_t *) &(UDF_SB_LVID(sb)->descTag))[i];		mark_buffer_dirty(UDF_SB_LVIDBH(sb));	}}static void udf_close_lvid(struct super_block *sb){	kernel_timestamp cpu_time;	int i;	if (UDF_SB_LVIDBH(sb) &&	    UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN) {		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;		if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))			UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);

⌨️ 快捷键说明

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