diff --git a/src/add-ons/kernel/file_systems/udf/Icb.cpp b/src/add-ons/kernel/file_systems/udf/Icb.cpp index faf1f9c5f2..61a91357af 100644 --- a/src/add-ons/kernel/file_systems/udf/Icb.cpp +++ b/src/add-ons/kernel/file_systems/udf/Icb.cpp @@ -183,7 +183,7 @@ void Icb::GetAccessTime(struct timespec ×pec) const { timestamp ts; - if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)) + if (_Tag().id() == TAGID_EXTENDED_FILE_ENTRY) ts = _ExtendedEntry()->access_date_and_time(); else ts = _FileEntry()->access_date_and_time(); @@ -200,7 +200,7 @@ void Icb::GetModificationTime(struct timespec ×pec) const { timestamp ts; - if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)) + if (_Tag().id() == TAGID_EXTENDED_FILE_ENTRY) ts = _ExtendedEntry()->modification_date_and_time(); else ts = _FileEntry()->modification_date_and_time(); @@ -214,7 +214,7 @@ Icb::GetModificationTime(struct timespec ×pec) const status_t -Icb::FindBlock(uint32 logicalBlock, off_t &block) +Icb::FindBlock(uint32 logicalBlock, off_t &block, bool &recorded) { off_t pos = logicalBlock << fVolume->BlockShift(); if (uint64(pos) >= Length()) { @@ -227,9 +227,11 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) status_t status = B_OK; long_address extent; bool isEmpty = false; + recorded = false; switch (_IcbTag().descriptor_flags()) { - case ICB_DESCRIPTOR_TYPE_SHORT: { + case ICB_DESCRIPTOR_TYPE_SHORT: + { TRACE(("Icb::FindBlock: descriptor type -> short\n")); AllocationDescriptorList list(this, ShortDescriptorAccessor(fPartition)); @@ -241,7 +243,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) break; } - case ICB_DESCRIPTOR_TYPE_LONG: { + case ICB_DESCRIPTOR_TYPE_LONG: + { TRACE(("Icb::FindBlock: descriptor type -> long\n")); AllocationDescriptorList list(this); status = list.FindExtent(pos, &extent, &isEmpty); @@ -252,7 +255,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) break; } - case ICB_DESCRIPTOR_TYPE_EXTENDED: { + case ICB_DESCRIPTOR_TYPE_EXTENDED: + { TRACE(("Icb::FindBlock: descriptor type -> extended\n")); // AllocationDescriptorList list(this, ExtendedDescriptorAccessor(0)); // RETURN(_Read(list, pos, buffer, length, block)); @@ -260,7 +264,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) break; } - case ICB_DESCRIPTOR_TYPE_EMBEDDED: { + case ICB_DESCRIPTOR_TYPE_EMBEDDED: + { TRACE(("Icb::FindBlock: descriptor type: embedded\n")); RETURN(B_ERROR); break; @@ -275,6 +280,7 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) if (status == B_OK) { block = extent.block(); + recorded = extent.type() == EXTENT_TYPE_RECORDED; TRACE(("Icb::FindBlock: block %lld\n", block)); } return status; @@ -301,7 +307,8 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) return file_cache_read(fFileCache, NULL, pos, buffer, length); switch (_IcbTag().descriptor_flags()) { - case ICB_DESCRIPTOR_TYPE_SHORT: { + case ICB_DESCRIPTOR_TYPE_SHORT: + { TRACE(("Icb::Read: descriptor type -> short\n")); AllocationDescriptorList list(this, ShortDescriptorAccessor(fPartition)); @@ -309,14 +316,16 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) break; } - case ICB_DESCRIPTOR_TYPE_LONG: { + case ICB_DESCRIPTOR_TYPE_LONG: + { TRACE(("Icb::Read: descriptor type -> long\n")); AllocationDescriptorList list(this); RETURN(_Read(list, pos, buffer, length, block)); break; } - case ICB_DESCRIPTOR_TYPE_EXTENDED: { + case ICB_DESCRIPTOR_TYPE_EXTENDED: + { TRACE(("Icb::Read: descriptor type -> extended\n")); // AllocationDescriptorList list(this, ExtendedDescriptorAccessor(0)); // RETURN(_Read(list, pos, buffer, length, block)); @@ -324,7 +333,8 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) break; } - case ICB_DESCRIPTOR_TYPE_EMBEDDED: { + case ICB_DESCRIPTOR_TYPE_EMBEDDED: + { TRACE(("Icb::Read: descriptor type: embedded\n")); RETURN(B_ERROR); break; diff --git a/src/add-ons/kernel/file_systems/udf/Icb.h b/src/add-ons/kernel/file_systems/udf/Icb.h index fd3893a40e..ab61ae71b0 100644 --- a/src/add-ons/kernel/file_systems/udf/Icb.h +++ b/src/add-ons/kernel/file_systems/udf/Icb.h @@ -105,7 +105,8 @@ public: uint32 AllocationDescriptorsSize() { return _AbstractEntry()->AllocationDescriptorsLength(); } - status_t FindBlock(uint32 logicalBlock, off_t &block); + status_t FindBlock(uint32 logicalBlock, off_t &block, + bool &recorded); status_t Read(off_t pos, void *buffer, size_t *length, uint32 *block = NULL); diff --git a/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp b/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp index 2c58a2c2a6..619a6b809c 100644 --- a/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp +++ b/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp @@ -31,8 +31,16 @@ MetadataPartition::MetadataPartition(Volume *volume, fMetadataIcb = new(nothrow) Icb(volume, address); if (fMetadataIcb == NULL || fMetadataIcb->InitCheck() != B_OK) fInitStatus = B_NO_MEMORY; + else + fInitStatus = B_OK; - fInitStatus = B_OK; + address.set_to(metadataMirrorFileLocation, fPartition); + + fMetadataMirrorIcb = new(nothrow) Icb(volume, address); + if (fMetadataMirrorIcb == NULL + || fMetadataMirrorIcb->InitCheck() != B_OK) { + fInitStatus = B_NO_MEMORY; + } } /*! \brief Destroys the MetadataPartition object. @@ -48,9 +56,17 @@ status_t MetadataPartition::MapBlock(uint32 logicalBlock, off_t &physicalBlock) { off_t block = 0; - status_t status = fMetadataIcb->FindBlock(logicalBlock, block); + bool isRecorded; + status_t status = fMetadataIcb->FindBlock(logicalBlock, block, isRecorded); if (status != B_OK) return status; + if (!isRecorded) { + status = fMetadataMirrorIcb->FindBlock(logicalBlock, block, isRecorded); + if (status != B_OK) + return status; + if (!isRecorded) + return B_BAD_DATA; + } return fParentPartition.MapBlock(block, physicalBlock); } diff --git a/src/add-ons/kernel/file_systems/udf/MetadataPartition.h b/src/add-ons/kernel/file_systems/udf/MetadataPartition.h index 0c97bf6d1c..030ca0db12 100644 --- a/src/add-ons/kernel/file_systems/udf/MetadataPartition.h +++ b/src/add-ons/kernel/file_systems/udf/MetadataPartition.h @@ -44,6 +44,7 @@ private: bool fMetadataIsDuplicated; status_t fInitStatus; Icb *fMetadataIcb; + Icb *fMetadataMirrorIcb; }; #endif // _UDF_METADATA_PARTITION_H