📄 super.c
字号:
{ lastblock = last[i]; UDF_SB_ANCHOR(sb)[2] = 512 + UDF_SB_SESSION(sb); } else { if (!(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize))) { ident = location = 0; } else { ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); udf_release_data(bh); } if (ident == TID_ANCHOR_VOL_DESC_PTR && location == last[i] - 256 - UDF_SB_SESSION(sb)) { lastblock = last[i]; UDF_SB_ANCHOR(sb)[1] = last[i] - 256; } else { if (!(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb), sb->s_blocksize))) { ident = location = 0; } else { ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); udf_release_data(bh); } if (ident == TID_ANCHOR_VOL_DESC_PTR && location == udf_variable_to_fixed(last[i]) - 256) { UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); lastblock = udf_variable_to_fixed(last[i]); UDF_SB_ANCHOR(sb)[1] = lastblock - 256; } } } } if (!lastblock) { /* We havn't found the lastblock. check 312 */ if ((bh = bread(sb->s_dev, 312 + UDF_SB_SESSION(sb), sb->s_blocksize))) { ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent); location = le32_to_cpu(((tag *)bh->b_data)->tagLocation); udf_release_data(bh); if (ident == TID_ANCHOR_VOL_DESC_PTR && location == 256) UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); } } for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++) { if (UDF_SB_ANCHOR(sb)[i]) { if (!(bh = udf_read_tagged(sb, UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident))) { UDF_SB_ANCHOR(sb)[i] = 0; } else { udf_release_data(bh); if ((ident != TID_ANCHOR_VOL_DESC_PTR) && (i || (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY))) { UDF_SB_ANCHOR(sb)[i] = 0; } } } else if (useranchor != 0xFFFFFFFF) { UDF_SB_ANCHOR(sb)[i] = useranchor; useranchor = 0xFFFFFFFF; i --; } } return lastblock;}static int udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root){ struct buffer_head *bh = NULL; long lastblock; Uint16 ident; if (fileset->logicalBlockNum != 0xFFFFFFFF || fileset->partitionReferenceNum != 0xFFFF) { bh = udf_read_ptagged(sb, *fileset, 0, &ident); if (!bh) return 1; else if (ident != TID_FILE_SET_DESC) { udf_release_data(bh); return 1; } } if (!bh) /* Search backwards through the partitions */ { lb_addr newfileset; return 1; for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1; (newfileset.partitionReferenceNum != 0xFFFF && fileset->logicalBlockNum == 0xFFFFFFFF && fileset->partitionReferenceNum == 0xFFFF); newfileset.partitionReferenceNum--) { lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum); newfileset.logicalBlockNum = 0; do { bh = udf_read_ptagged(sb, newfileset, 0, &ident); if (!bh) { newfileset.logicalBlockNum ++; continue; } switch (ident) { case TID_SPACE_BITMAP_DESC: { struct SpaceBitmapDesc *sp; sp = (struct SpaceBitmapDesc *)bh->b_data; newfileset.logicalBlockNum += 1 + ((le32_to_cpu(sp->numOfBytes) + sizeof(struct SpaceBitmapDesc) - 1) >> sb->s_blocksize_bits); udf_release_data(bh); break; } case TID_FILE_SET_DESC: { *fileset = newfileset; break; } default: { newfileset.logicalBlockNum ++; udf_release_data(bh); bh = NULL; break; } } } while (newfileset.logicalBlockNum < lastblock && fileset->logicalBlockNum == 0xFFFFFFFF && fileset->partitionReferenceNum == 0xFFFF); } } if ((fileset->logicalBlockNum != 0xFFFFFFFF || fileset->partitionReferenceNum != 0xFFFF) && bh) { udf_debug("Fileset at block=%d, partition=%d\n", fileset->logicalBlockNum, fileset->partitionReferenceNum); UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum; udf_load_fileset(sb, bh, root); udf_release_data(bh); return 0; } return 1;}static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh){ struct PrimaryVolDesc *pvoldesc; time_t recording; long recording_usec; struct ustr instr; struct ustr outstr; pvoldesc = (struct PrimaryVolDesc *)bh->b_data; if ( udf_stamp_to_time(&recording, &recording_usec, lets_to_cpu(pvoldesc->recordingDateAndTime)) ) { timestamp ts; ts = lets_to_cpu(pvoldesc->recordingDateAndTime); udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n", recording, recording_usec, ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone); UDF_SB_RECORDTIME(sb) = recording; } if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) ) { if (udf_CS0toUTF8(&outstr, &instr)) { strncpy( UDF_SB_VOLIDENT(sb), outstr.u_name, outstr.u_len > 31 ? 31 : outstr.u_len); udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb)); } } if ( !udf_build_ustr(&instr, pvoldesc->volSetIdent, 128) ) { if (udf_CS0toUTF8(&outstr, &instr)) udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); }}static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, lb_addr *root){ struct FileSetDesc *fset; fset = (struct FileSetDesc *)bh->b_data; *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation); UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum); udf_debug("Rootdir at block=%d, partition=%d\n", root->logicalBlockNum, root->partitionReferenceNum);}static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh){ struct PartitionDesc *p; int i; p=(struct PartitionDesc *)bh->b_data; for (i=0; i<UDF_SB_NUMPARTS(sb); i++) { udf_debug("Searching map: (%d == %d)\n", UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber)); if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber)) { UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */ UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb); if (UDF_SB_PARTTYPE(sb,i) == UDF_SPARABLE_MAP15) udf_fill_spartable(sb, &UDF_SB_TYPESPAR(sb,i), UDF_SB_PARTLEN(sb,i)); if (!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR02) || !strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR03)) { struct PartitionHeaderDesc *phd; phd = (struct PartitionHeaderDesc *)(p->partitionContentsUse); if (phd->unallocatedSpaceTable.extLength) udf_debug("unallocatedSpaceTable (part %d)\n", i); if (phd->unallocatedSpaceBitmap.extLength) { UDF_SB_PARTMAPS(sb)[i].s_uspace.bitmap = le32_to_cpu(phd->unallocatedSpaceBitmap.extPosition); UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP; udf_debug("unallocatedSpaceBitmap (part %d) @ %d\n", i, UDF_SB_PARTMAPS(sb)[i].s_uspace.bitmap); } if (phd->partitionIntegrityTable.extLength) udf_debug("partitionIntegrityTable (part %d)\n", i); if (phd->freedSpaceTable.extLength) udf_debug("freedSpaceTable (part %d)\n", i); if (phd->freedSpaceBitmap.extLength) { UDF_SB_PARTMAPS(sb)[i].s_fspace.bitmap = 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.bitmap); } } 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)); }}static int udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset){ struct LogicalVolDesc *lvd; int i, j, offset; Uint8 type; lvd = (struct LogicalVolDesc *)bh->b_data; UDF_SB_NUMPARTS(sb) = le32_to_cpu(lvd->numPartitionMaps); UDF_SB_ALLOC_PARTMAPS(sb, UDF_SB_NUMPARTS(sb)); 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; udf_debug("Partition (%d) type %d\n", i, type); 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(((Uint16 *)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(((Uint16 *)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))) { int plen; struct SparablePartitionMap *spm = (struct SparablePartitionMap *)&(lvd->partitionMaps[offset]); UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15; plen = le16_to_cpu(spm->packetLength); UDF_SB_TYPESPAR(sb,i).s_spar_pshift = 0; while (plen >>= 1) UDF_SB_TYPESPAR(sb,i).s_spar_pshift ++; for (j=0; j<spm->numSparingTables; j++) UDF_SB_TYPESPAR(sb,i).s_spar_loc[j] = le32_to_cpu(spm->locSparingTable[j]); 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); } } 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 voidudf_load_logicalvolint(struct super_block *sb, extent_ad loc){ struct buffer_head *bh = NULL; Uint16 ident; while ((bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident)) && ident == TID_LOGICAL_VOL_INTEGRITY_DESC && loc.extLength > 0) { 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) udf_release_data(bh); loc.extLength -= sb->s_blocksize; loc.extLocation ++; } if (UDF_SB_LVIDBH(sb) != bh) udf_release_data(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 intudf_process_sequence(struct super_block *sb, long block, long lastblock, lb_addr *fileset){ struct buffer_head *bh = NULL; struct udf_vds_record vds[VDS_POS_LENGTH]; struct GenericDesc *gd; int done=0; int i,j; Uint32 vdsn; Uint16 ident; 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 GenericDesc *)bh->b_data; vdsn = le32_to_cpu(gd->volDescSeqNum); switch (ident) { case TID_PRIMARY_VOL_DESC: /* 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 TID_VOL_DESC_PTR: /* 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; } break; case TID_IMP_USE_VOL_DESC: /* 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 TID_PARTITION_DESC: /* ISO 13346 3/10.5 */ if (!vds[VDS_POS_PARTITION_DESC].block) vds[VDS_POS_PARTITION_DESC].block = block; break; case TID_LOGICAL_VOL_DESC: /* 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 TID_UNALLOC_SPACE_DESC: /* 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 TID_TERMINATING_DESC: /* ISO 13346 3/10.9 */ vds[VDS_POS_TERMINATING_DESC].block = block; done = 1; break; } udf_release_data(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; udf_load_partdesc(sb, bh); for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++) { bh2 = udf_read_tagged(sb, j, j, &ident); gd = (struct GenericDesc *)bh2->b_data; if (ident == TID_PARTITION_DESC) udf_load_partdesc(sb, bh2); udf_release_data(bh2); } } udf_release_data(bh); } } return 0;}/* * udf_check_valid() */static intudf_check_valid(struct super_block *sb, int novrs, int silent){ long block; if (novrs) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -