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:
parent
4302df3c0e
commit
21c162a3be
@ -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<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.
|
||||
|
||||
\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<udf_file_set_descriptor*>(chunk.Data());
|
||||
fileSet->tag().init_check(0);
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user