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
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "Icb.h"
|
#include "Icb.h"
|
||||||
#include "MemoryChunk.h"
|
#include "MemoryChunk.h"
|
||||||
|
#include "Recognition.h"
|
||||||
|
|
||||||
using namespace Udf;
|
using namespace Udf;
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ Volume::Volume(nspace_id id)
|
|||||||
: fId(id)
|
: fId(id)
|
||||||
, fDevice(0)
|
, fDevice(0)
|
||||||
, fReadOnly(false)
|
, fReadOnly(false)
|
||||||
|
, fMounted(false)
|
||||||
, fOffset(0)
|
, fOffset(0)
|
||||||
, fBlockSize(0)
|
, fBlockSize(0)
|
||||||
, fBlockShift(0)
|
, fBlockShift(0)
|
||||||
@@ -31,6 +33,8 @@ Volume::Volume(nspace_id id)
|
|||||||
, fRootIcb(NULL)
|
, fRootIcb(NULL)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < UDF_MAX_PARTITION_MAPS; i++)
|
||||||
|
fPartitions[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
@@ -60,6 +64,151 @@ Volume::Identify(int device, off_t offset, off_t length, uint32 blockSize, char
|
|||||||
RETURN(err);
|
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<udf_generic_partition_map*>(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<udf_physical_partition_map*>(header);
|
||||||
|
// PDUMP(map);
|
||||||
|
PDUMP(reinterpret_cast<udf_physical_partition_map*>(header));
|
||||||
|
} else {
|
||||||
|
udf_sparable_partition_map* map =
|
||||||
|
reinterpret_cast<udf_sparable_partition_map*>(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<udf_file_set_descriptor*>(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.
|
/*! \brief Attempts to mount the given device.
|
||||||
|
|
||||||
\param volumeStart The block on the given device whereat the volume begins.
|
\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+");
|
// FILE *file = fopen("/boot/home/Desktop/vdoutput.txt", "w+");
|
||||||
// fprint
|
// fprint
|
||||||
|
|
||||||
fName.SetTo(fLogicalVD.logical_volume_identifier());
|
fName.SetTo(fLogicalVolumeDescriptor.logical_volume_identifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
fInitStatus = err < B_OK ? B_UNINITIALIZED : B_IDENTIFIED;
|
fInitStatus = err < B_OK ? B_UNINITIALIZED : B_IDENTIFIED;
|
||||||
@@ -521,10 +670,10 @@ Volume::_WalkVolumeDescriptorSequence(udf_extent_address extent)
|
|||||||
PDUMP(logical);
|
PDUMP(logical);
|
||||||
if (foundLogicalVD) {
|
if (foundLogicalVD) {
|
||||||
// Keep the vd with the highest vds_number
|
// Keep the vd with the highest vds_number
|
||||||
if (logical->vds_number() > fLogicalVD.vds_number())
|
if (logical->vds_number() > fLogicalVolumeDescriptor.vds_number())
|
||||||
fLogicalVD = *(logical);
|
fLogicalVolumeDescriptor = *(logical);
|
||||||
} else {
|
} else {
|
||||||
fLogicalVD = *(logical);
|
fLogicalVolumeDescriptor = *(logical);
|
||||||
foundLogicalVD = true;
|
foundLogicalVD = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -567,14 +716,14 @@ status_t
|
|||||||
Volume::_InitFileSetDescriptor()
|
Volume::_InitFileSetDescriptor()
|
||||||
{
|
{
|
||||||
DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS, "Volume");
|
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();
|
status_t err = chunk.InitCheck();
|
||||||
|
|
||||||
#if (!DRIVE_SETUP_ADDON)
|
#if (!DRIVE_SETUP_ADDON)
|
||||||
if (!err) {
|
if (!err) {
|
||||||
// err = Read(ad, fLogicalVD.file_set_address().length(), chunk.Data());
|
// err = Read(ad, fLogicalVolumeDescriptor.file_set_address().length(), chunk.Data());
|
||||||
err = Read(fLogicalVD.file_set_address(), fLogicalVD.file_set_address().length(), chunk.Data());
|
err = Read(fLogicalVolumeDescriptor.file_set_address(), fLogicalVolumeDescriptor.file_set_address().length(), chunk.Data());
|
||||||
if (!err) {
|
if (!err) {
|
||||||
udf_file_set_descriptor *fileSet = reinterpret_cast<udf_file_set_descriptor*>(chunk.Data());
|
udf_file_set_descriptor *fileSet = reinterpret_cast<udf_file_set_descriptor*>(chunk.Data());
|
||||||
fileSet->tag().init_check(0);
|
fileSet->tag().init_check(0);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ extern "C" {
|
|||||||
#include "CS0String.h"
|
#include "CS0String.h"
|
||||||
#include "DiskStructures.h"
|
#include "DiskStructures.h"
|
||||||
#include "PartitionMap.h"
|
#include "PartitionMap.h"
|
||||||
|
#include "Partition.h"
|
||||||
|
|
||||||
namespace Udf {
|
namespace Udf {
|
||||||
|
|
||||||
@@ -40,6 +41,8 @@ public:
|
|||||||
|
|
||||||
status_t Mount(const char *deviceName, off_t volumeStart, off_t volumeLength, uint32 flags,
|
status_t Mount(const char *deviceName, off_t volumeStart, off_t volumeLength, uint32 flags,
|
||||||
uint32 blockSize = 2048);
|
uint32 blockSize = 2048);
|
||||||
|
status_t Mount2(const char *deviceName, off_t offset, off_t length,
|
||||||
|
uint32 blockSize, uint32 flags);
|
||||||
status_t Unmount();
|
status_t Unmount();
|
||||||
|
|
||||||
const char *Name() const;
|
const char *Name() const;
|
||||||
@@ -56,6 +59,7 @@ public:
|
|||||||
off_t RelativeAddress(off_t address) { return Offset() * BlockSize() + address; }
|
off_t RelativeAddress(off_t address) { return Offset() * BlockSize() + address; }
|
||||||
|
|
||||||
bool IsReadOnly() const { return fReadOnly; }
|
bool IsReadOnly() const { return fReadOnly; }
|
||||||
|
bool Mounted() const { return fMounted; }
|
||||||
|
|
||||||
vnode_id ToVnodeId(off_t block) const { return (vnode_id)block; }
|
vnode_id ToVnodeId(off_t block) const { return (vnode_id)block; }
|
||||||
|
|
||||||
@@ -70,6 +74,8 @@ public:
|
|||||||
off_t MapAddress(udf_extent_address address);
|
off_t MapAddress(udf_extent_address address);
|
||||||
status_t MapBlock(udf_long_address address, off_t *mappedBlock);
|
status_t MapBlock(udf_long_address address, off_t *mappedBlock);
|
||||||
off_t MapAddress(udf_short_address address);
|
off_t MapAddress(udf_short_address address);
|
||||||
|
status_t MapExtent(udf_long_address logicalExtent, udf_extent_address &physicalExtent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Volume(); // unimplemented
|
Volume(); // unimplemented
|
||||||
Volume(const Volume &ref); // unimplemented
|
Volume(const Volume &ref); // unimplemented
|
||||||
@@ -100,15 +106,17 @@ private:
|
|||||||
nspace_id fId;
|
nspace_id fId;
|
||||||
int fDevice;
|
int fDevice;
|
||||||
bool fReadOnly;
|
bool fReadOnly;
|
||||||
|
bool fMounted;
|
||||||
|
|
||||||
off_t fOffset; //!< Starting block of the volume on the given device
|
off_t fOffset;
|
||||||
off_t fLength; //!< Block length of volume on the given device
|
off_t fLength;
|
||||||
uint32 fBlockSize;
|
uint32 fBlockSize;
|
||||||
uint32 fBlockShift;
|
uint32 fBlockShift;
|
||||||
|
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
|
|
||||||
udf_logical_descriptor fLogicalVD;
|
udf_logical_descriptor fLogicalVolumeDescriptor;
|
||||||
|
Partition *fPartitions[UDF_MAX_PARTITION_MAPS];
|
||||||
PartitionMap fPartitionMap;
|
PartitionMap fPartitionMap;
|
||||||
#if (!DRIVE_SETUP_ADDON)
|
#if (!DRIVE_SETUP_ADDON)
|
||||||
Icb *fRootIcb; // Destroyed by vfs via callback to udf_release_node()
|
Icb *fRootIcb; // Destroyed by vfs via callback to udf_release_node()
|
||||||
|
|||||||
Reference in New Issue
Block a user