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:49:27 +02:00
parent 3a0a7215a9
commit ee3c886743
4 changed files with 42 additions and 14 deletions
+21 -11
View File
@@ -183,7 +183,7 @@ void
Icb::GetAccessTime(struct timespec &timespec) const Icb::GetAccessTime(struct timespec &timespec) const
{ {
timestamp ts; timestamp ts;
if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)) if (_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)
ts = _ExtendedEntry()->access_date_and_time(); ts = _ExtendedEntry()->access_date_and_time();
else else
ts = _FileEntry()->access_date_and_time(); ts = _FileEntry()->access_date_and_time();
@@ -200,7 +200,7 @@ void
Icb::GetModificationTime(struct timespec &timespec) const Icb::GetModificationTime(struct timespec &timespec) const
{ {
timestamp ts; timestamp ts;
if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)) if (_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)
ts = _ExtendedEntry()->modification_date_and_time(); ts = _ExtendedEntry()->modification_date_and_time();
else else
ts = _FileEntry()->modification_date_and_time(); ts = _FileEntry()->modification_date_and_time();
@@ -214,7 +214,7 @@ Icb::GetModificationTime(struct timespec &timespec) const
status_t status_t
Icb::FindBlock(uint32 logicalBlock, off_t &block) Icb::FindBlock(uint32 logicalBlock, off_t &block, bool &recorded)
{ {
off_t pos = logicalBlock << fVolume->BlockShift(); off_t pos = logicalBlock << fVolume->BlockShift();
if (uint64(pos) >= Length()) { if (uint64(pos) >= Length()) {
@@ -227,9 +227,11 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block)
status_t status = B_OK; status_t status = B_OK;
long_address extent; long_address extent;
bool isEmpty = false; bool isEmpty = false;
recorded = false;
switch (_IcbTag().descriptor_flags()) { switch (_IcbTag().descriptor_flags()) {
case ICB_DESCRIPTOR_TYPE_SHORT: { case ICB_DESCRIPTOR_TYPE_SHORT:
{
TRACE(("Icb::FindBlock: descriptor type -> short\n")); TRACE(("Icb::FindBlock: descriptor type -> short\n"));
AllocationDescriptorList<ShortDescriptorAccessor> list(this, AllocationDescriptorList<ShortDescriptorAccessor> list(this,
ShortDescriptorAccessor(fPartition)); ShortDescriptorAccessor(fPartition));
@@ -241,7 +243,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block)
break; break;
} }
case ICB_DESCRIPTOR_TYPE_LONG: { case ICB_DESCRIPTOR_TYPE_LONG:
{
TRACE(("Icb::FindBlock: descriptor type -> long\n")); TRACE(("Icb::FindBlock: descriptor type -> long\n"));
AllocationDescriptorList<LongDescriptorAccessor> list(this); AllocationDescriptorList<LongDescriptorAccessor> list(this);
status = list.FindExtent(pos, &extent, &isEmpty); status = list.FindExtent(pos, &extent, &isEmpty);
@@ -252,7 +255,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block)
break; break;
} }
case ICB_DESCRIPTOR_TYPE_EXTENDED: { case ICB_DESCRIPTOR_TYPE_EXTENDED:
{
TRACE(("Icb::FindBlock: descriptor type -> extended\n")); TRACE(("Icb::FindBlock: descriptor type -> extended\n"));
// AllocationDescriptorList<ExtendedDescriptorAccessor> list(this, ExtendedDescriptorAccessor(0)); // AllocationDescriptorList<ExtendedDescriptorAccessor> list(this, ExtendedDescriptorAccessor(0));
// RETURN(_Read(list, pos, buffer, length, block)); // RETURN(_Read(list, pos, buffer, length, block));
@@ -260,7 +264,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block)
break; break;
} }
case ICB_DESCRIPTOR_TYPE_EMBEDDED: { case ICB_DESCRIPTOR_TYPE_EMBEDDED:
{
TRACE(("Icb::FindBlock: descriptor type: embedded\n")); TRACE(("Icb::FindBlock: descriptor type: embedded\n"));
RETURN(B_ERROR); RETURN(B_ERROR);
break; break;
@@ -275,6 +280,7 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block)
if (status == B_OK) { if (status == B_OK) {
block = extent.block(); block = extent.block();
recorded = extent.type() == EXTENT_TYPE_RECORDED;
TRACE(("Icb::FindBlock: block %lld\n", block)); TRACE(("Icb::FindBlock: block %lld\n", block));
} }
return status; 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); return file_cache_read(fFileCache, NULL, pos, buffer, length);
switch (_IcbTag().descriptor_flags()) { switch (_IcbTag().descriptor_flags()) {
case ICB_DESCRIPTOR_TYPE_SHORT: { case ICB_DESCRIPTOR_TYPE_SHORT:
{
TRACE(("Icb::Read: descriptor type -> short\n")); TRACE(("Icb::Read: descriptor type -> short\n"));
AllocationDescriptorList<ShortDescriptorAccessor> list(this, AllocationDescriptorList<ShortDescriptorAccessor> list(this,
ShortDescriptorAccessor(fPartition)); ShortDescriptorAccessor(fPartition));
@@ -309,14 +316,16 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
break; break;
} }
case ICB_DESCRIPTOR_TYPE_LONG: { case ICB_DESCRIPTOR_TYPE_LONG:
{
TRACE(("Icb::Read: descriptor type -> long\n")); TRACE(("Icb::Read: descriptor type -> long\n"));
AllocationDescriptorList<LongDescriptorAccessor> list(this); AllocationDescriptorList<LongDescriptorAccessor> list(this);
RETURN(_Read(list, pos, buffer, length, block)); RETURN(_Read(list, pos, buffer, length, block));
break; break;
} }
case ICB_DESCRIPTOR_TYPE_EXTENDED: { case ICB_DESCRIPTOR_TYPE_EXTENDED:
{
TRACE(("Icb::Read: descriptor type -> extended\n")); TRACE(("Icb::Read: descriptor type -> extended\n"));
// AllocationDescriptorList<ExtendedDescriptorAccessor> list(this, ExtendedDescriptorAccessor(0)); // AllocationDescriptorList<ExtendedDescriptorAccessor> list(this, ExtendedDescriptorAccessor(0));
// RETURN(_Read(list, pos, buffer, length, block)); // RETURN(_Read(list, pos, buffer, length, block));
@@ -324,7 +333,8 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
break; break;
} }
case ICB_DESCRIPTOR_TYPE_EMBEDDED: { case ICB_DESCRIPTOR_TYPE_EMBEDDED:
{
TRACE(("Icb::Read: descriptor type: embedded\n")); TRACE(("Icb::Read: descriptor type: embedded\n"));
RETURN(B_ERROR); RETURN(B_ERROR);
break; break;
+2 -1
View File
@@ -105,7 +105,8 @@ public:
uint32 AllocationDescriptorsSize() uint32 AllocationDescriptorsSize()
{ return _AbstractEntry()->AllocationDescriptorsLength(); } { 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, status_t Read(off_t pos, void *buffer, size_t *length,
uint32 *block = NULL); uint32 *block = NULL);
@@ -31,8 +31,16 @@ MetadataPartition::MetadataPartition(Volume *volume,
fMetadataIcb = new(nothrow) Icb(volume, address); fMetadataIcb = new(nothrow) Icb(volume, address);
if (fMetadataIcb == NULL || fMetadataIcb->InitCheck() != B_OK) if (fMetadataIcb == NULL || fMetadataIcb->InitCheck() != B_OK)
fInitStatus = B_NO_MEMORY; 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. /*! \brief Destroys the MetadataPartition object.
@@ -48,9 +56,17 @@ status_t
MetadataPartition::MapBlock(uint32 logicalBlock, off_t &physicalBlock) MetadataPartition::MapBlock(uint32 logicalBlock, off_t &physicalBlock)
{ {
off_t block = 0; 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) if (status != B_OK)
return status; 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); return fParentPartition.MapBlock(block, physicalBlock);
} }
@@ -44,6 +44,7 @@ private:
bool fMetadataIsDuplicated; bool fMetadataIsDuplicated;
status_t fInitStatus; status_t fInitStatus;
Icb *fMetadataIcb; Icb *fMetadataIcb;
Icb *fMetadataMirrorIcb;
}; };
#endif // _UDF_METADATA_PARTITION_H #endif // _UDF_METADATA_PARTITION_H