UDF: use mirror metadata file when needed

* style fixes
* try the mirror metadata file in case read fails on the main file
This commit is contained in:
Jérôme Duval 2012-10-23 21:46:36 +02:00 committed by Alexander von Gluck IV
parent 04211a0400
commit dd414d0027
4 changed files with 42 additions and 14 deletions

View File

@ -183,7 +183,7 @@ void
Icb::GetAccessTime(struct timespec &timespec) 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 &timespec) 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 &timespec) 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<ShortDescriptorAccessor> 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<LongDescriptorAccessor> 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<ExtendedDescriptorAccessor> 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<ShortDescriptorAccessor> 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<LongDescriptorAccessor> 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<ExtendedDescriptorAccessor> 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;

View File

@ -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);

View File

@ -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);
}

View File

@ -44,6 +44,7 @@ private:
bool fMetadataIsDuplicated;
status_t fInitStatus;
Icb *fMetadataIcb;
Icb *fMetadataMirrorIcb;
};
#endif // _UDF_METADATA_PARTITION_H