From 21c162a3bea565906dcb11c0f0a68c57026d8503 Mon Sep 17 00:00:00 2001 From: Tyler Dauwalder Date: Mon, 3 Nov 2003 20:07:10 +0000 Subject: [PATCH] Started migration to new recognition functions. New mount function implemented to partition-setup point. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5249 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/udf/Volume.cpp | 163 +++++++++++++++++- src/add-ons/kernel/file_systems/udf/Volume.h | 16 +- 2 files changed, 168 insertions(+), 11 deletions(-) diff --git a/src/add-ons/kernel/file_systems/udf/Volume.cpp b/src/add-ons/kernel/file_systems/udf/Volume.cpp index 049657e445..7de0400d70 100644 --- a/src/add-ons/kernel/file_systems/udf/Volume.cpp +++ b/src/add-ons/kernel/file_systems/udf/Volume.cpp @@ -10,6 +10,7 @@ #include "Icb.h" #include "MemoryChunk.h" +#include "Recognition.h" using namespace Udf; @@ -23,6 +24,7 @@ Volume::Volume(nspace_id id) : fId(id) , fDevice(0) , fReadOnly(false) + , fMounted(false) , fOffset(0) , fBlockSize(0) , fBlockShift(0) @@ -31,6 +33,8 @@ Volume::Volume(nspace_id id) , fRootIcb(NULL) #endif { + for (int i = 0; i < UDF_MAX_PARTITION_MAPS; i++) + fPartitions[i] = NULL; } status_t @@ -60,6 +64,151 @@ Volume::Identify(int device, off_t offset, off_t length, uint32 blockSize, char RETURN(err); } +/*! \brief Attempts to mount the given device. + + \param volumeStart The block on the given device whereat the volume begins. + \param volumeLength The block length of the volume on the given device. +*/ +status_t +Volume::Mount2(const char *deviceName, off_t offset, off_t length, + uint32 blockSize, uint32 flags) +{ + DEBUG_INIT_ETC(CF_PUBLIC | CF_VOLUME_OPS, "Volume", + ("deviceName: `%s', offset: %Ld, length: %Ld, blockSize: %ld, " + "flags: %ld", deviceName, offset, length, blockSize, flags)); + if (!deviceName) + RETURN(B_BAD_VALUE); + if (Mounted()) { + // Already mounted, thank you for asking + RETURN(B_BUSY); + } + + // Open the device read only + int device = open(deviceName, O_RDONLY); + if (device < B_OK) + RETURN(device); + + status_t error = B_OK; + + // If the device is actually a normal file, try to disable the cache + // for the file in the parent filesystem + struct stat stat; + error = fstat(device, &stat) < 0 ? B_ERROR : B_OK; + if (!error) { + if (stat.st_mode & S_IFREG && ioctl(device, IOCTL_FILE_UNCACHED_IO, NULL) < 0) { + DIE(("Unable to disable cache of underlying file system.\n")); + } + } + + udf_logical_descriptor logicalVolumeDescriptor; + udf_partition_descriptor partitionDescriptors[Udf::kMaxPartitionDescriptors]; + uint8 partitionDescriptorCount; + uint32 blockShift; + + error = udf_recognize(device, offset, length, blockSize, blockShift, + logicalVolumeDescriptor, partitionDescriptors, + partitionDescriptorCount); + + // Set up the block cache + if (!error) + error = init_cache_for_device(device, length); + + // Set up the partitions + if (!error) { + // Set up physical and sparable partitions first + int offset = 0; + for (uint8 i = 0; i < logicalVolumeDescriptor.partition_map_count(); i++) { + uint8 *maps = logicalVolumeDescriptor.partition_maps(); + udf_generic_partition_map *header = + reinterpret_cast(maps+offset); +// logicalVolumeDescriptor.partition_maps() + offset); + PRINT(("partition map %d (type %d):\n", i, header->type())); + if (header->type() == 1) { +// udf_physical_partition_map* map = +// reinterpret_cast(header); +// PDUMP(map); + PDUMP(reinterpret_cast(header)); + } else { + udf_sparable_partition_map* map = + reinterpret_cast(header); + DUMP(map->partition_type_id()); + } + + offset += header->length(); + } + } + + RETURN(B_ERROR); + + // At this point we've found a valid set of volume descriptors, and we + // have our partitions set up. We + // now need to investigate the file set descriptor pointed to by + // the logical volume descriptor + if (!error) { + MemoryChunk chunk(fLogicalVolumeDescriptor.file_set_address().length()); + + status_t error = chunk.InitCheck(); + + if (!error) { + error = Read(fLogicalVolumeDescriptor.file_set_address(), + fLogicalVolumeDescriptor.file_set_address().length(), + chunk.Data()); + if (!error) { + udf_file_set_descriptor *fileSet = + reinterpret_cast(chunk.Data()); + fileSet->tag().init_check(0); + PDUMP(fileSet); + fRootIcb = new Icb(this, fileSet->root_directory_icb()); + error = fRootIcb ? fRootIcb->InitCheck() : B_NO_MEMORY; + } + } + } + + if (!error) { + // Success, create a vnode for the root + error = new_vnode(Id(), RootIcb()->Id(), (void*)RootIcb()); + if (error) { + PRINT(("Error create vnode for root icb! error = 0x%lx, `%s'\n", + error, strerror(error))); + } + } + + fInitStatus = error < B_OK ? B_UNINITIALIZED : B_LOGICAL_VOLUME_INITIALIZED; + + // set name and other member variables + if (!error) { + + } + + fDevice = device; + fReadOnly = true; + fOffset = offset; + fLength = length; + fBlockSize = blockSize; + + RETURN(error); + +/* if (!error && volumeName) { + CS0String name(logicalVolumeDescriptor.logical_volume_identifier()); + strcpy(volumeName, name.String()); + } +*/ +/* + status_t error = _Init(device, volumeStart, volumeLength, blockSize); + if (!error) + error = _Identify(); + if (!error) + error = _Mount(); + + if (error) + fInitStatus = B_UNINITIALIZED; + + RETURN(error); + +*/ +} + + /*! \brief Attempts to mount the given device. \param volumeStart The block on the given device whereat the volume begins. @@ -269,7 +418,7 @@ Volume::_Identify() // FILE *file = fopen("/boot/home/Desktop/vdoutput.txt", "w+"); // fprint - fName.SetTo(fLogicalVD.logical_volume_identifier()); + fName.SetTo(fLogicalVolumeDescriptor.logical_volume_identifier()); } fInitStatus = err < B_OK ? B_UNINITIALIZED : B_IDENTIFIED; @@ -521,10 +670,10 @@ Volume::_WalkVolumeDescriptorSequence(udf_extent_address extent) PDUMP(logical); if (foundLogicalVD) { // Keep the vd with the highest vds_number - if (logical->vds_number() > fLogicalVD.vds_number()) - fLogicalVD = *(logical); + if (logical->vds_number() > fLogicalVolumeDescriptor.vds_number()) + fLogicalVolumeDescriptor = *(logical); } else { - fLogicalVD = *(logical); + fLogicalVolumeDescriptor = *(logical); foundLogicalVD = true; } break; @@ -567,14 +716,14 @@ status_t Volume::_InitFileSetDescriptor() { DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS, "Volume"); - MemoryChunk chunk(fLogicalVD.file_set_address().length()); + MemoryChunk chunk(fLogicalVolumeDescriptor.file_set_address().length()); status_t err = chunk.InitCheck(); #if (!DRIVE_SETUP_ADDON) if (!err) { -// err = Read(ad, fLogicalVD.file_set_address().length(), chunk.Data()); - err = Read(fLogicalVD.file_set_address(), fLogicalVD.file_set_address().length(), chunk.Data()); +// err = Read(ad, fLogicalVolumeDescriptor.file_set_address().length(), chunk.Data()); + err = Read(fLogicalVolumeDescriptor.file_set_address(), fLogicalVolumeDescriptor.file_set_address().length(), chunk.Data()); if (!err) { udf_file_set_descriptor *fileSet = reinterpret_cast(chunk.Data()); fileSet->tag().init_check(0); diff --git a/src/add-ons/kernel/file_systems/udf/Volume.h b/src/add-ons/kernel/file_systems/udf/Volume.h index fcaf2f92a8..41be760fa9 100644 --- a/src/add-ons/kernel/file_systems/udf/Volume.h +++ b/src/add-ons/kernel/file_systems/udf/Volume.h @@ -27,6 +27,7 @@ extern "C" { #include "CS0String.h" #include "DiskStructures.h" #include "PartitionMap.h" +#include "Partition.h" namespace Udf { @@ -40,6 +41,8 @@ public: status_t Mount(const char *deviceName, off_t volumeStart, off_t volumeLength, uint32 flags, uint32 blockSize = 2048); + status_t Mount2(const char *deviceName, off_t offset, off_t length, + uint32 blockSize, uint32 flags); status_t Unmount(); const char *Name() const; @@ -56,6 +59,7 @@ public: off_t RelativeAddress(off_t address) { return Offset() * BlockSize() + address; } bool IsReadOnly() const { return fReadOnly; } + bool Mounted() const { return fMounted; } vnode_id ToVnodeId(off_t block) const { return (vnode_id)block; } @@ -70,6 +74,8 @@ public: off_t MapAddress(udf_extent_address address); status_t MapBlock(udf_long_address address, off_t *mappedBlock); off_t MapAddress(udf_short_address address); + status_t MapExtent(udf_long_address logicalExtent, udf_extent_address &physicalExtent); + private: Volume(); // unimplemented Volume(const Volume &ref); // unimplemented @@ -100,15 +106,17 @@ private: nspace_id fId; int fDevice; bool fReadOnly; + bool fMounted; - off_t fOffset; //!< Starting block of the volume on the given device - off_t fLength; //!< Block length of volume on the given device + off_t fOffset; + off_t fLength; uint32 fBlockSize; uint32 fBlockShift; status_t fInitStatus; - - udf_logical_descriptor fLogicalVD; + + udf_logical_descriptor fLogicalVolumeDescriptor; + Partition *fPartitions[UDF_MAX_PARTITION_MAPS]; PartitionMap fPartitionMap; #if (!DRIVE_SETUP_ADDON) Icb *fRootIcb; // Destroyed by vfs via callback to udf_release_node()