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:
@@ -183,7 +183,7 @@ void
|
|||||||
Icb::GetAccessTime(struct timespec ×pec) const
|
Icb::GetAccessTime(struct timespec ×pec) 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 ×pec) const
|
Icb::GetModificationTime(struct timespec ×pec) 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 ×pec) 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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user