[haiku-commits] haiku.r1alpha4: hrevr1alpha4-44636 - src/add-ons/kernel/file_systems/udf

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 21 Oct 2012 15:07:41 +0200 (CEST)

hrevr1alpha4-44636 adds 2 changesets to branch 'r1alpha4'
old head: 4e944374c7d81b0c8c325f5038416cd7190fdb54
new head: 3adb6707bd37a20171158403688b48c3ef05ff4a

----------------------------------------------------------------------------

0812d56: UDF: support for metadata partition (feature from 2.50)
  
  * added Icb::FindBlock() to find block in extents.
  * MetadataPartition uses extents descriptors found in the metadatafile
  to lookup blocks on a physical partition
  * uses struct timespec instead of time_t
  * added init_entities() to call C++ structures constructors. This is
  called at module initialization, C++ constructors are currently not called 
when
  a kernel module is loaded.
  * tested with a sample bluray ISO.

3adb670: udf: moved partitions deletion before block cache deletion (#9004)

                                   [ JÃrÃme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

13 files changed, 445 insertions(+), 163 deletions(-)
src/add-ons/kernel/file_systems/udf/Icb.cpp        |  111 ++++++++++++++--
src/add-ons/kernel/file_systems/udf/Icb.h          |   19 ++-
.../kernel/file_systems/udf/MetadataPartition.cpp  |   48 +++++--
.../kernel/file_systems/udf/MetadataPartition.h    |   24 ++--
.../kernel/file_systems/udf/Recognition.cpp        |   29 +++-
src/add-ons/kernel/file_systems/udf/Recognition.h  |   20 +--
.../kernel/file_systems/udf/UdfStructures.cpp      |   62 ++++++---
.../kernel/file_systems/udf/UdfStructures.h        |   99 ++++++++++----
src/add-ons/kernel/file_systems/udf/Utils.cpp      |  103 ++++++++------
src/add-ons/kernel/file_systems/udf/Utils.h        |    2 +-
src/add-ons/kernel/file_systems/udf/Volume.cpp     |   59 ++++++--
src/add-ons/kernel/file_systems/udf/Volume.h       |    4 +
.../kernel/file_systems/udf/kernel_interface.cpp   |   28 +++-

############################################################################

Commit:      0812d56db744f5297613b133f37e2780e56d438d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=0812d56
Author:      JÃrÃme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Oct  9 20:35:26 2012 UTC
Committer:   Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Commit-Date: Sun Oct 21 13:02:39 2012 UTC

UDF: support for metadata partition (feature from 2.50)

* added Icb::FindBlock() to find block in extents.
* MetadataPartition uses extents descriptors found in the metadatafile
to lookup blocks on a physical partition
* uses struct timespec instead of time_t
* added init_entities() to call C++ structures constructors. This is
called at module initialization, C++ constructors are currently not called when
a kernel module is loaded.
* tested with a sample bluray ISO.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/udf/Icb.cpp 
b/src/add-ons/kernel/file_systems/udf/Icb.cpp
index 8092a58..faf1f9c 100644
--- a/src/add-ons/kernel/file_systems/udf/Icb.cpp
+++ b/src/add-ons/kernel/file_systems/udf/Icb.cpp
@@ -1,6 +1,7 @@
 /*
- * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2010, Michael Lotz, mmlr@xxxxxxxxx
+ * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
@@ -104,6 +105,7 @@ Icb::Icb(Volume *volume, long_address address)
        fData(volume),
        fInitStatus(B_NO_INIT),
        fId(to_vnode_id(address)),
+       fPartition(address.partition()),
        fFileEntry(&fData),
        fExtendedEntry(&fData),
        fFileCache(NULL),
@@ -177,17 +179,105 @@ Icb::InitCheck()
 }
 
 
-time_t
-Icb::AccessTime()
+void
+Icb::GetAccessTime(struct timespec &timespec) const
 {
-       return make_time(_FileEntry()->access_date_and_time());
+       timestamp ts;
+       if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY))
+               ts = _ExtendedEntry()->access_date_and_time();
+       else
+               ts = _FileEntry()->access_date_and_time();
+
+       if (decode_time(ts, timespec) != B_OK) {
+               decode_time(
+                       
fVolume->PrimaryVolumeDescriptor()->recording_date_and_time(),
+                       timespec);
+       }
 }
 
 
-time_t
-Icb::ModificationTime()
+void
+Icb::GetModificationTime(struct timespec &timespec) const
+{
+       timestamp ts;
+       if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY))
+               ts = _ExtendedEntry()->modification_date_and_time();
+       else
+               ts = _FileEntry()->modification_date_and_time();
+
+       if (decode_time(ts, timespec) != B_OK) {
+               decode_time(
+                       
fVolume->PrimaryVolumeDescriptor()->recording_date_and_time(),
+                       timespec);
+       }
+}
+
+
+status_t
+Icb::FindBlock(uint32 logicalBlock, off_t &block)
 {
-       return make_time(_FileEntry()->modification_date_and_time());
+       off_t pos = logicalBlock << fVolume->BlockShift();
+       if (uint64(pos) >= Length()) {
+               block = -1;
+               return B_ERROR;
+       }
+
+       DEBUG_INIT_ETC("Icb", ("pos: %lld", pos));
+
+       status_t status = B_OK;
+       long_address extent;
+       bool isEmpty = false;
+               
+       switch (_IcbTag().descriptor_flags()) {
+               case ICB_DESCRIPTOR_TYPE_SHORT: {
+                       TRACE(("Icb::FindBlock: descriptor type -> short\n"));
+                       AllocationDescriptorList<ShortDescriptorAccessor> 
list(this,
+                               ShortDescriptorAccessor(fPartition));
+                       status = list.FindExtent(pos, &extent, &isEmpty);
+                       if (status != B_OK) {
+                               TRACE_ERROR(("Icb::FindBlock: error finding 
extent for offset %Ld. "
+                                       "status = 0x%lx `%s'\n", pos, status, 
strerror(status)));
+                       }
+                       break;
+               }
+
+               case ICB_DESCRIPTOR_TYPE_LONG: {
+                       TRACE(("Icb::FindBlock: descriptor type -> long\n"));
+                       AllocationDescriptorList<LongDescriptorAccessor> 
list(this);
+                       status = list.FindExtent(pos, &extent, &isEmpty);
+                       if (status != B_OK) {
+                               TRACE_ERROR(("Icb::FindBlock: error finding 
extent for offset %Ld. "
+                                       "status = 0x%lx `%s'\n", pos, status, 
strerror(status)));
+                       }
+                       break;
+               }
+
+               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));
+                       RETURN(B_ERROR);
+                       break;
+               }
+
+               case ICB_DESCRIPTOR_TYPE_EMBEDDED: {
+                       TRACE(("Icb::FindBlock: descriptor type: embedded\n"));
+                       RETURN(B_ERROR);
+                       break;
+               }
+
+               default:
+                       TRACE(("Icb::FindBlock: invalid icb descriptor flags! 
(flags = %d)\n",
+                               _IcbTag().descriptor_flags()));
+                       RETURN(B_BAD_VALUE);
+                       break;
+       }
+
+       if (status == B_OK) {
+               block = extent.block();
+               TRACE(("Icb::FindBlock: block %lld\n", block));
+       }
+       return status;
 }
 
 
@@ -205,13 +295,16 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 
*block)
                return B_OK;
        }
 
+       DEBUG_INIT_ETC("Icb", ("pos: %lld, length: %ld", pos, *length));
+
        if (fFileCache != NULL)
                return file_cache_read(fFileCache, NULL, pos, buffer, length);
 
        switch (_IcbTag().descriptor_flags()) {
                case ICB_DESCRIPTOR_TYPE_SHORT: {
                        TRACE(("Icb::Read: descriptor type -> short\n"));
-                       AllocationDescriptorList<ShortDescriptorAccessor> 
list(this, ShortDescriptorAccessor(0));
+                       AllocationDescriptorList<ShortDescriptorAccessor> 
list(this,
+                               ShortDescriptorAccessor(fPartition));
                        RETURN(_Read(list, pos, buffer, length, block));
                        break;
                }
@@ -445,7 +538,7 @@ Icb::Find(const char *filename, ino_t *id)
        TRACE(("Icb::Find: filename = `%s', id = %p\n", filename, id));
 
        if (!filename || !id)
-               RETURN(B_BAD_VALUE);
+               return B_BAD_VALUE;
 
        DirectoryIterator *i;
        status_t status = GetDirectoryIterator(&i);
diff --git a/src/add-ons/kernel/file_systems/udf/Icb.h 
b/src/add-ons/kernel/file_systems/udf/Icb.h
index 7fac386..fd3893a 100644
--- a/src/add-ons/kernel/file_systems/udf/Icb.h
+++ b/src/add-ons/kernel/file_systems/udf/Icb.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@xxxxxxxxxx
  * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
@@ -96,14 +97,15 @@ public:
        uint64                                          Length() { return 
_FileEntry()->information_length(); }
        mode_t                                          Mode() { return 
(IsDirectory() ? S_IFDIR : S_IFREG)
                                                                        | 
S_IRUSR | S_IRGRP | S_IROTH; }
-       time_t                                          AccessTime();
-       time_t                                          ModificationTime();
+       void                                            GetAccessTime(struct 
timespec &timespec) const;
+       void                                            
GetModificationTime(struct timespec &timespec) const;
 
        uint8                                           *AllocationDescriptors()
                                                                        { 
return _AbstractEntry()->AllocationDescriptors(); }
        uint32                                          
AllocationDescriptorsSize()
                                                                        { 
return _AbstractEntry()->AllocationDescriptorsLength(); }
 
+       status_t                                        FindBlock(uint32 
logicalBlock, off_t &block);
        status_t                                        Read(off_t pos, void 
*buffer, size_t *length,
                                                                        uint32 
*block = NULL);
 
@@ -120,15 +122,17 @@ public:
        Volume                                          *GetVolume() const { 
return fVolume; }
 
 private:
-       AbstractFileEntry                       *_AbstractEntry() { return 
(_Tag().id()
+       AbstractFileEntry                       *_AbstractEntry() const { 
return (_Tag().id()
                                                                        == 
TAGID_EXTENDED_FILE_ENTRY)
                                                                        ? 
(AbstractFileEntry *)&fExtendedEntry
                                                                        : 
(AbstractFileEntry *)&fFileEntry; }
 
-       descriptor_tag                          &_Tag() { return ((icb_header 
*)fData.Block())->tag(); }
-       icb_entry_tag                           &_IcbTag() { return 
((icb_header *)fData.Block())->icb_tag(); }
-       file_icb_entry                          *_FileEntry() { return 
(file_icb_entry *)fData.Block(); }
-       extended_file_icb_entry         &_ExtendedEntry() { return 
*(extended_file_icb_entry *)fData.Block(); }
+       descriptor_tag                          &_Tag() const { return 
((icb_header *)fData.Block())->tag(); }
+       icb_entry_tag                           &_IcbTag() const { return 
((icb_header *)fData.Block())->icb_tag(); }
+       file_icb_entry                          *_FileEntry() const
+               { return (file_icb_entry *)fData.Block(); }
+       extended_file_icb_entry         *_ExtendedEntry() const
+               { return (extended_file_icb_entry *)fData.Block(); }
 
        template<class DescriptorList>
        status_t                                        
_GetFileMap(DescriptorList &list, off_t offset,
@@ -143,6 +147,7 @@ private:
        status_t                                        fInitStatus;
        ino_t                                           fId;
        SinglyLinkedList<DirectoryIterator>             fIteratorList;
+       uint16                                          fPartition;
        FileEntry<file_icb_entry>                               fFileEntry;
        FileEntry<extended_file_icb_entry>              fExtendedEntry;
        void *                                          fFileCache;
diff --git a/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp 
b/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp
index a652672..2c58a2c 100644
--- a/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp
+++ b/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp
@@ -1,29 +1,45 @@
+/*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
+ * This file may be used under the terms of the MIT License.
+ */
+
+
 #include "MetadataPartition.h"
 
-#define B_NOT_IMPLEMENTED B_ERROR
+#include "Icb.h"
 
 
 /*! \brief Creates a new MetadataPartition object.
 */
-MetadataPartition::MetadataPartition(Partition &parentPartition,
-                                     uint32 metadataFileLocation,
-                                        uint32 metadataMirrorFileLocation,
-                                        uint32 metadataBitmapFileLocation,
-                                        uint32 allocationUnitSize,
-                                        uint16 alignmentUnitSize,
-                                        bool metadataIsDuplicated)
-       : fParentPartition(parentPartition)
-       , fAllocationUnitSize(allocationUnitSize)
-       , fAlignmentUnitSize(alignmentUnitSize)
-       , fMetadataIsDuplicated(metadataIsDuplicated)
-       , fInitStatus(B_NO_INIT)
+MetadataPartition::MetadataPartition(Volume *volume,
+       uint16 parentNumber, Partition &parentPartition, uint32 
metadataFileLocation,
+       uint32 metadataMirrorFileLocation, uint32 metadataBitmapFileLocation,
+       uint32 allocationUnitSize, uint16 alignmentUnitSize,
+       bool metadataIsDuplicated)
+       : fPartition(parentNumber),
+       fParentPartition(parentPartition),
+       fAllocationUnitSize(allocationUnitSize),
+       fAlignmentUnitSize(alignmentUnitSize),
+       fMetadataIsDuplicated(metadataIsDuplicated),
+       fInitStatus(B_NO_INIT),
+       fMetadataIcb(NULL)
 {
+       long_address address;
+       address.set_to(metadataFileLocation, fPartition);
+       
+       fMetadataIcb = new(nothrow) Icb(volume, address);
+       if (fMetadataIcb == NULL || fMetadataIcb->InitCheck() != B_OK)
+               fInitStatus = B_NO_MEMORY;
+
+       fInitStatus = B_OK;
 }
 
 /*! \brief Destroys the MetadataPartition object.
 */
 MetadataPartition::~MetadataPartition()
 {
+       delete fMetadataIcb;
 }
 
 /*! \brief Maps the given logical block to a physical block on disc.
@@ -31,7 +47,11 @@ MetadataPartition::~MetadataPartition()
 status_t
 MetadataPartition::MapBlock(uint32 logicalBlock, off_t &physicalBlock)
 {
-       return B_NOT_IMPLEMENTED;
+       off_t block = 0;
+       status_t status = fMetadataIcb->FindBlock(logicalBlock, block);
+       if (status != B_OK)
+               return status;
+       return fParentPartition.MapBlock(block, physicalBlock);
 }
 
 /*! Returns the initialization status of the object.
diff --git a/src/add-ons/kernel/file_systems/udf/MetadataPartition.h 
b/src/add-ons/kernel/file_systems/udf/MetadataPartition.h
index d172c14..0c97bf6 100644
--- a/src/add-ons/kernel/file_systems/udf/MetadataPartition.h
+++ b/src/add-ons/kernel/file_systems/udf/MetadataPartition.h
@@ -1,9 +1,8 @@
-//----------------------------------------------------------------------
-//  This software is part of the OpenBeOS distribution and is covered 
-//  by the OpenBeOS license.
-//
-//  Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
-//---------------------------------------------------------------------
+/*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
+ * This file may be used under the terms of the MIT License.
+ */
 #ifndef _UDF_METADATA_PARTITION_H
 #define _UDF_METADATA_PARTITION_H
 
@@ -12,8 +11,9 @@
 
 #include <util/kernel_cpp.h>
 
-#include "Partition.h"
 #include "UdfDebug.h"
+#include "Volume.h"
+
 
 /*! \brief Type 2 metadata partition
 
@@ -24,10 +24,10 @@
 */
 class MetadataPartition : public Partition {
 public:
-       MetadataPartition(Partition &parentPartition, uint32 
metadataFileLocation,
-                         uint32 metadataMirrorFileLocation, uint32 
metadataBitmapFileLocation,
-                         uint32 allocationUnitSize, uint16 alignmentUnitSize,
-                         bool metadataIsDuplicated);
+       MetadataPartition(Volume *volume, uint16 partition, Partition 
&parentPartition, 
+                       uint32 metadataFileLocation, uint32 
metadataMirrorFileLocation,
+                       uint32 metadataBitmapFileLocation, uint32 
allocationUnitSize,
+                       uint16 alignmentUnitSize, bool metadataIsDuplicated);
        virtual ~MetadataPartition();
        virtual status_t MapBlock(uint32 logicalBlock, off_t &physicalBlock);
        
@@ -37,11 +37,13 @@ public:
        uint16 AlignmentUnitSize() const { return fAlignmentUnitSize; }
        uint32 MetadataIsDuplicated() const { return fMetadataIsDuplicated; }
 private:
+       uint16 fPartition;
        Partition &fParentPartition;
        uint32 fAllocationUnitSize;
        uint16 fAlignmentUnitSize;
        bool fMetadataIsDuplicated;
        status_t fInitStatus;
+       Icb     *fMetadataIcb;
 };
 
 #endif // _UDF_METADATA_PARTITION_H
diff --git a/src/add-ons/kernel/file_systems/udf/Recognition.cpp 
b/src/add-ons/kernel/file_systems/udf/Recognition.cpp
index da9dc76..fbc8a27 100644
--- a/src/add-ons/kernel/file_systems/udf/Recognition.cpp
+++ b/src/add-ons/kernel/file_systems/udf/Recognition.cpp
@@ -1,3 +1,10 @@
+/*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
 #include "Recognition.h"
 
 #include "UdfString.h"
@@ -18,6 +25,7 @@ walk_volume_recognition_sequence(int device, off_t offset, 
uint32 blockSize,
 static status_t
 walk_anchor_volume_descriptor_sequences(int device, off_t offset, off_t length,
        uint32 blockSize, uint32 blockShift,
+       primary_volume_descriptor &primaryVolumeDescriptor,
        logical_volume_descriptor &logicalVolumeDescriptor,
        partition_descriptor partitionDescriptors[],
        uint8 &partitionDescriptorCount);
@@ -25,6 +33,7 @@ walk_anchor_volume_descriptor_sequences(int device, off_t 
offset, off_t length,
 static status_t
 walk_volume_descriptor_sequence(extent_address descriptorSequence, int device,
        uint32 blockSize, uint32 blockShift,
+       primary_volume_descriptor &primaryVolumeDescriptor,
        logical_volume_descriptor &logicalVolumeDescriptor,
        partition_descriptor partitionDescriptors[],
        uint8 &partitionDescriptorCount);
@@ -40,7 +49,8 @@ walk_integrity_sequence(int device, uint32 blockSize, uint32 
blockShift,
 
 status_t
 udf_recognize(int device, off_t offset, off_t length, uint32 blockSize,
-       uint32 &blockShift, logical_volume_descriptor &logicalVolumeDescriptor,
+       uint32 &blockShift, primary_volume_descriptor &primaryVolumeDescriptor,
+       logical_volume_descriptor &logicalVolumeDescriptor,
        partition_descriptor partitionDescriptors[],
        uint8 &partitionDescriptorCount)
 {
@@ -66,7 +76,8 @@ udf_recognize(int device, off_t offset, off_t length, uint32 
blockSize,
        // Now hunt down a volume descriptor sequence from one of
        // the anchor volume pointers (if there are any).
        status = walk_anchor_volume_descriptor_sequences(device, offset, length,
-               blockSize, blockShift, logicalVolumeDescriptor, 
partitionDescriptors,
+               blockSize, blockShift, primaryVolumeDescriptor,
+               logicalVolumeDescriptor, partitionDescriptors,
                partitionDescriptorCount);
        if (status != B_OK) {
                TRACE_ERROR(("udf_recognize: cannot find volume descriptor. 
status = %ld\n",
@@ -161,6 +172,7 @@ walk_volume_recognition_sequence(int device, off_t offset, 
uint32 blockSize,
 static status_t
 walk_anchor_volume_descriptor_sequences(int device, off_t offset, off_t length,
        uint32 blockSize, uint32 blockShift, 
+       primary_volume_descriptor &primaryVolumeDescriptor,
        logical_volume_descriptor &logicalVolumeDescriptor,
        partition_descriptor partitionDescriptors[],
        uint8 &partitionDescriptorCount)
@@ -200,13 +212,15 @@ walk_anchor_volume_descriptor_sequences(int device, off_t 
offset, off_t length,
                        // Found an avds, so try the main sequence first, then
                        // the reserve sequence if the main one fails.
                        anchorErr = 
walk_volume_descriptor_sequence(anchor->main_vds(),
-                               device, blockSize, blockShift, 
logicalVolumeDescriptor,
-                               partitionDescriptors, partitionDescriptorCount);
+                               device, blockSize, blockShift, 
primaryVolumeDescriptor,
+                               logicalVolumeDescriptor, partitionDescriptors,
+                               partitionDescriptorCount);
 
                        if (anchorErr)
                                anchorErr = 
walk_volume_descriptor_sequence(anchor->reserve_vds(),
-                                       device, blockSize, blockShift, 
logicalVolumeDescriptor,
-                                       partitionDescriptors, 
partitionDescriptorCount);                                
+                                       device, blockSize, blockShift, 
primaryVolumeDescriptor,
+                                       logicalVolumeDescriptor, 
partitionDescriptors,
+                                       partitionDescriptorCount);              
                
                }
                if (!anchorErr) {
                        PRINT(("block %Ld: found valid vds\n", 
avds_locations[i]));
@@ -225,6 +239,7 @@ static
 status_t
 walk_volume_descriptor_sequence(extent_address descriptorSequence,
        int device, uint32 blockSize, uint32 blockShift,
+       primary_volume_descriptor &primaryVolumeDescriptor,
        logical_volume_descriptor &logicalVolumeDescriptor,
        partition_descriptor partitionDescriptors[],
        uint8 &partitionDescriptorCount)
@@ -271,7 +286,7 @@ walk_volume_descriptor_sequence(extent_address 
descriptorSequence,
                                {
                                        primary_volume_descriptor *primary = 
reinterpret_cast<primary_volume_descriptor*>(tag);
                                        PDUMP(primary);                         
-                                       (void)primary;  // kill the warning     
        
+                                       primaryVolumeDescriptor = *primary;
                                        break;
                                }
 
diff --git a/src/add-ons/kernel/file_systems/udf/Recognition.h 
b/src/add-ons/kernel/file_systems/udf/Recognition.h
index 73bc009..0b50b7b 100644
--- a/src/add-ons/kernel/file_systems/udf/Recognition.h
+++ b/src/add-ons/kernel/file_systems/udf/Recognition.h
@@ -1,9 +1,8 @@
-//----------------------------------------------------------------------
-//  This software is part of the OpenBeOS distribution and is covered 
-//  by the OpenBeOS license.
-//
-//  Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
-//---------------------------------------------------------------------
+/*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
 #ifndef _UDF_RECOGNITION_H
 #define _UDF_RECOGNITION_H
 
@@ -14,9 +13,10 @@
 #include "UdfDebug.h"
 
 status_t udf_recognize(int device, off_t offset, off_t length,
-                                          uint32 blockSize, uint32 &blockShift,
-                       logical_volume_descriptor &logicalVolumeDescriptor,
-                       partition_descriptor partitionDescriptors[],
-                       uint8 &partitionDescriptorCount);
+                                                                       uint32 
blockSize, uint32 &blockShift,
+                                                                       
primary_volume_descriptor &primaryVolumeDescriptor,
+                                                                       
logical_volume_descriptor &logicalVolumeDescriptor, 
+                                                                       
partition_descriptor partitionDescriptors[],
+                                                                       uint8 
&partitionDescriptorCount);
 
 #endif // _UDF_RECOGNITION_H
diff --git a/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp 
b/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp
index 66a90be..68e851d 100644
--- a/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp
+++ b/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp
@@ -1,9 +1,9 @@
-//----------------------------------------------------------------------
-//  This software is part of the OpenBeOS distribution and is covered 
-//  by the OpenBeOS license.
-//
-//  Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
-//----------------------------------------------------------------------
+/*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
+ * This file may be used under the terms of the MIT License.
+ */
+
 
 /*! \file UdfStructures.cpp
 
@@ -38,20 +38,6 @@ const char* kVSDID_ECMA167_2         = "NSR02";
 const char* kVSDID_ECMA167_3   = "NSR03";
 const char* kVSDID_ECMA168             = "CDW02";
 
-// entity_ids
-const entity_id kMetadataPartitionMapId(0, "*UDF Metadata Partition");
-const entity_id kSparablePartitionMapId(0, "*UDF Sparable Partition");
-const entity_id kVirtualPartitionMapId(0, "*UDF Virtual Partition");
-const entity_id kImplementationId(0, "*OpenBeOS UDF", 
implementation_id_suffix(OS_BEOS, BEOS_GENERIC));
-const entity_id kPartitionContentsId1xx(0, "+NSR02");
-const entity_id kPartitionContentsId2xx(0, "+NSR03");
-const entity_id kLogicalVolumeInfoId150(0, "*UDF LV Info", 
udf_id_suffix(0x0150, OS_BEOS, BEOS_GENERIC));
-const entity_id kLogicalVolumeInfoId201(0, "*UDF LV Info", 
udf_id_suffix(0x0201, OS_BEOS, BEOS_GENERIC));
-const entity_id kDomainId150(0, "*OSTA UDF Compliant", domain_id_suffix(0x0150,
-                                  DF_HARD_WRITE_PROTECT));
-const entity_id kDomainId201(0, "*OSTA UDF Compliant", domain_id_suffix(0x0201,
-                                  DF_HARD_WRITE_PROTECT));
-
 //! crc 010041 table, as generated by crc_table.cpp
 const uint16 kCrcTable[256] = {
     0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
@@ -92,6 +78,40 @@ const uint32 kLogicalVolumeDescriptorBaseSize = 
sizeof(logical_volume_descriptor
                                                      - (UDF_MAX_PARTITION_MAPS
                                                         * 
UDF_MAX_PARTITION_MAP_SIZE);
 
+// entity_ids
+entity_id kMetadataPartitionMapId;
+entity_id kSparablePartitionMapId;
+entity_id kVirtualPartitionMapId;
+entity_id kImplementationId;
+entity_id kPartitionContentsId1xx;
+entity_id kPartitionContentsId2xx;
+entity_id kLogicalVolumeInfoId150;
+entity_id kLogicalVolumeInfoId201;
+entity_id kDomainId150;
+entity_id kDomainId201;
+
+
+//----------------------------------------------------------------------
+// Entities initialization
+//----------------------------------------------------------------------
+
+void
+init_entities()
+{
+       kMetadataPartitionMapId = entity_id(0, "*UDF Metadata Partition");
+       kSparablePartitionMapId = entity_id(0, "*UDF Sparable Partition");
+       kVirtualPartitionMapId = entity_id(0, "*UDF Virtual Partition");
+       kImplementationId = entity_id(0, "*OpenBeOS UDF", 
implementation_id_suffix(OS_BEOS, BEOS_GENERIC));
+       kPartitionContentsId1xx = entity_id(0, "+NSR02");
+       kPartitionContentsId2xx = entity_id(0, "+NSR03");
+       kLogicalVolumeInfoId150 = entity_id(0, "*UDF LV Info", 
udf_id_suffix(0x0150, OS_BEOS, BEOS_GENERIC));
+       kLogicalVolumeInfoId201 = entity_id(0, "*UDF LV Info", 
udf_id_suffix(0x0201, OS_BEOS, BEOS_GENERIC));
+       kDomainId150 = entity_id(0, "*OSTA UDF Compliant", 
domain_id_suffix(0x0150,
+                                  DF_HARD_WRITE_PROTECT));
+       kDomainId201 = entity_id(0, "*OSTA UDF Compliant", 
domain_id_suffix(0x0201,
+                                  DF_HARD_WRITE_PROTECT));
+}
+
 
 //----------------------------------------------------------------------
 // Helper functions
@@ -527,7 +547,7 @@ descriptor_tag::init_check(uint32 block, bool calculateCrc)
 {
        DEBUG_INIT_ETC("descriptor_tag", ("location: %ld, calculateCrc: %s",
                       block, bool_to_string(calculateCrc)));
-       PRINT(("location   (paramater)    == %ld\n", block));
+       PRINT(("location   (parameter)    == %ld\n", block));
        PRINT(("location   (in structure) == %ld\n", location()));
        if (calculateCrc) {
                PRINT(("crc        (calculated)   == %d\n",
diff --git a/src/add-ons/kernel/file_systems/udf/UdfStructures.h 
b/src/add-ons/kernel/file_systems/udf/UdfStructures.h
index 56c4710..1f2634e 100644
--- a/src/add-ons/kernel/file_systems/udf/UdfStructures.h
+++ b/src/add-ons/kernel/file_systems/udf/UdfStructures.h
@@ -1,9 +1,8 @@
-//----------------------------------------------------------------------
-// This software is part of the OpenBeOS distribution and is covered 
-//  by the OpenBeOS license.
-//
-//  Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
-//---------------------------------------------------------------------
+/*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
+ * This file may be used under the terms of the MIT License.
+ */
 #ifndef _UDF_DISK_STRUCTURES_H
 #define _UDF_DISK_STRUCTURES_H
 
@@ -121,7 +120,8 @@ public:
        uint8 microsecond() const { return _microsecond; }
        
        // Set functions
-       void set_type_and_timezone(uint16 type_and_timezone) { 
_type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
+       void set_type_and_timezone(uint16 type_and_timezone) { 
+               _type_and_timezone = 
B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
        void set_type(uint8 type) {
                type_and_timezone_accessor t;
                t.type_and_timezone = type_and_timezone();
@@ -141,7 +141,8 @@ public:
        void set_minute(uint8 minute) { _minute = minute; }
        void set_second(uint8 second) { _second = second; }
        void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
-       void set_hundred_microsecond(uint8 hundred_microsecond) { 
_hundred_microsecond = hundred_microsecond; }
+       void set_hundred_microsecond(uint8 hundred_microsecond) { 
+               _hundred_microsecond = hundred_microsecond; }
        void set_microsecond(uint8 microsecond) { _microsecond = microsecond; }
 private:
        void _clear();
@@ -293,17 +294,18 @@ private:
        array<uint8, kIdentifierSuffixLength> _identifier_suffix;
 } __attribute__((packed));
 
-extern const entity_id kMetadataPartitionMapId;
-extern const entity_id kSparablePartitionMapId;
-extern const entity_id kVirtualPartitionMapId;
-extern const entity_id kImplementationId;
-extern const entity_id kPartitionContentsId1xx;
-extern const entity_id kPartitionContentsId2xx;
-extern const entity_id kUdfId;
-extern const entity_id kLogicalVolumeInfoId150;
-extern const entity_id kLogicalVolumeInfoId201;
-extern const entity_id kDomainId150;
-extern const entity_id kDomainId201;
+extern entity_id kMetadataPartitionMapId;
+extern entity_id kSparablePartitionMapId;
+extern entity_id kVirtualPartitionMapId;
+extern entity_id kImplementationId;
+extern entity_id kPartitionContentsId1xx;
+extern entity_id kPartitionContentsId2xx;
+extern entity_id kUdfId;
+extern entity_id kLogicalVolumeInfoId150;
+extern entity_id kLogicalVolumeInfoId201;
+extern entity_id kDomainId150;
+extern entity_id kDomainId201;
+extern void init_entities(void);
 
 //----------------------------------------------------------------------
 // ECMA-167 Part 2
@@ -1307,6 +1309,49 @@ private:
        See also: UDF-2.50 2.2.10
 */
 struct metadata_partition_map {
+public:
+       entity_id& partition_type_id() { return _partition_type_id; }
+       const entity_id& partition_type_id() const { return _partition_type_id; 
}
+
+       uint16 volume_sequence_number() const {
+               return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
+       void set_volume_sequence_number(uint16 number) {
+               _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
+
+       uint16 partition_number() const {
+               return B_LENDIAN_TO_HOST_INT16(_partition_number); }
+       void set_partition_number(uint16 number) {
+               _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
+
+       uint32 metadata_file_location() const {
+               return B_LENDIAN_TO_HOST_INT32(_metadata_file_location); }
+       void set_metadata_file_location(uint32 location) {
+               _metadata_file_location = B_HOST_TO_LENDIAN_INT32(location); }
+
+       uint32 metadata_mirror_file_location() const {
+               return B_LENDIAN_TO_HOST_INT32(_metadata_mirror_file_location); 
}
+       void set_metadata_mirror_file_location(uint32 location) {
+               _metadata_mirror_file_location = 
B_HOST_TO_LENDIAN_INT32(location); }
+
+       uint32 metadata_bitmap_file_location() const {
+               return B_LENDIAN_TO_HOST_INT32(_metadata_bitmap_file_location); 
}
+       void set_metadata_bitmap_file_location(uint32 location) {
+               _metadata_bitmap_file_location = 
B_HOST_TO_LENDIAN_INT32(location); }
+
+       uint32 allocation_unit_size() const {
+               return B_LENDIAN_TO_HOST_INT32(_allocation_unit_size); }
+       void set_allocation_unit_size(uint32 size) {
+               _allocation_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
+
+       uint32 alignment_unit_size() const {
+               return B_LENDIAN_TO_HOST_INT32(_alignment_unit_size); }
+       void set_alignment_unit_size(uint32 size) {
+               _alignment_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
+
+       uint8 flags() const { return _flags; }
+       void set_flags(uint8 flags) { _flags = flags; }
+       
+private:
        uint8 type;
        uint8 length;
        uint8 reserved1[2];
@@ -1315,14 +1360,20 @@ struct metadata_partition_map {
            - identifier: "*UDF Metadata Partition"
            - identifier_suffix: per UDF-2.50 2.1.5
        */
-       entity_id partition_type_id;
-       uint16 volume_sequence_number;
+       entity_id _partition_type_id;
+       uint16 _volume_sequence_number;
        
        /*! corresponding type 1 or type 2 sparable partition
            map in same logical volume
        */
-       uint16 partition_number;        
-       uint8 reserved2[24];
+       uint16 _partition_number;       
+       uint32 _metadata_file_location;
+       uint32 _metadata_mirror_file_location;
+       uint32 _metadata_bitmap_file_location;
+       uint32 _allocation_unit_size;
+       uint16 _alignment_unit_size;
+       uint8 _flags;
+       uint8 reserved2[5];
 } __attribute__((packed));
 
 
@@ -1470,7 +1521,7 @@ enum {
 
 /*! \brief Highest currently supported UDF read revision.
 */
-#define UDF_MAX_READ_REVISION 0x0201
+#define UDF_MAX_READ_REVISION 0x0250
 
 //----------------------------------------------------------------------
 // ECMA-167 Part 4
diff --git a/src/add-ons/kernel/file_systems/udf/Utils.cpp 
b/src/add-ons/kernel/file_systems/udf/Utils.cpp
index 07c69d3..111e410 100644
--- a/src/add-ons/kernel/file_systems/udf/Utils.cpp
+++ b/src/add-ons/kernel/file_systems/udf/Utils.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
@@ -79,8 +80,16 @@ get_block_shift(uint32 blockSize, uint32 &blockShift)
 }
 
 
-time_t
-make_time(timestamp &timestamp)
+#define EPOCH_YEAR     1970
+#define MAX_YEAR       69
+#define SECSPERMIN     60
+#define MINSPERHOUR    60
+#define HOURSPERDAY    24
+#define SECSPERDAY     (SECSPERMIN * MINSPERHOUR * HOURSPERDAY)
+#define DAYSPERNYEAR   365
+
+status_t
+decode_time(timestamp &timestamp, struct timespec &timespec)
 {
        DEBUG_INIT_ETC(NULL, ("timestamp: (tnt: 0x%x, type: %d, timezone: %d = 
0x%x, year: %d, " 
                   "month: %d, day: %d, hour: %d, minute: %d, second: %d)", 
timestamp.type_and_timezone(),
@@ -88,50 +97,56 @@ make_time(timestamp &timestamp)
                    timestamp.timezone(),timestamp.year(),
                   timestamp.month(), timestamp.day(), timestamp.hour(), 
timestamp.minute(), timestamp.second()));
 
-       time_t result = 0;
+       if (timestamp.year() < EPOCH_YEAR || timestamp.year() >= EPOCH_YEAR + 
MAX_YEAR)
+               return B_BAD_VALUE;
 
-       if (timestamp.year() >= 1970) {
-               const int monthLengths[12]
-                       = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-               int year = timestamp.year();
-               int month = timestamp.month();
-               int day = timestamp.day();
-               int hour = timestamp.hour();
-               int minute = timestamp.minute();
-               int second = timestamp.second();
-
-               // Range check the timezone offset, then round it down
-               // to the nearest hour, since no one I know treats timezones
-               // with a per-minute granularity, and none of the other OSes
-               // I've looked at appear to either.
-               int timezone_offset = timestamp.timezone();
-               if (-1440 > timezone_offset || timezone_offset > 1440)
-                       timezone_offset = 0;
-               timezone_offset -= timezone_offset % 60;
-
-               int previousLeapYears = (year - 1968) / 4;
-               bool isLeapYear = (year - 1968) % 4 == 0;
-               if (isLeapYear)
-                       --previousLeapYears;
-
-               // Years to days
-               result = (year - 1970) * 365 + previousLeapYears;
-               // Months to days
-               for (int i = 0; i < month-1; i++) {
-                       result += monthLengths[i];
-               }
-               if (month > 2 && isLeapYear)
-                       ++result;
-               // Days to hours
-               result = (result + day - 1) * 24;
-               // Hours to minutes
-               result = (result + hour) * 60 + timezone_offset;
-               // Minutes to seconds
-               result = (result + minute) * 60 + second;
+       time_t result = 0;
+       const int monthLengths[12]
+               = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+       int year = timestamp.year();
+       int month = timestamp.month();
+       int day = timestamp.day();
+       int hour = timestamp.hour();
+       int minute = timestamp.minute();
+       int second = timestamp.second();
+
+       // Range check the timezone offset, then round it down
+       // to the nearest hour, since no one I know treats timezones
+       // with a per-minute granularity, and none of the other OSes
+       // I've looked at appear to either.
+       int timezone_offset = 0;
+       if (timestamp.type() == 1)
+               timezone_offset = timestamp.timezone();
+       if (-SECSPERDAY > timezone_offset || timezone_offset > SECSPERDAY)
+               timezone_offset = 0;
+       timezone_offset -= timezone_offset % 60;
+
+       int previousLeapYears = (year - 1968) / 4;
+       bool isLeapYear = (year - 1968) % 4 == 0;
+       if (isLeapYear)
+               --previousLeapYears;
+
+       // Years to days
+       result = (year - EPOCH_YEAR) * DAYSPERNYEAR + previousLeapYears;
+       // Months to days
+       for (int i = 0; i < month-1; i++) {
+               result += monthLengths[i];
        }
-
-       return result;
+       if (month > 2 && isLeapYear)
+               ++result;
+       // Days to hours
+       result = (result + day - 1) * HOURSPERDAY;
+       // Hours to minutes
+       result = (result + hour) * MINSPERHOUR + timezone_offset;
+       // Minutes to seconds
+       result = (result + minute) * SECSPERMIN + second;
+
+       timespec.tv_sec = result;
+       timespec.tv_nsec = 1000 * (timestamp.microsecond()
+               + timestamp.hundred_microsecond() * 100
+               + timestamp.centisecond() * 10000);
+       return B_OK;
 }
 
 
diff --git a/src/add-ons/kernel/file_systems/udf/Utils.h 
b/src/add-ons/kernel/file_systems/udf/Utils.h
index c6de522..5749849 100644
--- a/src/add-ons/kernel/file_systems/udf/Utils.h
+++ b/src/add-ons/kernel/file_systems/udf/Utils.h
@@ -16,7 +16,7 @@ const char            *bool_to_string(bool value);
 uint16                 calculate_crc(uint8 *data, uint16 length);
 status_t               check_size_error(ssize_t bytesReturned, ssize_t 
bytesExpected);
 status_t               get_block_shift(uint32 blockSize, uint32 &blockShift);
-time_t                 make_time(timestamp &timestamp);
+status_t               decode_time(timestamp &timestamp, struct timespec 
&timespec);
 long_address   to_long_address(ino_t id, uint32 length = 0);
 ino_t                  to_vnode_id(long_address address);
 
diff --git a/src/add-ons/kernel/file_systems/udf/Volume.cpp 
b/src/add-ons/kernel/file_systems/udf/Volume.cpp
index edca75a..4790bac 100644
--- a/src/add-ons/kernel/file_systems/udf/Volume.cpp
+++ b/src/add-ons/kernel/file_systems/udf/Volume.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@xxxxxxxxx
  * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
@@ -8,6 +9,7 @@
 
 #include "Icb.h"
 #include "MemoryChunk.h"
+#include "MetadataPartition.h"
 #include "PhysicalPartition.h"
 #include "Recognition.h"
 
@@ -62,6 +64,7 @@ Volume::Mount(const char *deviceName, off_t offset, off_t 
length,
                return device;
        }
 
+       DEBUG_INIT_ETC("Volume", ("deviceName: %s", deviceName));
        status_t status = B_OK;
 
        // If the device is actually a normal file, try to disable the cache
@@ -84,8 +87,8 @@ Volume::Mount(const char *deviceName, off_t offset, off_t 
length,
        // Run through the volume recognition and descriptor sequences to
        // see if we have a potentially valid UDF volume on our hands
        status = udf_recognize(device, offset, length, blockSize, blockShift,
-                               logicalVolumeDescriptor, partitionDescriptors,
-                               partitionDescriptorCount);
+                               fPrimaryVolumeDescriptor, 
logicalVolumeDescriptor,
+                               partitionDescriptors, partitionDescriptorCount);
 
        // Set up the block cache
        if (!status) {
@@ -163,8 +166,43 @@ Volume::Mount(const char *deviceName, off_t offset, off_t 
length,
                                TRACE(("map type: metadata\n"));
                                metadata_partition_map* map =
                                        
reinterpret_cast<metadata_partition_map*>(header);
-                               metadataCount++;
-                               (void)map;      // kill the warning for now
+                               
+                               
+                               // Find the corresponding partition descriptor
+                               partition_descriptor *descriptor = NULL;
+                               for (uint8 j = 0; j < partitionDescriptorCount; 
j++) {
+                                       if (map->partition_number() ==
+                                               
partitionDescriptors[j].partition_number()) {
+                                               descriptor = 
&partitionDescriptors[j];
+                                               break;
+                                       }
+                               }
+                               Partition *parent = 
_GetPartition(map->partition_number());
+                               // Create and add the partition
+                               if (descriptor != NULL && parent != NULL) {
+                                       MetadataPartition *partition
+                                               = new(nothrow) 
MetadataPartition(this,
+                                                       
map->partition_number(), *parent,
+                                                       
map->metadata_file_location(),
+                                                       
map->metadata_mirror_file_location(),
+                                                       
map->metadata_bitmap_file_location(),
+                                                       
map->allocation_unit_size(),
+                                                       
map->alignment_unit_size(),
+                                                       map->flags() & 1);
+                                       status = partition ? 
partition->InitCheck() : B_NO_MEMORY;
+                                       if (!status) {
+                                               TRACE(("Volume::Mount: adding 
MetadataPartition()"));
+                                               status = _SetPartition(i, 
partition);
+                                               if (status == B_OK)
+                                                       metadataCount++;
+                                       } else {
+                                               TRACE_ERROR(("Volume::Mount: 
metadata partition "
+                                                       "creation failed! 
0x%lx\n", status));
+                                       }
+                               } else {
+                                       TRACE_ERROR(("Volume::Mount: no 
matching partition descriptor found!\n"));
+                                       status = B_ERROR;
+                               }
                        } else {
                                TRACE(("map type: unrecognized (`%.23s')\n",
                                       typeId.identifier()));
@@ -180,9 +218,9 @@ Volume::Mount(const char *deviceName, off_t offset, off_t 
length,
        // Do some checking as to what sorts of partitions we've actually found.
        if (!status) {
                status = (physicalCount == 1 && virtualCount == 0
-                        && sparableCount == 0 && metadataCount == 0)
+                        && sparableCount == 0)
                        || (physicalCount == 2 && virtualCount == 0
-                          && sparableCount == 0 && metadataCount == 0)
+                          && sparableCount == 0)
                        ? B_OK : B_ERROR;
                if (status) {
                        TRACE(("Invalid partition layout found:\n"));
@@ -294,6 +332,8 @@ Volume::MapBlock(long_address address, off_t *mappedBlock)
 {
        TRACE(("Volume::MapBlock: partition = %d, block = %ld, mappedBlock = 
%p\n",
                address.partition(), address.block(), mappedBlock));
+       DEBUG_INIT_ETC("Volume", ("partition = %d, block = %ld, mappedBlock = 
%p",
+               address.partition(), address.block(), mappedBlock));
        status_t error = mappedBlock ? B_OK : B_BAD_VALUE;
        if (!error) {
                Partition *partition = _GetPartition(address.partition());
diff --git a/src/add-ons/kernel/file_systems/udf/Volume.h 
b/src/add-ons/kernel/file_systems/udf/Volume.h
index a86e1c8..03487d3 100644
--- a/src/add-ons/kernel/file_systems/udf/Volume.h
+++ b/src/add-ons/kernel/file_systems/udf/Volume.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@xxxxxxxxx
  * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
@@ -50,6 +51,8 @@ public:
        uint32                          BlockShift() const { return 
fBlockShift; }
        bool                            Mounted() const { return fMounted; }
        Icb*                            RootIcb() { return fRootIcb; }
+       primary_volume_descriptor *PrimaryVolumeDescriptor() 
+                                                       { return 
&fPrimaryVolumeDescriptor; }
 
 private:
        void                            _Unset();
@@ -69,6 +72,7 @@ private:
        off_t                           fOffset;
        Partition                       *fPartitions[UDF_MAX_PARTITION_MAPS];
        Icb                                     *fRootIcb;      // Destroyed by 
vfs via callback to put_node()
+       primary_volume_descriptor fPrimaryVolumeDescriptor;
 };
 
 #endif // _UDF_VOLUME_H
diff --git a/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp 
b/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp
index 398bc6d..06a3a29 100644
--- a/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp
@@ -1,7 +1,8 @@
 /*
- * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
- * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@xxxxxxxxxx
+ * Copyright 2012, JÃrÃme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2010, Michael Lotz, mmlr@xxxxxxxxx
+ * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@xxxxxxxxxx
+ * Copyright 2003, Tyler Dauwalder, tyler@xxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
@@ -80,13 +81,14 @@ udf_identify_partition(int fd, partition_data *partition, 
void **_cookie)
                partition->offset, partition->size, partition->content_size,
                partition->block_size));
 
+       primary_volume_descriptor primaryVolumeDescriptor;
        logical_volume_descriptor logicalVolumeDescriptor;
        partition_descriptor partitionDescriptors[kMaxPartitionDescriptors];
        uint8 descriptorCount = kMaxPartitionDescriptors;
        uint32 blockShift;
        status_t error = udf_recognize(fd, partition->offset, partition->size,
-               partition->block_size, blockShift, logicalVolumeDescriptor,
-               partitionDescriptors, descriptorCount);
+               partition->block_size, blockShift, primaryVolumeDescriptor,
+               logicalVolumeDescriptor, partitionDescriptors, descriptorCount);
        if (error != B_OK)
                return -1;
 
@@ -293,8 +295,12 @@ udf_read_stat(fs_volume *_volume, fs_vnode *node, struct 
stat *stat)
        // File times. For now, treat the modification time as creation
        // time as well, since true creation time is an optional extended
        // attribute, and supporting EAs is going to be a PITA. ;-)
-       stat->st_atime = icb->AccessTime();
-       stat->st_mtime = stat->st_ctime = stat->st_crtime = 
icb->ModificationTime();
+       icb->GetAccessTime(stat->st_atim);
+       icb->GetModificationTime(stat->st_mtim);
+       icb->GetModificationTime(stat->st_ctim);
+       icb->GetModificationTime(stat->st_crtim);
+       //icb->GetChangeTime(stat->st_ctim);
+       //icb->GetCreationTime(stat->st_crtim);
 
        TRACE(("udf_read_stat: mode = 0x%x, st_ino: %Ld\n", stat->st_mode,
                stat->st_ino));
@@ -343,6 +349,8 @@ udf_read(fs_volume *volume, fs_vnode *vnode, void *cookie, 
off_t pos,
                ((Volume *)volume->private_volume)->ID(), pos, *length));
 
        Icb *icb = (Icb *)vnode->private_node;
+       DEBUG_INIT_ETC("udf_read", ("ID = %ld, pos = %lld, length = %lu",
+               ((Volume *)volume->private_volume)->ID(), pos, *length));
 
 //     if (!inode->HasUserAccessableStream()) {
 //             *_length = 0;
@@ -385,6 +393,8 @@ static status_t
 udf_open_dir(fs_volume *volume, fs_vnode *vnode, void **cookie)
 {
        TRACE(("udf_open_dir: volume = %p, vnode = %p\n", volume, vnode));
+       DEBUG_INIT_ETC("udf_open_dir", ("ID = %ld",
+               ((Volume *)volume->private_volume)->ID()));
 
        if (!volume || !vnode || !cookie)
                RETURN(B_BAD_VALUE);
@@ -443,6 +453,8 @@ udf_read_dir(fs_volume *_volume, fs_vnode *vnode, void 
*cookie,
        Icb *dir = (Icb *)vnode->private_node;
        DirectoryIterator *iterator = (DirectoryIterator *)cookie;
 
+       DEBUG_INIT_ETC("udf_read_dir", ("ID = %ld", volume->ID()));
+
        if (dir != iterator->Parent()) {
                TRACE_ERROR(("udf_read_dir: Icb does not match parent Icb of 
given "
                        "DirectoryIterator! (iterator->Parent = %p)\n", 
iterator->Parent()));
@@ -474,6 +486,8 @@ udf_rewind_dir(fs_volume *volume, fs_vnode *vnode, void 
*cookie)
 {
        TRACE(("udf_rewind_dir: volume = %p, vnode = %p, cookie = %p\n",
                volume, vnode, cookie));
+       DEBUG_INIT_ETC("udf_rewind_dir", ("ID = %ld",
+               ((Volume *)volume->private_volume)->ID()));
 
        if (!volume || !vnode || !cookie)
                RETURN(B_BAD_VALUE);
@@ -604,6 +618,8 @@ udf_std_ops(int32 op, ...)
 {
        switch (op) {
                case B_MODULE_INIT:
+                       init_entities();
+                       return B_OK;
                case B_MODULE_UNINIT:
                        return B_OK;
                default:

############################################################################

Revision:    hrevr1alpha4-44636
Commit:      3adb6707bd37a20171158403688b48c3ef05ff4a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3adb670
Author:      JÃrÃme Duval <jerome.duval@xxxxxxxxx>
Date:        Sun Oct 21 10:47:14 2012 UTC
Committer:   Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Commit-Date: Sun Oct 21 13:03:04 2012 UTC

Ticket:      https://dev.haiku-os.org/ticket/9004

udf: moved partitions deletion before block cache deletion (#9004)

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/udf/Volume.cpp 
b/src/add-ons/kernel/file_systems/udf/Volume.cpp
index 4790bac..8736016 100644
--- a/src/add-ons/kernel/file_systems/udf/Volume.cpp
+++ b/src/add-ons/kernel/file_systems/udf/Volume.cpp
@@ -352,11 +352,15 @@ void
 Volume::_Unset()
 {
        DEBUG_INIT("Volume");
+       // delete our partitions
+       for (int i = 0; i < UDF_MAX_PARTITION_MAPS; i++)
+               _SetPartition(i, NULL);
        fFSVolume->id = 0;
        if (fDevice >= 0) {
                block_cache_delete(fBlockCache, true);  
                close(fDevice);
        }
+       fBlockCache = NULL;
        fDevice = -1;
        fMounted = false;
        fOffset = 0;
@@ -364,9 +368,6 @@ Volume::_Unset()
        fBlockSize = 0;
        fBlockShift = 0;
        fName.SetTo("", 0);
-       // delete our partitions
-       for (int i = 0; i < UDF_MAX_PARTITION_MAPS; i++)
-               _SetPartition(i, NULL);
 }
 
 /*! \brief Sets the partition associated with the given number after


Other related posts: